Files
confidence-engine/tests/ui/investigation-overview-ui.test.jsx
T

238 lines
8.3 KiB
React

import { describe, expect, it } from "vitest";
import React from "react";
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
vi.mock("next/navigation", () => ({
useRouter: () => ({ push: () => {} }),
}));
// ---------------------------------------------------------------------------
// Route-level assertions for v0.55 architecture
// Portfolio = /index ; Investigation Report = dedicated page
// ---------------------------------------------------------------------------
function makeSnapshot(overrides = {}) {
const situationGraph = {
evidence: [
{ id: "e1", claim: "Complaints rose.", type: "finding" },
{ id: "e2", claim: "Production increased.", type: "finding" },
],
reconstruction: {
plausibleInterpretations: ["The denominator may have been narrowed."],
},
};
return {
scenario: "Complaints increased while production increased.",
situationGraph,
selectedQuestion: null,
summary: "Production quality declined.",
updatedAt: new Date().toISOString(),
schemaVersion: 1,
investigationReport: null,
findings: [],
...overrides,
};
}
describe("Portfolio page (v0.55 route architecture)", () => {
let Portfolio;
beforeAll(async () => {
const mod = await import("@/app/page.jsx");
Portfolio = mod.default;
});
it("shows + Create new investigation when no investigation exists", async () => {
localStorage.clear();
render(React.createElement(Portfolio));
expect(await screen.findByText(/Create new investigation/i)).toBeInTheDocument();
expect(screen.queryByText(/Open investigation/i)).not.toBeInTheDocument();
});
it("shows Open investigation card when one persisted investigation exists", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(makeSnapshot()),
);
render(React.createElement(Portfolio));
expect(await screen.findByText(/Open investigation/i)).toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
it("shows View report only when a persisted report exists", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(
makeSnapshot({
investigationReport: {
understanding: "We understand complaints rose.",
hasPlausibleInterpretations: false,
},
}),
),
);
render(React.createElement(Portfolio));
expect(await screen.findByText(/View report/i)).toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
it("does not show View report when no report persists", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(makeSnapshot()),
);
render(React.createElement(Portfolio));
expect(screen.queryByText(/View report/i)).not.toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
});
describe("Investigation Report page (v0.55 route architecture)", () => {
let ReportPage;
beforeAll(async () => {
const mod = await import("@/app/investigations/[id]/report/page.jsx");
ReportPage = mod.default;
});
it("renders persisted report with Situation and What we understand", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(
makeSnapshot({
investigationReport: {
understanding: "We understand complaints rose alongside production increases.",
hasPlausibleInterpretations: false,
},
}),
),
);
render(React.createElement(ReportPage));
expect(await screen.findByText(/Investigation Report/i)).toBeInTheDocument();
expect(await screen.findByText(/Situation/i)).toBeInTheDocument();
expect(screen.getByText(/What we understand/i)).toBeInTheDocument();
expect(screen.getByText("We understand complaints rose alongside production increases.")).toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
it("does not show pending placeholder during pre-hydration", async () => {
render(React.createElement(ReportPage));
// During pre-hydration, the page should render Investigation Report title
// but NOT the "Report generation pending" placeholder (which is for post-hydration no-report)
const pending = await screen.findByText(/Investigation Report/i);
expect(pending).toBeInTheDocument();
});
it("shows skeleton after hydration when genuinely no report exists", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(makeSnapshot()),
);
render(React.createElement(ReportPage));
expect(await screen.findByText(/Investigation Report/i)).toBeInTheDocument();
// After hydration, if no report, skeleton should appear (not during pre-hydration)
const pending = await screen.findByText(/Report generation pending/i);
expect(pending).toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
it("conditionally renders What remains plausible only when hasPlausibleInterpretations is true", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(
makeSnapshot({
investigationReport: {
understanding: "Some understanding.",
hasPlausibleInterpretations: false,
plausibleInterpretations: "",
},
}),
),
);
render(React.createElement(ReportPage));
expect(await screen.findByText(/Investigation Report/i)).toBeInTheDocument();
expect(screen.queryByText(/What remains plausible/i)).not.toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
it("renders What remains plausible when hasPlausibleInterpretations is true", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(
makeSnapshot({
investigationReport: {
understanding: "Some understanding.",
hasPlausibleInterpretations: true,
plausibleInterpretations: "The denominator may have been narrowed.",
},
}),
),
);
render(React.createElement(ReportPage));
expect(await screen.findByText(/What remains plausible/i)).toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
it("renders Back to investigation link", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(
makeSnapshot({
investigationReport: {
understanding: "Some understanding.",
hasPlausibleInterpretations: false,
},
}),
),
);
render(React.createElement(ReportPage));
expect(await screen.findByText(/Back to investigation/i)).toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
it("renders Back to portfolio link", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(
makeSnapshot({
investigationReport: {
understanding: "Some understanding.",
hasPlausibleInterpretations: false,
},
}),
),
);
render(React.createElement(ReportPage));
expect(await screen.findByText(/Back to portfolio/i)).toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
it("shows skeleton loading state when no persisted report exists", async () => {
localStorage.setItem(
"confidence-engine-investigation",
JSON.stringify(makeSnapshot()),
);
render(React.createElement(ReportPage));
expect(await screen.findByText(/Investigation Report/i)).toBeInTheDocument();
// Skeleton should not have actual understanding content
expect(screen.queryByText(/Report generation pending/i)).toBeInTheDocument();
localStorage.removeItem("confidence-engine-investigation");
});
});
describe("Investigation page (v0.55 route architecture)", () => {
let InvestigationPage;
beforeAll(async () => {
const mod = await import("@/app/investigations/[id]/page.jsx");
InvestigationPage = mod.default;
});
it("renders Back to portfolio link", async () => {
render(React.createElement(InvestigationPage));
expect(await screen.findByText(/Back to portfolio/i)).toBeInTheDocument();
});
});