test(fe): lock query-key factory shapes; unify nullable guard (R7 S2 review)
Code-review follow-ups on the S2 factory: - add queryKeys.test.ts pinning every branch (bare vs param, null-segment preservation, single-id, variadic composite spreads) — the contract the epic exists to protect now has a test (suite 68 -> 73) - unify feed/feedCount/facets on the `!== undefined` guard the rest of the factory already uses (behaviour-identical for the always-truthy FeedFilters, removes the collapse-on-null footgun) Two findings skipped with rationale: variadic composite-key typing (heterogeneous object/array segments make precise tuples high-effort; root centralized + shapes now tested) and a pre-existing thread(null) no-op (unreachable in practice).
This commit is contained in:
@@ -16,15 +16,17 @@ export const qk = {
|
||||
tags: () => ["tags"] as const,
|
||||
|
||||
// --- feed / video ---
|
||||
feed: (filters?: FeedFilters) => (filters ? (["feed", filters] as const) : (["feed"] as const)),
|
||||
// Every parameterized key guards on `!== undefined` (not truthiness), so "no arg → bare prefix
|
||||
// key" is the ONE rule across the factory. It also keeps a nullable segment intact: `q`/`id`
|
||||
// accept null because some call sites key on nullable state (`selectedId`, the search string),
|
||||
// and a NULL is a real key segment that must be preserved (`["playlist", null]`) rather than
|
||||
// silently collapsed to the prefix.
|
||||
feed: (filters?: FeedFilters) =>
|
||||
filters !== undefined ? (["feed", filters] as const) : (["feed"] as const),
|
||||
feedCount: (filters?: FeedFilters) =>
|
||||
filters ? (["feed-count", filters] as const) : (["feed-count"] as const),
|
||||
filters !== undefined ? (["feed-count", filters] as const) : (["feed-count"] as const),
|
||||
facets: (filters?: FeedFilters) =>
|
||||
filters ? (["facets", filters] as const) : (["facets"] as const),
|
||||
// `q`/`id` accept null (not just undefined) because the call sites key on nullable state
|
||||
// (`selectedId`, the search string): a NULL is a real key segment and must be preserved
|
||||
// (`["playlist", null]`), while a genuinely absent arg is the bare prefix key. The guard is
|
||||
// `!== undefined`, so only the no-arg call collapses to the prefix.
|
||||
filters !== undefined ? (["facets", filters] as const) : (["facets"] as const),
|
||||
ytSearch: (q?: string | null, count?: number) =>
|
||||
q !== undefined ? (["yt-search", q, count] as const) : (["yt-search"] as const),
|
||||
videoDetail: (id: string) => ["video-detail", id] as const,
|
||||
|
||||
Reference in New Issue
Block a user