테스트/린트 안정화: 버튼 쿼리 모호성 제거, 훅 deps 보강, vi.spyOn 모킹, 멀티선택 Moveable 간섭 방지 재확인, 스냅 우선순위 회귀 그린
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
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(<WysiwygBuilderPage />)
|
||||
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(<WysiwygBuilderPage />)
|
||||
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(<WysiwygBuilderPage />)
|
||||
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(<WysiwygBuilderPage />)
|
||||
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(<WysiwygBuilderPage />)
|
||||
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(<WysiwygBuilderPage />)
|
||||
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)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user