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: "Name", 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."); }); });