prop/test/microwaveprop_web/live/skewt_location_resolver_test.exs
Graham McIntire e40ade3b19
feat(skewt): add /skewt LiveView with HRRR-backed Skew-T-Log-P plot
Single search bar accepts an address, Maidenhead grid square, or
callsign; resolves it to lat/lon via Geocoder / Maidenhead /
CallsignLocation (cheapest classification first), snaps to the HRRR
grid via the existing ProfilesFile reader, and renders an SVG
Skew-T-Log-P with isobars, skewed isotherms, dry/moist adiabats, and
mixing-ratio lines. A button row picks between every available
forecast hour (now → f18); default is the most recent analysis.
Right pane lists derived stability and refractivity stats from
SoundingParams.derive (PWAT, BL depth, K-index, lifted index, min
dN/dh, ducting status + per-duct base/top/ΔM).

Renderer is server-side SVG so the page works without JS and serializes
into the LiveView payload as a single tag. Wind barbs are deliberately
omitted — HRRR's persisted profile carries wind only at 10 m AGL.
2026-04-25 12:13:46 -05:00

46 lines
1.7 KiB
Elixir

defmodule MicrowavepropWeb.SkewtLocationResolverTest do
use Microwaveprop.DataCase, async: false
alias MicrowavepropWeb.SkewtLocationResolver
describe "classify/1" do
test "recognises 4/6/8-character Maidenhead grid squares" do
assert SkewtLocationResolver.classify("EM12") == :grid
assert SkewtLocationResolver.classify("EM12kp") == :grid
assert SkewtLocationResolver.classify("EM12kp37") == :grid
end
test "recognises typical US/foreign callsigns" do
assert SkewtLocationResolver.classify("W5ISP") == :callsign
assert SkewtLocationResolver.classify("KM5PO") == :callsign
assert SkewtLocationResolver.classify("VE3ABC") == :callsign
assert SkewtLocationResolver.classify("G0ABC") == :callsign
end
test "anything else is treated as an address" do
assert SkewtLocationResolver.classify("Dallas, TX") == :address
assert SkewtLocationResolver.classify("123 Main St, Plano TX") == :address
assert SkewtLocationResolver.classify("Eiffel Tower") == :address
end
test "is whitespace and case tolerant" do
assert SkewtLocationResolver.classify(" em12 ") == :grid
assert SkewtLocationResolver.classify("w5isp") == :callsign
end
end
describe "resolve/1 — grid square branch" do
test "returns lat/lon for a valid grid square" do
assert {:ok, %{lat: lat, lon: lon, label: "EM12KP", source: :grid}} =
SkewtLocationResolver.resolve("EM12kp")
assert_in_delta lat, 32.646, 0.01
assert_in_delta lon, -97.125, 0.01
end
test "round-trips a 4-char grid" do
assert {:ok, %{label: "EM12", source: :grid}} =
SkewtLocationResolver.resolve("EM12")
end
end
end