1
0
Files
record-shop/web/test/auth.test.tsx

69 lines
2.0 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import { AuthProvider, useAuth } from '../src/auth'
function Probe() {
const { status, user, setupNeeded } = useAuth()
return (
<div>
<div>status:{status}</div>
{setupNeeded && <div>setup-needed</div>}
{user && <div>user:{user.username}</div>}
</div>
)
}
const fetchMock = vi.fn()
beforeEach(() => {
fetchMock.mockReset()
vi.stubGlobal('fetch', fetchMock)
})
function jsonOnce(status: number, body: unknown) {
return new Response(JSON.stringify(body), {
status,
headers: { 'content-type': 'application/json' },
})
}
describe('AuthProvider', () => {
it('reports setupNeeded when the server has no users', async () => {
fetchMock.mockResolvedValueOnce(jsonOnce(200, { needed: true }))
render(
<AuthProvider>
<Probe />
</AuthProvider>
)
expect(screen.getByText('status:loading')).toBeTruthy()
await waitFor(() => expect(screen.getByText('status:setup')).toBeTruthy())
expect(screen.getByText('setup-needed')).toBeTruthy()
expect(fetchMock).toHaveBeenCalledWith('/api/setup', expect.anything())
})
it('exposes the user when /api/me succeeds', async () => {
fetchMock
.mockResolvedValueOnce(jsonOnce(200, { needed: false }))
.mockResolvedValueOnce(jsonOnce(200, { user: { id: 1, username: 'sam', isAdmin: true } }))
render(
<AuthProvider>
<Probe />
</AuthProvider>
)
await waitFor(() => expect(screen.getByText('status:authenticated')).toBeTruthy())
expect(screen.getByText('user:sam')).toBeTruthy()
})
it('reports unauthenticated when /api/me is 401', async () => {
fetchMock
.mockResolvedValueOnce(jsonOnce(200, { needed: false }))
.mockResolvedValueOnce(jsonOnce(401, { error: 'unauthorized' }))
render(
<AuthProvider>
<Probe />
</AuthProvider>
)
await waitFor(() => expect(screen.getByText('status:unauthenticated')).toBeTruthy())
})
})