- Remove Mox.set_mox_global() in DPW extra test; rely on $callers
instead so concurrent vendor SNMP tests stop intermittently failing
with VerificationError.
- Make ToweropsWeb.Plugs.GraphQLIntrospectionTest async: false. It
mutates Application.put_env(:towerops, :env, :prod), which polluted
every async vendor test that reads :env via
Towerops.Snmp.Client.phoenix_snmp_disabled/0.
- Bump test pool queue_target/queue_interval. AgentChannelTest spawns
many `:proc_lib` channel processes that hold sandbox connections;
the default 50ms queue caused intermittent
'could not checkout the connection' errors.
- Tag real-System.cmd("ping") tests as :network so they're excluded
by default. Saves ~20s on every full run.
- Make JobCleanupTask's internal 1s settle sleep configurable via
:job_cleanup_settle_ms; the test overrides it to 0.
Plus the pending CoverageLive.Form edit-save / EIRP recompute and
TraceLive deep-link tests from before the compact.
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%.