fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 08:43:55 +00:00
|
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
2025-12-03 21:56:50 +00:00
|
|
|
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>,
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
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-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
|
fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 08:43:55 +00:00
|
|
|
// ErrorDisplay shows fallback message for generic errors
|
2025-12-13 02:34:34 +00:00
|
|
|
expect(
|
|
|
|
|
screen.getByText(/Une erreur inattendue s'est produite/i),
|
|
|
|
|
).toBeInTheDocument();
|
fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 08:43:55 +00:00
|
|
|
expect(screen.getByRole('alert')).toBeInTheDocument();
|
2025-12-03 21:56:50 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should display retry button', () => {
|
|
|
|
|
render(
|
|
|
|
|
<ErrorBoundary>
|
|
|
|
|
<ThrowError shouldThrow={true} />
|
2025-12-13 02:34:34 +00:00
|
|
|
</ErrorBoundary>,
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
|
fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 08:43:55 +00:00
|
|
|
const retryButton = screen.getByRole('button', { name: /retry/i });
|
2025-12-03 21:56:50 +00:00
|
|
|
expect(retryButton).toBeInTheDocument();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should display home button', () => {
|
|
|
|
|
render(
|
|
|
|
|
<ErrorBoundary>
|
|
|
|
|
<ThrowError shouldThrow={true} />
|
2025-12-13 02:34:34 +00:00
|
|
|
</ErrorBoundary>,
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
|
2025-12-13 02:34:34 +00:00
|
|
|
const homeButton = screen.getByRole('button', {
|
fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 08:43:55 +00:00
|
|
|
name: /return home/i,
|
2025-12-13 02:34:34 +00:00
|
|
|
});
|
2025-12-03 21:56:50 +00:00
|
|
|
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-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
|
2025-12-13 02:34:34 +00:00
|
|
|
expect(
|
fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 08:43:55 +00:00
|
|
|
screen.getByText(/Une erreur inattendue s'est produite/i),
|
2025-12-13 02:34:34 +00:00
|
|
|
).toBeInTheDocument();
|
2025-12-03 21:56:50 +00:00
|
|
|
|
fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 08:43:55 +00:00
|
|
|
// Rerender avec shouldThrow=false avant le clic pour que le boundary reçu un enfant qui ne lance pas
|
2025-12-03 21:56:50 +00:00
|
|
|
rerender(
|
|
|
|
|
<ErrorBoundary>
|
|
|
|
|
<ThrowError shouldThrow={false} />
|
2025-12-13 02:34:34 +00:00
|
|
|
</ErrorBoundary>,
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
|
fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 08:43:55 +00:00
|
|
|
const retryButton = screen.getByRole('button', { name: /retry/i });
|
|
|
|
|
fireEvent.click(retryButton);
|
|
|
|
|
|
|
|
|
|
// Le composant devrait afficher le contenu normal après le reset
|
2025-12-03 21:56:50 +00:00
|
|
|
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>,
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(screen.getByText('Custom error message')).toBeInTheDocument();
|
2025-12-13 02:34:34 +00:00
|
|
|
expect(
|
fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 08:43:55 +00:00
|
|
|
screen.queryByText(/Une erreur inattendue s'est produite/i),
|
2025-12-13 02:34:34 +00:00
|
|
|
).not.toBeInTheDocument();
|
2025-12-03 21:56:50 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should log error to console', () => {
|
|
|
|
|
render(
|
|
|
|
|
<ErrorBoundary>
|
|
|
|
|
<ThrowError shouldThrow={true} />
|
2025-12-13 02:34:34 +00:00
|
|
|
</ErrorBoundary>,
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
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>,
|
2025-12-03 21:56:50 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// L'ErrorBoundary devrait avoir un état d'erreur
|
|
|
|
|
expect(container.querySelector('.min-h-screen')).toBeInTheDocument();
|
|
|
|
|
});
|
|
|
|
|
});
|