144 lines
4.2 KiB
TypeScript
144 lines
4.2 KiB
TypeScript
import { describe, it, expect, mock, beforeEach } from 'bun:test'
|
|
import { render, screen, waitFor } from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
import EditTournamentForm from '@/components/EditTournamentForm'
|
|
|
|
// Mock next/navigation
|
|
mock.module('next/navigation', () => ({
|
|
useRouter: () => ({
|
|
push: mock(() => {}),
|
|
}),
|
|
}))
|
|
|
|
// Mock next/link
|
|
mock.module('next/link', () => ({
|
|
default: ({ children, href }: { children: React.ReactNode; href: string }) => (
|
|
<a href={href}>{children}</a>
|
|
),
|
|
}))
|
|
|
|
// Mock fetch
|
|
const mockFetch = mock(async () => new Response())
|
|
global.fetch = mockFetch as any
|
|
|
|
const mockTournament = {
|
|
id: 1,
|
|
event_id: null,
|
|
name: 'Test Tournament',
|
|
description: 'A test tournament',
|
|
eventDate: new Date('2024-01-15'),
|
|
eventType: 'tournament',
|
|
tournamentType: 'individual',
|
|
format: 'round_robin',
|
|
status: 'planned',
|
|
maxParticipants: 16,
|
|
ownerId: null,
|
|
targetScore: null,
|
|
allowTies: false,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
teamDurability: 'permanent',
|
|
partnerRotation: 'none',
|
|
allowByes: true,
|
|
teamConfiguration: null,
|
|
maxRosterChanges: null,
|
|
requireAdminVerify: false,
|
|
}
|
|
|
|
describe('EditTournamentForm', () => {
|
|
beforeEach(() => {
|
|
// Only clear the specific mocks we create, not global module mocks
|
|
mockFetch.mockClear()
|
|
})
|
|
|
|
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...')
|
|
})
|
|
})
|