Skip to content

Commit

Permalink
HAI-1311 Redirect user to original route after login
Browse files Browse the repository at this point in the history
If user tries to access page that requires login, that path
is saved to session storage and user is redirected to login and
after successful login user is redirected to the path
in session storage.
  • Loading branch information
markohaarni committed Sep 20, 2023
1 parent 740d994 commit 689ae23
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 11 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
"i18next-browser-languagedetector": "^7.0.1",
"immer": "8.0.2",
"jest-fetch-mock": "^3.0.3",
"jest-localstorage-mock": "^2.4.6",
"local-web-server": "^4.2.1",
"lodash": "^4.17.21",
"msw": "^0.49.0",
Expand Down
3 changes: 2 additions & 1 deletion src/common/routes/PrivateRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
import { Navigate } from 'react-router-dom';
import { Navigate, useLocation } from 'react-router-dom';
import useUser from '../../domain/auth/useUser';
import { REDIRECT_PATH_KEY } from './constants';

Expand All @@ -10,6 +10,7 @@ type Props = {
const PrivateRoute: React.FC<React.PropsWithChildren<Props>> = ({ element }) => {
const { data: user } = useUser();
const isAuthenticated = Boolean(user?.profile);
const location = useLocation();

useEffect(() => {
if (isAuthenticated) {
Expand Down
79 changes: 79 additions & 0 deletions src/common/routes/Routes.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { I18nextProvider } from 'react-i18next';
import { QueryClient, QueryClientProvider } from 'react-query';
import { InitialEntry } from '@remix-run/router';
import { User } from 'oidc-client';
import { Provider } from 'react-redux';
import AppRoutes from './AppRoutes';
import { FeatureFlagsProvider } from '../components/featureFlags/FeatureFlagsContext';
import { GlobalNotificationProvider } from '../components/globalNotification/GlobalNotificationContext';
import authService from '../../domain/auth/authService';
import { store } from '../redux/store';
import i18n from '../../locales/i18n';
import { REDIRECT_PATH_KEY } from './constants';

afterEach(() => {
sessionStorage.clear();
});

const path = '/fi/johtoselvityshakemus';

const mockUser: Partial<User> = {
id_token: 'fffff-aaaaaa-11111',
access_token: '.BnutWVN1x7RSAP5bU2a-tXdVPuof_9pBNd_Ozw',
profile: {
iss: '',
sub: '',
aud: '',
exp: 0,
iat: 0,
},
};

function getWrapper(routerInitialEntries?: InitialEntry[]) {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retryDelay: 0,
},
},
});

return render(
<MemoryRouter initialEntries={routerInitialEntries}>
<Provider store={store}>
<QueryClientProvider client={queryClient}>
<I18nextProvider i18n={i18n}>
<FeatureFlagsProvider>
<GlobalNotificationProvider>
<AppRoutes />
</GlobalNotificationProvider>
</FeatureFlagsProvider>
</I18nextProvider>
</QueryClientProvider>
</Provider>
</MemoryRouter>,
);
}

test('Should save path to session storage and navigate to login if trying to navigate to private route', async () => {
const login = jest.spyOn(authService, 'login').mockResolvedValue();

getWrapper([path]);

await waitFor(() => expect(login).toHaveBeenCalled());
expect(window.sessionStorage.getItem(REDIRECT_PATH_KEY)).toBe(path);
});

test('Should redirect to path stored in session storage after login if one exists', async () => {
sessionStorage.setItem(REDIRECT_PATH_KEY, path);
jest.spyOn(authService.userManager, 'getUser').mockResolvedValue(mockUser as User);

getWrapper();

await waitFor(() =>
expect(window.document.title).toBe('Haitaton - Luo uusi johtoselvityshakemus'),
);
});
3 changes: 0 additions & 3 deletions src/domain/auth/authService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ describe('authService', () => {

afterEach(() => {
localStorage.clear();
// eslint-disable-next-line
// @ts-ignore
localStorage.setItem.mockClear();
jest.restoreAllMocks();
});

Expand Down
1 change: 0 additions & 1 deletion src/setupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
import '@testing-library/jest-dom/extend-expect';
import 'jest-localstorage-mock';
import { GlobalWithFetchMock } from 'jest-fetch-mock';
import 'jest-canvas-mock';
import { server } from './domain/mocks/test-server';
Expand Down
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10787,11 +10787,6 @@ jest-leak-detector@^27.5.1:
jest-get-type "^27.5.1"
pretty-format "^27.5.1"

jest-localstorage-mock@^2.4.6:
version "2.4.6"
resolved "https://registry.yarnpkg.com/jest-localstorage-mock/-/jest-localstorage-mock-2.4.6.tgz#ebb9481943bf52e0f8c864ae4858eb791d68149d"
integrity sha512-8n6tuqscEShpvC7vkq3BPabOGGszD1cdLAKTtTtCRqH2bWJIVfpV4aIhrDJstV7xLOjo56wSVZkoMbT7dWLIVg==

jest-matcher-utils@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab"
Expand Down

0 comments on commit 689ae23

Please sign in to comment.