prop/test/microwaveprop_web/live/skewt_live_test.exs
Graham McIntire 888701e627
test: bump coverage 80% -> 81.3% via more LiveView + module tests
- Pskr.Client: 0% -> 18% (init/standby/handle_info/terminate)
- RoverPlanningLive.PathShow: 0% -> 82% (mount/load_path)
- Rover.CandidateDetail: 0% -> partial (summarize/5 with stations)
- Mix.Tasks.Weather.RebatchAsos: 0% -> covered (wrapper run/1)
- HrrrNativeClient: 57% -> 67% (fetch_native_duct_grid error paths)
- RoverLive: 40% -> 48% (toggle/delete/update_station_grid logged-in)
- PathLive: 62% -> 63% (path_forecast_detail + rover_path_id branches)
- PathCompute: 64% -> 64% (compute/4 full pipeline + resolve_location)
- SkewtLive: 29% -> 31% (search/select_time event no-ops)
- SkewtLocationResolver: 38% -> 60%+ (callsign cache + error paths)

3557 tests passing.
2026-05-08 09:10:34 -05:00

161 lines
5 KiB
Elixir

defmodule MicrowavepropWeb.SkewtLiveTest do
use MicrowavepropWeb.ConnCase, async: false
import Phoenix.LiveViewTest
alias Microwaveprop.Weather.HrrrProfile
describe "with HRRR profile data near the queried location" do
setup do
profile_data = [
%{"pres" => 1000.0, "hght" => 110, "tmpc" => 25.0, "dwpc" => 18.0},
%{"pres" => 925.0, "hght" => 770, "tmpc" => 18.0, "dwpc" => 12.0},
%{"pres" => 850.0, "hght" => 1500, "tmpc" => 14.0, "dwpc" => 8.0},
%{"pres" => 700.0, "hght" => 3000, "tmpc" => 0.0, "dwpc" => -10.0},
%{"pres" => 500.0, "hght" => 5500, "tmpc" => -20.0, "dwpc" => -30.0}
]
# Insert near EM12kp (32.646, -97.125)
now = DateTime.truncate(DateTime.utc_now(), :second)
%HrrrProfile{}
|> HrrrProfile.changeset(%{
valid_time: now,
run_time: now,
lat: 32.65,
lon: -97.12,
profile: profile_data,
hpbl_m: 1500.0,
pwat_mm: 25.0,
surface_temp_c: 25.0,
surface_dewpoint_c: 18.0,
surface_pressure_mb: 1013.0,
surface_refractivity: 320.5,
min_refractivity_gradient: -45.0,
ducting_detected: false
})
|> Microwaveprop.Repo.insert!()
:ok
end
test "renders the time selector when valid_times list is non-empty", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt?q=EM12kp")
_ = render_async(view)
# We can't reliably assert HRRR data renders since fetch_rich_cell
# tries an HTTP call that fails — but the page should not crash.
assert render(view) =~ "Skew-T"
end
end
describe "select_time event" do
test "ignored when no location is set yet", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt")
# No location resolved → select_time falls through to the no-op.
result = render_hook(view, "select_time", %{"valid_time" => "2026-04-29T12:00:00Z"})
# Render still works.
assert result =~ "Skew-T"
end
test "ignored when valid_time is unparseable", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt?q=EM12kp")
render_async(view)
result = render_hook(view, "select_time", %{"valid_time" => "not-a-timestamp"})
assert result =~ "Skew-T"
end
end
describe "search event" do
test "patches URL when user submits the form", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt")
render_hook(view, "search", %{"q" => "EM13"})
assert render_async(view) =~ "EM13"
end
end
describe "GET /skewt" do
test "renders search bar with no results when no query is supplied", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/skewt")
assert html =~ "Skew-T-Log-P"
assert html =~ ~s|placeholder="EM12kp|
refute html =~ "viewBox=\"0 0 720"
end
test "initial render with a URL query shows the page chrome + a loading indicator", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/skewt?q=EM12kp")
assert html =~ "Skew-T-Log-P"
assert html =~ ~s|placeholder="EM12kp|
assert html =~ "Resolving location"
refute html =~ "EM12KP"
end
test "after the async completes the resolved location label appears", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt?q=EM12kp")
html = render_async(view)
assert html =~ "EM12KP"
assert html =~ "32.646"
assert html =~ "-97.125"
refute html =~ "Resolving location"
end
test "submitting the form patches the URL with the query", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt")
view |> form("form", q: "EM12") |> render_submit()
assert render_async(view) =~ "EM12"
end
test "shows info alert when no HRRR profiles are stored", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt?q=EM12kp")
html = render_async(view)
assert html =~ "No HRRR profiles are currently stored"
assert has_element?(view, ".alert.alert-info")
end
test "time selector is not shown when there are no valid times", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt?q=EM12kp")
render_async(view)
refute has_element?(view, "button[phx-click=select_time]")
end
test "loading indicator visible while async is in flight", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt?q=EM12kp")
assert has_element?(view, ".loading")
assert render(view) =~ "Resolving location"
end
test "on successful async the loading state is cleared and location shown", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt?q=EM12kp")
html = render_async(view)
refute html =~ "Resolving location"
assert html =~ "EM12KP"
assert html =~ "32.646"
end
test "coordinates are formatted with 3 decimal places", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/skewt?q=EM12kp")
html = render_async(view)
assert html =~ "32.646"
assert html =~ "-97.125"
end
end
end