import { test, expect } from "@playwright/test"; const ADMIN_USER = process.env.ADMIN_TEST_USERNAME || "admin"; const ADMIN_PASS = process.env.ADMIN_TEST_PASSWORD || "admin123"; async function checkBackendAvailable(): Promise { try { const ctrl = new AbortController(); const id = setTimeout(() => ctrl.abort(), 2000); const res = await fetch("http://localhost:3001/api/health", { signal: ctrl.signal }); clearTimeout(id); return res.ok; } catch { return false; } } async function uiLogin(page: Parameters[0]): Promise { try { await page.goto("/login"); await page.fill("input#username", ADMIN_USER); await page.fill("input#password", ADMIN_PASS); await page.click('button[type="submit"]'); await page.waitForURL((url) => !url.toString().includes("/login"), { timeout: 8000 }); return true; } catch { return false; } } test.describe("API Token 管理 API", () => { test("GET /api/api-tokens 返回 Token 列表", async ({ page }) => { if (!await checkBackendAvailable()) { test.skip(); } if (!await uiLogin(page)) { test.skip(); } const res = await page.request.get("/api/api-tokens"); expect(res.status()).toBe(200); const data = await res.json(); expect(Array.isArray(data.tokens)).toBe(true); }); test("POST /api/api-tokens 创建新 Token", async ({ page }) => { if (!await checkBackendAvailable()) { test.skip(); } if (!await uiLogin(page)) { test.skip(); } const tokenName = `test_token_${Date.now()}`; const res = await page.request.post("/api/api-tokens", { data: { name: tokenName, permissions: ["platform:read"], expiresInDays: 7, }, }); expect(res.status()).toBe(201); const data = await res.json(); expect(data).toHaveProperty("id"); expect(data).toHaveProperty("token"); expect(data.name).toBe(tokenName); if (data.id) { await page.request.delete(`/api/api-tokens/${data.id}`); } }); test("POST /api/api-tokens Token 名称为空返回 400", async ({ page }) => { if (!await checkBackendAvailable()) { test.skip(); } if (!await uiLogin(page)) { test.skip(); } const res = await page.request.post("/api/api-tokens", { data: { name: "", permissions: [] }, }); expect(res.status()).toBe(400); }); test("DELETE /api/api-tokens/[id] 无效 ID 返回 400", async ({ page }) => { if (!await checkBackendAvailable()) { test.skip(); } if (!await uiLogin(page)) { test.skip(); } const res = await page.request.delete("/api/api-tokens/not_a_number"); expect(res.status()).toBe(400); }); }); test.describe("认证登出 API", () => { test("POST /api/auth/logout 登出成功", async ({ page }) => { if (!await checkBackendAvailable()) { test.skip(); } if (!await uiLogin(page)) { test.skip(); } const res = await page.request.post("/api/auth/logout"); expect(res.status()).toBe(200); const data = await res.json(); expect(data.success).toBe(true); }); test("POST /api/auth/logout 未登录返回 401", async ({ request }) => { const res = await request.post("/api/auth/logout"); expect(res.status()).toBe(401); }); }); test.describe("健康检查 API", () => { test("GET /api/health 无需认证返回 ok", async ({ page }) => { const res = await page.request.get("/api/health"); expect(res.status()).toBe(200); const data = await res.json(); expect(data.status).toBe("ok"); }); });