veza/apps/web/src/features/tracks/components/TrackSearchResults.test.tsx
2025-12-22 22:00:50 +01:00

167 lines
4.2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen } from '@testing-library/react';
import { TrackSearchResults } from './TrackSearchResults';
import type { Track } from '../types/track';
// Mock react-router-dom
vi.mock('react-router-dom', () => ({
Link: ({ children, to }: { children: React.ReactNode; to: string }) => (
<a href={to}>{children}</a>
),
}));
describe('TrackSearchResults', () => {
const mockTracks: Track[] = [
{
id: 1,
creator_id: 123,
title: 'Test Track 1',
artist: 'Test Artist 1',
duration: 180,
file_path: '/test/track1.mp3',
file_size: 5000000,
format: 'MP3',
genre: 'Rock',
is_public: true,
play_count: 10,
like_count: 5,
created_at: '2024-01-01T00:00:00Z',
updated_at: '2024-01-01T00:00:00Z',
},
{
id: 2,
creator_id: 123,
title: 'Test Track 2',
artist: 'Test Artist 2',
duration: 200,
file_path: '/test/track2.mp3',
file_size: 6000000,
format: 'FLAC',
genre: 'Pop',
is_public: true,
play_count: 20,
like_count: 10,
created_at: '2024-01-02T00:00:00Z',
updated_at: '2024-01-02T00:00:00Z',
},
];
const mockOnPageChange = vi.fn();
beforeEach(() => {
vi.clearAllMocks();
});
it('should display loading state', () => {
render(
<TrackSearchResults
tracks={[]}
total={0}
page={1}
limit={20}
onPageChange={mockOnPageChange}
loading={true}
/>,
);
// Loading spinner should be visible (checking by role or text)
expect(screen.queryByText('Aucun track trouvé')).not.toBeInTheDocument();
});
it('should display error message', () => {
render(
<TrackSearchResults
tracks={[]}
total={0}
page={1}
limit={20}
onPageChange={mockOnPageChange}
error="Search failed"
/>,
);
expect(screen.getByText('Erreur')).toBeInTheDocument();
expect(screen.getByText('Search failed')).toBeInTheDocument();
});
it('should display empty state when no tracks', () => {
render(
<TrackSearchResults
tracks={[]}
total={0}
page={1}
limit={20}
onPageChange={mockOnPageChange}
/>,
);
expect(screen.getByText('Aucun track trouvé')).toBeInTheDocument();
expect(
screen.getByText(/Essayez de modifier vos critères de recherche/i),
).toBeInTheDocument();
});
it('should display tracks', () => {
render(
<TrackSearchResults
tracks={mockTracks}
total={2}
page={1}
limit={20}
onPageChange={mockOnPageChange}
/>,
);
expect(screen.getByText('Test Track 1')).toBeInTheDocument();
expect(screen.getByText('Test Track 2')).toBeInTheDocument();
expect(screen.getByText('Test Artist 1')).toBeInTheDocument();
expect(screen.getByText('Test Artist 2')).toBeInTheDocument();
expect(screen.getByText('2 résultats trouvés')).toBeInTheDocument();
});
it('should display pagination when multiple pages', () => {
render(
<TrackSearchResults
tracks={mockTracks}
total={50}
page={1}
limit={20}
onPageChange={mockOnPageChange}
/>,
);
expect(screen.getByText('Page 1 sur 3')).toBeInTheDocument();
expect(screen.getByText('Précédent')).toBeInTheDocument();
expect(screen.getByText('Suivant')).toBeInTheDocument();
});
it('should disable previous button on first page', () => {
render(
<TrackSearchResults
tracks={mockTracks}
total={50}
page={1}
limit={20}
onPageChange={mockOnPageChange}
/>,
);
const prevButton = screen.getByText('Précédent').closest('button');
expect(prevButton).toBeDisabled();
});
it('should disable next button on last page', () => {
render(
<TrackSearchResults
tracks={mockTracks}
total={50}
page={3}
limit={20}
onPageChange={mockOnPageChange}
/>,
);
const nextButton = screen.getByText('Suivant').closest('button');
expect(nextButton).toBeDisabled();
});
});