feat: add initial situation graph orchestration
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const mockStartCase = vi.fn();
|
||||
|
||||
vi.mock("@/lib/graph/orchestrator.js", () => ({
|
||||
startCase: (...args) => mockStartCase(...args),
|
||||
}));
|
||||
|
||||
describe("app/api/cases/start route", () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("delegates request body to the orchestrator", async () => {
|
||||
mockStartCase.mockResolvedValue({
|
||||
success: true,
|
||||
situationGraph: { nodes: [{ id: "n1" }], edges: [] },
|
||||
selectedQuestion: null,
|
||||
diagnostics: {},
|
||||
});
|
||||
|
||||
const { POST } = await import("@/app/api/cases/start/route.js");
|
||||
const request = new Request("http://localhost/api/cases/start", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ scenario: "Scenario text" }),
|
||||
headers: { "content-type": "application/json" },
|
||||
});
|
||||
|
||||
await POST(request);
|
||||
|
||||
expect(mockStartCase).toHaveBeenCalledWith({ scenario: "Scenario text" });
|
||||
});
|
||||
|
||||
it("returns 200 on success", async () => {
|
||||
mockStartCase.mockResolvedValue({
|
||||
success: true,
|
||||
situationGraph: { nodes: [{ id: "n1" }], edges: [] },
|
||||
selectedQuestion: null,
|
||||
diagnostics: {},
|
||||
});
|
||||
|
||||
const { POST } = await import("@/app/api/cases/start/route.js");
|
||||
const response = await POST(
|
||||
new Request("http://localhost/api/cases/start", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ scenario: "Scenario text" }),
|
||||
headers: { "content-type": "application/json" },
|
||||
}),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
it("returns 400 for invalid request input", async () => {
|
||||
mockStartCase.mockResolvedValue({
|
||||
success: false,
|
||||
error: "Invalid start-case request",
|
||||
validationErrors: [{ message: "Required" }],
|
||||
statusCode: 400,
|
||||
});
|
||||
|
||||
const { POST } = await import("@/app/api/cases/start/route.js");
|
||||
const response = await POST(
|
||||
new Request("http://localhost/api/cases/start", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({}),
|
||||
headers: { "content-type": "application/json" },
|
||||
}),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(400);
|
||||
await expect(response.json()).resolves.toMatchObject({
|
||||
success: false,
|
||||
error: "Invalid start-case request",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns provider/internal failures as 5xx without stack traces", async () => {
|
||||
mockStartCase.mockResolvedValue({
|
||||
success: false,
|
||||
error: "Provider unavailable",
|
||||
diagnostics: { modelName: "llama3" },
|
||||
statusCode: 502,
|
||||
});
|
||||
|
||||
const { POST } = await import("@/app/api/cases/start/route.js");
|
||||
const response = await POST(
|
||||
new Request("http://localhost/api/cases/start", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ scenario: "Scenario text" }),
|
||||
headers: { "content-type": "application/json" },
|
||||
}),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(502);
|
||||
await expect(response.json()).resolves.not.toHaveProperty("stack");
|
||||
});
|
||||
|
||||
it("returns structured 500 on malformed JSON", async () => {
|
||||
const { POST } = await import("@/app/api/cases/start/route.js");
|
||||
const request = {
|
||||
json: vi.fn().mockRejectedValue(new Error("Unexpected token")),
|
||||
};
|
||||
|
||||
const response = await POST(request);
|
||||
|
||||
expect(response.status).toBe(500);
|
||||
await expect(response.json()).resolves.toMatchObject({
|
||||
success: false,
|
||||
error: "Internal server error",
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user