Simplify import logic and add relevant tests
Import directly redirects to the record - previous version was buggy and worked completely by chance. In addition, this commit adds extensive tests around importing a record via use of mocks.
This commit is contained in:
@@ -33,7 +33,10 @@ defmodule MusicLibraryWeb.RecordLive.ImportComponent do
|
||||
|
||||
defp result(assigns) do
|
||||
~H"""
|
||||
<li class="flex justify-between gap-x-6 py-5 hover:bg-gray-50">
|
||||
<li
|
||||
id={"music_brainz_" <> @release_group.id}
|
||||
class="flex justify-between gap-x-6 py-5 hover:bg-gray-50"
|
||||
>
|
||||
<div class="flex min-w-0 gap-x-4">
|
||||
<div class="min-w-0 flex-auto">
|
||||
<p class="text-sm font-semibold leading-6 text-gray-900">
|
||||
|
||||
@@ -78,10 +78,6 @@ defmodule MusicLibraryWeb.RecordLive.Index do
|
||||
{:noreply, stream_insert(socket, :records, record)}
|
||||
end
|
||||
|
||||
def handle_info({__MODULE__, {:saved, record}}, socket) do
|
||||
{:noreply, push_navigate(socket, to: ~p"/records/#{record}")}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("delete", %{"id" => id}, socket) do
|
||||
record = Records.get_record!(id)
|
||||
@@ -103,12 +99,10 @@ defmodule MusicLibraryWeb.RecordLive.Index do
|
||||
def handle_event("import", %{"id" => musicbrainz_id, "format" => format}, socket) do
|
||||
case Records.import_from_musicbrainz(musicbrainz_id, format: format) do
|
||||
{:ok, record} ->
|
||||
notify_parent({:saved, record})
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Record imported successfully")
|
||||
|> push_patch(to: ~p"/records")}
|
||||
|> push_navigate(to: ~p"/records/#{record.id}")}
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, assign(socket, form: to_form(changeset))}
|
||||
@@ -143,8 +137,6 @@ defmodule MusicLibraryWeb.RecordLive.Index do
|
||||
String.to_integer(value)
|
||||
end
|
||||
|
||||
defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
|
||||
|
||||
defp musicbrainz_url(record) do
|
||||
"https://musicbrainz.org/release-group/#{record.musicbrainz_id}"
|
||||
end
|
||||
|
||||
@@ -3,8 +3,11 @@ defmodule MusicLibraryWeb.RecordIndexTest do
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
import MusicLibrary.RecordsFixtures
|
||||
import Mox
|
||||
alias MusicLibrary.Records.Record
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
defp create_records(_) do
|
||||
records = Enum.map(1..30, fn _ -> record_fixture() end)
|
||||
%{records: records}
|
||||
@@ -151,4 +154,184 @@ defmodule MusicLibraryWeb.RecordIndexTest do
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "Importing a new record" do
|
||||
test "it shows the import modal", %{conn: conn} do
|
||||
{:ok, index_live, _html} = live(conn, ~p"/records")
|
||||
|
||||
assert index_live
|
||||
|> element("a", "Import from MusicBrainz")
|
||||
|> render_click() =~ "Search for a record on MusicBrainz"
|
||||
|
||||
assert_patch(index_live, ~p"/records/import")
|
||||
end
|
||||
|
||||
test "it imports a record when selected", %{conn: conn} do
|
||||
{:ok, import_live, _html} = live(conn, ~p"/records/import")
|
||||
|
||||
mock_results =
|
||||
[
|
||||
%{
|
||||
id: "20790e26-98e4-3ad3-a67f-b674758b942d",
|
||||
type: :album,
|
||||
title: "Marbles",
|
||||
artists: "Marillion",
|
||||
release: "2004-05-03"
|
||||
},
|
||||
%{
|
||||
id: "bf20ac32-a793-3bb4-beff-f7b9bffaca38",
|
||||
type: :album,
|
||||
title: "Marbles Live",
|
||||
artists: "Marillion",
|
||||
release: "2005-10-24"
|
||||
}
|
||||
]
|
||||
|
||||
expect(APIBehaviourMock, :search_release_group, fn "Marillion Marbles",
|
||||
limit: 10,
|
||||
offset: 0 ->
|
||||
{:ok, mock_results}
|
||||
end)
|
||||
|
||||
assert import_live
|
||||
|> element("#import_form")
|
||||
|> render_change(%{mb_query: "Marillion Marbles"})
|
||||
|
||||
updated_list = import_live |> render()
|
||||
|
||||
for result <- mock_results do
|
||||
assert updated_list =~ result.title
|
||||
assert updated_list =~ result.release
|
||||
assert updated_list =~ result.artists
|
||||
end
|
||||
|
||||
first_result = hd(mock_results)
|
||||
first_result_id = first_result.id
|
||||
|
||||
expect(APIBehaviourMock, :get_release_group, fn ^first_result_id ->
|
||||
release_group = %{
|
||||
"artist-credit" => [
|
||||
%{
|
||||
"artist" => %{
|
||||
"disambiguation" => "British progressive rock band",
|
||||
"genres" => [
|
||||
%{
|
||||
"count" => 10,
|
||||
"disambiguation" => "",
|
||||
"id" => "ae9b8279-3959-48d8-8a88-741a7f6d4a48",
|
||||
"name" => "progressive rock"
|
||||
}
|
||||
],
|
||||
"id" => "1932f5b6-0b7b-4050-b1df-833ca89e5f44",
|
||||
"name" => "Marillion",
|
||||
"sort-name" => "Marillion",
|
||||
"type" => "Group",
|
||||
"type-id" => "e431f5f6-b5d2-343d-8b36-72607fffb74b"
|
||||
},
|
||||
"joinphrase" => "",
|
||||
"name" => "Marillion"
|
||||
}
|
||||
],
|
||||
"disambiguation" => "",
|
||||
"first-release-date" => "2004-05-03",
|
||||
"genres" => [
|
||||
%{
|
||||
"count" => 1,
|
||||
"disambiguation" => "",
|
||||
"id" => "ceeaa283-5d7b-4202-8d1d-e25d116b2a18",
|
||||
"name" => "alternative rock"
|
||||
},
|
||||
%{
|
||||
"count" => 1,
|
||||
"disambiguation" => "",
|
||||
"id" => "b7ef058e-6d83-4ca4-8123-9724bff4648b",
|
||||
"name" => "art rock"
|
||||
},
|
||||
%{
|
||||
"count" => 1,
|
||||
"disambiguation" => "",
|
||||
"id" => "150eb95a-7739-4fde-a5fe-b62ca576a928",
|
||||
"name" => "baroque pop"
|
||||
},
|
||||
%{
|
||||
"count" => 1,
|
||||
"disambiguation" => "",
|
||||
"id" => "797e2e85-5ffd-495c-a757-8b4079052f0e",
|
||||
"name" => "pop rock"
|
||||
},
|
||||
%{
|
||||
"count" => 2,
|
||||
"disambiguation" => "",
|
||||
"id" => "ae9b8279-3959-48d8-8a88-741a7f6d4a48",
|
||||
"name" => "progressive rock"
|
||||
},
|
||||
%{
|
||||
"count" => 1,
|
||||
"disambiguation" => "",
|
||||
"id" => "2aeb5340-c474-4677-b9a6-35ddac9b6a58",
|
||||
"name" => "psychedelic pop"
|
||||
},
|
||||
%{
|
||||
"count" => 2,
|
||||
"disambiguation" => "",
|
||||
"id" => "0e3fc579-2d24-4f20-9dae-736e1ec78798",
|
||||
"name" => "rock"
|
||||
}
|
||||
],
|
||||
"id" => "20790e26-98e4-3ad3-a67f-b674758b942d",
|
||||
"primary-type" => "Album",
|
||||
"primary-type-id" => "f529b476-6e62-324f-b0aa-1f3e33d313fc",
|
||||
"secondary-type-ids" => [],
|
||||
"secondary-types" => [],
|
||||
"title" => "Marbles"
|
||||
}
|
||||
|
||||
{:ok, release_group}
|
||||
end)
|
||||
|
||||
cover_data = File.read!(marbles_cover_fixture())
|
||||
|
||||
expect(APIBehaviourMock, :get_cover_art, fn ^first_result_id ->
|
||||
{:ok, cover_data}
|
||||
end)
|
||||
|
||||
import_live
|
||||
|> element("#music_brainz_#{first_result_id} button", "CD")
|
||||
|> render_click()
|
||||
|
||||
[record] = MusicLibrary.Repo.all(MusicLibrary.Records.Record)
|
||||
|
||||
assert record.musicbrainz_id == first_result_id
|
||||
assert record.title == "Marbles"
|
||||
assert record.release == "2004-05-03"
|
||||
assert record.format == :cd
|
||||
|
||||
assert record.genres == [
|
||||
"alternative rock",
|
||||
"art rock",
|
||||
"baroque pop",
|
||||
"pop rock",
|
||||
"progressive rock",
|
||||
"psychedelic pop",
|
||||
"rock"
|
||||
]
|
||||
|
||||
assert record.cover_hash ==
|
||||
"599407DDF69907D4A60FE13CCAA824D25CF08DC124FD6AA3E8E7ECD98C885FFE"
|
||||
|
||||
assert record.cover_data == cover_data
|
||||
|
||||
[marillion] = record.artists
|
||||
|
||||
assert %MusicLibrary.Records.Record.Artist{
|
||||
id: _,
|
||||
name: "Marillion",
|
||||
sort_name: "Marillion",
|
||||
disambiguation: "British progressive rock band",
|
||||
musicbrainz_id: "1932f5b6-0b7b-4050-b1df-833ca89e5f44"
|
||||
} = marillion
|
||||
|
||||
assert_redirect(import_live, ~p"/records/#{record.id}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
Mox.defmock(APIBehaviourMock, for: MusicLibrary.Records.MusicBrainz.APIBehaviour)
|
||||
Application.put_env(:music_library, :music_brainz, APIBehaviourMock)
|
||||
|
||||
ExUnit.start()
|
||||
Ecto.Adapters.SQL.Sandbox.mode(MusicLibrary.Repo, :manual)
|
||||
|
||||
Reference in New Issue
Block a user