Adds ~600 new test cases (2013 → 2613 tests; 170 properties; 0
failures) across 12 new test files plus expansions of eight existing
files. Big lifts per module:
ContactLive.Mechanism 33 → 100%
MetricsPlug 54 → ~100%
Microwaveprop.Release 15.8 → 70%+
Telemetry 38 → 76%
HrrrNativeGridWorker 27.7 → 76%
ContactLive.Show 34 → 48% (handler + render branches)
Admin.ContactEditLive 49.7 → 70%+
GefsFetchWorker 35.8 → ~55%
IonosphereFetchWorker 56.3 → 75%
PathLive 58.9 → 67%
WeatherMapLive 66.9 → 80.2%
RoverLive 0 → 70.3%
ContactMapLive 59.2 → 89.8%
ContactMapController 0 → 100%
Mix tasks (Rust.Golden, Notebook, Backtest, HrrrBackfill,
HrrrClimatology, HrrrNativeBackfill, NexradBackfill,
RadarBackfill, ImportContestLogs, PropagationGrid,
ResetEnrichment, Hrrr.PurgeGridPoints) 0 → ~60-100%
Two incidental fixes made while adding tests:
- ContactLive.Show.handle_event("toggle_flag", ...) was passing
socket.assigns.current_scope to admin?/1 instead of socket.assigns,
so admins never matched the pattern and every toggle ran the
"Admins only." flash branch. Flag now toggles for admins again.
- Commercial.PollWorker.fetch_weather/1 promoted from private to
@doc'd public so the IEM-fetch + ASOS-upsert path can be tested
directly without driving perform/1 through live SNMP (which was
timing out for ~50 s per test in the earlier attempt).
Stable property-test additions cover the dewpoint-from-RH monotonicity,
nearest_run/1 idempotence, and the ionosphere station envelope.
111 lines
3.8 KiB
Elixir
111 lines
3.8 KiB
Elixir
defmodule MicrowavepropWeb.RoverLiveTest do
|
|
use MicrowavepropWeb.ConnCase, async: false
|
|
|
|
import Phoenix.LiveViewTest
|
|
|
|
describe "GET /rover" do
|
|
test "renders the Rover Planner sidebar + map hook", %{conn: conn} do
|
|
{:ok, _view, html} = live(conn, ~p"/rover")
|
|
|
|
assert html =~ "Rover Planner"
|
|
# Band selector + station form.
|
|
assert html =~ ~s(id="rover-map")
|
|
assert html =~ ~s(phx-hook="RoverMap")
|
|
assert html =~ "Add station"
|
|
# Default band is 10_000 MHz — check the corresponding option label.
|
|
assert html =~ "10 GHz"
|
|
end
|
|
|
|
test "band selector shows every amateur microwave option", %{conn: conn} do
|
|
{:ok, _view, html} = live(conn, ~p"/rover")
|
|
|
|
# BandConfig.band_options/0 currently includes these microwave bands.
|
|
for label <- ~w(50MHz 144MHz 432MHz 1296MHz 10GHz 24GHz) do
|
|
nospace = label |> String.replace("MHz", " MHz") |> String.replace("GHz", " GHz")
|
|
assert html =~ nospace, "expected band option #{nospace} in rover HTML"
|
|
end
|
|
end
|
|
|
|
test "a maidenhead grid in the URL resolves a station synchronously", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/rover?stations=EM13")
|
|
|
|
# Async resolution runs in a message; flush by calling render.
|
|
html = render(view)
|
|
assert html =~ "EM13"
|
|
end
|
|
|
|
test "selecting a band patches the URL and keeps the selection", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/rover")
|
|
|
|
view
|
|
|> element(~s(select[name="band"]))
|
|
|> render_change(%{band: "1296"})
|
|
|
|
# URL patch replaces the current URL with ?band=1296.
|
|
assert_patched(view, ~p"/rover?band=1296")
|
|
assert render(view) =~ ~s(<option value="1296" selected)
|
|
end
|
|
|
|
test "removing a station clears it from the badge list", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/rover?stations=EM13")
|
|
render(view)
|
|
assert render(view) =~ "EM13"
|
|
|
|
view
|
|
|> element(~s(button[phx-click="remove_station"]))
|
|
|> render_click(%{index: "0"})
|
|
|
|
refute render(view) =~ "EM13"
|
|
end
|
|
|
|
test "add_station event with a grid resolves via the direct maidenhead path", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/rover")
|
|
|
|
# Submit the add-station form. add_station sends a message to
|
|
# self() and toggles resolving: true; after the message is handled
|
|
# the station appears.
|
|
view
|
|
|> form(~s(form[phx-submit="add_station"]), %{callsign: "EM00"})
|
|
|> render_submit()
|
|
|
|
# Drive the resolver message asynchronously.
|
|
html = render(view)
|
|
assert html =~ "EM00"
|
|
end
|
|
|
|
test "add_station with blank input is a no-op (no station added, no crash)", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/rover")
|
|
|
|
html =
|
|
view
|
|
|> form(~s(form[phx-submit="add_station"]), %{callsign: " "})
|
|
|> render_submit()
|
|
|
|
# The stations list stays empty.
|
|
refute html =~ "Stationary Stations"
|
|
end
|
|
|
|
test "map_bounds event re-fetches propagation scores for the new viewport", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/rover")
|
|
|
|
new_bounds = %{"south" => 30.0, "north" => 34.0, "west" => -100.0, "east" => -95.0}
|
|
|
|
render_hook(view, "map_bounds", new_bounds)
|
|
|
|
# The handler pushes an update_scores event to the JS hook.
|
|
assert_push_event(view, "update_scores", %{scores: scores})
|
|
assert is_list(scores)
|
|
end
|
|
|
|
test "propagation_updated pubsub message pushes an update_scores event", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/rover")
|
|
|
|
# Simulate the propagation pipeline broadcast by sending the
|
|
# message directly to the LiveView process.
|
|
send(view.pid, {:propagation_updated, [DateTime.utc_now()]})
|
|
|
|
assert_push_event(view, "update_scores", %{scores: scores})
|
|
assert is_list(scores)
|
|
end
|
|
end
|
|
end
|