181 lines
6.2 KiB
Elixir
181 lines
6.2 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 each file's own source content", %{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()
|
|
|
|
# Capture file A's source content from the rendered HTML
|
|
html_a = render(view)
|
|
# Each .ex file starts with "defmodule", grab the first defmodule line as unique content
|
|
assert html_a =~ "defmodule",
|
|
"File A source should be visible when expanded"
|
|
|
|
# Expand file B (should auto-collapse A)
|
|
view
|
|
|> element("button[phx-value-path=\"#{file_b}\"]", "Expand")
|
|
|> render_click()
|
|
|
|
# Capture file B's source content
|
|
html_b = render(view)
|
|
|
|
# The two source viewers must show different content
|
|
refute html_a == html_b,
|
|
"Source content should differ when switching between files"
|
|
|
|
# File A's button should now say "Expand" (collapsed)
|
|
refute html_b =~ ~r(phx-value-path="#{Regex.escape(file_a)}"[^>]*>\s*Collapse\s*</),
|
|
"file A should be collapsed after switching expand to file B"
|
|
|
|
# File B's button should say "Collapse" (expanded)
|
|
assert html_b =~ ~r(phx-value-path="#{Regex.escape(file_b)}"[^>]*>\s*Collapse\s*</),
|
|
"file B should show Collapse button when expanded"
|
|
end
|
|
end
|
|
|
|
describe "URL state persistence" do
|
|
test "expanded path is restored from query param on mount", %{conn: conn} do
|
|
files = MicroprintsLive.scan_source_files()
|
|
file_a = List.first(files)
|
|
|
|
{:ok, view, _html} = live(conn, ~p"/microprints?expanded=#{file_a}")
|
|
|
|
html = render(view)
|
|
assert html =~ "Collapse",
|
|
"Expanded file should show Collapse button when restored from URL param"
|
|
assert html =~ ~s(phx-value-path="#{file_a}")
|
|
end
|
|
|
|
test "unknown expanded path in URL is ignored gracefully", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/microprints?expanded=nonexistent.ex")
|
|
|
|
html = render(view)
|
|
refute html =~ "Collapse",
|
|
"Nonexistent expanded path should not show Collapse"
|
|
end
|
|
|
|
test "expand updates URL with expanded param", %{conn: conn} do
|
|
files = MicroprintsLive.scan_source_files()
|
|
file_a = List.first(files)
|
|
|
|
{:ok, view, _html} = live(conn, ~p"/microprints")
|
|
|
|
view
|
|
|> element("button[phx-value-path=\"#{file_a}\"]", "Expand")
|
|
|> render_click()
|
|
|
|
# URL should contain expanded param after clicking Expand
|
|
html = render(view)
|
|
assert html =~ "Collapse",
|
|
"File should remain expanded after push_patch updates URL"
|
|
end
|
|
end
|
|
end
|