import type { Page, Route } from '@playwright/test'; export type MockAdmin = { id: string; email: string; nickname: string; role: string; language: string; avatar_url: string | null; }; export const MOCK_ADMIN: MockAdmin = { id: 'admin-e2e-1', email: 'e2e@eventhub.local', nickname: 'E2E Admin', role: 'superadmin', language: 'ru', avatar_url: null, }; async function json(route: Route, status: number, body: unknown, headers: Record = {}) { await route.fulfill({ status, contentType: 'application/json', headers, body: JSON.stringify(body), }); } type MockOptions = { user?: MockAdmin; }; /** Default admin API mocks for Control Center shell / login. */ export async function installAdminApiMocks(page: Page, options: MockOptions = {}) { let currentUser: MockAdmin = { ...MOCK_ADMIN, ...options.user }; await page.route('**/v1/admin/**', async (route) => { const req = route.request(); const method = req.method(); const url = new URL(req.url()); const path = url.pathname; if (method === 'POST' && path.endsWith('/v1/admin/login')) { const payload = req.postDataJSON() as { email?: string; password?: string }; if (payload?.email === MOCK_ADMIN.email && payload?.password === 'e2e-pass') { await json(route, 200, { token: 'e2e-access-token', refresh_token: 'e2e-refresh-token', user: currentUser, }); return; } await json(route, 401, { error: 'invalid_credentials' }); return; } if (method === 'GET' && path.endsWith('/v1/admin/me')) { await json(route, 200, currentUser); return; } if (method === 'PUT' && path.endsWith('/v1/admin/me')) { const payload = (req.postDataJSON() || {}) as Partial; currentUser = { ...currentUser, ...payload }; await json(route, 200, currentUser); return; } if (method === 'GET' && path.endsWith('/v1/admin/health')) { await json(route, 200, { status: 'ok', service: 'eventhub', version: '0.1', git_sha: 'e2etestsha000', built_at: '2026-07-14T00:00:00Z', }); return; } if (method === 'GET' && path.endsWith('/v1/admin/stats')) { await json(route, 200, { users_total: 10, events_total: 5, reviews_total: 2, calendars_total: 3, tickets_total: 1, tickets_open: 1, reports_total: 2, reports_pending: 1, reports_reviewed: 1, avg_report_resolution_h: 1.5, avg_ticket_resolution_h: 2, events_by_day: [], registrations_by_day: [], reviews_by_day: [], reports_by_day: [], tickets_by_day: [], subscriptions_by_day: [], }); return; } if (method === 'GET' && path.includes('/v1/admin/nodes/metrics')) { await json(route, 200, { nodes: [] }); return; } if (method === 'GET') { await json(route, 200, [], { 'X-Total-Count': '0' }); return; } await json(route, 200, { ok: true }); }); }