fix(oracle-r4): validate selectedStepId across live refreshes
Oracle r4 'Watch Out For' caught a real edge case: if a backend graph changes shape while the scenarioId stays the same, the prior selectedStepId could survive the merge and point at a step that no longer exists. Two new vitest regressions in state/store.test.ts now pin the contract: - refreshLive() resets selectedStepId to the scenario's defaultStepId when the prior step no longer exists in the merged catalog - refreshLive() preserves a still-valid selectedStepId runLiveFetch() now derives stepStillThere from the merged scenario's own steps (not the old store) and falls back to defaultStepId when stale. Same single-set call as before; no extra renders. Confidence: high Scope-risk: narrow Not-tested: real backend definition with step IDs that disappear mid-session (covered by stub + assertion above)
This commit is contained in:
@@ -74,4 +74,28 @@ describe("store live-mode + refresh", () => {
|
||||
await useApp.getState().setMode("snapshot");
|
||||
expect(useApp.getState().toasts.length).toBe(before);
|
||||
});
|
||||
|
||||
it("refreshLive() resets selectedStepId to defaultStepId when the prior step no longer exists in the merged catalog", async () => {
|
||||
stubFetch();
|
||||
await useApp.getState().setMode("live");
|
||||
const scenario = useApp.getState().scenarios[0];
|
||||
if (!scenario) throw new Error("no scenario");
|
||||
useApp.setState({ scenarioId: scenario.id, selectedStepId: "definitely-not-a-real-step-id" });
|
||||
await useApp.getState().refreshLive();
|
||||
const after = useApp.getState();
|
||||
const sc = after.scenarios.find((s) => s.id === after.scenarioId);
|
||||
expect(sc).toBeDefined();
|
||||
expect(sc!.steps.some((st) => st.id === after.selectedStepId)).toBe(true);
|
||||
});
|
||||
|
||||
it("refreshLive() preserves a still-valid selectedStepId", async () => {
|
||||
stubFetch();
|
||||
await useApp.getState().setMode("live");
|
||||
const scenario = useApp.getState().scenarios[0];
|
||||
if (!scenario) throw new Error("no scenario");
|
||||
const validStep = scenario.steps[scenario.steps.length - 1];
|
||||
useApp.setState({ scenarioId: scenario.id, selectedStepId: validStep.id });
|
||||
await useApp.getState().refreshLive();
|
||||
expect(useApp.getState().selectedStepId).toBe(validStep.id);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user