Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/app/services/useSessionExpired.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {KEY, persistence} from "./localStorage";
import {useCheckCurrentUserOnActivity} from "./useCheckCurrentUserOnActivity";

export const setAfterRenewPath = () => {
persistence.session.save(KEY.AFTER_SESSION_RENEW_PATH, window.location.pathname);
persistence.session.save(KEY.AFTER_SESSION_RENEW_PATH, window.location.href);
};

export const useSessionExpired = (): [string, () => void] => {
Expand Down Expand Up @@ -33,4 +33,4 @@ export const useSessionExpired = (): [string, () => void] => {
}, [loggedBackIn]);

return [target, clearRenewPath];
};
};
2 changes: 1 addition & 1 deletion src/app/state/actions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ export const continueToAfterAuthPath = (user?: {readonly role?: UserRole, readon

// Hard redirect (refreshes page)
export const redirectTo = (path: string) => {
window.location.href = window.location.origin + path;
window.location.href = path;
};

export const registerPageChange = (path: string) => {
Expand Down
2 changes: 1 addition & 1 deletion src/app/state/middleware/userConsistencyChecker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const userConsistencyCheckerMiddleware: Middleware = (api: MiddlewareAPI)
// Redirect after action has been processed so that the notificationManager sees a logged-out user when deciding
// whether to show the "required fields" modal and recording that in local storage.
// TODO this might not be the case anymore since this is now a hard redirect now.
redirectTo(redirect);
redirectTo(window.location.origin + redirect);
}

return result;
Expand Down
39 changes: 34 additions & 5 deletions src/test/pages/SessionCookieExpired.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {navigateToMyAccount, renderTestEnvironment} from "../testUtils";
import {navigateToMyAccount, renderTestEnvironment, setUrl} from "../testUtils";
import {NOW, SOME_FIXED_FUTURE_DATE} from "../dateUtils";
import {redirectTo} from "../../app/state";
import * as Actions from "../../app/state/actions";
import { screen } from "@testing-library/dom";


describe("SessionExpired", () => {
Expand All @@ -10,7 +11,9 @@ describe("SessionExpired", () => {
// Annoyingly, the hard-redirect we use is not implemented in JSDOM/RTL, so we need to mock it out.
jest.spyOn(Actions, "redirectTo");
// @ts-ignore
redirectTo.mockImplementation(() => true);
redirectTo.mockImplementation(async (path) => {
await setUrl({pathname: path});
});

// Set the session expiry to be now
await renderTestEnvironment({role: "STUDENT", sessionExpires: new Date(NOW).toUTCString()});
Expand All @@ -25,7 +28,7 @@ describe("SessionExpired", () => {
// Assert
// Check we were redirected to the login page. Ideally we'd check the page itself, but this is the best we can
// do for the reasons described above.
expect(redirectTo).toHaveBeenLastCalledWith("/error_expired");
expect(redirectTo).toHaveBeenLastCalledWith(window.location.origin + "/error_expired");

// Teardown
// @ts-ignore
Expand All @@ -36,7 +39,9 @@ describe("SessionExpired", () => {
// Arrange
jest.spyOn(Actions, "redirectTo");
// @ts-ignore
redirectTo.mockImplementation(() => true);
redirectTo.mockImplementation(async (path) => {
await setUrl({pathname: path});
});

// Set the session expiry to in the future
await renderTestEnvironment({role: "STUDENT", sessionExpires: new Date(SOME_FIXED_FUTURE_DATE).toUTCString()});
Expand All @@ -51,6 +56,30 @@ describe("SessionExpired", () => {
// Assert
// We should still be where we were.
expect(window.location.pathname).toEqual("/account");
expect(redirectTo).not.toHaveBeenLastCalledWith("/error_expired");
expect(redirectTo).not.toHaveBeenLastCalledWith(window.location.origin + "/error_expired");

// @ts-ignore
redirectTo.mockRestore();
});

it("should restore correct url with 'continue' button", async () => {
jest.spyOn(Actions, "redirectTo");
// @ts-ignore
redirectTo.mockImplementation(async (path) => {
await setUrl({pathname: path});
});

await renderTestEnvironment({role: "STUDENT", sessionExpires: new Date(NOW).toUTCString()});
await navigateToMyAccount();
await setUrl({pathname: "/account", search: "?some=param"});

await new Promise((r) => setTimeout(r, 1500));

const continueLink = screen.getByRole("link", {name: "Continue"});

expect(continueLink.getAttribute("href")).toEqual(window.location.origin + "/account?some=param");

// @ts-ignore
redirectTo.mockRestore();
});
});
2 changes: 2 additions & 0 deletions src/test/testUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ export const withSizedWindow = async (width: number, height: number, cb: () => v
export type PathString = `/${string}`;
export type SearchString = `?${string}`;
export const setUrl = async (location: Partial<URL>) => {
// this act seems to be generating a lot of warnings for both being there and for not being there if you remove it.
// seems like an RTL issue: https://github.com/testing-library/react-testing-library/issues/1413
await act(async () => {
// push a new state, then go to it
history.pushState({}, "", `${location?.pathname}${location?.search ?? ''}${location?.hash ?? ''}`);
Expand Down
Loading