test(api): cover PATCH /api/v1/preferences and the cookie overlay - #343
Merged
Conversation
`PATCH /api/v1/preferences` had no test at all — it was the only uncovered code left in routes/api.py. That matters more than a coverage number: it is the endpoint an external client writes preferences through, and the price-source/currency values it carries decide whether two apps agree on what a collection is worth. Covers, on the endpoint: partial application (exclude_unset), normalization of bad input (unknown currency/price-source fall back, view collapses to grid, page_size/card_size/foil_speed/spin_speed clamp), an explicit null not wiping a stored value, unknown fields ignored, the read-only guard, and the token gate — which is the documented reason /prefs exists as a separate browser-facing router. Also covers `_clamp`'s non-numeric fallback (reachable from the service / CLI layer, since the API's typed model rejects those first) and the cookie overlay in `resolve`, including off-menu page sizes and junk values. preferences.py and routes/api.py are both back to 100%; repo-wide uncovered drops from 16 lines to 5. Tests only — no behavior change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Found while checking coverage on #342:
PATCH /api/v1/preferenceshad no test at all — its three lines were the only uncovered code inroutes/api.py.That matters more than the coverage number. It's the endpoint an external client writes preferences through, and the
price_source/currency/hist_currencyvalues it carries are what decide whether two apps agree on what a collection is worth. ADR 0002 just made those a cross-app contract rather than a display preference.What's covered
On the endpoint:
/prefsrouter — same singleton.exclude_unset) — fields not sent keep prior values.viewcollapses togrid, andpage_size/card_size/foil_speed/spin_speedclamp to their ranges. Garbage never persists.nulldoesn't wipe a stored value — it means "not set", which is easy to get wrong in a PATCH./prefsexists as a separate browser-facing router. There was a test assertingGET /api/v1/preferencesis gated; now PATCH is too.Below the endpoint:
_clamp's non-numeric fallback, reachable from the service/CLI layer since the API's typed model rejects those first.resolve— a device's own choices winning until a row is saved — including off-menu page sizes and junk values being ignored.Result
preferences.pyandroutes/api.pyare both back to 100%. Repo-wide uncovered drops from 16 lines to 5.Tests only — no behavior change.
ruff check src testsclean; full suite 1176 passed.🤖 Generated with Claude Code