From db361c83052442b9811dcb9ab227070fb1a21968 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Mon, 4 May 2026 17:49:19 -0400 Subject: [PATCH] feat(web/m7-377): CompactTrackCard gains like + queue + kebab overlays --- .../lib/components/CompactTrackCard.svelte | 61 +++++++++++++------ .../lib/components/CompactTrackCard.test.ts | 51 +++++++++++++++- 2 files changed, 92 insertions(+), 20 deletions(-) diff --git a/web/src/lib/components/CompactTrackCard.svelte b/web/src/lib/components/CompactTrackCard.svelte index 436032fe..0b69fb84 100644 --- a/web/src/lib/components/CompactTrackCard.svelte +++ b/web/src/lib/components/CompactTrackCard.svelte @@ -1,7 +1,10 @@ - +
e.stopPropagation()}> + +
-
{track.title}
-
{track.artist_name}
- +
+ +
+ diff --git a/web/src/lib/components/CompactTrackCard.test.ts b/web/src/lib/components/CompactTrackCard.test.ts index 859671e9..87bf9969 100644 --- a/web/src/lib/components/CompactTrackCard.test.ts +++ b/web/src/lib/components/CompactTrackCard.test.ts @@ -1,13 +1,52 @@ import { afterEach, describe, expect, test, vi } from 'vitest'; import { render, screen, fireEvent } from '@testing-library/svelte'; import type { TrackRef } from '$lib/api/types'; +import { readable } from 'svelte/store'; + +vi.mock('$lib/api/likes', () => ({ + createLikedIdsQuery: () => + readable({ data: { track_ids: [], album_ids: [], artist_ids: [] }, isPending: false, isError: false }), + likeEntity: vi.fn().mockResolvedValue(undefined), + unlikeEntity: vi.fn().mockResolvedValue(undefined) +})); + +vi.mock('$lib/api/quarantine', () => ({ + flagTrack: vi.fn().mockResolvedValue({}), + unflagTrack: vi.fn().mockResolvedValue(undefined), + listMyQuarantine: vi.fn().mockResolvedValue([]), + createMyQuarantineQuery: () => readable({ data: [], isPending: false, isError: false }) +})); + +vi.mock('$lib/api/admin/tracks', () => ({ + removeTrack: vi.fn().mockResolvedValue({ deleted_track_id: 't1' }) +})); + +vi.mock('$lib/api/playlists', () => ({ + createPlaylistsQuery: () => + readable({ data: { owned: [], public: [] }, isPending: false, isError: false }), + appendTracks: vi.fn().mockResolvedValue({ id: 'p1', tracks: [] }), + createPlaylist: vi.fn().mockResolvedValue({ id: 'p1', name: 'New' }) +})); + +vi.mock('$lib/auth/store.svelte', () => ({ + user: { get value() { return { id: 'u1', username: 'u', is_admin: false }; } } +})); + +vi.mock('$app/navigation', () => ({ goto: vi.fn() })); + +vi.mock('@tanstack/svelte-query', async (orig) => { + const actual = (await orig()) as Record; + return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) }; +}); vi.mock('$lib/player/store.svelte', () => ({ - playQueue: vi.fn() + playQueue: vi.fn(), + enqueueTrack: vi.fn(), + playNext: vi.fn() })); import CompactTrackCard from './CompactTrackCard.svelte'; -import { playQueue } from '$lib/player/store.svelte'; +import { playQueue, enqueueTrack } from '$lib/player/store.svelte'; const tracks: TrackRef[] = [ { id: 't1', title: 'First', album_id: 'a1', album_title: 'A', @@ -39,4 +78,12 @@ describe('CompactTrackCard', () => { expect(screen.getByText('First')).toBeInTheDocument(); expect(screen.getByText('Artist')).toBeInTheDocument(); }); + + test('+ queue button calls enqueueTrack', async () => { + render(CompactTrackCard, { + props: { track: tracks[0], sectionTracks: tracks, index: 0 } + }); + await fireEvent.click(screen.getByRole('button', { name: /add first to queue/i })); + expect(enqueueTrack).toHaveBeenCalledWith(tracks[0]); + }); });