Files
euchre_camp/src/__tests__/EditTournamentForm.test.tsx
T

136 lines
3.9 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, MockedFunction } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import EditTournamentForm from '@/components/EditTournamentForm'
// Mock next/navigation
vi.mock('next/navigation', () => ({
useRouter: () => ({
push: vi.fn(),
}),
}))
// Mock next/link
vi.mock('next/link', () => ({
default: ({ children, href }: { children: React.ReactNode; href: string }) => (
<a href={href}>{children}</a>
),
}))
// Mock fetch
const mockFetch = vi.fn()
global.fetch = mockFetch as MockedFunction<typeof global.fetch>
const mockTournament = {
id: 1,
event_id: null,
name: 'Test Tournament',
description: 'A test tournament',
eventDate: new Date('2024-01-15'),
eventType: 'tournament',
format: 'round_robin',
status: 'planned',
maxParticipants: 16,
ownerId: null,
targetScore: null,
allowTies: false,
createdAt: new Date(),
updatedAt: new Date(),
}
describe('EditTournamentForm', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('renders form with initial values', () => {
render(<EditTournamentForm tournament={mockTournament} />)
expect(screen.getByLabelText('Tournament Name')).toHaveValue('Test Tournament')
expect(screen.getByLabelText('Description')).toHaveValue('A test tournament')
expect(screen.getByLabelText('Date')).toHaveValue('2024-01-15')
expect(screen.getByLabelText('Event Type')).toHaveValue('tournament')
expect(screen.getByLabelText('Format')).toHaveValue('round_robin')
expect(screen.getByLabelText('Status')).toHaveValue('planned')
expect(screen.getByLabelText('Max Participants (optional)')).toHaveValue(16)
})
it('updates form values on change', async () => {
const user = userEvent.setup()
render(<EditTournamentForm tournament={mockTournament} />)
const nameInput = screen.getByLabelText('Tournament Name')
await user.clear(nameInput)
await user.type(nameInput, 'Updated Tournament')
expect(nameInput).toHaveValue('Updated Tournament')
})
it('submits form with updated data', async () => {
const user = userEvent.setup()
mockFetch.mockResolvedValueOnce({
ok: true,
json: async () => ({ success: true }),
} as Response)
render(<EditTournamentForm tournament={mockTournament} />)
const nameInput = screen.getByLabelText('Tournament Name')
await user.clear(nameInput)
await user.type(nameInput, 'Updated Tournament')
const submitButton = screen.getByText('Save Changes')
await user.click(submitButton)
await waitFor(() => {
expect(mockFetch).toHaveBeenCalledWith(
'/api/tournaments/1',
expect.objectContaining({
method: 'PUT',
body: expect.stringContaining('Updated Tournament'),
})
)
})
})
it('shows error message on failed submission', async () => {
const user = userEvent.setup()
mockFetch.mockResolvedValueOnce({
ok: false,
json: async () => ({ error: 'Failed to update tournament' }),
} as Response)
render(<EditTournamentForm tournament={mockTournament} />)
const submitButton = screen.getByText('Save Changes')
await user.click(submitButton)
await waitFor(() => {
expect(screen.getByText('Failed to update tournament')).toBeInTheDocument()
})
})
it('disables submit button while loading', async () => {
const user = userEvent.setup()
mockFetch.mockImplementation(
() =>
new Promise((resolve) => {
setTimeout(() => {
resolve({
ok: true,
json: async () => ({ success: true }),
} as Response)
}, 100)
})
)
render(<EditTournamentForm tournament={mockTournament} />)
const submitButton = screen.getByText('Save Changes')
await user.click(submitButton)
expect(submitButton).toBeDisabled()
expect(submitButton).toHaveTextContent('Saving...')
})
})