mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 06:43:06 +00:00
Staff see role-ranked shortcuts (advisor portfolio by signal age; CG/candidate by alta priority deficit) via POST mode suggest, without treating empty query as search.
113 lines
3 KiB
TypeScript
113 lines
3 KiB
TypeScript
import { act, renderHook } from '@testing-library/react'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import { useHomeSearchQuery } from '@/components/campaign/dashboard/useHomeSearchQuery'
|
|
import { HOME_SEARCH_DEBOUNCE_MS } from '@/lib/campaignHomeSearchContract'
|
|
|
|
describe('useHomeSearchQuery', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers()
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers()
|
|
})
|
|
|
|
it('debounces raw input before updating debounced and isActive', () => {
|
|
const { result } = renderHook(() => useHomeSearchQuery())
|
|
|
|
act(() => {
|
|
result.current.setRaw('ca')
|
|
})
|
|
|
|
expect(result.current.query.debounced).toBe('')
|
|
expect(result.current.query.isActive).toBe(false)
|
|
|
|
act(() => {
|
|
vi.advanceTimersByTime(HOME_SEARCH_DEBOUNCE_MS)
|
|
})
|
|
|
|
expect(result.current.query.debounced).toBe('ca')
|
|
expect(result.current.query.isActive).toBe(true)
|
|
})
|
|
|
|
it('does not activate until trimmed debounced length meets minimum', () => {
|
|
const { result } = renderHook(() => useHomeSearchQuery())
|
|
|
|
act(() => {
|
|
result.current.setRaw('a')
|
|
})
|
|
act(() => {
|
|
vi.advanceTimersByTime(HOME_SEARCH_DEBOUNCE_MS)
|
|
})
|
|
|
|
expect(result.current.query.isActive).toBe(false)
|
|
|
|
act(() => {
|
|
result.current.setRaw('ab')
|
|
})
|
|
act(() => {
|
|
vi.advanceTimersByTime(HOME_SEARCH_DEBOUNCE_MS)
|
|
})
|
|
|
|
expect(result.current.query.isActive).toBe(true)
|
|
})
|
|
|
|
it('trims debounced value and treats whitespace-only as inactive', () => {
|
|
const { result } = renderHook(() => useHomeSearchQuery())
|
|
|
|
act(() => {
|
|
result.current.setRaw(' ca ')
|
|
})
|
|
act(() => {
|
|
vi.advanceTimersByTime(HOME_SEARCH_DEBOUNCE_MS)
|
|
})
|
|
|
|
expect(result.current.query.debounced).toBe('ca')
|
|
expect(result.current.query.isActive).toBe(true)
|
|
|
|
act(() => {
|
|
result.current.setRaw(' ')
|
|
})
|
|
act(() => {
|
|
vi.advanceTimersByTime(HOME_SEARCH_DEBOUNCE_MS)
|
|
})
|
|
|
|
expect(result.current.query.debounced).toBe('')
|
|
expect(result.current.query.isActive).toBe(false)
|
|
})
|
|
|
|
it('clear resets raw, debounced, and debouncing state', () => {
|
|
const { result } = renderHook(() => useHomeSearchQuery())
|
|
|
|
act(() => {
|
|
result.current.setRaw('cairu')
|
|
})
|
|
act(() => {
|
|
vi.advanceTimersByTime(HOME_SEARCH_DEBOUNCE_MS)
|
|
})
|
|
|
|
expect(result.current.query.isActive).toBe(true)
|
|
|
|
act(() => {
|
|
result.current.clear()
|
|
})
|
|
|
|
expect(result.current.query.raw).toBe('')
|
|
expect(result.current.query.debounced).toBe('')
|
|
expect(result.current.query.isActive).toBe(false)
|
|
expect(result.current.isDebouncing).toBe(false)
|
|
expect(result.current.inputFocused).toBe(false)
|
|
})
|
|
|
|
it('uiFocused is true when input is focused without an active query', () => {
|
|
const { result } = renderHook(() => useHomeSearchQuery())
|
|
|
|
act(() => {
|
|
result.current.setInputFocused(true)
|
|
})
|
|
|
|
expect(result.current.uiFocused).toBe(true)
|
|
expect(result.current.query.isActive).toBe(false)
|
|
})
|
|
})
|