feat(confidence-engine): clarify understanding during Done refresh
This commit is contained in:
@@ -2147,4 +2147,96 @@ describe("ReasoningWorkspace UI", () => {
|
||||
expect(nextResult.selectedQuestion.question).toBe("What denominator is being used for the complaint rate?");
|
||||
expect(nextResult.diagnostics.modelName).toBe("test");
|
||||
});
|
||||
|
||||
// ── CU synthesis loading overlay (wired to visible PostAnalyse CU path) ─────────────────────────────
|
||||
|
||||
// Uses renderToStaticMarkup + ReasoningWorkspace.initialPostAnalyseStatus test init prop
|
||||
// to exercise Path A (initial-reflection CU with shimmer overlay) without effect lifecycle.
|
||||
// initialPostAnalyseStatus="success" lets us render the same card that useEffect produces
|
||||
// in production, proving cuSynthesisLoading reaches the actually visible CU card.
|
||||
|
||||
function createCUOverlayProps(cuSynthesisLoading) {
|
||||
return {
|
||||
status: "success",
|
||||
updateStatus: "idle",
|
||||
initialPostAnalyseStatus: "success",
|
||||
currentUnderstanding: "We have identified a key question to investigate further.",
|
||||
cuSynthesisLoading,
|
||||
result: makeWorkspaceResult({
|
||||
situationGraph: {
|
||||
...makeWorkspaceResult().situationGraph,
|
||||
activeUnknownNodeId: null,
|
||||
nodes: makeWorkspaceResult().situationGraph.nodes.map((n) =>
|
||||
n.id === "n-unknown" ? { ...n, status: "resolved", value: "the denominator is total units sold" } : n,
|
||||
),
|
||||
resolvedNodeIds: ["n-unknown"],
|
||||
},
|
||||
}),
|
||||
answer: "",
|
||||
setAnswer: vi.fn(),
|
||||
onAnswerSubmit: vi.fn(),
|
||||
};
|
||||
}
|
||||
|
||||
it("does NOT show CU synthesis overlay when cuSynthesisLoading is false", () => {
|
||||
const html = renderToStaticMarkup(<ReasoningWorkspace {...createCUOverlayProps(false)} />);
|
||||
|
||||
// The visible PostAnalyse CU card renders on Path A (postAnalyseStatus === "success")
|
||||
expect(html).toContain("Current Understanding");
|
||||
// But cu-skeleton-overlay class MUST NOT be present
|
||||
expect(html).not.toContain("cu-skeleton-overlay");
|
||||
});
|
||||
|
||||
it("shows CU skeleton overlay on the ACTUAL VISIBLE PostAnalyse CU card when cuSynthesisLoading is true", () => {
|
||||
const html = renderToStaticMarkup(<ReasoningWorkspace {...createCUOverlayProps(true)} />);
|
||||
|
||||
// ── Prove the skeleton reaches Path A (the authoritative visible CU) ──────────
|
||||
// initialPostAnalyseStatus="success" puts ReasoningWorkspace in the same state
|
||||
// as after useEffect fires → Path A renders (initial-reflection CU).
|
||||
// The skeleton overlay MUST appear there — this assertion would fail if cuSynthesisLoading
|
||||
// were wired only to the old grid path (which is on Path B).
|
||||
|
||||
// role="status" proves the overlay's accessible status container renders
|
||||
expect(html).toContain("role=\"status\"");
|
||||
// "Clarifying your current understanding…" message visible
|
||||
expect(html).toContain("Clarifying your current understanding…");
|
||||
// The skeleton overlay class is present on Path A (not dead on Path B)
|
||||
expect(html).toContain("cu-skeleton-overlay");
|
||||
// Exactly 7 skeleton line placeholders (strong skeleton requirement)
|
||||
// cu-skeleton-lines parent class contains cu-skeleton-line as prefix substring,
|
||||
// so count = 7 bars + 1 parent = 8 occurrences → split gives 9 parts
|
||||
expect(html.split("cu-skeleton-line").length).toBe(9);
|
||||
// Old CU text remains structurally available behind the overlay
|
||||
expect(html).toContain("We have identified a key question to investigate further.");
|
||||
});
|
||||
|
||||
it("proves skeleton is on Path A not the grid CU by verifying PostAnalyse CU header when cuSynthesisLoading=true", () => {
|
||||
const html = renderToStaticMarkup(<ReasoningWorkspace {...createCUOverlayProps(true)} />);
|
||||
|
||||
// The PostAnalyse visible CU header and skeleton are present
|
||||
expect(html).toContain("Current Understanding");
|
||||
expect(html).toContain("cu-skeleton-overlay");
|
||||
});
|
||||
|
||||
it("proves skeleton visible alongside clarified question — pending state does not block graph transition", () => {
|
||||
// ── Pending-state assertion: cuSynthesisLoading=true AND resolved node coexist ─
|
||||
// The overlay (skeleton) must be visible WHILE the canonical graph already
|
||||
// reflects the clarification. This proves the immediate move is NOT gated by
|
||||
// async reconsideration completion.
|
||||
const html = renderToStaticMarkup(<ReasoningWorkspace {...createCUOverlayProps(true)} />);
|
||||
|
||||
// Skeleton present → CU being regenerated
|
||||
expect(html).toContain("cu-skeleton-overlay");
|
||||
// Target question already in Questions we have clarified (resolvedNodeIds)
|
||||
expect(html).toContain("Questions we have clarified");
|
||||
// Question "Complaint rate denominator" moved into the resolved section
|
||||
expect(html).toContain("Complaint rate denominator");
|
||||
});
|
||||
|
||||
it("proves skeleton loading surface blocks old CU — opaque gray background", () => {
|
||||
const html = renderToStaticMarkup(<ReasoningWorkspace {...createCUOverlayProps(true)} />);
|
||||
|
||||
// The overlay uses a strong bg-gray-50 blocking surface (not transparent)
|
||||
expect(html).toContain("bg-gray-50");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user