180 lines
5.9 KiB
TypeScript
180 lines
5.9 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { render, screen } from '@testing-library/react';
|
|
import { TrackInfo } from './TrackInfo';
|
|
import type { Track } from '../types';
|
|
|
|
describe('TrackInfo', () => {
|
|
const mockTrack: Track = {
|
|
id: 1,
|
|
title: 'Test Track',
|
|
artist: 'Test Artist',
|
|
album: 'Test Album',
|
|
genre: 'Rock',
|
|
duration: 180,
|
|
url: 'https://example.com/track.mp3',
|
|
cover: 'https://example.com/cover.jpg',
|
|
};
|
|
|
|
it('should render placeholder when track is null', () => {
|
|
render(<TrackInfo track={null} />);
|
|
|
|
expect(screen.getByText('Aucune piste sélectionnée')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should display track title', () => {
|
|
render(<TrackInfo track={mockTrack} />);
|
|
|
|
expect(screen.getByText('Test Track')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should display track artist', () => {
|
|
render(<TrackInfo track={mockTrack} />);
|
|
|
|
expect(screen.getByText('Test Artist')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should display track cover when provided', () => {
|
|
render(<TrackInfo track={mockTrack} showCover={true} />);
|
|
|
|
const cover = screen.getByAltText('Cover de Test Track');
|
|
expect(cover).toBeInTheDocument();
|
|
expect(cover).toHaveAttribute('src', 'https://example.com/cover.jpg');
|
|
});
|
|
|
|
it('should display placeholder icon when cover is not provided', () => {
|
|
const trackWithoutCover = { ...mockTrack, cover: undefined };
|
|
const { container } = render(
|
|
<TrackInfo track={trackWithoutCover} showCover={true} />,
|
|
);
|
|
|
|
// The Music icon should be present in the placeholder
|
|
const placeholder = container.querySelector('[class*="bg-muted"]');
|
|
expect(placeholder).toBeInTheDocument();
|
|
const icon = container.querySelector('svg');
|
|
expect(icon).toBeInTheDocument();
|
|
});
|
|
|
|
it('should not display cover when showCover is false', () => {
|
|
render(<TrackInfo track={mockTrack} showCover={false} />);
|
|
|
|
expect(
|
|
screen.queryByAltText('Cover de Test Track'),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('should display album metadata when showMetadata is true', () => {
|
|
render(<TrackInfo track={mockTrack} showMetadata={true} />);
|
|
|
|
expect(screen.getByText('Test Album')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should display genre metadata when showMetadata is true', () => {
|
|
render(<TrackInfo track={mockTrack} showMetadata={true} />);
|
|
|
|
expect(screen.getByText('Rock')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should not display metadata when showMetadata is false', () => {
|
|
render(<TrackInfo track={mockTrack} showMetadata={false} />);
|
|
|
|
expect(screen.queryByText('Test Album')).not.toBeInTheDocument();
|
|
expect(screen.queryByText('Rock')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('should handle track without artist', () => {
|
|
const trackWithoutArtist = { ...mockTrack, artist: undefined };
|
|
render(<TrackInfo track={trackWithoutArtist} />);
|
|
|
|
expect(screen.getByText('Test Track')).toBeInTheDocument();
|
|
expect(screen.queryByText('Test Artist')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('should handle track without album', () => {
|
|
const trackWithoutAlbum = { ...mockTrack, album: undefined };
|
|
render(<TrackInfo track={trackWithoutAlbum} showMetadata={true} />);
|
|
|
|
expect(screen.getByText('Rock')).toBeInTheDocument();
|
|
expect(screen.queryByText('Test Album')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('should handle track without genre', () => {
|
|
const trackWithoutGenre = { ...mockTrack, genre: undefined };
|
|
render(<TrackInfo track={trackWithoutGenre} showMetadata={true} />);
|
|
|
|
expect(screen.getByText('Test Album')).toBeInTheDocument();
|
|
expect(screen.queryByText('Rock')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('should apply custom className', () => {
|
|
const { container } = render(
|
|
<TrackInfo track={mockTrack} className="custom-class" />,
|
|
);
|
|
|
|
expect(container.firstChild).toHaveClass('custom-class');
|
|
});
|
|
|
|
it('should apply cover size classes', () => {
|
|
const { container: smContainer } = render(
|
|
<TrackInfo track={mockTrack} coverSize="sm" />,
|
|
);
|
|
|
|
const cover = smContainer.querySelector('img');
|
|
expect(cover).toHaveClass('h-12', 'w-12');
|
|
|
|
const { container: mdContainer } = render(
|
|
<TrackInfo track={mockTrack} coverSize="md" />,
|
|
);
|
|
|
|
const mdCover = mdContainer.querySelector('img');
|
|
expect(mdCover).toHaveClass('h-16', 'w-16');
|
|
|
|
const { container: lgContainer } = render(
|
|
<TrackInfo track={mockTrack} coverSize="lg" />,
|
|
);
|
|
|
|
const lgCover = lgContainer.querySelector('img');
|
|
expect(lgCover).toHaveClass('h-24', 'w-24');
|
|
});
|
|
|
|
it('should truncate long titles', () => {
|
|
const longTitleTrack = {
|
|
...mockTrack,
|
|
title: 'This is a very long track title that should be truncated',
|
|
};
|
|
render(<TrackInfo track={longTitleTrack} />);
|
|
|
|
const title = screen.getByText(longTitleTrack.title);
|
|
expect(title).toHaveClass('truncate');
|
|
expect(title).toHaveAttribute('title', longTitleTrack.title);
|
|
});
|
|
|
|
it('should truncate long artist names', () => {
|
|
const longArtistTrack = {
|
|
...mockTrack,
|
|
artist: 'This is a very long artist name that should be truncated',
|
|
};
|
|
render(<TrackInfo track={longArtistTrack} />);
|
|
|
|
const artist = screen.getByText(longArtistTrack.artist);
|
|
expect(artist).toHaveClass('truncate');
|
|
expect(artist).toHaveAttribute('title', longArtistTrack.artist);
|
|
});
|
|
|
|
it('should display separator between album and genre', () => {
|
|
render(<TrackInfo track={mockTrack} showMetadata={true} />);
|
|
|
|
const separators = screen.getAllByText('•');
|
|
expect(separators.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should not display separator when only album or only genre', () => {
|
|
const trackOnlyAlbum = { ...mockTrack, genre: undefined };
|
|
const { container } = render(
|
|
<TrackInfo track={trackOnlyAlbum} showMetadata={true} />,
|
|
);
|
|
|
|
const separators = container.querySelectorAll('.text-gray-400');
|
|
// Should not have separator when only one metadata item
|
|
expect(separators.length).toBe(0);
|
|
});
|
|
});
|