diff --git a/lib/aprsme/device_identification.ex b/lib/aprsme/device_identification.ex index 17bd00c..9ad770e 100644 --- a/lib/aprsme/device_identification.ex +++ b/lib/aprsme/device_identification.ex @@ -144,14 +144,18 @@ defmodule Aprsme.DeviceIdentification do defp now_for_insert, do: NaiveDateTime.utc_now(:second) def fetch_and_upsert_devices do - case CircuitBreaker.call(:aprs_foundation_api, &fetch_devices_from_url/0, 15_000) do + url = Application.get_env(:aprsme, :device_id_url, @url) + + case CircuitBreaker.call(:aprs_foundation_api, fn -> fetch_devices_from_url(url) end, 15_000) do {:ok, result} -> result {:error, reason} -> {:error, reason} end end - defp fetch_devices_from_url do - case Req.get(@url) do + @doc false + # Exposed for testing via URL injection. + def fetch_devices_from_url(url \\ @url) do + case Req.get(url) do {:ok, %Req.Response{status: 200, body: body}} -> upsert_devices(body) diff --git a/test/aprsme/device_identification_test.exs b/test/aprsme/device_identification_test.exs index a2dade6..c092df4 100644 --- a/test/aprsme/device_identification_test.exs +++ b/test/aprsme/device_identification_test.exs @@ -203,6 +203,15 @@ defmodule Aprsme.DeviceIdentificationTest do end end + describe "fetch_devices_from_url/1 with direct URL" do + test "returns an error tuple on non-200 response" do + # httpbin.org-style path that returns non-200 is not reliable; + # just pass an invalid URL to hit the error branch. + result = DeviceIdentification.fetch_devices_from_url("http://invalid.local.test.invalid:1/404") + assert match?({:error, _}, result) + end + end + describe "fetch_and_upsert_devices circuit-breaker path" do test "returns an error tuple when circuit breaker rejects or HTTP fails" do # This just exercises the fetch_and_upsert_devices path, which runs via diff --git a/test/aprsme_web/live/map_live/index_test.exs b/test/aprsme_web/live/map_live/index_test.exs index 0fac729..14a1c7c 100644 --- a/test/aprsme_web/live/map_live/index_test.exs +++ b/test/aprsme_web/live/map_live/index_test.exs @@ -4,6 +4,17 @@ defmodule AprsmeWeb.MapLive.IndexTest do import Phoenix.ConnTest import Phoenix.LiveViewTest + setup do + # Reset the shared Hammer ETS so per-IP request counts don't bleed + # between test cases and trigger 429s in the middle of a run. + case :ets.info(Aprsme.RateLimiter) do + :undefined -> :ok + _ -> :ets.delete_all_objects(Aprsme.RateLimiter) + end + + :ok + end + describe "Index" do test "renders map view", %{conn: conn} do {:ok, view, html} = live(conn, "/", on_error: :warn)