veza/apps/web/src/components/ErrorBoundary.test.tsx

134 lines
3.4 KiB
TypeScript
Raw Normal View History

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { ErrorBoundary } from './ErrorBoundary';
// Composant qui lance une erreur pour tester l'ErrorBoundary
const ThrowError = ({ shouldThrow }: { shouldThrow: boolean }) => {
if (shouldThrow) {
throw new Error('Test error');
}
return <div>No error</div>;
};
// Suppression de console.error pour les tests
const originalError = console.error;
beforeEach(() => {
console.error = vi.fn();
});
afterEach(() => {
console.error = originalError;
});
describe('ErrorBoundary', () => {
it('should render children when there is no error', () => {
render(
<ErrorBoundary>
<div>Test content</div>
2025-12-13 02:34:34 +00:00
</ErrorBoundary>,
);
expect(screen.getByText('Test content')).toBeInTheDocument();
});
it('should catch errors and display error UI', () => {
render(
<ErrorBoundary>
<ThrowError shouldThrow={true} />
2025-12-13 02:34:34 +00:00
</ErrorBoundary>,
);
2025-12-13 02:34:34 +00:00
expect(
screen.getByText(/Oups ! Une erreur est survenue/i),
).toBeInTheDocument();
expect(
screen.getByText(/Une erreur inattendue s'est produite/i),
).toBeInTheDocument();
});
it('should display retry button', () => {
render(
<ErrorBoundary>
<ThrowError shouldThrow={true} />
2025-12-13 02:34:34 +00:00
</ErrorBoundary>,
);
const retryButton = screen.getByRole('button', { name: /réessayer/i });
expect(retryButton).toBeInTheDocument();
});
it('should display home button', () => {
render(
<ErrorBoundary>
<ThrowError shouldThrow={true} />
2025-12-13 02:34:34 +00:00
</ErrorBoundary>,
);
2025-12-13 02:34:34 +00:00
const homeButton = screen.getByRole('button', {
name: /retour à l'accueil/i,
});
expect(homeButton).toBeInTheDocument();
});
it('should reset error state when retry button is clicked', () => {
const { rerender } = render(
<ErrorBoundary>
<ThrowError shouldThrow={true} />
2025-12-13 02:34:34 +00:00
</ErrorBoundary>,
);
2025-12-13 02:34:34 +00:00
expect(
screen.getByText(/Oups ! Une erreur est survenue/i),
).toBeInTheDocument();
const retryButton = screen.getByRole('button', { name: /réessayer/i });
fireEvent.click(retryButton);
// Rerender avec shouldThrow=false pour simuler le reset
rerender(
<ErrorBoundary>
<ThrowError shouldThrow={false} />
2025-12-13 02:34:34 +00:00
</ErrorBoundary>,
);
// Le composant devrait afficher le contenu normal
expect(screen.getByText('No error')).toBeInTheDocument();
});
it('should use custom fallback when provided', () => {
const customFallback = <div>Custom error message</div>;
render(
<ErrorBoundary fallback={customFallback}>
<ThrowError shouldThrow={true} />
2025-12-13 02:34:34 +00:00
</ErrorBoundary>,
);
expect(screen.getByText('Custom error message')).toBeInTheDocument();
2025-12-13 02:34:34 +00:00
expect(
screen.queryByText(/Oups ! Une erreur est survenue/i),
).not.toBeInTheDocument();
});
it('should log error to console', () => {
render(
<ErrorBoundary>
<ThrowError shouldThrow={true} />
2025-12-13 02:34:34 +00:00
</ErrorBoundary>,
);
expect(console.error).toHaveBeenCalled();
});
it('should have correct state structure', () => {
const { container } = render(
<ErrorBoundary>
<ThrowError shouldThrow={true} />
2025-12-13 02:34:34 +00:00
</ErrorBoundary>,
);
// L'ErrorBoundary devrait avoir un état d'erreur
expect(container.querySelector('.min-h-screen')).toBeInTheDocument();
});
});