Remove mox in favour of built-in Req stubs

This commit is contained in:
Claudio Ortolina
2025-02-28 16:38:11 +00:00
parent 8aa283cb84
commit a218942110
16 changed files with 844 additions and 195 deletions
+1 -3
View File
@@ -33,9 +33,7 @@ config :music_library, LastFm,
api_key: "change me", api_key: "change me",
user_agent: user_agent user_agent: user_agent
config :music_library, MusicBrainz, config :music_library, MusicBrainz, user_agent: user_agent
api: MusicBrainz.APIImpl,
user_agent: user_agent
# Configure esbuild (the version is required) # Configure esbuild (the version is required)
config :esbuild, config :esbuild,
+6
View File
@@ -42,4 +42,10 @@ config :music_library, LastFm,
max_retries: 0 max_retries: 0
] ]
config :music_library, MusicBrainz,
req_options: [
plug: {Req.Test, MusicBrainz.API},
max_retries: 0
]
config :phoenix_test, :endpoint, MusicLibraryWeb.Endpoint config :phoenix_test, :endpoint, MusicLibraryWeb.Endpoint
+8 -6
View File
@@ -1,9 +1,11 @@
defmodule MusicBrainz do defmodule MusicBrainz do
alias MusicBrainz.API
def search_release_group(query, opts \\ []) do def search_release_group(query, opts \\ []) do
limit = Keyword.get(opts, :limit, 20) limit = Keyword.get(opts, :limit, 20)
offset = Keyword.get(opts, :offset, 0) offset = Keyword.get(opts, :offset, 0)
music_brainz_config().api.search_release_group( API.search_release_group(
query, query,
[limit: limit, offset: offset], [limit: limit, offset: offset],
music_brainz_config() music_brainz_config()
@@ -11,23 +13,23 @@ defmodule MusicBrainz do
end end
def get_release_group(musicbrainz_id) do def get_release_group(musicbrainz_id) do
music_brainz_config().api.get_release_group(musicbrainz_id, music_brainz_config()) API.get_release_group(musicbrainz_id, music_brainz_config())
end end
def get_releases(musicbrainz_id, opts) do def get_releases(musicbrainz_id, opts) do
music_brainz_config().api.get_releases(musicbrainz_id, opts, music_brainz_config()) API.get_releases(musicbrainz_id, opts, music_brainz_config())
end end
def get_release(musicbrainz_id) do def get_release(musicbrainz_id) do
music_brainz_config().api.get_release(musicbrainz_id, music_brainz_config()) API.get_release(musicbrainz_id, music_brainz_config())
end end
def search_release_by_barcode(barcode) do def search_release_by_barcode(barcode) do
music_brainz_config().api.search_release_by_barcode(barcode, music_brainz_config()) API.search_release_by_barcode(barcode, music_brainz_config())
end end
def get_cover_art(id_or_url) do def get_cover_art(id_or_url) do
music_brainz_config().api.get_cover_art(id_or_url, music_brainz_config()) API.get_cover_art(id_or_url, music_brainz_config())
end end
defp music_brainz_config, do: MusicBrainz.Config.resolve(:music_library) defp music_brainz_config, do: MusicBrainz.Config.resolve(:music_library)
@@ -1,4 +1,4 @@
defmodule MusicBrainz.APIImpl do defmodule MusicBrainz.API do
@moduledoc """ @moduledoc """
The original data from Obsidian maps records to MusicBrainz release groups, so we can leverage the MusicBrainz API to: The original data from Obsidian maps records to MusicBrainz release groups, so we can leverage the MusicBrainz API to:
@@ -6,8 +6,6 @@ defmodule MusicBrainz.APIImpl do
- Extend the metadata associated with existing records - Extend the metadata associated with existing records
""" """
@behaviour MusicBrainz.APIBehaviour
require Logger require Logger
alias MusicBrainz.{ReleaseGroupSearchResult, ReleaseSearchResult} alias MusicBrainz.{ReleaseGroupSearchResult, ReleaseSearchResult}
@@ -208,7 +206,6 @@ defmodule MusicBrainz.APIImpl do
} }
""" """
@impl true
def get_release_group(id, config) do def get_release_group(id, config) do
config config
|> new_request() |> new_request()
@@ -285,7 +282,6 @@ defmodule MusicBrainz.APIImpl do
"title": "Clark (Soundtrack From the Netflix Series)" "title": "Clark (Soundtrack From the Netflix Series)"
} }
""" """
@impl true
def get_release(id, config) do def get_release(id, config) do
config config
|> new_request() |> new_request()
@@ -299,7 +295,6 @@ defmodule MusicBrainz.APIImpl do
|> get_request() |> get_request()
end end
@impl true
def get_releases(release_group_id, opts, config) do def get_releases(release_group_id, opts, config) do
Keyword.validate!(opts, [:limit, :offset]) Keyword.validate!(opts, [:limit, :offset])
@@ -319,7 +314,6 @@ defmodule MusicBrainz.APIImpl do
|> get_request() |> get_request()
end end
@impl true
def search_release_by_barcode(barcode, config) do def search_release_by_barcode(barcode, config) do
config config
|> new_request() |> new_request()
@@ -436,7 +430,6 @@ defmodule MusicBrainz.APIImpl do
] ]
} }
""" """
@impl true
def search_release_group(query, opts, config) do def search_release_group(query, opts, config) do
Keyword.validate!(opts, [:limit, :offset]) Keyword.validate!(opts, [:limit, :offset])
@@ -461,7 +454,6 @@ defmodule MusicBrainz.APIImpl do
@doc """ @doc """
Uses the [cover art](https://musicbrainz.org/doc/Cover_Art_Archive/API) endpoint with the release group id to get the cover image. Uses the [cover art](https://musicbrainz.org/doc/Cover_Art_Archive/API) endpoint with the release group id to get the cover image.
""" """
@impl true
def get_cover_art({:musicbrainz_id, musicbrainz_id}, config) do def get_cover_art({:musicbrainz_id, musicbrainz_id}, config) do
url = "https://coverartarchive.org/release-group/#{musicbrainz_id}/front" url = "https://coverartarchive.org/release-group/#{musicbrainz_id}/front"
@@ -470,6 +462,7 @@ defmodule MusicBrainz.APIImpl do
def get_cover_art({:url, url}, config) do def get_cover_art({:url, url}, config) do
case Req.new(url: url, max_retries: 1, user_agent: config.user_agent) case Req.new(url: url, max_retries: 1, user_agent: config.user_agent)
|> Req.Request.merge_options(config.req_options)
|> Req.Request.append_request_steps(log_attempt: &log_attempt/1) |> Req.Request.append_request_steps(log_attempt: &log_attempt/1)
|> Req.Request.append_response_steps(log_error: &log_error/1) |> Req.Request.append_response_steps(log_error: &log_error/1)
|> get_request() do |> get_request() do
@@ -484,6 +477,7 @@ defmodule MusicBrainz.APIImpl do
max_retries: 1, max_retries: 1,
user_agent: config.user_agent user_agent: config.user_agent
) )
|> Req.Request.merge_options(config.req_options)
|> Req.Request.append_request_steps(log_attempt: &log_attempt/1) |> Req.Request.append_request_steps(log_attempt: &log_attempt/1)
end end
-20
View File
@@ -1,20 +0,0 @@
defmodule MusicBrainz.APIBehaviour do
@type musicbrainz_id :: String.t()
@type config :: MusicBrainz.Config.t()
@type limit :: pos_integer()
@type barcode :: String.t()
@callback get_release_group(musicbrainz_id, config) :: {:ok, map()} | {:error, String.t()}
@callback get_releases(musicbrainz_id, limit, config) :: {:ok, map()} | {:error, String.t()}
@callback get_release(musicbrainz_id, config) :: {:ok, map()} | {:error, String.t()}
@callback search_release_group(String.t(), Keyword.t(), config) ::
{:ok, [map()]} | {:error, String.t()}
@callback search_release_by_barcode(barcode, config) :: {:ok, [map()]} | {:error, String.t()}
@callback get_cover_art({:musicbrainz_id, musicbrainz_id()} | {:url, String.t()}, config) ::
{:ok, binary()} | {:error, String.t()}
end
+10 -9
View File
@@ -1,22 +1,23 @@
defmodule MusicBrainz.Config do defmodule MusicBrainz.Config do
@type t :: %__MODULE__{ @type t :: %__MODULE__{
api: module(), user_agent: String.t(),
user_agent: String.t() req_options: Keyword.t()
} }
@enforce_keys [:api, :user_agent] @enforce_keys [:user_agent]
defstruct api: MusicBrainz.APIImpl, defstruct user_agent: "change me",
user_agent: "change me" req_options: []
@schema NimbleOptions.new!( @schema NimbleOptions.new!(
api: [
type: :atom,
required: true
],
user_agent: [ user_agent: [
type: :string, type: :string,
required: false, required: false,
default: "change me" default: "change me"
],
req_options: [
type: :keyword_list,
required: false,
default: []
] ]
) )
-1
View File
@@ -85,7 +85,6 @@ defmodule MusicLibrary.MixProject do
# Test tooling # Test tooling
{:phoenix_test, "~> 0.5.1", only: :test}, {:phoenix_test, "~> 0.5.1", only: :test},
{:floki, ">= 0.30.0", only: :test}, {:floki, ">= 0.30.0", only: :test},
{:mox, "~> 1.2", only: :test},
# Prod error/perf tooling # Prod error/perf tooling
{:phoenix_live_dashboard, "~> 0.8.3"}, {:phoenix_live_dashboard, "~> 0.8.3"},
-2
View File
@@ -26,9 +26,7 @@
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
"mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"},
"mox": {:hex, :mox, "1.2.0", "a2cd96b4b80a3883e3100a221e8adc1b98e4c3a332a8fc434c39526babafd5b3", [:mix], [{:nimble_ownership, "~> 1.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}], "hexpm", "c7b92b3cc69ee24a7eeeaf944cd7be22013c52fcb580c1f33f50845ec821089a"},
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
"nimble_ownership": {:hex, :nimble_ownership, "1.0.1", "f69fae0cdd451b1614364013544e66e4f5d25f36a2056a9698b793305c5aa3a6", [:mix], [], "hexpm", "3825e461025464f519f3f3e4a1f9b68c47dc151369611629ad08b636b73bb22d"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"},
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
"phoenix": {:hex, :phoenix, "1.7.20", "6bababaf27d59f5628f9b608de902a021be2cecefb8231e1dbdc0a2e2e480e9b", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "6be2ab98302e8784a31829e0d50d8bdfa81a23cd912c395bafd8b8bfb5a086c2"}, "phoenix": {:hex, :phoenix, "1.7.20", "6bababaf27d59f5628f9b608de902a021be2cecefb8231e1dbdc0a2e2e480e9b", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "6be2ab98302e8784a31829e0d50d8bdfa81a23cd912c395bafd8b8bfb5a086c2"},
+15 -12
View File
@@ -1,22 +1,22 @@
defmodule MusicBrainzTest do defmodule MusicBrainzTest do
use ExUnit.Case, async: true use ExUnit.Case, async: true
alias MusicBrainz.{APIMock, ReleaseSearchResult} alias MusicBrainz.ReleaseGroupSearchResult
import MusicBrainz.Fixtures.Release import MusicBrainz.Fixtures.Release
import MusicBrainz.Fixtures.ReleaseGroup import MusicBrainz.Fixtures.ReleaseGroup
import Mox
setup :verify_on_exit!
describe "search_release_group/2" do describe "search_release_group/2" do
test "it returns results with correct limit and offset" do test "it returns results with correct limit and offset" do
mock_results = release_group_search_results() results = release_group_search_results()
expect(APIMock, :search_release_group, fn "Marillion", [limit: 20, offset: 10], _config -> expected_results =
{:ok, mock_results} Enum.map(results["release-groups"], &ReleaseGroupSearchResult.from_api_response/1)
Req.Test.stub(MusicBrainz.API, fn conn ->
Req.Test.json(conn, results)
end) end)
assert {:ok, mock_results} == assert {:ok, expected_results} ==
MusicBrainz.search_release_group("Marillion", limit: 20, offset: 10) MusicBrainz.search_release_group("Marillion", limit: 20, offset: 10)
end end
end end
@@ -24,13 +24,16 @@ defmodule MusicBrainzTest do
describe "search_release_by_barcode/1" do describe "search_release_by_barcode/1" do
test "it returns releases belonging to the same release group" do test "it returns releases belonging to the same release group" do
barcode = "5052205070023" barcode = "5052205070023"
releases = releases(:queen_greatest_hits)
expect(APIMock, :search_release_by_barcode, fn ^barcode, _config -> releases =
{:ok, Enum.map(releases, &ReleaseSearchResult.from_api_response/1)} releases(:queen_greatest_hits)
Req.Test.stub(MusicBrainz.API, fn conn ->
Req.Test.json(conn, releases)
end) end)
assert {:ok, results} = MusicBrainz.search_release_by_barcode(barcode) assert {:ok, results} =
MusicBrainz.search_release_by_barcode(barcode)
assert Enum.all?(results, fn result -> assert Enum.all?(results, fn result ->
result.release_group.id == "69ce61c8-127f-3809-95d8-62fdf3ae1347" && result.release_group.id == "69ce61c8-127f-3809-95d8-62fdf3ae1347" &&
+34 -37
View File
@@ -1,15 +1,11 @@
defmodule MusicLibrary.RecordsTest do defmodule MusicLibrary.RecordsTest do
use MusicLibrary.DataCase use MusicLibrary.DataCase
alias MusicBrainz.APIMock
alias MusicLibrary.Records alias MusicLibrary.Records
alias MusicLibrary.Records.SearchIndex alias MusicLibrary.Records.SearchIndex
import MusicLibrary.Fixtures.Records import MusicLibrary.Fixtures.Records
import MusicBrainz.Fixtures.ReleaseGroup import MusicBrainz.Fixtures.ReleaseGroup
import MusicBrainz.Fixtures.Release import MusicBrainz.Fixtures.Release
import Mox
setup :verify_on_exit!
defp create_records(_) do defp create_records(_) do
records = [ records = [
@@ -63,12 +59,14 @@ defmodule MusicLibrary.RecordsTest do
assert record.release_ids == [] assert record.release_ids == []
assert record.included_release_group_ids == [] assert record.included_release_group_ids == []
expect(APIMock, :get_release_group, fn ^release_group_id, _config -> Req.Test.stub(MusicBrainz.API, fn conn ->
{:ok, release_group(:lockdown_trilogy)} case conn.path_info do
end) [_ws, _version, "release-group", ^release_group_id] ->
Req.Test.json(conn, release_group(:lockdown_trilogy))
expect(APIMock, :get_releases, fn ^release_group_id, _opts, _config -> [_ws, _version, "release"] ->
{:ok, %{"releases" => release_group(:lockdown_trilogy)["releases"]}} Req.Test.json(conn, %{"releases" => release_group(:lockdown_trilogy)["releases"]})
end
end) end)
{:ok, updated_record} = Records.refresh_musicbrainz_data(record) {:ok, updated_record} = Records.refresh_musicbrainz_data(record)
@@ -189,18 +187,19 @@ defmodule MusicLibrary.RecordsTest do
release_group = release_group(:marbles) release_group = release_group(:marbles)
release_group_id = release_group_id(:marbles) release_group_id = release_group_id(:marbles)
expect(APIMock, :get_release_group, fn ^release_group_id, _config ->
{:ok, release_group}
end)
expect(APIMock, :get_releases, fn ^release_group_id, _opts, _config ->
{:ok, %{"releases" => release_group["releases"]}}
end)
cover_data = File.read!(marbles_cover_fixture()) cover_data = File.read!(marbles_cover_fixture())
expect(APIMock, :get_cover_art, fn {:musicbrainz_id, ^release_group_id}, _config -> Req.Test.stub(MusicBrainz.API, fn conn ->
{:ok, cover_data} case conn.path_info do
[_ws, _version, "release-group", ^release_group_id] ->
Req.Test.json(conn, release_group)
[_ws, _version, "release"] ->
Req.Test.json(conn, %{"releases" => release_group["releases"]})
[_release_group, ^release_group_id, "front"] ->
Plug.Conn.send_resp(conn, 200, cover_data)
end
end) end)
assert {:ok, record} = assert {:ok, record} =
@@ -243,22 +242,22 @@ defmodule MusicLibrary.RecordsTest do
release_group = release_group(:marbles) release_group = release_group(:marbles)
release_group_id = release_group_id(:marbles) release_group_id = release_group_id(:marbles)
expect(APIMock, :get_release, fn ^release_id, _config ->
{:ok, release}
end)
expect(APIMock, :get_release_group, fn ^release_group_id, _config ->
{:ok, release_group}
end)
expect(APIMock, :get_releases, fn ^release_group_id, _opts, _config ->
{:ok, %{"releases" => release_group["releases"]}}
end)
cover_data = File.read!(marbles_cover_fixture()) cover_data = File.read!(marbles_cover_fixture())
expect(APIMock, :get_cover_art, fn {:musicbrainz_id, ^release_group_id}, _config -> Req.Test.stub(MusicBrainz.API, fn conn ->
{:ok, cover_data} case conn.path_info do
[_ws, _version, "release-group", ^release_group_id] ->
Req.Test.json(conn, release_group)
[_ws, _version, "release", ^release_id] ->
Req.Test.json(conn, release)
[_ws, _version, "release"] ->
Req.Test.json(conn, %{"releases" => release_group["releases"]})
[_release_group, ^release_group_id, "front"] ->
Plug.Conn.send_resp(conn, 200, cover_data)
end
end) end)
assert {:ok, record} = assert {:ok, record} =
@@ -297,10 +296,8 @@ defmodule MusicLibrary.RecordsTest do
raven_cover_data = File.read!(raven_cover_fixture()) raven_cover_data = File.read!(raven_cover_fixture())
cover_url = record.cover_url Req.Test.stub(MusicBrainz.API, fn conn ->
Plug.Conn.send_resp(conn, 200, raven_cover_data)
expect(APIMock, :get_cover_art, fn {:url, ^cover_url}, _config ->
{:ok, raven_cover_data}
end) end)
assert {:ok, updated_record} = Records.refresh_cover(record) assert {:ok, updated_record} = Records.refresh_cover(record)
@@ -5,12 +5,9 @@ defmodule MusicLibraryWeb.CollectionLive.IndexTest do
import MusicBrainz.Fixtures.ReleaseGroup import MusicBrainz.Fixtures.ReleaseGroup
import MusicBrainz.Fixtures.Release import MusicBrainz.Fixtures.Release
import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1] import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1]
import Mox alias MusicBrainz.ReleaseGroupSearchResult
alias MusicBrainz.{APIMock, ReleaseSearchResult}
alias MusicLibrary.Records.{Cover, Record} alias MusicLibrary.Records.{Cover, Record}
setup :verify_on_exit!
@default_records_page_size 20 @default_records_page_size 20
@total_records @default_records_page_size + 10 @total_records @default_records_page_size + 10
@@ -243,12 +240,29 @@ defmodule MusicLibraryWeb.CollectionLive.IndexTest do
end end
test "it imports a record when selected", %{conn: conn} do test "it imports a record when selected", %{conn: conn} do
mock_results = release_group_search_results() release_group_search_results = Map.get(release_group_search_results(), "release-groups")
expect(APIMock, :search_release_group, fn "Marillion Marbles", first_release_group_search_result = hd(release_group_search_results)
[limit: 10, offset: 0], first_release_group_search_result_id = first_release_group_search_result["id"]
_config ->
{:ok, mock_results} release_group = release_group(:marbles)
cover_data = File.read!(marbles_cover_fixture())
Req.Test.stub(MusicBrainz.API, fn conn ->
case conn.path_info do
[_ws, _version, "release-group", ^first_release_group_search_result_id] ->
Req.Test.json(conn, release_group)
[_ws, _version, "release-group"] ->
Req.Test.json(conn, release_group_search_results())
[_ws, _version, "release"] ->
Req.Test.json(conn, %{"releases" => release_group["releases"]})
[_release_group, ^first_release_group_search_result_id, "front"] ->
Plug.Conn.send_resp(conn, 200, cover_data)
end
end) end)
session = session =
@@ -256,39 +270,22 @@ defmodule MusicLibraryWeb.CollectionLive.IndexTest do
|> visit(~p"/collection/import") |> visit(~p"/collection/import")
|> fill_in("Search for a record on MusicBrainz", with: "Marillion Marbles") |> fill_in("Search for a record on MusicBrainz", with: "Marillion Marbles")
for result <- mock_results do for release_group_search_result <- release_group_search_results do
result = ReleaseGroupSearchResult.from_api_response(release_group_search_result)
session session
|> assert_has("h1", text: result.artists) |> assert_has("h1", text: result.artists)
|> assert_has("h2", text: result.title) |> assert_has("h2", text: result.title)
|> assert_has("p", text: Record.format_release(result.release)) |> assert_has("p", text: Record.format_release(result.release))
end end
first_result = hd(mock_results)
first_result_id = first_result.id
release_group = release_group(:marbles)
expect(APIMock, :get_release_group, fn ^first_result_id, _config ->
{:ok, release_group}
end)
expect(APIMock, :get_releases, fn ^first_result_id, _opts, _config ->
{:ok, %{"releases" => release_group["releases"]}}
end)
cover_data = File.read!(marbles_cover_fixture())
expect(APIMock, :get_cover_art, fn {:musicbrainz_id, ^first_result_id}, _config ->
{:ok, cover_data}
end)
session = session =
session session
|> click_link("#musicbrainz_#{first_result_id} a", "CD") |> click_link("#musicbrainz_#{first_release_group_search_result_id} a", "CD")
[record] = MusicLibrary.Repo.all(MusicLibrary.Records.Record) [record] = MusicLibrary.Repo.all(MusicLibrary.Records.Record)
assert record.musicbrainz_id == first_result_id assert record.musicbrainz_id == first_release_group_search_result_id
assert record.title == "Marbles" assert record.title == "Marbles"
assert record.release == "2004-05-03" assert record.release == "2004-05-03"
assert record.format == :cd assert record.format == :cd
@@ -352,32 +349,34 @@ defmodule MusicLibraryWeb.CollectionLive.IndexTest do
barcode = "5037300650128" barcode = "5037300650128"
releases = releases(:marbles) releases = releases(:marbles)
expect(APIMock, :search_release_by_barcode, fn ^barcode, _config ->
{:ok, Enum.map(releases, &ReleaseSearchResult.from_api_response/1)}
end)
release = release(:marbles) release = release(:marbles)
release_id = release_id(:marbles) release_id = release_id(:marbles)
expect(APIMock, :get_release, fn ^release_id, _config ->
{:ok, release}
end)
release_group = release_group(:marbles) release_group = release_group(:marbles)
release_group_id = release_group["id"] release_group_id = release_group["id"]
expect(APIMock, :get_release_group, fn ^release_group_id, _config ->
{:ok, release_group}
end)
expect(APIMock, :get_releases, fn ^release_group_id, _opts, _config ->
{:ok, %{"releases" => release_group["releases"]}}
end)
cover_data = File.read!(marbles_cover_fixture()) cover_data = File.read!(marbles_cover_fixture())
expect(APIMock, :get_cover_art, fn {:musicbrainz_id, ^release_group_id}, _config -> Req.Test.stub(MusicBrainz.API, fn conn ->
{:ok, cover_data} case conn.path_info do
[_ws, _version, "release-group", ^release_group_id] ->
Req.Test.json(conn, release_group)
[_ws, _version, "release", ^release_id] ->
Req.Test.json(conn, release)
[_ws, _version, "release"] ->
if conn.params["query"] do
# barcode scan
Req.Test.json(conn, releases)
else
# Search by release group ID
Req.Test.json(conn, %{"releases" => release_group["releases"]})
end
[_release_group, ^release_group_id, "front"] ->
Plug.Conn.send_resp(conn, 200, cover_data)
end
end) end)
conn conn
@@ -1,15 +1,11 @@
defmodule MusicLibraryWeb.StatsLive.IndexTest do defmodule MusicLibraryWeb.StatsLive.IndexTest do
use MusicLibraryWeb.ConnCase use MusicLibraryWeb.ConnCase
alias MusicBrainz.APIMock
alias MusicLibrary.{Records, Repo, Wishlist} alias MusicLibrary.{Records, Repo, Wishlist}
import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1] import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1]
import MusicLibrary.Fixtures.Records import MusicLibrary.Fixtures.Records
import MusicBrainz.Fixtures.ReleaseGroup import MusicBrainz.Fixtures.ReleaseGroup
import MusicBrainz.Fixtures.Release import MusicBrainz.Fixtures.Release
import Mox
setup :verify_on_exit!
defp fill_collection(_) do defp fill_collection(_) do
records = Enum.map(1..19, fn _ -> record() end) records = Enum.map(1..19, fn _ -> record() end)
@@ -186,23 +182,22 @@ defmodule MusicLibraryWeb.StatsLive.IndexTest do
release_group = release_group(:mystery_of_time) release_group = release_group(:mystery_of_time)
release_group_id = release_group_id(:mystery_of_time) release_group_id = release_group_id(:mystery_of_time)
expect(APIMock, :get_release, fn ^release_id, _config ->
{:ok, release}
end)
expect(APIMock, :get_release_group, fn ^release_group_id, _config ->
{:ok, release_group}
end)
expect(APIMock, :get_releases, fn ^release_group_id, _opts, _config ->
{:ok, %{"releases" => release_group["releases"]}}
end)
# Doesn't matter if we use a different cover
cover_data = File.read!(marbles_cover_fixture()) cover_data = File.read!(marbles_cover_fixture())
expect(APIMock, :get_cover_art, fn {:musicbrainz_id, ^release_group_id}, _config -> Req.Test.stub(MusicBrainz.API, fn conn ->
{:ok, cover_data} case conn.path_info do
[_ws, _version, "release-group", ^release_group_id] ->
Req.Test.json(conn, release_group)
[_ws, _version, "release", ^release_id] ->
Req.Test.json(conn, release)
[_ws, _version, "release"] ->
Req.Test.json(conn, %{"releases" => release_group["releases"]})
[_release_group, ^release_group_id, "front"] ->
Plug.Conn.send_resp(conn, 200, cover_data)
end
end) end)
assert [] == Wishlist.search_records("mbid:#{release_group_id}") assert [] == Wishlist.search_records("mbid:#{release_group_id}")
@@ -5,14 +5,12 @@ defmodule MusicBrainz.Fixtures.Release do
Path.join([@fixtures_folder, "releases - queen - greatest hits.json"]) Path.join([@fixtures_folder, "releases - queen - greatest hits.json"])
|> File.read!() |> File.read!()
|> Jason.decode!() |> Jason.decode!()
|> Map.get("releases")
end end
def releases(:marbles) do def releases(:marbles) do
Path.join([@fixtures_folder, "releases - marillion - marbles.json"]) Path.join([@fixtures_folder, "releases - marillion - marbles.json"])
|> File.read!() |> File.read!()
|> Jason.decode!() |> Jason.decode!()
|> Map.get("releases")
end end
def release(:mystery_of_time) do def release(:mystery_of_time) do
@@ -1,25 +1,10 @@
defmodule MusicBrainz.Fixtures.ReleaseGroup do defmodule MusicBrainz.Fixtures.ReleaseGroup do
@fixtures_folder Path.join([File.cwd!(), "test/support/fixtures/music_brainz"]) @fixtures_folder Path.join([File.cwd!(), "test/support/fixtures/music_brainz"])
alias MusicBrainz.ReleaseGroupSearchResult
def release_group_search_results do def release_group_search_results do
[ Path.join([@fixtures_folder, "release_group_search_results - marillion marbles.json"])
%ReleaseGroupSearchResult{ |> File.read!()
id: "20790e26-98e4-3ad3-a67f-b674758b942d", |> JSON.decode!()
type: :album,
title: "Marbles",
artists: "Marillion",
release: "2004-05-03"
},
%ReleaseGroupSearchResult{
id: "bf20ac32-a793-3bb4-beff-f7b9bffaca38",
type: :album,
title: "Marbles Live",
artists: "Marillion",
release: "2005-10-24"
}
]
end end
def release_group(:mystery_of_time) do def release_group(:mystery_of_time) do
@@ -0,0 +1,702 @@
{
"created": "2025-02-28T11:35:03.807Z",
"count": 437,
"offset": 0,
"release-groups": [
{
"id": "20790e26-98e4-3ad3-a67f-b674758b942d",
"type-id": "f529b476-6e62-324f-b0aa-1f3e33d313fc",
"score": 100,
"primary-type-id": "f529b476-6e62-324f-b0aa-1f3e33d313fc",
"count": 10,
"title": "Marbles",
"first-release-date": "2004-05-03",
"primary-type": "Album",
"artist-credit": [
{
"name": "Marillion",
"artist": {
"id": "1932f5b6-0b7b-4050-b1df-833ca89e5f44",
"name": "Marillion",
"sort-name": "Marillion",
"disambiguation": "British progressive rock band",
"aliases": [
{
"sort-name": "Trios Marillos, Los",
"name": "Los Trios Marillos",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Skyline Drifters",
"name": "Skyline Drifters",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Low Fat Yoghurts",
"name": "Low Fat Yoghurts",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
}
]
}
}
],
"releases": [
{
"id": "3f89357a-eeb3-4040-af34-a27b7c2aea2b",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "0e290154-5375-4f4f-a658-4a92bf02faa5",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "f3937bc5-b99f-443a-9609-a404201f21ca",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "d3f9b9e2-73f5-4b47-a2a7-2c2199aad608",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "4b9fe13b-4837-4c02-9368-e97ba6f5a086",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "3f1cc80f-4507-48a9-899c-c1bda83280c2",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "a4b02377-0b5e-448e-9cd6-5500c0378523",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "ab151aa6-7538-4e93-be60-eded52b5b7b7",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "b94bbd1f-ae5d-4e7b-98ff-28bfe135f20c",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "2c4ecd84-7a84-4f42-a600-2f00ed8978c9",
"status-id": "1156806e-d06a-38bd-83f0-cf2284a808b9",
"title": "Marbles",
"status": "Bootleg"
}
],
"tags": [
{
"count": 2,
"name": "rock"
},
{
"count": 1,
"name": "alternative rock"
},
{
"count": 2,
"name": "progressive rock"
},
{
"count": 1,
"name": "art rock"
},
{
"count": 1,
"name": "baroque pop"
},
{
"count": 1,
"name": "psychedelic pop"
},
{
"count": 1,
"name": "pop rock"
}
]
},
{
"id": "bf20ac32-a793-3bb4-beff-f7b9bffaca38",
"type-id": "6fd474e2-6b58-3102-9d17-d6f7eb7da0a0",
"score": 90,
"primary-type-id": "f529b476-6e62-324f-b0aa-1f3e33d313fc",
"count": 1,
"title": "Marbles Live",
"first-release-date": "2005-10-24",
"primary-type": "Album",
"secondary-types": [
"Live"
],
"secondary-type-ids": [
"6fd474e2-6b58-3102-9d17-d6f7eb7da0a0"
],
"artist-credit": [
{
"name": "Marillion",
"artist": {
"id": "1932f5b6-0b7b-4050-b1df-833ca89e5f44",
"name": "Marillion",
"sort-name": "Marillion",
"disambiguation": "British progressive rock band",
"aliases": [
{
"sort-name": "Skyline Drifters",
"name": "Skyline Drifters",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Low Fat Yoghurts",
"name": "Low Fat Yoghurts",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Trios Marillos, Los",
"name": "Los Trios Marillos",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
}
]
}
}
],
"releases": [
{
"id": "bdc6ee20-edd8-4a74-8666-f6f90a67a36a",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles Live",
"status": "Official"
}
],
"tags": [
{
"count": 1,
"name": "rock"
}
]
},
{
"id": "ea42b213-0502-391b-bb51-e2ef6315b300",
"type-id": "dd2a21e1-0c00-3729-a7a0-de60b84eb5d1",
"score": 77,
"primary-type-id": "f529b476-6e62-324f-b0aa-1f3e33d313fc",
"count": 1,
"title": "A Handful of Marbles",
"first-release-date": "2005-06",
"primary-type": "Album",
"secondary-types": [
"Compilation"
],
"secondary-type-ids": [
"dd2a21e1-0c00-3729-a7a0-de60b84eb5d1"
],
"artist-credit": [
{
"name": "Marillion",
"artist": {
"id": "1932f5b6-0b7b-4050-b1df-833ca89e5f44",
"name": "Marillion",
"sort-name": "Marillion",
"disambiguation": "British progressive rock band",
"aliases": [
{
"sort-name": "Low Fat Yoghurts",
"name": "Low Fat Yoghurts",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Skyline Drifters",
"name": "Skyline Drifters",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Trios Marillos, Los",
"name": "Los Trios Marillos",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
}
]
}
}
],
"releases": [
{
"id": "09bbc223-0c47-4074-ac8e-a619407d1ab2",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "A Handful of Marbles",
"status": "Official"
}
],
"tags": [
{
"count": 1,
"name": "rock"
},
{
"count": 1,
"name": "alternative rock"
}
]
},
{
"id": "134154a8-4c48-4185-b515-831b01164a68",
"type-id": "6fd474e2-6b58-3102-9d17-d6f7eb7da0a0",
"score": 77,
"primary-type-id": "f529b476-6e62-324f-b0aa-1f3e33d313fc",
"count": 2,
"title": "Marbles on the Road",
"first-release-date": "2004",
"primary-type": "Album",
"secondary-types": [
"Live"
],
"secondary-type-ids": [
"6fd474e2-6b58-3102-9d17-d6f7eb7da0a0"
],
"artist-credit": [
{
"name": "Marillion",
"artist": {
"id": "1932f5b6-0b7b-4050-b1df-833ca89e5f44",
"name": "Marillion",
"sort-name": "Marillion",
"disambiguation": "British progressive rock band",
"aliases": [
{
"sort-name": "Trios Marillos, Los",
"name": "Los Trios Marillos",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Skyline Drifters",
"name": "Skyline Drifters",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Low Fat Yoghurts",
"name": "Low Fat Yoghurts",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
}
]
}
}
],
"releases": [
{
"id": "f23430e9-cc04-42e0-a697-92f0b802c9c1",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles on the Road",
"status": "Official"
},
{
"id": "480ec2f0-d567-4814-aee2-c2f9a2367da8",
"status-id": "1156806e-d06a-38bd-83f0-cf2284a808b9",
"title": "Marbles on the Road",
"status": "Bootleg"
}
]
},
{
"id": "5fb9fdb0-cd94-412c-b4d1-f0354128e4c2",
"type-id": "6fd474e2-6b58-3102-9d17-d6f7eb7da0a0",
"score": 77,
"primary-type-id": "f529b476-6e62-324f-b0aa-1f3e33d313fc",
"count": 4,
"title": "Marbles in the Park",
"first-release-date": "2016-11-06",
"primary-type": "Album",
"secondary-types": [
"Live"
],
"secondary-type-ids": [
"6fd474e2-6b58-3102-9d17-d6f7eb7da0a0"
],
"artist-credit": [
{
"name": "Marillion",
"artist": {
"id": "1932f5b6-0b7b-4050-b1df-833ca89e5f44",
"name": "Marillion",
"sort-name": "Marillion",
"disambiguation": "British progressive rock band",
"aliases": [
{
"sort-name": "Trios Marillos, Los",
"name": "Los Trios Marillos",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Skyline Drifters",
"name": "Skyline Drifters",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Low Fat Yoghurts",
"name": "Low Fat Yoghurts",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
}
]
}
}
],
"releases": [
{
"id": "f5db4db0-1b60-492a-a4c1-b286dda4e03a",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles in the Park",
"status": "Official"
},
{
"id": "a8a70e02-828f-46a3-ba0e-7e97ee5b9d02",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles in the Park",
"status": "Official"
},
{
"id": "53a08c1a-a9a1-48f2-b5ae-7ac8a75f3f21",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles in the Park",
"status": "Official"
},
{
"id": "f7151d70-64d9-4520-97a0-0d2747b514fc",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles in the Park",
"status": "Official"
}
],
"tags": [
{
"count": 1,
"name": "rock"
},
{
"count": 1,
"name": "pop"
},
{
"count": 1,
"name": "art rock"
}
]
},
{
"id": "84ad8315-f7fe-3988-962f-440307682dd6",
"type-id": "6fd474e2-6b58-3102-9d17-d6f7eb7da0a0",
"score": 77,
"primary-type-id": "f529b476-6e62-324f-b0aa-1f3e33d313fc",
"count": 2,
"title": "Marbles by the Sea",
"first-release-date": "2005-10",
"primary-type": "Album",
"secondary-types": [
"Live"
],
"secondary-type-ids": [
"6fd474e2-6b58-3102-9d17-d6f7eb7da0a0"
],
"artist-credit": [
{
"name": "Marillion",
"artist": {
"id": "1932f5b6-0b7b-4050-b1df-833ca89e5f44",
"name": "Marillion",
"sort-name": "Marillion",
"disambiguation": "British progressive rock band",
"aliases": [
{
"sort-name": "Trios Marillos, Los",
"name": "Los Trios Marillos",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Skyline Drifters",
"name": "Skyline Drifters",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Low Fat Yoghurts",
"name": "Low Fat Yoghurts",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
}
]
}
}
],
"releases": [
{
"id": "2a4dd3a3-e63f-4f6d-8035-34da48670593",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles by the Sea",
"status": "Official"
},
{
"id": "0c724b38-216e-4a33-931e-f23c7f175792",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles by the Sea",
"status": "Official"
}
],
"tags": [
{
"count": 1,
"name": "rock"
}
]
},
{
"id": "56286106-d546-4a3a-9304-242ca7715453",
"type-id": "4fc3be2b-de1e-396b-a933-beb8f1607a22",
"score": 69,
"primary-type-id": "4fc3be2b-de1e-396b-a933-beb8f1607a22",
"count": 2,
"title": "Glass Half Full: Making of Marbles",
"first-release-date": "2015",
"primary-type": "Other",
"artist-credit": [
{
"name": "Marillion",
"artist": {
"id": "1932f5b6-0b7b-4050-b1df-833ca89e5f44",
"name": "Marillion",
"sort-name": "Marillion",
"disambiguation": "British progressive rock band",
"aliases": [
{
"sort-name": "Trios Marillos, Los",
"name": "Los Trios Marillos",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Skyline Drifters",
"name": "Skyline Drifters",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
},
{
"sort-name": "Low Fat Yoghurts",
"name": "Low Fat Yoghurts",
"locale": null,
"type": null,
"primary": null,
"begin-date": null,
"end-date": null
}
]
}
}
],
"releases": [
{
"id": "a2459015-e3e6-4f1c-b765-2d8ec3a0564f",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Glass Half Full The Making of Marbles",
"status": "Official"
},
{
"id": "68351699-e4d8-4650-850f-d40460c76b7b",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Glass Half Full: Making of Marbles",
"status": "Official"
}
],
"tags": [
{
"count": 1,
"name": "rock"
}
]
},
{
"id": "9006f9e9-207e-4741-8c99-562f94c87fe1",
"type-id": "6d0c5bf6-7a33-3420-a519-44fc63eedebf",
"score": 68,
"primary-type-id": "6d0c5bf6-7a33-3420-a519-44fc63eedebf",
"count": 1,
"title": "MARBLES",
"first-release-date": "2024-03-13",
"primary-type": "EP",
"artist-credit": [
{
"name": "THE ORAL CIGARETTES",
"artist": {
"id": "7974fd3f-b3e7-4607-a1ad-9d85c07ac3b9",
"name": "THE ORAL CIGARETTES",
"sort-name": "ORAL CIGARETTES, THE"
}
}
],
"releases": [
{
"id": "7495379e-fa66-411a-9092-a1bf634352d3",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "MARBLES",
"status": "Official"
}
]
},
{
"id": "765278d7-1c6d-4f02-8642-d3d4120ad765",
"score": 68,
"count": 1,
"title": "Marbles",
"first-release-date": "2021-02-22",
"artist-credit": [
{
"name": "slowbomb",
"artist": {
"id": "1dc4d526-7896-4309-9814-1399d5451fb9",
"name": "slowbomb",
"sort-name": "slowbomb"
}
}
],
"releases": [
{
"id": "b45fec65-b17b-4c74-87d2-11a62d9ee456",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
}
]
},
{
"id": "fdfdbd61-6b9b-360e-96a3-efd2f95d2169",
"type-id": "f529b476-6e62-324f-b0aa-1f3e33d313fc",
"score": 68,
"primary-type-id": "f529b476-6e62-324f-b0aa-1f3e33d313fc",
"count": 2,
"title": "Marbles",
"first-release-date": "1993",
"primary-type": "Album",
"artist-credit": [
{
"name": "King Apparatus",
"artist": {
"id": "cc97c476-5587-42cc-814b-7ccb4005fd4e",
"name": "King Apparatus",
"sort-name": "King Apparatus"
}
}
],
"releases": [
{
"id": "04548253-77bc-4d92-abe7-c8f8f0640f3b",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
},
{
"id": "dc7bc259-7e05-4ae4-a126-98ec0599b1e6",
"status-id": "4e304316-386d-3409-af2e-78857eec5cfe",
"title": "Marbles",
"status": "Official"
}
],
"tags": [
{
"count": 1,
"name": "rock"
},
{
"count": 1,
"name": "ska"
}
]
}
]
}
-8
View File
@@ -1,10 +1,2 @@
Mox.defmock(MusicBrainz.APIMock, for: MusicBrainz.APIBehaviour)
music_brainz_config =
Application.get_env(:music_library, MusicBrainz)
|> Keyword.put(:api, MusicBrainz.APIMock)
Application.put_env(:music_library, MusicBrainz, music_brainz_config)
ExUnit.start() ExUnit.start()
Ecto.Adapters.SQL.Sandbox.mode(MusicLibrary.Repo, :manual) Ecto.Adapters.SQL.Sandbox.mode(MusicLibrary.Repo, :manual)