import { describe, expect, it } from "vitest"; import type { AnnotationDTO, AnnotationData, AnnotationType } from "@/db/schema"; import { DRAW_PENS, STAMP_PRESETS, annotationNote, annotationPreviewText, annotationTypeLabel, effectiveDrawOpacity, } from "@/utils/annotation-display"; const dto = (type: AnnotationType, data: AnnotationData): AnnotationDTO => ({ id: "00000000-0000-0000-0000-000000000001", fileId: "00000000-0000-0000-0000-000000000002", pageIndex: 0, userId: "user-1", userName: "ทดสอบ", type, data, createdAt: "2026-01-01T00:00:00.000Z", updatedAt: "2026-01-01T00:00:00.000Z", resolved: false, resolvedAt: null, }); describe("annotationTypeLabel", () => { it("HIGHLIGHT ตาม style + fallback เมื่อไม่ระบุ style", () => { expect( annotationTypeLabel(dto("HIGHLIGHT", { text: "a", color: "#000", rects: [], style: "underline" })), ).toBe("เส้นใต้"); expect(annotationTypeLabel(dto("HIGHLIGHT", { text: "a", color: "#000", rects: [] }))).toBe("ไฮไลต์"); }); it("ครบทุกชนิดที่เหลือ", () => { expect(annotationTypeLabel(dto("DRAW", { strokeColor: "#000", strokeWidth: 1, paths: [] }))).toBe("เส้นวาด"); expect(annotationTypeLabel(dto("COMMENT", { position: { x: 0, y: 0 }, message: "m" }))).toBe("คอมเมนต์"); expect( annotationTypeLabel( dto("SHAPE", { shape: "ellipse", rect: { x: 0, y: 0, width: 1, height: 1 }, strokeColor: "#000", strokeWidth: 1 }), ), ).toBe("รูปทรง (วงรี)"); expect(annotationTypeLabel(dto("REDACTION", { rect: { x: 0, y: 0, width: 1, height: 1 } }))).toBe("ปิดพราง"); expect( annotationTypeLabel(dto("TEXTBOX", { position: { x: 0, y: 0 }, text: "t", color: "#000", fontSize: 1 })), ).toBe("กล่องข้อความ"); expect(annotationTypeLabel(dto("STAMP", { label: "สำคัญ", position: { x: 0, y: 0 }, scale: 18 }))).toBe("ตรายาง"); }); }); describe("annotationPreviewText", () => { it("HIGHLIGHT ใช้ข้อความที่คลุม / ว่าง → placeholder", () => { expect( annotationPreviewText(dto("HIGHLIGHT", { text: "ข้อความที่คลุม", color: "#000", rects: [] })), ).toBe("ข้อความที่คลุม"); expect(annotationPreviewText(dto("HIGHLIGHT", { text: "", color: "#000", rects: [] }))).toBe( "(ไม่มีข้อความ)", ); }); it("COMMENT → message, TEXTBOX → text, STAMP → label, DRAW → ข้อความตายตัว", () => { expect( annotationPreviewText(dto("COMMENT", { position: { x: 0, y: 0 }, message: "ดูจุดนี้" })), ).toBe("ดูจุดนี้"); expect( annotationPreviewText(dto("TEXTBOX", { position: { x: 0, y: 0 }, text: "หมายเหตุ", color: "#000", fontSize: 1 })), ).toBe("หมายเหตุ"); expect( annotationPreviewText(dto("STAMP", { label: "ตรวจสอบแล้ว", position: { x: 0, y: 0 }, scale: 18 })), ).toBe("ตรวจสอบแล้ว"); expect( annotationPreviewText(dto("DRAW", { strokeColor: "#000", strokeWidth: 1, paths: [{ x: 0, y: 0 }] })), ).toBe("เส้นวาดอิสระ"); }); }); describe("annotationNote", () => { it("มี note → คืนค่านั้น / ไม่มี → ช่องว่าง", () => { expect( annotationNote(dto("DRAW", { strokeColor: "#000", strokeWidth: 1, paths: [], note: "เหตุผล" })), ).toBe("เหตุผล"); expect(annotationNote(dto("DRAW", { strokeColor: "#000", strokeWidth: 1, paths: [] }))).toBe(""); }); it("COMMENT (ไม่มี field note) → ช่องว่าง", () => { expect(annotationNote(dto("COMMENT", { position: { x: 0, y: 0 }, message: "m" }))).toBe(""); }); }); describe("effectiveDrawOpacity", () => { it("opacity ที่เก็บชัดชนะเสมอ", () => { expect(effectiveDrawOpacity({ pen: "highlighter", opacity: 0.8 })).toBe(0.8); expect(effectiveDrawOpacity({ opacity: 0.3 })).toBe(0.3); }); it("ไม่มี opacity → fallback ตาม preset ของ pen", () => { expect(effectiveDrawOpacity({ pen: "highlighter" })).toBe(DRAW_PENS.highlighter.opacity); expect(effectiveDrawOpacity({ pen: "pencil" })).toBe(DRAW_PENS.pencil.opacity); }); it("ไม่มีทั้ง pen และ opacity → pencil", () => { expect(effectiveDrawOpacity({})).toBe(DRAW_PENS.pencil.opacity); }); }); describe("presets ที่ sidebar/export ใช้ร่วมกัน", () => { it("STAMP_PRESETS มีค่าตาม D7 (preset ข้อความเท่านั้น)", () => { expect(STAMP_PRESETS).toEqual(["ตรวจสอบแล้ว", "สำคัญ"]); }); });