From 84159a1c0d020fb9202516731ed77ea10f69e307 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Sat, 7 Feb 2026 10:39:22 +0000 Subject: [PATCH] Improve test coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Files Created (8 files, 54 new tests) Fixtures 1. test/support/fixtures/music_library/record_sets.ex — record_set/1 and record_set_with_records/2 helpers 2. test/support/fixtures/music_library/online_store_templates.ex — online_store_template/1 helper Context Tests 3. test/music_library/record_sets_test.exs — 20 tests covering search, count, CRUD, add/remove/move records 4. test/music_library/online_store_templates_test.exs — 8 tests covering list, CRUD, URL generation, validation 5. test/music_library/search_test.exs — 5 tests covering universal search and search counts 6. test/music_library/notes_test.exs — 4 tests covering get, create, update LiveView Tests 7. test/music_library_web/live/record_set_live/index_test.exs — 11 tests covering listing, empty state, search, ordering, create/edit/delete sets, remove records, reorder records 8. test/music_library_web/live/online_store_template_live/index_test.exs — 6 tests covering listing, create/edit/delete, toggle enabled Results - 297 tests, 0 failures (up from 243 — 54 new tests added) - All existing tests continue to pass There's a remaining gettext warning that needs to be investigated --- test/music_library/notes_test.exs | 56 +++++ .../online_store_templates_test.exs | 95 ++++++++ test/music_library/record_sets_test.exs | 210 ++++++++++++++++++ test/music_library/search_test.exs | 77 +++++++ .../online_store_template_live/index_test.exs | 108 +++++++++ .../live/record_set_live/index_test.exs | 158 +++++++++++++ .../music_library/online_store_templates.ex | 24 ++ .../fixtures/music_library/record_sets.ex | 35 +++ 8 files changed, 763 insertions(+) create mode 100644 test/music_library/notes_test.exs create mode 100644 test/music_library/online_store_templates_test.exs create mode 100644 test/music_library/record_sets_test.exs create mode 100644 test/music_library/search_test.exs create mode 100644 test/music_library_web/live/online_store_template_live/index_test.exs create mode 100644 test/music_library_web/live/record_set_live/index_test.exs create mode 100644 test/support/fixtures/music_library/online_store_templates.ex create mode 100644 test/support/fixtures/music_library/record_sets.ex diff --git a/test/music_library/notes_test.exs b/test/music_library/notes_test.exs new file mode 100644 index 00000000..1f35dc3f --- /dev/null +++ b/test/music_library/notes_test.exs @@ -0,0 +1,56 @@ +defmodule MusicLibrary.NotesTest do + use MusicLibrary.DataCase + + alias MusicLibrary.Notes + alias MusicLibrary.Notes.Note + + @musicbrainz_id Ecto.UUID.generate() + + describe "get_note/2" do + test "returns nil when no note exists" do + assert Notes.get_note(:record, Ecto.UUID.generate()) == nil + end + + test "returns note for record" do + {:ok, note} = + Notes.create_note(%Note{}, %{ + entity: :record, + musicbrainz_id: @musicbrainz_id, + content: "Great album" + }) + + found = Notes.get_note(:record, @musicbrainz_id) + assert found.id == note.id + assert found.content == "Great album" + end + end + + describe "create_note/2" do + test "creates a note" do + assert {:ok, note} = + Notes.create_note(%Note{}, %{ + entity: :artist, + musicbrainz_id: @musicbrainz_id, + content: "Fantastic artist" + }) + + assert note.entity == :artist + assert note.content == "Fantastic artist" + assert note.musicbrainz_id == @musicbrainz_id + end + end + + describe "update_note/2" do + test "updates note content" do + {:ok, note} = + Notes.create_note(%Note{}, %{ + entity: :record, + musicbrainz_id: @musicbrainz_id, + content: "Original" + }) + + assert {:ok, updated} = Notes.update_note(note, %{content: "Updated content"}) + assert updated.content == "Updated content" + end + end +end diff --git a/test/music_library/online_store_templates_test.exs b/test/music_library/online_store_templates_test.exs new file mode 100644 index 00000000..99363acc --- /dev/null +++ b/test/music_library/online_store_templates_test.exs @@ -0,0 +1,95 @@ +defmodule MusicLibrary.OnlineStoreTemplatesTest do + use MusicLibrary.DataCase + + import MusicLibrary.Fixtures.OnlineStoreTemplates + import MusicLibrary.Fixtures.Records + + alias MusicLibrary.OnlineStoreTemplates + + describe "list_templates/0 and list_enabled_templates/0" do + test "lists all templates" do + t1 = online_store_template(%{name: "Amazon", enabled: true}) + t2 = online_store_template(%{name: "Bandcamp", enabled: false}) + + all = OnlineStoreTemplates.list_templates() + ids = Enum.map(all, & &1.id) + assert t1.id in ids + assert t2.id in ids + end + + test "lists only enabled templates" do + t1 = online_store_template(%{name: "Amazon", enabled: true}) + t2 = online_store_template(%{name: "Bandcamp", enabled: false}) + + enabled = OnlineStoreTemplates.list_enabled_templates() + ids = Enum.map(enabled, & &1.id) + assert t1.id in ids + refute t2.id in ids + end + end + + describe "create_template/1" do + test "creates with valid attrs" do + assert {:ok, template} = + OnlineStoreTemplates.create_template(%{ + name: "Test Store", + url_template: "https://example.com/search?q={artist}" + }) + + assert template.name == "Test Store" + assert template.enabled == true + end + + test "returns error with invalid attrs" do + assert {:error, changeset} = OnlineStoreTemplates.create_template(%{name: nil}) + assert %{name: ["can't be blank"]} = errors_on(changeset) + end + + test "returns error with invalid URL template" do + assert {:error, changeset} = + OnlineStoreTemplates.create_template(%{ + name: "Bad", + url_template: "not-a-url" + }) + + assert %{url_template: ["must be a valid HTTP or HTTPS URL"]} = errors_on(changeset) + end + end + + describe "update_template/2" do + test "updates with valid attrs" do + template = online_store_template() + + assert {:ok, updated} = + OnlineStoreTemplates.update_template(template, %{name: "Updated Name"}) + + assert updated.name == "Updated Name" + end + end + + describe "delete_template/1" do + test "deletes the template" do + template = online_store_template() + assert {:ok, _} = OnlineStoreTemplates.delete_template(template) + assert_raise Ecto.NoResultsError, fn -> OnlineStoreTemplates.get_template!(template.id) end + end + end + + describe "generate_url/2" do + test "generates URL from template and record" do + template = + online_store_template(%{ + url_template: "https://example.com/search?q={artist}+{title}+{format}" + }) + + rec = record_with_artist("Pink Floyd", %{title: "The Wall", format: :vinyl}) + + url = OnlineStoreTemplates.generate_url(template, rec) + + assert url =~ "Pink+Floyd" + assert url =~ "The+Wall" + assert url =~ "vinyl" + assert String.starts_with?(url, "https://example.com/search?q=") + end + end +end diff --git a/test/music_library/record_sets_test.exs b/test/music_library/record_sets_test.exs new file mode 100644 index 00000000..c0c895d9 --- /dev/null +++ b/test/music_library/record_sets_test.exs @@ -0,0 +1,210 @@ +defmodule MusicLibrary.RecordSetsTest do + use MusicLibrary.DataCase + + import MusicLibrary.Fixtures.Records + import MusicLibrary.Fixtures.RecordSets + + alias MusicLibrary.RecordSets + + describe "search_record_sets/2" do + test "returns sets matching by name" do + set = record_set(%{name: "Road Trip Mix"}) + _other = record_set(%{name: "Unrelated"}) + + results = RecordSets.search_record_sets("Road Trip") + assert Enum.any?(results, &(&1.id == set.id)) + refute Enum.any?(results, &(&1.name == "Unrelated")) + end + + test "returns sets matching by description" do + set = record_set(%{name: "My Set", description: "Great progressive rock"}) + _other = record_set(%{name: "Other", description: "Nothing here"}) + + results = RecordSets.search_record_sets("progressive") + assert Enum.any?(results, &(&1.id == set.id)) + end + + test "returns sets matching by record title" do + {set, [rec | _]} = record_set_with_records(1, %{name: "Favorites"}) + + results = RecordSets.search_record_sets(rec.title) + assert Enum.any?(results, &(&1.id == set.id)) + end + + test "returns sets matching by artist name" do + rec = record_with_artist("Marillion") + set = record_set(%{name: "Prog"}) + {:ok, _} = RecordSets.add_record_to_set(set, rec.id) + + results = RecordSets.search_record_sets("Marillion") + assert Enum.any?(results, &(&1.id == set.id)) + end + + test "returns all sets when query is empty" do + set1 = record_set(%{name: "First"}) + set2 = record_set(%{name: "Second"}) + + results = RecordSets.search_record_sets("") + ids = Enum.map(results, & &1.id) + assert set1.id in ids + assert set2.id in ids + end + + test "respects offset and limit" do + for i <- 1..5, do: record_set(%{name: "Set #{i}"}) + + results = RecordSets.search_record_sets("", limit: 2) + assert length(results) == 2 + + all = RecordSets.search_record_sets("") + offset_results = RecordSets.search_record_sets("", offset: 2, limit: 2) + + refute Enum.at(all, 0).id == Enum.at(offset_results, 0).id + end + + test "orders by updated_at desc by default" do + s1 = record_set(%{name: "Alpha"}) + s2 = record_set(%{name: "Beta"}) + + # Manually set timestamps to ensure deterministic ordering + past = ~U[2024-01-01 00:00:00Z] + future = ~U[2025-01-01 00:00:00Z] + Repo.update_all(from(rs in "record_sets", where: rs.id == ^s1.id), set: [updated_at: past]) + + Repo.update_all(from(rs in "record_sets", where: rs.id == ^s2.id), + set: [updated_at: future] + ) + + results = RecordSets.search_record_sets("") + ids = Enum.map(results, & &1.id) + + # s2 has newer updated_at so it should be first + assert Enum.find_index(ids, &(&1 == s2.id)) < Enum.find_index(ids, &(&1 == s1.id)) + end + + test "orders alphabetically when order: :alphabetical" do + record_set(%{name: "Zulu"}) + record_set(%{name: "Alpha"}) + + results = RecordSets.search_record_sets("", order: :alphabetical) + names = Enum.map(results, & &1.name) + + assert Enum.find_index(names, &(&1 == "Alpha")) < Enum.find_index(names, &(&1 == "Zulu")) + end + end + + describe "count_record_sets/0 and count_record_sets/1" do + test "returns total count" do + assert RecordSets.count_record_sets() == 0 + + record_set(%{name: "One"}) + record_set(%{name: "Two"}) + + assert RecordSets.count_record_sets() == 2 + end + + test "returns count matching query" do + record_set(%{name: "Road Trip"}) + record_set(%{name: "Sunday Morning"}) + + assert RecordSets.count_record_sets("Road") == 1 + assert RecordSets.count_record_sets("") == 2 + end + end + + describe "create_record_set/1" do + test "creates with valid attrs" do + assert {:ok, set} = RecordSets.create_record_set(%{name: "My Set"}) + assert set.name == "My Set" + assert set.items == [] + end + + test "returns error changeset with invalid attrs" do + assert {:error, changeset} = RecordSets.create_record_set(%{name: nil}) + assert %{name: ["can't be blank"]} = errors_on(changeset) + end + end + + describe "update_record_set/2" do + test "updates with valid attrs" do + set = record_set(%{name: "Old Name"}) + assert {:ok, updated} = RecordSets.update_record_set(set, %{name: "New Name"}) + assert updated.name == "New Name" + end + end + + describe "delete_record_set/1" do + test "deletes the record set" do + set = record_set() + assert {:ok, _} = RecordSets.delete_record_set(set) + assert_raise Ecto.NoResultsError, fn -> RecordSets.get_record_set!(set.id) end + end + end + + describe "add_record_to_set/2" do + test "adds a record to the set" do + set = record_set() + rec = record() + + assert {:ok, updated} = RecordSets.add_record_to_set(set, rec.id) + assert length(updated.items) == 1 + assert hd(updated.items).record.id == rec.id + end + + test "returns error on duplicate" do + set = record_set() + rec = record() + + {:ok, _} = RecordSets.add_record_to_set(set, rec.id) + assert {:error, _changeset} = RecordSets.add_record_to_set(set, rec.id) + end + end + + describe "remove_record_from_set/2" do + test "removes a record and recompacts positions" do + {set, [r1, r2, r3]} = record_set_with_records(3) + + {:ok, updated} = RecordSets.remove_record_from_set(set, r2.id) + + record_ids = Enum.map(updated.items, & &1.record.id) + assert r1.id in record_ids + assert r3.id in record_ids + refute r2.id in record_ids + + positions = Enum.map(updated.items, & &1.position) + assert positions == [0, 1] + end + end + + describe "move_record_in_set/3" do + test "moves a record up" do + {set, [r1, r2 | _]} = record_set_with_records(3) + + {:ok, updated} = RecordSets.move_record_in_set(set, r2.id, :up) + + ids_in_order = Enum.map(updated.items, & &1.record.id) + assert Enum.at(ids_in_order, 0) == r2.id + assert Enum.at(ids_in_order, 1) == r1.id + end + + test "moves a record down" do + {set, [r1, r2 | _]} = record_set_with_records(3) + + {:ok, updated} = RecordSets.move_record_in_set(set, r1.id, :down) + + ids_in_order = Enum.map(updated.items, & &1.record.id) + assert Enum.at(ids_in_order, 0) == r2.id + assert Enum.at(ids_in_order, 1) == r1.id + end + + test "no-ops at boundaries" do + {set, [r1, _, r3]} = record_set_with_records(3) + + {:ok, moved_up} = RecordSets.move_record_in_set(set, r1.id, :up) + assert Enum.map(moved_up.items, & &1.record.id) == Enum.map(set.items, & &1.record.id) + + {:ok, moved_down} = RecordSets.move_record_in_set(set, r3.id, :down) + assert Enum.map(moved_down.items, & &1.record.id) == Enum.map(set.items, & &1.record.id) + end + end +end diff --git a/test/music_library/search_test.exs b/test/music_library/search_test.exs new file mode 100644 index 00000000..d486e484 --- /dev/null +++ b/test/music_library/search_test.exs @@ -0,0 +1,77 @@ +defmodule MusicLibrary.SearchTest do + use MusicLibrary.DataCase + + import MusicLibrary.Fixtures.Records + + alias MusicLibrary.Search + + defp create_records(_) do + collected = + record_with_artist("Marillion", %{title: "Brave", purchased_at: DateTime.utc_now()}) + + wishlisted = + record_with_artist("Marillion", %{title: "Afraid of Sunlight", purchased_at: nil}) + + # Create artist info so search_artists can find artists + [artist] = collected.artists + artist_info(artist.musicbrainz_id) + + %{collected: collected, wishlisted: wishlisted} + end + + describe "universal_search/2" do + setup [:create_records] + + test "returns collection, wishlist, and artist results", %{ + collected: collected, + wishlisted: wishlisted + } do + results = Search.universal_search("Marillion") + + collection_ids = Enum.map(results.collection, & &1.id) + assert collected.id in collection_ids + + wishlist_ids = Enum.map(results.wishlist, & &1.id) + assert wishlisted.id in wishlist_ids + + artist_names = Enum.map(results.artists, fn a -> a.artist.name end) + assert "Marillion" in artist_names + end + + test "returns empty results for no matches" do + results = Search.universal_search("zzz_nonexistent_zzz") + + assert results.collection == [] + assert results.wishlist == [] + assert results.artists == [] + end + + test "respects limit", %{collected: _collected} do + results = Search.universal_search("Marillion", limit: 1) + + assert length(results.collection) <= 1 + assert length(results.wishlist) <= 1 + assert length(results.artists) <= 1 + end + end + + describe "search_counts/1" do + setup [:create_records] + + test "returns counts per category" do + counts = Search.search_counts("Marillion") + + assert counts.collection_count >= 1 + assert counts.wishlist_count >= 1 + assert counts.artists_count >= 1 + end + + test "returns zero counts for no matches" do + counts = Search.search_counts("zzz_nonexistent_zzz") + + assert counts.collection_count == 0 + assert counts.wishlist_count == 0 + assert counts.artists_count == 0 + end + end +end diff --git a/test/music_library_web/live/online_store_template_live/index_test.exs b/test/music_library_web/live/online_store_template_live/index_test.exs new file mode 100644 index 00000000..d484d610 --- /dev/null +++ b/test/music_library_web/live/online_store_template_live/index_test.exs @@ -0,0 +1,108 @@ +defmodule MusicLibraryWeb.OnlineStoreTemplateLive.IndexTest do + use MusicLibraryWeb.ConnCase + + import MusicLibrary.Fixtures.OnlineStoreTemplates + import Phoenix.LiveViewTest + + alias MusicLibrary.OnlineStoreTemplates + + describe "Index" do + test "lists all templates", %{conn: conn} do + online_store_template(%{name: "Amazon UK"}) + online_store_template(%{name: "Bandcamp"}) + + conn + |> visit(~p"/online-store-templates") + |> assert_has("h1", text: "Online Store Templates") + |> assert_has("p", text: "Amazon UK") + |> assert_has("p", text: "Bandcamp") + end + end + + describe "Create template" do + test "creates with valid data", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/online-store-templates/new") + + view + |> form("#online_store_template-form", + online_store_template: %{ + name: "New Store", + url_template: "https://store.example.com/search?q={artist}+{title}" + } + ) + |> render_submit() + + templates = OnlineStoreTemplates.list_templates() + assert Enum.any?(templates, &(&1.name == "New Store")) + end + + test "shows validation errors", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/online-store-templates/new") + + html = + view + |> form("#online_store_template-form", + online_store_template: %{name: "", url_template: ""} + ) + |> render_change() + + assert html =~ "can't be blank" + end + end + + describe "Edit template" do + test "updates with valid data", %{conn: conn} do + template = online_store_template(%{name: "Old Name"}) + + {:ok, view, _html} = live(conn, ~p"/online-store-templates/#{template}/edit") + + view + |> form("#online_store_template-form", + online_store_template: %{name: "Updated Name"} + ) + |> render_submit() + + updated = OnlineStoreTemplates.get_template!(template.id) + assert updated.name == "Updated Name" + end + end + + describe "Delete template" do + test "deletes from listing", %{conn: conn} do + template = online_store_template(%{name: "To Delete"}) + + {:ok, view, _html} = live(conn, ~p"/online-store-templates") + + view + |> element("button[phx-click='delete'][phx-value-id='#{template.id}']") + |> render_click() + + refute has_element?(view, "p", "To Delete") + assert_raise Ecto.NoResultsError, fn -> OnlineStoreTemplates.get_template!(template.id) end + end + end + + describe "Toggle enabled" do + test "toggles template enabled status", %{conn: conn} do + template = online_store_template(%{name: "Toggle Me", enabled: true}) + + {:ok, view, _html} = live(conn, ~p"/online-store-templates") + + # Toggle to disabled + view + |> element("button[phx-click='toggle-enabled'][phx-value-id='#{template.id}']") + |> render_click() + + updated = OnlineStoreTemplates.get_template!(template.id) + refute updated.enabled + + # Toggle back to enabled + view + |> element("button[phx-click='toggle-enabled'][phx-value-id='#{template.id}']") + |> render_click() + + updated = OnlineStoreTemplates.get_template!(template.id) + assert updated.enabled + end + end +end diff --git a/test/music_library_web/live/record_set_live/index_test.exs b/test/music_library_web/live/record_set_live/index_test.exs new file mode 100644 index 00000000..d5e51a41 --- /dev/null +++ b/test/music_library_web/live/record_set_live/index_test.exs @@ -0,0 +1,158 @@ +defmodule MusicLibraryWeb.RecordSetLive.IndexTest do + use MusicLibraryWeb.ConnCase + + import MusicLibrary.Fixtures.RecordSets + import Phoenix.LiveViewTest + + alias MusicLibrary.RecordSets + + describe "Index" do + test "lists record sets with names and record counts", %{conn: conn} do + {_set, _records} = record_set_with_records(2, %{name: "My Favorites"}) + + conn + |> visit(~p"/record-sets") + |> assert_has("h1", text: "Record Sets") + |> assert_has("h2", text: "My Favorites") + end + + test "shows empty state when no sets exist", %{conn: conn} do + conn + |> visit(~p"/record-sets") + |> assert_has("p", text: "No record sets yet") + end + end + + describe "Search" do + test "filters sets by query", %{conn: conn} do + record_set(%{name: "Road Trip"}) + record_set(%{name: "Unrelated Set"}) + + conn + |> visit(~p"/record-sets?query=Road") + |> assert_has("h2", text: "Road Trip") + |> refute_has("h2", text: "Unrelated Set") + end + end + + describe "Ordering" do + test "switches to alphabetical via URL param", %{conn: conn} do + record_set(%{name: "Zulu Set"}) + record_set(%{name: "Alpha Set"}) + + {:ok, _view, html} = live(conn, ~p"/record-sets?order=alphabetical") + + alpha_pos = :binary.match(html, "Alpha Set") + zulu_pos = :binary.match(html, "Zulu Set") + + assert alpha_pos < zulu_pos + end + end + + describe "Create set" do + test "creates a set with valid data", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/record-sets/new") + + view + |> form("#record-set-form", record_set: %{name: "Brand New Set"}) + |> render_submit() + + assert [set] = RecordSets.search_record_sets("Brand New Set") + assert set.name == "Brand New Set" + end + + test "shows validation errors with invalid data", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/record-sets/new") + + html = + view + |> form("#record-set-form", record_set: %{name: ""}) + |> render_change() + + assert html =~ "can't be blank" + end + end + + describe "Edit set" do + test "updates set with valid data", %{conn: conn} do + set = record_set(%{name: "Old Name"}) + + {:ok, view, _html} = live(conn, ~p"/record-sets/#{set}/edit") + + view + |> form("#record-set-form", record_set: %{name: "Updated Name"}) + |> render_submit() + + updated = RecordSets.get_record_set!(set.id) + assert updated.name == "Updated Name" + end + end + + describe "Delete set" do + test "deletes a set from the listing", %{conn: conn} do + set = record_set(%{name: "To Delete"}) + + {:ok, view, _html} = live(conn, ~p"/record-sets") + + view + |> element("button[phx-click='delete_set'][phx-value-id='#{set.id}']") + |> render_click() + + refute has_element?(view, "h2", "To Delete") + assert_raise Ecto.NoResultsError, fn -> RecordSets.get_record_set!(set.id) end + end + end + + describe "Remove record from set" do + test "removes a record from the set", %{conn: conn} do + {set, [r1 | _]} = record_set_with_records(2) + + {:ok, view, _html} = live(conn, ~p"/record-sets") + + view + |> element( + "button[phx-click='remove_record'][phx-value-set-id='#{set.id}'][phx-value-record-id='#{r1.id}']" + ) + |> render_click() + + updated = RecordSets.get_record_set!(set.id) + refute Enum.any?(updated.items, &(&1.record.id == r1.id)) + end + end + + describe "Reorder records" do + test "moves a record left (up)", %{conn: conn} do + {set, [r1, r2 | _]} = record_set_with_records(3) + + {:ok, view, _html} = live(conn, ~p"/record-sets") + + view + |> element( + "button[phx-click='move_up'][phx-value-set-id='#{set.id}'][phx-value-record-id='#{r2.id}']" + ) + |> render_click() + + updated = RecordSets.get_record_set!(set.id) + ids_in_order = Enum.map(updated.items, & &1.record.id) + assert Enum.at(ids_in_order, 0) == r2.id + assert Enum.at(ids_in_order, 1) == r1.id + end + + test "moves a record right (down)", %{conn: conn} do + {set, [r1, r2 | _]} = record_set_with_records(3) + + {:ok, view, _html} = live(conn, ~p"/record-sets") + + view + |> element( + "button[phx-click='move_down'][phx-value-set-id='#{set.id}'][phx-value-record-id='#{r1.id}']" + ) + |> render_click() + + updated = RecordSets.get_record_set!(set.id) + ids_in_order = Enum.map(updated.items, & &1.record.id) + assert Enum.at(ids_in_order, 0) == r2.id + assert Enum.at(ids_in_order, 1) == r1.id + end + end +end diff --git a/test/support/fixtures/music_library/online_store_templates.ex b/test/support/fixtures/music_library/online_store_templates.ex new file mode 100644 index 00000000..8a1ad057 --- /dev/null +++ b/test/support/fixtures/music_library/online_store_templates.ex @@ -0,0 +1,24 @@ +defmodule MusicLibrary.Fixtures.OnlineStoreTemplates do + @moduledoc """ + This module defines test helpers for creating + entities via the `MusicLibrary.OnlineStoreTemplates` context. + """ + + alias MusicLibrary.OnlineStoreTemplates + + def online_store_template(attrs \\ %{}) do + n = System.unique_integer([:positive]) + + {:ok, template} = + attrs + |> Enum.into(%{ + name: "Store #{n}", + description: "A test store template", + url_template: "https://example.com/search?q={artist}+{title}+{format}", + enabled: true + }) + |> OnlineStoreTemplates.create_template() + + template + end +end diff --git a/test/support/fixtures/music_library/record_sets.ex b/test/support/fixtures/music_library/record_sets.ex new file mode 100644 index 00000000..15ba8c8f --- /dev/null +++ b/test/support/fixtures/music_library/record_sets.ex @@ -0,0 +1,35 @@ +defmodule MusicLibrary.Fixtures.RecordSets do + @moduledoc """ + This module defines test helpers for creating + entities via the `MusicLibrary.RecordSets` context. + """ + + alias MusicLibrary.RecordSets + + def record_set(attrs \\ %{}) do + {:ok, record_set} = + attrs + |> Enum.into(%{ + name: "Set #{System.unique_integer([:positive])}", + description: "A test record set" + }) + |> RecordSets.create_record_set() + + record_set + end + + def record_set_with_records(n, attrs \\ %{}) do + import MusicLibrary.Fixtures.Records, only: [record: 1] + + set = record_set(attrs) + + records = + Enum.map(1..n, fn _ -> + rec = record(%{}) + {:ok, _} = RecordSets.add_record_to_set(set, rec.id) + rec + end) + + {RecordSets.get_record_set!(set.id), records} + end +end