import { describe, it, expect, beforeEach } from 'vitest'
import { screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { http, HttpResponse } from 'msw'
import { server } from '@/test/mocks/server'
import { renderWithProviders } from '@/test/utils'
import { AdminUsersPage } from '@/pages/AdminUsersPage'
describe('AdminUsersPage', () => {
beforeEach(() => {
localStorage.setItem('access_token', 'test-token')
})
it('renders user list with user data', async () => {
renderWithProviders(, { initialRoute: '/admin/users' })
await waitFor(() => {
// mockUserResponse has username 'admin_user', email 'admin@dak.de', role 'admin'
expect(screen.getByText('admin_user')).toBeInTheDocument()
})
expect(screen.getByText('admin@dak.de')).toBeInTheDocument()
expect(screen.getByText('Admin')).toBeInTheDocument()
// "Aktiv" appears both as table header and badge; check for at least 2
const aktivElements = screen.getAllByText('Aktiv')
expect(aktivElements.length).toBeGreaterThanOrEqual(2)
})
it('shows "Neuen Benutzer erstellen" button and opens dialog', async () => {
const user = userEvent.setup()
renderWithProviders(, { initialRoute: '/admin/users' })
await waitFor(() => {
expect(screen.getByText('Neuen Benutzer erstellen')).toBeInTheDocument()
})
// Click the create button to open the dialog
await user.click(screen.getByText('Neuen Benutzer erstellen'))
// Dialog should open with form fields
await waitFor(() => {
expect(screen.getByLabelText('Benutzername')).toBeInTheDocument()
})
expect(screen.getByLabelText('E-Mail')).toBeInTheDocument()
expect(screen.getByLabelText('Passwort')).toBeInTheDocument()
})
it('handles empty user list', async () => {
server.use(
http.get('/api/admin/users', () => {
return HttpResponse.json([])
}),
)
renderWithProviders(, { initialRoute: '/admin/users' })
await waitFor(() => {
expect(screen.getByText('Keine Benutzer gefunden.')).toBeInTheDocument()
})
})
it('shows loading state', () => {
server.use(
http.get('/api/admin/users', async () => {
await new Promise((resolve) => setTimeout(resolve, 500))
return HttpResponse.json([])
}),
)
renderWithProviders(, { initialRoute: '/admin/users' })
// Heading is always visible
expect(screen.getByText('Benutzer')).toBeInTheDocument()
// During loading, user data should not be visible yet
expect(screen.queryByText('admin_user')).not.toBeInTheDocument()
expect(screen.queryByText('Keine Benutzer gefunden.')).not.toBeInTheDocument()
})
it('shows error state on API failure', async () => {
server.use(
http.get('/api/admin/users', () => {
return new HttpResponse(null, { status: 500 })
}),
)
renderWithProviders(, { initialRoute: '/admin/users' })
// When the query fails, users defaults to [] so it should show empty state
await waitFor(() => {
expect(screen.getByText('Keine Benutzer gefunden.')).toBeInTheDocument()
})
})
})