test(api): URL builders + playback URL resolver + share link composition (Phase F3) (#544)

subsonic.contract.test.ts (21): parseSubsonicEntityStarRating (userRating
first then rating fallback, numeric-string coercion, undefined for null /
NaN / non-numeric), libraryFilterParams (empty without active server, empty
on "all" filter, returns musicFolderId on specific filter), getClient
(throws without a server, returns baseUrl + auth params, rotates token + salt
across calls), coverArtCacheKey (serverId:cover:id:size shape, "_" fallback
without active server, no ephemeral salt embedded -- stays cacheable),
buildStreamUrl (URL shape + Subsonic auth params: id u t s v=1.16.1
c=psysonic/* f=json, rotates t/s across calls so Rust matches by id, special
character ids encoded once not twice), buildCoverArtUrl (default size=256),
buildDownloadUrl (download.view path), trailing-slash + scheme handling on
base URL.

resolvePlaybackUrl.test.ts (15): precedence offline > hot-cache > stream
(first priority wins even when later sources also have the track), forwards
trackId + serverId to both stores. getPlaybackSourceKind for offline / hot
/ stream / engine-preload-hint cases. streamUrlTrackId parser (id from
stream.view query, null for non-stream URLs / no query / missing id, decodes
URL-encoded ids, manual-query fallback for relative paths).

copyEntityShareLink.test.ts (5): writes a psysonic2-prefixed payload that
round-trips, returns false without an active server, returns false on
empty / whitespace id, trims surrounding whitespace before encoding,
propagates clipboard-failure return.

Gate broadens with src/utils/resolvePlaybackUrl.ts (95.8 %) +
src/utils/copyEntityShareLink.ts (100 %). subsonic.ts at 12.7 % stays out
-- the URL-builder + parser surface this PR covers is the structural part;
the async API endpoints need axios mocking, deferred to a follow-up.
authStore.ts (79 %) and playerStore.ts (40 %) deferred-list comments
updated to reflect F2 + F1 actuals.
This commit is contained in:
Frank Stellmacher
2026-05-11 22:51:29 +02:00
committed by GitHub
parent ae23bf61eb
commit d2898ebaf6
4 changed files with 418 additions and 3 deletions
+5 -3
View File
@@ -20,9 +20,9 @@
#
# Deferred from the gate, with current coverage shown for reference:
# - src/store/previewStore.ts (33 % — only `_on*` + `stopPreview` covered, Phase 4 target)
# - src/store/playerStore.ts (0 % — 3700-LOC monolith, Phase 1 target)
# - src/store/authStore.ts (18 % — Phase 2 target)
# - src/api/subsonic.ts (Phase 3 target)
# - src/store/playerStore.ts (40 % — F1 closed under the 50 % floor; further coverage TBD)
# - src/store/authStore.ts (79 % — F2 cleared 60 % floor; staying out one or two PRs to verify stability)
# - src/api/subsonic.ts (13 % — F3 covered the URL-builder + parser surface; async API endpoints need axios mocking, deferred)
# ── utils (already at or above threshold) ────────────────────────────
src/utils/coverArtRegisteredSizes.ts
@@ -30,3 +30,5 @@ src/utils/serverDisplayName.ts
src/utils/serverMagicString.ts
src/utils/shareLink.ts
src/utils/dynamicColors.ts
src/utils/resolvePlaybackUrl.ts
src/utils/copyEntityShareLink.ts