diff --git a/test/aprsme_web/live/map_live/historical_loader_test.exs b/test/aprsme_web/live/map_live/historical_loader_test.exs index 69c68b6..811f140 100644 --- a/test/aprsme_web/live/map_live/historical_loader_test.exs +++ b/test/aprsme_web/live/map_live/historical_loader_test.exs @@ -219,4 +219,115 @@ defmodule AprsmeWeb.MapLive.HistoricalLoaderTest do refute result.assigns.historical_loading end end + + describe "advance cursor path via packets with id/received_at" do + test "advances cursor when last packet has both id and received_at" do + now = DateTime.utc_now() + + Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> + [ + %{ + id: "cursor-test-1", + sender: "CUR1", + base_callsign: "CUR1", + ssid: "1", + lat: 33.5, + lon: -96.5, + has_position: true, + symbol_table_id: "/", + symbol_code: ">", + received_at: now, + path: "" + } + ] + end) + + socket = + build_socket(%{ + map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0}, + map_zoom: 10, + historical_loading: true, + loading_generation: 1 + }) + + result = HistoricalLoader.load_historical_batch(socket, 0, nil) + # Cursor should be set from last packet. + assert result.assigns.historical_cursor == %{received_at: now, id: "cursor-test-1"} + end + end + + describe "loading with invalid-coord packets filters them out" do + test "invalid coordinates don't break the pipeline" do + now = DateTime.utc_now() + + Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> + [ + %{ + id: "bad-coord", + sender: "BAD1", + base_callsign: "BAD1", + ssid: "1", + # Out-of-range coordinates — should be filtered. + lat: 200.0, + lon: 500.0, + has_position: true, + symbol_table_id: "/", + symbol_code: ">", + received_at: now, + path: "" + } + ] + end) + + socket = + build_socket(%{ + map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0}, + map_zoom: 10, + historical_loading: true, + loading_generation: 1 + }) + + result = HistoricalLoader.load_historical_batch(socket, 0, nil) + # Still advanced loading state even when all packets were filtered. + assert is_map(result.assigns) + end + end + + describe "zoom >= 10 single-batch branch" do + test "starts loading in a single batch at high zoom" do + Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> [] end) + + socket = + build_socket(%{ + map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0}, + map_zoom: 12, + loading_generation: 0 + }) + + result = HistoricalLoader.start_progressive_historical_loading(socket) + + # High zoom → total_batches set to 1 for single-batch path. + assert result.assigns.total_batches == 1 + assert result.assigns.loading_generation == 1 + end + end + + describe "max packets-for-zoom limit" do + test "finishes loading when batch_offset * batch_size exceeds zoom limit" do + # At zoom 10, limit=1500, batch_size=500. A batch_offset of 3 exceeds + # the 1500-row zoom limit, so the load should finish without a query. + socket = + build_socket(%{ + map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0}, + map_zoom: 10, + historical_loading: true, + total_batches: 4, + loading_generation: 1 + }) + + result = HistoricalLoader.load_historical_batch(socket, 3, nil) + # finish_historical_loading flips historical_loading off. + refute result.assigns.historical_loading + end + end end