import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { PlaybackSpeedControl } from './PlaybackSpeedControl'; import type { PlaybackSpeed } from './PlaybackSpeedControl'; describe('PlaybackSpeedControl', () => { const mockOnSpeedChange = vi.fn(); const defaultProps = { currentSpeed: 1 as PlaybackSpeed, onSpeedChange: mockOnSpeedChange, }; beforeEach(() => { vi.clearAllMocks(); }); it('should render playback speed control', () => { render(); expect(screen.getByLabelText('Vitesse de lecture: 1x')).toBeInTheDocument(); }); it('should display current speed', () => { render(); expect(screen.getByText('1.5x')).toBeInTheDocument(); }); it('should open dropdown when button is clicked', async () => { const user = userEvent.setup(); render(); const button = screen.getByLabelText('Vitesse de lecture: 1x'); await user.click(button); await waitFor(() => { expect(screen.getByRole('menu')).toBeInTheDocument(); }); }); it('should close dropdown when clicking outside', async () => { const user = userEvent.setup(); render(
Outside
, ); const button = screen.getByLabelText('Vitesse de lecture: 1x'); await user.click(button); await waitFor(() => { expect(screen.getByRole('menu')).toBeInTheDocument(); }); const outside = screen.getByTestId('outside'); await user.click(outside); await waitFor(() => { expect(screen.queryByRole('menu')).not.toBeInTheDocument(); }); }); it('should call onSpeedChange when speed is selected', async () => { const user = userEvent.setup(); render(); const button = screen.getByLabelText('Vitesse de lecture: 1x'); await user.click(button); await waitFor(() => { expect(screen.getByRole('menu')).toBeInTheDocument(); }); const speed15x = screen.getByText('1.5x'); await user.click(speed15x); expect(mockOnSpeedChange).toHaveBeenCalledWith(1.5); }); it('should display all speed options', async () => { const user = userEvent.setup(); render(); const button = screen.getByLabelText('Vitesse de lecture: 1x'); await user.click(button); await waitFor(() => { const menu = screen.getByRole('menu'); expect(menu).toBeInTheDocument(); }); const menu = screen.getByRole('menu'); expect(menu).toHaveTextContent('0.5x'); expect(menu).toHaveTextContent('0.75x'); expect(menu).toHaveTextContent('1x'); expect(menu).toHaveTextContent('1.25x'); expect(menu).toHaveTextContent('1.5x'); expect(menu).toHaveTextContent('2x'); }); it('should be disabled when disabled prop is true', () => { render(); const button = screen.getByLabelText('Vitesse de lecture: 1x'); expect(button).toBeDisabled(); }); it('should not open dropdown when disabled', async () => { const user = userEvent.setup(); render(); const button = screen.getByLabelText('Vitesse de lecture: 1x'); await user.click(button); expect(screen.queryByRole('menu')).not.toBeInTheDocument(); }); it('should apply custom className', () => { render( , ); const button = screen.getByLabelText('Vitesse de lecture: 1x'); expect(button).toHaveClass('custom-class'); }); it('should handle all speed values', () => { const { rerender } = render( , ); expect(screen.getByText('0.5x')).toBeInTheDocument(); rerender(); expect(screen.getByText('0.75x')).toBeInTheDocument(); rerender(); expect(screen.getByText('1x')).toBeInTheDocument(); rerender(); expect(screen.getByText('1.25x')).toBeInTheDocument(); rerender(); expect(screen.getByText('1.5x')).toBeInTheDocument(); rerender(); expect(screen.getByText('1.75x')).toBeInTheDocument(); rerender(); expect(screen.getByText('2x')).toBeInTheDocument(); }); });