Files
Jyotisha/frontend/tests/birth-time-dynamic-action-receipt.test.ts
T
2026-07-19 09:12:45 +08:00

46 lines
1.6 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import { dynamicActionReceiptSchema } from "../src/lib/birth-time-dynamic-action-receipt.ts";
const base = {
actionId: "700406ad-1ca6-437d-9f77-61354ba8e36a",
turnVersion: 7,
} as const;
test("dynamic receipts strictly bind every user mutation payload", () => {
for (const receipt of [
{ ...base, kind: "answer_choice", questionId: "question", optionId: "option" },
{
...base,
kind: "commit_question",
outcome: "question",
questionId: "question",
questionFingerprint: "question-fingerprint",
partitionFingerprint: "partition-fingerprint",
submittedQuestionFingerprint: "question-fingerprint",
submittedPartitionFingerprint: "partition-fingerprint",
},
{ ...base, kind: "unmatched_context", questionId: "question", note: "大约 2017 年" },
{ ...base, kind: "pause" },
{ ...base, kind: "finish" },
]) assert.equal(dynamicActionReceiptSchema.safeParse(receipt).success, true);
});
test("dynamic receipts reject missing, cross-kind, and noncanonical fields", () => {
for (const receipt of [
{ ...base, kind: "answer_choice", questionId: "question" },
{ ...base, kind: "pause", note: "forged" },
{ ...base, actionId: base.actionId.toUpperCase(), kind: "finish" },
{
...base,
kind: "commit_question",
outcome: "terminal",
questionId: "forged-question",
questionFingerprint: null,
partitionFingerprint: null,
submittedQuestionFingerprint: null,
submittedPartitionFingerprint: null,
},
]) assert.equal(dynamicActionReceiptSchema.safeParse(receipt).success, false);
});