firehose/app/test/firehose_web/live/microprints_live_test.exs
Firehose Bot 7c06204ac2 fix(microprints): fix source viewer showing stale content when switching files
The source_viewer component used static DOM IDs (id='source-viewer')
with phx-update='ignore'. When switching expanded files, LiveView
reused the same DOM element but phx-update='ignore' prevented content
from being updated, showing the previous file's source.

- Override source_viewer/1 in MicroprintsLive with unique per-file IDs
  generated via :erlang.phash2(file_path)
- Add test verifying expand-switch shows correct source content
- Add test for highlight/expand coupling (collapse when highlighting
  a different file)
- All 160 tests pass
2026-05-18 18:04:47 +01:00

136 lines
4.7 KiB
Elixir

alias FirehoseWeb.MicroprintsLive
defmodule FirehoseWeb.MicroprintsLiveTest do
use FirehoseWeb.ConnCase, async: true
import Phoenix.LiveViewTest
describe "scan_source_files/0" do
test "returns exactly 2 files" do
files = FirehoseWeb.MicroprintsLive.scan_source_files()
assert length(files) == 2
end
test "returns only .ex files from app/ and blogex/ directories" do
files = FirehoseWeb.MicroprintsLive.scan_source_files()
# With the 2-file limit, check that returned files are valid .ex paths
Enum.each(files, fn file ->
assert String.ends_with?(file, ".ex")
assert String.starts_with?(file, "lib/") or String.starts_with?(file, "../blogex/")
end)
end
test "does not include files from _build/ directory" do
files = FirehoseWeb.MicroprintsLive.scan_source_files()
refute Enum.any?(files, &String.starts_with?(&1, "_build/"))
end
test "does not include files from deps/ directory" do
files = FirehoseWeb.MicroprintsLive.scan_source_files()
refute Enum.any?(files, &String.starts_with?(&1, "deps/"))
end
test "does not include files from examples/ directory" do
files = FirehoseWeb.MicroprintsLive.scan_source_files()
refute Enum.any?(files, &String.contains?(&1, "/examples/"))
end
test "does not include test files" do
files = FirehoseWeb.MicroprintsLive.scan_source_files()
refute Enum.any?(files, &String.contains?(&1, "/test/"))
end
test "paths are relative (no leading slash or absolute path)" do
files = FirehoseWeb.MicroprintsLive.scan_source_files()
refute Enum.any?(files, &String.starts_with?(&1, "/"))
end
test "app paths do not contain source dir prefix" do
files = FirehoseWeb.MicroprintsLive.scan_source_files()
app_files = Enum.filter(files, &String.starts_with?(&1, "lib/"))
refute Enum.any?(app_files, &String.starts_with?(&1, "app/"))
end
test "blogex paths start with ../blogex/" do
files = FirehoseWeb.MicroprintsLive.scan_source_files()
blogex_files = Enum.filter(files, &String.starts_with?(&1, "../blogex/"))
# With the 2-file limit, blogex files may or may not be included
# depending on which files are most recently modified
assert is_list(blogex_files)
end
end
describe "expanded_path and highlighted_path coupling" do
test "expanding file A and highlighting a line in file B should collapse file A", %{conn: conn} do
files = MicroprintsLive.scan_source_files()
assert length(files) >= 2, "Need at least 2 files to test coupling"
[file_a, file_b | _] = files
{:ok, view, _html} = live(conn, ~p"/microprints")
# Expand file A
view
|> element("button[phx-value-path=\"#{file_a}\"]", "Expand")
|> render_click()
# Verify file A shows "Collapse" button (it's expanded)
html = render(view)
assert html =~ ~s(phx-value-path="#{file_a}")
assert html =~ "Collapse"
# Highlight a line in file B (rect elements inside SVG)
view
|> element("svg rect[phx-value-line=\"1\"][phx-value-path=\"#{file_b}\"]")
|> render_click()
# file A should be collapsed when highlighting a different file
html = render(view)
refute html =~ "Collapse",
"file A should be collapsed after highlighting a different file, but the Collapse button is still visible (expanded_path is uncoupled from highlighted_path)"
end
test "switching expand from file A to file B shows file B's source content, not file A's", %{conn: conn} do
files = MicroprintsLive.scan_source_files()
assert length(files) >= 2, "Need at least 2 files to test source switching"
[file_a, file_b | _] = files
{:ok, view, _html} = live(conn, ~p"/microprints")
# Expand file A
view
|> element("button[phx-value-path=\"#{file_a}\"]", "Expand")
|> render_click()
# Verify file A's source is shown (check for module def from microprints_live.ex)
html = render(view)
assert html =~ "FirehoseWeb.MicroprintsLive",
"When file A is expanded, its source should be visible"
# Expand file B (should auto-collapse A)
view
|> element("button[phx-value-path=\"#{file_b}\"]", "Expand")
|> render_click()
# Verify file B's source is shown, NOT file A's
html = render(view)
assert html =~ "Firehose.Application",
"When file B is expanded, its source should be visible (not file A's source)"
# File A's button should now say "Expand" (collapsed)
refute html =~ ~s(phx-value-path="#{file_a}".*Collapse),
"file A should be collapsed after switching expand to file B"
end
end
end