From 0586483a42e514d035ed6bab062b118e17f915af Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Fri, 1 May 2026 20:19:16 -0400 Subject: [PATCH] feat(web): add CompactTrackCard for Most played rows Small 140px clickable card showing album cover, title, and artist name. Clicking calls playQueue(sectionTracks, index) to play through the full section list. Includes Vitest tests for click and render behaviour. Co-Authored-By: Claude Sonnet 4.6 --- .../lib/components/CompactTrackCard.svelte | 44 +++++++++++++++++++ .../lib/components/CompactTrackCard.test.ts | 42 ++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 web/src/lib/components/CompactTrackCard.svelte create mode 100644 web/src/lib/components/CompactTrackCard.test.ts diff --git a/web/src/lib/components/CompactTrackCard.svelte b/web/src/lib/components/CompactTrackCard.svelte new file mode 100644 index 00000000..436032fe --- /dev/null +++ b/web/src/lib/components/CompactTrackCard.svelte @@ -0,0 +1,44 @@ + + + diff --git a/web/src/lib/components/CompactTrackCard.test.ts b/web/src/lib/components/CompactTrackCard.test.ts new file mode 100644 index 00000000..859671e9 --- /dev/null +++ b/web/src/lib/components/CompactTrackCard.test.ts @@ -0,0 +1,42 @@ +import { afterEach, describe, expect, test, vi } from 'vitest'; +import { render, screen, fireEvent } from '@testing-library/svelte'; +import type { TrackRef } from '$lib/api/types'; + +vi.mock('$lib/player/store.svelte', () => ({ + playQueue: vi.fn() +})); + +import CompactTrackCard from './CompactTrackCard.svelte'; +import { playQueue } from '$lib/player/store.svelte'; + +const tracks: TrackRef[] = [ + { id: 't1', title: 'First', album_id: 'a1', album_title: 'A', + artist_id: 'art-1', artist_name: 'Artist', + track_number: 1, disc_number: 1, duration_sec: 1, stream_url: '/a' }, + { id: 't2', title: 'Second', album_id: 'a1', album_title: 'A', + artist_id: 'art-1', artist_name: 'Artist', + track_number: 2, disc_number: 1, duration_sec: 1, stream_url: '/b' }, + { id: 't3', title: 'Third', album_id: 'a1', album_title: 'A', + artist_id: 'art-1', artist_name: 'Artist', + track_number: 3, disc_number: 1, duration_sec: 1, stream_url: '/c' } +]; + +afterEach(() => vi.clearAllMocks()); + +describe('CompactTrackCard', () => { + test('clicking the card calls playQueue with sectionTracks at the right index', async () => { + render(CompactTrackCard, { + props: { track: tracks[1], sectionTracks: tracks, index: 1 } + }); + await fireEvent.click(screen.getByRole('button', { name: /play second/i })); + expect(playQueue).toHaveBeenCalledWith(tracks, 1); + }); + + test('renders title and artist name', () => { + render(CompactTrackCard, { + props: { track: tracks[0], sectionTracks: tracks, index: 0 } + }); + expect(screen.getByText('First')).toBeInTheDocument(); + expect(screen.getByText('Artist')).toBeInTheDocument(); + }); +});