From 7de1aef64800f8d5a414940e3679365ff656022a Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Fri, 8 May 2026 13:21:53 -0500 Subject: [PATCH] Add coverage tests for HistoricalLoader real-Packets path and Packets edge cases --- test/aprsme/packets_test.exs | 80 +++++++++++++++++++ .../live/map_live/historical_loader_test.exs | 59 ++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/test/aprsme/packets_test.exs b/test/aprsme/packets_test.exs index 8b223bb..af60445 100644 --- a/test/aprsme/packets_test.exs +++ b/test/aprsme/packets_test.exs @@ -1720,6 +1720,86 @@ defmodule Aprsme.PacketsTest do end end + describe "store_packet/1 with string-keyed nested position" do + test "extracts position with string-keyed 'position' map and atom 'latitude' key" do + # Targets find_coordinate_value heads at lines 189-192 — the four + # combinations of string outer key + (atom|string) inner keys. + packet_data = %{ + sender: "POS-MIX", + base_callsign: "POS", + ssid: "1", + destination: "APRS", + raw_packet: "POS-MIX>APRS:test", + data_type: "position", + symbol_table_id: "/", + symbol_code: ">", + data_extended: %{ + "position" => %{latitude: 33.5, longitude: -96.5} + } + } + + result = Packets.store_packet(packet_data) + assert match?({:ok, _}, result) or match?({:error, _}, result) + end + + test "extracts position with string-keyed nested position and string keys" do + packet_data = %{ + sender: "POS-STR", + base_callsign: "POS", + ssid: "1", + destination: "APRS", + raw_packet: "POS-STR>APRS:test", + data_type: "position", + symbol_table_id: "/", + symbol_code: ">", + data_extended: %{ + "position" => %{"latitude" => 33.5, "longitude" => -96.5} + } + } + + result = Packets.store_packet(packet_data) + assert match?({:ok, _}, result) or match?({:error, _}, result) + end + end + + describe "round_coordinate via store_packet with binary string lat/lon" do + test "lat/lon as parseable strings via Float.parse → rounded" do + packet_data = %{ + sender: "BIN-LATLON", + base_callsign: "BIN", + ssid: "1", + destination: "APRS", + raw_packet: "BIN-LATLON>APRS:test", + data_type: "position", + symbol_table_id: "/", + symbol_code: ">", + lat: "33.123456789", + lon: "-96.987654321" + } + + result = Packets.store_packet(packet_data) + assert match?({:ok, _}, result) or match?({:error, _}, result) + end + + test "unparseable lat string falls through round_coordinate to nil" do + packet_data = %{ + sender: "JUNK-LATLON", + base_callsign: "JUNK", + ssid: "1", + destination: "APRS", + raw_packet: "JUNK-LATLON>APRS:test", + data_type: "position", + symbol_table_id: "/", + symbol_code: ">", + lat: "not-a-number", + lon: "also-junk" + } + + result = Packets.store_packet(packet_data) + assert match?({:ok, _}, result) or match?({:error, _}, result) + end + end + describe "get_nearby_stations/4 with empty result set" do test "returns an empty list when no stations are nearby" do result = Packets.get_nearby_stations(85.0, 0.0, nil, %{}) diff --git a/test/aprsme_web/live/map_live/historical_loader_test.exs b/test/aprsme_web/live/map_live/historical_loader_test.exs index 6ac8ff2..33e69c0 100644 --- a/test/aprsme_web/live/map_live/historical_loader_test.exs +++ b/test/aprsme_web/live/map_live/historical_loader_test.exs @@ -7,6 +7,7 @@ defmodule AprsmeWeb.MapLive.HistoricalLoaderTest do import Mox alias AprsmeWeb.MapLive.HistoricalLoader + alias Ecto.Adapters.SQL.Sandbox alias Phoenix.LiveView.Socket setup :verify_on_exit! @@ -33,10 +34,68 @@ defmodule AprsmeWeb.MapLive.HistoricalLoaderTest do %Socket{assigns: Map.merge(defaults, assigns)} end + describe "real Packets module path with seeded packets covers maybe_include_latest_packet" do + setup do + original = Application.get_env(:aprsme, :packets_module) + Application.put_env(:aprsme, :packets_module, Aprsme.Packets) + Sandbox.checkout(Aprsme.Repo) + Sandbox.mode(Aprsme.Repo, {:shared, self()}) + + on_exit(fn -> + Application.put_env(:aprsme, :packets_module, original) + end) + + :ok + end + + test "non-empty tracked callsign with seeded packet exercises latest-packet inclusion" do + Aprsme.PacketsFixtures.packet_fixture(%{ + sender: "TEST-CS", + base_callsign: "TEST", + ssid: "CS", + received_at: DateTime.utc_now(), + lat: Decimal.new("33.5"), + lon: Decimal.new("-96.5"), + has_position: true + }) + + socket = + build_socket(%{ + map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0}, + map_zoom: 10, + historical_loading: true, + loading_generation: 1, + tracked_callsign: "TEST-CS" + }) + + result = HistoricalLoader.load_historical_batch(socket, 0, 1) + assert is_map(result.assigns) + end + + test "non-empty tracked callsign with non-zero batch_offset hits the fallthrough" do + socket = + build_socket(%{ + map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0}, + map_zoom: 10, + historical_loading: true, + loading_generation: 1, + tracked_callsign: "TRACK-N" + }) + + # batch_offset != 0 means maybe_include_latest_packet hits the catch-all + # at line 309 (returns recent_packets unchanged). + result = HistoricalLoader.load_historical_batch(socket, 1, 1) + assert is_map(result.assigns) + end + end + describe "real Packets module path (no mock)" do setup do original = Application.get_env(:aprsme, :packets_module) Application.put_env(:aprsme, :packets_module, Aprsme.Packets) + # Set up DB sandbox so DB queries actually run against the test repo. + Sandbox.checkout(Aprsme.Repo) + Sandbox.mode(Aprsme.Repo, {:shared, self()}) on_exit(fn -> Application.put_env(:aprsme, :packets_module, original) end) :ok end