167 lines
4.2 KiB
TypeScript
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();
|
|
});
|
|
});
|