-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdashboard-routes.test.ts
More file actions
91 lines (84 loc) · 3.54 KB
/
Copy pathdashboard-routes.test.ts
File metadata and controls
91 lines (84 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import { CommandCenterDashboard } from "../src/core/dashboard.js";
import { EventStore } from "../src/history/event-store.js";
describe("dashboard route coverage", () => {
let testDir: string;
let repoDir: string;
let store: EventStore;
beforeEach(() => {
testDir = fs.mkdtempSync(path.join(os.tmpdir(), "dashboard-routes-"));
repoDir = path.join(testDir, "repo");
fs.mkdirSync(repoDir);
fs.writeFileSync(path.join(repoDir, "package.json"), JSON.stringify({ scripts: { test: "vitest" } }));
process.env.PROMPT_REFINER_GLOBAL_DIR = path.join(testDir, "global");
(EventStore as any).instance = null;
store = EventStore.getInstance();
});
afterEach(() => {
store.close();
delete process.env.PROMPT_REFINER_GLOBAL_DIR;
fs.rmSync(testDir, { recursive: true, force: true });
});
it("serves state, timeline, commits, lessons, templates, tournaments, health, and HTML", async () => {
const repoId = store.ensureRepository(repoDir).id;
store.recordPrompt({ id: "prompt", repo_id: repoId, client: "test", raw_prompt: "Implement feature" });
store.recordCommit({
id: "commit",
repo_id: repoId,
sha: "abc",
message: "feat: test",
committed_at: new Date().toISOString(),
});
store.recordLesson({
id: "lesson",
repo_id: repoId,
lesson_type: "quality",
title: "Lesson",
summary: "Summary",
confidence: "high",
source: "test",
});
store.recordTemplate({
id: "template",
repo_id: repoId,
category: "feature",
title: "Template",
template_text: "Implement it.",
usage_notes: "",
source_type: "test",
success_score: 80,
});
store.recordTournament({
id: "tournament",
repo_id: repoId,
baseline_prompt: "baseline",
variant_a: "variant a",
variant_b: "variant b",
winner_observed: "A",
details_json: "{}",
});
const app = CommandCenterDashboard.createApp(repoDir);
for (const route of ["/api/state", "/api/timeline", "/api/commits", "/api/lessons", "/api/templates", "/api/tournaments", "/api/health", "/"]) {
const response = await app.request(route);
expect(response.status, route).toBe(200);
}
const fallback = await app.request(`/api/state?project=${encodeURIComponent(path.join(testDir, "not-visible"))}`);
expect((await fallback.json() as any).selectedPath).toBe(path.resolve(repoDir));
});
it("validates every review mutation boundary", async () => {
const app = CommandCenterDashboard.createApp(repoDir);
const request = (route: string, body = "{}", headers: Record<string, string> = { "content-type": "application/json", origin: "http://localhost" }) =>
app.request(route, { method: "POST", headers, body });
expect((await request("/api/review/unsupported/id", JSON.stringify({ decision: "approve" }))).status).toBe(400);
expect((await request("/api/review/lesson/id", "{}", { origin: "http://localhost" })).status).toBe(415);
expect((await request("/api/review/lesson/id", "{")).status).toBe(400);
expect((await request("/api/review/lesson/id", JSON.stringify({ decision: "approve" }), {
"content-type": "application/json",
origin: "https://attacker.example",
})).status).toBe(403);
expect((await request(`/api/review/lesson/${"x".repeat(201)}`, JSON.stringify({ decision: "approve" }))).status).toBe(400);
});
});