defmodule Microwaveprop.Rover.CoverageTest do use Microwaveprop.DataCase, async: false alias Microwaveprop.Rover.Coverage describe "compute/2" do test "returns ranked grids for stations within range" do stations = [ %{label: "STA1", lat: 33.0, lon: -97.0}, %{label: "STA2", lat: 33.5, lon: -97.5} ] result = Coverage.compute(stations, 10_000) assert is_list(result) assert length(result) > 0 scores = Enum.map(result, & &1.coverage_score) assert scores == Enum.sort(scores, :desc) first = hd(result) assert is_binary(first.grid) assert byte_size(first.grid) == 4 assert is_number(first.lat) assert is_number(first.lon) assert is_integer(first.coverage_score) assert first.coverage_score >= 0 and first.coverage_score <= 100 assert is_integer(first.stations_in_range) assert first.stations_in_range > 0 assert is_integer(first.workable_count) assert is_integer(first.prop_score) assert is_list(first.station_details) assert is_list(first.forecast) end test "returns empty list with fewer than 2 stations" do assert Coverage.compute([%{label: "STA1", lat: 33.0, lon: -97.0}], 10_000) == [] assert Coverage.compute([], 10_000) == [] end test "station_details includes distance and in_range" do stations = [ %{label: "STA1", lat: 33.0, lon: -97.0}, %{label: "STA2", lat: 33.5, lon: -97.0} ] [first | _] = Coverage.compute(stations, 10_000) assert length(first.station_details) == 2 for detail <- first.station_details do assert Map.has_key?(detail, :label) assert Map.has_key?(detail, :dist_km) assert Map.has_key?(detail, :in_range) assert is_number(detail.dist_km) assert is_boolean(detail.in_range) end end test "higher frequency bands have shorter range so fewer grids cover both stations" do far_stations = [ %{label: "STA1", lat: 33.0, lon: -97.0}, %{label: "STA2", lat: 35.0, lon: -97.0} ] result_10g = Coverage.compute(far_stations, 10_000) result_241g = Coverage.compute(far_stations, 241_000) # 10 GHz has 500 km range, 241 GHz has 50 km — far fewer grids reach both at 241 grids_reaching_both_10g = Enum.count(result_10g, &(&1.stations_in_range == 2)) grids_reaching_both_241g = Enum.count(result_241g, &(&1.stations_in_range == 2)) assert grids_reaching_both_10g >= grids_reaching_both_241g end test "top results have station details with expected fields" do stations = [ %{label: "STA1", lat: 33.0, lon: -97.0}, %{label: "STA2", lat: 33.2, lon: -97.2} ] [first | _] = Coverage.compute(stations, 10_000) # Each station detail should have core fields for detail <- first.station_details do assert Map.has_key?(detail, :label) assert Map.has_key?(detail, :dist_km) assert Map.has_key?(detail, :in_range) end # At least one station should be in range assert Enum.any?(first.station_details, & &1.in_range) end end end