- Beacon detail endpoints (LiveView + REST API) now hide unapproved beacons from anonymous and unauthorized viewers; only the submitter and admins can see pending records before approval. Adds Beacons.get_visible_beacon/2 with scope-aware checks. - API contact pagination now honors per_page end-to-end. Radio.list_contacts/1 accepts :per_page and clamps to 200. - API rate limiter: ETS table is now owned by a long-lived Sweeper GenServer (won't die with a request task); Sweeper periodically prunes expired-window rows to bound memory; init_table/0 race is rescued. - /scores/cells and /weather/cells: add per-IP rate limiting and a shared GridBounds clamp/413 guard so global / oversized viewports no longer drive unbounded binary responses. - NEXRAD PNG unfilter (sub/up/average/paeth): replace acc++[byte] + Enum.at(acc, idx-bpp) with O(n) binary recursion. Decode time for the 12200x5400 n0q frame goes from quadratic to linear. - LiveTableFooter.parse_page and ScoresFile.fetch_bound: switch String.to_integer/String.to_float to Integer.parse/Float.parse, fall back to defaults instead of raising. - PathLive and MapLive band-event handlers: replace String.to_integer(params["band"]) with parse_int / parse_band_param so a non-numeric band parameter no longer crashes the LiveView.
38 lines
1.3 KiB
Elixir
38 lines
1.3 KiB
Elixir
defmodule MicrowavepropWeb.GridBoundsTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
alias MicrowavepropWeb.GridBounds
|
|
|
|
describe "clamp/1" do
|
|
test "passes nil through" do
|
|
assert GridBounds.clamp(nil) == {:ok, nil}
|
|
end
|
|
|
|
test "passes a small viewport through unchanged" do
|
|
bounds = %{"south" => 30.0, "north" => 35.0, "west" => -100.0, "east" => -90.0}
|
|
assert {:ok, ^bounds} = GridBounds.clamp(bounds)
|
|
end
|
|
|
|
test "clamps south/north/west/east to the supported extent" do
|
|
bounds = %{"south" => -50.0, "north" => 90.0, "west" => -200.0, "east" => 50.0}
|
|
assert {:error, :viewport_too_large} = GridBounds.clamp(bounds)
|
|
end
|
|
|
|
test "rejects global bounds with 413-equivalent error" do
|
|
global = %{"south" => -90.0, "north" => 90.0, "west" => -180.0, "east" => 180.0}
|
|
assert GridBounds.clamp(global) == {:error, :viewport_too_large}
|
|
end
|
|
|
|
test "rejects inverted bounds" do
|
|
inverted = %{"south" => 40.0, "north" => 30.0, "west" => -90.0, "east" => -100.0}
|
|
assert GridBounds.clamp(inverted) == {:error, :invalid_bounds}
|
|
end
|
|
|
|
test "rejects malformed bounds" do
|
|
assert GridBounds.clamp(%{}) == {:error, :invalid_bounds}
|
|
|
|
assert GridBounds.clamp(%{"south" => "x", "north" => 1, "west" => 1, "east" => 1}) ==
|
|
{:error, :invalid_bounds}
|
|
end
|
|
end
|
|
end
|