Files
TREK/client/src/components/Tours/useTourDayAssignment.test.ts
T
Maurice 52ed63715c Tours: tests follow the provenance read and the shared day assignment, the tours addon ends MCP sessions, a line without a point is not copied
The repository stubs of the tour service tests answer findProvenance, which getTour and createTour read since P2C-02.
Switching the Tours addon off now ends live MCP sessions like every other addon that gates a tool (MCP-GATE-PARITY-001).
copyTour refuses a line without a point instead of placing the copy at 0/0, and new tests cover the reachable paths
of the copy, the source check and the provenance of a snapshot without its import record, including a trip copy
keeping that record. On the client the shared day assignment hands the plan exactly the tour and the day, the new
visibility store is reset between tests, and the tests of the sidebar, the detail, the phone sheet and the origin
section match the views this PR built.
2026-10-15 22:34:33 +00:00

69 lines
3.0 KiB
TypeScript

import { act, renderHook } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { resetAllStores, seedStore } from '../../../tests/helpers/store';
import { useTripStore } from '../../store/tripStore';
import type { AssignmentsMap } from '../../types';
import { isTourOnDay, useTourDayAssignment } from './useTourDayAssignment';
const assignments = { '3': [{ id: 31, place_id: 42 }], '4': [] } as unknown as AssignmentsMap;
beforeEach(() => {
resetAllStores();
seedStore(useTripStore, { assignments });
});
describe('isTourOnDay (PR1-18)', () => {
it('reads the day lists: a tour is on a day once it has an assignment there', () => {
expect(isTourOnDay(assignments, 42, 3)).toBe(true);
expect(isTourOnDay(assignments, 42, 4)).toBe(false);
expect(isTourOnDay(assignments, 42, 99)).toBe(false);
});
});
describe('useTourDayAssignment (PR1-18)', () => {
it('offers only a day that does not have the tour yet, and nothing without the right', () => {
const allowed = renderHook(() => useTourDayAssignment({ canAssign: true, onAssignToDay: vi.fn() }));
expect(allowed.result.current.isOnDay(42, 3)).toBe(true);
expect(allowed.result.current.isAvailable(42, 3)).toBe(false);
expect(allowed.result.current.isAvailable(42, 4)).toBe(true);
const denied = renderHook(() => useTourDayAssignment({ canAssign: false, onAssignToDay: vi.fn() }));
expect(denied.result.current.isAvailable(42, 4)).toBe(false);
});
it('sends one write per tour and day while it is on its way, and says whether it happened', async () => {
let finish: (value: boolean) => void = () => undefined;
const onAssignToDay = vi.fn(() => new Promise<boolean>((resolve) => (finish = resolve)));
const { result } = renderHook(() => useTourDayAssignment({ canAssign: true, onAssignToDay }));
let first: Promise<boolean> = Promise.resolve(false);
let second: Promise<boolean> = Promise.resolve(false);
act(() => {
first = result.current.assign(42, 4);
second = result.current.assign(42, 4);
});
expect(onAssignToDay).toHaveBeenCalledTimes(1);
expect(onAssignToDay).toHaveBeenCalledWith(42, 4);
expect(await second).toBe(false);
expect(result.current.isPending(42, 4)).toBe(true);
expect(result.current.isAvailable(42, 4)).toBe(false);
await act(async () => {
finish(true);
expect(await first).toBe(true);
});
expect(result.current.isPending(42, 4)).toBe(false);
});
it('reports a refused write as not done, and a day that has the tour is not even asked', async () => {
const onAssignToDay = vi.fn(async () => false);
const { result } = renderHook(() => useTourDayAssignment({ canAssign: true, onAssignToDay }));
await act(async () => {
expect(await result.current.assign(42, 4)).toBe(false);
expect(await result.current.assign(42, 3)).toBe(false);
});
expect(onAssignToDay).toHaveBeenCalledTimes(1);
expect(onAssignToDay).toHaveBeenCalledWith(42, 4);
});
});