teqo-backup/tests/unit/campaignLongPress.unit.spec.tsx
Francisco Ignácio Fontoura Solla 274cde65a7 B58: polish Início action strip and centralize coarse press state.
Short staff labels, hidden scrollbar, circle feedback on hover/press, and long-press pressing lives in useCampaignLongPress for reuse.
2026-07-29 16:10:24 -03:00

117 lines
3.6 KiB
TypeScript

import { act, cleanup, fireEvent, render, screen } from '@testing-library/react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { CAMPAIGN_LONG_PRESS_MS, useCampaignLongPress } from '@/lib/campaignLongPress'
const LongPressHarness = ({
onLongPress,
onClick,
}: {
onLongPress: () => void
onClick?: () => void
}) => {
const { pressing, ...handlers } = useCampaignLongPress({
enabled: true,
onLongPress,
onClick,
})
return (
<button type="button" data-pressing={pressing ? true : undefined} {...handlers}>
Alvo
</button>
)
}
beforeEach(() => {
vi.useFakeTimers()
})
afterEach(() => {
cleanup()
vi.useRealTimers()
})
describe('useCampaignLongPress', () => {
it('calls onLongPress after the threshold and suppresses the following click', () => {
const onLongPress = vi.fn()
const onClick = vi.fn()
render(<LongPressHarness onLongPress={onLongPress} onClick={onClick} />)
const target = screen.getByRole('button', { name: 'Alvo' })
fireEvent.pointerDown(target, { button: 0, clientX: 0, clientY: 0 })
act(() => {
vi.advanceTimersByTime(CAMPAIGN_LONG_PRESS_MS)
})
expect(onLongPress).toHaveBeenCalledTimes(1)
fireEvent.pointerUp(target)
fireEvent.click(target)
expect(onClick).not.toHaveBeenCalled()
})
it('calls onClick on a short tap', () => {
const onLongPress = vi.fn()
const onClick = vi.fn()
render(<LongPressHarness onLongPress={onLongPress} onClick={onClick} />)
const target = screen.getByRole('button', { name: 'Alvo' })
fireEvent.pointerDown(target, { button: 0, clientX: 0, clientY: 0 })
fireEvent.pointerUp(target)
fireEvent.click(target)
expect(onLongPress).not.toHaveBeenCalled()
expect(onClick).toHaveBeenCalledTimes(1)
})
it('aborts when the pointer moves beyond slop', () => {
const onLongPress = vi.fn()
render(<LongPressHarness onLongPress={onLongPress} />)
const target = screen.getByRole('button', { name: 'Alvo' })
fireEvent.pointerDown(target, { button: 0, clientX: 0, clientY: 0 })
fireEvent.pointerMove(target, { clientX: 24, clientY: 0 })
act(() => {
vi.advanceTimersByTime(CAMPAIGN_LONG_PRESS_MS)
})
expect(onLongPress).not.toHaveBeenCalled()
})
it('clears the timer on pointercancel', () => {
const onLongPress = vi.fn()
render(<LongPressHarness onLongPress={onLongPress} />)
const target = screen.getByRole('button', { name: 'Alvo' })
fireEvent.pointerDown(target, { button: 0, clientX: 0, clientY: 0 })
fireEvent.pointerCancel(target)
act(() => {
vi.advanceTimersByTime(CAMPAIGN_LONG_PRESS_MS)
})
expect(onLongPress).not.toHaveBeenCalled()
})
it('sets pressing while the primary pointer is down', () => {
const onLongPress = vi.fn()
render(<LongPressHarness onLongPress={onLongPress} />)
const target = screen.getByRole('button', { name: 'Alvo' })
expect(target.getAttribute('data-pressing')).toBeNull()
fireEvent.pointerDown(target, { button: 0, clientX: 0, clientY: 0 })
expect(target.getAttribute('data-pressing')).toBe('true')
fireEvent.pointerUp(target)
expect(target.getAttribute('data-pressing')).toBeNull()
})
it('does not call onLongPress after unmount during the hold', () => {
const onLongPress = vi.fn()
const { unmount } = render(<LongPressHarness onLongPress={onLongPress} />)
const target = screen.getByRole('button', { name: 'Alvo' })
fireEvent.pointerDown(target, { button: 0, clientX: 0, clientY: 0 })
unmount()
act(() => {
vi.advanceTimersByTime(CAMPAIGN_LONG_PRESS_MS)
})
expect(onLongPress).not.toHaveBeenCalled()
})
})