Add comprehensive tests for: - Pagination: navigation, page numbers, disabled states - EmptyState: message, icon, title, action button - LoadingState: different types (page, card, table, list) - Modal: open/close, backdrop click, escape key, sizes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
175 lines
5.5 KiB
TypeScript
175 lines
5.5 KiB
TypeScript
/**
|
|
* Tests for the Pagination component
|
|
* @jest-environment jsdom
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { render, screen, fireEvent } from '@testing-library/react';
|
|
import { Pagination } from '@/components/ui/Pagination';
|
|
|
|
describe('Pagination', () => {
|
|
const mockOnPageChange = jest.fn();
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it('should return null when totalPages is 1', () => {
|
|
const { container } = render(
|
|
<Pagination currentPage={1} totalPages={1} onPageChange={mockOnPageChange} />
|
|
);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it('should return null when totalPages is 0', () => {
|
|
const { container } = render(
|
|
<Pagination currentPage={1} totalPages={0} onPageChange={mockOnPageChange} />
|
|
);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it('should render previous and next buttons', () => {
|
|
render(
|
|
<Pagination currentPage={2} totalPages={5} onPageChange={mockOnPageChange} />
|
|
);
|
|
expect(screen.getByText('Précédent')).toBeInTheDocument();
|
|
expect(screen.getByText('Suivant')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should disable previous button on first page', () => {
|
|
render(
|
|
<Pagination currentPage={1} totalPages={5} onPageChange={mockOnPageChange} />
|
|
);
|
|
const prevButton = screen.getByText('Précédent').closest('button');
|
|
expect(prevButton).toBeDisabled();
|
|
});
|
|
|
|
it('should disable next button on last page', () => {
|
|
render(
|
|
<Pagination currentPage={5} totalPages={5} onPageChange={mockOnPageChange} />
|
|
);
|
|
const nextButton = screen.getByText('Suivant').closest('button');
|
|
expect(nextButton).toBeDisabled();
|
|
});
|
|
|
|
it('should call onPageChange with previous page when clicking previous', () => {
|
|
render(
|
|
<Pagination currentPage={3} totalPages={5} onPageChange={mockOnPageChange} />
|
|
);
|
|
fireEvent.click(screen.getByText('Précédent'));
|
|
expect(mockOnPageChange).toHaveBeenCalledWith(2);
|
|
});
|
|
|
|
it('should call onPageChange with next page when clicking next', () => {
|
|
render(
|
|
<Pagination currentPage={3} totalPages={5} onPageChange={mockOnPageChange} />
|
|
);
|
|
fireEvent.click(screen.getByText('Suivant'));
|
|
expect(mockOnPageChange).toHaveBeenCalledWith(4);
|
|
});
|
|
|
|
it('should not call onPageChange when clicking disabled previous', () => {
|
|
render(
|
|
<Pagination currentPage={1} totalPages={5} onPageChange={mockOnPageChange} />
|
|
);
|
|
fireEvent.click(screen.getByText('Précédent'));
|
|
expect(mockOnPageChange).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should not call onPageChange when clicking disabled next', () => {
|
|
render(
|
|
<Pagination currentPage={5} totalPages={5} onPageChange={mockOnPageChange} />
|
|
);
|
|
fireEvent.click(screen.getByText('Suivant'));
|
|
expect(mockOnPageChange).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should show page numbers when showPageNumbers is true', () => {
|
|
render(
|
|
<Pagination
|
|
currentPage={1}
|
|
totalPages={3}
|
|
onPageChange={mockOnPageChange}
|
|
showPageNumbers={true}
|
|
/>
|
|
);
|
|
expect(screen.getByText('1')).toBeInTheDocument();
|
|
expect(screen.getByText('2')).toBeInTheDocument();
|
|
expect(screen.getByText('3')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should show page text when showPageNumbers is false', () => {
|
|
render(
|
|
<Pagination
|
|
currentPage={2}
|
|
totalPages={5}
|
|
onPageChange={mockOnPageChange}
|
|
showPageNumbers={false}
|
|
/>
|
|
);
|
|
expect(screen.getByText('Page 2 sur 5')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should call onPageChange when clicking a page number', () => {
|
|
render(
|
|
<Pagination currentPage={1} totalPages={5} onPageChange={mockOnPageChange} />
|
|
);
|
|
fireEvent.click(screen.getByText('3'));
|
|
expect(mockOnPageChange).toHaveBeenCalledWith(3);
|
|
});
|
|
|
|
it('should highlight current page', () => {
|
|
render(
|
|
<Pagination currentPage={2} totalPages={3} onPageChange={mockOnPageChange} />
|
|
);
|
|
const currentPageButton = screen.getByText('2');
|
|
expect(currentPageButton).toHaveClass('bg-blue-600');
|
|
expect(currentPageButton).toHaveClass('text-white');
|
|
});
|
|
|
|
it('should show ellipsis for many pages when at start', () => {
|
|
render(
|
|
<Pagination currentPage={2} totalPages={10} onPageChange={mockOnPageChange} />
|
|
);
|
|
expect(screen.getByText('...')).toBeInTheDocument();
|
|
expect(screen.getByText('10')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should show ellipsis for many pages when at end', () => {
|
|
render(
|
|
<Pagination currentPage={9} totalPages={10} onPageChange={mockOnPageChange} />
|
|
);
|
|
expect(screen.getByText('...')).toBeInTheDocument();
|
|
expect(screen.getByText('1')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should show two ellipsis when in middle of many pages', () => {
|
|
render(
|
|
<Pagination currentPage={5} totalPages={10} onPageChange={mockOnPageChange} />
|
|
);
|
|
const ellipsis = screen.getAllByText('...');
|
|
expect(ellipsis).toHaveLength(2);
|
|
});
|
|
|
|
it('should apply custom className', () => {
|
|
const { container } = render(
|
|
<Pagination
|
|
currentPage={1}
|
|
totalPages={3}
|
|
onPageChange={mockOnPageChange}
|
|
className="custom-class"
|
|
/>
|
|
);
|
|
expect(container.firstChild).toHaveClass('custom-class');
|
|
});
|
|
|
|
it('should have flex layout', () => {
|
|
const { container } = render(
|
|
<Pagination currentPage={1} totalPages={3} onPageChange={mockOnPageChange} />
|
|
);
|
|
expect(container.firstChild).toHaveClass('flex');
|
|
expect(container.firstChild).toHaveClass('items-center');
|
|
expect(container.firstChild).toHaveClass('justify-center');
|
|
});
|
|
});
|