admin/features/events/edit/syncEventExtras.test.ts
alisaza e1eaf5eff5 feat: initial ghabilee-admin backoffice app
Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js
app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
2026-09-05 13:12:59 +03:30

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')
})
})