feat(FN-3368): tighten research view test coverage and resolve dashboard ty

This merge introduces an eval automation domain store with persistence schema and a plugin dashboard view registry (FN-3512/FN-3513), adds scheduled eval batch architecture documentation (FN-3388), and includes substantial test coverage for Research routes and hooks (FN-3368 steps 1-3). The branch a

Fusion-Task-Id: FN-3368
This commit is contained in:
Fusion
2026-05-05 13:05:57 -07:00
committed by gsxdsm
parent c36d30f517
commit 0aef085f13
10 changed files with 205 additions and 13 deletions

View File

@@ -85,6 +85,7 @@ function createMockStore(options?: {
}
return { filename: "RR-1-finding-1.md" };
}),
appendAgentLog: vi.fn(async () => undefined),
log: vi.fn(async () => undefined),
};
}
@@ -197,10 +198,26 @@ describe("research-routes", () => {
expect.objectContaining({
source: expect.objectContaining({
sourceType: "research",
sourceMetadata: expect.objectContaining({ runId: "RR-1", findingId: "finding-1" }),
sourceRunId: "RR-1",
sourceMetadata: expect.objectContaining({ runId: "RR-1", findingId: "finding-1", documentKey: "research-RR-1" }),
}),
}),
);
expect(store.upsertTaskDocument).toHaveBeenCalledWith(
"FN-1",
expect.objectContaining({
key: "research-RR-1",
author: "research",
metadata: expect.objectContaining({ runId: "RR-1", findingId: "finding-1" }),
}),
);
expect(store.appendAgentLog).toHaveBeenCalledWith(
"FN-1",
expect.stringContaining("Task created from research finding finding-1 in run RR-1"),
"text",
"research-task-integration",
"executor",
);
});
it("enriches existing task from finding and returns revision", async () => {
@@ -221,6 +238,21 @@ describe("research-routes", () => {
expect(response.body.taskId).toBe("FN-42");
expect(response.body.documentKey).toBe("research-RR-1");
expect(response.body.revision).toBe(1);
expect(store.upsertTaskDocument).toHaveBeenCalledWith(
"FN-42",
expect.objectContaining({
key: "research-RR-1",
author: "research",
metadata: expect.objectContaining({ runId: "RR-1", findingId: "finding-1" }),
}),
);
expect(store.appendAgentLog).toHaveBeenCalledWith(
"FN-42",
expect.stringContaining("Task enriched from research finding finding-1 in run RR-1"),
"text",
"research-task-integration",
"executor",
);
});
it("skips duplicate attachment when original name already exists", async () => {
@@ -401,6 +433,29 @@ describe("research-routes", () => {
expect(response.body.error).toContain("attachExport must be a boolean");
});
it("returns 400 when create payload title/description are empty strings", async () => {
const store = createMockStore();
const app = express();
app.use(express.json());
app.use(createResearchRouter(store as any));
const response = await performRequest(
app,
"POST",
"/runs/RR-1/findings/finding-1/task",
JSON.stringify({ title: " ", description: " " }),
{ "content-type": "application/json" },
);
expect(response.status).toBe(201);
expect(store.createTask).toHaveBeenCalledWith(
expect.objectContaining({
title: "Research: Finding One",
description: expect.stringContaining("Important actionable result."),
}),
);
});
it("returns 400 when attachment exceeds size limit", async () => {
const app = express();
app.use(express.json());