Skip to content

Commit

Permalink
Update authcallback router tests
Browse files Browse the repository at this point in the history
  • Loading branch information
RioKnightleyNHS committed Nov 28, 2023
1 parent 7905f72 commit 3cc4665
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 133 deletions.
95 changes: 77 additions & 18 deletions app/src/components/layout/navLinks/NavLinks.test.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,99 @@
import { render, screen } from '@testing-library/react';
import { render, screen, waitFor } from '@testing-library/react';
import NavLinks from './NavLinks';
import SessionProvider, { Session } from '../../../providers/sessionProvider/SessionProvider';
import { buildUserAuth } from '../../../helpers/test/testBuilders';
import * as ReactRouter from 'react-router';
import { createMemoryHistory } from 'history';
import { act } from 'react-dom/test-utils';
import userEvent from '@testing-library/user-event';
import { routes } from '../../../types/generic/routes';

const mockedUseNavigate = jest.fn();
jest.mock('react-router', () => ({
useNavigate: () => mockedUseNavigate,
}));

describe('NavLinks', () => {
const oldWindowLocation = window.location;

beforeEach(() => {
sessionStorage.setItem('UserSession', '');
process.env.REACT_APP_ENVIRONMENT = 'jest';
});
afterEach(() => {
jest.clearAllMocks();
window.location = oldWindowLocation;
});

it('renders a navlink that returns to app home', () => {
renderNavWithRouter();
describe('Rendering', () => {
it('renders a navlink for app home when user logged in', () => {
const isLoggedIn = true;
renderNav(isLoggedIn);

expect(screen.getByRole('link', { name: 'Home' })).toBeInTheDocument();
});

it('renders a navlink for app logout when user logged in', () => {
const isLoggedIn = true;
renderNav(isLoggedIn);

expect(screen.getByRole('link', { name: 'Log Out' })).toBeInTheDocument();
});
it('does not render a navlink for app home when user logged out', () => {
const isLoggedIn = false;
renderNav(isLoggedIn);

expect(screen.queryByRole('link', { name: 'Home' })).not.toBeInTheDocument();
});

it('does not render a navlink for app logout when user logged out', () => {
const isLoggedIn = false;
renderNav(isLoggedIn);

expect(screen.queryByRole('link', { name: 'Log Out' })).not.toBeInTheDocument();
});
});

describe('Navigation', () => {
it('navigates to app home when home link is clicked', async () => {
const isLoggedIn = true;
renderNav(isLoggedIn);

const homeLink = screen.getByRole('link', { name: 'Home' });
expect(homeLink).toBeInTheDocument();

act(() => {
userEvent.click(homeLink);
});

await waitFor(() => {
expect(mockedUseNavigate).toHaveBeenCalledWith(routes.HOME);
});
});

expect(screen.getByRole('link', { name: 'Home' })).toBeInTheDocument();
it('navigates to app logout when logout link is clicked', async () => {
const isLoggedIn = true;
renderNav(isLoggedIn);

const logoutLink = screen.getByRole('link', { name: 'Log Out' });
expect(logoutLink).toBeInTheDocument();

act(() => {
userEvent.click(logoutLink);
});

await waitFor(() => {
expect(mockedUseNavigate).toHaveBeenCalledWith(routes.LOGOUT);
});
});
});
});

const renderNavWithRouter = (authOverride?: Partial<Session>) => {
const renderNav = (isLoggedIn: boolean) => {
const auth: Session = {
auth: buildUserAuth(),
isLoggedIn: true,
...authOverride,
};
const history = createMemoryHistory({
initialEntries: ['/'],
initialIndex: 1,
});
render(
<ReactRouter.Router navigator={history} location={'/'}>
<SessionProvider sessionOverride={auth}>
<NavLinks />
</SessionProvider>
</ReactRouter.Router>,
<SessionProvider sessionOverride={isLoggedIn ? auth : undefined}>
<NavLinks />
</SessionProvider>,
);
};
49 changes: 14 additions & 35 deletions app/src/pages/authCallbackPage/AuthCallbackPage.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { render, screen, waitFor } from '@testing-library/react';
import AuthCallbackPage from './AuthCallbackPage';
import SessionProvider from '../../providers/sessionProvider/SessionProvider';
import * as ReactRouter from 'react-router';
import { History, createMemoryHistory } from 'history';
import axios from 'axios';
import { buildUserAuth } from '../../helpers/test/testBuilders';
import { routes } from '../../types/generic/routes';
jest.mock('axios');

const mockedUseNavigate = jest.fn();
jest.mock('axios');
jest.mock('react-router', () => ({
useNavigate: () => mockedUseNavigate,
}));
const mockedAxios = axios as jest.Mocked<typeof axios>;
const params = {
code: 'cis2-code',
Expand Down Expand Up @@ -42,35 +44,25 @@ describe('AuthCallbackPage', () => {
});

it('returns a loading state until redirection to token request handler', async () => {
const history = createMemoryHistory({
initialEntries: [currentPage],
initialIndex: 0,
});

mockedAxios.get.mockImplementation(() => Promise.resolve({ data: buildUserAuth() }));
renderCallbackPage(history);
renderCallbackPage();
expect(screen.getByRole('status')).toBeInTheDocument();
expect(screen.getByText('Logging in...')).toBeInTheDocument();

await waitFor(() => {
expect(history.location.pathname).toBe(routes.UPLOAD_SEARCH);
expect(mockedUseNavigate).toHaveBeenCalledWith(routes.UPLOAD_SEARCH);
});
});

it('navigates to the select role page when callback token request is successful', async () => {
const history = createMemoryHistory({
initialEntries: [currentPage],
initialIndex: 0,
});

mockedAxios.get.mockImplementation(() => Promise.resolve({ data: buildUserAuth() }));
renderCallbackPage(history);
renderCallbackPage();

expect(screen.getByRole('status')).toBeInTheDocument();
expect(screen.getByText('Logging in...')).toBeInTheDocument();
expect(history.location.pathname).toBe(currentPage);

await waitFor(() => {
expect(history.location.pathname).toBe(routes.UPLOAD_SEARCH);
expect(mockedUseNavigate).toHaveBeenCalledWith(routes.UPLOAD_SEARCH);
});
});

Expand All @@ -81,36 +73,23 @@ describe('AuthCallbackPage', () => {
message: '400 Bad Request',
},
};
const history = createMemoryHistory({
initialEntries: [currentPage],
initialIndex: 0,
});

mockedAxios.get.mockImplementation(() => Promise.reject(errorResponse));
renderCallbackPage(history);
renderCallbackPage();

expect(screen.getByRole('status')).toBeInTheDocument();
expect(screen.getByText('Logging in...')).toBeInTheDocument();
expect(history.location.pathname).toBe(currentPage);

await waitFor(() => {
expect(history.location.pathname).toBe(routes.AUTH_ERROR);
expect(mockedUseNavigate).toHaveBeenCalledWith(routes.AUTH_ERROR);
});
});
});

const renderCallbackPage = (
history: History = createMemoryHistory({
initialEntries: [currentPage],
initialIndex: 1,
}),
) => {
const renderCallbackPage = () => {
render(
<SessionProvider>
<ReactRouter.Router navigator={history} location={history.location}>
<AuthCallbackPage />,
</ReactRouter.Router>
,
<AuthCallbackPage />
</SessionProvider>,
);
};
17 changes: 6 additions & 11 deletions app/src/pages/authErrorPage/AuthErrorPage.test.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { render, screen } from '@testing-library/react';
import * as ReactRouter from 'react-router';
import { createMemoryHistory } from 'history';
import AuthErrorPage from './AuthErrorPage';
import { LinkProps } from 'react-router-dom';

jest.mock('react-router-dom', () => ({
__esModule: true,
Link: (props: LinkProps) => <a {...props} role="link" />,
}));
describe('AuthErrorPage', () => {
it('renders unauthorised message', () => {
const history = createMemoryHistory({
initialEntries: ['/'],
initialIndex: 0,
});
render(
<ReactRouter.Router navigator={history} location={history.location}>
<AuthErrorPage />
</ReactRouter.Router>,
);
render(<AuthErrorPage />);
expect(screen.getByText('You have been logged out')).toBeInTheDocument();
});
});
59 changes: 16 additions & 43 deletions app/src/pages/logoutPage/LogoutPage.test.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { render, screen, waitFor } from '@testing-library/react';
import LogoutPage from './LogoutPage';
import { createMemoryHistory } from 'history';
import SessionProvider, { Session } from '../../providers/sessionProvider/SessionProvider';
import { buildUserAuth } from '../../helpers/test/testBuilders';
import * as ReactRouter from 'react-router';
import axios from 'axios';
import { routes } from '../../types/generic/routes';

jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;
const mockSetSession = jest.fn();
const mockedUseNavigate = jest.fn();
jest.mock('react-router', () => ({
useNavigate: () => mockedUseNavigate,
}));

describe('logoutPage', () => {
const currentPage = '/example';
beforeEach(() => {
process.env.REACT_APP_ENVIRONMENT = 'jest';
});
Expand All @@ -25,65 +28,45 @@ describe('logoutPage', () => {
});

it('navigates to the home page when logout is successful', async () => {
const history = createMemoryHistory({
initialEntries: [currentPage],
initialIndex: 0,
});

const successResponse = {
response: {
status: 200,
},
};

mockedAxios.get.mockImplementation(() => Promise.resolve(successResponse));
renderLogoutPage(history);
expect(history.location.pathname).toBe(currentPage);
renderLogoutPage();

await waitFor(() => {
expect(history.location.pathname).toBe(routes.HOME);
expect(mockedUseNavigate).toHaveBeenCalledWith(routes.HOME);
});
});

it('navigates to the previous page when logout fails', async () => {
const previousPage = '/previous';
const history = createMemoryHistory({
initialEntries: [previousPage, currentPage],
initialIndex: 1,
});
const errorResponse = {
response: {
status: 500,
},
};

mockedAxios.get.mockImplementation(() => Promise.reject(errorResponse));
renderLogoutPage(history);
expect(history.location.pathname).toBe(currentPage);
renderLogoutPage();

await waitFor(() => {
expect(history.location.pathname).toBe(previousPage);
expect(mockedUseNavigate).toHaveBeenCalledWith(-1);
});
});

it('clears the session from session provider', async () => {
const history = createMemoryHistory({
initialEntries: [currentPage],
initialIndex: 0,
});
const mockSetSession = jest.fn();
Storage.prototype.setItem = jest.fn();
const successResponse = {
response: {
status: 200,
},
};
const auth: Session = {
auth: buildUserAuth(),
isLoggedIn: true,
};

mockedAxios.get.mockImplementation(() => Promise.resolve(successResponse));
renderLogoutPage(history, auth, mockSetSession);
renderLogoutPage();

await waitFor(() => {
expect(mockSetSession).toHaveBeenCalledWith({
Expand All @@ -94,24 +77,14 @@ describe('logoutPage', () => {
});
});

const renderLogoutPage = (
history = createMemoryHistory({
initialEntries: ['/'],
initialIndex: 0,
}),
authOverride?: Partial<Session>,
setSessionOverride = jest.fn(),
) => {
const renderLogoutPage = () => {
const auth: Session = {
auth: buildUserAuth(),
isLoggedIn: true,
...authOverride,
};
render(
<ReactRouter.Router navigator={history} location={'/'}>
<SessionProvider sessionOverride={auth} setSessionOverride={setSessionOverride}>
<LogoutPage />
</SessionProvider>
</ReactRouter.Router>,
<SessionProvider sessionOverride={auth} setSessionOverride={mockSetSession}>
<LogoutPage />
</SessionProvider>,
);
};
18 changes: 7 additions & 11 deletions app/src/pages/notFoundPage/NotFoundPage.test.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import { render, screen } from '@testing-library/react';
import * as ReactRouter from 'react-router';
import { createMemoryHistory } from 'history';
import NotFoundPage from './NotFoundPage';
import { LinkProps } from 'react-router-dom';

jest.mock('react-router-dom', () => ({
__esModule: true,
Link: (props: LinkProps) => <a {...props} role="link" />,
}));
describe('NotFoundPage', () => {
it('renders unauthorised message', () => {
const history = createMemoryHistory({
initialEntries: ['/'],
initialIndex: 0,
});
render(
<ReactRouter.Router navigator={history} location={history.location}>
<NotFoundPage />
</ReactRouter.Router>,
);
render(<NotFoundPage />);
expect(screen.getByText('Page not found')).toBeInTheDocument();
});
});
Loading

0 comments on commit 3cc4665

Please sign in to comment.