feat(worker): poll + reconcile stopwatch to server (admin stop/cancel)
This commit is contained in:
@@ -4,6 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import type { Activity, WorkSession } from '@solelog/shared';
|
||||
import Stopwatch from './Stopwatch';
|
||||
import { ApiError } from '../lib/api';
|
||||
import { useActivities } from '../api/activities';
|
||||
import {
|
||||
useActiveSessions,
|
||||
@@ -247,4 +248,52 @@ describe('Stopwatch', () => {
|
||||
|
||||
expect(await screen.findByText('Gepauzeerd — tik om te hervatten')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('resets and shows a notice when the running session is stopped by the admin', async () => {
|
||||
// Start with the session present so the screen adopts the running state.
|
||||
mockedUseActiveSessions.mockReturnValue(
|
||||
query<ReturnType<typeof useActiveSessions>>([activeSession()]),
|
||||
);
|
||||
const { rerender } = renderStopwatch();
|
||||
|
||||
// Confirm we are running (the Stop & Opslaan button is shown).
|
||||
await screen.findByRole('button', { name: 'Stop & Opslaan' });
|
||||
|
||||
// The admin stops the session: the active list now no longer contains it.
|
||||
mockedUseActiveSessions.mockReturnValue(query<ReturnType<typeof useActiveSessions>>([]));
|
||||
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
||||
rerender(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Stopwatch />
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
|
||||
// The stopwatch resets to idle and shows the admin-stopped notice.
|
||||
expect(
|
||||
await screen.findByText('Deze sessie is door de beheerder gestopt.'),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: 'Start Stopwatch' })).toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: 'Stop & Opslaan' })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('resets locally when stop fails with a 409 (already closed)', async () => {
|
||||
const user = userEvent.setup();
|
||||
stopMutate.mockImplementation((_id: number, opts?: { onError?: (e: unknown) => void }) => {
|
||||
opts?.onError?.(new ApiError(409, 'Conflict'));
|
||||
});
|
||||
mockedUseActiveSessions.mockReturnValue(
|
||||
query<ReturnType<typeof useActiveSessions>>([activeSession()]),
|
||||
);
|
||||
renderStopwatch();
|
||||
|
||||
const stopBtn = await screen.findByRole('button', { name: 'Stop & Opslaan' });
|
||||
await user.click(stopBtn);
|
||||
|
||||
expect(stopMutate).toHaveBeenCalledTimes(1);
|
||||
// The timer resets to idle despite the 409 (no stuck running state).
|
||||
await waitFor(() =>
|
||||
expect(screen.getByRole('button', { name: 'Start Stopwatch' })).toBeInTheDocument(),
|
||||
);
|
||||
expect(screen.queryByRole('button', { name: 'Stop & Opslaan' })).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user