Public Access
refactor(frontend): lint, one session guard, one request helper, one user context
This commit is contained in:
1 parent
111ab1e200
commit
d0ea9e900d
78 files changed
+2138
-624
No files matched your search
@@ -5,11 +5,12 @@ import {MemoryRouter, Route, Routes} from 'react-router-dom';
|
||||
import {toast} from 'sonner';
|
||||
import ImportPage, {initialChoice, stepOf} from './ImportPage.jsx';
|
||||
import {PreferencesProvider} from '../context/PreferencesContext.jsx';
|
||||
import {CurrentUserProvider} from '../context/CurrentUserContext.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()}}));
|
||||
|
||||
const json = (status, body) => ({ok: status < 400, status, json: async () => body});
|
||||
|
||||
const hades = {igdbId: 1, name: 'Hades', year: 2020, imageUrl: null, platforms: ['PC', 'Switch'], inLibrary: false};
|
||||
const hades2 = {igdbId: 2, name: 'Hades II', year: 2025, imageUrl: null, platforms: ['PC'], inLibrary: false};
|
||||
@@ -25,19 +26,20 @@ const ready = {
|
||||
],
|
||||
};
|
||||
|
||||
// routes: 'METHOD path after /imports' -> response or (init) => response; any other URL (Auth) answers the favorite
|
||||
// routes: 'METHOD path after /imports' -> response or (init) => response; Auth answers the favorite
|
||||
function renderPage(routes, entry = '/import') {
|
||||
globalThis.fetch = vi.fn(async (url, init) => {
|
||||
if (!url.includes('/api/library/imports')) return json(200, {settings: {favoritePlatform: 'Switch'}});
|
||||
const path = new URL(url, 'http://x').pathname.replace(/.*\/api\/library\/imports/, '');
|
||||
const answer = routes[`${init?.method ?? 'GET'} ${path}`];
|
||||
if (!answer) throw new Error(`no route ${init?.method ?? 'GET'} ${path}`);
|
||||
return typeof answer === 'function' ? answer(init) : answer;
|
||||
fetchRoutes({
|
||||
'GET /api/users/me': json(200, {settings: {favoritePlatform: 'Switch'}}),
|
||||
...Object.fromEntries(Object.entries(routes).map(([key, answer]) => {
|
||||
const [method, path] = key.split(' ');
|
||||
return [`${method} /api/library/imports${path}`,
|
||||
typeof answer === 'function' ? (url, init) => answer(init) : answer];
|
||||
})),
|
||||
});
|
||||
render(
|
||||
<MemoryRouter initialEntries={[entry]}>
|
||||
<Routes>
|
||||
<Route path="/import" element={<PreferencesProvider><ImportPage/></PreferencesProvider>}/>
|
||||
<Route path="/import" element={<PreferencesProvider><CurrentUserProvider><ImportPage/></CurrentUserProvider></PreferencesProvider>}/>
|
||||
<Route path="/login" element={<p>login</p>}/>
|
||||
</Routes>
|
||||
</MemoryRouter>,
|
||||
@@ -250,3 +252,24 @@ describe('ImportPage', () => {
|
||||
expect(await screen.findByText('IMPORT.MATCHING', {}, {timeout: 4000})).toBeTruthy();
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
describe('review findings', () => {
|
||||
it('shows the review when Auth cannot be reached for the favorite', async () => {
|
||||
vi.spyOn(console, 'error').mockImplementation(() => undefined);
|
||||
fetchRoutes({
|
||||
'GET /api/users/me': () => Promise.reject(new TypeError('Failed to fetch')),
|
||||
'GET /api/library/imports': json(200, {imports: []}),
|
||||
'GET /api/library/imports/5': json(200, ready),
|
||||
});
|
||||
render(
|
||||
<MemoryRouter initialEntries={['/import?id=5']}>
|
||||
<Routes>
|
||||
<Route path="/import" element={<PreferencesProvider><CurrentUserProvider><ImportPage/></CurrentUserProvider></PreferencesProvider>}/>
|
||||
</Routes>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
|
||||
expect(await screen.findByLabelText('IMPORT.LINE: Hades', {}, {timeout: 2000})).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user