test: data router, one render helper, fetchRoutes in every test

This commit is contained in:
lobo committed 2026-09-29 16:15:50 +02:00
1 parent d0ea9e900d
commit 2a22789435
37 files changed
+454 -425

No files matched your search

+11 -17
View File
@@ -4,6 +4,7 @@ import {cleanup, fireEvent, render, screen, waitFor} from '@testing-library/reac
import {MemoryRouter} from 'react-router-dom';
import PlayNextPage from './PlayNextPage.jsx';
import {PreferencesProvider} from '../context/PreferencesContext.jsx';
import {fetchRoutes, json} from '../test/fetchRoutes.js';
vi.mock('react-i18next', () => import('../test/i18n-mock.js'));
vi.mock('sonner', () => ({toast: {success: vi.fn(), error: vi.fn()}}));
@@ -13,15 +14,13 @@ const game = (appid, extra = {}) => ({
timeToBeatMinutes: 600, ...extra,
});
const json = (body, status = 200) => ({ok: status < 400, status, json: async () => body});
// Answers each picker call with the next list and records every request.
function mockBackend(pickerAnswers, detail = null) {
// Answers each picker call with the next list.
function mockBackend(pickerAnswers, routes = {}) {
const answers = [...pickerAnswers];
globalThis.fetch = vi.fn(async (url, options = {}) => {
if (url.includes('/api/library/picker')) return json({games: answers.shift() ?? []});
if (options.method === 'PUT') return json(JSON.parse(options.body));
return json(detail);
fetchRoutes({
'GET /api/library/picker': () => json(200, {games: answers.shift() ?? []}),
'PUT /api/library/games/7/status': (url, init) => json(200, JSON.parse(init.body)),
...routes,
});
}
@@ -135,10 +134,8 @@ describe('PlayNextPage', () => {
});
it('drops the old picks when a new budget fails to load', async () => {
mockBackend([[game(1)]]);
const pickerFetch = globalThis.fetch;
globalThis.fetch = vi.fn(async (url, options) =>
(url.includes('maxMinutes=300') ? json({}, 500) : pickerFetch(url, options)));
mockBackend([], {'GET /api/library/picker': (url) =>
(url.includes('maxMinutes=300') ? json(500, {}) : json(200, {games: [game(1)]}))});
renderPage();
await screen.findByText('Game 1');
@@ -195,10 +192,7 @@ describe('PlayNextPage', () => {
});
it('lets the user try again when saving fails', async () => {
mockBackend([[game(7)]]);
const pickerFetch = globalThis.fetch;
globalThis.fetch = vi.fn(async (url, options) =>
(options?.method === 'PUT' ? json({}, 500) : pickerFetch(url, options)));
mockBackend([[game(7)]], {'PUT /api/library/games/7/status': json(500, {})});
renderPage();
await screen.findByText('Game 7');
@@ -224,7 +218,7 @@ describe('PlayNextPage', () => {
});
it('offers a retry when the first load fails', async () => {
globalThis.fetch = vi.fn(async () => { throw new TypeError('Failed to fetch'); });
mockBackend([], {'GET /api/library/picker': () => { throw new TypeError('Failed to fetch'); }});
renderPage();
await screen.findByText('INFO.ERROR.NETWORK_FAILURE');