gitdataai/admin/tests/01-auth.spec.ts
ZhenYi fb91f5a6c5 feat(admin): add admin panel with billing alerts and model sync
- Add libs/api/admin with admin API endpoints:
  sync models, workspace credit, billing alert check
- Add workspace_alert_config model and alert service
- Add Session::no_op() for background tasks without user context
- Add admin/ Next.js admin panel (AI models, billing, workspaces, audit)
- Start billing alert background task every 30 minutes
2026-04-19 20:48:59 +08:00

67 lines
2.5 KiB
TypeScript

import { test, expect } from "@playwright/test";
const ADMIN_USER = process.env.ADMIN_TEST_USERNAME || "admin";
const ADMIN_PASS = process.env.ADMIN_TEST_PASSWORD || "admin123";
test.describe("认证模块", () => {
test("登录页面可访问且包含表单", async ({ page }) => {
await page.goto("/login");
// 表单使用 id 属性
await expect(page.locator("input#username")).toBeVisible();
await expect(page.locator("input#password")).toBeVisible();
await expect(page.locator('button[type="submit"]')).toBeVisible();
});
test("未登录访问受保护页面重定向到登录页", async ({ page }) => {
await page.goto("/dashboard");
await page.waitForURL(/\/login/, { timeout: 5000 });
expect(page.url()).toContain("/login");
});
test("无效凭据登录失败", async ({ page }) => {
await page.goto("/login");
await page.fill("input#username", "wronguser");
await page.fill("input#password", "wrongpass");
await page.click('button[type="submit"]');
// 等待错误提示出现
await page.waitForTimeout(2000);
const onLogin = page.url().includes("/login");
const hasError = await page.locator(".alert-error").count() > 0;
expect(onLogin || hasError).toBeTruthy();
});
test("GET /api/auth/me 未登录返回 401", async ({ request }) => {
const res = await request.get("/api/auth/me");
expect(res.status()).toBe(401);
});
test("GET /api/auth/me 登录后返回 user", async ({ page }) => {
// 使用 UI 登录
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 });
// 登录后 /api/auth/me 应返回 user
const res = await page.request.get("/api/auth/me");
expect(res.status()).toBe(200);
const data = await res.json();
expect(data).toHaveProperty("user");
expect(data.user).not.toBeNull();
});
test("POST /api/auth/login 无效凭据返回 4xx", async ({ request }) => {
const res = await request.post("/api/auth/login", {
data: { username: "invalid", password: "invalid" },
});
expect([400, 401]).toContain(res.status());
});
test("POST /api/auth/login 缺少参数返回 4xx", async ({ request }) => {
const res = await request.post("/api/auth/login", {
data: { username: "admin" },
});
expect([400, 401]).toContain(res.status());
});
});