feat(ui): RTO.31 ownership of focused contributions flows to scenario form
- Add focusedContributions state + appendFocusedContribution callback in ScenarioForm - Contributions persist through session lifecycle (save/restore/restart) - Pass onFocusedContribution and focusedContributions to ReasoningWorkspace - Call onFocusedContribution on successful deconstruct with full result shape - Test: contribution sequence, field preservation, same/different target coexistence
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import React from "react";
|
||||
import { renderHook, act } from "@testing-library/react";
|
||||
|
||||
// ── Test contribution shape and sequence logic ────────────────
|
||||
|
||||
describe("contribution append behavior", () => {
|
||||
function simulateAppend(contributions, contribution) {
|
||||
return [...contributions, { ...contribution, id: `contrib-${String(contributions.length + 1).padStart(4, "0")}`, sequence: contributions.length + 1 }];
|
||||
}
|
||||
|
||||
it("first successful deconstruct -> one contribution", () => {
|
||||
const result = simulateAppend([], { targetNodeId: "a" });
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0].id).toBe("contrib-0001");
|
||||
expect(result[0].sequence).toBe(1);
|
||||
});
|
||||
|
||||
it("second successful deconstruct -> two contributions", () => {
|
||||
const first = simulateAppend([], { targetNodeId: "a" });
|
||||
const result = simulateAppend(first, { targetNodeId: "b" });
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result[1].id).toBe("contrib-0002");
|
||||
expect(result[1].sequence).toBe(2);
|
||||
});
|
||||
|
||||
it("same-target contributions coexist as distinct records", () => {
|
||||
const first = simulateAppend([], { targetNodeId: "a", question: "Q1?", answer: "A1" });
|
||||
const result = simulateAppend(first, { targetNodeId: "a", question: "Q2?", answer: "A2" });
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result[0].targetNodeId).toBe("a");
|
||||
expect(result[1].targetNodeId).toBe("a");
|
||||
expect(result[0].id).not.toBe(result[1].id);
|
||||
expect(result[0].question).toBe("Q1?");
|
||||
expect(result[1].question).toBe("Q2?");
|
||||
});
|
||||
|
||||
it("different-target contributions coexist", () => {
|
||||
const first = simulateAppend([], { targetNodeId: "a" });
|
||||
const result = simulateAppend(first, { targetNodeId: "b" });
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result[0].targetNodeId).toBe("a");
|
||||
expect(result[1].targetNodeId).toBe("b");
|
||||
});
|
||||
|
||||
it("contribution preserves exact fields", () => {
|
||||
const data = {
|
||||
targetNodeId: "node-abc",
|
||||
targetLabel: "Test Label",
|
||||
targetDescription: "Test description text",
|
||||
question: "What is the answer?",
|
||||
answer: "The definitive answer.",
|
||||
observations: ["obs1", "obs2"],
|
||||
uncertainties: ["unc1"],
|
||||
assumptions: ["asm1"],
|
||||
relationships: [{ from: "a", to: "b", type: "depends_on" }],
|
||||
possibleFollowUpQuestions: ["follow1"],
|
||||
};
|
||||
const result = simulateAppend([], data);
|
||||
expect(result[0].targetNodeId).toBe("node-abc");
|
||||
expect(result[0].targetLabel).toBe("Test Label");
|
||||
expect(result[0].targetDescription).toBe("Test description text");
|
||||
expect(result[0].question).toBe("What is the answer?");
|
||||
expect(result[0].answer).toBe("The definitive answer.");
|
||||
expect(result[0].observations).toEqual(["obs1", "obs2"]);
|
||||
expect(result[0].uncertainties).toEqual(["unc1"]);
|
||||
expect(result[0].assumptions).toEqual(["asm1"]);
|
||||
expect(result[0].relationships).toEqual([{ from: "a", to: "b", type: "depends_on" }]);
|
||||
expect(result[0].possibleFollowUpQuestions).toEqual(["follow1"]);
|
||||
});
|
||||
|
||||
it("failed deconstruct appends nothing", () => {
|
||||
const before = [];
|
||||
// Simulate failure: do not call append
|
||||
const result = before;
|
||||
expect(result).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user