import { describe, expect, it } from 'vitest' import { buildListParams, getColumnFilterConfig, serializeFilters, withRowKeys } from '@/components/paginated-list/paginatedListUtils' import type { PaginationListColumnType } from '@/types' describe('paginatedListUtils', () => { it('serializes scalar and range filters without mutating the input', () => { const filters = { status: 'active', price: { from: '10', to: '20' }, ignored: '' } expect(serializeFilters(filters)).toEqual({ status: 'active', price: '10,20' }) expect(filters.price).toEqual({ from: '10', to: '20' }) }) it('merges inherited filters and applies an optional API prefix', () => { expect( buildListParams({ filterPrefix: 'booking', filters: { status: 'paid' }, page: 2, rowsPerPage: 30, sort: '-createdAt', urlParams: { page: 1, pageSize: 20, filters: { owner: 'me' } }, }) ).toEqual({ 'booking.page': 2, 'booking.pageSize': 30, 'booking.filters': { owner: 'me', status: 'paid' }, 'booking.sort': '-createdAt', }) }) it('creates stable row keys from row id, customer id, or index', () => { expect(withRowKeys([{ id: 7 }, { customer: { id: 'customer-1' } }, { title: 'fallback' }])).toEqual([ { id: '7' }, { customer: { id: 'customer-1' }, id: 'customer-1' }, { title: 'fallback', id: 'row-2' }, ]) }) // getColumnFilterConfig is the single source of truth both // PaginatedListColumnFilter (inline) and PaginatedListFilterModal (modal) // dispatch off of via PaginatedListFilterField (FE-4-T1) — locking down // this mapping is what keeps the two call sites structurally unable to // diverge for a new column type, in place of testing each consumer // separately. describe('getColumnFilterConfig', () => { const column = (type?: PaginationListColumnType['type'], filterItems?: unknown[]) => ({ field: 'f', label: 'F', type, filterItems }) as PaginationListColumnType it('maps text, number, and untyped columns to scalar', () => { expect(getColumnFilterConfig(column(undefined))).toBe('scalar') expect(getColumnFilterConfig(column('text'))).toBe('scalar') expect(getColumnFilterConfig(column('number'))).toBe('scalar') }) it('maps inputFromTo to range', () => { expect(getColumnFilterConfig(column('inputFromTo'))).toBe('range') }) it('maps select to select only when filterItems are present, else none', () => { expect(getColumnFilterConfig(column('select', [{ code: '1', name: 'One' }]))).toBe('select') expect(getColumnFilterConfig(column('select', []))).toBe('none') expect(getColumnFilterConfig(column('select'))).toBe('none') }) it('maps date to date and dateFromTo to dateRange', () => { expect(getColumnFilterConfig(column('date'))).toBe('date') expect(getColumnFilterConfig(column('dateFromTo'))).toBe('dateRange') }) it('falls back to none for an unrecognized type', () => { expect(getColumnFilterConfig(column('somethingNew' as never))).toBe('none') }) }) })