157 lines
7.4 KiB
TypeScript
157 lines
7.4 KiB
TypeScript
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)
|
|
})
|
|
})
|