리스트/에디터 스타일 정리 및 버그 수정
CI / test (push) Failing after 7m55s
CI / pr_and_merge (push) Has been skipped

This commit is contained in:
2025-11-30 16:52:27 +09:00
parent 17bfac62ed
commit 0cf67b5619
45 changed files with 1606 additions and 530 deletions
+65 -19
View File
@@ -52,28 +52,25 @@ describe("BlocksSidebar - 템플릿 버튼", () => {
Object.values(templateActions).forEach((fn) => fn.mockReset());
});
it("Hero 템플릿 추가 버튼 클릭 시 addHeroTemplateSection 이 호출되어야 한다", () => {
it("Hero 템플릿 버튼 클릭 시 addHeroTemplateSection 이 호출되어야 한다", () => {
render(<BlocksSidebar />);
const button = screen.getByRole("button", { name: "Hero 템플릿 추가" });
const button = screen.getByRole("button", { name: "Hero 템플릿" });
fireEvent.click(button);
expect(templateActions.addHeroTemplateSection).toHaveBeenCalledTimes(1);
});
it("Features 템플릿 추가 버튼 클릭 시 addFeaturesTemplateSection 이 호출되어야 한다", () => {
it("Features 템플릿 버튼 클릭 시 addFeaturesTemplateSection 이 호출되어야 한다", () => {
render(<BlocksSidebar />);
const button = screen.getByRole("button", { name: "Features 템플릿 추가" });
const button = screen.getByRole("button", { name: "기능 템플릿" });
fireEvent.click(button);
expect(templateActions.addFeaturesTemplateSection).toHaveBeenCalledTimes(1);
});
it("CTA 템플릿 추가 버튼 클릭 시 addCtaTemplateSection 이 호출되어야 한다", () => {
it("CTA 템플릿 버튼 클릭 시 addCtaTemplateSection 이 호출되어야 한다", () => {
render(<BlocksSidebar />);
const button = screen.getByRole("button", { name: "CTA 템플릿 추가" });
const button = screen.getByRole("button", { name: "CTA 템플릿" });
fireEvent.click(button);
expect(templateActions.addCtaTemplateSection).toHaveBeenCalledTimes(1);
@@ -81,13 +78,12 @@ describe("BlocksSidebar - 템플릿 버튼", () => {
it("FAQ/Pricing/Testimonials/Blog/Team/Footer 템플릿 버튼도 각각의 액션을 호출해야 한다", () => {
render(<BlocksSidebar />);
fireEvent.click(screen.getByRole("button", { name: "FAQ 템플릿 추가" }));
fireEvent.click(screen.getByRole("button", { name: "Pricing 템플릿 추가" }));
fireEvent.click(screen.getByRole("button", { name: "Testimonials 템플릿 추가" }));
fireEvent.click(screen.getByRole("button", { name: "Blog 템플릿 추가" }));
fireEvent.click(screen.getByRole("button", { name: "Team 템플릿 추가" }));
fireEvent.click(screen.getByRole("button", { name: "Footer 템플릿 추가" }));
fireEvent.click(screen.getByRole("button", { name: "FAQ 템플릿" }));
fireEvent.click(screen.getByRole("button", { name: "상품 템플릿" }));
fireEvent.click(screen.getByRole("button", { name: "후기 템플릿" }));
fireEvent.click(screen.getByRole("button", { name: "블로그 템플릿" }));
fireEvent.click(screen.getByRole("button", { name: "Team 템플릿" }));
fireEvent.click(screen.getByRole("button", { name: "Footer 템플릿" }));
expect(templateActions.addFaqTemplateSection).toHaveBeenCalledTimes(1);
expect(templateActions.addPricingTemplateSection).toHaveBeenCalledTimes(1);
@@ -111,10 +107,9 @@ describe("BlocksSidebar - 템플릿 버튼", () => {
expect(screen.getByText("페이지 푸터 섹션"));
});
it("비디오 블록 추가 버튼 클릭 시 addVideoBlock 이 호출되어야 한다", () => {
it("비디오 버튼 클릭 시 addVideoBlock 이 호출되어야 한다", () => {
render(<BlocksSidebar />);
const button = screen.getByRole("button", { name: "비디오 블록 추가" });
const button = screen.getByRole("button", { name: "비디오" });
fireEvent.click(button);
expect(otherActions.addVideoBlock).toHaveBeenCalledTimes(1);
@@ -165,4 +160,55 @@ describe("BlocksSidebar - 템플릿 버튼", () => {
expect(pricingThumb.children.length).toBe(3);
expect(teamThumb.children.length).toBe(3);
});
it("블록 섹션 타이틀을 클릭하면 블록 버튼들을 접고 펼 수 있어야 한다", () => {
render(<BlocksSidebar />);
// 초기에는 텍스트 버튼이 보여야 한다.
expect(screen.getByRole("button", { name: "텍스트" })).toBeDefined();
const blockToggle = screen.getByRole("button", { name: "블록" });
fireEvent.click(blockToggle);
// 접힌 상태에서는 텍스트 버튼이 보이지 않아야 한다.
expect(screen.queryByRole("button", { name: "텍스트" })).toBeNull();
// 다시 클릭하면 펼쳐져야 한다.
fireEvent.click(blockToggle);
expect(screen.getByRole("button", { name: "텍스트" })).toBeDefined();
});
it("폼 요소 섹션 타이틀을 클릭하면 폼 관련 버튼들을 접고 펼 수 있어야 한다", () => {
render(<BlocksSidebar />);
// 초기에는 폼 입력 버튼이 보여야 한다.
expect(screen.getByRole("button", { name: "입력(Input)" })).toBeDefined();
const formToggle = screen.getByRole("button", { name: "폼 요소" });
fireEvent.click(formToggle);
// 접힌 상태에서는 폼 입력 버튼이 보이지 않아야 한다.
expect(screen.queryByRole("button", { name: "입력(Input)" })).toBeNull();
// 다시 클릭하면 펼쳐져야 한다.
fireEvent.click(formToggle);
expect(screen.getByRole("button", { name: "입력(Input)" })).toBeDefined();
});
it("템플릿 섹션 타이틀을 클릭하면 템플릿 카드들을 접고 펼 수 있어야 한다", () => {
render(<BlocksSidebar />);
// 초기에는 Hero 템플릿 버튼이 보여야 한다.
expect(screen.getByRole("button", { name: "Hero 템플릿" })).toBeDefined();
const templateToggle = screen.getByRole("button", { name: "템플릿" });
fireEvent.click(templateToggle);
// 접힌 상태에서는 Hero 템플릿 버튼이 보이지 않아야 한다.
expect(screen.queryByRole("button", { name: "Hero 템플릿" })).toBeNull();
// 다시 클릭하면 펼쳐져야 한다.
fireEvent.click(templateToggle);
expect(screen.getByRole("button", { name: "Hero 템플릿" })).toBeDefined();
});
});
+2
View File
@@ -6,6 +6,8 @@ import EditorPage from "@/app/editor/page";
let mockState: any;
beforeEach(() => {
window.localStorage.clear();
const baseProjectConfig: ProjectConfig = {
title: "멀티 선택 테스트",
slug: "multi-select",
+72
View File
@@ -0,0 +1,72 @@
import { describe, it, expect, vi, afterEach } from "vitest";
import { render, screen, fireEvent, cleanup } from "@testing-library/react";
import type { Block } from "@/features/editor/state/editorStore";
import { PropertiesSidebar } from "@/app/editor/panels/PropertiesSidebar";
describe("PropertiesSidebar HELP 튜토리얼 모달", () => {
afterEach(() => {
cleanup();
});
const createTextBlock = (): Block => ({
id: "text-1",
type: "text",
props: {
text: "도움말 테스트",
align: "left",
size: "base",
} as any,
sectionId: null,
columnId: null,
});
const defaultProps = (blocks: Block[], selectedBlockId: string | null) => ({
blocks,
selectedBlockId,
selectedListItemId: null,
updateBlock: vi.fn(),
removeBlock: vi.fn(),
duplicateBlock: vi.fn(),
editingBlockId: null,
setEditingText: vi.fn(),
onMoveSelectedItemUp: vi.fn(),
onMoveSelectedItemDown: vi.fn(),
onIndentSelectedItem: vi.fn(),
onOutdentSelectedItem: vi.fn(),
});
it("텍스트 블록이 선택된 상태에서 HELP 버튼을 노출해야 한다", () => {
const textBlock = createTextBlock();
render(<PropertiesSidebar {...defaultProps([textBlock], textBlock.id)} />);
const helpButton = screen.getByRole("button", { name: "HELP" });
expect(helpButton).toBeDefined();
});
it("HELP 버튼 클릭 시 현재 블록 타입에 맞는 튜토리얼 모달이 열려야 한다", () => {
const textBlock = createTextBlock();
render(<PropertiesSidebar {...defaultProps([textBlock], textBlock.id)} />);
const helpButton = screen.getByRole("button", { name: "HELP" });
fireEvent.click(helpButton);
expect(screen.getByText("텍스트 블록 튜토리얼")).toBeDefined();
expect(screen.getByText(/제목과 본문 텍스트를 입력할 때 사용하는 기본 블록입니다/)).toBeDefined();
});
it("모달의 닫기 버튼을 클릭하면 튜토리얼 모달이 닫혀야 한다", () => {
const textBlock = createTextBlock();
render(<PropertiesSidebar {...defaultProps([textBlock], textBlock.id)} />);
const helpButton = screen.getByRole("button", { name: "HELP" });
fireEvent.click(helpButton);
const closeButton = screen.getByRole("button", { name: "닫기" });
fireEvent.click(closeButton);
expect(screen.queryByText("텍스트 블록 튜토리얼")).toBeNull();
});
});
+20
View File
@@ -221,6 +221,11 @@ describe("formHelpers - editor tokens", () => {
widthMode: "fixed",
widthPx: 260,
borderRadius: "lg",
paddingX: 12,
paddingY: 6,
fontSizeCustom: "14px",
lineHeightCustom: "20px",
letterSpacingCustom: "1px",
} as any);
expect(tokens.fieldStyle.color).toBe("#ff0000");
@@ -228,6 +233,11 @@ describe("formHelpers - editor tokens", () => {
expect(tokens.fieldStyle.borderColor).toBe("#654321");
expect(tokens.fieldStyle.width).toBe("260px");
expect(tokens.fieldStyle.borderRadius).toBe(9999);
expect(tokens.fieldStyle.paddingInline).toBe("12px");
expect(tokens.fieldStyle.paddingBlock).toBe("6px");
expect(tokens.fieldStyle.fontSize).toBe("14px");
expect(tokens.fieldStyle.lineHeight).toBe("20px");
expect(tokens.fieldStyle.letterSpacing).toBe("1px");
});
it("computeFormOptionGroupEditorTokens: 에디터 라디오/체크박스 그룹 필드 스타일을 계산해야 한다", () => {
@@ -239,6 +249,11 @@ describe("formHelpers - editor tokens", () => {
widthMode: "fixed",
widthPx: 280,
borderRadius: "lg",
paddingX: 8,
paddingY: 4,
fontSizeCustom: "15px",
lineHeightCustom: "22px",
letterSpacingCustom: "0.5px",
} as any);
expect(tokens.fieldStyle.color).toBe("#ff0000");
@@ -246,6 +261,11 @@ describe("formHelpers - editor tokens", () => {
expect(tokens.fieldStyle.borderColor).toBe("#654321");
expect(tokens.fieldStyle.width).toBe("280px");
expect(tokens.fieldStyle.borderRadius).toBe(9999);
expect(tokens.fieldStyle.paddingInline).toBe("8px");
expect(tokens.fieldStyle.paddingBlock).toBe("4px");
expect(tokens.fieldStyle.fontSize).toBe("15px");
expect(tokens.fieldStyle.lineHeight).toBe("22px");
expect(tokens.fieldStyle.letterSpacing).toBe("0.5px");
});
});