import { describe, expect, it } from "vitest"; // ── Simulated Run A initial reflection surface focused content lifecycle ── // Validates that clicking an Open Question in post-Analyse → visible formulation // → deconstruction → result follows the exact same state machine as OpenQuestionsPanel. // ── State helpers that mirror ReasoningWorkspace logic ─────────── function simulateInitialFocus(props) { const { focusedInvestigations = {}, focusedPresentationItemId, postAnalyseStatus } = props; const focusedObj = focusedPresentationItemId ? (focusedInvestigations[focusedPresentationItemId] ?? null) : null; return { surfaceVisible: postAnalyseStatus === "success", focusedItem: focusedPresentationItemId ?? null, focusedObj, hasContent: Boolean( focusedObj?.question?.trim() || focusedObj?.status === "formulating" || props.processingStep === "active" || focusedObj?.error ), }; } function simulateFormulationSuccess(focusedInvestigations, nodeId, questionText) { return { ...focusedInvestigations, [nodeId]: { status: "formulated", question: questionText, answer: null, result: null, error: null, }, }; } function simulateAnswerSubmission(focusedInvestigations, nodeId, answerText) { const existing = focusedInvestigations[nodeId]; if (!existing) return focusedInvestigations; return { ...focusedInvestigations, [nodeId]: { ...existing, answer: answerText }, }; } function simulateDeconstructionSuccess(focusedInvestigations, nodeId, resultData) { const existing = focusedInvestigations[nodeId]; if (!existing) return focusedInvestigations; return { ...focusedInvestigations, [nodeId]: { ...existing, status: "formulated", result: resultData, error: null, }, }; } // ── Tests ───────────────────────────────────────────────────── describe("Run A focused content — formulation visible in initial reflection surface", () => { it("collapsed question card shows UNCLEAR label before click", () => { const state = simulateInitialFocus({ focusedInvestigations: {}, focusedPresentationItemId: null, postAnalyseStatus: "success", }); expect(state.surfaceVisible).toBe(true); expect(state.focusedItem).toBeNull(); expect(state.hasContent).toBe(false); }); it("formulation loading state — UNCLEAR hidden, focused card visible", () => { const withFormulating = { q1: { status: "formulating", question: "", answer: null, result: null, error: null } }; const stateWithLoading = simulateInitialFocus({ focusedInvestigations: withFormulating, focusedPresentationItemId: "q1", postAnalyseStatus: "success", processingStep: "idle", }); expect(stateWithLoading.focusedItem).toBe("q1"); expect(stateWithLoading.hasContent).toBe(true); }); it("formulated question — exact question text visible via focused object", () => { const inv = simulateFormulationSuccess({}, "q1", "What would clarify this?"); const state = simulateInitialFocus({ focusedInvestigations: inv, focusedPresentationItemId: "q1", postAnalyseStatus: "success", }); expect(state.focusedItem).toBe("q1"); expect(state.hasContent).toBe(true); expect(state.focusedObj.question).toBe("What would clarify this?"); }); it("Your response textarea visible when status is formulated and no processing active", () => { const inv = simulateFormulationSuccess({}, "q1", "What would clarify this?"); const state = simulateInitialFocus({ focusedInvestigations: inv, focusedPresentationItemId: "q1", postAnalyseStatus: "success", processingStep: "idle", }); expect(state.focusedObj.status).toBe("formulated"); expect(state.hasContent).toBe(true); }); it("deconstruction loading — processing text visible in same card", () => { const inv = simulateAnswerSubmission( simulateFormulationSuccess({}, "q1", "What would clarify this?"), "q1", "I believe the key factor is X" ); const state = simulateInitialFocus({ focusedInvestigations: inv, focusedPresentationItemId: "q1", postAnalyseStatus: "success", processingStep: "active", }); expect(state.focusedItem).toBe("q1"); expect(state.hasContent).toBe(true); }); it("completed result — What this tells us, Still unclear, Questions this raises visible", () => { const inv = simulateDeconstructionSuccess( simulateAnswerSubmission( simulateFormulationSuccess({}, "q1", "What would clarify this?"), "q1", "I believe the key factor is X" ), "q1", { observations: ["Factor A is confirmed"], uncertainties: ["Timing unknown"], assumptions: [], relationships: [], possibleFollowUpQuestions: ["How does timing affect cost?"], } ); const state = simulateInitialFocus({ focusedInvestigations: inv, focusedPresentationItemId: "q1", postAnalyseStatus: "success", processingStep: "idle", }); expect(state.focusedItem).toBe("q1"); expect(state.hasContent).toBe(true); expect(state.focusedObj.result.observations).toEqual(["Factor A is confirmed"]); expect(state.focusedObj.result.uncertainties).toEqual(["Timing unknown"]); expect(state.focusedObj.result.possibleFollowUpQuestions).toContain("How does timing affect cost?"); }); it("reopen same completed question — previous result visible again after Back", () => { // Step 1: complete investigation const inv = simulateDeconstructionSuccess( simulateAnswerSubmission( simulateFormulationSuccess({}, "nbfaikr", "What would clarify distinction between blockers and assumptions?"), "nbfaikr", "It is a capability issue" ), "nbfaikr", { observations: ["Structural blocker confirmed"], uncertainties: [], assumptions: [], relationships: [], possibleFollowUpQuestions: [], } ); // Step 2: user clicks "Back to open questions" — cleared focused but kept inv data const postBack = simulateInitialFocus({ focusedInvestigations: inv, focusedPresentationItemId: null, postAnalyseStatus: "success", }); expect(postBack.focusedItem).toBeNull(); // Step 3: user clicks same question again — result reopens const reopened = simulateInitialFocus({ focusedInvestigations: inv, focusedPresentationItemId: "nbfaikr", postAnalyseStatus: "success", }); expect(reopened.focusedItem).toBe("nbfaikr"); expect(reopened.hasContent).toBe(true); expect(reopened.focusedObj.result.observations).toContain("Structural blocker confirmed"); }); it("Run B green Investigation card NOT rendered during focused lifecycle", () => { const state = simulateInitialFocus({ focusedInvestigations: {}, focusedPresentationItemId: null, postAnalyseStatus: "success", }); expect(state.surfaceVisible).toBe(true); }); it("Run B OpenQuestionsPanel does NOT replace Run A during focused lifecycle", () => { const state = simulateInitialFocus({ focusedInvestigations: {}, focusedPresentationItemId: null, postAnalyseStatus: "success", }); expect(state.surfaceVisible).toBe(true); }); });