Skip to content

Commit

Permalink
Router tests: More advanced auth mock (redwoodjs#5742)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobbe authored Jun 26, 2022
1 parent 647065c commit 151d89e
Showing 1 changed file with 73 additions and 6 deletions.
79 changes: 73 additions & 6 deletions packages/router/src/__tests__/router.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jest.mock('../util', () => {
}
})

import React from 'react'
import React, { useEffect, useState } from 'react'

import { render, waitFor, act, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
Expand Down Expand Up @@ -61,24 +61,46 @@ function createDummyAuthContextValues(partial: Partial<AuthContextInterface>) {
return { ...authContextValues, ...partial }
}

interface MockAuth {
isAuthenticated?: boolean
loading?: boolean
hasRole?: boolean
loadingTimeMs?: number
}

const mockUseAuth =
(
{
isAuthenticated = false,
loading = false,
hasRole = false,
}: { isAuthenticated?: boolean; loading?: boolean; hasRole?: boolean } = {
loadingTimeMs,
}: MockAuth = {
isAuthenticated: false,
loading: false,
hasRole: false,
}
) =>
() =>
createDummyAuthContextValues({
loading,
isAuthenticated,
() => {
const [authLoading, setAuthLoading] = useState(loading)
const [authIsAuthenticated, setAuthIsAuthenticated] =
useState(isAuthenticated)

useEffect(() => {
if (loadingTimeMs) {
setTimeout(() => {
setAuthLoading(false)
setAuthIsAuthenticated(true)
}, loadingTimeMs)
}
}, [])

return createDummyAuthContextValues({
loading: authLoading,
isAuthenticated: authIsAuthenticated,
hasRole: () => hasRole,
})
}

// SETUP
const HomePage = () => <h1>Home Page</h1>
Expand Down Expand Up @@ -736,6 +758,51 @@ test('can display a loading screen whilst waiting for auth', async () => {
})
})

test('can display a loading screen with a hook', async () => {
const HookLoader = () => {
const [showStill, setShowStill] = useState(false)

useEffect(() => {
setTimeout(() => setShowStill(true), 100)
}, [])

return <>{showStill ? 'Still authenticating...' : 'Authenticating...'}</>
}

const TestRouter = () => (
<Router
useAuth={mockUseAuth({
isAuthenticated: false,
loading: true,
loadingTimeMs: 700,
})}
>
<Route path="/" page={HomePage} name="home" />
<Private unauthenticated="home" whileLoadingAuth={HookLoader}>
<Route path="/private" page={PrivatePage} name="private" />
</Private>
</Router>
)
const screen = render(<TestRouter />)

// starts on home page
await waitFor(() => screen.getByText(/Home Page/i))

// navigate to private page
// should not redirect
act(() => navigate(routes.private()))
await waitFor(() => {
expect(screen.getByText(/Authenticating.../)).toBeInTheDocument()
expect(screen.queryByText(/Home Page/)).not.toBeInTheDocument()
expect(screen.queryByText(/Private Page/)).not.toBeInTheDocument()
})
await waitFor(() => {
expect(screen.getByText(/Still authenticating.../)).toBeInTheDocument()
expect(screen.queryByText(/Home Page/)).not.toBeInTheDocument()
expect(screen.queryByText(/Private Page/)).not.toBeInTheDocument()
})
})

test('inits routes two private routes with a space in between and loads as expected', async () => {
const TestRouter = () => (
<Router useAuth={mockUseAuth()}>
Expand Down

0 comments on commit 151d89e

Please sign in to comment.