Files
TREK/client/src/components/Budget/useCostsMode.test.ts
T
Maurice c2ba78253d fix(client): lint, theme and size ratchets of the quick-win round, and the tests that followed the features
New warnings fixed at their source (refs written in effects, typed tile
options, no stray imports, smaller functions and components), the payer and
split heads hold their switch instead of letting it overhang, the baselines
lowered where the round removed warnings, and the tests updated to the
solo trip, the shares view and the revisit status.
2026-11-13 12:40:17 +01:00

54 lines
2.5 KiB
TypeScript

// FE-BUDGET-COSTSMODE-001 to FE-BUDGET-COSTSMODE-003
import { act, renderHook } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { buildTrip } from '../../../tests/helpers/factories';
import { resetAllStores } from '../../../tests/helpers/store';
import { useTripStore, type TripStoreState } from '../../store/tripStore';
import { useCostsMode } from './useCostsMode';
const toast = vi.hoisted(() => ({ error: vi.fn(), success: vi.fn(), info: vi.fn(), warning: vi.fn() }));
vi.mock('../shared/Toast', () => ({ useToast: () => toast }));
let updateTrip: ReturnType<typeof vi.fn>;
const trip = (costsMode?: 'split' | 'totals') => buildTrip({ id: 7, ...(costsMode ? { costs_mode: costsMode } : {}) });
beforeEach(() => {
resetAllStores();
updateTrip = vi.fn(async () => buildTrip({ id: 7 }));
useTripStore.setState({ updateTrip } as unknown as Partial<TripStoreState>);
toast.error.mockClear();
});
describe('useCostsMode (#1714)', () => {
it('FE-BUDGET-COSTSMODE-001: a trip splits its costs until it says otherwise, and keeps totals only when it does', () => {
expect(renderHook(() => useCostsMode(trip(), 2, true)).result.current.splitting).toBe(true);
expect(renderHook(() => useCostsMode(trip('split'), 2, true)).result.current.splitting).toBe(true);
expect(renderHook(() => useCostsMode(trip('totals'), 2, true)).result.current.splitting).toBe(false);
});
it('FE-BUDGET-COSTSMODE-002: the switch is offered to whoever may edit the costs, on a trip of more than one', () => {
expect(renderHook(() => useCostsMode(trip(), 2, true)).result.current.offered).toBe(true);
expect(renderHook(() => useCostsMode(trip(), 1, true)).result.current.offered).toBe(false);
expect(renderHook(() => useCostsMode(trip(), 3, false)).result.current.offered).toBe(false);
});
it('FE-BUDGET-COSTSMODE-003: switching saves the mode on the trip, and a failure says so', async () => {
const { result } = renderHook(() => useCostsMode(trip(), 2, true));
await act(async () => {
await result.current.setSplitting(false);
});
expect(updateTrip).toHaveBeenCalledWith(7, { costs_mode: 'totals' });
expect(result.current.saving).toBe(false);
updateTrip.mockRejectedValueOnce(new Error('offline'));
await act(async () => {
await result.current.setSplitting(true);
});
expect(updateTrip).toHaveBeenLastCalledWith(7, { costs_mode: 'split' });
expect(toast.error).toHaveBeenCalled();
expect(result.current.saving).toBe(false);
});
});