255 lines
8.8 KiB
React
255 lines
8.8 KiB
React
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);
|
|
});
|
|
});
|