prop/test/microwaveprop_web/controllers/weather_tile_controller_test.exs
Graham McIntire 2de1b89efc
chore(weather): drop tile endpoint and JSON cells back-compat
The client moved to the binary cell-pack and canvas overlay last
commit, so the per-tile SVG endpoint, the TileRenderer module, and the
JSON shape of /weather/cells are all dead code. Remove them.

/weather/cells now always returns the binary WCEL pack (the ?format=bin
toggle is gone — there's only one format). The data-weather-tile-url
attribute and the weather_tile_url assign are dropped from the LiveView.

Also fix a latent bug surfaced once tests covered the default-layers
path: nil row values were writing the atom :nan into the binary segment
at runtime. Replaced with the explicit f32 quiet-NaN bit pattern so
Number.isNaN flags them correctly on the JS side.
2026-04-29 13:45:43 -05:00

114 lines
3.4 KiB
Elixir

defmodule MicrowavepropWeb.WeatherTileControllerTest do
use MicrowavepropWeb.ConnCase, async: false
alias Microwaveprop.Propagation.ProfilesFile
alias Microwaveprop.Weather.GridCache
setup do
GridCache.clear()
on_exit(fn ->
GridCache.clear()
ProfilesFile.prune_older_than(~U[2099-12-31 23:59:59Z])
end)
:ok
end
describe "GET /weather/cells" do
test "returns 400 for missing or invalid params", %{conn: conn} do
conn = get(conn, ~p"/weather/cells?time=not-a-time")
assert json_response(conn, 400)
end
test "returns the binary cell pack with all default layers when ?layers is absent", %{conn: conn} do
valid_time = ~U[2026-04-28 12:00:00Z]
ProfilesFile.write!(valid_time, %{
{33.0, -97.0} => %{
surface_temp_c: 22.0,
surface_dewpoint_c: 12.0,
surface_pressure_mb: 1010.0,
hpbl_m: 800.0,
pwat_mm: 25.0,
profile: []
}
})
time = DateTime.to_iso8601(valid_time)
conn =
get(
conn,
~p"/weather/cells?time=#{time}&south=32.5&north=33.5&west=-97.5&east=-96.5"
)
assert ["application/octet-stream"] = get_resp_header(conn, "content-type")
body = response(conn, 200)
assert <<"WCEL", 1::8, _cell_count::little-32, _layer_count::8, _rest::binary>> = body
end
test "with ?layers=foo,bar limits the binary pack to those layers", %{conn: conn} do
valid_time = ~U[2026-04-28 12:00:00Z]
ProfilesFile.write!(valid_time, %{
{33.0, -97.0} => %{
surface_temp_c: 22.0,
surface_dewpoint_c: 12.0,
surface_pressure_mb: 1010.0,
hpbl_m: 800.0,
pwat_mm: 25.0,
profile: []
},
{33.125, -97.0} => %{
surface_temp_c: 23.0,
surface_dewpoint_c: 13.0,
surface_pressure_mb: 1011.0,
hpbl_m: 700.0,
pwat_mm: 26.0,
profile: []
}
})
time = DateTime.to_iso8601(valid_time)
conn =
get(
conn,
~p"/weather/cells?time=#{time}&south=32.0&north=34.0&west=-98.0&east=-96.0&layers=temperature,pwat"
)
assert ["application/octet-stream"] = get_resp_header(conn, "content-type")
body = response(conn, 200)
assert <<"WCEL", 1::8, cell_count::little-32, 2::8, rest::binary>> = body
assert cell_count == 2
# Two layer names: "temperature" (11), "pwat" (4).
<<11::8, "temperature", 4::8, "pwat", padded_rest::binary>> = rest
# Header so far: 4(magic) + 1 + 4 + 1 + (1+11) + (1+4) = 27 bytes. One
# byte of zero padding aligns the f32 arrays to a 4-byte boundary.
<<0::8, lats_and_more::binary>> = padded_rest
<<lat1::little-float-32, lat2::little-float-32, _rest::binary>> = lats_and_more
assert_in_delta lat1, 33.0, 0.001
assert_in_delta lat2, 33.125, 0.001
end
test "returns an empty pack when no data exists for the valid_time", %{conn: conn} do
valid_time = ~U[2099-04-28 12:00:00Z]
time = DateTime.to_iso8601(valid_time)
conn =
get(
conn,
~p"/weather/cells?time=#{time}&south=32.0&north=34.0&west=-98.0&east=-96.0"
)
assert ["application/octet-stream"] = get_resp_header(conn, "content-type")
body = response(conn, 200)
assert <<"WCEL", 1::8, 0::little-32, _layer_count::8, _rest::binary>> = body
end
end
end