From 3f2e5f2e278861d7491a91e4932c56af62996c77 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Fri, 22 May 2026 16:27:42 +0100 Subject: [PATCH] ML-169.10: drop socket-internals delete tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove 12 unit tests that accessed socket internals via :sys.get_state and called handle_async directly — these leak implementation details and error/exit paths can't be reached through the DOM. Keep the 3 integration delete tests that use pure DOM assertions: visit, assert_has, click, refute_has, render_async, DB verification. --- .../live/collection_live/index_test.exs | 69 ------------------ .../live/scrobbled_tracks_live/index_test.exs | 72 ------------------- .../live/wishlist_live/index_test.exs | 68 ------------------ 3 files changed, 209 deletions(-) diff --git a/test/music_library_web/live/collection_live/index_test.exs b/test/music_library_web/live/collection_live/index_test.exs index 2f4c7b89..b3a3bf98 100644 --- a/test/music_library_web/live/collection_live/index_test.exs +++ b/test/music_library_web/live/collection_live/index_test.exs @@ -13,7 +13,6 @@ defmodule MusicLibraryWeb.CollectionLive.IndexTest do alias MusicLibrary.Records.Record alias MusicLibrary.Worker.ImportFromMusicbrainzRelease alias MusicLibrary.Worker.ImportFromMusicbrainzReleaseGroup - alias MusicLibraryWeb.CollectionLive.Index, as: CollectionIndex alias Req.Test # make it a multiple of 4 for easier calculations @@ -777,72 +776,4 @@ defmodule MusicLibraryWeb.CollectionLive.IndexTest do payload = Transform.encode!(transform) ~p"/assets/#{payload}" end - - describe "handle_async delete_record" do - import Phoenix.LiveViewTest - - defp build_socket(conn) do - {:ok, view, _html} = live(conn, ~p"/collection") - state = :sys.get_state(view.pid) - state.socket - end - - test "{:ok, {:ok, _}} is a no-op", %{conn: conn} do - record = record(%{title: "HandleAsync Success"}) - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :records, record) - - assert {:noreply, _socket} = - CollectionIndex.handle_async( - {:delete_record, record.id}, - {:ok, {:ok, record}}, - socket - ) - end - - test "{:ok, {:error, _}} does not crash", %{conn: conn} do - record = record(%{title: "HandleAsync Error"}) - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :records, record) - - assert {:noreply, _socket} = - CollectionIndex.handle_async( - {:delete_record, record.id}, - {:ok, {:error, :not_found}}, - socket - ) - end - - test "{:exit, _} does not crash", %{conn: conn} do - record = record(%{title: "HandleAsync Exit"}) - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :records, record) - - assert {:noreply, _socket} = - CollectionIndex.handle_async( - {:delete_record, record.id}, - {:exit, :killed}, - socket - ) - end - - test "{:exit, _} uses generic message, never leaks reason", %{conn: conn} do - record = record(%{title: "HandleAsync Exit No Leak"}) - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :records, record) - - {:noreply, socket} = - CollectionIndex.handle_async( - {:delete_record, record.id}, - {:exit, {:killed, "some stacktrace that should not leak"}}, - socket - ) - - # Verify the toast contains the generic message, NOT the raw exit reason - assert socket.assigns[:toasts_sync] - [toast | _] = socket.assigns.toasts_sync - refute inspect(toast) =~ "stacktrace" - refute inspect(toast) =~ "killed" - end - end end diff --git a/test/music_library_web/live/scrobbled_tracks_live/index_test.exs b/test/music_library_web/live/scrobbled_tracks_live/index_test.exs index 5afe4460..c921f471 100644 --- a/test/music_library_web/live/scrobbled_tracks_live/index_test.exs +++ b/test/music_library_web/live/scrobbled_tracks_live/index_test.exs @@ -4,7 +4,6 @@ defmodule MusicLibraryWeb.ScrobbledTracksLiveTest do import MusicLibrary.ScrobbledTracksFixtures alias MusicLibrary.ListeningStats - alias MusicLibraryWeb.ScrobbledTracksLive.Index, as: ScrobbledTracksIndex @valid_track_attrs %{ title: "Updated Track Title", @@ -156,75 +155,4 @@ defmodule MusicLibraryWeb.ScrobbledTracksLiveTest do end end end - - describe "handle_async delete_track" do - import Phoenix.LiveViewTest - - defp build_socket(conn) do - {:ok, view, _html} = live(conn, ~p"/scrobbled-tracks") - state = :sys.get_state(view.pid) - state.socket - end - - test "{:ok, {{:ok, _}, _}} is a no-op", %{conn: conn} do - track = track_fixture() - element = %{track: track} - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :tracks, element) - - assert {:noreply, _socket} = - ScrobbledTracksIndex.handle_async( - {:delete_track, track.scrobbled_at_uts}, - {:ok, {{:ok, track}, element}}, - socket - ) - end - - test "{:ok, {{:error, _}, _}} does not crash", %{conn: conn} do - track = track_fixture() - element = %{track: track} - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :tracks, element) - - assert {:noreply, _socket} = - ScrobbledTracksIndex.handle_async( - {:delete_track, track.scrobbled_at_uts}, - {:ok, {{:error, :not_found}, element}}, - socket - ) - end - - test "{:exit, _} does not crash", %{conn: conn} do - track = track_fixture() - element = %{track: track} - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :tracks, element) - - assert {:noreply, _socket} = - ScrobbledTracksIndex.handle_async( - {:delete_track, track.scrobbled_at_uts}, - {:exit, :killed}, - socket - ) - end - - test "{:exit, _} uses generic message, never leaks reason", %{conn: conn} do - track = track_fixture() - element = %{track: track} - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :tracks, element) - - {:noreply, socket} = - ScrobbledTracksIndex.handle_async( - {:delete_track, track.scrobbled_at_uts}, - {:exit, {:killed, "some stacktrace that should not leak"}}, - socket - ) - - assert socket.assigns[:toasts_sync] - [toast | _] = socket.assigns.toasts_sync - refute inspect(toast) =~ "stacktrace" - refute inspect(toast) =~ "killed" - end - end end diff --git a/test/music_library_web/live/wishlist_live/index_test.exs b/test/music_library_web/live/wishlist_live/index_test.exs index eb518a70..37d8eb2f 100644 --- a/test/music_library_web/live/wishlist_live/index_test.exs +++ b/test/music_library_web/live/wishlist_live/index_test.exs @@ -9,7 +9,6 @@ defmodule MusicLibraryWeb.WishlistLive.IndexTest do alias MusicLibrary.Records alias MusicLibrary.Records.Record alias MusicLibrary.Worker.ImportFromMusicbrainzReleaseGroup - alias MusicLibraryWeb.WishlistLive.Index, as: WishlistIndex alias Req.Test defp fill_wishlist(_) do @@ -176,71 +175,4 @@ defmodule MusicLibraryWeb.WishlistLive.IndexTest do end end) end - - describe "handle_async delete_record" do - import Phoenix.LiveViewTest - - defp build_socket(conn) do - {:ok, view, _html} = live(conn, ~p"/wishlist") - state = :sys.get_state(view.pid) - state.socket - end - - test "{:ok, {:ok, _}} is a no-op", %{conn: conn} do - record = record(%{title: "HandleAsync Success", purchased_at: nil}) - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :records, record) - - assert {:noreply, _socket} = - WishlistIndex.handle_async( - {:delete_record, record.id}, - {:ok, {:ok, record}}, - socket - ) - end - - test "{:ok, {:error, _}} does not crash", %{conn: conn} do - record = record(%{title: "HandleAsync Error", purchased_at: nil}) - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :records, record) - - assert {:noreply, _socket} = - WishlistIndex.handle_async( - {:delete_record, record.id}, - {:ok, {:error, :not_found}}, - socket - ) - end - - test "{:exit, _} does not crash", %{conn: conn} do - record = record(%{title: "HandleAsync Exit", purchased_at: nil}) - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :records, record) - - assert {:noreply, _socket} = - WishlistIndex.handle_async( - {:delete_record, record.id}, - {:exit, :killed}, - socket - ) - end - - test "{:exit, _} uses generic message, never leaks reason", %{conn: conn} do - record = record(%{title: "HandleAsync Exit No Leak", purchased_at: nil}) - socket = build_socket(conn) - socket = Phoenix.LiveView.stream_delete(socket, :records, record) - - {:noreply, socket} = - WishlistIndex.handle_async( - {:delete_record, record.id}, - {:exit, {:killed, "some stacktrace that should not leak"}}, - socket - ) - - assert socket.assigns[:toasts_sync] - [toast | _] = socket.assigns.toasts_sync - refute inspect(toast) =~ "stacktrace" - refute inspect(toast) =~ "killed" - end - end end