Closes ML-143 review findings:
- cast_id/1 uses Integer.parse instead of String.to_integer
- add_to_cart validates against server-side release_groups
- JS.push payload trimmed to {id, format} only
- Oban.insert_all result checked for partial failures
- handle_async success resets @importing? to false
- ImportFromMusicbrainzReleaseGroup gets unique constraint
- Record.parse_datetime/1 made public with safe match
- Workers delegate to Record.parse_datetime/1
- Test coverage: change_format, clear_cart, wishlist single import
Map.has_key? verified the key existed but not the content. The
fixture is deterministic — assert the stored value equals
Wikipedia.Fixtures.article_extract_html/0.
Refs #176
Switch the 500-response stubs to Req.Test.json so Req decodes the
body, then match the map shape. Avoids coupling the assertion to
the exact JSON serialization.
Refs #176
Repo.delete always returns the struct it was given, so deleted.id
== original.id is trivially true. Thread deleted.id through the
trailing get_*! call instead, so the binding is load-bearing.
Refs #176
Pin the duplicate-rule error to the match_value field and "has already been
taken" message, matching the unique_constraint error_key in the changeset.
Refs #176
Pin invalid-attrs error to specific field, assert collection UUID round-trips
through Ecto.UUID.cast unchanged, and assert deleted.id == chat.id on delete.
Refs #176
Assert deleted.id == set.id on delete, and pin the duplicate error to the
specific field and message from the unique_constraint on record_set_id.
Refs #176
Bind returned embeddings and assert record_id / text_representation match.
Pin OpenAI error path to the actual raw string body returned by the stub.
Refs #176
Replace 9 `{:ok, _}` sites with specific response-body checks to verify
the context returns the Last.fm API payload and not just the success branch.
Refs #176
Covers all action handlers on LiveHelpers.RecordActions and all
update/event clauses on Components.Chat — including streaming
chunk/done/error transitions and the retry re-send path.
Closes#179
SQLite interprets bare years (e.g. "1970") as Julian day numbers
in strftime, producing wrong month-day matches. Filter to only
full YYYY-MM-DD dates before comparing.