defmodule ToweropsWeb.Plugs.DetectEUUserTest do use ToweropsWeb.ConnCase, async: true alias ToweropsWeb.Plugs.DetectEUUser describe "init/1" do test "returns options unchanged" do assert DetectEUUser.init([]) == [] assert DetectEUUser.init(some: :option) == [some: :option] end end describe "call/2 - localhost" do test "always requires consent for localhost" do conn = build_conn() |> Map.put(:host, "localhost") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) assert conn.assigns.requires_cookie_consent == true assert get_session(conn, :requires_cookie_consent) == true assert Process.get(:requires_cookie_consent) == true end test "always requires consent for 127.0.0.1" do conn = build_conn() |> Map.put(:host, "127.0.0.1") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) assert conn.assigns.requires_cookie_consent == true assert get_session(conn, :requires_cookie_consent) == true end end describe "call/2 - non-localhost (GeoIP integration)" do test "requires consent when GeoIP returns nil (conservative approach)" do # GeoIP.lookup will return nil in test environment (no data) # This tests the conservative default behavior conn = build_conn() |> Map.put(:host, "example.com") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) # Should default to requiring consent when country cannot be determined assert conn.assigns.requires_cookie_consent == true end end describe "call/2 - stores in multiple locations" do test "stores consent requirement in session, assigns, and process dictionary" do conn = build_conn() |> Map.put(:host, "localhost") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) # Check all three storage locations assert conn.assigns.requires_cookie_consent == true assert get_session(conn, :requires_cookie_consent) == true assert Process.get(:requires_cookie_consent) == true end end describe "call/2 - X-Forwarded-For header" do test "processes X-Forwarded-For header when present" do # Just verify the plug doesn't crash with X-Forwarded-For header conn = build_conn() |> Map.put(:host, "example.com") |> put_req_header("x-forwarded-for", "203.0.113.195") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) # In test env, GeoIP returns nil, so conservative default is true assert conn.assigns.requires_cookie_consent == true end test "handles comma-separated X-Forwarded-For" do # Verify the plug handles multiple IPs without crashing conn = build_conn() |> Map.put(:host, "example.com") |> put_req_header("x-forwarded-for", "203.0.113.195, 10.0.0.1, 192.168.1.1") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) assert conn.assigns.requires_cookie_consent == true end end describe "call/2 - cookie consent check" do test "does not require consent when cookie_consent=accepted cookie exists" do conn = build_conn() |> Map.put(:host, "localhost") |> put_req_cookie("cookie_consent", "accepted") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) # Should not require consent even though localhost normally would assert conn.assigns.requires_cookie_consent == false assert get_session(conn, :requires_cookie_consent) == false assert Process.get(:requires_cookie_consent) == false end test "requires consent when cookie_consent cookie is missing" do conn = build_conn() |> Map.put(:host, "localhost") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) # Should require consent (normal localhost behavior) assert conn.assigns.requires_cookie_consent == true assert get_session(conn, :requires_cookie_consent) == true assert Process.get(:requires_cookie_consent) == true end test "requires consent when cookie_consent cookie has wrong value" do conn = build_conn() |> Map.put(:host, "localhost") |> put_req_cookie("cookie_consent", "rejected") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) # Should require consent (cookie value is not "accepted") assert conn.assigns.requires_cookie_consent == true assert get_session(conn, :requires_cookie_consent) == true assert Process.get(:requires_cookie_consent) == true end test "does not require consent for non-localhost with accepted cookie" do conn = build_conn() |> Map.put(:host, "example.com") |> put_req_cookie("cookie_consent", "accepted") |> Plug.Test.init_test_session(%{}) |> DetectEUUser.call([]) # Should not require consent even though GeoIP would return nil (conservative default) assert conn.assigns.requires_cookie_consent == false assert get_session(conn, :requires_cookie_consent) == false assert Process.get(:requires_cookie_consent) == false end end end