Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
131 lines
3.7 KiB
TypeScript
131 lines
3.7 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
const createEventMedia = vi.fn()
|
|
const updateEventMedia = vi.fn()
|
|
const deleteEventMedia = vi.fn()
|
|
const createEventFaq = vi.fn()
|
|
const updateEventFaq = vi.fn()
|
|
const deleteEventFaq = vi.fn()
|
|
|
|
vi.mock('@/services/events', () => ({
|
|
createEventMedia: (...args: unknown[]) => createEventMedia(...args),
|
|
updateEventMedia: (...args: unknown[]) => updateEventMedia(...args),
|
|
deleteEventMedia: (...args: unknown[]) => deleteEventMedia(...args),
|
|
createEventFaq: (...args: unknown[]) => createEventFaq(...args),
|
|
updateEventFaq: (...args: unknown[]) => updateEventFaq(...args),
|
|
deleteEventFaq: (...args: unknown[]) => deleteEventFaq(...args),
|
|
}))
|
|
|
|
import { syncEventFaqs, syncEventMedia } from '@/features/events/edit/syncEventExtras'
|
|
|
|
describe('syncEventMedia', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('creates new items, updates changed ones, and deletes removed ones', async () => {
|
|
const initial = [
|
|
{
|
|
id: 'm1',
|
|
eventId: 'e1',
|
|
mediaType: 'image' as const,
|
|
url: 'https://cdn/a.jpg',
|
|
thumbnailUrl: null,
|
|
sortOrder: 0,
|
|
isPoster: true,
|
|
isSquarePoster: false,
|
|
createdAt: '2026-01-01T00:00:00.000Z',
|
|
},
|
|
{
|
|
id: 'm2',
|
|
eventId: 'e1',
|
|
mediaType: 'image' as const,
|
|
url: 'https://cdn/b.jpg',
|
|
thumbnailUrl: null,
|
|
sortOrder: 1,
|
|
isPoster: false,
|
|
isSquarePoster: true,
|
|
createdAt: '2026-01-01T00:00:00.000Z',
|
|
},
|
|
{
|
|
id: 'm3',
|
|
eventId: 'e1',
|
|
mediaType: 'image' as const,
|
|
url: 'https://cdn/c.jpg',
|
|
thumbnailUrl: null,
|
|
sortOrder: 2,
|
|
isPoster: false,
|
|
isSquarePoster: false,
|
|
createdAt: '2026-01-01T00:00:00.000Z',
|
|
},
|
|
]
|
|
|
|
await syncEventMedia('e1', initial, [
|
|
{ id: 'm1', url: 'https://cdn/a.jpg', isPoster: true, isSquarePoster: false, sortOrder: 0 },
|
|
{ id: 'm2', url: 'https://cdn/b2.jpg', isPoster: false, isSquarePoster: true, sortOrder: 1 },
|
|
{ id: 'new-1', url: 'https://cdn/d.jpg', isPoster: false, isSquarePoster: false, sortOrder: 2 },
|
|
])
|
|
|
|
expect(createEventMedia).toHaveBeenCalledWith('e1', {
|
|
mediaType: 'image',
|
|
url: 'https://cdn/d.jpg',
|
|
sortOrder: 2,
|
|
isPoster: false,
|
|
isSquarePoster: false,
|
|
})
|
|
expect(updateEventMedia).toHaveBeenCalledWith('e1', 'm2', {
|
|
url: 'https://cdn/b2.jpg',
|
|
sortOrder: 1,
|
|
isPoster: false,
|
|
isSquarePoster: true,
|
|
})
|
|
expect(deleteEventMedia).toHaveBeenCalledWith('e1', 'm3')
|
|
})
|
|
})
|
|
|
|
describe('syncEventFaqs', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('creates, updates, and deletes FAQ rows by id', async () => {
|
|
const initial = [
|
|
{
|
|
id: 'f1',
|
|
eventId: 'e1',
|
|
question: 'ق۱',
|
|
answer: 'ج۱',
|
|
sortOrder: 0,
|
|
createdAt: '2026-01-01T00:00:00.000Z',
|
|
updatedAt: '2026-01-01T00:00:00.000Z',
|
|
},
|
|
{
|
|
id: 'f2',
|
|
eventId: 'e1',
|
|
question: 'ق۲',
|
|
answer: 'ج۲',
|
|
sortOrder: 1,
|
|
createdAt: '2026-01-01T00:00:00.000Z',
|
|
updatedAt: '2026-01-01T00:00:00.000Z',
|
|
},
|
|
]
|
|
|
|
await syncEventFaqs('e1', initial, [
|
|
{ id: 'f1', question: 'ق۱ جدید', answer: 'ج۱' },
|
|
{ id: 'f3', question: 'ق۳', answer: 'ج۳' },
|
|
])
|
|
|
|
expect(updateEventFaq).toHaveBeenCalledWith('e1', 'f1', {
|
|
question: 'ق۱ جدید',
|
|
answer: 'ج۱',
|
|
sortOrder: 0,
|
|
})
|
|
expect(createEventFaq).toHaveBeenCalledWith('e1', {
|
|
question: 'ق۳',
|
|
answer: 'ج۳',
|
|
sortOrder: 1,
|
|
})
|
|
expect(deleteEventFaq).toHaveBeenCalledWith('e1', 'f2')
|
|
})
|
|
})
|