aprs.me/test/aprsme_web/channels/mobile_user_socket_test.exs
Graham McIntire aa0c6e6566
refactor: pattern-match in DeviceCache and DatabaseMetrics + add tests
- DeviceCache.pattern_matches?: replace a 3-branch `cond` with a
  two-clause `case` on `String.contains?(pattern, "?")`. The old `*`
  branch was dead code (it did the same exact-match compare as the
  fallback), so it's removed.
- Telemetry.DatabaseMetrics.collect_postgres_metrics: dispatch on
  environment atom via multi-clause private functions instead of
  `if Application.get_env(...) == :test`.

New tests:
- DeviceCache wildcard/exact lookup paths exercised via a seeded cache.
- MobileUserSocket connect/3 for x_headers/peer_data/empty info and
  rate-limit deny.
- DatabaseMetrics pool-metrics emission captured via :telemetry handler
  and the :test-env short-circuit.
2026-04-23 13:46:00 -05:00

99 lines
3.7 KiB
Elixir

defmodule AprsmeWeb.MobileUserSocketTest do
# The rate limiter uses a process-wide ETS table; we're careful to use unique
# IPs so tests don't interfere with each other, but we still mark async:false
# to avoid clashing with anything else that flips the :aprsme, :env flag.
use ExUnit.Case, async: false
alias AprsmeWeb.MobileUserSocket
defp unique_ip, do: "203.0.113." <> to_string(System.unique_integer([:positive]))
setup do
original_env = Application.get_env(:aprsme, :env)
on_exit(fn -> Application.put_env(:aprsme, :env, original_env) end)
:ok
end
describe "connect/3 in :test env" do
test "always succeeds regardless of rate-limit key" do
Application.put_env(:aprsme, :env, :test)
socket = %Phoenix.Socket{assigns: %{}}
connect_info = %{x_headers: [{"cf-connecting-ip", "198.51.100.1"}]}
assert {:ok, result} = MobileUserSocket.connect(%{}, socket, connect_info)
assert result.assigns.peer_ip == "198.51.100.1"
end
test "extracts IP from x-forwarded-for, splitting on comma" do
Application.put_env(:aprsme, :env, :test)
socket = %Phoenix.Socket{assigns: %{}}
connect_info = %{
x_headers: [{"x-forwarded-for", "198.51.100.5, 10.0.0.1"}]
}
assert {:ok, result} = MobileUserSocket.connect(%{}, socket, connect_info)
assert result.assigns.peer_ip == "198.51.100.5"
end
test "extracts IP from x-real-ip" do
Application.put_env(:aprsme, :env, :test)
socket = %Phoenix.Socket{assigns: %{}}
connect_info = %{x_headers: [{"x-real-ip", "198.51.100.7"}]}
assert {:ok, result} = MobileUserSocket.connect(%{}, socket, connect_info)
assert result.assigns.peer_ip == "198.51.100.7"
end
test "falls back to 'unknown' when x_headers list contains no known IP header" do
Application.put_env(:aprsme, :env, :test)
socket = %Phoenix.Socket{assigns: %{}}
connect_info = %{x_headers: [{"user-agent", "curl"}]}
assert {:ok, result} = MobileUserSocket.connect(%{}, socket, connect_info)
assert result.assigns.peer_ip == "unknown"
end
test "uses peer_data when no x_headers" do
Application.put_env(:aprsme, :env, :test)
socket = %Phoenix.Socket{assigns: %{}}
connect_info = %{peer_data: %{address: {127, 0, 0, 1}}}
assert {:ok, result} = MobileUserSocket.connect(%{}, socket, connect_info)
assert result.assigns.peer_ip == "127.0.0.1"
end
test "falls back to 'unknown' for empty connect_info" do
Application.put_env(:aprsme, :env, :test)
socket = %Phoenix.Socket{assigns: %{}}
assert {:ok, result} = MobileUserSocket.connect(%{}, socket, %{})
assert result.assigns.peer_ip == "unknown"
end
end
describe "connect/3 in non-test env with rate limits" do
test "allows first connection from an IP" do
Application.put_env(:aprsme, :env, :prod)
socket = %Phoenix.Socket{assigns: %{}}
ip = unique_ip()
connect_info = %{x_headers: [{"cf-connecting-ip", ip}]}
assert {:ok, _} = MobileUserSocket.connect(%{}, socket, connect_info)
end
test "denies once the per-IP limit is exceeded" do
Application.put_env(:aprsme, :env, :prod)
socket = %Phoenix.Socket{assigns: %{}}
ip = unique_ip()
connect_info = %{x_headers: [{"cf-connecting-ip", ip}]}
# The configured limit is 30 in-module; burn through it, then one more.
for _ <- 1..30, do: MobileUserSocket.connect(%{}, socket, connect_info)
assert :error == MobileUserSocket.connect(%{}, socket, connect_info)
end
end
describe "id/1" do
test "always returns nil (anonymous socket)" do
assert MobileUserSocket.id(%Phoenix.Socket{assigns: %{}}) == nil
end
end
end