// @vitest-environment jsdom import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'; import {cleanup, render, screen, waitFor} from '@testing-library/react'; import {MemoryRouter, Route, Routes, useLocation} from 'react-router-dom'; import Dashboard from './Dashboard.jsx'; vi.mock('react-i18next', () => import('../test/i18n-mock.js')); vi.mock('../hooks/useLibrarySync.js', () => ({default: () => ({status: 'OK', lastSyncedAt: null, isRunning: false})})); vi.mock('../hooks/useForceSync.js', () => ({default: () => ({trigger: vi.fn(), busy: false})})); const current = {location: null}; function Spy() { current.location = useLocation(); return null; } const ok = (body) => ({ok: true, status: 200, json: async () => body}); const unauthorized = () => ({ok: false, status: 401, json: async () => ({})}); beforeEach(() => { localStorage.setItem('tbp_jwt', 'token'); }); afterEach(() => { cleanup(); localStorage.clear(); }); describe('Dashboard', () => { it('opens the login page when the core API answers 401', async () => { globalThis.fetch = vi.fn(async (url) => url.includes('/api/users/me') ? ok({email: 'a@b.de', steamId: '76561198000000000'}) : unauthorized()); render( }/> }/> , ); await waitFor(() => expect(fetch.mock.calls.length).toBeGreaterThanOrEqual(5)); await waitFor(() => expect(current.location.pathname).toBe('/login')); expect(current.location.state).toEqual({sessionExpired: true, from: '/dashboard'}); expect(screen.queryByText('LIBRARY.EMPTY')).toBeNull(); }); });