From 12d1cb739bdd10f4037d17a88590a2f90845b9f0 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 23 Apr 2026 18:40:40 -0400 Subject: [PATCH] feat(web): add TrackRow component Non-interactive album track row with number, title, duration. Player plan will add click-to-play. --- web/src/lib/components/TrackRow.svelte | 14 +++++++++++ web/src/lib/components/TrackRow.test.ts | 31 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 web/src/lib/components/TrackRow.svelte create mode 100644 web/src/lib/components/TrackRow.test.ts diff --git a/web/src/lib/components/TrackRow.svelte b/web/src/lib/components/TrackRow.svelte new file mode 100644 index 00000000..bd32ab62 --- /dev/null +++ b/web/src/lib/components/TrackRow.svelte @@ -0,0 +1,14 @@ + + +
+ + {track.track_number ?? '—'} + + {track.title} + {formatDuration(track.duration_sec)} +
diff --git a/web/src/lib/components/TrackRow.test.ts b/web/src/lib/components/TrackRow.test.ts new file mode 100644 index 00000000..1f108ea6 --- /dev/null +++ b/web/src/lib/components/TrackRow.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, test } from 'vitest'; +import { render, screen } from '@testing-library/svelte'; +import TrackRow from './TrackRow.svelte'; +import type { TrackRef } from '$lib/api/types'; + +const track: TrackRef = { + id: 't1', + title: 'So What', + album_id: 'xyz', + album_title: 'Kind of Blue', + artist_id: 'm-davis', + artist_name: 'Miles Davis', + track_number: 1, + disc_number: 1, + duration_sec: 545, + stream_url: '/api/tracks/t1/stream', +}; + +describe('TrackRow', () => { + test('renders track number, title, formatted duration', () => { + render(TrackRow, { props: { track } }); + expect(screen.getByText('1')).toBeInTheDocument(); + expect(screen.getByText('So What')).toBeInTheDocument(); + expect(screen.getByText('9:05')).toBeInTheDocument(); + }); + + test('track number falls back to dash when missing', () => { + render(TrackRow, { props: { track: { ...track, track_number: undefined } } }); + expect(screen.getByText('—')).toBeInTheDocument(); + }); +});