- Add 17 missing @spec annotations (layouts, error_json, error_html, skewt_svg) - Move 12+ nested alias/import/require to module top level - Add phx-change/id attributes to 11 raw HTML <form> tags - Remove 4 unused LiveView assigns (:bounds, :data_provider) - Add 3 missing doctest references (HrrrNativeClient, BulkFetch, Accounts) - Break 2 long lines (path_compute.ex:382) - Strengthen weak test assertions (is_binary→byte_size, is_list→!=[]) - Replace Module.concat with Module.safe_concat (2 occurrences) - Replace length/1 > 0 with list != [] (9 occurrences) - Remove no-op assert true, fix no-assertion tests Remaining: 24 socket.assigns introspection warnings (deliberate test pattern for observable behavior testing), 1 formatter-resistant long line, 3 app-code usage warnings.
170 lines
5.9 KiB
Elixir
170 lines
5.9 KiB
Elixir
defmodule Microwaveprop.Buildings.MsFootprintsTest do
|
|
use ExUnit.Case, async: false
|
|
use ExUnitProperties
|
|
|
|
alias Microwaveprop.Buildings.MsFootprints
|
|
|
|
describe "quadkey/3" do
|
|
test "returns a string of length equal to zoom" do
|
|
assert String.length(MsFootprints.quadkey(33.0, -97.0, 9)) == 9
|
|
assert String.length(MsFootprints.quadkey(33.0, -97.0, 5)) == 5
|
|
end
|
|
|
|
test "returns the same quadkey for the same coordinates" do
|
|
assert MsFootprints.quadkey(33.0, -97.0, 9) == MsFootprints.quadkey(33.0, -97.0, 9)
|
|
end
|
|
|
|
test "coordinates far apart produce different quadkeys" do
|
|
q1 = MsFootprints.quadkey(33.0, -97.0, 9)
|
|
q2 = MsFootprints.quadkey(40.0, -80.0, 9)
|
|
refute q1 == q2
|
|
end
|
|
end
|
|
|
|
describe "quadkeys_for_bbox/2" do
|
|
test "returns a list of quadkey strings" do
|
|
bbox = %{"south" => 32.0, "north" => 34.0, "west" => -98.0, "east" => -96.0}
|
|
keys = MsFootprints.quadkeys_for_bbox(bbox, 9)
|
|
assert keys != []
|
|
assert Enum.all?(keys, &is_binary/1)
|
|
end
|
|
|
|
test "each quadkey has the expected length" do
|
|
bbox = %{"south" => 32.0, "north" => 34.0, "west" => -98.0, "east" => -96.0}
|
|
keys = MsFootprints.quadkeys_for_bbox(bbox, 9)
|
|
Enum.each(keys, fn k -> assert String.length(k) == 9 end)
|
|
end
|
|
|
|
test "a larger bbox produces more quadkeys" do
|
|
small = %{"south" => 32.5, "north" => 33.0, "west" => -97.5, "east" => -96.5}
|
|
large = %{"south" => 32.0, "north" => 34.0, "west" => -98.0, "east" => -96.0}
|
|
assert length(MsFootprints.quadkeys_for_bbox(large, 9)) > length(MsFootprints.quadkeys_for_bbox(small, 9))
|
|
end
|
|
end
|
|
|
|
describe "cache_dir/0" do
|
|
test "returns a string" do
|
|
assert byte_size(MsFootprints.cache_dir()) > 0
|
|
end
|
|
end
|
|
|
|
describe "dataset_index/0 with stubbed HTTP" do
|
|
setup do
|
|
Microwaveprop.Cache.invalidate(:ms_footprints_index)
|
|
prev = Application.get_env(:microwaveprop, :ms_footprints_http_get)
|
|
|
|
on_exit(fn ->
|
|
if prev,
|
|
do: Application.put_env(:microwaveprop, :ms_footprints_http_get, prev),
|
|
else: Application.delete_env(:microwaveprop, :ms_footprints_http_get)
|
|
end)
|
|
|
|
:ok
|
|
end
|
|
|
|
test "parses dataset-links CSV into quadkey -> URL map" do
|
|
Application.put_env(:microwaveprop, :ms_footprints_http_get, fn _url, _opts ->
|
|
{:ok,
|
|
%{
|
|
status: 200,
|
|
body:
|
|
"RegionName,QuadKey,Url,Size,DatasetDate\nUnitedStates,023112330,https://example.com/tile1.csv.gz,1234,2026-01-01\nUnitedStates,023112331,https://example.com/tile2.csv.gz,5678,2026-01-01\nCanada,023112332,https://example.com/ca-tile.csv.gz,9999,2026-01-01\n"
|
|
}}
|
|
end)
|
|
|
|
index = MsFootprints.dataset_index()
|
|
assert index["023112330"] == "https://example.com/tile1.csv.gz"
|
|
assert index["023112331"] == "https://example.com/tile2.csv.gz"
|
|
refute Map.has_key?(index, "023112332")
|
|
assert map_size(index) == 2
|
|
end
|
|
|
|
test "handles empty CSV gracefully" do
|
|
Application.put_env(:microwaveprop, :ms_footprints_http_get, fn _url, _opts ->
|
|
{:ok, %{status: 200, body: "RegionName,QuadKey,Url,Size,DatasetDate\n"}}
|
|
end)
|
|
|
|
assert MsFootprints.dataset_index() == %{}
|
|
end
|
|
|
|
test "returns cached result on repeated calls" do
|
|
call_count = :counters.new(1, [:atomics])
|
|
|
|
Application.put_env(:microwaveprop, :ms_footprints_http_get, fn _url, _opts ->
|
|
:counters.add(call_count, 1, 1)
|
|
|
|
{:ok,
|
|
%{
|
|
status: 200,
|
|
body: "RegionName,QuadKey,Url,Size,DatasetDate\nUnitedStates,qk,http://example.com/t,1,2026-01-01\n"
|
|
}}
|
|
end)
|
|
|
|
MsFootprints.dataset_index()
|
|
MsFootprints.dataset_index()
|
|
|
|
assert :counters.get(call_count, 1) == 1
|
|
end
|
|
end
|
|
|
|
describe "download_tile/1 with stubbed HTTP" do
|
|
setup do
|
|
prev = Application.get_env(:microwaveprop, :buildings_cache_dir)
|
|
tmp = Path.join(System.tmp_dir!(), "ms_footprints_#{System.unique_integer([:positive])}")
|
|
Application.put_env(:microwaveprop, :buildings_cache_dir, tmp)
|
|
Microwaveprop.Cache.invalidate(:ms_footprints_index)
|
|
|
|
prev_http = Application.get_env(:microwaveprop, :ms_footprints_http_get)
|
|
|
|
on_exit(fn ->
|
|
File.rm_rf(tmp)
|
|
|
|
if prev,
|
|
do: Application.put_env(:microwaveprop, :buildings_cache_dir, prev),
|
|
else: Application.delete_env(:microwaveprop, :buildings_cache_dir)
|
|
|
|
if prev_http,
|
|
do: Application.put_env(:microwaveprop, :ms_footprints_http_get, prev_http),
|
|
else: Application.delete_env(:microwaveprop, :ms_footprints_http_get)
|
|
end)
|
|
|
|
:ok
|
|
end
|
|
|
|
test "downloads tile when quadkey exists in index" do
|
|
Application.put_env(:microwaveprop, :ms_footprints_http_get, fn url, _opts ->
|
|
if String.contains?(url, "dataset-links.csv") do
|
|
{:ok,
|
|
%{
|
|
status: 200,
|
|
body:
|
|
"RegionName,QuadKey,Url,Size,DatasetDate\nUnitedStates,023112330,http://example.com/tile,1234,2026-01-01\n"
|
|
}}
|
|
else
|
|
{:ok, %{status: 200, body: "fake-gzip-data"}}
|
|
end
|
|
end)
|
|
|
|
assert {:ok, path} = MsFootprints.download_tile("023112330")
|
|
assert File.exists?(path)
|
|
assert File.read!(path) == "fake-gzip-data"
|
|
end
|
|
|
|
test "returns error for unknown quadkey" do
|
|
Application.put_env(:microwaveprop, :ms_footprints_http_get, fn _url, _opts ->
|
|
{:ok, %{status: 200, body: "RegionName,QuadKey,Url,Size,DatasetDate\n"}}
|
|
end)
|
|
|
|
assert {:error, :unknown_quadkey} = MsFootprints.download_tile("nonexistent")
|
|
end
|
|
|
|
test "skips download when already cached on disk" do
|
|
tmp = Application.get_env(:microwaveprop, :buildings_cache_dir)
|
|
File.mkdir_p!(tmp)
|
|
File.write!(Path.join(tmp, "023112330.csv.gz"), "existing-data")
|
|
|
|
assert {:ok, path} = MsFootprints.download_tile("023112330")
|
|
assert File.read!(path) == "existing-data"
|
|
end
|
|
end
|
|
end
|