Files
Jyotisha/frontend/tests/birth-time-intake.test.ts
T
2026-07-19 14:51:06 +08:00

135 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from "node:assert/strict";
import test from "node:test";
import {
assistantIntentCopy,
birthTimeDisplayState,
birthTimePersistenceValues,
describeBirthTimeDraft,
formatBirthDate,
isBirthTimeReadyForConsultation,
isBirthTimeDraftReady,
parseBirthDate,
type BirthTimeDraft,
} from "../src/lib/birth-time-intake-model.ts";
const emptyDraft: BirthTimeDraft = {
date: "1993-04-17",
time: "",
reportedTime: "",
birthTimeSource: "",
birthTimePeriod: "",
birthTimeClue: "",
uncertaintyBeforeMinutes: null,
uncertaintyAfterMinutes: null,
birthTimeStatus: "",
};
test("birth time intake requires only the fields selected by the source", () => {
const hospital = {
...emptyDraft,
birthTimeSource: "hospital_record",
reportedTime: "08:16",
} satisfies BirthTimeDraft;
const period = {
...emptyDraft,
birthTimeSource: "period_only",
birthTimePeriod: "evening",
} satisfies BirthTimeDraft;
const incompleteApproximate = {
...emptyDraft,
birthTimeSource: "approximate",
reportedTime: "14:30",
} satisfies BirthTimeDraft;
assert.equal(isBirthTimeDraftReady(hospital), true);
assert.equal(isBirthTimeDraftReady(period), true);
assert.equal(isBirthTimeDraftReady(incompleteApproximate), false);
assert.equal(isBirthTimeDraftReady({ ...emptyDraft, birthTimeSource: "unknown" }), true);
});
test("a persisted candidate working time can leave rectification onboarding", () => {
const candidate = {
...emptyDraft,
time: "04:53",
birthTimeStatus: "candidate",
} satisfies BirthTimeDraft;
assert.equal(isBirthTimeReadyForConsultation(candidate), true);
assert.equal(isBirthTimeReadyForConsultation({ ...candidate, time: "" }), false);
assert.equal(isBirthTimeReadyForConsultation({ ...candidate, birthTimeStatus: "rectifying" }), false);
});
test("a persisted candidate working time takes precedence over the reported range", () => {
// Given: rectification saved a candidate minute while preserving the user's original period.
const candidate = {
...emptyDraft,
time: "04:53",
birthTimeSource: "period_only",
birthTimePeriod: "early_morning",
birthTimeStatus: "candidate",
} satisfies BirthTimeDraft;
// When: a profile surface asks what birth-time state to display.
const display = birthTimeDisplayState(candidate);
// Then: the candidate minute is primary and the original period remains secondary.
assert.deepEqual(display, {
kind: "candidate",
activeTime: "04:53",
reportedLabel: "凌晨 / 清晨(04:00—07:59",
});
});
test("birth time declaration payload cannot write deterministic application fields", () => {
const draft = {
...emptyDraft,
time: "14:24",
reportedTime: "14:30",
birthTimeSource: "approximate",
uncertaintyBeforeMinutes: 30,
uncertaintyAfterMinutes: 30,
birthTimeStatus: "confirmed",
} satisfies BirthTimeDraft;
assert.deepEqual(birthTimePersistenceValues(draft), {
reported_birth_time: "14:30",
birth_time_source: "approximate",
birth_time_period: null,
birth_time_clue: null,
uncertainty_before_minutes: 30,
uncertainty_after_minutes: 30,
});
});
test("birth time intake describes uncertainty without claiming false precision", () => {
const approximate = {
...emptyDraft,
birthTimeSource: "approximate",
reportedTime: "14:30",
uncertaintyBeforeMinutes: 30,
uncertaintyAfterMinutes: 30,
} satisfies BirthTimeDraft;
assert.equal(describeBirthTimeDraft(approximate), "1993年4月17日,约 14:30(前后 30 分钟)");
assert.equal(
assistantIntentCopy("present_saved_candidate_range"),
"目前只能保存候选范围,还没有足够证据应用到具体分钟。",
);
});
test("birth date parsing preserves the local calendar day", () => {
const parsed = parseBirthDate("1993-04-17");
assert.equal(parsed?.getFullYear(), 1993);
assert.equal(parsed?.getMonth(), 3);
assert.equal(parsed?.getDate(), 17);
});
test("birth date values round trip leap days and reject invalid input", () => {
const leapDay = parseBirthDate("2000-02-29");
assert.equal(leapDay === undefined ? undefined : formatBirthDate(leapDay), "2000-02-29");
assert.equal(parseBirthDate(""), undefined);
assert.equal(parseBirthDate("2001-02-29"), undefined);
});