Files
erika/lib/submission-intake.test.ts
T
2026-07-28 00:02:34 +07:00

154 lines
4.9 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import {
answersByTemplateIndex,
normalizeSubmissionAnswers,
submissionUpdateText,
type SubmissionQuestion,
} from "@/lib/submission-intake";
const questions: SubmissionQuestion[] = [
{
id: "q-name",
type: "text",
label: "<b>Name</b>",
required: true,
options: [],
allowOther: false,
},
{
id: "q-skill",
type: "radio",
label: "Skill",
required: true,
options: ["Build", "Fight"],
allowOther: true,
},
{
id: "q-tags",
type: "checkbox",
label: "Tags",
required: false,
options: ["Alpha", "Beta"],
allowOther: true,
},
];
describe("Submission intake", () => {
test("normalizes answers into stored and display values", () => {
const normalized = normalizeSubmissionAnswers(questions, [
{ questionId: "q-name", value: "Erika" },
{ questionId: "q-skill", value: "Custom skill" },
{ questionId: "q-tags", value: ["Alpha", "Gamma"] },
]);
expect(normalized).toEqual([
{ questionId: "q-name", value: "Erika", imageCdnId: null, displayValue: "Erika" },
{ questionId: "q-skill", value: "Custom skill", imageCdnId: null, displayValue: "Custom skill" },
{ questionId: "q-tags", value: '["Alpha","Gamma"]', imageCdnId: null, displayValue: "Alpha, Gamma" },
]);
});
test("validates required image-only and text plus image answers", () => {
const imageQuestions: SubmissionQuestion[] = [
{
id: "q-image",
type: "text",
label: "Screenshot",
required: false,
options: [],
allowOther: false,
imageAnswerMode: "required",
},
{
id: "q-text-image",
type: "textarea",
label: "Proof",
required: true,
options: [],
allowOther: false,
imageAnswerMode: "required",
},
];
expect(() => normalizeSubmissionAnswers(imageQuestions, [
{ questionId: "q-image", value: "" },
{ questionId: "q-text-image", value: "Details", imageCdnId: "img-2" },
])).toThrow("จำเป็นต้องอัปโหลดรูปสำหรับ “Screenshot”");
expect(normalizeSubmissionAnswers(imageQuestions, [
{ questionId: "q-image", value: "", imageCdnId: "img-1" },
{ questionId: "q-text-image", value: "Details", imageCdnId: "img-2" },
])).toEqual([
{ questionId: "q-image", value: "", imageCdnId: "img-1", displayValue: "" },
{ questionId: "q-text-image", value: "Details", imageCdnId: "img-2", displayValue: "Details" },
]);
});
test("rejects answers for questions outside the Form", () => {
expect(() => normalizeSubmissionAnswers(questions, [
{ questionId: "q-name", value: "Erika" },
{ questionId: "missing", value: "Injected" },
])).toThrow("ข้อมูลคำตอบไม่ตรงกับแบบฟอร์ม");
});
test("rejects duplicate answers for one Question", () => {
expect(() => normalizeSubmissionAnswers(questions, [
{ questionId: "q-name", value: "Erika" },
{ questionId: "q-name", value: "Duplicate" },
])).toThrow("ข้อมูลคำตอบไม่ตรงกับแบบฟอร์ม");
});
test("rejects unresolved Other answer placeholders", () => {
expect(() => normalizeSubmissionAnswers(questions, [
{ questionId: "q-name", value: "Erika" },
{ questionId: "q-skill", value: "__OTHER__" },
])).toThrow("โปรดระบุคำตอบสำหรับ “Skill”");
});
test("maps answers by Question order for webhook templates", () => {
const normalized = normalizeSubmissionAnswers(questions, [
{ questionId: "q-name", value: "Erika" },
{ questionId: "q-skill", value: "Build" },
{ questionId: "q-tags", value: ["Beta"] },
]);
expect(answersByTemplateIndex(questions, normalized)).toEqual({
"1": "Erika",
"2": "Build",
"3": "Beta",
});
});
test("renders Update text from stored old answers", () => {
const normalized = normalizeSubmissionAnswers(questions, [
{ questionId: "q-name", value: "Erika" },
{ questionId: "q-skill", value: "Fight" },
{ questionId: "q-tags", value: ["Alpha", "Gamma"] },
]);
expect(submissionUpdateText(questions, normalized, {
"q-name": "Erika",
"q-skill": "Build",
"q-tags": '["Alpha"]',
})).toBe([
"**Skill**: `Build` ➡️ `Fight`",
"**Tags**: `Alpha` ➡️ `Alpha, Gamma`",
].join("\n"));
});
test("renders a stable no-change Update message", () => {
const normalized = normalizeSubmissionAnswers(questions, [
{ questionId: "q-name", value: "Erika" },
{ questionId: "q-skill", value: "Build" },
{ questionId: "q-tags", value: ["Alpha"] },
]);
expect(submissionUpdateText(questions, normalized, {
"q-name": "Erika",
"q-skill": "Build",
"q-tags": '["Alpha"]',
})).toBe("No changes made.");
});
});