veza/apps/web/src/features/player/components/PlayPauseButton.test.tsx
2025-12-12 21:34:34 -05:00

155 lines
4.7 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 { PlayPauseButton } from './PlayPauseButton';
describe('PlayPauseButton', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should render play button when not playing', () => {
render(<PlayPauseButton isPlaying={false} />);
const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
expect(button).toHaveAttribute('aria-label', 'Lire');
});
it('should render pause button when playing', () => {
render(<PlayPauseButton isPlaying={true} />);
const button = screen.getByRole('button');
expect(button).toBeInTheDocument();
expect(button).toHaveAttribute('aria-label', 'Mettre en pause');
});
it('should show loading spinner when loading', () => {
render(<PlayPauseButton isPlaying={false} isLoading={true} />);
const button = screen.getByRole('button');
expect(button).toHaveAttribute('aria-busy', 'true');
expect(button).toBeDisabled();
});
it('should call onClick when clicked', async () => {
const user = userEvent.setup();
const handleClick = vi.fn();
render(<PlayPauseButton isPlaying={false} onClick={handleClick} />);
const button = screen.getByRole('button');
await user.click(button);
expect(handleClick).toHaveBeenCalledTimes(1);
});
it('should not call onClick when disabled', async () => {
const user = userEvent.setup();
const handleClick = vi.fn();
render(
<PlayPauseButton isPlaying={false} onClick={handleClick} disabled />,
);
const button = screen.getByRole('button');
await user.click(button);
expect(handleClick).not.toHaveBeenCalled();
});
it('should not call onClick when loading', async () => {
const user = userEvent.setup();
const handleClick = vi.fn();
render(
<PlayPauseButton isPlaying={false} onClick={handleClick} isLoading />,
);
const button = screen.getByRole('button');
await user.click(button);
expect(handleClick).not.toHaveBeenCalled();
});
it('should apply custom className', () => {
const { container } = render(
<PlayPauseButton isPlaying={false} className="custom-class" />,
);
expect(container.firstChild).toHaveClass('custom-class');
});
it('should apply size classes', () => {
const { container: smContainer } = render(
<PlayPauseButton isPlaying={false} size="sm" />,
);
expect(smContainer.firstChild).toHaveClass('h-8', 'w-8');
const { container: mdContainer } = render(
<PlayPauseButton isPlaying={false} size="md" />,
);
expect(mdContainer.firstChild).toHaveClass('h-10', 'w-10');
const { container: lgContainer } = render(
<PlayPauseButton isPlaying={false} size="lg" />,
);
expect(lgContainer.firstChild).toHaveClass('h-12', 'w-12');
});
it('should apply variant classes', () => {
const { container: defaultContainer } = render(
<PlayPauseButton isPlaying={false} variant="default" />,
);
expect(defaultContainer.firstChild).toHaveClass('bg-blue-600');
const { container: ghostContainer } = render(
<PlayPauseButton isPlaying={false} variant="ghost" />,
);
expect(ghostContainer.firstChild).toHaveClass('bg-transparent');
const { container: outlineContainer } = render(
<PlayPauseButton isPlaying={false} variant="outline" />,
);
expect(outlineContainer.firstChild).toHaveClass('border');
});
it('should be disabled when disabled prop is true', () => {
render(<PlayPauseButton isPlaying={false} disabled />);
const button = screen.getByRole('button');
expect(button).toBeDisabled();
});
it('should be disabled when loading', () => {
render(<PlayPauseButton isPlaying={false} isLoading />);
const button = screen.getByRole('button');
expect(button).toBeDisabled();
});
it('should have accessible labels', () => {
const { rerender } = render(<PlayPauseButton isPlaying={false} />);
let button = screen.getByRole('button');
expect(button).toHaveAttribute('aria-label', 'Lire');
expect(
screen.getByText('Lire', { selector: '.sr-only' }),
).toBeInTheDocument();
rerender(<PlayPauseButton isPlaying={true} />);
button = screen.getByRole('button');
expect(button).toHaveAttribute('aria-label', 'Mettre en pause');
expect(
screen.getByText('Mettre en pause', { selector: '.sr-only' }),
).toBeInTheDocument();
});
it('should pass through additional props', () => {
render(<PlayPauseButton isPlaying={false} data-testid="custom-testid" />);
const button = screen.getByTestId('custom-testid');
expect(button).toBeInTheDocument();
});
});