import { beforeEach, describe, expect, it, vi } from "vitest"; import { GET as getDashboard } from "@/app/api/metrics/dashboard/route"; vi.mock("@/modules/metrics/collector", () => ({ getMetricsSnapshot: vi.fn(), })); vi.mock("@/workers/rpa/queue", () => ({ getQueueDepth: vi.fn(), })); vi.mock("@/lib/prisma", () => ({ prisma: { alertLog: { count: vi.fn(), }, }, })); import { getMetricsSnapshot } from "@/modules/metrics/collector"; import { prisma } from "@/lib/prisma"; import { getQueueDepth } from "@/workers/rpa/queue"; import { METRIC_COUNTER } from "@/lib/constants/metrics"; const ADMIN_HEADERS = { "x-auth-type": "admin", "x-user-id": "U_admin_demo", "x-user-role": "admin", }; const SERVICE_HEADERS = { "x-auth-type": "service", "x-customer-id": "CUST_001", "x-permissions": "", }; const SAMPLE_SNAPSHOT = { api_success_rate: 99.5, rpa_success_rate: 85, realtime_rate: 90, cache_hit_rate: 92, p95_latency_ms: 12_000, latency_sample_count: 100, counters: { [METRIC_COUNTER.POST_TOTAL]: 1000, [METRIC_COUNTER.POST_DONE]: 995, [METRIC_COUNTER.CACHE_HIT_L1]: 200, [METRIC_COUNTER.CACHE_HIT_L2]: 720, [METRIC_COUNTER.RPA_TRIGGERED]: 80, [METRIC_COUNTER.RPA_DONE]: 68, [METRIC_COUNTER.DONE_TOTAL]: 995, [METRIC_COUNTER.DONE_REALTIME]: 896, }, }; beforeEach(() => { vi.clearAllMocks(); }); describe("GET /api/metrics/dashboard", () => { it("admin → 200 + GD-4 四指标", async () => { vi.mocked(getMetricsSnapshot).mockResolvedValue(SAMPLE_SNAPSHOT); vi.mocked(getQueueDepth).mockResolvedValue(3); vi.mocked(prisma.alertLog.count).mockResolvedValue(5); const response = await getDashboard( new Request("http://localhost/api/metrics/dashboard", { headers: ADMIN_HEADERS, }), ); const json = await response.json(); expect(response.status).toBe(200); expect(json.code).toBe(0); expect(json.data.api_success_rate).toBe(99.5); expect(json.data.rpa_success_rate).toBe(85); expect(json.data.realtime_rate).toBe(90); expect(json.data.cache_hit_rate).toBe(92); expect(json.data.p95_latency_ms).toBe(12_000); expect(json.data.queue_depth).toBe(3); expect(json.data.open_alerts_count).toBe(5); }); it("非 admin → 403", async () => { const response = await getDashboard( new Request("http://localhost/api/metrics/dashboard", { headers: SERVICE_HEADERS, }), ); expect(response.status).toBe(403); expect(getMetricsSnapshot).not.toHaveBeenCalled(); }); });