import React from 'react' import { describe, it, expect, vi, beforeEach } from 'vitest' import { render, screen, waitFor } from '@testing-library/react' import { act } from 'react-dom/test-utils' import { Canvas } from '@/components/wysiwyg/Canvas' import type { Frame } from '@/lib/wysiwyg/schema' const capture = vi.fn() type MProps = { onDragStart?: () => void onDrag?: (e: { left?: number; top?: number }) => void onDragEnd?: () => void } vi.mock('react-moveable', () => { const Mock = (props: Record) => { capture(props) return
} return { default: Mock } }) const frame: Frame = { id: 'f-guides-edges', width: 500, height: 400, background: '#fff', layers: [ { id: 'l1', name: 'L1', visible: true, locked: false, objects: [ // 드래그 대상(o1) - 기본 선택되도록 첫 번째 { id: 'o1', type: 'text', x: 10, y: 10, width: 40, height: 30, rotate: 0, zIndex: 1, props: { text: 'A', fontSize: 16, color: '#000' } }, // 기준(o2) - 좌/우 에지: 200, 280 { id: 'o2', type: 'text', x: 200, y: 50, width: 80, height: 30, rotate: 0, zIndex: 0, props: { text: 'B', fontSize: 16, color: '#000' } }, ]} ] } describe('Canvas guidelines advanced (edge snap)', () => { beforeEach(() => capture.mockReset()) it('snaps left edge to other object left edge within 8px threshold and shows vertical guide', async () => { render() const last = capture.mock.calls.at(-1)?.[0] as MProps expect(last).toBeTruthy() await act(async () => { last.onDragStart?.() }) // o2.left = 200. o1을 205로 제안하면 임계(≤8px) 내 → 200으로 스냅 await act(async () => { last.onDrag?.({ left: 205, top: 10 }) }) const obj = screen.getByTestId('obj-o1') as HTMLElement await waitFor(() => { expect(obj.style.left).toBe('200px') }) // 수직 가이드 라인 표시(에지 x=200) await screen.findByTestId('guide-x') await act(async () => { last.onDragEnd?.() }) await waitFor(() => { expect(screen.queryByTestId('guide-x')).toBeNull() }) }) })