117 lines
3.5 KiB
TypeScript
117 lines
3.5 KiB
TypeScript
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<string, string> = {}) {
|
|
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<MockAdmin>;
|
|
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 });
|
|
});
|
|
}
|