248 lines
6.6 KiB
TypeScript
248 lines
6.6 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { render, screen } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { NextPreviousButtons } from './NextPreviousButtons';
|
|
|
|
describe('NextPreviousButtons', () => {
|
|
const mockOnNext = vi.fn();
|
|
const mockOnPrevious = vi.fn();
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('should render both buttons', () => {
|
|
render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByLabelText('Piste précédente')).toBeInTheDocument();
|
|
expect(screen.getByLabelText('Piste suivante')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should call onPrevious when previous button is clicked', async () => {
|
|
const user = userEvent.setup();
|
|
|
|
render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
/>,
|
|
);
|
|
|
|
const previousButton = screen.getByLabelText('Piste précédente');
|
|
await user.click(previousButton);
|
|
|
|
expect(mockOnPrevious).toHaveBeenCalledTimes(1);
|
|
expect(mockOnNext).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should call onNext when next button is clicked', async () => {
|
|
const user = userEvent.setup();
|
|
|
|
render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
/>,
|
|
);
|
|
|
|
const nextButton = screen.getByLabelText('Piste suivante');
|
|
await user.click(nextButton);
|
|
|
|
expect(mockOnNext).toHaveBeenCalledTimes(1);
|
|
expect(mockOnPrevious).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should disable previous button when canGoPrevious is false', () => {
|
|
render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={false}
|
|
/>,
|
|
);
|
|
|
|
const previousButton = screen.getByLabelText('Piste précédente');
|
|
expect(previousButton).toBeDisabled();
|
|
expect(previousButton).toHaveAttribute('aria-disabled', 'true');
|
|
});
|
|
|
|
it('should disable next button when canGoNext is false', () => {
|
|
render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={false}
|
|
canGoPrevious={true}
|
|
/>,
|
|
);
|
|
|
|
const nextButton = screen.getByLabelText('Piste suivante');
|
|
expect(nextButton).toBeDisabled();
|
|
expect(nextButton).toHaveAttribute('aria-disabled', 'true');
|
|
});
|
|
|
|
it('should disable both buttons when disabled prop is true', () => {
|
|
render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
disabled={true}
|
|
/>,
|
|
);
|
|
|
|
const previousButton = screen.getByLabelText('Piste précédente');
|
|
const nextButton = screen.getByLabelText('Piste suivante');
|
|
|
|
expect(previousButton).toBeDisabled();
|
|
expect(nextButton).toBeDisabled();
|
|
});
|
|
|
|
it('should not call callbacks when buttons are disabled', async () => {
|
|
const user = userEvent.setup();
|
|
|
|
render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={false}
|
|
canGoPrevious={false}
|
|
/>,
|
|
);
|
|
|
|
const previousButton = screen.getByLabelText('Piste précédente');
|
|
const nextButton = screen.getByLabelText('Piste suivante');
|
|
|
|
await user.click(previousButton);
|
|
await user.click(nextButton);
|
|
|
|
expect(mockOnPrevious).not.toHaveBeenCalled();
|
|
expect(mockOnNext).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should apply custom className', () => {
|
|
const { container } = render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
className="custom-class"
|
|
/>,
|
|
);
|
|
|
|
expect(container.firstChild).toHaveClass('custom-class');
|
|
});
|
|
|
|
it('should apply size classes', () => {
|
|
const { container: smContainer } = render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
size="sm"
|
|
/>,
|
|
);
|
|
|
|
const buttons = smContainer.querySelectorAll('button');
|
|
buttons.forEach((button) => {
|
|
expect(button).toHaveClass('h-8', 'w-8');
|
|
});
|
|
|
|
const { container: mdContainer } = render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
size="md"
|
|
/>,
|
|
);
|
|
|
|
const mdButtons = mdContainer.querySelectorAll('button');
|
|
mdButtons.forEach((button) => {
|
|
expect(button).toHaveClass('h-10', 'w-10');
|
|
});
|
|
|
|
const { container: lgContainer } = render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
size="lg"
|
|
/>,
|
|
);
|
|
|
|
const lgButtons = lgContainer.querySelectorAll('button');
|
|
lgButtons.forEach((button) => {
|
|
expect(button).toHaveClass('h-12', 'w-12');
|
|
});
|
|
});
|
|
|
|
it('should apply variant classes', () => {
|
|
const { container: defaultContainer } = render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
variant="default"
|
|
/>,
|
|
);
|
|
|
|
const buttons = defaultContainer.querySelectorAll('button');
|
|
buttons.forEach((button) => {
|
|
expect(button).toHaveClass('bg-primary');
|
|
});
|
|
|
|
const { container: ghostContainer } = render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
variant="ghost"
|
|
/>,
|
|
);
|
|
|
|
const ghostButtons = ghostContainer.querySelectorAll('button');
|
|
ghostButtons.forEach((button) => {
|
|
expect(button).toHaveClass('bg-transparent');
|
|
});
|
|
});
|
|
|
|
it('should have accessible labels', () => {
|
|
render(
|
|
<NextPreviousButtons
|
|
onNext={mockOnNext}
|
|
onPrevious={mockOnPrevious}
|
|
canGoNext={true}
|
|
canGoPrevious={true}
|
|
/>,
|
|
);
|
|
|
|
expect(screen.getByLabelText('Piste précédente')).toBeInTheDocument();
|
|
expect(screen.getByLabelText('Piste suivante')).toBeInTheDocument();
|
|
expect(
|
|
screen.getAllByText('Piste précédente', { selector: '.sr-only' }),
|
|
).toHaveLength(1);
|
|
expect(
|
|
screen.getAllByText('Piste suivante', { selector: '.sr-only' }),
|
|
).toHaveLength(1);
|
|
});
|
|
});
|