import { expect, test, type Page } from '@playwright/test' import { createHostEvent, hostInsights } from '@/e2e/fixtures/hostEvent' import { authenticateAs } from '@/e2e/fixtures/session' interface ReviewEventFixture { [key: string]: unknown status: string publishedAt: string | null adminApprovedAt: string | null rejectionReason: string | null } function pendingReviewEvent(): ReviewEventFixture { return createHostEvent({ title: 'رویداد در انتظار بررسی', status: 'pending_review', publishedAt: null, adminApprovedAt: null, rejectionReason: null, organizerId: 'host-1', organizer: { id: 'host-1', firstName: 'میزبان', lastName: 'تست', mobile: '989121234567' }, settings: { isDiscoverable: false, autoCreateGroup: true, addressVisibility: 'public', generalArea: null, waitlistAutoOffer: true, sendReviewRequestSms: false, }, }) } async function mockReviewEndpoints(page: Page) { let current = pendingReviewEvent() const requests: { path: string; payload: unknown }[] = [] await page.route('**/api/v1/**', async (route) => { const request = route.request() const url = new URL(request.url()) const { pathname } = url if (pathname.endsWith('/users/me')) { await route.fulfill({ json: { success: true, data: { id: 'admin-id', role: 'admin', status: 'active' } } }) return } if (pathname.endsWith('/admin/events/event-1/approve') && request.method() === 'PATCH') { requests.push({ path: pathname, payload: request.postDataJSON() }) current = { ...current, status: 'published', publishedAt: '2030-01-01T10:00:00.000Z', adminApprovedAt: '2030-01-01T10:00:00.000Z', } await route.fulfill({ json: { success: true, data: current } }) return } if (pathname.endsWith('/admin/events/event-1/reject') && request.method() === 'PATCH') { const payload = request.postDataJSON() as { rejectionReason: string } requests.push({ path: pathname, payload }) current = { ...current, status: 'rejected', publishedAt: null, adminApprovedAt: null, rejectionReason: payload.rejectionReason, } await route.fulfill({ json: { success: true, data: current } }) return } if (pathname.endsWith('/admin/events/event-1') && request.method() === 'GET') { await route.fulfill({ json: { success: true, data: current } }) return } if (pathname.endsWith('/admin/events/event-1/insights')) { await route.fulfill({ json: { success: true, data: hostInsights } }) return } if (pathname.endsWith('/event-categories') || pathname.includes('/event-categories?')) { await route.fulfill({ json: { success: true, data: [] } }) return } if (pathname.endsWith('/geography/cities') || pathname.includes('/geography/cities?')) { await route.fulfill({ json: { success: true, data: [] } }) return } if (pathname.endsWith('/geography/provinces') || pathname.includes('/geography/provinces?')) { await route.fulfill({ json: { success: true, data: [] } }) return } if (pathname.endsWith('/events/event-1/media') || pathname.endsWith('/events/event-1/faqs')) { await route.fulfill({ json: { success: true, data: [] } }) return } await route.fulfill({ json: { success: true, data: { items: [], response: { page: 1, pageSize: 20, totalItemsCount: 0 } } } }) }) return requests } test.beforeEach(async ({ context, page }) => { await authenticateAs(context, page, 'admin') }) test('admin approval publishes a pending-review event exactly once', async ({ page }) => { const requests = await mockReviewEndpoints(page) await page.goto('/manage-events/event-1') await expect(page.getByRole('button', { name: 'تأیید و انتشار' })).toBeEnabled() await page.getByRole('button', { name: 'تأیید و انتشار' }).click() await page.getByRole('button', { name: 'تأیید' }).click() await expect.poll(() => requests).toEqual([{ path: '/api/v1/admin/events/event-1/approve', payload: null }]) await expect(page.getByRole('button', { name: 'تأیید و انتشار' })).toHaveCount(0) await expect(page.getByRole('button', { name: 'رد' })).toHaveCount(0) }) test('admin rejection requires a reason and marks the event as rejected', async ({ page }) => { const requests = await mockReviewEndpoints(page) await page.goto('/manage-events/event-1') await page.getByRole('button', { name: 'رد' }).click() const reject = page.getByRole('button', { name: 'رد رویداد', exact: true }) await expect(reject).toBeDisabled() await page.getByLabel('دلیل رد').fill(' زمان و مکان رویداد را اصلاح کنید ') await expect(reject).toBeEnabled() await reject.click() await expect .poll(() => requests) .toEqual([ { path: '/api/v1/admin/events/event-1/reject', payload: { rejectionReason: 'زمان و مکان رویداد را اصلاح کنید' }, }, ]) await expect(page.getByRole('button', { name: 'تأیید برای انتشار' })).toBeEnabled() await expect(page.getByRole('button', { name: 'رد' })).toHaveCount(0) })