import { test, expect } from "./fixtures"; import { E2E_ADMIN } from "./global-setup"; import { freshAccount, loginViaUi, smsAndLogin, pickBottle } from "./helpers"; test.describe("admin governance", () => { test("admin login is guarded, reports are resolved with audit, sanction applies", async ({ browser, request, }) => { // 预置管理员账号(global-setup),用 demo 登录拿到 accessToken const adminSession = await smsAndLogin(request, E2E_ADMIN); expect(adminSession.accessToken).toBeTruthy(); const adminHeaders = { authorization: `Bearer ${adminSession.accessToken}`, "content-type": "application/json", }; // 制造举报:Alice 投瓶,Bob 捞瓶回复后举报会话 const aliceAccount = freshAccount("147"); const ctxAlice = await browser.newContext(); const alicePage = await ctxAlice.newPage(); await loginViaUi(alicePage, aliceAccount); await alicePage.goto("/throw"); await alicePage .getByPlaceholder("写下你想让陌生人看到的话…") .fill(`治理测试会话 ${Date.now()}`); await alicePage.getByRole("button", { name: /扔进海里/ }).click(); await expect(alicePage.getByText(/瓶子已进入审核/)).toBeVisible(); const bobAccount = freshAccount("145"); const ctxBob = await browser.newContext(); const bobPage = await ctxBob.newPage(); await loginViaUi(bobPage, bobAccount); await bobPage.goto("/pick"); await pickBottle(bobPage); await bobPage.locator(".bottle-card textarea").fill("这条消息将被举报"); await bobPage.getByRole("button", { name: /回复并建立会话/ }).click(); await expect(bobPage).toHaveURL(/\/conversations\//, { timeout: 15_000 }); // Bob 举报该会话 await bobPage.getByRole("button", { name: /举报会话/ }).click(); await bobPage.getByRole("button", { name: "提交举报" }).click(); await expect(bobPage.getByText(/举报已提交审核/)).toBeVisible(); // 管理员查看待审举报并处置 const after = await request.get( "/api/v1/admin/reports?status=PENDING&limit=5", { headers: adminHeaders }, ); expect(after.ok()).toBeTruthy(); const afterBody = (await after.json()) as { data?: { items?: Array<{ id: string }> }; }; const pending = afterBody.data?.items ?? []; expect(pending.length).toBeGreaterThan(0); const report = pending[0]!; const resolve = await request.post( `/api/v1/admin/reports/${report.id}/resolve`, { headers: adminHeaders, data: { decision: "DISMISSED", resolution: "E2E 无违规" }, }, ); expect(resolve.ok()).toBeTruthy(); // 独立处罚:为 Bob 的公开 ID 施加警告 const aliceMe = await request.get("/api/v1/me", { headers: { authorization: `Bearer ${ (await smsAndLogin(request, aliceAccount)).accessToken }`, }, }); const aliceBody = (await aliceMe.json()) as { data?: { publicId?: string }; }; const publicId = aliceBody.data?.publicId; if (publicId) { const sanction = await request.post( `/api/v1/admin/accounts/${publicId}/sanctions`, { headers: adminHeaders, data: { type: "WARNING", reason: "E2E 处罚验证" }, }, ); expect(sanction.ok()).toBeTruthy(); } await ctxBob.close(); await ctxAlice.close(); }); test("non-admin user is forbidden from the admin workbench", async ({ page, }) => { const account = freshAccount("152"); await loginViaUi(page, account); await page.goto("/admin"); // 非管理员应被引导回独立管理员登录页并显示无权限 await expect(page).toHaveURL(/\/admin\/login/, { timeout: 15_000 }); await expect(page.getByText(/没有管理员权限/).first()).toBeVisible(); }); });