import { afterEach, describe, expect, it, vi } from 'vitest' import { queryClient, queryKeys } from '../src/api/queryClient' import { applyTaskBoardCardDelta, type TaskBoardCardDto, type TaskBoardPageDto } from '../src/api/taskBoard' afterEach(() => { queryClient.clear() }) describe('canonical server-state query cache', () => { it('deduplicates three simultaneous consumers into one HTTP query', async () => { let resolveRequest: ((value: string[]) => void) | undefined const response = new Promise(resolve => { resolveRequest = resolve }) const queryFn = vi.fn(() => response) const options = { queryKey: queryKeys.projects(), queryFn, staleTime: 15_000, } const consumers = [ queryClient.fetchQuery(options), queryClient.fetchQuery(options), queryClient.fetchQuery(options), ] expect(queryFn).toHaveBeenCalledTimes(1) resolveRequest?.(['project-1']) await expect(Promise.all(consumers)).resolves.toEqual([ ['project-1'], ['project-1'], ['project-1'], ]) expect(queryFn).toHaveBeenCalledTimes(1) }) it('moves a persisted task delta between board columns without a full snapshot', () => { const card: TaskBoardCardDto = { id: '0d2d33d7-bafa-4510-b135-c6a96021957a', title: 'Release review', detail: null, source: 'bao', state: 'Backlog', priority: 'Medium', assignedTo: 'bao', parentTaskId: null, projectId: null, dueDate: null, createdAt: '2026-07-31T08:00:00.000Z', updatedAt: '2026-07-31T08:00:00.000Z', isAgentTask: false, expectedFrom: null, lastActivityMessage: null, lastActivityAt: null, childTaskCount: 0, openChildTaskCount: 0, hasVisibleDelegation: false, } const page: TaskBoardPageDto = { revision: 'board-r1', offen: [card], inProgress: [], review: [], blocked: [], done: [], nextDoneCursor: null, hasMoreDone: false, } queryClient.setQueryData(queryKeys.taskBoard(50), { pages: [page], pageParams: [null], }) applyTaskBoardCardDelta({ ...card, state: 'Review', updatedAt: '2026-07-31T08:01:00.000Z', }) const result = queryClient.getQueryData<{ pages: TaskBoardPageDto[] pageParams: Array }>(queryKeys.taskBoard(50)) expect(result?.pages[0]?.offen).toEqual([]) expect(result?.pages[0]?.review.map(item => item.id)).toEqual([card.id]) }) })