Add coverage tests for DeviceCache live process branch, PacketConsumer start_link with name, and integer/Decimal coordinate paths

This commit is contained in:
Graham McIntire 2026-05-08 16:54:26 -05:00
parent 5ba458d505
commit b911bbd626
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
3 changed files with 133 additions and 0 deletions

View file

@ -100,6 +100,28 @@ defmodule Aprsme.DeviceCacheTest do
assert {:noreply, ^state} = DeviceCache.handle_info(:refresh_cache, state)
end
test "refresh_cache/0 calls into the running GenServer process" do
# Start a temporary DeviceCache to exercise the live-process branch
# (line 51: _pid -> GenServer.call(...)).
{:ok, pid} = GenServer.start_link(DeviceCache, [])
original_pid = Process.whereis(DeviceCache)
if original_pid, do: :erlang.unregister(DeviceCache)
Process.register(pid, DeviceCache)
try do
assert DeviceCache.refresh_cache() == :ok
after
if Process.whereis(DeviceCache) == pid, do: :erlang.unregister(DeviceCache)
if original_pid && !Process.whereis(DeviceCache) do
Process.register(original_pid, DeviceCache)
end
Process.exit(pid, :normal)
end
end
test "initial_load in non-test env loads real devices from the DB" do
# The load_devices_into_cache non-test branch reads Repo.all(Devices).
# Swap env, then trigger and restore.

View file

@ -7,6 +7,70 @@ defmodule Aprsme.PacketConsumerTest do
alias Aprsme.PacketConsumer
alias Aprsme.StreamingPacketsPubSub
describe "start_link/1" do
test "starts an unnamed GenStage consumer when no :name option is given" do
assert {:ok, pid} = PacketConsumer.start_link(subscribe_to: [])
assert is_pid(pid)
GenStage.stop(pid)
end
test "starts a named GenStage consumer when :name is provided" do
name = :"test_consumer_#{System.unique_integer([:positive])}"
assert {:ok, pid} = PacketConsumer.start_link(name: name, subscribe_to: [])
assert Process.whereis(name) == pid
GenStage.stop(pid)
end
end
describe "normalize_numeric_types via handle_events with integer weather field" do
test "integer temperature is coerced to float by normalize_numeric_types" do
events = [
%{
sender: "INT-T",
base_callsign: "INT-T",
ssid: "0",
destination: "APRS",
path: "WIDE1-1",
data_type: "position",
lat: 33.0,
lon: -96.0,
# Integer weather value should be coerced to float (line 774).
temperature: 72,
humidity: 50,
wind_speed: 5,
information_field: "test",
raw_packet: "INT-T>APRS"
}
]
state = %{batch: [], batch_length: 0, batch_size: 1, batch_timeout: 1000, max_batch_size: 100, timer: nil}
{:noreply, [], _new_state} = PacketConsumer.handle_events(events, nil, state)
Process.sleep(50)
end
test "ssid passed as integer gets normalized to string by normalize_ssid" do
events = [
%{
sender: "SSID-INT",
base_callsign: "SSID-INT",
# Integer ssid hits the to_string branch in normalize_ssid (line 737).
ssid: 9,
destination: "APRS",
path: "WIDE1-1",
data_type: "position",
lat: 33.0,
lon: -96.0,
information_field: "test",
raw_packet: "SSID-INT>APRS"
}
]
state = %{batch: [], batch_length: 0, batch_size: 1, batch_timeout: 1000, max_batch_size: 100, timer: nil}
{:noreply, [], _new_state} = PacketConsumer.handle_events(events, nil, state)
Process.sleep(50)
end
end
describe "init/1" do
test "returns a :consumer tuple with default configuration" do
# Start an isolated consumer with no subscription to avoid contaminating

View file

@ -1812,6 +1812,53 @@ defmodule Aprsme.PacketsTest do
end
end
describe "round_coordinate via store_packet with various input types" do
test "store_packet with Decimal lat/lon hits round_coordinate(%Decimal{})" do
packet = %{
sender: "DEC-COORD",
base_callsign: "DEC-COORD",
ssid: "0",
destination: "APRS",
raw_packet: "DEC-COORD>APRS",
data_type: "position",
lat: Decimal.new("33.123456789"),
lon: Decimal.new("-96.987654321")
}
assert {:ok, _} = Packets.store_packet(packet)
end
test "store_packet with integer lat/lon hits round_coordinate(integer)" do
packet = %{
sender: "INT-COORD",
base_callsign: "INT-COORD",
ssid: "0",
destination: "APRS",
raw_packet: "INT-COORD>APRS",
data_type: "position",
lat: 33,
lon: -96
}
assert {:ok, _} = Packets.store_packet(packet)
end
test "store_packet with valid binary lat/lon hits round_coordinate(binary) parse path" do
packet = %{
sender: "BIN-COORD",
base_callsign: "BIN-COORD",
ssid: "0",
destination: "APRS",
raw_packet: "BIN-COORD>APRS",
data_type: "position",
lat: "33.5",
lon: "-96.5"
}
assert {:ok, _} = Packets.store_packet(packet)
end
end
describe "store_bad_packet/2 with various error shapes" do
test "store_bad_packet/2 with binary packet_data and a struct error uses Exception.message" do
result = Packets.store_bad_packet("rawpacket-binary", %ArgumentError{message: "boom"})