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 {:ok, %{"south" => 20.0, "north" => 65.0, "west" => -150.0, "east" => -50.0}} = GridBounds.clamp(bounds) end # The map's own `minZoom: 4` produces a viewport that clamps to the # full extent. Rejecting it blanked the overlay whenever a user # zoomed all the way out, so the clamped full grid must be served. test "serves global bounds by clamping them to the supported extent" do global = %{"south" => -90.0, "north" => 90.0, "west" => -180.0, "east" => 180.0} assert {:ok, %{"south" => 20.0, "north" => 65.0, "west" => -150.0, "east" => -50.0}} = GridBounds.clamp(global) end # The cap is defense-in-depth against the clamp window being widened # later; nothing the clamp can emit today exceeds it. test "the clamped extent stays inside the area cap" do assert (65.0 - 20.0) * (-50.0 - -150.0) <= GridBounds.max_viewport_area_sq_deg() 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