import { act, renderHook } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; import { travelFieldKey, useTravelTime, type TravelTimeEntry } from './useTravelTime'; describe('useTravelTime', () => { it('creates backend field keys from mode and destination slug', () => { expect( travelFieldKey({ mode: 'transit', slug: 'kings-cross', label: 'Kings Cross', timeRange: [0, 45], useBest: true, }) ).toBe('tt_transit_kings-cross'); }); it('adds, updates, toggles, and removes travel-time entries', () => { const { result } = renderHook(() => useTravelTime()); act(() => result.current.handleAddEntry('transit')); expect(result.current.entries).toEqual([ { mode: 'transit', slug: '', label: '', timeRange: null, useBest: false }, ]); expect(result.current.activeEntries).toEqual([]); act(() => result.current.handleSetDestination(0, 'bank', 'Bank')); expect(result.current.entries[0]).toMatchObject({ slug: 'bank', label: 'Bank', timeRange: [0, 120], }); expect(result.current.activeEntries).toHaveLength(1); act(() => result.current.handleTimeRangeChange(0, [10, 35])); expect(result.current.entries[0].timeRange).toEqual([10, 35]); act(() => result.current.handleToggleBest(0)); expect(result.current.entries[0].useBest).toBe(true); act(() => result.current.handleRemoveEntry(0)); expect(result.current.entries).toEqual([]); }); it('replaces entries wholesale for AI-generated filters', () => { const initial: TravelTimeEntry = { mode: 'walking', slug: 'old', label: 'Old', timeRange: [0, 20], useBest: false, }; const replacement: TravelTimeEntry = { mode: 'car', slug: 'new', label: 'New', timeRange: [5, 30], useBest: false, }; const { result } = renderHook(() => useTravelTime({ entries: [initial] })); act(() => result.current.handleSetEntries([replacement])); expect(result.current.entries).toEqual([replacement]); expect(result.current.activeEntries).toEqual([replacement]); }); it('deduplicates initial and replacement entries using the tightest range', () => { const wide: TravelTimeEntry = { mode: 'transit', slug: 'bank-tube-station', label: 'Bank', timeRange: [0, 60], useBest: false, }; const tight: TravelTimeEntry = { mode: 'transit', slug: 'bank-tube-station', label: 'Bank', timeRange: [10, 45], useBest: false, }; const replacement: TravelTimeEntry = { mode: 'transit', slug: 'bank-tube-station', label: 'Bank', timeRange: [20, 40], useBest: true, }; const { result } = renderHook(() => useTravelTime({ entries: [wide, tight] })); expect(result.current.entries).toEqual([ { mode: 'transit', slug: 'bank-tube-station', label: 'Bank', timeRange: [10, 45], useBest: false, }, ]); act(() => result.current.handleSetEntries([wide, replacement])); expect(result.current.entries).toEqual([ { mode: 'transit', slug: 'bank-tube-station', label: 'Bank', timeRange: [20, 40], useBest: true, }, ]); }); });