test: Add comprehensive tests for non-position packets and edge cases

- Added tests for packets with has_position: false (status, messages, telemetry)
- Added callsign normalization to handle whitespace-only callsigns
- Added tests for edge cases (whitespace, lowercase callsigns)
- Improved robustness of callsign tracking feature

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Graham McIntire 2025-07-30 14:09:43 -05:00
parent 047cd3a7ce
commit 4213fa3105
No known key found for this signature in database
2 changed files with 124 additions and 6 deletions

View file

@ -450,18 +450,22 @@ defmodule Aprsme.Packets do
# Build base query with time filter
# Only filter by position if not tracking a specific callsign
# Also normalize callsign to handle edge cases
callsign = opts[:callsign]
normalized_callsign = if is_binary(callsign), do: String.trim(callsign), else: ""
base_query =
if Map.has_key?(opts, :callsign) and opts[:callsign] != nil and opts[:callsign] != "" do
# When tracking a callsign, show all their packets regardless of position
from(p in Packet,
where: p.received_at >= ^time_ago
)
else
if normalized_callsign == "" do
# For general map view, only show packets with positions
from(p in Packet,
where: p.has_position == true,
where: p.received_at >= ^time_ago
)
else
# When tracking a callsign, show all their packets regardless of position
from(p in Packet,
where: p.received_at >= ^time_ago
)
end
# Apply spatial and other filters BEFORE limiting

View file

@ -122,5 +122,119 @@ defmodule AprsmeWeb.MapLive.TrackedCallsignOldPacketTest do
assert socket.assigns.tracked_callsign == "NOPACKETS-1"
assert socket.assigns.tracked_latest_packet == nil
end
test "displays non-position packet for tracked callsign", %{conn: conn} do
# Create a status packet without position data - this is the key test case
non_position_packet =
packet_fixture(%{
sender: "TEST-STATUS",
raw_packet: "TEST-STATUS>APRS:>Status message without position",
received_at: DateTime.utc_now(),
has_position: false,
lat: nil,
lon: nil,
data_type: "status"
})
# Navigate to the tracked callsign URL
{:ok, view, _html} = live(conn, "/TEST-STATUS")
# Wait for map to be ready
send(view.pid, %{
event: "map_ready",
data: %{
center: %{lat: 35.0, lng: -97.0},
zoom: 10,
bounds: %{
north: 36.0,
south: 34.0,
east: -96.0,
west: -98.0
}
}
})
:timer.sleep(100)
# Check that the tracked callsign is set
assert render(view) =~ "TEST-STATUS"
# The non-position packet should still be loaded
state = :sys.get_state(view.pid)
socket = elem(state, 1).socket
assert socket.assigns.tracked_callsign == "TEST-STATUS"
assert socket.assigns.tracked_callsign_latest_packet.id == non_position_packet.id
assert socket.assigns.tracked_callsign_latest_packet.has_position == false
end
test "displays message packet without position for tracked callsign", %{conn: conn} do
# Create a message packet without position data
message_packet =
packet_fixture(%{
sender: "TEST-MSG",
raw_packet: "TEST-MSG>APRS::W5ISP :Hello there! This is a test message{001",
# 1 hour old
received_at: DateTime.add(DateTime.utc_now(), -3600, :second),
has_position: false,
lat: nil,
lon: nil,
data_type: "message",
aprs_messaging: true
})
# Navigate to the tracked callsign URL
{:ok, view, _html} = live(conn, "/TEST-MSG")
# The message packet should be tracked despite no position
state = :sys.get_state(view.pid)
socket = elem(state, 1).socket
assert socket.assigns.tracked_callsign == "TEST-MSG"
assert socket.assigns.tracked_callsign_latest_packet.id == message_packet.id
assert socket.assigns.tracked_callsign_latest_packet.aprs_messaging == true
end
test "handles whitespace in callsign parameter", %{conn: conn} do
# Create a packet for testing
packet =
packet_fixture(%{
sender: "TEST-WS",
raw_packet: "TEST-WS>APRS:>Test whitespace handling",
has_position: false
})
# Navigate with extra whitespace
{:ok, view, _html} = live(conn, "/ TEST-WS ")
# Should normalize to uppercase and trim whitespace
state = :sys.get_state(view.pid)
socket = elem(state, 1).socket
# The callsign should be normalized (trimmed and uppercased)
assert socket.assigns.tracked_callsign == "TEST-WS"
assert socket.assigns.tracked_callsign_latest_packet.id == packet.id
end
test "handles lowercase callsign with non-position packet", %{conn: conn} do
# Create a telemetry packet without position
telemetry_packet =
packet_fixture(%{
sender: "TEST-TELEM",
raw_packet: "TEST-TELEM>APRS:T#123,456,789,012,345,678,00000000",
has_position: false,
data_type: "telemetry"
})
# Navigate with lowercase callsign
{:ok, view, _html} = live(conn, "/test-telem")
state = :sys.get_state(view.pid)
socket = elem(state, 1).socket
# Should normalize to uppercase
assert socket.assigns.tracked_callsign == "TEST-TELEM"
assert socket.assigns.tracked_callsign_latest_packet.id == telemetry_packet.id
end
end
end