- ErrorHTML: explicit 400 path + 401/403/999 delegation.
- Layouts.body_class/1 returns the expected light/dark theme classes.
- MapLive.Components: map_container + slideover_panel exercising all
connection_status variants, loading state, tracked_callsign clear
button, and view-mode radios.
- CoreComponents: icon (found + fallback), button, label, error,
flash (info + error + close=false), checkbox input, JS composers.
- Accounts: get_user_by_email{_and_password}, get_user!, register_user
happy-path + error paths, change_* changesets, session-token
round-trip.
Refactor: DeviceIdentification.maybe_refresh_devices splits its nested
logic into fetch_most_recent_device/0, to_datetime/1, and
refresh_if_stale/2 — each a multi-clause function matching on shape.
Coverage 68.28 → 69.56%.
142 lines
3.7 KiB
Elixir
142 lines
3.7 KiB
Elixir
defmodule AprsmeWeb.MapLive.ComponentsTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
import Phoenix.LiveViewTest
|
|
|
|
alias AprsmeWeb.MapLive.Components
|
|
|
|
describe "map_container/1" do
|
|
test "renders aprs-map div with encoded center and zoom" do
|
|
html =
|
|
render_component(&Components.map_container/1,
|
|
map_center: %{lat: 40.0, lng: -100.0},
|
|
map_zoom: 5,
|
|
slideover_open: false
|
|
)
|
|
|
|
assert html =~ ~s(id="aprs-map")
|
|
assert html =~ ~s(phx-hook="APRSMap")
|
|
assert html =~ "data-zoom=\"5\""
|
|
assert html =~ "40.0"
|
|
assert html =~ "-100.0"
|
|
end
|
|
|
|
test "adds slideover-open class when panel is open" do
|
|
html =
|
|
render_component(&Components.map_container/1,
|
|
map_center: %{lat: 0.0, lng: 0.0},
|
|
map_zoom: 5,
|
|
slideover_open: true
|
|
)
|
|
|
|
assert html =~ "slideover-open"
|
|
end
|
|
|
|
test "adds slideover-closed class when panel is closed" do
|
|
html =
|
|
render_component(&Components.map_container/1,
|
|
map_center: %{lat: 0.0, lng: 0.0},
|
|
map_zoom: 5,
|
|
slideover_open: false
|
|
)
|
|
|
|
assert html =~ "slideover-closed"
|
|
end
|
|
end
|
|
|
|
describe "slideover_panel/1" do
|
|
defp base_assigns(overrides \\ %{}) do
|
|
Enum.into(overrides, %{
|
|
slideover_open: true,
|
|
loading: false,
|
|
connection_status: "connected",
|
|
packets: [],
|
|
show_all_packets: true,
|
|
tracked_callsign: "",
|
|
tracked_callsign_latest_packet: nil
|
|
})
|
|
end
|
|
|
|
test "renders header + content when open" do
|
|
html = render_component(&Components.slideover_panel/1, base_assigns())
|
|
assert html =~ "APRS Packets"
|
|
assert html =~ "slideover-panel"
|
|
end
|
|
|
|
test "shows the 'connected' indicator text for a connected status" do
|
|
html =
|
|
render_component(
|
|
&Components.slideover_panel/1,
|
|
base_assigns(%{connection_status: "connected"})
|
|
)
|
|
|
|
assert html =~ "Connected to APRS-IS"
|
|
end
|
|
|
|
test "shows 'connecting' indicator text" do
|
|
html =
|
|
render_component(
|
|
&Components.slideover_panel/1,
|
|
base_assigns(%{connection_status: "connecting"})
|
|
)
|
|
|
|
assert html =~ "Connecting to APRS-IS"
|
|
end
|
|
|
|
test "shows 'disconnected' indicator text" do
|
|
html =
|
|
render_component(
|
|
&Components.slideover_panel/1,
|
|
base_assigns(%{connection_status: "disconnected"})
|
|
)
|
|
|
|
assert html =~ "Disconnected from APRS-IS"
|
|
end
|
|
|
|
test "shows 'Initializing...' for pending/unknown status" do
|
|
html =
|
|
render_component(
|
|
&Components.slideover_panel/1,
|
|
base_assigns(%{connection_status: "pending"})
|
|
)
|
|
|
|
assert html =~ "Initializing"
|
|
end
|
|
|
|
test "shows the loading spinner when loading" do
|
|
html =
|
|
render_component(
|
|
&Components.slideover_panel/1,
|
|
base_assigns(%{loading: true})
|
|
)
|
|
|
|
assert html =~ "Loading packets"
|
|
# Spinner SVG has an animate-spin class.
|
|
assert html =~ "animate-spin"
|
|
end
|
|
|
|
test "shows a clear button only when a callsign is tracked" do
|
|
with_tracked =
|
|
render_component(
|
|
&Components.slideover_panel/1,
|
|
base_assigns(%{tracked_callsign: "K5ABC"})
|
|
)
|
|
|
|
assert with_tracked =~ "clear_callsign_filter"
|
|
|
|
without_tracked =
|
|
render_component(
|
|
&Components.slideover_panel/1,
|
|
base_assigns(%{tracked_callsign: ""})
|
|
)
|
|
|
|
refute without_tracked =~ "clear_callsign_filter"
|
|
end
|
|
|
|
test "renders the 'All' and 'With Position' radio options" do
|
|
html = render_component(&Components.slideover_panel/1, base_assigns())
|
|
assert html =~ "All Packets"
|
|
assert html =~ "With Position"
|
|
end
|
|
end
|
|
end
|