Skip to content

Commit a6a39cc

Browse files
committed
fix(tests): mock ToastContext in Scans polling tests
1 parent 650db79 commit a6a39cc

1 file changed

Lines changed: 12 additions & 15 deletions

File tree

frontend/testing/unit/pages/Scans.polling.test.tsx

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@ import { MemoryRouter } from 'react-router-dom';
33
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
44
import Scans from '../../../src/pages/Scans';
55

6-
// ── Mocks ────────────────────────────────────────────────────────────────────
7-
86
vi.mock('../../../src/api', () => ({
97
API_BASE: 'http://localhost',
108
deleteTask: vi.fn(),
119
clearAllTasks: vi.fn(),
1210
bulkDeleteTasks: vi.fn(),
1311
}));
1412

13+
vi.mock('../../../src/components/ToastContext', () => ({
14+
useToast: () => ({
15+
addToast: vi.fn(),
16+
removeToast: vi.fn(),
17+
}),
18+
ToastProvider: ({ children }: any) => children,
19+
}));
20+
1521
vi.mock('react-router-dom', async (importOriginal) => {
1622
const actual = await importOriginal<typeof import('react-router-dom')>();
1723
return { ...actual, useNavigate: () => vi.fn() };
@@ -49,10 +55,7 @@ beforeEach(() => {
4955
json: () => Promise.resolve(EMPTY_RESPONSE),
5056
});
5157
vi.stubGlobal('fetch', fetchSpy);
52-
53-
// Use fake timers; microtasks drained via Promise.resolve() chains in flush()/tickTime()
5458
vi.useFakeTimers();
55-
5659
Object.defineProperty(document, 'visibilityState', {
5760
configurable: true,
5861
get: () => 'visible',
@@ -81,7 +84,6 @@ function setVisibility(state: 'visible' | 'hidden') {
8184
document.dispatchEvent(new Event('visibilitychange'));
8285
}
8386

84-
// Drain pending microtasks — works with Vitest 2.1.x.
8587
async function flush() {
8688
await act(async () => {
8789
await Promise.resolve();
@@ -90,7 +92,6 @@ async function flush() {
9092
});
9193
}
9294

93-
// Advance fake timers then drain microtasks so fetch callbacks settle.
9495
async function tickTime(ms: number) {
9596
await act(async () => {
9697
vi.advanceTimersByTime(ms);
@@ -114,8 +115,6 @@ function deferredResponse(body: unknown) {
114115
};
115116
}
116117

117-
// ── Tests ────────────────────────────────────────────────────────────────────
118-
119118
describe('Scans — visibility-aware polling', () => {
120119
it('fires one fetch on mount', async () => {
121120
renderScans();
@@ -154,13 +153,13 @@ describe('Scans — visibility-aware polling', () => {
154153

155154
setVisibility('hidden');
156155
await tickTime(15_000);
157-
expect(fetchSpy).toHaveBeenCalledTimes(1); // still paused
156+
expect(fetchSpy).toHaveBeenCalledTimes(1);
158157

159158
setVisibility('visible');
160-
await flush(); // immediate fetch on resume
159+
await flush();
161160
expect(fetchSpy).toHaveBeenCalledTimes(2);
162161

163-
await tickTime(5_000); // interval restarts
162+
await tickTime(5_000);
164163
expect(fetchSpy).toHaveBeenCalledTimes(3);
165164
});
166165

@@ -172,7 +171,6 @@ describe('Scans — visibility-aware polling', () => {
172171
await tickTime(5_000);
173172
await tickTime(5_000);
174173
await tickTime(5_000);
175-
// 1 mount + 3 ticks = exactly 4
176174
expect(fetchSpy).toHaveBeenCalledTimes(4);
177175
});
178176

@@ -186,7 +184,6 @@ describe('Scans — visibility-aware polling', () => {
186184
unmount();
187185

188186
await tickTime(15_000);
189-
// No extra fetches after unmount
190187
expect(fetchSpy).toHaveBeenCalledTimes(callsAfterMount);
191188
expect(removeSpy).toHaveBeenCalledWith('visibilitychange', expect.any(Function));
192189
});
@@ -225,4 +222,4 @@ describe('Scans — visibility-aware polling', () => {
225222
expect(screen.getByText('Latest Tool')).toBeInTheDocument();
226223
expect(screen.queryByText('Stale Tool')).not.toBeInTheDocument();
227224
});
228-
});
225+
});

0 commit comments

Comments
 (0)