import { describe, it, expect } from 'vitest' import { render, screen, fireEvent } from '@testing-library/react' import { WysiwygBuilderPage } from '@/components/wysiwyg/WysiwygBuilderPage' function getBox() { const el = screen.getByTestId(/obj-text-/) as HTMLElement const style = el.style const left = parseInt(style.left || '0', 10) const top = parseInt(style.top || '0', 10) const width = parseInt(style.width || '0', 10) const height = parseInt(style.height || '0', 10) return { left, top, width, height } } function snap8(v: number) { return Math.round(v / 8) * 8 } describe('WYSIWYG Builder - Resize directional handles', () => { it('left handle resizes by moving left edge and shifts x', async () => { render() fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i })) const obj = await screen.findByTestId(/obj-text-/) // select fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 }) // end any potential drag fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const before = getBox() const hLeft = await screen.findByTestId(/resize-handle-w-/) // drag left handle to the left by 16px (two 8px snaps) fireEvent.mouseDown(hLeft, { clientX: before.left, clientY: before.top + 5 }) fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left - 16, clientY: before.top + 5 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const after = getBox() const expectedLeft = Math.min(snap8(before.left - 16), before.left + before.width - 8) const expectedWidth = (before.left + before.width) - expectedLeft expect(after.left).toBe(expectedLeft) expect(after.width).toBe(expectedWidth) // orthogonal axis may adjust minimally due to snapping/rounding; primary check is x/width }) it('corner NW handle moves left/top and expands width/height', async () => { render() fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i })) const obj = await screen.findByTestId(/obj-text-/) fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const before = getBox() const hNW = await screen.findByTestId(/resize-handle-nw-/) fireEvent.mouseDown(hNW, { clientX: before.left, clientY: before.top }) fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left - 16, clientY: before.top - 16 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const after = getBox() const expLeft = Math.min(snap8(before.left - 16), before.left + before.width - 8) const expTop = Math.min(snap8(before.top - 16), before.top + before.height - 8) expect(after.left).toBe(expLeft) expect(after.top).toBe(expTop) expect(after.width).toBe((before.left + before.width) - expLeft) expect(after.height).toBe((before.top + before.height) - expTop) }) it('corner SW handle moves left and expands height with bottom drag', async () => { render() fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i })) const obj = await screen.findByTestId(/obj-text-/) fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const before = getBox() const hSW = await screen.findByTestId(/resize-handle-sw-/) fireEvent.mouseDown(hSW, { clientX: before.left, clientY: before.top + before.height }) fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left - 16, clientY: before.top + before.height + 16 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const after = getBox() const expLeft2 = Math.min(snap8(before.left - 16), before.left + before.width - 8) expect(after.left).toBe(expLeft2) expect(after.width).toBe((before.left + before.width) - expLeft2) // bottom 증가, top은 유지 expect(after.top).toBe(before.top) expect(after.height).toBe(snap8(before.height + 16)) }) it('top handle resizes by moving top edge and shifts y', async () => { render() fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i })) const obj = await screen.findByTestId(/obj-text-/) fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const before = getBox() const hTop = await screen.findByTestId(/resize-handle-n-/) fireEvent.mouseDown(hTop, { clientX: before.left + 5, clientY: before.top }) fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left + 5, clientY: before.top - 16 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const after = getBox() const expectedTop = Math.min(snap8(before.top - 16), before.top + before.height - 8) const expectedHeight = (before.top + before.height) - expectedTop expect(after.top).toBe(expectedTop) expect(after.height).toBe(expectedHeight) // orthogonal axis may adjust minimally due to snapping; primary check is y/height }) it('right and bottom handles increase width/height without shifting origin', async () => { render() fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i })) const obj = await screen.findByTestId(/obj-text-/) fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 }) const before = getBox() const hRight = await screen.findByTestId(/resize-handle-e-/) fireEvent.mouseDown(hRight, { clientX: before.left + before.width, clientY: before.top + 5 }) fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left + before.width + 16, clientY: before.top + 5 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const mid = getBox() // primary check: width increased by snapped delta expect(mid.width).toBe(snap8(before.width + 16)) const hBottom = await screen.findByTestId(/resize-handle-s-/) fireEvent.mouseDown(hBottom, { clientX: mid.left + 5, clientY: mid.top + mid.height }) fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: mid.left + 5, clientY: mid.top + mid.height + 16 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const after = getBox() // origin should remain same on y for bottom handle expect(after.top).toBe(mid.top) expect(after.height).toBe(snap8(mid.height + 16)) }) it('corner NE handle adjusts width and height with appropriate origin shift on Y', async () => { render() fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i })) const obj = await screen.findByTestId(/obj-text-/) fireEvent.mouseDown(obj, { clientX: 80, clientY: 80 }) const before = getBox() const hNE = await screen.findByTestId(/resize-handle-ne-/) fireEvent.mouseDown(hNE, { clientX: before.left + before.width, clientY: before.top }) fireEvent.mouseMove(screen.getByTestId('wysiwyg-canvas'), { clientX: before.left + before.width + 16, clientY: before.top - 16 }) fireEvent.mouseUp(screen.getByTestId('wysiwyg-canvas')) const after = getBox() // NE: primary checks are top shifted up and width increased; left origin may adjust under snapping const expectedTop2 = Math.min(snap8(before.top - 16), before.top + before.height - 8) expect(after.top).toBe(expectedTop2) expect(after.width).toBe(snap8(before.width + 16)) expect(after.height).toBe((before.top + before.height) - expectedTop2) }) })