From 965e177841737f987a23f3aa3c137e8e5bb21de5 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Thu, 23 Apr 2026 18:06:13 -0500 Subject: [PATCH] test: HistoricalLoader bounds-driven load paths via mock --- .../live/map_live/historical_loader_test.exs | 104 +++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) 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 27a9943..69c68b6 100644 --- a/test/aprsme_web/live/map_live/historical_loader_test.exs +++ b/test/aprsme_web/live/map_live/historical_loader_test.exs @@ -1,9 +1,17 @@ defmodule AprsmeWeb.MapLive.HistoricalLoaderTest do - use ExUnit.Case, async: true + # Shares Mox stubs with other tests via the app-level :packets_module env. + # Mox.set_mox_from_context + allow() doesn't cleanly scope inside async tests + # without a Mox.Test start, so we pin to async: false. + use ExUnit.Case, async: false + + import Mox alias AprsmeWeb.MapLive.HistoricalLoader alias Phoenix.LiveView.Socket + setup :verify_on_exit! + setup :set_mox_from_context + defp build_socket(assigns) do defaults = %{ map_bounds: nil, @@ -117,4 +125,98 @@ defmodule AprsmeWeb.MapLive.HistoricalLoaderTest do assert Process.cancel_timer(timer) == false end end + + describe "load_historical_batch/3 with bounds and mocked packets" do + test "handles an empty result set by marking loading complete" do + # Mock returns no packets — exercises the empty-batch branch. + 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: 10, + historical_loading: true, + loading_generation: 1 + }) + + result = HistoricalLoader.load_historical_batch(socket, 0, nil) + + # Loading should be marked complete and batch advanced. + refute result.assigns.historical_loading + assert result.assigns.loading_batch == 1 + end + + test "advances loading_batch when packets come back from the mock" do + # Return a single packet — exercises the process_loaded_packets branch. + Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> + [ + %{ + id: "p-1", + sender: "HIST-1", + base_callsign: "HIST", + ssid: "1", + lat: 33.5, + lon: -96.5, + has_position: true, + symbol_table_id: "/", + symbol_code: ">", + received_at: DateTime.utc_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) + + # Either loading complete (under-full batch) or advanced a batch. + assert result.assigns.loading_batch >= 1 + end + + test "handles empty result with pending bounds set" 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: 10, + pending_bounds: %{north: 1.0, south: 0.0, east: 1.0, west: 0.0}, + historical_loading: true, + loading_generation: 1 + }) + + result = HistoricalLoader.load_historical_batch(socket, 0, nil) + refute result.assigns.historical_loading + # process_pending_bounds is sent when loading completes with pending bounds. + assert_received {:process_pending_bounds} + refute result.assigns.historical_loading + end + end + + describe "start_progressive_historical_loading/1 with bounds" do + test "calls into load_historical_batch with map_zoom < 10" 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: 5, + loading_generation: 0 + }) + + result = HistoricalLoader.start_progressive_historical_loading(socket) + + assert result.assigns.loading_generation == 1 + # With empty mock results at low zoom, the first batch completes and + # historical_loading flips back to false. + refute result.assigns.historical_loading + end + end end