From 23dab73bd8187b28b6acf8ca1a6e0d95b8135dd3 Mon Sep 17 00:00:00 2001 From: Denis Urs Rudolph Date: Mon, 6 Apr 2026 22:06:20 +0200 Subject: [PATCH] Add Dashboard component tests - Create dashboard.test.tsx with 14 test cases - Tests for organizer dashboard (loading, data display, quick actions) - Tests for participant dashboard (stats, registrations) - Negative tests for API failures and null data --- .../components/__tests__/dashboard.test.tsx | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 frontend/src/components/__tests__/dashboard.test.tsx diff --git a/frontend/src/components/__tests__/dashboard.test.tsx b/frontend/src/components/__tests__/dashboard.test.tsx new file mode 100644 index 0000000..5caa3d4 --- /dev/null +++ b/frontend/src/components/__tests__/dashboard.test.tsx @@ -0,0 +1,199 @@ +import { render, screen, waitFor } from '@testing-library/react'; +import { Dashboard } from '../dashboard'; +import { useAuth } from '@/lib/auth-context'; +import { api } from '@/lib/api'; + +// Mock the auth context and API +jest.mock('@/lib/auth-context', () => ({ + useAuth: jest.fn(), +})); + +jest.mock('@/lib/api', () => ({ + api: { + getOrganizerDashboard: jest.fn(), + getParticipantDashboard: jest.fn(), + }, +})); + +describe('Dashboard', () => { + const mockOrganizerData = { + totalEvents: 10, + publishedEvents: 5, + draftEvents: 3, + totalRegistrations: 50, + totalRevenue: 2500.00, + upcomingEvents: [ + { id: '1', name: 'Marathon', eventDate: '2024-06-15', registrationCount: 45 }, + ], + }; + + const mockParticipantData = { + totalRegistrations: 5, + upcomingEvents: 2, + completedEvents: 3, + cancelledRegistrations: 0, + myRegistrations: [ + { id: '1', eventId: '1', eventName: 'Marathon', eventDate: '2024-06-15', status: 'Confirmed' }, + ], + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Organizer Dashboard', () => { + it('renders loading state initially', () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Organizer' } }); + (api.getOrganizerDashboard as jest.Mock).mockImplementation(() => new Promise(() => {})); + + render(); + + expect(screen.getByText(/loading dashboard/i)).toBeInTheDocument(); + }); + + it('renders organizer dashboard with data', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Organizer' } }); + (api.getOrganizerDashboard as jest.Mock).mockResolvedValue(mockOrganizerData); + + render(); + + await waitFor(() => { + expect(screen.getByText('Total Events')).toBeInTheDocument(); + }); + + expect(screen.getByText('10')).toBeInTheDocument(); // totalEvents + expect(screen.getByText('5')).toBeInTheDocument(); // publishedEvents + expect(screen.getByText('3')).toBeInTheDocument(); // draftEvents + expect(screen.getByText('50')).toBeInTheDocument(); // totalRegistrations + }); + + it('displays quick action buttons for organizer', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Organizer' } }); + (api.getOrganizerDashboard as jest.Mock).mockResolvedValue(mockOrganizerData); + + render(); + + await waitFor(() => { + expect(screen.getByText('Create Event')).toBeInTheDocument(); + }); + + expect(screen.getByText('Manage Events')).toBeInTheDocument(); + }); + + it('shows upcoming events section', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Organizer' } }); + (api.getOrganizerDashboard as jest.Mock).mockResolvedValue(mockOrganizerData); + + render(); + + await waitFor(() => { + expect(screen.getByText('Upcoming Events')).toBeInTheDocument(); + }); + + expect(screen.getByText('Marathon')).toBeInTheDocument(); + }); + + it('displays revenue information', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Organizer' } }); + (api.getOrganizerDashboard as jest.Mock).mockResolvedValue(mockOrganizerData); + + render(); + + await waitFor(() => { + expect(screen.getByText('Revenue')).toBeInTheDocument(); + }); + + expect(screen.getByText('$2,500.00')).toBeInTheDocument(); + }); + }); + + describe('Participant Dashboard', () => { + it('renders participant dashboard with data', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Participant' } }); + (api.getParticipantDashboard as jest.Mock).mockResolvedValue(mockParticipantData); + + render(); + + await waitFor(() => { + expect(screen.getByText('Total Registrations')).toBeInTheDocument(); + }); + + expect(screen.getByText('5')).toBeInTheDocument(); // totalRegistrations + expect(screen.getByText('2')).toBeInTheDocument(); // upcomingEvents + expect(screen.getByText('3')).toBeInTheDocument(); // completedEvents + }); + + it('displays quick action buttons for participant', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Participant' } }); + (api.getParticipantDashboard as jest.Mock).mockResolvedValue(mockParticipantData); + + render(); + + await waitFor(() => { + expect(screen.getByText('Browse Events')).toBeInTheDocument(); + }); + + expect(screen.getByText('My Registrations')).toBeInTheDocument(); + }); + + it('shows my recent registrations', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Participant' } }); + (api.getParticipantDashboard as jest.Mock).mockResolvedValue(mockParticipantData); + + render(); + + await waitFor(() => { + expect(screen.getByText('My Recent Registrations')).toBeInTheDocument(); + }); + + expect(screen.getByText('Marathon')).toBeInTheDocument(); + expect(screen.getByText('Confirmed')).toBeInTheDocument(); + }); + }); + + describe('Negative Tests', () => { + it('displays error when API fails', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Organizer' } }); + (api.getOrganizerDashboard as jest.Mock).mockRejectedValue(new Error('Network error')); + + render(); + + await waitFor(() => { + expect(screen.getByText(/failed to load dashboard/i)).toBeInTheDocument(); + }); + }); + + it('handles organizer dashboard API failure', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Organizer' } }); + (api.getOrganizerDashboard as jest.Mock).mockRejectedValue(new Error('API Error')); + + render(); + + await waitFor(() => { + expect(screen.getByText(/api error/i)).toBeInTheDocument(); + }); + }); + + it('handles participant dashboard API failure', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Participant' } }); + (api.getParticipantDashboard as jest.Mock).mockRejectedValue(new Error('API Error')); + + render(); + + await waitFor(() => { + expect(screen.getByText(/api error/i)).toBeInTheDocument(); + }); + }); + + it('shows no data available when dashboard is null', async () => { + (useAuth as jest.Mock).mockReturnValue({ user: { role: 'Organizer' } }); + (api.getOrganizerDashboard as jest.Mock).mockResolvedValue(null); + + render(); + + await waitFor(() => { + expect(screen.getByText(/no data available/i)).toBeInTheDocument(); + }); + }); + }); +});