Claudio Ortolina
3849b338f3
Improve performance of job counting in maintenance
...
- Use a single query for all workers
- Replace the manual Ecto query against Oban.Job with Oban.Job.query/1
2026-04-30 14:54:56 +01:00
Claudio Ortolina
c489fde1cc
ML-152: add /api/v1/ version prefix to all API routes
2026-04-30 11:57:43 +01:00
Claudio Ortolina
f2839dfaf1
Test needs to be sync
2026-04-29 22:50:29 +01:00
Claudio Ortolina
9f8ef6c329
Use larger image for Last.fm artists
2026-04-25 21:22:18 +01:00
Claudio Ortolina
9113df5879
ML-146: honour API retry headers
2026-04-25 07:39:49 +01:00
Claudio Ortolina
d588e5738f
Remove redundant tests
2026-04-25 06:57:03 +01:00
Claudio Ortolina
a1c665b490
ML-21: Classify API errors as transient vs permanent
2026-04-24 14:02:15 +01:00
Claudio Ortolina
252caf31ce
ML-11: Improve performance of Telemetry.Storage with in-memory buffer
2026-04-24 10:30:28 +01:00
Claudio Ortolina
0784fc5e0c
Fix page title for scrobble anything release page
2026-04-23 21:06:32 +01:00
Claudio Ortolina
1bd5707cb4
Fix page title for scrobble anything index and release group route
2026-04-23 21:06:12 +01:00
Claudio Ortolina
8911afad94
Add tests for Top Albums component
2026-04-23 16:41:44 +01:00
Claudio Ortolina
c7c7e1fe4e
Navigate from scrobble search to release-group page
2026-04-23 14:47:50 +01:00
Claudio Ortolina
0dcd6eab83
Replace /scrobble/:release_id with nested route
2026-04-23 14:39:26 +01:00
Claudio Ortolina
d8041dc0dd
Add /scrobble/:rg_id release-group page
2026-04-23 14:35:58 +01:00
Claudio Ortolina
4c48bda7b2
Refactor Release component to take release_id
2026-04-23 14:19:11 +01:00
Claudio Ortolina
0d1f580379
Refactor TracklistPdf to take release alone
2026-04-23 07:48:53 +01:00
Claudio Ortolina
f7f38d580e
Enable unaliased modules ex_slop check
2026-04-22 20:37:09 +01:00
Claudio Ortolina
0776700170
ML-142: Improve scrobble UI in the release component
...
- Sticky bar for easier track-based scrobbling
- Support setting custom finish time
2026-04-22 17:19:35 +01:00
Claudio Ortolina
9851a5c6bf
Use cart with barcode scanner
2026-04-20 15:46:40 +01:00
Claudio Ortolina
eaece07193
Count formats in results
2026-04-20 15:15:29 +01:00
Claudio Ortolina
c4ebe636ff
Fix ML-143 review: security, worker, and test improvements
...
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
2026-04-20 15:15:29 +01:00
Claudio Ortolina
3f5ce060b1
Implement ML-143: Cart-style multi record import
...
Closes ML-143.
2026-04-20 15:15:29 +01:00
Claudio Ortolina
78487b0085
Pin Wikipedia intro_html to fixture value
...
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
2026-04-20 06:50:04 +01:00
Claudio Ortolina
a6319d55df
Pin artist_live/show image_data_hash assertions
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
07c99992a3
Pin barcode_scan release assertions
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
162c10e70a
Pin fetch_artist_image asset lookup
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
bce8560ce8
Pin fetch_artist_info stored-data assertions
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
1f457f0f11
Pin prune_assets test to %Asset{hash: ^hash} match
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
8a6c688a56
Assert parsed audit JSON structure
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
0eabe4b3ab
Assert import count > 0 in options-forwarding test
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
8ce5da65e2
Pin Brave search error body assertion
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
cedb86af5d
Pin OpenAI API error assertions to their shapes
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
6adfbea336
Pin Records.populate_genres error to OpenAI prefix
...
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
0ee0dcb118
Match decoded OpenAI error body, not raw JSON
...
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
2026-04-20 06:50:04 +01:00
Claudio Ortolina
1429f7a826
Drop tautological delete.id checks
...
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
2026-04-20 06:50:04 +01:00
Claudio Ortolina
bb260437a1
Pin populate_genres error to OpenAI prefix
...
Match the string prefix "OpenAI API error:" that propagates from
OpenAI.gpt on non-2xx responses.
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
a841ccf8e8
Tighten generate_record_embedding assertions
...
Assert stored embedding text matches the representation helper.
Pin the OpenAI-500 error path to the raw JSON body string.
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
bbe0d5cd9e
Pin artist_refresh_discogs_data assertions
...
Bind the returned ArtistInfo. For the no-discogs branch, assert
discogs_data was not touched.
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
f9e3e8c5f8
Pin artist_refresh_wikipedia_data assertions
...
Bind perform_job results and assert id equality. For the unchanged case,
also assert wikipedia_data is the same as before the job ran.
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
914fb4fbee
Match specific errors on scrobble_rules duplicate
...
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
2026-04-20 06:50:04 +01:00
Claudio Ortolina
9e29de55aa
Pin online_store_templates delete assertion
...
Assert deleted.id == template.id rather than wildcard-matching the
returned struct.
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
a90fdcf82f
Tighten chats assertions
...
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
2026-04-20 06:50:04 +01:00
Claudio Ortolina
66c36f4d09
Tighten record_sets delete and duplicate assertions
...
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
2026-04-20 06:50:04 +01:00
Claudio Ortolina
60e95804ad
Tighten similarity test assertions
...
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
2026-04-20 06:50:04 +01:00
Claudio Ortolina
e0fe5051ec
Pin asset dedup assertion to same-hash
...
The duplicate prevention test asserted `{:ok, _}` twice without checking
that both calls returned the same asset. Assert hash equality.
Refs #176
2026-04-20 06:50:04 +01:00
Claudio Ortolina
ae036e79fb
Tighten scrobble_activity assertions
...
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
2026-04-20 06:50:04 +01:00
Claudio Ortolina
beaf38fcfe
Add record_release tests
2026-04-19 16:11:32 +01:00
Claudio Ortolina
0dcfecf741
Increase render_async timeout to cater for slower CI
2026-04-19 09:29:04 +01:00
Claudio Ortolina
f4db063298
Test artist edit form and record set picker flows
...
Closes #180
2026-04-19 09:00:06 +01:00
Claudio Ortolina
45236e4b10
Convert ErrorIgnorer tests to doctests
2026-04-19 07:50:39 +01:00