Add test coverage for ScrobbleLive Index and Show

This commit is contained in:
Claudio Ortolina
2026-03-05 14:52:58 +00:00
parent fb7ccad6f9
commit 42a51b9539
2 changed files with 291 additions and 0 deletions
@@ -0,0 +1,155 @@
defmodule MusicLibraryWeb.ScrobbleLive.IndexTest do
use MusicLibraryWeb.ConnCase
import Phoenix.LiveViewTest, only: [render: 1, render_submit: 1, render_click: 3, form: 3]
alias MusicBrainz.Fixtures.ReleaseGroup
defp stub_search_results(_) do
Req.Test.stub(MusicBrainz.API, fn conn ->
case conn.request_path do
"/ws/2/release-group" ->
Req.Test.json(conn, ReleaseGroup.release_group_search_results())
"/ws/2/release" ->
Req.Test.json(conn, ReleaseGroup.release_group_releases(:marbles))
_ ->
Req.Test.json(conn, %{})
end
end)
:ok
end
defp stub_empty_search_results(_) do
Req.Test.stub(MusicBrainz.API, fn conn ->
case conn.request_path do
"/ws/2/release-group" ->
Req.Test.json(conn, %{"count" => 0, "release-groups" => []})
_ ->
Req.Test.json(conn, %{})
end
end)
:ok
end
describe "Index" do
setup [:stub_search_results]
test "renders search page with form", %{conn: conn} do
conn
|> visit(~p"/scrobble")
|> assert_has("form[phx-submit='search']")
end
test "shows connect Last.fm button when not authenticated", %{conn: conn} do
conn
|> visit(~p"/scrobble")
|> assert_has("a", text: "Connect your Last.fm account")
end
test "search with results shows release groups", %{conn: conn} do
session = visit(conn, ~p"/scrobble")
session
|> unwrap(fn view ->
view
|> form("form[phx-submit='search']", %{query: "marbles"})
|> render_submit()
# Process the {:perform_search, query} message
render(view)
end)
|> assert_has("h3", text: "Release Groups")
|> assert_has("p", text: "Marbles")
end
test "search with empty query does not trigger search", %{conn: conn} do
session = visit(conn, ~p"/scrobble")
session
|> unwrap(fn view ->
view
|> form("form[phx-submit='search']", %{query: ""})
|> render_submit()
end)
|> refute_has("h3", text: "Release Groups")
end
test "select release group shows releases", %{conn: conn} do
release_group_id = ReleaseGroup.release_group_id(:marbles)
session = visit(conn, ~p"/scrobble")
session
|> unwrap(fn view ->
view
|> form("form[phx-submit='search']", %{query: "marbles"})
|> render_submit()
# Process search results
render(view)
# Click on a release group
view
|> render_click("select_release_group", %{
"release_group_id" => release_group_id
})
# Process the {:fetch_releases, release_group} message
render(view)
end)
|> assert_has("h3", text: "Releases for")
|> assert_has("button", text: "Back")
end
test "clear selection goes back to release groups", %{conn: conn} do
release_group_id = ReleaseGroup.release_group_id(:marbles)
session = visit(conn, ~p"/scrobble")
session
|> unwrap(fn view ->
view
|> form("form[phx-submit='search']", %{query: "marbles"})
|> render_submit()
render(view)
view
|> render_click("select_release_group", %{
"release_group_id" => release_group_id
})
render(view)
# Click back button
view
|> render_click("clear_selection", %{})
end)
|> assert_has("h3", text: "Release Groups")
|> refute_has("h3", text: "Releases for")
end
end
describe "Index with no results" do
setup [:stub_empty_search_results]
test "shows no results message", %{conn: conn} do
session = visit(conn, ~p"/scrobble")
session
|> unwrap(fn view ->
view
|> form("form[phx-submit='search']", %{query: "nonexistent"})
|> render_submit()
render(view)
end)
|> assert_has("p", text: "No release groups found")
end
end
end
@@ -0,0 +1,136 @@
defmodule MusicLibraryWeb.ScrobbleLive.ShowTest do
use MusicLibraryWeb.ConnCase
import Phoenix.LiveViewTest, only: [render_click: 3]
alias MusicBrainz.Fixtures.Release, as: ReleaseFixtures
alias MusicLibrary.Secrets
@release_id ReleaseFixtures.release_id(:marbles)
defp stub_musicbrainz_release(_) do
Req.Test.stub(MusicBrainz.API, fn conn ->
case conn.request_path do
"/ws/2/release/" <> _id ->
Req.Test.json(conn, ReleaseFixtures.release_with_media(:marbles))
_ ->
Req.Test.json(conn, %{})
end
end)
:ok
end
defp stub_musicbrainz_release_error(_) do
Req.Test.stub(MusicBrainz.API, fn conn ->
Plug.Conn.send_resp(conn, 404, "Not Found")
end)
:ok
end
defp stub_lastfm_scrobble(_) do
Req.Test.stub(LastFm.API, fn conn ->
Req.Test.json(conn, %{"scrobbles" => %{"@attr" => %{"accepted" => 1}}})
end)
:ok
end
defp store_lastfm_session_key(_) do
Secrets.store("last_fm_session_key", "test_session_key")
:ok
end
describe "Show" do
setup [:stub_musicbrainz_release]
test "renders release details", %{conn: conn} do
conn
|> visit(~p"/scrobble/#{@release_id}")
|> assert_has("h2", text: "Marbles")
|> assert_has("a", text: "Back to search")
end
test "shows Last.fm not connected alert when no session key", %{conn: conn} do
conn
|> visit(~p"/scrobble/#{@release_id}")
|> assert_has("div", text: "You need to connect your Last.fm account")
end
test "displays tracks", %{conn: conn} do
conn
|> visit(~p"/scrobble/#{@release_id}")
|> assert_has("h3", text: "Tracks")
end
end
describe "Show with Last.fm connected" do
setup [:stub_musicbrainz_release, :stub_lastfm_scrobble, :store_lastfm_session_key]
test "does not show Last.fm not connected alert", %{conn: conn} do
conn
|> visit(~p"/scrobble/#{@release_id}")
|> refute_has("[data-part='title']", text: "Last.fm not connected")
end
test "scrobble full release", %{conn: conn} do
session = visit(conn, ~p"/scrobble/#{@release_id}")
session
|> unwrap(fn view ->
render_click(view, "scrobble_release", %{})
end)
|> assert_has("#toast-group", text: "Release scrobbled successfully")
end
test "scrobble single medium", %{conn: conn} do
session = visit(conn, ~p"/scrobble/#{@release_id}")
session
|> unwrap(fn view ->
render_click(view, "scrobble_medium", %{"medium_number" => "1"})
end)
|> assert_has("#toast-group", text: "Disc scrobbled successfully")
end
test "toggle track selection", %{conn: conn} do
session = visit(conn, ~p"/scrobble/#{@release_id}")
# Get a track ID from the rendered page, then toggle it
session
|> unwrap(fn view ->
# Toggle a track on
render_click(view, "toggle_track", %{"track-id" => "some-track-id"})
end)
end
test "scrobble selected tracks", %{conn: conn} do
release_data = ReleaseFixtures.release_with_media(:marbles)
first_track = release_data["media"] |> List.first() |> Map.get("tracks") |> List.first()
track_id = first_track["id"]
session = visit(conn, ~p"/scrobble/#{@release_id}")
session
|> unwrap(fn view ->
# Select a track first
render_click(view, "toggle_track", %{"track-id" => track_id})
# Then scrobble selected
render_click(view, "scrobble_selected_tracks", %{})
end)
|> assert_has("#toast-group", text: "Selected tracks scrobbled successfully")
end
end
describe "Show with failed release fetch" do
setup [:stub_musicbrainz_release_error]
test "redirects to scrobble index with error", %{conn: conn} do
conn
|> visit(~p"/scrobble/#{@release_id}")
|> assert_path(~p"/scrobble")
end
end
end