import React from 'react'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; import LoginPage from './views/LoginPage'; import { ToastProvider } from './toast'; import { I18nProvider } from './i18n/I18nProvider'; import { api } from './api'; const mockNavigate = jest.fn(); jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useNavigate: () => mockNavigate, })); const mockedApi = api as jest.Mocked; let consoleErrorSpy: jest.SpyInstance; function renderLoginPage() { return render( , ); } describe('LoginPage', () => { beforeEach(() => { const originalConsoleError = console.error.bind(console); consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation((...args: unknown[]) => { const [first] = args; const message = typeof first === 'string' ? first : ''; if (message.includes('ForwardRef(TouchRipple) inside a test was not wrapped in act')) { return; } originalConsoleError(...args); }); window.localStorage.clear(); window.sessionStorage.clear(); mockedApi.post.mockReset(); mockNavigate.mockReset(); }); afterEach(() => { consoleErrorSpy.mockRestore(); }); it('posts remember-me preference without storing an auth token in browser storage', async () => { mockedApi.post.mockResolvedValueOnce({ data: { authenticated: true, provider: 'local' } } as any); mockedApi.get.mockResolvedValueOnce({ data: { roles: [], email: 'person@example.com', userName: 'person' } } as any); renderLoginPage(); await screen.findByLabelText('Email'); await userEvent.type(screen.getByLabelText('Email'), 'person@example.com'); await userEvent.type(screen.getByLabelText('Current password'), 'hunter2'); await userEvent.click(screen.getByLabelText('Remember me')); await userEvent.click(screen.getByRole('button', { name: 'Sign in' })); await waitFor(() => expect(mockedApi.post).toHaveBeenCalledWith('/auth/login', { email: 'person@example.com', password: 'hunter2', rememberMe: false })); await waitFor(() => expect(mockedApi.get).toHaveBeenCalledWith('/auth/me')); expect(window.sessionStorage.getItem('authToken')).toBeNull(); expect(window.localStorage.getItem('authToken')).toBeNull(); expect(window.localStorage.getItem('authTokenPersistence')).toBe('session'); }); it('opens the separate forgot-password page with the typed email prefilled', async () => { renderLoginPage(); await screen.findByLabelText('Email'); await userEvent.type(screen.getByLabelText('Email'), 'person@example.com'); await userEvent.click(screen.getByRole('button', { name: 'Forgot password?' })); expect(mockNavigate).toHaveBeenCalledWith('/forgot-password?email=person%40example.com'); }); });