You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.5 KiB
95 lines
2.5 KiB
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();
|
|
});
|
|
});
|