ML-169.10: drop socket-internals delete tests

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.
This commit is contained in:
Claudio Ortolina
2026-05-22 16:27:42 +01:00
parent b10be7ba3c
commit 3f2e5f2e27
3 changed files with 0 additions and 209 deletions
@@ -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
@@ -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
@@ -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