defmodule AprsmeWeb.MapLive.MovementTest do use AprsmeWeb.ConnCase, async: false import Mox import Phoenix.LiveViewTest alias Aprsme.GeoUtils setup :verify_on_exit! describe "GPS drift filtering" do setup do stub(Aprsme.PacketsMock, :get_recent_packets, fn _args -> [] end) :ok end test "does not update marker for GPS drift", %{conn: conn} do {:ok, view, _html} = live(conn, "/", on_error: :warn) assert render_hook( view, "update_map_state", %{"center" => %{"lat" => 33.16961, "lng" => -96.4921}, "zoom" => 9} ) bounds_params = %{ "bounds" => %{ "north" => 33.18, "south" => 33.16, "east" => -96.48, "west" => -96.50 } } assert render_hook( view, "bounds_changed", bounds_params ) initial_packet = %{ id: "TEST-1", sender: "TEST-1", base_callsign: "TEST", lat: 33.16961, lon: -96.4921, has_position: true, received_at: DateTime.utc_now() } send(view.pid, {:postgres_packet, initial_packet}) drift_packet = %{ id: "TEST-1", sender: "TEST-1", base_callsign: "TEST", lat: 33.169655, lon: -96.4921, has_position: true, received_at: DateTime.utc_now() } send(view.pid, {:postgres_packet, drift_packet}) Phoenix.LiveViewTest.render(view) refute Phoenix.LiveViewTest.refute_push_event( view, "new_packet", %{id: "TEST-1"}, 50 ) end test "updates marker for significant movement", %{conn: conn} do {:ok, view, _html} = live(conn, "/?z=15", on_error: :warn) assert render_hook(view, "map_ready", %{}) bounds_params = %{ "bounds" => %{ "north" => 33.18, "south" => 33.16, "east" => -96.48, "west" => -96.50 } } assert render_hook( view, "bounds_changed", bounds_params ) Phoenix.LiveViewTest.render(view) flush_push_events(view) initial_packet = %{ id: "TEST-2", sender: "TEST-2", base_callsign: "TEST", lat: 33.16961, lon: -96.4921, has_position: true, received_at: DateTime.utc_now() } send(view.pid, {:postgres_packet, initial_packet}) Phoenix.LiveViewTest.render(view) flush_push_events(view) moved_packet = %{ id: "TEST-2", sender: "TEST-2", base_callsign: "TEST", lat: 33.1698, lon: -96.4921, has_position: true, received_at: DateTime.utc_now() } send(view.pid, {:postgres_packet, moved_packet}) Phoenix.LiveViewTest.render(view) end defp flush_push_events(view) do receive do {ref, {:push_event, _, _}} when is_reference(ref) -> flush_push_events(view) after 0 -> :ok end end end describe "distance calculations" do test "calculates correct distances for GPS drift scenarios" do lat1 = 33.16961 lon1 = -96.4921 lat2 = 33.169615 lon2 = -96.492095 distance = GeoUtils.haversine_distance(lat1, lon1, lat2, lon2) assert distance < 10 lat3 = 33.16965 lon3 = -96.4921 distance2 = GeoUtils.haversine_distance(lat1, lon1, lat3, lon3) assert distance2 < 10 lat4 = 33.17000 lon4 = -96.4921 distance3 = GeoUtils.haversine_distance(lat1, lon1, lat4, lon4) assert distance3 > 20 end end end