Commit graph

112 commits

Author SHA1 Message Date
d0296c9f4e
Expand mobile channel, packet consumer, and user settings tests for coverage 2026-05-08 12:08:21 -05:00
57077e2bb1
Add coverage tests for partition manager, map live message handlers, display manager, weather/device id paths
Bumps total coverage to 88.11%.
2026-05-08 12:03:10 -05:00
f9cfbf630e
Improve test coverage to 88.02%
Adds tests covering:
- Aprsme.Packet edge cases (already committed)
- Encoding valid_codepoint? branches via slow grapheme path and encoding_info shapes
- ErrorHandler database/network error categorization (CastError, ConstraintError, QueryError, Postgrex.Error, RuntimeError circuit_open/timeout, custom map :reason)
- HealthCheck plug ask_shutting_down? nil and unresponsive-pid paths
- SpatialPubSub ensure_float branches, dateline broadcast wrap-around, monitored client DOWN handler, no-coordinate broadcast skip
- DataBuilder weather popup, weather-only fallback, tuple value conversion, string weather convert_unit branches
- DeviceIdentification fetch_devices_from_url default-arg head
- PageController format_uptime branches via fake Aprsme.Is GenServer
- WeatherLive.CallsignView compare_timestamps branches via :weather_packet messages
- PacketConsumer field-conversion private helpers via crafted handle_events events
2026-05-08 11:58:09 -05:00
1e32ce7051
Improve test coverage to 87% and point vendor/aprs submodule at codeberg
Coverage:
- Adds focused tests across 13 files covering previously-uncovered
  branches: Packet changeset normalisation (course, wind_direction,
  struct data_extended); Packets store_packet edge cases (nested
  position shapes, ssid handling, string-keyed raw_packet);
  DeviceIdentification HTTP success/404 via Req plug stub; ResendAdapter
  catch-all body, deliver_many, nil/binary formatters; ApiDocsLive
  packets with missing fields; AprsSymbol normalize helpers;
  BadPacketsLive refresh and postgres_notify; MobileChannel handle_info
  catch-all and postgres_packet path; PacketProcessor existing-marker
  movement detection; PacketReplay sanitize_value type clauses;
  InsertOptimizer GenServer lifecycle and negative-duration metric;
  PageController shutdown-handler integration; UrlParams delegated
  helpers.
- mix.exs: configure test_coverage with summary threshold of 87 and
  ignore_modules for test fixtures and macro-only template modules.

Bug fix:
- MapLive.Index handle_info: add a clause for the raw {:new_deployment,
  _} tuple. Phoenix.PubSub.broadcast delivers the raw payload to plain
  subscribers, but the existing handler only matched the %Broadcast{}
  fast-lane wrapper. DeploymentNotifier broadcasts via the raw path,
  which crashed the LiveView under test concurrency.

Submodule:
- Update .gitmodules vendor/aprs URL from
  https://github.com/aprsme/aprs.git to
  ssh://git@codeberg.org/gmcintire/aprs.git.
2026-05-05 15:18:28 -05:00
145ff5fecd
test: MapLive historical_loading_timeout matching generation + show_error handler 2026-04-24 09:57:11 -05:00
a1f88c41bd
test: expand coverage for StatusLive cluster render + MobileChannel type conversions 2026-04-24 09:53:10 -05:00
4a4e25c08f
test: cover InfoLive.Show path decode branches + position fallback 2026-04-24 09:51:07 -05:00
4875904303
test: InfoLive.Show weather link + no-packet branches 2026-04-24 09:07:29 -05:00
e3a6a8268d
test: MapLive tracked-callsign filtering + trail duration cleanup 2026-04-24 09:03:31 -05:00
cde015deca
test: MapLive.Index invalid-bounds rejection 2026-04-24 09:01:48 -05:00
dcb759ecfa
test: InfoLive.Show PHG render paths 2026-04-24 08:59:36 -05:00
d01a15eac0
test: reset Hammer rate limiter state in MapLive.Index suite 2026-04-24 08:54:56 -05:00
a9647916fa
test: PacketsLive.CallsignView overflow + iso8601 broadcast paths 2026-04-24 08:46:35 -05:00
1b8d359f41
test: StatusLive.Index health_score 3/4 render paths 2026-04-24 08:44:47 -05:00
c264a9bc3d
test: HistoricalLoader RF path + low-zoom heat map paths 2026-04-24 08:32:29 -05:00
ee0830a7fc
test: InfoLive.Show heard-by stations path decoding 2026-04-24 08:20:47 -05:00
25804a6f7f
test: InfoLive.Show renders with seeded device identifier 2026-04-24 08:20:03 -05:00
6f142a7391
fix(weather): use Map.get for fallback comment access; add WeatherLive render tests 2026-04-24 08:15:01 -05:00
5bb9b05e31
test: MapLive tracked callsign render + deployment_events broadcast 2026-04-24 08:12:53 -05:00
43036a6b6d
test: StatusLive.Index connected-path render via cached status 2026-04-24 08:08:24 -05:00
34729f8769
test: HistoricalLoader cursor/zoom/limit edge cases 2026-04-24 08:07:22 -05:00
1b9743191a
test: broader InfoLive rendering + PacketReplay update_filters branches 2026-04-23 18:23:55 -05:00
bdcba9b18e
test: InfoLive.Show broadcast paths with position change 2026-04-23 18:18:26 -05:00
4c94dc3059
test: MapLive.Index event edge cases + clear_and_reload at low zoom 2026-04-23 18:14:44 -05:00
5f64a43304
test: additional MapLive.Index handle_info + InfoLive path decoders 2026-04-23 18:08:10 -05:00
965e177841
test: HistoricalLoader bounds-driven load paths via mock 2026-04-23 18:06:17 -05:00
fac52cf288
test: broaden coverage across Packets/Weather/Info/Map/Status modules 2026-04-23 18:04:36 -05:00
0f4e5234f1
test: add InfoLive.Show scenarios for various packet types and broadcasts 2026-04-23 17:44:45 -05:00
001303d17c
test: integration tests for spatial_packet and packet_batch paths 2026-04-23 17:39:37 -05:00
a285eb815b
test: add PacketsLive.CallsignView mount tests 2026-04-23 17:22:23 -05:00
dac0198825
test: add MapLive.Index integration tests with real DB packets 2026-04-23 17:22:23 -05:00
30d852fbc5
test: info_live full render with various packet types 2026-04-23 17:11:50 -05:00
3eec54439b
test: add MapLive.Index zoom threshold and tracking tests 2026-04-23 17:05:59 -05:00
b4d0093a8f
test: add MapLive.Index URL param and callsign route tests 2026-04-23 17:05:59 -05:00
adb304e069
test: cover HistoricalLoader pure functions 2026-04-23 17:05:59 -05:00
0a1c5aa61d
test: add ApiDocsLive full-packet path to exercise format functions 2026-04-23 16:58:13 -05:00
e3dfdf03ba
test: cover PacketConsumer init and process_batch callbacks 2026-04-23 16:58:13 -05:00
f0db8f711e
test: add MapLive.Index message handler tests 2026-04-23 16:58:13 -05:00
b6adf64dbd
test: add MapLive.Index event-handler integration tests 2026-04-23 16:51:42 -05:00
91c9220a2d
test: cover ThemeManager selector, ApiDocsLive packet path and InfoLive Show integration 2026-04-23 16:49:54 -05:00
a5b2c4bccb
test: cover UserAuth, StatusLive handlers and UserNotifier 2026-04-23 16:40:47 -05:00
46e71019de
test: expand coverage for Layouts, DeviceCache, Components and others 2026-04-23 16:36:01 -05:00
41731257e6
test: cover auth LiveViews, PacketReplay, ShutdownHandler and more 2026-04-23 16:30:51 -05:00
fa893dd12e
test: cover ErrorHTML, Layouts, MapLive.Components, CoreComponents, Accounts
- ErrorHTML: explicit 400 path + 401/403/999 delegation.
- Layouts.body_class/1 returns the expected light/dark theme classes.
- MapLive.Components: map_container + slideover_panel exercising all
  connection_status variants, loading state, tracked_callsign clear
  button, and view-mode radios.
- CoreComponents: icon (found + fallback), button, label, error,
  flash (info + error + close=false), checkbox input, JS composers.
- Accounts: get_user_by_email{_and_password}, get_user!, register_user
  happy-path + error paths, change_* changesets, session-token
  round-trip.

Refactor: DeviceIdentification.maybe_refresh_devices splits its nested
logic into fetch_most_recent_device/0, to_datetime/1, and
refresh_if_stale/2 — each a multi-clause function matching on shape.

Coverage 68.28 → 69.56%.
2026-04-23 16:16:31 -05:00
1d68868d27
refactor: pattern-match InfoLive.Show path parsing + add tests
- parse_path_element_with_link splits its fat `if`/or-chain into three
  focused helpers: linkable_callsign?/1 (regex + alias check),
  path_alias?/1 (four String.starts_with guards), and
  classify_path_element/2 (link vs. text dispatched on the boolean).
- display_for_element/2 chooses the callsign form with/without the
  asterisk via two function heads instead of an inline `if`.

Adds 7 tests covering the parse_path_with_links/1 public API — plain
callsigns, heard-via asterisk preservation, non-linkable aliases
(WIDE/TRACE/RELAY/TCPIP), q-constructs, whitespace trimming, and mixed
paths.
2026-04-23 14:23:16 -05:00
35bd098b30
refactor: more pattern matching + drop unreachable get_field_value clause
- Aprsme.Packet.put_phg_fields: dispatch on the shape of the phg value
  (map / 4-char binary / anything else) via put_phg_fields_for/2.
- Aprsme.Packet.get_field_value: remove the catch-all nil clause. After
  the put_phg_fields refactor, dialyzer can prove every call site passes
  a map and flagged the fallback as unreachable — so it's gone, and
  a future mistyped caller now fails loudly instead of silently.
- LogSanitizer.sanitize_map: extract redact_field/2 for readability.
- DeviceIdentification.pattern_matches?: match_pattern/3 dispatched on
  String.contains?/2 keeps the rescue tight around the regex path.
- InfoLive.Show: get_received_at pattern-matches on key shape;
  format_distance splits locale × range via four format_*_distance
  helpers; calculate_course pipes through normalize_bearing/1.

Adds 15 tests exercising the InfoLive.Show helpers (imperial vs. metric
formatting, cardinal bearings, haversine symmetry, Decimal inputs).
Coverage 67.43 → 67.72%.
2026-04-23 14:09:53 -05:00
ee02769d38
refactor: pattern-match in HealthCheck, EncodingUtils, and StatusLive helpers
- HealthCheck.check_health(:readiness): collapse the 3-branch cond into
  readiness_status/2 dispatched on (health_status, shutting_down?).
- HealthCheck.shutting_down?: the whereis + alive? + try/catch nest
  becomes a small pipeline of function heads (ask_shutting_down?/1 +
  ask_if_alive/2), with the catch isolated to the single place it fires.
- EncodingUtils.sanitize_string_fields and sanitize_nested_map shared a
  three-branch atom-or-string key lookup. Extract update_existing_key/3
  + first_present_key/3 + nil_aware/1 helpers; the original functions
  become two-liners.
- StatusLive.Index.format_uptime: splits the cond into
  format_uptime_parts/4 clauses with numeric guards.
- StatusLive.Index.calculate_health_score: struct-shape pattern match
  on %{connected: false} / %{uptime_seconds: s} guards replaces the cond.
- StatusLive.Index.format_time_ago: pipe the diff through
  format_seconds_ago/1 with four clauses.

Adds tests for the four public StatusLive.Index helpers
(format_uptime, format_time_ago, get_health_description, format_number).
Coverage 67.29 → 67.43%.
2026-04-23 14:02:50 -05:00
7db78675a2
refactor: collapse nested if/case into pattern-matched helpers
- SharedPacketHandler.handle_packet_update: dispatch on filter-result,
  and use maybe_enrich/2 dispatched on the enrich? boolean instead of
  an inner `if`. lookup_device_info/1 is now a trio of function heads.
- Cluster.Topology.child_spec: build_spec/3 dispatches on
  (cluster_enabled?, topologies) tuples — no more nested `if`.
- Cluster.PacketDistributor.distribute_packet: maybe_broadcast/2
  dispatches on the leader-and-enabled check; the non-leader / disabled
  paths return :ok explicitly instead of relying on an `if` expression's
  implicit nil.

Adds tests for SharedPacketHandler (filter/enrich/match paths,
callsign_filter + callsign_and_weather_filter factories) and extends
Cluster.Topology tests to cover the nil-topology and opts-merge cases.
Coverage 66.41 → 66.81%.
2026-04-23 13:55:11 -05:00
e43107a25f
refactor(packet_processor): split cond/if into multi-clause helpers
- render_for_zoom/3: zoom ≤ 8 uses heatmap; high zoom with marker_data
  pushes to the client; high zoom + nil marker_data is a no-op. Each
  branch is now a separate function head.
- push_new_packet/3: a boolean-dispatched pair replaces the popup-open
  conditional on the push_event payload.
- prepare_packet_state: the two rebinding `if`s turn into a pipeline
  through prune_if_over_cap/1 (pattern-matched on map_size/1) and
  build_marker_data/5 with a zoom ≤ 8 short-circuit clause, plus
  maybe_tag_convert_from/3 for the replacement-marker tag.
- moved_significantly?/3: the duplicated guard check between
  dispatch_visibility and batch_dispatch collapses into one helper that
  pattern-matches on the coordinate tuple returned by CoordinateUtils.

Adds extra tests covering the new significance / stale-coords branches
and the connection card LiveComponent render paths. Coverage 65.89 → 66.41%.
2026-04-23 13:51:17 -05:00
c5a82b77c1
refactor: pattern-match over conditionals in Navigation and InsertOptimizer
Swaps `if`/`cond` branches for multi-clause function heads or head-pattern
matching, making the control flow visible in the function signatures:

- Navigation.determine_map_location: resolve_location/4 now dispatches on
  the shape of the geolocation input and whether URL params are explicit.
- Navigation.handle_callsign_tracking: per-case clauses for empty callsign
  and explicit-URL-params short-circuits, plus a final clause that does the
  DB lookup and rescues once.
- Navigation.handle_callsign_search: dispatch_callsign_search/3 separates
  the valid/invalid callsign branches.
- InsertOptimizer.optimize_based_on_performance: pattern-match on
  [_, _, _ | _] to require ≥3 samples without calling length/1.
- InsertOptimizer.calculate_insert_options and throughput helpers split
  into guarded clauses instead of inline `if`.
- maybe_emit_optimization uses same-var pattern matching to skip the
  telemetry hit when nothing changed.

Adds unit tests covering every branch of both modules plus SignalHandler,
LocaleHook, and the InsertOptimizer's :noproc fallback path. Coverage
64.69% → 65.72%.
2026-04-23 13:38:24 -05:00