154 lines
4.9 KiB
TypeScript
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.");
|
|
});
|
|
});
|