Polish settings and auth flows
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
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 './pages/LoginPage';
|
||||
import { ToastProvider } from './toast';
|
||||
import { I18nProvider } from './i18n/I18nProvider';
|
||||
import { api } from './api';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useNavigate: () => jest.fn(),
|
||||
}));
|
||||
|
||||
const mockedApi = api as jest.Mocked<typeof api>;
|
||||
|
||||
let consoleErrorSpy: jest.SpyInstance;
|
||||
|
||||
function renderLoginPage() {
|
||||
return render(
|
||||
<MemoryRouter future={{ v7_startTransition: true, v7_relativeSplatPath: true }}>
|
||||
<I18nProvider>
|
||||
<ToastProvider>
|
||||
<LoginPage />
|
||||
</ToastProvider>
|
||||
</I18nProvider>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
consoleErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('stores auth token in session storage when remember me is unchecked', async () => {
|
||||
mockedApi.post.mockResolvedValueOnce({ data: { accessToken: 'header.payload.sig', tokenType: 'Bearer' } } 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' }));
|
||||
|
||||
expect(window.sessionStorage.getItem('authToken')).toBe('header.payload.sig');
|
||||
expect(window.localStorage.getItem('authToken')).toBeNull();
|
||||
expect(window.localStorage.getItem('authTokenPersistence')).toBe('session');
|
||||
});
|
||||
|
||||
it('requests a password reset link for the entered email', async () => {
|
||||
mockedApi.post.mockResolvedValueOnce({ data: {} } as any);
|
||||
|
||||
renderLoginPage();
|
||||
await screen.findByLabelText('Email');
|
||||
|
||||
await userEvent.type(screen.getByLabelText('Email'), 'person@example.com');
|
||||
await userEvent.click(screen.getByRole('button', { name: 'Forgot password?' }));
|
||||
|
||||
await waitFor(() => expect(mockedApi.post).toHaveBeenCalledWith('/auth/request-password-reset', { email: 'person@example.com' }));
|
||||
expect(await screen.findByText('If that account exists, a reset link has been sent.')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user