import { describe, it, expect, vi } from 'vitest' import { render, screen, fireEvent } from '@testing-library/react' import React, { useState } from 'react' import SectionCanvas from '@/components/SectionCanvas' import type { Section } from '@/lib/state/store' type DragEvt = { active: { id: string }; over: { id: string } } vi.mock('@dnd-kit/core', async () => { const actual = await vi.importActual('@dnd-kit/core') return { ...actual, DndContext: ({ onDragEnd, children }: { onDragEnd?: (e: DragEvt) => void; children: React.ReactNode }) => (
onDragEnd?.({ active: { id: 'sec-0' }, over: { id: 'sec-2' } })}> {children}
), closestCenter: vi.fn(), PointerSensor: function () {}, useSensor: vi.fn(() => ({})), useSensors: vi.fn(() => []), } }) vi.mock('@dnd-kit/sortable', async () => { const actual = await vi.importActual('@dnd-kit/sortable') return { ...actual, SortableContext: ({ children }: { children: React.ReactNode }) => <>{children}, useSortable: () => ({ attributes: {} as Record, listeners: {} as Record, setNodeRef: () => {}, transform: null as unknown, transition: null as unknown, }), verticalListSortingStrategy: vi.fn(), } }) function Wrapper() { const [sections, setSections] = useState([ { type: 'hero', props: { heading: 'Welcome', subheading: '' } }, { type: 'faq', props: { items: [] } }, { type: 'cta', props: { text: 'Go', href: '#' } }, ]) return ( { const next = sections.slice() const [sp] = next.splice(from, 1) next.splice(to, 0, sp) setSections(next) }} onRemove={(i) => setSections((prev) => prev.filter((_, idx) => idx !== i))} /> ) } describe('SectionCanvas - dnd', () => { it('드래그 종료 이벤트로 섹션 순서를 변경한다', () => { render() const list = screen.getByTestId('section-canvas') let items = list.querySelectorAll('li') expect(items[0].textContent).toMatch(/hero/) expect(items[1].textContent).toMatch(/faq/) expect(items[2].textContent).toMatch(/cta/) fireEvent.click(screen.getByTestId('mock-dnd')) items = list.querySelectorAll('li') expect(items[0].textContent).toMatch(/faq/) expect(items[1].textContent).toMatch(/cta/) expect(items[2].textContent).toMatch(/hero/) }) })