teqo-backup/tests/unit/campaignHeaderFilterPopover.unit.spec.ts
Francisco Ignácio Fontoura Solla 0b6843eb80 Polish selected-first filter shells after simplify.
Drop redundant comments, use a Set for mobile checkmarks, and keep behavior unchanged.
2026-07-28 18:37:05 -03:00

201 lines
5.5 KiB
TypeScript

import { cleanup, fireEvent, render, screen, within } from '@testing-library/react'
import { createElement, useState } from 'react'
import { afterEach, describe, expect, it, vi } from 'vitest'
vi.mock('next/navigation', async (importActual) => ({
...(await importActual()),
useRouter: () => ({ replace: vi.fn(), push: vi.fn() }),
}))
import {
CampaignHeaderFilterPopover,
type CampaignHeaderFilterRow,
} from '@/components/campaign/shared/CampaignHeaderFilterPopover'
afterEach(cleanup)
const labelsInOrder = (nav: HTMLElement) =>
within(nav)
.getAllByRole('link')
.map((link) => link.textContent?.trim() ?? '')
const multiRows = (selected: ReadonlySet<string>): CampaignHeaderFilterRow[] =>
[
{ value: 'a', label: 'Alpha' },
{ value: 'b', label: 'Beta' },
{ value: 'c', label: 'Charlie' },
{ value: 'd', label: 'Delta' },
{ value: 'e', label: 'Echo' },
{ value: 'f', label: 'Foxtrot' },
{ value: 'g', label: 'Golf' },
{ value: 'h', label: 'Hotel' },
].map((option) => ({
...option,
href: `/campanha/municipios?region=${option.value}`,
selected: selected.has(option.value),
checkbox: true,
onChoose: () => undefined,
}))
const singleRows = (selected: string | null): CampaignHeaderFilterRow[] => [
{
value: '',
label: 'Todas',
href: '/campanha/municipios',
selected: selected === null,
onChoose: () => undefined,
},
{
value: 'municipio',
label: 'Município',
href: '/campanha/municipios?kind=municipio',
selected: selected === 'municipio',
onChoose: () => undefined,
},
{
value: 'zona',
label: 'Zona eleitoral',
href: '/campanha/municipios?kind=zona',
selected: selected === 'zona',
onChoose: () => undefined,
},
]
const openFilter = (label = 'Território') => {
fireEvent.click(screen.getByRole('button', { name: new RegExp(`Filtrar.*${label}`) }))
}
const optionNav = () => screen.getByRole('navigation', { name: 'Território' })
/** Popover + external button that replaces the selected set (simulates parent re-render). */
const SnapshotHarness = ({
initialSelected,
nextSelected,
buttonLabel,
}: {
initialSelected: ReadonlySet<string>
nextSelected: ReadonlySet<string>
buttonLabel: string
}) => {
const [selected, setSelected] = useState(() => new Set(initialSelected))
return createElement(
'div',
null,
createElement(CampaignHeaderFilterPopover, {
id: 'filter-region',
label: 'Território',
active: true,
optionRows: multiRows(selected),
}),
createElement(
'button',
{
type: 'button',
onClick: () => setSelected(new Set(nextSelected)),
},
buttonLabel,
),
)
}
describe('CampaignHeaderFilterPopover selected-first ordering', () => {
it('lifts selected options to the top when the popover opens', () => {
render(
createElement(CampaignHeaderFilterPopover, {
id: 'filter-region',
label: 'Território',
active: true,
optionRows: multiRows(new Set(['c', 'a'])),
}),
)
openFilter()
expect(labelsInOrder(optionNav())).toEqual([
'Alpha',
'Charlie',
'Beta',
'Delta',
'Echo',
'Foxtrot',
'Golf',
'Hotel',
])
})
it('freezes order while open when the parent re-renders with a new selection', () => {
render(
createElement(SnapshotHarness, {
initialSelected: new Set(['c', 'a']),
nextSelected: new Set(['a']),
buttonLabel: 'Drop Charlie',
}),
)
openFilter()
expect(labelsInOrder(optionNav()).slice(0, 2)).toEqual(['Alpha', 'Charlie'])
fireEvent.click(screen.getByRole('button', { name: 'Drop Charlie' }))
// Snapshot still has both — Charlie stays at the top even though unchecked.
expect(labelsInOrder(optionNav()).slice(0, 2)).toEqual(['Alpha', 'Charlie'])
expect(screen.getByRole('link', { name: 'Charlie' }).getAttribute('aria-current')).toBeNull()
expect(screen.getByRole('link', { name: 'Alpha' }).getAttribute('aria-current')).toBe('true')
})
it('regroups on the next open after closing', () => {
render(
createElement(SnapshotHarness, {
initialSelected: new Set(['c', 'a']),
nextSelected: new Set(['d']),
buttonLabel: 'Select Delta only',
}),
)
openFilter()
// Close via the trigger (Radix toggles).
openFilter()
fireEvent.click(screen.getByRole('button', { name: 'Select Delta only' }))
openFilter()
expect(labelsInOrder(optionNav())[0]).toBe('Delta')
})
it('keeps selected-first order among search matches', () => {
render(
createElement(CampaignHeaderFilterPopover, {
id: 'filter-region',
label: 'Território',
active: true,
optionRows: multiRows(new Set(['h', 'f'])),
}),
)
openFilter()
fireEvent.change(screen.getByRole('textbox', { name: 'Buscar em Território' }), {
target: { value: 'o' },
})
expect(labelsInOrder(optionNav())).toEqual(['Foxtrot', 'Hotel', 'Echo', 'Golf'])
})
it('does not reorder single-select rows (no checkbox)', () => {
render(
createElement(CampaignHeaderFilterPopover, {
id: 'filter-kind',
label: 'Tipo',
active: true,
closeOnChoose: true,
optionRows: singleRows('zona'),
}),
)
fireEvent.click(screen.getByRole('button', { name: /Filtrar.*Tipo/ }))
expect(labelsInOrder(screen.getByRole('navigation', { name: 'Tipo' }))).toEqual([
'Todas',
'Município',
'Zona eleitoral',
])
})
})