/** * Tests for UserStatusChart Component */ import { render, screen } from '@testing-library/react'; import { UserStatusChart } from '@/components/charts/UserStatusChart'; import type { UserStatusData } from '@/components/charts/UserStatusChart'; // Capture label function at module level for testing let capturedLabelFunction: ((entry: any) => string) | null = null; // Mock recharts to avoid rendering issues in tests jest.mock('recharts', () => { const OriginalModule = jest.requireActual('recharts'); const MockPie = (props: any) => { // Capture the label function for testing if (props.label && typeof props.label === 'function') { capturedLabelFunction = props.label; } return
{props.children}
; }; return { ...OriginalModule, ResponsiveContainer: ({ children }: { children: React.ReactNode }) => (
{children}
), PieChart: ({ children }: { children: React.ReactNode }) => (
{children}
), Pie: MockPie, Cell: ({ fill }: { fill: string }) =>
, Tooltip: () =>
, Legend: () =>
, }; }); describe('UserStatusChart', () => { const mockData: UserStatusData[] = [ { name: 'Active', value: 142, color: 'hsl(var(--chart-1))' }, { name: 'Inactive', value: 28, color: 'hsl(var(--chart-2))' }, { name: 'Pending', value: 15, color: 'hsl(var(--chart-3))' }, ]; it('renders chart card with title and description', () => { render(); expect(screen.getByText('User Status Distribution')).toBeInTheDocument(); expect(screen.getByText('Breakdown of users by status')).toBeInTheDocument(); }); it('renders chart with provided data', () => { render(); expect(screen.getByTestId('responsive-container')).toBeInTheDocument(); }); it('renders with mock data when no data is provided', () => { render(); expect(screen.getByText('User Status Distribution')).toBeInTheDocument(); expect(screen.getByText('No user status data available')).toBeInTheDocument(); }); it('shows loading state', () => { render(); expect(screen.getByText('User Status Distribution')).toBeInTheDocument(); // Chart should not be visible when loading expect(screen.queryByTestId('responsive-container')).not.toBeInTheDocument(); }); it('shows error state', () => { render(); expect(screen.getByText('User Status Distribution')).toBeInTheDocument(); expect(screen.getByText('Failed to load chart data')).toBeInTheDocument(); // Chart should not be visible when error expect(screen.queryByTestId('responsive-container')).not.toBeInTheDocument(); }); it('renders with empty data array', () => { render(); expect(screen.getByText('User Status Distribution')).toBeInTheDocument(); expect(screen.getByText('No user status data available')).toBeInTheDocument(); }); describe('renderLabel function', () => { beforeEach(() => { capturedLabelFunction = null; }); it('formats label with name and percentage', () => { render(); expect(capturedLabelFunction).toBeTruthy(); if (capturedLabelFunction) { const result = capturedLabelFunction({ name: 'Active', percent: 0.75 }); expect(result).toBe('Active: 75%'); } }); it('formats label with zero percent', () => { render(); if (capturedLabelFunction) { const result = capturedLabelFunction({ name: 'Inactive', percent: 0 }); expect(result).toBe('Inactive: 0%'); } }); it('formats label with 100 percent', () => { render(); if (capturedLabelFunction) { const result = capturedLabelFunction({ name: 'All Users', percent: 1 }); expect(result).toBe('All Users: 100%'); } }); it('rounds percentage to nearest whole number', () => { render(); if (capturedLabelFunction) { const result = capturedLabelFunction({ name: 'Pending', percent: 0.4567 }); expect(result).toBe('Pending: 46%'); } }); it('handles small percentages', () => { render(); if (capturedLabelFunction) { const result = capturedLabelFunction({ name: 'Suspended', percent: 0.025 }); expect(result).toBe('Suspended: 3%'); } }); }); });