test: SpatialPubSub broadcast paths and client lifecycle

This commit is contained in:
Graham McIntire 2026-04-24 08:23:03 -05:00
parent b04efb8b6c
commit 791733af45
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59

View file

@ -98,6 +98,73 @@ defmodule Aprsme.SpatialPubSubTest do
end
end
describe "broadcast_packet" do
test "broadcasts to clients whose viewport contains the packet location" do
client_id = "test_bc_#{:rand.uniform(100_000)}"
bounds = %{north: 41.0, south: 40.0, east: -73.0, west: -74.0}
{:ok, topic} = SpatialPubSub.register_viewport(client_id, bounds)
Phoenix.PubSub.subscribe(Aprsme.PubSub, topic)
# Broadcast a packet inside the viewport.
assert :ok = SpatialPubSub.broadcast_packet(%{lat: 40.5, lon: -73.5, sender: "IN1"})
assert_receive {:spatial_packet, %{sender: "IN1"}}, 1_000
SpatialPubSub.unregister_client(client_id)
end
test "does not broadcast to clients outside the viewport" do
client_id = "test_outside_#{:rand.uniform(100_000)}"
bounds = %{north: 41.0, south: 40.0, east: -73.0, west: -74.0}
{:ok, topic} = SpatialPubSub.register_viewport(client_id, bounds)
Phoenix.PubSub.subscribe(Aprsme.PubSub, topic)
# Broadcast far outside bounds.
assert :ok = SpatialPubSub.broadcast_packet(%{lat: 0.0, lon: 0.0, sender: "OUT1"})
refute_receive {:spatial_packet, _}, 100
SpatialPubSub.unregister_client(client_id)
end
test "ignores packets with missing or invalid location" do
# Packet with nil coords should not crash.
assert :ok = SpatialPubSub.broadcast_packet(%{lat: nil, lon: nil})
assert :ok = SpatialPubSub.broadcast_packet(%{lat: "bad", lon: "bad"})
assert :ok = SpatialPubSub.broadcast_packet(%{})
end
test "binary-string coordinates in bounds are parsed" do
client_id = "test_strbounds_#{:rand.uniform(100_000)}"
bounds = %{north: "41.0", south: "40.0", east: "-73.0", west: "-74.0"}
assert {:ok, _topic} = SpatialPubSub.register_viewport(client_id, bounds)
SpatialPubSub.unregister_client(client_id)
end
end
describe "client lifecycle" do
test "unregister removes client from spatial index" do
client_id = "test_unreg_#{:rand.uniform(100_000)}"
bounds = %{north: 41.0, south: 40.0, east: -73.0, west: -74.0}
{:ok, _topic} = SpatialPubSub.register_viewport(client_id, bounds)
before_stats = SpatialPubSub.get_stats()
SpatialPubSub.unregister_client(client_id)
# Give cast time to process
_ = SpatialPubSub.get_stats()
after_stats = SpatialPubSub.get_stats()
assert after_stats.clients_count <= before_stats.clients_count
end
test "update_viewport returns error for unregistered client" do
bounds = %{north: 41.0, south: 40.0, east: -73.0, west: -74.0}
result = SpatialPubSub.update_viewport("never_registered_#{:rand.uniform(100_000)}", bounds)
assert result == {:error, :not_registered}
end
end
describe "when the server is not running" do
setup do
pid = Process.whereis(SpatialPubSub)