From 1a324af241add9cf52224d2c9ec291040c553b0b Mon Sep 17 00:00:00 2001
From: viktorstrate <viktorstrate@gmail.com>
Date: Tue, 1 Feb 2022 13:39:15 +0100
Subject: [PATCH] Fix remaining unit tests

---
 ui/src/Pages/PeoplePage/PeoplePage.test.tsx   |  11 +-
 .../SingleFaceGroup/SingleFaceGroup.test.tsx  |   9 +-
 .../routes/AuthorizedRoute.test.tsx           | 115 ++++++++++++++++--
 ui/src/components/routes/AuthorizedRoute.tsx  |  14 +--
 4 files changed, 117 insertions(+), 32 deletions(-)

diff --git a/ui/src/Pages/PeoplePage/PeoplePage.test.tsx b/ui/src/Pages/PeoplePage/PeoplePage.test.tsx
index efef1f8..92f9aee 100644
--- a/ui/src/Pages/PeoplePage/PeoplePage.test.tsx
+++ b/ui/src/Pages/PeoplePage/PeoplePage.test.tsx
@@ -1,6 +1,7 @@
 import React from 'react'
 import { fireEvent, render, screen, waitFor } from '@testing-library/react'
-import PeoplePage, {
+import {
+  PeoplePage,
   FaceDetails,
   FaceGroup,
   MY_FACES_QUERY,
@@ -69,16 +70,10 @@ describe('PeoplePage component', () => {
   ]
 
   test('people page', async () => {
-    const matchMock = {
-      params: {
-        person: undefined,
-      },
-    }
-
     render(
       <MemoryRouter initialEntries={['/people']}>
         <MockedProvider mocks={graphqlMocks} addTypename={false}>
-          <PeoplePage match={matchMock} />
+          <PeoplePage />
         </MockedProvider>
       </MemoryRouter>
     )
diff --git a/ui/src/Pages/PeoplePage/SingleFaceGroup/SingleFaceGroup.test.tsx b/ui/src/Pages/PeoplePage/SingleFaceGroup/SingleFaceGroup.test.tsx
index acd0e20..f22658e 100644
--- a/ui/src/Pages/PeoplePage/SingleFaceGroup/SingleFaceGroup.test.tsx
+++ b/ui/src/Pages/PeoplePage/SingleFaceGroup/SingleFaceGroup.test.tsx
@@ -2,6 +2,7 @@ import React from 'react'
 import { render, screen, waitFor } from '@testing-library/react'
 import { MockedProvider } from '@apollo/client/testing'
 import SingleFaceGroup, { SINGLE_FACE_GROUP } from './SingleFaceGroup'
+import { MemoryRouter } from 'react-router-dom'
 
 jest.mock('../../../hooks/useScrollPagination')
 
@@ -83,9 +84,11 @@ test('single face group', async () => {
   ]
 
   render(
-    <MockedProvider mocks={graphqlMocks}>
-      <SingleFaceGroup faceGroupID="123" />
-    </MockedProvider>
+    <MemoryRouter initialEntries={['/person/123']}>
+      <MockedProvider mocks={graphqlMocks}>
+        <SingleFaceGroup faceGroupID="123" />
+      </MockedProvider>
+    </MemoryRouter>
   )
 
   await waitFor(() => {
diff --git a/ui/src/components/routes/AuthorizedRoute.test.tsx b/ui/src/components/routes/AuthorizedRoute.test.tsx
index 7e87756..307a27d 100644
--- a/ui/src/components/routes/AuthorizedRoute.test.tsx
+++ b/ui/src/components/routes/AuthorizedRoute.test.tsx
@@ -1,9 +1,11 @@
 import React from 'react'
-import AuthorizedRoute from './AuthorizedRoute'
-import { render, screen } from '@testing-library/react'
-import { MemoryRouter, Route } from 'react-router-dom'
+import AuthorizedRoute, { useIsAdmin } from './AuthorizedRoute'
+import { render, screen, waitFor } from '@testing-library/react'
+import { MemoryRouter, Route, Routes } from 'react-router-dom'
 
 import * as authentication from '../../helpers/authentication'
+import { MockedProvider } from '@apollo/client/testing'
+import { ADMIN_QUERY } from '../layout/Layout'
 
 jest.mock('../../helpers/authentication.ts')
 
@@ -18,26 +20,117 @@ describe('AuthorizedRoute component', () => {
     authToken.mockImplementation(() => null)
 
     render(
-      <MemoryRouter initialEntries={['/']}>
-        <Route path="/login">login redirect</Route>
-        <AuthorizedRoute path="/" component={AuthorizedComponent} />
+      <MemoryRouter initialEntries={['/authorized']}>
+        <Routes>
+          <Route index element={<div>redirect</div>} />
+          <Route
+            path="/authorized"
+            element={
+              <AuthorizedRoute>
+                <AuthorizedComponent />
+              </AuthorizedRoute>
+            }
+          />
+        </Routes>
       </MemoryRouter>
     )
 
-    expect(screen.getByText('login redirect')).toBeInTheDocument()
+    expect(screen.getByText('redirect')).toBeInTheDocument()
+    expect(screen.queryByText('authorized content')).toBeNull()
   })
 
   test('logged in', async () => {
     authToken.mockImplementation(() => 'token-here')
 
     render(
-      <MemoryRouter initialEntries={['/']}>
-        <Route path="/login">login redirect</Route>
-        <AuthorizedRoute path="/" component={AuthorizedComponent} />
+      <MemoryRouter initialEntries={['/authorized']}>
+        <Routes>
+          <Route index element={<div>redirect</div>} />
+          <Route
+            path="/authorized"
+            element={
+              <AuthorizedRoute>
+                <AuthorizedComponent />
+              </AuthorizedRoute>
+            }
+          />
+        </Routes>
       </MemoryRouter>
     )
 
     expect(screen.getByText('authorized content')).toBeInTheDocument()
-    expect(screen.queryByText('login redirect')).toBeNull()
+    expect(screen.queryByText('redirect')).toBeNull()
+  })
+})
+
+describe('useIsAdmin hook', () => {
+  const graphqlMock = (admin: boolean) => ({
+    request: {
+      query: ADMIN_QUERY,
+    },
+    result: {
+      data: {
+        myUser: {
+          admin,
+        },
+      },
+    },
+  })
+
+  test('not logged in', async () => {
+    authToken.mockImplementation(() => null)
+
+    const TestComponent = () => {
+      const isAdmin = useIsAdmin()
+      return isAdmin ? <div>is admin</div> : <div>not admin</div>
+    }
+
+    render(
+      <MockedProvider mocks={[graphqlMock(true)]}>
+        <TestComponent />
+      </MockedProvider>
+    )
+
+    await waitFor(() => {
+      expect(screen.getByText('not admin')).toBeInTheDocument()
+    })
+  })
+
+  test('not admin', async () => {
+    authToken.mockImplementation(() => 'token-here')
+
+    const TestComponent = () => {
+      const isAdmin = useIsAdmin()
+      return isAdmin ? <div>is admin</div> : <div>not admin</div>
+    }
+
+    render(
+      <MockedProvider mocks={[graphqlMock(false)]}>
+        <TestComponent />
+      </MockedProvider>
+    )
+
+    await waitFor(() => {
+      expect(screen.getByText('not admin')).toBeInTheDocument()
+    })
+  })
+
+  test('is admin', async () => {
+    authToken.mockImplementation(() => 'token-here')
+
+    const TestComponent = () => {
+      const isAdmin = useIsAdmin()
+      return isAdmin ? <div>is admin</div> : <div>not admin</div>
+    }
+
+    render(
+      <MockedProvider mocks={[graphqlMock(true)]}>
+        <TestComponent />
+      </MockedProvider>
+    )
+
+    await waitFor(() => {
+      expect(screen.getByText('is admin')).toBeInTheDocument()
+    })
   })
 })
diff --git a/ui/src/components/routes/AuthorizedRoute.tsx b/ui/src/components/routes/AuthorizedRoute.tsx
index 5a07e3b..a563284 100644
--- a/ui/src/components/routes/AuthorizedRoute.tsx
+++ b/ui/src/components/routes/AuthorizedRoute.tsx
@@ -1,6 +1,6 @@
-import React, { useEffect } from 'react'
-import { RouteProps, Navigate } from 'react-router-dom'
 import { useLazyQuery } from '@apollo/client'
+import React, { useEffect } from 'react'
+import { Navigate } from 'react-router-dom'
 import { authToken } from '../../helpers/authentication'
 import { ADMIN_QUERY } from '../layout/Layout'
 
@@ -26,23 +26,17 @@ export const Authorized = ({ children }: { children: JSX.Element }) => {
   return token ? children : null
 }
 
-interface AuthorizedRouteProps extends Omit<RouteProps, 'component'> {
+interface AuthorizedRouteProps {
   children: React.ReactNode
-  admin?: boolean
 }
 
-const AuthorizedRoute = ({ admin = false, children }: AuthorizedRouteProps) => {
+const AuthorizedRoute = ({ children }: AuthorizedRouteProps) => {
   const token = authToken()
-  const isAdmin = useIsAdmin()
 
   if (!token) {
     return <Navigate to="/" />
   }
 
-  if (admin && !isAdmin) {
-    return <Navigate to="/" />
-  }
-
   return <>{children}</>
 }
 
