Remove 12 unit tests that accessed socket internals via :sys.get_state
and called handle_async directly — these leak implementation details and
error/exit paths can't be reached through the DOM.
Keep the 3 integration delete tests that use pure DOM assertions: visit,
assert_has, click, refute_has, render_async, DB verification.
Cover current delete behavior across LiveView index and show paths, and strengthen existing delete tests with persistence assertions.\n\nValidation: mise run dev:precommit
Add live_action guard to handle_info({:update, record}) in both
CollectionLive.Show and WishlistLive.Show. When the user is editing,
background worker updates are skipped and a warning toast is shown
instead of overwriting the socket. Normal show-mode updates and
mismatched-ID no-ops are unchanged.
6 tests added covering all three code paths.
Replace direct LiveView PID and isolated component test patterns with PhoenixTest-backed page flows while keeping narrow unwrap bridges where PhoenixTest cannot express the component interaction.
Precommit: mise run dev:precommit
Import workers now broadcast :records_index_changed on
"records:index_changed" after successful import via
Records.broadcast_index_changed/0.
CollectionLive.Index and WishlistLive.Index subscribe to the
topic in mount/3 and reload their record streams on receipt,
with a live_action guard to skip reloads when the grid is
hidden behind a modal (:import, :barcode_scan).
IndexActions.handle_index_changed/1 refreshes total_entries
before reloading to keep the pagination bar accurate.
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