defmodule AprsmeWeb.MapLive.RfPathTest do use AprsmeWeb.ConnCase import AprsmeWeb.TestHelpers import Phoenix.LiveViewTest alias AprsmeWeb.MapLive.Index describe "RF path parsing" do test "parses RF paths correctly", %{conn: conn} do # Test the parse_rf_path function indirectly through module # Since it's a private function, we test the behavior {:ok, _digi1} = create_test_packet(%{ sender: "K5GVL-10", base_callsign: "K5GVL", ssid: "10", lat: Decimal.new("33.1000"), lon: Decimal.new("-96.6000"), symbol_table_id: "#", symbol_code: "r" }) {:ok, view, _html} = live(conn, "/", on_error: :warn) # Send a marker_hover_start event render_hook(view, "marker_hover_start", %{ "id" => "test-1", "path" => "K5GVL-10*,WIDE1-1,WIDE2-1", "lat" => 33.2837, "lng" => -96.5728 }) # The function should parse the path and try to find positions # We can't directly test the private function, but we can verify no errors occur assert view.module == Index end test "parses complex RF paths with multiple stations", %{conn: conn} do # Create multiple stations that could be in the path {:ok, _station1} = create_test_packet(%{ sender: "N5ABC", base_callsign: "N5ABC", ssid: nil, lat: Decimal.new("33.2000"), lon: Decimal.new("-96.6000") }) {:ok, _station2} = create_test_packet(%{ sender: "WB5DEF-1", base_callsign: "WB5DEF", ssid: "1", lat: Decimal.new("33.3000"), lon: Decimal.new("-96.7000") }) {:ok, view, _html} = live(conn, "/", on_error: :warn) # Test path with multiple digipeaters render_hook(view, "marker_hover_start", %{ "id" => "test-complex", "path" => "N5ABC,WB5DEF-1,WIDE2-1,qAR,K5VOM-10", "lat" => 33.2837, "lng" => -96.5728 }) # Should handle complex paths without errors assert view.module == Index end test "handles paths with asterisks correctly", %{conn: conn} do {:ok, _station} = create_test_packet(%{ sender: "WA5VHU-8", base_callsign: "WA5VHU", ssid: "8", lat: Decimal.new("33.1500"), lon: Decimal.new("-96.5500") }) {:ok, view, _html} = live(conn, "/", on_error: :warn) # Test path with asterisks (used digipeaters) render_hook(view, "marker_hover_start", %{ "id" => "test-asterisk", "path" => "WA5VHU-8,WIDE1*,WIDE2-1,qAR,K5VOM-10", "lat" => 33.2837, "lng" => -96.5728 }) # Should handle asterisks without errors assert view.module == Index end test "filters out TCPIP from paths", %{conn: conn} do {:ok, view, _html} = live(conn, "/", on_error: :warn) # Send a hover event with TCPIP in path render_hook(view, "marker_hover_start", %{ "id" => "test-2", "path" => "TCPIP*,qAC,T2TEXAS", "lat" => 33.2837, "lng" => -96.5728 }) # Should not crash and should filter out TCPIP assert view.module == Index end test "filters out APRS beacon patterns from paths", %{conn: conn} do # Create a real station that should be included {:ok, _station} = create_test_packet(%{ sender: "KC5ABC-9", base_callsign: "KC5ABC", ssid: "9", lat: Decimal.new("33.2500"), lon: Decimal.new("-96.6500") }) {:ok, view, _html} = live(conn, "/", on_error: :warn) # Send a hover event with various beacon patterns that should be filtered render_hook(view, "marker_hover_start", %{ "id" => "test-beacons", "path" => "KC5ABC-9,WIDE1-1,WIDE2-1,TRACE3-3,RELAY,ECHO,HOP7-7", "lat" => 33.2837, "lng" => -96.5728 }) # Should filter out all beacon patterns but keep KC5ABC-9 assert view.module == Index end test "handles empty paths gracefully", %{conn: conn} do {:ok, view, _html} = live(conn, "/", on_error: :warn) # Send hover event with empty path render_hook(view, "marker_hover_start", %{"id" => "test-3", "path" => "", "lat" => 33.2837, "lng" => -96.5728}) # Should not crash assert view.module == Index end test "marker hover end event works", %{conn: conn} do {:ok, view, _html} = live(conn, "/", on_error: :warn) # Send hover end event render_hook(view, "marker_hover_end", %{"id" => "test-1"}) # Should not crash assert view.module == Index end end describe "path station position queries" do setup do # Create test packets with positions {:ok, _digi1} = create_test_packet(%{ sender: "K5GVL-10", base_callsign: "K5GVL", ssid: "10", lat: Decimal.new("33.1000"), lon: Decimal.new("-96.6000") }) {:ok, _digi2} = create_test_packet(%{ sender: "N5TXZ-10", base_callsign: "N5TXZ", ssid: "10", lat: Decimal.new("33.2000"), lon: Decimal.new("-96.5000") }) :ok end test "finds positions for digipeaters in path", %{conn: conn} do {:ok, view, _html} = live(conn, "/", on_error: :warn) # Send hover event with known digipeaters render_hook(view, "marker_hover_start", %{ "id" => "test-4", "path" => "K5GVL-10*,N5TXZ-10", "lat" => 33.2837, "lng" => -96.5728 }) # The function should find these stations assert view.module == Index end end describe "RF path with stations outside bounds" do setup do # Create test packets - one inside a small bounds, one outside # Station inside typical Texas bounds {:ok, _inside_station} = create_test_packet(%{ sender: "K5INSIDE-10", base_callsign: "K5INSIDE", ssid: "10", # Inside Texas area lat: Decimal.new("32.5000"), # Inside Texas area lon: Decimal.new("-96.5000") }) # Station outside bounds (way outside in Boston area) {:ok, _outside_station} = create_test_packet(%{ sender: "W1OUTSIDE-10", base_callsign: "W1OUTSIDE", ssid: "10", # Boston area - far from Texas lat: Decimal.new("42.0000"), # Boston area - far from Texas lon: Decimal.new("-71.0000") }) :ok end test "includes path stations outside map bounds", %{conn: conn} do {:ok, view, _html} = live(conn, "/", on_error: :warn) # Set map bounds to a small area around Texas that excludes the outside station bounds = texas_bounds() render_hook(view, "bounds_changed", %{"bounds" => bounds}) # Now hover over a marker with a path that includes both inside and outside stations render_hook(view, "marker_hover_start", %{ "id" => "test-bounds", # Both inside and outside stations "path" => "K5INSIDE-10*,W1OUTSIDE-10", "lat" => 32.5, "lng" => -96.5 }) # With the fix, both stations should be found regardless of bounds # The test passes if no errors occur during the hover event assert view.module == Index end test "finds stations regardless of bounds constraints", %{conn: conn} do {:ok, view, _html} = live(conn, "/", on_error: :warn) # Set very restrictive bounds that exclude both stations bounds = restrictive_bounds() render_hook(view, "bounds_changed", %{"bounds" => bounds}) # Hover with path containing stations outside these bounds render_hook(view, "marker_hover_start", %{ "id" => "test-no-bounds", "path" => "K5INSIDE-10,W1OUTSIDE-10", "lat" => 32.5, "lng" => -96.5 }) # Should work without errors - stations found regardless of bounds assert view.module == Index end end end