From 8b22815e97cd01c70579b9b644c4acb4099b82ea Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Wed, 10 Nov 2021 09:46:14 +0000 Subject: [PATCH] Request user details on Welcome page load Previously the page would require state params to be passed from the landing page, otherwise it would redirect back to it. The OAuth flow now returns the user to the Welcome screen after login, so it should make its own request for user info. --- web/src/pages/landing/Landing.test.tsx | 4 +- web/src/pages/landing/Landing.tsx | 2 +- web/src/pages/welcome/Welcome.test.tsx | 62 +++++++++++++++++++++++--- web/src/pages/welcome/Welcome.tsx | 32 ++++++++----- 4 files changed, 78 insertions(+), 22 deletions(-) diff --git a/web/src/pages/landing/Landing.test.tsx b/web/src/pages/landing/Landing.test.tsx index 031f644..9cd524e 100644 --- a/web/src/pages/landing/Landing.test.tsx +++ b/web/src/pages/landing/Landing.test.tsx @@ -74,9 +74,7 @@ test("button click requests user data", async () => { expect(getSpy).toHaveBeenCalledWith(serverMeEndpoint, { withCredentials: true, }); - expect(history.replace).toHaveBeenCalledWith("/welcome", { - user: testUser, - }); + expect(history.replace).toHaveBeenCalledWith("/welcome"); }); }); diff --git a/web/src/pages/landing/Landing.tsx b/web/src/pages/landing/Landing.tsx index 4998313..eca5db3 100644 --- a/web/src/pages/landing/Landing.tsx +++ b/web/src/pages/landing/Landing.tsx @@ -20,7 +20,7 @@ function Landing() { if (result.error) { return Promise.reject(result.error); } - history.replace("/welcome", { user: result.data }); + history.replace("/welcome"); }) .catch((e: AxiosError) => { if (e.response?.status === 401) { diff --git a/web/src/pages/welcome/Welcome.test.tsx b/web/src/pages/welcome/Welcome.test.tsx index ab387bd..3363061 100644 --- a/web/src/pages/welcome/Welcome.test.tsx +++ b/web/src/pages/welcome/Welcome.test.tsx @@ -1,26 +1,74 @@ import { render, screen, waitFor } from "@testing-library/react"; -import { createMemoryHistory } from "history"; +import { setLogger } from "react-query"; import { Router } from "react-router-dom"; +import { setupServer } from "msw/node"; +import { ResponseComposition, rest, RestContext, RestRequest } from "msw"; +import { createMemoryHistory } from "history"; import Welcome from "./Welcome"; import TestWrapper from "../../testing/test-wrapper"; +import { User } from "../../data/user"; + +const testUser: User = { organizationUuid: "foo", displayName: "bar" }; +const serverMeEndpoint = "https://localhost:8001/v1/me"; + +const server = setupServer(); + +beforeAll(() => { + server.listen(); + setLogger({ + log: () => {}, + warn: () => {}, + error: () => {}, + }); +}); + +afterEach(() => server.resetHandlers()); + +afterAll(() => { + server.close(); +}); -test("redirects when user is missing", () => { +test("redirects when user request errors", async () => { const history = createMemoryHistory(); + history.replace = jest.fn(); + + Object.defineProperty(window, "location", { + writable: true, + value: { assign: jest.fn() }, + }); + + server.use( + rest.get( + serverMeEndpoint, + (req: RestRequest, res: ResponseComposition, ctx: RestContext) => { + return res(ctx.status(500), ctx.json("error")); + } + ) + ); + render( , { wrapper: TestWrapper } ); - expect(history.location.pathname).toBe("/"); + + await waitFor(() => { + expect(history.replace).toHaveBeenCalledWith("/"); + }); }); -test("renders user passed by state", async () => { +test("renders user from request", async () => { const history = createMemoryHistory(); - history.location.state = { - user: { organizationUuid: "foo", displayName: "bar" }, - }; + + server.use( + rest.get( + serverMeEndpoint, + (req: RestRequest, res: ResponseComposition, ctx: RestContext) => + res(ctx.json(testUser)) + ) + ); render( diff --git a/web/src/pages/welcome/Welcome.tsx b/web/src/pages/welcome/Welcome.tsx index 78e9b8b..60d225c 100644 --- a/web/src/pages/welcome/Welcome.tsx +++ b/web/src/pages/welcome/Welcome.tsx @@ -1,31 +1,41 @@ -import { Box, Heading, Text, VStack } from "@chakra-ui/react"; +import { Box, Heading, Spinner, Text, VStack } from "@chakra-ui/react"; +import { AxiosError } from "axios"; import { useHistory } from "react-router-dom"; import "./Welcome.css"; +import { useUser } from "../../hooks/use-user"; +import { QueryObserverResult } from "react-query"; import { User } from "../../data/user"; function Welcome() { const history = useHistory(); - const state = history.location.state as WelcomeState; + const user = useUser(); - if (!state?.user) { - history.replace("/"); - return <>; + if (!user.data) { + user.refetch().then((result: QueryObserverResult) => { + if (result.error) { + history.replace("/"); + } + }); + } + + if (user.isLoading || !user.data) { + return ( + + + + ); } return ( Welcome - Org id: {state.user.organizationUuid} - Display name: {state.user.displayName} + Org id: {user.data.organizationUuid} + Display name: {user.data.displayName} ); } -interface WelcomeState { - user: User; -} - export default Welcome;