Dialyzer: * Add Lidar.Tile @type, narrow several @specs to match success-typing, prefix discarded function returns with `_ =`, fix the broken File.stream! call in the ms-buildings worker (it was causing dialyzer to mark every private fun unreachable), broaden Antenna.spec key types from `float()` to `number()` to match catalog int literals. * Add :geo, :geo_postgis, :db_connection to plt_add_apps so the dep PLT actually contains the modules we use. * Result: 0 unsuppressed dialyzer warnings (was 50+ in project code). Tree canopy: * Replace the dead landfire.gov URL with the ETH Zurich Global Canopy Height 10 m product. ETH publishes proper COGs with overviews on libdrive.ethz.ch — confirmed working with /vsicurl/ byte-range reads. The module now picks the 3°×3° tile containing the bbox centroid, with both a `:metres` decoder (ETH Byte raster, NoData=255) and a `:landfire_evh` decoder for operators self-hosting LANDFIRE EVH COGs. * Re-enable canopy by default now that there's a working source. Tests (+105 tests, 0 failures): * CoverageLive Index/Show/Form/Map — empty/loaded/auth states, LiveView event handlers, formatters. * Coverages.Building changeset + helpers. * Coverages.TreeCanopy provider tile-URL builder and decoders. * Workers.MsBuildingsImportWorker (full import flow incl. blank lines, MultiPolygon, idempotency, hash fallback) — also fixed the partial-index ON CONFLICT bug that prevented imports from ever working: the unique index has WHERE ms_footprint_id IS NOT NULL, so the worker now uses an :unsafe_fragment conflict target that includes the predicate. * GraphQLDocsController smoke test (was 0%). Coverage rose from 73.19% → 74% with the major project modules I touched all moved from 0% / <50% to >75%.
56 lines
1.6 KiB
Elixir
56 lines
1.6 KiB
Elixir
defmodule ToweropsWeb.CoverageLive.FormTest do
|
|
use ToweropsWeb.ConnCase
|
|
|
|
import Phoenix.LiveViewTest
|
|
import Towerops.CoveragesFixtures
|
|
import Towerops.OrganizationsFixtures
|
|
|
|
setup :register_and_log_in_user
|
|
|
|
setup %{conn: conn, user: user} do
|
|
org = organization_fixture(user.id)
|
|
site = site_fixture(org.id, %{latitude: 30.27, longitude: -97.74})
|
|
conn = Plug.Conn.put_session(conn, :current_organization_id, org.id)
|
|
|
|
%{conn: conn, org: org, site: site}
|
|
end
|
|
|
|
describe "new" do
|
|
test "renders the new-coverage form", %{conn: conn} do
|
|
{:ok, _view, html} = live(conn, ~p"/coverage/new")
|
|
assert html =~ "New Coverage" or html =~ "Coverage"
|
|
end
|
|
|
|
test "validate event re-renders with errors for blank name", %{conn: conn} do
|
|
{:ok, view, _html} = live(conn, ~p"/coverage/new")
|
|
|
|
html =
|
|
view
|
|
|> form("form", coverage: %{"name" => ""})
|
|
|> render_change()
|
|
|
|
assert html =~ "Coverage"
|
|
end
|
|
|
|
test "requires authentication" do
|
|
conn = build_conn()
|
|
assert {:error, {:redirect, %{to: path}}} = live(conn, ~p"/coverage/new")
|
|
assert path =~ "/users/log-in"
|
|
end
|
|
end
|
|
|
|
describe "edit" do
|
|
test "renders the edit form populated with the existing coverage", %{conn: conn, org: org, site: site} do
|
|
cov = coverage_fixture(org.id, site.id, %{name: "EditMe"})
|
|
|
|
{:ok, _view, html} = live(conn, ~p"/coverage/#{cov.id}/edit")
|
|
assert html =~ "EditMe"
|
|
end
|
|
|
|
test "404 for unknown coverage", %{conn: conn} do
|
|
assert_raise Ecto.NoResultsError, fn ->
|
|
live(conn, ~p"/coverage/#{Ecto.UUID.generate()}/edit")
|
|
end
|
|
end
|
|
end
|
|
end
|