merge: integrate WP6-01 dependency for TASK-WP6-04
# Conflicts: # apps/web/src/admin-models.tsx # apps/web/src/admin-users.tsx # apps/web/src/main.tsx # package.json # scripts/lib/openapi.mjs
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
import { mkdirSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
import { expect, test, type Page } from "@playwright/test";
|
||||
import { createServer, type ViteDevServer } from "vite";
|
||||
|
||||
import { adminOverviewFixture } from "../fixtures/wp6-01-admin-overview.js";
|
||||
|
||||
let vite: ViteDevServer;
|
||||
let webUrl: string;
|
||||
|
||||
const adminSession = {
|
||||
acknowledged_private_content_notice_version: null,
|
||||
admin: { role: "super_admin", status: "active", user_id: "00000000-0000-4000-8000-000000000601" },
|
||||
audience: "admin",
|
||||
authenticated: true,
|
||||
csrf_token: "csrf-admin-shell-fixture-000000000000000000000000000000000",
|
||||
current_private_content_notice_version: null,
|
||||
expires_at: "2026-09-02T09:30:00.000Z",
|
||||
notice_acknowledged: false,
|
||||
};
|
||||
|
||||
const navigation = [
|
||||
["总览", "/admin"],
|
||||
["用户与点数", "/admin/users"],
|
||||
["邀请码", "/admin/invites"],
|
||||
["模型", "/admin/models"],
|
||||
["素材", "/admin/assets"],
|
||||
["内部预览", "/admin/preview"],
|
||||
["生成记录", "/admin/generations"],
|
||||
["服务与存储", "/admin/services-storage"],
|
||||
["审计", "/admin/audit"],
|
||||
] as const;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
vite = await createServer({
|
||||
configFile: resolve("apps/web/vite.config.ts"),
|
||||
root: resolve("apps/web"),
|
||||
server: { host: "127.0.0.1", port: 0 },
|
||||
});
|
||||
await vite.listen();
|
||||
const address = vite.httpServer?.address();
|
||||
if (!address || typeof address === "string") throw new Error("Vite did not expose a test port.");
|
||||
webUrl = `http://127.0.0.1:${address.port}`;
|
||||
});
|
||||
|
||||
test.afterAll(async () => vite.close());
|
||||
|
||||
async function routeActiveAdmin(page: Page) {
|
||||
await page.route("**/api/v1/admin-auth/session", (route) => route.fulfill({
|
||||
body: JSON.stringify(adminSession),
|
||||
contentType: "application/json",
|
||||
status: 200,
|
||||
}));
|
||||
await page.route("**/api/v1/admin/overview", (route) => route.fulfill({
|
||||
body: JSON.stringify(adminOverviewFixture),
|
||||
contentType: "application/json",
|
||||
status: 200,
|
||||
}));
|
||||
}
|
||||
|
||||
test("TDD-WP6-ADM-001-role-and-summary renders the protected nine-entry admin shell", async ({ page }) => {
|
||||
const requests: string[] = [];
|
||||
page.on("request", (request) => requests.push(request.url()));
|
||||
await routeActiveAdmin(page);
|
||||
await page.goto(`${webUrl}/admin`);
|
||||
|
||||
await expect(page.getByRole("heading", { level: 2, name: "运营总览" })).toBeVisible();
|
||||
const sidebar = page.getByRole("navigation", { name: "后台主导航" });
|
||||
await expect(sidebar).toBeVisible();
|
||||
for (const [name, href] of navigation) {
|
||||
await expect(sidebar.getByRole("link", { name, exact: true })).toHaveAttribute("href", href);
|
||||
}
|
||||
expect(Math.round((await sidebar.boundingBox())?.width ?? 0)).toBe(216);
|
||||
await expect(page.getByText("4 / 10", { exact: true })).toBeVisible();
|
||||
await expect(page.getByText("待人工核对 1", { exact: true })).toBeVisible();
|
||||
await expect(page.getByText("85.0%", { exact: true })).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: "有异常", exact: true })).toBeVisible();
|
||||
await expect(page.locator("body")).not.toContainText(/forbidden|example\.invalid|api[_ -]?key|完整提示词/i);
|
||||
expect(requests.some((url) => /prompt|private-content|image-content/i.test(url))).toBe(false);
|
||||
|
||||
const evidenceRoot = process.env.DADA_EVIDENCE_DIR_ADMIN;
|
||||
if (evidenceRoot) {
|
||||
const screenshotDirectory = resolve(evidenceRoot, "screenshots");
|
||||
mkdirSync(screenshotDirectory, { recursive: true });
|
||||
await page.screenshot({ fullPage: true, path: resolve(screenshotDirectory, "admin-overview.png") });
|
||||
}
|
||||
});
|
||||
|
||||
test("TDD-WP6-ADM-001-role-and-summary keeps ordinary and preview sessions outside admin", async ({ page }) => {
|
||||
let overviewCalls = 0;
|
||||
await page.route("**/api/v1/admin-auth/session", (route) => route.fulfill({
|
||||
body: JSON.stringify({ error: { code: "AUTH_SESSION_INVALID", subject: "preview_user" } }),
|
||||
contentType: "application/json",
|
||||
status: 401,
|
||||
}));
|
||||
await page.route("**/api/v1/admin/overview", (route) => {
|
||||
overviewCalls += 1;
|
||||
return route.fulfill({ body: "null", contentType: "application/json", status: 401 });
|
||||
});
|
||||
|
||||
await page.goto(`${webUrl}/admin`);
|
||||
await expect(page).toHaveURL(`${webUrl}/admin/login`);
|
||||
await expect(page.getByRole("heading", { name: "管理员邮箱验证码登录" })).toBeVisible();
|
||||
expect(overviewCalls).toBe(0);
|
||||
await expect(page.getByText("DADA ADMIN", { exact: true })).toHaveCount(0);
|
||||
const evidenceRoot = process.env.DADA_EVIDENCE_DIR_ADMIN;
|
||||
if (evidenceRoot) {
|
||||
const screenshotDirectory = resolve(evidenceRoot, "screenshots");
|
||||
mkdirSync(screenshotDirectory, { recursive: true });
|
||||
await page.screenshot({ fullPage: true, path: resolve(screenshotDirectory, "admin-denied.png") });
|
||||
}
|
||||
});
|
||||
|
||||
test("TDD-WP6-ADM-001-role-and-summary ejects a disabled admin when the session is rechecked", async ({ page }) => {
|
||||
let active = true;
|
||||
await page.route("**/api/v1/admin-auth/session", (route) => route.fulfill(active ? {
|
||||
body: JSON.stringify(adminSession),
|
||||
contentType: "application/json",
|
||||
status: 200,
|
||||
} : {
|
||||
body: JSON.stringify({ error: { code: "AUTH_SESSION_INVALID" } }),
|
||||
contentType: "application/json",
|
||||
status: 401,
|
||||
}));
|
||||
await page.route("**/api/v1/admin/overview", (route) => route.fulfill({
|
||||
body: JSON.stringify(adminOverviewFixture),
|
||||
contentType: "application/json",
|
||||
status: 200,
|
||||
}));
|
||||
await page.goto(`${webUrl}/admin`);
|
||||
await expect(page.getByRole("heading", { level: 2, name: "运营总览" })).toBeVisible();
|
||||
|
||||
active = false;
|
||||
await page.evaluate(() => window.dispatchEvent(new Event("dada:session-invalid")));
|
||||
await expect(page).toHaveURL(`${webUrl}/admin/login`);
|
||||
});
|
||||
Reference in New Issue
Block a user