import { describe, it, expect, vi } from 'vitest'; import { render, screen, fireEvent } from '@testing-library/svelte'; import Pagination from '$lib/components/molecules/Pagination/Pagination.svelte'; describe('Pagination', () => { it('renders nothing when totalPages <= 1', () => { const { container } = render(Pagination, { props: { currentPage: 1, totalPages: 1, onPageChange: vi.fn() } }); expect(container.querySelector('nav')).toBeNull(); }); it('renders nothing when totalPages is 0', () => { const { container } = render(Pagination, { props: { currentPage: 1, totalPages: 0, onPageChange: vi.fn() } }); expect(container.querySelector('nav')).toBeNull(); }); it('renders all pages when totalPages <= 7', () => { render(Pagination, { props: { currentPage: 1, totalPages: 5, onPageChange: vi.fn() } }); for (let i = 1; i <= 5; i++) { expect(screen.getByRole('button', { name: `Page ${i}` })).toBeTruthy(); } }); it('renders ellipsis for large page counts', () => { const { container } = render(Pagination, { props: { currentPage: 10, totalPages: 20, onPageChange: vi.fn() } }); const ellipses = container.querySelectorAll('.pagination-ellipsis'); expect(ellipses.length).toBeGreaterThanOrEqual(1); }); it('marks current page with aria-current="page"', () => { render(Pagination, { props: { currentPage: 3, totalPages: 5, onPageChange: vi.fn() } }); const currentButton = screen.getByRole('button', { name: 'Page 3' }); expect(currentButton.getAttribute('aria-current')).toBe('page'); const otherButton = screen.getByRole('button', { name: 'Page 1' }); expect(otherButton.getAttribute('aria-current')).toBeNull(); }); it('disables "Précédent" button on page 1', () => { render(Pagination, { props: { currentPage: 1, totalPages: 5, onPageChange: vi.fn() } }); const prevButton = screen.getByRole('button', { name: 'Page précédente' }); expect(prevButton.hasAttribute('disabled')).toBe(true); }); it('disables "Suivant" button on last page', () => { render(Pagination, { props: { currentPage: 5, totalPages: 5, onPageChange: vi.fn() } }); const nextButton = screen.getByRole('button', { name: 'Page suivante' }); expect(nextButton.hasAttribute('disabled')).toBe(true); }); it('calls onPageChange with correct page on click', async () => { const onPageChange = vi.fn(); render(Pagination, { props: { currentPage: 2, totalPages: 5, onPageChange } }); await fireEvent.click(screen.getByRole('button', { name: 'Page 3' })); expect(onPageChange).toHaveBeenCalledWith(3); }); it('calls onPageChange on next button click', async () => { const onPageChange = vi.fn(); render(Pagination, { props: { currentPage: 2, totalPages: 5, onPageChange } }); await fireEvent.click(screen.getByRole('button', { name: 'Page suivante' })); expect(onPageChange).toHaveBeenCalledWith(3); }); it('calls onPageChange on previous button click', async () => { const onPageChange = vi.fn(); render(Pagination, { props: { currentPage: 3, totalPages: 5, onPageChange } }); await fireEvent.click(screen.getByRole('button', { name: 'Page précédente' })); expect(onPageChange).toHaveBeenCalledWith(2); }); it('clamps currentPage > totalPages gracefully', () => { render(Pagination, { props: { currentPage: 9999, totalPages: 5, onPageChange: vi.fn() } }); // Page 5 should be marked as active (clamped) const lastPageButton = screen.getByRole('button', { name: 'Page 5' }); expect(lastPageButton.getAttribute('aria-current')).toBe('page'); }); it('has aria-hidden on ellipsis elements', () => { const { container } = render(Pagination, { props: { currentPage: 10, totalPages: 20, onPageChange: vi.fn() } }); const ellipses = container.querySelectorAll('.pagination-ellipsis'); ellipses.forEach((el) => { expect(el.getAttribute('aria-hidden')).toBe('true'); }); }); });