Skip to content

Commit

Permalink
Add follow_redirect/2 to Phoenix.ConnTest (#5797)
Browse files Browse the repository at this point in the history
This PR adds follow_redirect/2 to Phoenix.ConnTest.

When testing complex redirect flows e.g a callback from an external source, then I found it as usefull as Phoenix.LiveViewTest.follow_redirect.
  • Loading branch information
Schultzer committed May 2, 2024
1 parent 9e35d85 commit 5d3dc22
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
23 changes: 23 additions & 0 deletions lib/phoenix/test/conn_test.ex
Expand Up @@ -243,6 +243,29 @@ defmodule Phoenix.ConnTest do
|> endpoint.call(endpoint.init(action))
end

@doc """
Follows a redirected conn.
## Examples
assert follow_redirect(conn, ~"/").resp_body =~ "foo"
"""
def follow_redirect(%Conn{status: status} = conn, expected_to) when status in 300..308 do
to = Plug.Conn.get_resp_header(conn, "location")
if "#{expected_to}" == "#{to}" do
dispatch(conn, conn.private.phoenix_endpoint, :get, expected_to)
else
raise ArgumentError, "expected connection to redirect to #{inspect(expected_to)}, but got #{inspect(to)}"
end
end
def follow_redirect(%Conn{status: status}, _expected_to) when status not in 300..308 do
raise "expected redirection with status 302, got: #{status}"
end
def follow_redirect(%Conn{} = _conn, _exptected_to) do
raise "expected connection to have redirected but no response was set/sent"
end

defp from_set_to_sent(%Conn{state: :set} = conn), do: Conn.send_resp(conn)
defp from_set_to_sent(conn), do: conn

Expand Down
41 changes: 41 additions & 0 deletions test/phoenix/test/conn_test.exs
Expand Up @@ -156,6 +156,47 @@ defmodule Phoenix.Test.ConnTest do
refute conn.private.phoenix_recycled
end

test "follow_redirect/2" do
Enum.each 300..308, fn(status) ->
conn =
build_conn(:get, "/")
|> Endpoint.call(Endpoint.init([]))
|> put_resp_header("location", "/new_location")
|> send_resp(status, "foo")

assert follow_redirect(conn, "/new_location").resp_body == "foo"
end
end

test "follow_redirect/2 without header" do
assert_raise ArgumentError,
"expected connection to redirect to \"/new_location\", but got []", fn ->
build_conn(:get, "/")
|> send_resp(302, "ok")
|> follow_redirect("/new_location")
end
end

test "follow_redirect/2 without redirection" do
assert_raise RuntimeError,
"expected redirection with status 302, got: 200", fn ->
build_conn(:get, "/")
|> put_resp_header("location", "new location")
|> send_resp(200, "ok")
|> follow_redirect("/new_location")
end
end

test "follow_redirect/2 with wrong path" do
assert_raise ArgumentError,
"expected connection to redirect to \"/wrong_location\", but got [\"/new_location\"]", fn ->
build_conn(:get, "/")
|> put_resp_header("location", "/new_location")
|> send_resp(302, "ok")
|> follow_redirect("/wrong_location")
end
end

describe "recycle/1" do
test "relevant request headers are persisted" do
conn =
Expand Down

0 comments on commit 5d3dc22

Please sign in to comment.