Files
Jyotisha/frontend/tests/birth-time-journey-response-invariants.test.ts
T
2026-07-18 18:40:23 +08:00

150 lines
4.3 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import { parseJourneyResponse } from "../src/lib/birth-time-journey-client.ts";
import {
highConfirmationTurn,
} from "./birth-time-journey-client-test-support.ts";
const baselineQuestion = {
questionId: "baseline_education_1",
phase: "baseline",
domain: "education",
requestedPrecision: ["year", "month"],
allowUnknown: true,
purposeCode: "candidate_difference_education",
plannerVersion: "candidate-difference-v1",
} as const;
const baselineProgress = {
phase: "baseline",
baselineDomainCount: 1,
confirmedEvidenceCount: 2,
adaptiveRound: 0,
maxAdaptiveRounds: 3,
} as const;
test("client rejects inconsistent versioned route and result actions", () => {
assert.throws(() => parseJourneyResponse({
...highConfirmationTurn,
snapshot: {
...highConfirmationTurn.snapshot,
state: "ready",
input: "none",
route: "direct_chart",
canApply: false,
activeTime: null,
},
nextAction: { kind: "ready", activeTime: "14:24" },
permissions: { canConfirmCandidate: false },
}));
assert.throws(() => parseJourneyResponse({
...highConfirmationTurn,
nextAction: {
kind: "request_candidate_confirmation",
resultId: "45857b75-4718-4590-aaf5-7113a03ea765",
},
}));
assert.throws(() => parseJourneyResponse({
...highConfirmationTurn,
candidateResult: null,
snapshot: {
...highConfirmationTurn.snapshot,
state: "rectifying",
assistantIntent: "start_standard_rectification",
input: "rectification_questions",
route: "direct_chart",
confidence: null,
canApply: false,
activeTime: "14:24",
},
nextAction: { kind: "ask_baseline_evidence", question: baselineQuestion },
progress: { ...baselineProgress, baselineDomainCount: 0, confirmedEvidenceCount: 0 },
permissions: { canConfirmCandidate: false },
}));
});
test("client accepts a projected baseline action for a legacy snapshot", () => {
const parsed = parseJourneyResponse({
...highConfirmationTurn,
candidateResult: null,
snapshot: {
...highConfirmationTurn.snapshot,
state: "candidate",
assistantIntent: "present_saved_candidate_range",
input: "rectification_questions",
route: "rectification",
confidence: null,
canApply: false,
},
nextAction: { kind: "ask_baseline_evidence", question: baselineQuestion },
progress: baselineProgress,
permissions: { canConfirmCandidate: false },
});
assert.equal(parsed.nextAction.kind, "ask_baseline_evidence");
});
test("client rejects versioned baseline and review invariant violations", () => {
assert.throws(() => parseJourneyResponse({
...highConfirmationTurn,
candidateResult: null,
snapshot: {
...highConfirmationTurn.snapshot,
state: "rectifying",
assistantIntent: "continue_rectification_questions",
input: "rectification_questions",
route: "rectification",
confidence: null,
canApply: false,
},
nextAction: {
kind: "ask_baseline_evidence",
question: { ...baselineQuestion, questionId: "adaptive_education_1", phase: "adaptive" },
},
progress: {
...baselineProgress,
baselineDomainCount: 2,
confirmedEvidenceCount: 3,
},
permissions: { canConfirmCandidate: false },
}));
assert.throws(() => parseJourneyResponse({
...highConfirmationTurn,
candidateResult: null,
snapshot: {
...highConfirmationTurn.snapshot,
state: "rectifying",
assistantIntent: "collect_dated_life_events",
input: "life_events",
route: "rectification",
confidence: null,
canApply: false,
},
nextAction: {
kind: "review_evidence_draft",
draftId: "5cb071d6-6d99-46be-85dc-a9bf59ef6ac5",
},
progress: {
...baselineProgress,
phase: "review",
baselineDomainCount: 2,
confirmedEvidenceCount: 3,
},
permissions: { canConfirmCandidate: false },
evidenceDraft: null,
}));
});
test("client preserves optimistic turn versions", () => {
const parsed = parseJourneyResponse({ ...highConfirmationTurn, turnVersion: 7 });
assert.equal(parsed.turnVersion, 7);
assert.throws(() => parseJourneyResponse({
...highConfirmationTurn,
turnVersion: -1,
}));
});