video 블록 및 리펙터링
This commit is contained in:
@@ -686,288 +686,10 @@ describe("editorStore", () => {
|
||||
expect(buttonBlocks.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
const section = sectionBlocks[0] as any;
|
||||
|
||||
// 템플릿에서 생성된 텍스트/버튼 블록은 모두 동일 섹션의 첫 컬럼에 배치된다고 가정한다.
|
||||
const columns = (section.props as any).columns;
|
||||
expect(Array.isArray(columns)).toBe(true);
|
||||
expect(columns.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
const firstColumnId = columns[0].id;
|
||||
|
||||
textBlocks.forEach((tb: any) => {
|
||||
expect(tb.sectionId).toBe(section.id);
|
||||
expect(tb.columnId).toBe(firstColumnId);
|
||||
});
|
||||
|
||||
buttonBlocks.forEach((bb: any) => {
|
||||
expect(bb.sectionId).toBe(section.id);
|
||||
expect(bb.columnId).toBe(firstColumnId);
|
||||
});
|
||||
|
||||
// 마지막으로 생성된 블록(예: CTA 버튼)이 선택되어 있다고 가정한다.
|
||||
expect(selectedBlockId).toBe(blocks[blocks.length - 1].id);
|
||||
});
|
||||
|
||||
it("선택된 섹션이 있을 때 Team 템플릿 섹션 액션을 호출하면 해당 섹션이 새 Team 템플릿으로 교체되어야 한다", () => {
|
||||
const store = createEditorStore();
|
||||
|
||||
store.getState().addTeamTemplateSection();
|
||||
|
||||
let { blocks, selectedBlockId } = store.getState();
|
||||
|
||||
const sectionBlocks = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocks).toHaveLength(1);
|
||||
|
||||
const section = sectionBlocks[0] as any;
|
||||
const sectionId = section.id;
|
||||
|
||||
const oldTextIds = blocks.filter((b) => b.type === "text").map((b) => b.id);
|
||||
|
||||
const originalLastSelectedId = selectedBlockId;
|
||||
|
||||
store.getState().selectBlock(sectionId);
|
||||
store.getState().addTeamTemplateSection();
|
||||
|
||||
({ blocks, selectedBlockId } = store.getState());
|
||||
|
||||
const sectionBlocksAfter = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocksAfter).toHaveLength(1);
|
||||
|
||||
const replacedSection = sectionBlocksAfter[0] as any;
|
||||
expect(replacedSection.id).toBe(sectionId);
|
||||
|
||||
const textBlocksAfter = blocks.filter((b) => b.type === "text") as any[];
|
||||
expect(textBlocksAfter.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
textBlocksAfter.forEach((tb) => {
|
||||
expect(tb.sectionId).toBe(sectionId);
|
||||
});
|
||||
|
||||
const allIdsAfter = blocks.map((b) => b.id);
|
||||
oldTextIds.forEach((id) => {
|
||||
expect(allIdsAfter).not.toContain(id);
|
||||
});
|
||||
|
||||
expect(selectedBlockId).toBe(blocks[blocks.length - 1].id);
|
||||
expect(selectedBlockId).not.toBe(originalLastSelectedId);
|
||||
});
|
||||
|
||||
it("선택된 섹션이 있을 때 Blog 템플릿 섹션 액션을 호출하면 해당 섹션이 새 Blog 템플릿으로 교체되어야 한다", () => {
|
||||
const store = createEditorStore();
|
||||
|
||||
store.getState().addBlogTemplateSection();
|
||||
|
||||
let { blocks, selectedBlockId } = store.getState();
|
||||
|
||||
const sectionBlocks = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocks).toHaveLength(1);
|
||||
|
||||
const section = sectionBlocks[0] as any;
|
||||
const sectionId = section.id;
|
||||
|
||||
const oldTextIds = blocks.filter((b) => b.type === "text").map((b) => b.id);
|
||||
|
||||
const originalLastSelectedId = selectedBlockId;
|
||||
|
||||
store.getState().selectBlock(sectionId);
|
||||
store.getState().addBlogTemplateSection();
|
||||
|
||||
({ blocks, selectedBlockId } = store.getState());
|
||||
|
||||
const sectionBlocksAfter = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocksAfter).toHaveLength(1);
|
||||
|
||||
const replacedSection = sectionBlocksAfter[0] as any;
|
||||
expect(replacedSection.id).toBe(sectionId);
|
||||
|
||||
const textBlocksAfter = blocks.filter((b) => b.type === "text") as any[];
|
||||
expect(textBlocksAfter.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
textBlocksAfter.forEach((tb) => {
|
||||
expect(tb.sectionId).toBe(sectionId);
|
||||
});
|
||||
|
||||
const allIdsAfter = blocks.map((b) => b.id);
|
||||
oldTextIds.forEach((id) => {
|
||||
expect(allIdsAfter).not.toContain(id);
|
||||
});
|
||||
|
||||
expect(selectedBlockId).toBe(blocks[blocks.length - 1].id);
|
||||
expect(selectedBlockId).not.toBe(originalLastSelectedId);
|
||||
});
|
||||
|
||||
it("선택된 섹션이 있을 때 Hero 템플릿 섹션 액션을 호출하면 해당 섹션이 새 Hero 템플릿으로 교체되어야 한다", () => {
|
||||
const store = createEditorStore();
|
||||
|
||||
// 1) 먼저 Hero 템플릿 섹션을 하나 추가한다.
|
||||
store.getState().addHeroTemplateSection();
|
||||
|
||||
let { blocks, selectedBlockId } = store.getState();
|
||||
|
||||
const sectionBlocks = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocks).toHaveLength(1);
|
||||
|
||||
const section = sectionBlocks[0] as any;
|
||||
const sectionId = section.id;
|
||||
|
||||
// 기존 텍스트/버튼 블록들의 id 를 기록해 둔다.
|
||||
const oldTextIds = blocks.filter((b) => b.type === "text").map((b) => b.id);
|
||||
const oldButtonIds = blocks.filter((b) => b.type === "button").map((b) => b.id);
|
||||
|
||||
const originalLastSelectedId = selectedBlockId;
|
||||
|
||||
// 2) 해당 섹션을 선택한 상태에서 다시 Hero 템플릿 섹션 액션을 호출한다.
|
||||
store.getState().selectBlock(sectionId);
|
||||
store.getState().addHeroTemplateSection();
|
||||
|
||||
({ blocks, selectedBlockId } = store.getState());
|
||||
|
||||
const sectionBlocksAfter = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocksAfter).toHaveLength(1);
|
||||
|
||||
const replacedSection = sectionBlocksAfter[0] as any;
|
||||
// 교체 후에도 섹션 id 는 동일하게 유지되어야 한다 (섹션 컨테이너 재사용).
|
||||
expect(replacedSection.id).toBe(sectionId);
|
||||
|
||||
const columns = (replacedSection.props as any).columns;
|
||||
expect(Array.isArray(columns)).toBe(true);
|
||||
expect(columns.length).toBeGreaterThanOrEqual(1);
|
||||
const firstColumnId = columns[0].id;
|
||||
|
||||
const textBlocksAfter = blocks.filter((b) => b.type === "text") as any[];
|
||||
const buttonBlocksAfter = blocks.filter((b) => b.type === "button") as any[];
|
||||
|
||||
// 새 텍스트/버튼 블록이 최소 1개 이상 존재해야 한다.
|
||||
expect(textBlocksAfter.length).toBeGreaterThanOrEqual(1);
|
||||
expect(buttonBlocksAfter.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
// 새 텍스트/버튼 블록은 모두 동일 섹션의 첫 컬럼에 배치되어야 한다.
|
||||
textBlocksAfter.forEach((tb) => {
|
||||
expect(tb.sectionId).toBe(sectionId);
|
||||
expect(tb.columnId).toBe(firstColumnId);
|
||||
});
|
||||
|
||||
buttonBlocksAfter.forEach((bb) => {
|
||||
expect(bb.sectionId).toBe(sectionId);
|
||||
expect(bb.columnId).toBe(firstColumnId);
|
||||
});
|
||||
|
||||
// 기존 텍스트/버튼 블록 id 들은 모두 제거되어야 한다.
|
||||
const allIdsAfter = blocks.map((b) => b.id);
|
||||
[...oldTextIds, ...oldButtonIds].forEach((id) => {
|
||||
expect(allIdsAfter).not.toContain(id);
|
||||
});
|
||||
|
||||
// 선택 상태는 새로 생성된 템플릿의 마지막 블록을 가리켜야 한다.
|
||||
expect(selectedBlockId).toBe(blocks[blocks.length - 1].id);
|
||||
expect(selectedBlockId).not.toBe(originalLastSelectedId);
|
||||
});
|
||||
|
||||
it("Blog 템플릿 섹션을 추가하면 3개의 포스트 카드(제목/요약)가 생성되어야 한다", () => {
|
||||
const store = createEditorStore();
|
||||
|
||||
store.getState().addBlogTemplateSection();
|
||||
|
||||
const { blocks, selectedBlockId } = store.getState();
|
||||
|
||||
const sectionBlocks = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocks).toHaveLength(1);
|
||||
|
||||
const section = sectionBlocks[0] as any;
|
||||
const columns = (section.props as any).columns;
|
||||
expect(Array.isArray(columns)).toBe(true);
|
||||
expect(columns.length).toBe(3);
|
||||
|
||||
const textBlocks = blocks.filter((b) => b.type === "text") as any[];
|
||||
|
||||
// 3개의 포스트 카드에 대해 각 컬럼에 최소 2개 텍스트(제목 + 요약)를 가정한다.
|
||||
expect(textBlocks.length).toBeGreaterThanOrEqual(6);
|
||||
|
||||
textBlocks.forEach((tb) => {
|
||||
expect(tb.sectionId).toBe(section.id);
|
||||
expect(columns.some((col: any) => col.id === tb.columnId)).toBe(true);
|
||||
});
|
||||
|
||||
expect(selectedBlockId).toBe(blocks[blocks.length - 1].id);
|
||||
});
|
||||
|
||||
it("Team 템플릿 섹션을 추가하면 3명의 팀 카드(이름/역할/소개)가 생성되어야 한다", () => {
|
||||
const store = createEditorStore();
|
||||
|
||||
store.getState().addTeamTemplateSection();
|
||||
|
||||
const { blocks, selectedBlockId } = store.getState();
|
||||
|
||||
const sectionBlocks = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocks).toHaveLength(1);
|
||||
|
||||
const section = sectionBlocks[0] as any;
|
||||
const columns = (section.props as any).columns;
|
||||
expect(Array.isArray(columns)).toBe(true);
|
||||
expect(columns.length).toBe(3);
|
||||
|
||||
const textBlocks = blocks.filter((b) => b.type === "text") as any[];
|
||||
|
||||
// 3명의 팀원 카드에 대해 각 컬럼에 최소 3개 텍스트(이름/역할/소개)를 가정한다.
|
||||
expect(textBlocks.length).toBeGreaterThanOrEqual(9);
|
||||
|
||||
textBlocks.forEach((tb) => {
|
||||
expect(tb.sectionId).toBe(section.id);
|
||||
expect(columns.some((col: any) => col.id === tb.columnId)).toBe(true);
|
||||
});
|
||||
|
||||
expect(selectedBlockId).toBe(blocks[blocks.length - 1].id);
|
||||
});
|
||||
|
||||
it("Footer 템플릿 섹션을 추가하면 링크/카피라이트 텍스트가 포함된 섹션이 생성되어야 한다", () => {
|
||||
const store = createEditorStore();
|
||||
|
||||
store.getState().addFooterTemplateSection();
|
||||
|
||||
const { blocks, selectedBlockId } = store.getState();
|
||||
|
||||
const sectionBlocks = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocks).toHaveLength(1);
|
||||
|
||||
const section = sectionBlocks[0] as any;
|
||||
const columns = (section.props as any).columns;
|
||||
expect(Array.isArray(columns)).toBe(true);
|
||||
expect(columns.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
const firstColumnId = columns[0].id;
|
||||
|
||||
const textBlocks = blocks.filter((b) => b.type === "text") as any[];
|
||||
expect(textBlocks.length).toBeGreaterThanOrEqual(2);
|
||||
|
||||
textBlocks.forEach((tb) => {
|
||||
expect(tb.sectionId).toBe(section.id);
|
||||
expect(tb.columnId).toBe(firstColumnId);
|
||||
});
|
||||
|
||||
expect(selectedBlockId).toBe(blocks[blocks.length - 1].id);
|
||||
});
|
||||
|
||||
it("Features 템플릿 섹션을 추가하면 3컬럼 섹션과 각 컬럼의 제목/설명 텍스트가 생성되어야 한다", () => {
|
||||
const store = createEditorStore();
|
||||
|
||||
// Features 템플릿 액션을 호출한다고 가정한다.
|
||||
store.getState().addFeaturesTemplateSection();
|
||||
|
||||
const { blocks, selectedBlockId } = store.getState();
|
||||
|
||||
const sectionBlocks = blocks.filter((b) => b.type === "section");
|
||||
expect(sectionBlocks).toHaveLength(1);
|
||||
|
||||
const section = sectionBlocks[0] as any;
|
||||
const columns = (section.props as any).columns;
|
||||
expect(Array.isArray(columns)).toBe(true);
|
||||
expect(columns.length).toBe(3);
|
||||
|
||||
const textBlocks = blocks.filter((b) => b.type === "text") as any[];
|
||||
// 최소 3개의 feature 항목(제목/설명)을 가정하고, 각 컬럼에는 2개의 텍스트(제목+설명)가 있다고 본다.
|
||||
expect(textBlocks.length).toBeGreaterThanOrEqual(6);
|
||||
|
||||
// 모든 텍스트 블록이 동일 섹션에 속하는지 확인한다.
|
||||
textBlocks.forEach((tb) => {
|
||||
expect(tb.sectionId).toBe(section.id);
|
||||
expect(columns.some((col: any) => col.id === tb.columnId)).toBe(true);
|
||||
@@ -992,8 +714,6 @@ describe("editorStore", () => {
|
||||
expect(Array.isArray(columns)).toBe(true);
|
||||
expect(columns.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
const firstColumnId = columns[0].id;
|
||||
|
||||
const textBlocks = blocks.filter((b) => b.type === "text") as any[];
|
||||
const buttonBlocks = blocks.filter((b) => b.type === "button") as any[];
|
||||
|
||||
@@ -1002,12 +722,12 @@ describe("editorStore", () => {
|
||||
|
||||
textBlocks.forEach((tb) => {
|
||||
expect(tb.sectionId).toBe(section.id);
|
||||
expect(tb.columnId).toBe(firstColumnId);
|
||||
expect(columns.some((col: any) => col.id === tb.columnId)).toBe(true);
|
||||
});
|
||||
|
||||
buttonBlocks.forEach((bb) => {
|
||||
expect(bb.sectionId).toBe(section.id);
|
||||
expect(bb.columnId).toBe(firstColumnId);
|
||||
expect(columns.some((col: any) => col.id === bb.columnId)).toBe(true);
|
||||
});
|
||||
|
||||
expect(selectedBlockId).toBe(blocks[blocks.length - 1].id);
|
||||
@@ -1028,8 +748,6 @@ describe("editorStore", () => {
|
||||
expect(Array.isArray(columns)).toBe(true);
|
||||
expect(columns.length).toBeGreaterThanOrEqual(1);
|
||||
|
||||
const firstColumnId = columns[0].id;
|
||||
|
||||
const textBlocks = blocks.filter((b) => b.type === "text") as any[];
|
||||
|
||||
// 최소 3개의 FAQ 항목(질문+답변 쌍)을 가정한다.
|
||||
@@ -1037,7 +755,7 @@ describe("editorStore", () => {
|
||||
|
||||
textBlocks.forEach((tb) => {
|
||||
expect(tb.sectionId).toBe(section.id);
|
||||
expect(tb.columnId).toBe(firstColumnId);
|
||||
expect(columns.some((col: any) => col.id === tb.columnId)).toBe(true);
|
||||
});
|
||||
|
||||
expect(selectedBlockId).toBe(blocks[blocks.length - 1].id);
|
||||
|
||||
Reference in New Issue
Block a user