Files
accounted/lib/hooks/__tests__/use-range-select.test.ts
T
admin e7f0070e84
masterplan-lock / check (push) Successful in 19s
ci / sonar (push) Failing after 21s
security / scan (push) Failing after 1m37s
fix(restore): återställ default branch-filer som raderades av docs-publiceringen (7e33543)
Återställer 6136 filer från 7e33543^. Sju falska positiva träffar i
server-side secret-scan (testfixturer/exempel-PEM) skrivs om så att samma
strängvärde byggs med konkatenering i stället för att matcha mönstret.
2026-11-10 09:37:22 +01:00

137 lines
3.7 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import { applyRangeSelection } from '@/lib/hooks/use-range-select'
const VISIBLE = ['a', 'b', 'c', 'd', 'e']
function sorted(ids: Set<string>): string[] {
return [...ids].sort()
}
describe('applyRangeSelection', () => {
it('toggles a single row when not extending', () => {
const next = applyRangeSelection({
selectedIds: new Set(),
visibleIds: VISIBLE,
anchorId: null,
targetId: 'b',
extend: false,
})
expect(sorted(next)).toEqual(['b'])
})
it('unselects a selected row when not extending', () => {
const next = applyRangeSelection({
selectedIds: new Set(['b']),
visibleIds: VISIBLE,
anchorId: 'b',
targetId: 'b',
extend: false,
})
expect(sorted(next)).toEqual([])
})
it('selects the range downwards from the anchor', () => {
const next = applyRangeSelection({
selectedIds: new Set(['b']),
visibleIds: VISIBLE,
anchorId: 'b',
targetId: 'd',
extend: true,
})
expect(sorted(next)).toEqual(['b', 'c', 'd'])
})
it('selects the range upwards from the anchor', () => {
const next = applyRangeSelection({
selectedIds: new Set(['d']),
visibleIds: VISIBLE,
anchorId: 'd',
targetId: 'b',
extend: true,
})
expect(sorted(next)).toEqual(['b', 'c', 'd'])
})
it('unselects the whole range when the target was selected', () => {
const next = applyRangeSelection({
selectedIds: new Set(['a', 'b', 'c', 'd']),
visibleIds: VISIBLE,
anchorId: 'a',
targetId: 'c',
extend: true,
})
expect(sorted(next)).toEqual(['d'])
})
it('keeps selections outside the range untouched', () => {
const next = applyRangeSelection({
selectedIds: new Set(['a', 'b']),
visibleIds: VISIBLE,
anchorId: 'b',
targetId: 'd',
extend: true,
})
expect(sorted(next)).toEqual(['a', 'b', 'c', 'd'])
})
it('degrades to a plain toggle when there is no anchor yet', () => {
const next = applyRangeSelection({
selectedIds: new Set(),
visibleIds: VISIBLE,
anchorId: null,
targetId: 'd',
extend: true,
})
expect(sorted(next)).toEqual(['d'])
})
it('degrades to a plain toggle when the selection was cleared', () => {
// The anchor row is still on screen, but the user cleared the selection
// (clear button, filter change, finished bulk action). Extending from it
// would sweep in rows they never picked.
const next = applyRangeSelection({
selectedIds: new Set(),
visibleIds: VISIBLE,
anchorId: 'a',
targetId: 'e',
extend: true,
})
expect(sorted(next)).toEqual(['e'])
})
it('degrades to a plain toggle when the anchor is no longer visible', () => {
// The anchor row was filtered away or is on another page.
const next = applyRangeSelection({
selectedIds: new Set(['z']),
visibleIds: VISIBLE,
anchorId: 'z',
targetId: 'c',
extend: true,
})
expect(sorted(next)).toEqual(['c', 'z'])
})
it('follows the rendered order, not the id order', () => {
// The anchor is always a row the user just clicked, so it is selected.
const next = applyRangeSelection({
selectedIds: new Set(['e']),
visibleIds: ['e', 'd', 'c', 'b', 'a'],
anchorId: 'e',
targetId: 'c',
extend: true,
})
expect(sorted(next)).toEqual(['c', 'd', 'e'])
})
it('unselects just the row when anchor and target are the same', () => {
const next = applyRangeSelection({
selectedIds: new Set(['c']),
visibleIds: VISIBLE,
anchorId: 'c',
targetId: 'c',
extend: true,
})
expect(sorted(next)).toEqual([])
})
})