69 lines
2.0 KiB
TypeScript
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())
|
||
|
|
})
|
||
|
|
})
|