24 new tests covering the smaller action surfaces F1 / 2a-c skipped:
- setStarredOverride / setUserRatingOverride (per-id maps)
- openContextMenu / closeContextMenu (state + isOpen flip)
- openSongInfo / closeSongInfo (modal state)
- toggleQueue / setQueueVisible (visibility flip with persisted side effect)
- toggleFullscreen (boolean flip)
- setLastfmLoved (writes verbatim + caches under title::artist when track is
set; does NOT cache without a track) + toggleLastfmLove (no-op without
track or session-key; flips state + cache otherwise)
- setLastfmLovedForSong (caches under title::artist key)
- setProgress (currentTime + derived progress)
- stop (invokes audio_stop, resets playback bookkeeping)
- shuffleQueue (no-op when queue < 2; deterministic with mocked RNG,
current track stays at queueIndex 0)
- shuffleUpcomingQueue (no-op when upcoming < 2; head + current untouched,
upcoming tail shuffled)
- pruneUpcomingToCurrent (drops everything after queueIndex; clears the
queue entirely when no current track; early return when queue is already
empty)
- setRadioArtistId (does-not-throw smoke; no public getter for the
module-level state it writes)
playerStore.ts coverage 40.48% -> 48.02% lines (functions 37.84% -> 50.34%).
Close to but not over the F1 50% line floor — the remaining ~2pp lives in
playTrack's async hot-cache/replay-gain body, which is the same surface PR
2c flagged for a separate follow-up. Not adding playerStore.ts to the gate
yet; staying out one more PR to see the number stabilise.
Frontend suite: 451 -> 475 tests (+24).