From 9a166f90320e587ad9baf002ab54e4c8fcd5719d Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sun, 14 Jun 2026 21:48:57 -0400 Subject: [PATCH] test(web): update TrackMenu spec for Android-parity kebab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kebab gained "Start radio" and dropped the duplicate "Flag this track…" (its action now lives solely under "Hide", which opens the same FlagPopover). Net item count is unchanged (9 admin / 8 non-admin), but the named-item and flag-entry assertions needed updating: - mock playRadio in the store mock; assert Start radio dispatches playRadio. - swap the flag-item presence check for start-radio. - replace the "click Flag" test with "click Hide opens the popover". Co-Authored-By: Claude Opus 4.8 (1M context) --- web/src/lib/components/TrackMenu.test.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/web/src/lib/components/TrackMenu.test.ts b/web/src/lib/components/TrackMenu.test.ts index 6e359649..79c58e57 100644 --- a/web/src/lib/components/TrackMenu.test.ts +++ b/web/src/lib/components/TrackMenu.test.ts @@ -33,11 +33,12 @@ vi.mock('$lib/api/playlists', () => emptyPlaylistsMock()); vi.mock('$lib/player/store.svelte', () => ({ playNext: vi.fn(), - enqueueTrack: vi.fn() + enqueueTrack: vi.fn(), + playRadio: vi.fn() })); import TrackMenu from './TrackMenu.svelte'; -import { playNext, enqueueTrack } from '$lib/player/store.svelte'; +import { playNext, enqueueTrack, playRadio } from '$lib/player/store.svelte'; const track = makeTrack({ title: 'Roygbiv' }); @@ -63,9 +64,9 @@ describe('TrackMenu', () => { expect(screen.getByRole('menuitem', { name: /add to queue/i })).toBeInTheDocument(); expect(screen.getByRole('menuitem', { name: /^like$/i })).toBeInTheDocument(); expect(screen.getByRole('menuitem', { name: /add to playlist/i })).toBeInTheDocument(); + expect(screen.getByRole('menuitem', { name: /start radio/i })).toBeInTheDocument(); expect(screen.getByRole('menuitem', { name: /go to album/i })).toBeInTheDocument(); expect(screen.getByRole('menuitem', { name: /go to artist/i })).toBeInTheDocument(); - expect(screen.getByRole('menuitem', { name: /flag this track/i })).toBeInTheDocument(); expect(screen.getByRole('menuitem', { name: /^hide$/i })).toBeInTheDocument(); expect(screen.getByRole('menuitem', { name: /remove from library/i })).toBeInTheDocument(); @@ -113,10 +114,17 @@ describe('TrackMenu', () => { expect(screen.queryByRole('menu')).not.toBeInTheDocument(); }); - test('clicking "Flag this track…" opens FlagPopover and closes menu', async () => { + test('"Start radio" dispatches playRadio(track.id)', async () => { render(TrackMenu, { props: { track } }); await fireEvent.click(screen.getByRole('button', { name: /track actions/i })); - await fireEvent.click(screen.getByRole('menuitem', { name: /flag this track/i })); + await fireEvent.click(screen.getByRole('menuitem', { name: /start radio/i })); + expect(playRadio).toHaveBeenCalledWith(track.id); + }); + + test('clicking "Hide" opens the flag/quarantine popover and closes menu', async () => { + render(TrackMenu, { props: { track } }); + await fireEvent.click(screen.getByRole('button', { name: /track actions/i })); + await fireEvent.click(screen.getByRole('menuitem', { name: /^hide$/i })); expect(screen.queryByRole('menu')).not.toBeInTheDocument(); expect( screen.getByRole('dialog', { name: /flag this track as broken/i })