import { describe, it, expect, vi, afterEach } from "vitest"; import { render, screen, fireEvent, cleanup } from "@testing-library/react"; import { DividerPropertiesPanel } from "@/app/editor/panels/DividerPropertiesPanel"; import type { DividerBlockProps } from "@/features/editor/state/editorStore"; // DividerPropertiesPanel 컨트롤 TDD // - 정렬/두께 select 변경 시 updateBlock 이 올바른 필드로 호출되는지 // - 색상 HEX 인풋 변경 시 colorHex 로 호출되는지 // - 위/아래 여백 커스텀(px) 입력 시 marginYPx 로 호출되는지 describe("DividerPropertiesPanel", () => { const baseProps: DividerBlockProps = { align: "left", thickness: "thin", widthMode: "full", colorHex: "#475569", marginY: "md", }; afterEach(() => { cleanup(); }); it("정렬 select 변경 시 updateBlock 이 align 으로 호출되어야 한다", () => { const updateBlock = vi.fn(); render( , ); const select = screen.getByLabelText("Divider alignment"); fireEvent.change(select, { target: { value: "center" } }); expect(updateBlock).toHaveBeenCalledWith( "divider-1", expect.objectContaining({ align: "center" }), ); }); it("두께 select 변경 시 updateBlock 이 thickness 로 호출되어야 한다", () => { const updateBlock = vi.fn(); render( , ); const select = screen.getByLabelText("Divider thickness"); fireEvent.change(select, { target: { value: "medium" } }); expect(updateBlock).toHaveBeenCalledWith( "divider-2", expect.objectContaining({ thickness: "medium" }), ); }); it("길이 모드 select 변경 시 updateBlock 이 widthMode 로 호출되어야 한다", () => { const updateBlock = vi.fn(); render( , ); const select = screen.getByLabelText("Divider length mode"); fireEvent.change(select, { target: { value: "fixed" } }); expect(updateBlock).toHaveBeenCalledWith( "divider-5", expect.objectContaining({ widthMode: "fixed" }), ); }); it("고정 길이 커스텀 인풋 변경 시 updateBlock 이 widthPx 로 호출되어야 한다", () => { const updateBlock = vi.fn(); render( , ); const widthInput = screen.getByLabelText("Fixed length 커스텀"); fireEvent.change(widthInput, { target: { value: "480" } }); expect(updateBlock).toHaveBeenCalledWith( "divider-6", expect.objectContaining({ widthPx: 480 }), ); }); it("색상 HEX 인풋 변경 시 updateBlock 이 colorHex 로 호출되어야 한다", () => { const updateBlock = vi.fn(); render( , ); const hexInputs = screen.getAllByLabelText("Divider color HEX"); const hexInput = hexInputs[0] as HTMLInputElement; fireEvent.change(hexInput, { target: { value: "#123456" } }); expect(updateBlock).toHaveBeenCalledWith( "divider-3", expect.objectContaining({ colorHex: "#123456" }), ); }); it("위/아래 여백 커스텀 인풋 변경 시 updateBlock 이 marginYPx 로 호출되어야 한다", () => { const updateBlock = vi.fn(); render( , ); const marginInputs = screen.getAllByLabelText("Vertical margin 커스텀"); const marginInput = marginInputs[0] as HTMLInputElement; fireEvent.change(marginInput, { target: { value: "24" } }); expect(updateBlock).toHaveBeenCalledWith( "divider-4", expect.objectContaining({ marginYPx: 24 }), ); }); it("DividerPropertiesPanel 주요 셀렉트 컨트롤은 라이트/다크 듀얼 테마 크롬을 사용해야 한다", () => { const updateBlock = vi.fn(); render( , ); const alignSelect = screen.getByLabelText("Divider alignment") as HTMLSelectElement; const alignClass = alignSelect.getAttribute("class") ?? ""; expect(alignClass).toContain("bg-white"); expect(alignClass).toContain("text-slate-900"); expect(alignClass).toContain("border-slate-300"); expect(alignClass).toContain("dark:bg-slate-900"); expect(alignClass).toContain("dark:text-slate-100"); expect(alignClass).toContain("dark:border-slate-700"); const thicknessSelect = screen.getByLabelText("Divider thickness") as HTMLSelectElement; const thicknessClass = thicknessSelect.getAttribute("class") ?? ""; expect(thicknessClass).toContain("bg-white"); expect(thicknessClass).toContain("text-slate-900"); expect(thicknessClass).toContain("border-slate-300"); expect(thicknessClass).toContain("dark:bg-slate-900"); expect(thicknessClass).toContain("dark:text-slate-100"); expect(thicknessClass).toContain("dark:border-slate-700"); const widthModeSelect = screen.getByLabelText("Divider length mode") as HTMLSelectElement; const widthModeClass = widthModeSelect.getAttribute("class") ?? ""; expect(widthModeClass).toContain("bg-white"); expect(widthModeClass).toContain("text-slate-900"); expect(widthModeClass).toContain("border-slate-300"); expect(widthModeClass).toContain("dark:bg-slate-900"); expect(widthModeClass).toContain("dark:text-slate-100"); expect(widthModeClass).toContain("dark:border-slate-700"); }); });