buckets/frontend/src/router.test.tsx

106 lines
3.3 KiB
TypeScript
Raw Normal View History

import { render, screen } from '@testing-library/react'
import { http, HttpResponse } from 'msw'
import { createMemoryRouter, RouterProvider } from 'react-router'
import { describe, expect, it } from 'vitest'
import { AuthProvider } from './auth/AuthProvider'
import { routes } from './router'
import { server } from './test/server'
/**
* Smoke tests for the REAL route-object array (`routes` from ./router), driven
* through `createMemoryRouter`. Unlike the guard/page component tests, these
* exercise the actual shipped config end-to-end catch-all redirect, both
* guards, and the real pages so a future swapped path/element regression in
* router.tsx is caught here instead of only in hand-built test route trees.
*/
describe('app router config', () => {
it('unknown paths redirect to the app root', async () => {
server.use(
http.get('http://localhost/api/me', () =>
HttpResponse.json({ id: 'u1', email: 'a@b.com' }),
),
http.get('http://localhost/api/scenarios', () =>
HttpResponse.json({
'@context': '/api/contexts/Scenario',
'@id': '/api/scenarios',
'@type': 'hydra:Collection',
member: [
{
'@id': '/api/scenarios/11111111-1111-1111-1111-111111111111',
'@type': 'Scenario',
name: 'Emergency Fund',
description: 'Rainy day savings',
},
],
totalItems: 1,
}),
),
)
const router = createMemoryRouter(routes, {
initialEntries: ['/some/unknown/path'],
})
render(
<AuthProvider>
<RouterProvider router={router} />
</AuthProvider>,
)
expect(await screen.findByText('Emergency Fund')).toBeInTheDocument()
})
it('the /login route resolves to the login page for a guest', async () => {
server.use(
http.get('http://localhost/api/me', () =>
HttpResponse.json({ message: 'unauthorized' }, { status: 401 }),
),
)
const router = createMemoryRouter(routes, { initialEntries: ['/login'] })
render(
<AuthProvider>
<RouterProvider router={router} />
</AuthProvider>,
)
expect(await screen.findByLabelText(/email/i)).toBeInTheDocument()
})
it('an authenticated user at /login is redirected to the app', async () => {
server.use(
http.get('http://localhost/api/me', () =>
HttpResponse.json({ id: 'u1', email: 'a@b.com' }),
),
http.get('http://localhost/api/scenarios', () =>
HttpResponse.json({
'@context': '/api/contexts/Scenario',
'@id': '/api/scenarios',
'@type': 'hydra:Collection',
member: [
{
'@id': '/api/scenarios/11111111-1111-1111-1111-111111111111',
'@type': 'Scenario',
name: 'Emergency Fund',
description: 'Rainy day savings',
},
],
totalItems: 1,
}),
),
)
const router = createMemoryRouter(routes, { initialEntries: ['/login'] })
render(
<AuthProvider>
<RouterProvider router={router} />
</AuthProvider>,
)
expect(await screen.findByText('Emergency Fund')).toBeInTheDocument()
expect(screen.queryByLabelText(/email/i)).not.toBeInTheDocument()
})
})