import { render, screen, fireEvent } from '@testing-library/react'; import { Pagination as PaginationComponent } from '../../../../src/components/stats/Pagination'; describe('Pagination', () => { const onPageChange = vi.fn(); it('returns null when totalPages <= 1', () => { const { container } = render( ); expect(container.firstChild).toBeNull(); }); it('renders all page numbers when totalPages <= 5', () => { render(); expect(screen.getByText('1')).toBeInTheDocument(); expect(screen.getByText('2')).toBeInTheDocument(); expect(screen.getByText('3')).toBeInTheDocument(); expect(screen.getByText('4')).toBeInTheDocument(); expect(screen.getByText('5')).toBeInTheDocument(); expect(screen.getByText('2')).toHaveClass('bg-blue-600'); }); it('handles ellipsis correctly when currentPage is in the middle of a large set', () => { // totalPages = 10, currentPage = 5 // Expected: [1, '...', 4, 5, 6, '...', 10] render(); expect(screen.getByText('1')).toBeInTheDocument(); expect(screen.getByText('4')).toBeInTheDocument(); expect(screen.getByText('5')).toBeInTheDocument(); expect(screen.getByText('6')).toBeInTheDocument(); expect(screen.getByText('10')).toBeInTheDocument(); const allButtons = screen.getAllByRole('button'); const pageButtons = allButtons.filter(btn => !['Previous page', 'Next page'].includes(btn.getAttribute('aria-label') || '')); expect(pageButtons).toHaveLength(5); // 1, 4, 5, 6, 10 }); it('handles large page set with ellipsis at start and end correctly', () => { // totalPages = 10, currentPage = 2 // Expected: [1, 2, 3, '...', 10] render(); expect(screen.getByText('1')).toBeInTheDocument(); expect(screen.getByText('2')).toBeInTheDocument(); expect(screen.getByText('3')).toBeInTheDocument(); expect(screen.getByText('10')).toBeInTheDocument(); const allButtons = screen.getAllByRole('button'); const pageButtons = allButtons.filter(btn => !['Previous page', 'Next page'].includes(btn.getAttribute('aria-label') || '')); expect(pageButtons).toHaveLength(4); // 1, 2, 3, 10 }); it('handles large page set where current page is near the end', () => { // totalPages = 10, currentPage = 9 // Expected: [1, '...', 8, 9, 10] render(); expect(screen.getByText('1')).toBeInTheDocument(); expect(screen.getByText('8')).toBeInTheDocument(); expect(screen.getByText('9')).toBeInTheDocument(); expect(screen.getByText('10')).toBeInTheDocument(); const allButtons = screen.getAllByRole('button'); const pageButtons = allButtons.filter(btn => !['Previous page', 'Next page'].includes(btn.getAttribute('aria-label') || '')); expect(pageButtons).toHaveLength(4); // 1, 8, 9, 10 }); it('calls onPageChange with correct page when a page number is clicked', () => { render(); fireEvent.click(screen.getByText('4')); expect(onPageChange).toHaveBeenCalledWith(4); }); it('calls onPageChange with correct page when "Previous" is clicked', () => { render(); fireEvent.click(screen.getByRole('button', { name: /previous/i })); expect(onPageChange).toHaveBeenCalledWith(1); }); it('calls onPageChange with correct page when "Next" is clicked', () => { render(); fireEvent.click(screen.getByRole('button', { name: /next/i })); expect(onPageChange).toHaveBeenCalledWith(5); }); it('disables "Previous" button on first page', () => { render(); expect(screen.getByRole('button', { name: /previous/i })).toBeDisabled(); }); it('disables "Next" button on last page', () => { render(); expect(screen.getByRole('button', { name: /next/i })).toBeDisabled(); }); });