From 535cd73dd38bb4b4dd2c21d3ba87b0fba36bf968 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Thu, 12 Jan 2023 17:35:22 +0000 Subject: [PATCH 1/3] refactor: wrap authenticated routes --- site/src/AppRouter.tsx | 563 ++++++++---------- .../NavbarLayout.test.tsx} | 8 +- .../NavbarLayout.tsx} | 44 +- .../components/RequireAuth/RequireAuth.tsx | 13 +- 4 files changed, 275 insertions(+), 353 deletions(-) rename site/src/components/{AuthAndFrame/AuthAndFrame.test.tsx => NavbarLayout/NavbarLayout.test.tsx} (82%) rename site/src/components/{AuthAndFrame/AuthAndFrame.tsx => NavbarLayout/NavbarLayout.tsx} (60%) diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index 1158305678745..bb472ca0ae91a 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -18,7 +18,7 @@ import { Route, Routes } from "react-router-dom" import { selectPermissions } from "xServices/auth/authSelectors" import { selectFeatureVisibility } from "xServices/entitlements/entitlementsSelectors" import { XServiceContext } from "xServices/StateContext" -import { AuthAndFrame } from "./components/AuthAndFrame/AuthAndFrame" +import { NavbarLayout } from "./components/NavbarLayout/NavbarLayout" import { RequireAuth } from "./components/RequireAuth/RequireAuth" import { SettingsLayout } from "./components/SettingsLayout/SettingsLayout" import { DeploySettingsLayout } from "components/DeploySettingsLayout/DeploySettingsLayout" @@ -131,375 +131,310 @@ export const AppRouter: FC = () => { return ( }> - - - - } - /> - } /> } /> - - - - } - /> - - - - } - /> - - - - } - /> + {/* Authenticated routes */} + }> + } /> - - - - - } - /> + } /> + } /> - - - } - > - - - - - - + + + } /> - - - - } - /> - - + - - - - - } - /> - - - - - + + + } /> + - - + + + } /> + + + - - + + + } /> - + + } /> + + + + + + + + } + /> - - + + + + + } /> + } /> + } /> + + + + + } + /> + - - - - - - - - - } - /> - - - - } - /> - - - - - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - - - - - - } - /> - - - - - - - - - - - } - /> - - - - - - - - } - /> - - - - - - - - } - /> - - - - - - - - } - /> - - - - - - - - } - /> - - - - - - - - } - /> - - - - - - - - - } - /> - - - - - - } - /> - - - - - - } - /> - - - - + - - + + + + + } /> + } /> + + + + + + + + } + /> + } /> - - + + + } /> + } /> + + - - + + + + + } /> + + + + + + + + + + } + /> + + + + + + + + } + /> + + + + + + + + } + /> + + + + + + + + } + /> - - + + + + + + + } /> + + + + + + + + } + /> + + + + + + + + } + /> + + + + + + } + /> - - + + + + + } /> + + + + + + + } + /> + + } /> + + } /> + + + + + } + /> + + } + /> + + {/* Using path="*"" means "match anything", so this route diff --git a/site/src/components/AuthAndFrame/AuthAndFrame.test.tsx b/site/src/components/NavbarLayout/NavbarLayout.test.tsx similarity index 82% rename from site/src/components/AuthAndFrame/AuthAndFrame.test.tsx rename to site/src/components/NavbarLayout/NavbarLayout.test.tsx index 2ea19161659d0..21e79da8d7042 100644 --- a/site/src/components/AuthAndFrame/AuthAndFrame.test.tsx +++ b/site/src/components/NavbarLayout/NavbarLayout.test.tsx @@ -5,7 +5,7 @@ import i18next from "i18next" const { t } = i18next -describe("AuthAndFrame", () => { +describe("NavbarLayout", () => { it("sets localStorage key-value when dismissed", async () => { const localStorageMock = { ...global.localStorage, @@ -13,13 +13,15 @@ describe("AuthAndFrame", () => { } global.localStorage = localStorageMock - // rendering a random page that is wrapped in AuthAndFrame - return renderWithAuth() + // rendering a random page that is wrapped in NavbarLayout + renderWithAuth() + fireEvent.click( screen.getByRole("button", { name: t("ctas.dismissCta", { ns: "common" }), }), ) + expect(localStorageMock.getItem).toHaveBeenCalledWith("dismissedVersion") }) }) diff --git a/site/src/components/AuthAndFrame/AuthAndFrame.tsx b/site/src/components/NavbarLayout/NavbarLayout.tsx similarity index 60% rename from site/src/components/AuthAndFrame/AuthAndFrame.tsx rename to site/src/components/NavbarLayout/NavbarLayout.tsx index 6eea191491794..eb900dadf1bab 100644 --- a/site/src/components/AuthAndFrame/AuthAndFrame.tsx +++ b/site/src/components/NavbarLayout/NavbarLayout.tsx @@ -1,21 +1,13 @@ import { makeStyles } from "@material-ui/core/styles" import { useActor } from "@xstate/react" import { Loader } from "components/Loader/Loader" -import { FC, Suspense, useContext, useEffect } from "react" +import { FC, PropsWithChildren, Suspense, useContext, useEffect } from "react" import { XServiceContext } from "../../xServices/StateContext" import { Navbar } from "../Navbar/Navbar" -import { RequireAuth } from "../RequireAuth/RequireAuth" import { UpdateCheckBanner } from "components/UpdateCheckBanner/UpdateCheckBanner" import { Margins } from "components/Margins/Margins" -interface AuthAndFrameProps { - children: JSX.Element -} - -/** - * Wraps page in RequireAuth and renders it between Navbar and Footer - */ -export const AuthAndFrame: FC = ({ children }) => { +export const NavbarLayout: FC = ({ children }) => { const styles = useStyles() const xServices = useContext(XServiceContext) const [authState] = useActor(xServices.authXService) @@ -32,25 +24,23 @@ export const AuthAndFrame: FC = ({ children }) => { }, [authState, updateCheckSend]) return ( - -
- - {updateCheckState.context.show && ( -
- - updateCheckSend("DISMISS")} - /> - -
- )} -
- }>{children} +
+ + {updateCheckState.context.show && ( +
+ + updateCheckSend("DISMISS")} + /> +
+ )} +
+ }>{children}
- +
) } diff --git a/site/src/components/RequireAuth/RequireAuth.tsx b/site/src/components/RequireAuth/RequireAuth.tsx index f2e79b82f9a2f..d4f9ce22e6a5c 100644 --- a/site/src/components/RequireAuth/RequireAuth.tsx +++ b/site/src/components/RequireAuth/RequireAuth.tsx @@ -1,17 +1,12 @@ import { useActor } from "@xstate/react" -import { useContext, FC, PropsWithChildren } from "react" +import { useContext, FC } from "react" import { Navigate, useLocation } from "react-router" +import { Outlet } from "react-router-dom" import { embedRedirect } from "../../util/redirect" import { XServiceContext } from "../../xServices/StateContext" import { FullScreenLoader } from "../Loader/FullScreenLoader" -export interface RequireAuthProps { - children: JSX.Element -} - -export const RequireAuth: FC> = ({ - children, -}) => { +export const RequireAuth: FC = () => { const xServices = useContext(XServiceContext) const [authState] = useActor(xServices.authXService) const location = useLocation() @@ -25,6 +20,6 @@ export const RequireAuth: FC> = ({ } else if (authState.hasTag("loading")) { return } else { - return children + return } } From 5aceaca67984a08c11f9d55e0d131925ff34a6df Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Thu, 12 Jan 2023 18:10:32 +0000 Subject: [PATCH 2/3] Fix tests --- site/src/testHelpers/renderHelpers.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/site/src/testHelpers/renderHelpers.tsx b/site/src/testHelpers/renderHelpers.tsx index 82552128b68af..6535997347dda 100644 --- a/site/src/testHelpers/renderHelpers.tsx +++ b/site/src/testHelpers/renderHelpers.tsx @@ -64,11 +64,10 @@ export function renderWithAuth( - {ui}} - /> - {routes} + }> + + {routes} + From 281525ee2db27cc319fa57fe2d3be979ef91dbb8 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Thu, 12 Jan 2023 18:32:02 +0000 Subject: [PATCH 3/3] Fix tests --- .../NavbarLayout/NavbarLayout.test.tsx | 27 ------------------- site/src/testHelpers/renderHelpers.tsx | 2 +- 2 files changed, 1 insertion(+), 28 deletions(-) delete mode 100644 site/src/components/NavbarLayout/NavbarLayout.test.tsx diff --git a/site/src/components/NavbarLayout/NavbarLayout.test.tsx b/site/src/components/NavbarLayout/NavbarLayout.test.tsx deleted file mode 100644 index 21e79da8d7042..0000000000000 --- a/site/src/components/NavbarLayout/NavbarLayout.test.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { fireEvent, screen } from "@testing-library/react" -import { renderWithAuth } from "testHelpers/renderHelpers" -import { AccountPage } from "pages/UserSettingsPage/AccountPage/AccountPage" -import i18next from "i18next" - -const { t } = i18next - -describe("NavbarLayout", () => { - it("sets localStorage key-value when dismissed", async () => { - const localStorageMock = { - ...global.localStorage, - getItem: jest.fn(), - } - global.localStorage = localStorageMock - - // rendering a random page that is wrapped in NavbarLayout - renderWithAuth() - - fireEvent.click( - screen.getByRole("button", { - name: t("ctas.dismissCta", { ns: "common" }), - }), - ) - - expect(localStorageMock.getItem).toHaveBeenCalledWith("dismissedVersion") - }) -}) diff --git a/site/src/testHelpers/renderHelpers.tsx b/site/src/testHelpers/renderHelpers.tsx index 6535997347dda..3900ef81479b6 100644 --- a/site/src/testHelpers/renderHelpers.tsx +++ b/site/src/testHelpers/renderHelpers.tsx @@ -66,8 +66,8 @@ export function renderWithAuth( }> - {routes} + {routes}