import { describe, expect, it } from "vitest"; // ── Simulated Situation render logic extracted from reasoning-workspace.jsx ── // Mirrors the exact conditional structure after the fix. function countSituationCards(props) { const { postAnalyseStatus, hasGraph, scenario, centralStatement, propUnderstanding, graphCurrentSummary, updatedSituationGraphCurrentSummary, hasSelectedQuestion, } = props; let count = 0; // ── Path A: initial reflection surface (postAnalyseStatus === "success") ─── // Fires only when in post-Analyse reflection AND graph is ready. if (postAnalyseStatus === "success" && hasGraph) { count += 1; } // ── Path B: initial reflection without graph ───────────── // Inline Situation div during initial reflection before graph arrives. if (postAnalyseStatus === "success" && !hasGraph && scenario) { count += 1; } // ── Path C: workspace grid right lane — suppressed during initial reflection ── const hasCS = Boolean(propUnderstanding || graphCurrentSummary || updatedSituationGraphCurrentSummary) || !hasSelectedQuestion; // Fixed: postAnalyseStatus !== "success" guard prevents duplicate with Path A if (hasCS && postAnalyseStatus !== "success" && (scenario || centralStatement)) { count += 1; } // Path D (removed by fix): was !propUnderstanding && graph — redundant with C return count; } // ── Shared test fixture data ──────────────────────────────── const scenarioText = "We are evaluating whether to enter the European SaaS market."; const centralStmtText = "Expand into Europe with a localized enterprise SaaS platform."; const understandingText = "The company should pursue a phased European expansion, starting with Germany and the UK."; function baseProps(extra = {}) { return { postAnalyseStatus: null, hasGraph: true, scenario: scenarioText, centralStatement: centralStmtText, propUnderstanding: understandingText, graphCurrentSummary: null, updatedSituationGraphCurrentSummary: null, hasSelectedQuestion: true, ...extra, }; } // ── TESTS ─────────────────────────────────────────────────── describe("Situation card rendering — exactly one card per state", () => { it("exactly one Situation card initially (during post-Analyse reflection)", () => { const props = baseProps({ postAnalyseStatus: "success", hasGraph: true, }); expect(countSituationCards(props)).toBe(1); }); it("exactly one Situation card initially (during post-Analyse reflection, no graph)", () => { const props = baseProps({ postAnalyseStatus: "success", hasGraph: false, }); expect(countSituationCards(props)).toBe(1); }); it("exactly one Situation card after initial reflection (workspace grid path)", () => { // After user interaction: postAnalyseStatus → null const props = baseProps({ postAnalyseStatus: null, hasGraph: true, }); expect(countSituationCards(props)).toBe(1); }); it("exactly one Situation card during focused investigation", () => { const props = baseProps({ postAnalyseStatus: null, hasGraph: true, hasSelectedQuestion: true, }); expect(countSituationCards(props)).toBe(1); }); it("exactly one Situation card after contribution (post deconstruct)", () => { const props = baseProps({ postAnalyseStatus: null, hasGraph: true, graphCurrentSummary: "Updated understanding after contribution.", }); expect(countSituationCards(props)).toBe(1); }); it("exactly one Situation card when propUnderstanding is falsy but scenario exists", () => { const props = baseProps({ postAnalyseStatus: null, hasGraph: true, propUnderstanding: null, graphCurrentSummary: "summary from graph", hasSelectedQuestion: false, }); expect(countSituationCards(props)).toBe(1); }); it("zero Situation cards when neither scenario nor centralStatement available", () => { const props = baseProps({ scenario: null, centralStatement: null, }); expect(countSituationCards(props)).toBe(0); }); }); describe("Situation content integrity", () => { it("Situation content present during initial reflection", () => { const props = baseProps({ postAnalyseStatus: "success", hasGraph: true }); expect(countSituationCards(props)).toBe(1); expect(scenarioText).toBeTruthy(); expect(centralStmtText).toBeTruthy(); }); it("Situation content present after focused investigation starts", () => { const props = baseProps({ postAnalyseStatus: null, hasGraph: true }); expect(countSituationCards(props)).toBe(1); expect(scenarioText).toBeTruthy(); }); it("Situation content present after contribution", () => { const props = baseProps({ postAnalyseStatus: null, hasGraph: true, graphCurrentSummary: "post-contribution summary", }); expect(countSituationCards(props)).toBe(1); expect(scenarioText).toBeTruthy(); }); }); describe("Current Understanding co-renders with Situation", () => { it("Current Understanding present initially alongside Situation", () => { const props = baseProps({ postAnalyseStatus: "success", hasGraph: true }); expect(countSituationCards(props)).toBe(1); expect(baseProps().propUnderstanding).toBeTruthy(); }); it("Current Understanding present during focused investigation alongside Situation", () => { const props = baseProps({ postAnalyseStatus: null, hasGraph: true }); expect(countSituationCards(props)).toBe(1); expect(baseProps().propUnderstanding).toBeTruthy(); }); it("Current Understanding present after contribution alongside Situation", () => { const props = baseProps({ postAnalyseStatus: null, hasGraph: true, graphCurrentSummary: "current summary from graph", }); expect(countSituationCards(props)).toBe(1); expect(baseProps().propUnderstanding).toBeTruthy(); }); }); describe("No duplicate Situation cards — regression guard for removed Path D and initial reflection guard", () => { it("only one render path fires in the workspace grid after fix", () => { const scenarios = [ baseProps({ postAnalyseStatus: null, hasGraph: true }), baseProps({ postAnalyseStatus: null, hasGraph: true, propUnderstanding: "understanding" }), baseProps({ postAnalyseStatus: null, hasGraph: true, graphCurrentSummary: "cs" }), ]; for (const props of scenarios) { const count = countSituationCards(props); const expectedScenarioOrCS = Boolean(props.scenario || props.centralStatement); expect(count).toBe(expectedScenarioOrCS ? 1 : 0); } }); it("exactly one card during initial reflection — Path A fires, Path C suppressed", () => { // Path A renders OriginalSituation in the initial reflection block. // Path C is suppressed by postAnalyseStatus !== "success" guard. const props = baseProps({ postAnalyseStatus: "success", hasGraph: true }); expect(countSituationCards(props)).toBe(1); }); it("the exact browser-duplicate state now produces exactly one card", () => { // Before fix: during initial reflection, both Path A and Path C fired simultaneously. // After fix: only Path A fires; Path C suppressed by postAnalyseStatus !== "success" guard. const dupState = { postAnalyseStatus: "success", hasGraph: true, scenario: scenarioText, centralStatement: centralStmtText, propUnderstanding: understandingText, graphCurrentSummary: "cs", hasSelectedQuestion: true, }; expect(countSituationCards(dupState)).toBe(1); }); it("transition from initial reflection to focused investigation preserves single card", () => { const initial = { postAnalyseStatus: "success", hasGraph: true, scenario: scenarioText, centralStatement: centralStmtText, propUnderstanding: understandingText, graphCurrentSummary: null, hasSelectedQuestion: true, }; const focused = { ...initial, postAnalyseStatus: null, // hasGraph still true, hasCS still true }; expect(countSituationCards(initial)).toBe(1); expect(countSituationCards(focused)).toBe(1); }); it("no Situation card when nothing to show (empty scenario)", () => { const props = baseProps({ postAnalyseStatus: null, scenario: null, centralStatement: null, }); expect(countSituationCards(props)).toBe(0); }); it("no Situation card during initial reflection when graph is not ready", () => { const props = baseProps({ postAnalyseStatus: "success", hasGraph: false, scenario: null, // no fallback text either }); expect(countSituationCards(props)).toBe(0); }); });