Improve tests: better assertions, meaningful tests

Track resulting principles in project conventions
This commit is contained in:
Claudio Ortolina
2026-03-27 15:46:31 +00:00
parent 6e96bd019f
commit 96836ae715
19 changed files with 91 additions and 140 deletions
+18 -6
View File
@@ -8,31 +8,43 @@ defmodule MusicLibrary.Artists.BatchTest do
setup do
record = record()
artist = hd(record.artists)
_artist_info = artist_info(artist.musicbrainz_id)
:ok
artist_info = artist_info(artist.musicbrainz_id)
%{artist_info: artist_info}
end
describe "refresh_musicbrainz_data/0" do
test "enqueues refresh jobs for all artist infos" do
test "enqueues refresh jobs for all artist infos", %{artist_info: artist_info} do
assert {:ok, []} = Batch.refresh_musicbrainz_data()
assert_enqueued worker: MusicLibrary.Worker.ArtistRefreshMusicBrainzData,
args: %{id: artist_info.id}
end
end
describe "refresh_discogs_data/0" do
test "enqueues refresh jobs for all artist infos" do
test "enqueues refresh jobs for all artist infos", %{artist_info: artist_info} do
assert {:ok, []} = Batch.refresh_discogs_data()
assert_enqueued worker: MusicLibrary.Worker.ArtistRefreshDiscogsData,
args: %{id: artist_info.id}
end
end
describe "refresh_wikipedia_data/0" do
test "enqueues refresh jobs for all artist infos" do
test "enqueues refresh jobs for all artist infos", %{artist_info: artist_info} do
assert {:ok, []} = Batch.refresh_wikipedia_data()
assert_enqueued worker: MusicLibrary.Worker.ArtistRefreshWikipediaData,
args: %{id: artist_info.id}
end
end
describe "refresh_lastfm_data/0" do
test "enqueues refresh jobs for all artist infos" do
test "enqueues refresh jobs for all artist infos", %{artist_info: artist_info} do
assert {:ok, []} = Batch.refresh_lastfm_data()
assert_enqueued worker: MusicLibrary.Worker.FetchArtistLastFmData,
args: %{id: artist_info.id}
end
end
end
+1 -1
View File
@@ -115,7 +115,7 @@ defmodule MusicLibrary.BarcodeScanTest do
Req.Test.transport_error(conn, :timeout)
end)
assert {:error, _reason} = BarcodeScan.scan("5052205070023")
assert {:error, %Req.TransportError{reason: :timeout}} = BarcodeScan.scan("5052205070023")
end
end
+2 -11
View File
@@ -5,18 +5,9 @@ defmodule MusicLibrary.MaintenanceTest do
alias MusicLibrary.Maintenance
describe "vacuum/0" do
test "delegates to Repo.vacuum/0" do
# VACUUM cannot run inside the Ecto sandbox transaction,
# so we verify it attempts the operation and returns the expected tuple shape.
assert {:error, %Exqlite.Error{message: "cannot VACUUM from within a transaction"}} =
Maintenance.vacuum()
end
end
describe "optimize/0" do
test "returns {:ok, _}" do
assert {:ok, _} = Maintenance.optimize()
test "runs PRAGMA optimize on the database" do
assert {:ok, %Exqlite.Result{command: :execute}} = Maintenance.optimize()
end
end
+24 -33
View File
@@ -57,14 +57,34 @@ defmodule MusicLibrary.ScrobbleActivityTest do
end
end
describe "scrobble_release/3 without session key" do
describe "all scrobble operations without session key" do
setup [:stub_lastfm_success]
test "returns error" do
started_at = DateTime.utc_now()
test "scrobble_release/3 returns :no_session_key" do
assert {:error, :no_session_key} =
ScrobbleActivity.scrobble_release(@release, :started_at, DateTime.utc_now())
end
test "scrobble_medium/4 returns :no_session_key" do
assert {:error, :no_session_key} =
ScrobbleActivity.scrobble_medium(1, @release, :started_at, DateTime.utc_now())
end
test "scrobble_tracks/4 returns :no_session_key" do
track_ids =
@release
|> Release.tracks()
|> Enum.take(1)
|> Enum.map(& &1.id)
|> MapSet.new()
assert {:error, :no_session_key} =
ScrobbleActivity.scrobble_release(@release, :started_at, started_at)
ScrobbleActivity.scrobble_tracks(
track_ids,
@release,
:started_at,
DateTime.utc_now()
)
end
end
@@ -114,17 +134,6 @@ defmodule MusicLibrary.ScrobbleActivityTest do
end
end
describe "scrobble_medium/4 without session key" do
setup [:stub_lastfm_success]
test "returns error" do
started_at = DateTime.utc_now()
assert {:error, :no_session_key} =
ScrobbleActivity.scrobble_medium(1, @release, :started_at, started_at)
end
end
describe "scrobble_tracks/4" do
setup [:store_session_key, :stub_lastfm_success]
@@ -189,24 +198,6 @@ defmodule MusicLibrary.ScrobbleActivityTest do
end
end
describe "scrobble_tracks/4 without session key" do
setup [:stub_lastfm_success]
test "returns error" do
track_ids =
@release
|> Release.tracks()
|> Enum.take(1)
|> Enum.map(& &1.id)
|> MapSet.new()
started_at = DateTime.utc_now()
assert {:error, :no_session_key} =
ScrobbleActivity.scrobble_tracks(track_ids, @release, :started_at, started_at)
end
end
describe "scrobble construction" do
setup [:store_session_key]
@@ -9,13 +9,12 @@ defmodule MusicLibrary.Worker.ArtistRefreshAllDiscogsDataTest do
test "enqueues refresh jobs for all artist infos" do
record = record()
artist = hd(record.artists)
_artist_info = artist_info(artist.musicbrainz_id)
artist_info = artist_info(artist.musicbrainz_id)
assert {:ok, []} = perform_job(ArtistRefreshAllDiscogsData, %{})
end
test "succeeds with no artist infos" do
assert {:ok, []} = perform_job(ArtistRefreshAllDiscogsData, %{})
assert_enqueued worker: MusicLibrary.Worker.ArtistRefreshDiscogsData,
args: %{id: artist_info.id}
end
end
end
@@ -9,13 +9,12 @@ defmodule MusicLibrary.Worker.ArtistRefreshAllMusicBrainzDataTest do
test "enqueues refresh jobs for all artist infos" do
record = record()
artist = hd(record.artists)
_artist_info = artist_info(artist.musicbrainz_id)
artist_info = artist_info(artist.musicbrainz_id)
assert {:ok, []} = perform_job(ArtistRefreshAllMusicBrainzData, %{})
end
test "succeeds with no artist infos" do
assert {:ok, []} = perform_job(ArtistRefreshAllMusicBrainzData, %{})
assert_enqueued worker: MusicLibrary.Worker.ArtistRefreshMusicBrainzData,
args: %{id: artist_info.id}
end
end
end
@@ -9,13 +9,12 @@ defmodule MusicLibrary.Worker.ArtistRefreshAllWikipediaDataTest do
test "enqueues refresh jobs for all artist infos" do
record = record()
artist = hd(record.artists)
_artist_info = artist_info(artist.musicbrainz_id)
artist_info = artist_info(artist.musicbrainz_id)
assert {:ok, []} = perform_job(ArtistRefreshAllWikipediaData, %{})
end
test "succeeds with no artist infos" do
assert {:ok, []} = perform_job(ArtistRefreshAllWikipediaData, %{})
assert_enqueued worker: MusicLibrary.Worker.ArtistRefreshWikipediaData,
args: %{id: artist_info.id}
end
end
end
@@ -24,7 +24,7 @@ defmodule MusicLibrary.Worker.ArtistRefreshDiscogsDataTest do
assert {:ok, _} = perform_job(ArtistRefreshDiscogsData, %{"id" => artist_info.id})
updated = Artists.get_artist_info!(artist_info.id)
assert updated.discogs_data != nil
assert updated.discogs_data == ArtistFixture.get_artist()
end
test "returns ok when no discogs data is available" do
@@ -34,8 +34,8 @@ defmodule MusicLibrary.Worker.ArtistRefreshWikipediaDataTest do
assert {:ok, _} = perform_job(ArtistRefreshWikipediaData, %{"id" => artist_info.id})
updated = Artists.get_artist_info!(artist_info.id)
assert updated.wikipedia_data != nil
assert updated.wikipedia_data != %{}
assert is_map(updated.wikipedia_data)
assert Map.has_key?(updated.wikipedia_data, "intro_html")
end
test "discards job when no wikidata_id exists in musicbrainz_data" do
@@ -24,7 +24,8 @@ defmodule MusicLibrary.Worker.FetchArtistImageTest do
assert :ok = perform_job(FetchArtistImage, %{"id" => artist_info.id})
updated = Artists.get_artist_info!(artist_info.id)
assert updated.image_data_hash != nil
assert is_binary(updated.image_data_hash) and byte_size(updated.image_data_hash) > 0
assert MusicLibrary.Assets.get(updated.image_data_hash) != nil
end
test "cancels when no discogs data exists" do
@@ -7,13 +7,12 @@ defmodule MusicLibrary.Worker.RecordGenerateAllEmbeddingsTest do
describe "perform/1" do
test "enqueues embedding generation jobs for all records" do
_record = record()
record = record()
assert {:ok, []} = perform_job(RecordGenerateAllEmbeddings, %{})
end
test "succeeds with no records" do
assert {:ok, []} = perform_job(RecordGenerateAllEmbeddings, %{})
assert_enqueued worker: MusicLibrary.Worker.GenerateRecordEmbedding,
args: %{record_id: record.id}
end
end
end
@@ -7,13 +7,12 @@ defmodule MusicLibrary.Worker.RecordRefreshAllMusicBrainzDataTest do
describe "perform/1" do
test "enqueues refresh jobs for all records" do
_record = record()
record = record()
assert {:ok, []} = perform_job(RecordRefreshAllMusicBrainzData, %{})
end
test "succeeds with no records" do
assert {:ok, []} = perform_job(RecordRefreshAllMusicBrainzData, %{})
assert_enqueued worker: MusicLibrary.Worker.RecordRefreshMusicBrainzData,
args: %{id: record.id}
end
end
end
@@ -24,7 +24,7 @@ defmodule MusicLibrary.Worker.RecordRefreshMusicBrainzDataTest do
assert :ok = perform_job(RecordRefreshMusicBrainzData, %{"id" => record.id})
updated = Records.get_record!(record.id)
assert updated.musicbrainz_data != nil
assert updated.musicbrainz_data["title"] == "Marbles"
end
test "raises when record does not exist" do
@@ -18,8 +18,10 @@ defmodule MusicLibrary.Worker.RefreshCoverTest do
assert :ok = perform_job(RefreshCover, %{"id" => record.id})
updated = Records.get_record!(record.id)
assert updated.cover_hash != nil
assert Assets.get(updated.cover_hash) != nil
assert is_binary(updated.cover_hash) and byte_size(updated.cover_hash) > 0
asset = Assets.get(updated.cover_hash)
assert asset.format == "image/jpeg"
end
test "raises when record does not exist" do
@@ -1,11 +0,0 @@
defmodule MusicLibrary.Worker.RepoOptimizeTest do
use MusicLibrary.DataCase
alias MusicLibrary.Worker.RepoOptimize
describe "perform/1" do
test "runs optimize on the repo" do
assert {:ok, %Exqlite.Result{}} = perform_job(RepoOptimize, %{})
end
end
end
@@ -12,15 +12,23 @@ defmodule MusicLibraryWeb.CollectionControllerTest do
|> Keyword.fetch!(:api_token)
end
describe "authentication" do
test "all API endpoints require a bearer token", %{conn: conn} do
for path <- [
~p"/api/collection/latest",
~p"/api/collection/random",
~p"/api/collection",
~p"/api/collection/on_this_day"
] do
assert get(conn, path).status == 401,
"expected 401 for unauthenticated GET #{path}"
end
end
end
describe "GET /api/collection/latest" do
setup [:create_record]
test "requires authentication", %{conn: conn} do
conn = get(conn, ~p"/api/collection/latest")
assert conn.status == 401
end
test "returns the latest record", %{conn: conn, record: record} do
conn =
conn
@@ -34,12 +42,6 @@ defmodule MusicLibraryWeb.CollectionControllerTest do
describe "GET /api/collection/random" do
setup [:create_record]
test "requires authentication", %{conn: conn} do
conn = get(conn, ~p"/api/collection/random")
assert conn.status == 401
end
# We're not testing random here - the query is solid enough
test "returns a random record", %{conn: conn, record: record} do
conn =
@@ -54,12 +56,6 @@ defmodule MusicLibraryWeb.CollectionControllerTest do
describe "GET /api/collection" do
setup [:create_record]
test "requires authentication", %{conn: conn} do
conn = get(conn, ~p"/api/collection")
assert conn.status == 401
end
test "returns a paginated list of records", %{conn: conn, record: record} do
conn =
conn
@@ -78,12 +74,6 @@ defmodule MusicLibraryWeb.CollectionControllerTest do
describe "GET /api/collection/on_this_day" do
setup [:create_record]
test "requires authentication", %{conn: conn} do
conn = get(conn, ~p"/api/collection/on_this_day")
assert conn.status == 401
end
test "returns a list of records", %{conn: conn, record: record} do
conn =
conn
@@ -1,15 +0,0 @@
defmodule MusicLibraryWeb.ErrorHTMLTest do
use MusicLibraryWeb.ConnCase, async: true
# Bring render_to_string/4 for testing custom views
import Phoenix.Template
test "renders 404.html" do
assert render_to_string(MusicLibraryWeb.ErrorHTML, "404", "html", []) == "Not Found"
end
test "renders 500.html" do
assert render_to_string(MusicLibraryWeb.ErrorHTML, "500", "html", []) ==
"Internal Server Error"
end
end
@@ -1,12 +0,0 @@
defmodule MusicLibraryWeb.ErrorJSONTest do
use MusicLibraryWeb.ConnCase, async: true
test "renders 404" do
assert MusicLibraryWeb.ErrorJSON.render("404.json", %{}) == %{errors: %{detail: "Not Found"}}
end
test "renders 500" do
assert MusicLibraryWeb.ErrorJSON.render("500.json", %{}) ==
%{errors: %{detail: "Internal Server Error"}}
end
end