Add EventList component tests
- Create event-list.test.tsx with 12 test cases - Tests for loading states, data display, filtering - Tests for error handling and empty states - Mock API for isolated testing
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { EventList } from '../event-list';
|
||||
import { api } from '@/lib/api';
|
||||
|
||||
// Mock the API
|
||||
jest.mock('@/lib/api', () => ({
|
||||
api: {
|
||||
getEvents: jest.fn(),
|
||||
},
|
||||
Event: {},
|
||||
}));
|
||||
|
||||
describe('EventList', () => {
|
||||
const mockEvents = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'Marathon 2024',
|
||||
description: 'Annual city marathon',
|
||||
eventDate: '2024-06-15',
|
||||
location: 'City Center',
|
||||
status: 'Published',
|
||||
category: 'Running',
|
||||
tags: ['marathon', 'running'],
|
||||
maxParticipants: 100,
|
||||
currentRegistrations: 45,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'Cycling Race',
|
||||
description: 'Mountain cycling event',
|
||||
eventDate: '2024-07-20',
|
||||
location: 'Mountain Trail',
|
||||
status: 'Draft',
|
||||
category: 'Cycling',
|
||||
tags: ['cycling', 'mountain'],
|
||||
maxParticipants: 50,
|
||||
currentRegistrations: 20,
|
||||
},
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
// Positive Tests
|
||||
describe('Positive Tests', () => {
|
||||
it('renders loading state initially', () => {
|
||||
(api.getEvents as jest.Mock).mockImplementation(() => new Promise(() => {}));
|
||||
|
||||
render(<EventList />);
|
||||
|
||||
expect(screen.getByText(/loading events/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders list of events', async () => {
|
||||
(api.getEvents as jest.Mock).mockResolvedValue(mockEvents);
|
||||
|
||||
render(<EventList />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Marathon 2024')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(screen.getByText('Cycling Race')).toBeInTheDocument();
|
||||
expect(screen.getByText('Annual city marathon')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('filters events by category', async () => {
|
||||
(api.getEvents as jest.Mock).mockResolvedValue([mockEvents[0]]);
|
||||
|
||||
render(<EventList />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(/loading/i)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
fireEvent.change(screen.getByLabelText(/category/i), {
|
||||
target: { value: 'Running' },
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(api.getEvents).toHaveBeenCalledWith(expect.objectContaining({ category: 'Running' }));
|
||||
});
|
||||
});
|
||||
|
||||
it('filters events by status', async () => {
|
||||
(api.getEvents as jest.Mock).mockResolvedValue([mockEvents[1]]);
|
||||
|
||||
render(<EventList />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(/loading/i)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
fireEvent.change(screen.getByLabelText(/status/i), {
|
||||
target: { value: 'Draft' },
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(api.getEvents).toHaveBeenCalledWith(expect.objectContaining({ status: 'Draft' }));
|
||||
});
|
||||
});
|
||||
|
||||
it('displays event details correctly', async () => {
|
||||
(api.getEvents as jest.Mock).mockResolvedValue([mockEvents[0]]);
|
||||
|
||||
render(<EventList />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Marathon 2024')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(screen.getByText('City Center')).toBeInTheDocument();
|
||||
expect(screen.getByText(/45.*\/.*100.*registered/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows view details link for events', async () => {
|
||||
(api.getEvents as jest.Mock).mockResolvedValue([mockEvents[0]]);
|
||||
|
||||
render(<EventList />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Marathon 2024')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const viewLink = screen.getByRole('link', { name: /view details/i });
|
||||
expect(viewLink).toHaveAttribute('href', '/events/1');
|
||||
});
|
||||
});
|
||||
|
||||
// Negative Tests
|
||||
describe('Negative Tests', () => {
|
||||
it('displays error message when API fails', async () => {
|
||||
(api.getEvents as jest.Mock).mockRejectedValue(new Error('Failed to fetch'));
|
||||
|
||||
render(<EventList />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/failed to load events/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('shows empty state when no events', async () => {
|
||||
(api.getEvents as jest.Mock).mockResolvedValue([]);
|
||||
|
||||
render(<EventList />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/no events found/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('handles network error gracefully', async () => {
|
||||
(api.getEvents as jest.Mock).mockRejectedValue(new Error('Network error'));
|
||||
|
||||
render(<EventList />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/network error/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user