import { describe, it, expect, vi } from 'vitest'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { PlayerError } from './PlayerError'; describe('PlayerError', () => { it('should not render when error is null', () => { const { container } = render(); expect(container.firstChild).toBeNull(); }); it('should render when error is provided', () => { const error = new Error('Test error'); render(); expect(screen.getByRole('alert')).toBeInTheDocument(); }); it('should display error message', () => { const error = new Error('Test error'); render(); expect( screen.getByText('Une erreur est survenue lors de la lecture.'), ).toBeInTheDocument(); }); it('should display error title', () => { const error = new Error('Test error'); render(); expect(screen.getByText('Erreur de lecture')).toBeInTheDocument(); }); it('should display network error message', () => { const error = new Error('Network error'); error.name = 'NetworkError'; render(); expect( screen.getByText( 'Erreur de connexion. Vérifiez votre connexion internet.', ), ).toBeInTheDocument(); }); it('should display decode error message', () => { const error = new Error('Decode error'); error.name = 'DecodeError'; render(); expect( screen.getByText( 'Erreur de décodage audio. Le fichier est peut-être corrompu.', ), ).toBeInTheDocument(); }); it('should display source error message', () => { const error = new Error('Source not found'); error.name = 'NotFoundError'; render(); expect( screen.getByText( 'Erreur de source audio. Le fichier est introuvable ou inaccessible.', ), ).toBeInTheDocument(); }); it('should display abort error message', () => { const error = new Error('Abort error'); error.name = 'AbortError'; render(); expect(screen.getByText('Chargement annulé.')).toBeInTheDocument(); }); it('should use custom errorType', () => { const error = new Error('Test error'); render(); expect( screen.getByText( 'Erreur de connexion. Vérifiez votre connexion internet.', ), ).toBeInTheDocument(); }); it('should display retry button when onRetry is provided', () => { const error = new Error('Test error'); const onRetry = vi.fn(); render(); expect(screen.getByText('Réessayer')).toBeInTheDocument(); }); it('should not display retry button when onRetry is not provided', () => { const error = new Error('Test error'); render(); expect(screen.queryByText('Réessayer')).not.toBeInTheDocument(); }); it('should not display retry button when showRetry is false', () => { const error = new Error('Test error'); const onRetry = vi.fn(); render(); expect(screen.queryByText('Réessayer')).not.toBeInTheDocument(); }); it('should call onRetry when retry button is clicked', async () => { const user = userEvent.setup(); const error = new Error('Test error'); const onRetry = vi.fn(); render(); const retryButton = screen.getByText('Réessayer'); await user.click(retryButton); expect(onRetry).toHaveBeenCalledTimes(1); }); it('should use custom retry label', () => { const error = new Error('Test error'); const onRetry = vi.fn(); render(); expect(screen.getByText('Retry')).toBeInTheDocument(); }); it('should apply custom className', () => { const error = new Error('Test error'); const { container } = render( , ); expect(container.firstChild).toHaveClass('custom-class'); }); it('should have accessible attributes', () => { const error = new Error('Test error'); render(); const alert = screen.getByRole('alert'); expect(alert).toHaveAttribute('aria-live', 'assertive'); }); it('should have accessible retry button', () => { const error = new Error('Test error'); const onRetry = vi.fn(); const { container } = render( , ); const retryButton = screen.getByText('Réessayer'); // Check that aria-label is present on the button element const buttonElement = container.querySelector('button[aria-label]'); expect(buttonElement).toBeInTheDocument(); expect(buttonElement?.getAttribute('aria-label')).toContain('Réessayer'); }); it('should detect network error from message', () => { const error = new Error('Network request failed'); render(); expect( screen.getByText( 'Erreur de connexion. Vérifiez votre connexion internet.', ), ).toBeInTheDocument(); }); it('should detect decode error from message', () => { const error = new Error('Failed to decode audio data'); render(); expect( screen.getByText( 'Erreur de décodage audio. Le fichier est peut-être corrompu.', ), ).toBeInTheDocument(); }); it('should detect source error from message', () => { const error = new Error('Source not found'); render(); expect( screen.getByText( 'Erreur de source audio. Le fichier est introuvable ou inaccessible.', ), ).toBeInTheDocument(); }); it('should detect abort error from message', () => { const error = new Error('Request aborted'); render(); expect(screen.getByText('Chargement annulé.')).toBeInTheDocument(); }); });