81 lines
2.5 KiB
Elixir
81 lines
2.5 KiB
Elixir
defmodule ToweropsWeb.Plugs.RemoteIpLoggerTest do
|
|
use ToweropsWeb.ConnCase, async: true
|
|
|
|
alias ToweropsWeb.Plugs.RemoteIpLogger
|
|
|
|
describe "init/1" do
|
|
test "returns options unchanged" do
|
|
assert RemoteIpLogger.init([]) == []
|
|
assert RemoteIpLogger.init(some: :option) == [some: :option]
|
|
end
|
|
end
|
|
|
|
describe "call/2" do
|
|
test "extracts IP from X-Forwarded-For header" do
|
|
build_conn()
|
|
|> put_req_header("x-forwarded-for", "203.0.113.195")
|
|
|> RemoteIpLogger.call([])
|
|
|
|
assert Logger.metadata()[:remote_ip] == "203.0.113.195"
|
|
end
|
|
|
|
test "extracts first IP from comma-separated X-Forwarded-For" do
|
|
build_conn()
|
|
|> put_req_header("x-forwarded-for", "203.0.113.195, 10.0.0.1, 192.168.1.1")
|
|
|> RemoteIpLogger.call([])
|
|
|
|
assert Logger.metadata()[:remote_ip] == "203.0.113.195"
|
|
end
|
|
|
|
test "trims whitespace from X-Forwarded-For IP" do
|
|
build_conn()
|
|
|> put_req_header("x-forwarded-for", " 203.0.113.195 , 10.0.0.1")
|
|
|> RemoteIpLogger.call([])
|
|
|
|
assert Logger.metadata()[:remote_ip] == "203.0.113.195"
|
|
end
|
|
|
|
test "falls back to X-Real-IP when X-Forwarded-For is not present" do
|
|
build_conn()
|
|
|> put_req_header("x-real-ip", "198.51.100.42")
|
|
|> RemoteIpLogger.call([])
|
|
|
|
assert Logger.metadata()[:remote_ip] == "198.51.100.42"
|
|
end
|
|
|
|
test "formats IPv4 from conn.remote_ip when no proxy headers present" do
|
|
# ConnCase builds a conn with remote_ip {127, 0, 0, 1}
|
|
RemoteIpLogger.call(build_conn(), [])
|
|
|
|
assert Logger.metadata()[:remote_ip] == "127.0.0.1"
|
|
end
|
|
|
|
test "formats IPv6 from conn.remote_ip" do
|
|
build_conn()
|
|
|> Map.put(:remote_ip, {8193, 3512, 0, 0, 0, 0, 0, 1})
|
|
|> RemoteIpLogger.call([])
|
|
|
|
# IPv6 formatted as hex segments separated by colons (uppercase)
|
|
assert Logger.metadata()[:remote_ip] == "2001:DB8:0:0:0:0:0:1"
|
|
end
|
|
|
|
test "prefers X-Forwarded-For over X-Real-IP" do
|
|
build_conn()
|
|
|> put_req_header("x-forwarded-for", "203.0.113.195")
|
|
|> put_req_header("x-real-ip", "198.51.100.42")
|
|
|> RemoteIpLogger.call([])
|
|
|
|
assert Logger.metadata()[:remote_ip] == "203.0.113.195"
|
|
end
|
|
|
|
test "returns conn unchanged" do
|
|
original_conn = build_conn()
|
|
result_conn = RemoteIpLogger.call(original_conn, [])
|
|
|
|
# Conn should pass through unchanged (only metadata is modified)
|
|
assert result_conn.adapter == original_conn.adapter
|
|
assert result_conn.method == original_conn.method
|
|
assert result_conn.path_info == original_conn.path_info
|
|
end
|
|
end
|
|
end
|