defmodule ToweropsWeb.RemoteIpTest do use ToweropsWeb.ConnCase, async: true alias ToweropsWeb.RemoteIp test "extracts the first forwarded IP from conn headers", %{conn: conn} do conn = conn |> put_req_header("x-forwarded-for", "203.0.113.10, 10.0.0.1") |> put_req_header("x-real-ip", "198.51.100.1") assert RemoteIp.from_conn(conn) == "203.0.113.10" end test "formats IPv6 addresses in uppercase hex" do assert RemoteIp.format({8193, 3512, 0, 0, 0, 0, 0, 1}) == "2001:DB8:0:0:0:0:0:1" end describe "from_socket/1" do test "returns formatted IP from peer_data in assigns" do socket = %Phoenix.Socket{ assigns: %{peer_data: %{address: {192, 168, 1, 42}, port: 12_345}} } assert RemoteIp.from_socket(socket) == "192.168.1.42" end test "returns nil when peer_data is missing" do socket = %Phoenix.Socket{assigns: %{}} assert RemoteIp.from_socket(socket) == nil end test "returns nil when peer_data has no address tuple" do socket = %Phoenix.Socket{assigns: %{peer_data: %{}}} assert RemoteIp.from_socket(socket) == nil end end end