The IPGeolocation plug was setting session data, but the live_session wasn't forwarding it to the LiveView mount. Also removed the root-path restriction so geolocation works on any initial page load.
128 lines
3.7 KiB
Elixir
128 lines
3.7 KiB
Elixir
defmodule AprsmeWeb.Plugs.IPGeolocationTest do
|
|
use AprsmeWeb.ConnCase
|
|
|
|
alias AprsmeWeb.Plugs.IPGeolocation
|
|
|
|
setup %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> Plug.Session.call(Plug.Session.init(store: :cookie, key: "_aprs_key", signing_salt: "test"))
|
|
|> fetch_session()
|
|
|
|
{:ok, conn: conn}
|
|
end
|
|
|
|
describe "call/2 with Cloudflare headers" do
|
|
test "sets session from CF-IPLatitude and CF-IPLongitude headers on root GET", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> put_req_header("cf-iplatitude", "37.7749")
|
|
|> put_req_header("cf-iplongitude", "-122.4194")
|
|
|> IPGeolocation.call([])
|
|
|
|
geo = get_session(conn, :ip_geolocation)
|
|
assert geo == %{"lat" => 37.7749, "lng" => -122.4194}
|
|
end
|
|
|
|
test "skips when CF headers are missing", %{conn: conn} do
|
|
conn = IPGeolocation.call(conn, [])
|
|
|
|
assert get_session(conn, :ip_geolocation) == nil
|
|
end
|
|
|
|
test "skips when only latitude header is present", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> put_req_header("cf-iplatitude", "37.7749")
|
|
|> IPGeolocation.call([])
|
|
|
|
assert get_session(conn, :ip_geolocation) == nil
|
|
end
|
|
|
|
test "skips when only longitude header is present", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> put_req_header("cf-iplongitude", "-122.4194")
|
|
|> IPGeolocation.call([])
|
|
|
|
assert get_session(conn, :ip_geolocation) == nil
|
|
end
|
|
|
|
test "works on non-root paths", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> Map.put(:request_path, "/about")
|
|
|> put_req_header("cf-iplatitude", "37.7749")
|
|
|> put_req_header("cf-iplongitude", "-122.4194")
|
|
|> IPGeolocation.call([])
|
|
|
|
geo = get_session(conn, :ip_geolocation)
|
|
assert geo == %{"lat" => 37.7749, "lng" => -122.4194}
|
|
end
|
|
|
|
test "skips non-GET requests", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> Map.put(:method, "POST")
|
|
|> put_req_header("cf-iplatitude", "37.7749")
|
|
|> put_req_header("cf-iplongitude", "-122.4194")
|
|
|> IPGeolocation.call([])
|
|
|
|
assert get_session(conn, :ip_geolocation) == nil
|
|
end
|
|
|
|
test "uses cached session data without re-reading headers", %{conn: conn} do
|
|
geo_data = %{"lat" => 40.7128, "lng" => -74.006}
|
|
|
|
conn =
|
|
conn
|
|
|> put_session(:ip_geolocation, geo_data)
|
|
|> put_req_header("cf-iplatitude", "37.7749")
|
|
|> put_req_header("cf-iplongitude", "-122.4194")
|
|
|> IPGeolocation.call([])
|
|
|
|
assert get_session(conn, :ip_geolocation) == geo_data
|
|
end
|
|
|
|
test "rejects latitude out of range", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> put_req_header("cf-iplatitude", "91.0")
|
|
|> put_req_header("cf-iplongitude", "-122.4194")
|
|
|> IPGeolocation.call([])
|
|
|
|
assert get_session(conn, :ip_geolocation) == nil
|
|
end
|
|
|
|
test "rejects longitude out of range", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> put_req_header("cf-iplatitude", "37.7749")
|
|
|> put_req_header("cf-iplongitude", "181.0")
|
|
|> IPGeolocation.call([])
|
|
|
|
assert get_session(conn, :ip_geolocation) == nil
|
|
end
|
|
|
|
test "rejects non-numeric header values", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> put_req_header("cf-iplatitude", "not_a_number")
|
|
|> put_req_header("cf-iplongitude", "-122.4194")
|
|
|> IPGeolocation.call([])
|
|
|
|
assert get_session(conn, :ip_geolocation) == nil
|
|
end
|
|
|
|
test "handles boundary coordinate values", %{conn: conn} do
|
|
conn =
|
|
conn
|
|
|> put_req_header("cf-iplatitude", "-90.0")
|
|
|> put_req_header("cf-iplongitude", "180.0")
|
|
|> IPGeolocation.call([])
|
|
|
|
geo = get_session(conn, :ip_geolocation)
|
|
assert geo == %{"lat" => -90.0, "lng" => 180.0}
|
|
end
|
|
end
|
|
end
|