Last active
September 6, 2024 23:44
-
-
Save joeytrapp/35c984a67cf2eb6eb0f6f4b3ef9e060f to your computer and use it in GitHub Desktop.
Demonstrate that manually set request headers are not present in redirect/navigate requests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Mix.install( | |
[ | |
{:phoenix_playground, "~> 0.1.6"}, | |
{:phoenix_test, "~> 0.3.2"} | |
], | |
config: [ | |
phoenix_test: [endpoint: Demo.Endpoint], | |
phoenix_playground: [ | |
{Demo.Endpoint, | |
[ | |
render_errors: [view: Demo.ErrorView, layout: false], | |
secret_key_base: String.duplicate("a", 32), | |
server: false | |
]} | |
] | |
] | |
) | |
defmodule Demo.DemoLive do | |
use Phoenix.LiveView | |
import Phoenix.Component | |
def mount(_params, _session, socket) do | |
{:ok, socket} | |
end | |
def handle_params(_params, _session, socket) do | |
{:noreply, assign(socket, :title, page_title(socket.assigns.live_action))} | |
end | |
def render(assigns) do | |
~H""" | |
<h1><%= @title %></h1> | |
<.link navigate="/">List</.link> | |
<.link navigate="/new">New</.link> | |
""" | |
end | |
defp page_title(:index), do: "List Page" | |
defp page_title(:new), do: "New Page" | |
end | |
defmodule Demo.Router do | |
use Phoenix.Router | |
import Phoenix.LiveView.Router | |
pipeline :browser do | |
plug :accepts, ["html"] | |
plug :fetch_session | |
plug :put_root_layout, html: {PhoenixPlayground.Layout, :root} | |
plug :put_secure_browser_headers | |
plug :expect_req_header | |
end | |
scope "/", Demo do | |
pipe_through :browser | |
live "/", DemoLive, :index | |
live "/new", DemoLive, :new | |
end | |
# | |
# This requirement of the request header existing causes the failure | |
# | |
def expect_req_header(conn, _opts) do | |
case Plug.Conn.get_req_header(conn, "required-id") do | |
[] -> | |
conn | |
|> Plug.Conn.send_resp(401, "Unauthorized") | |
|> Plug.Conn.halt() | |
[header_value | _] -> | |
Plug.Conn.assign(conn, :required_id, header_value) | |
end | |
end | |
end | |
defmodule Demo.ErrorView do | |
def render("500.html", _assigns), do: nil | |
end | |
defmodule Demo.Endpoint do | |
use Phoenix.Endpoint, otp_app: :phoenix_playground | |
plug Plug.Logger | |
socket "/live", Phoenix.LiveView.Socket | |
plug Plug.Static, from: {:phoenix, "priv/static"}, at: "/assets/phoenix" | |
plug Plug.Static, from: {:phoenix_live_view, "priv/static"}, at: "/assets/phoenix_live_view" | |
socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket | |
plug Phoenix.LiveReloader | |
plug Phoenix.CodeReloader, reloader: &PhoenixPlayground.CodeReloader.reload/2 | |
plug Plug.Session, store: :cookie, key: "_demo_key", signing_salt: "asdfbasd" | |
plug Demo.Router | |
end | |
Logger.configure(level: :warning) | |
ExUnit.start() | |
defmodule Demo.DemoLiveTest do | |
use ExUnit.Case | |
use PhoenixPlayground.Test, endpoint: Demo.Endpoint | |
import PhoenixTest | |
test "fails because required-id is not present for the navigate redirect" do | |
build_conn() | |
|> Plug.Conn.put_req_header("required-id", "mock-id-value") | |
|> visit("/") | |
|> assert_has("h1", text: "List Page") | |
|> click_link("New") | |
|> assert_path("/new") | |
|> assert_has("h1", text: "New Page") | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ elixir phoenix_test_example.exs | |
Running ExUnit with seed: 719174, max_cases: 32 | |
1) test fails because required-id is not present for the navigate redirect (Demo.DemoLiveTest) | |
phoenix_test_example.exs:103 | |
** (FunctionClauseError) no function clause matching in Phoenix.LiveViewTest.connect_from_static_token/2 | |
The following arguments were given to Phoenix.LiveViewTest.connect_from_static_token/2: | |
# 1 | |
%Plug.Conn{adapter: {Plug.Adapters.Test.Conn, :...}, assigns: %{}, body_params: %Plug.Conn.Unfetched{aspect: :body_params}, cookies: %{}, halted: true, host: "www.example.com", method: "GET", owner: #PID<0.242.0>, params: %{}, path_info: ["new"], path_params: %{}, port: 80, private: %{:phoenix_live_view => {Demo.DemoLive, [action: :new, router: Demo.Router], %{extra: %{}, name: :default, vsn: 1725665773615184792}}, Demo.Router => [], :phoenix_router => Demo.Router, :plug_session_fetch => :done, :plug_session => %{}, :before_send => [#Function<0.9035112/1 in Plug.Session.before_send/2>, #Function<1.8684523/1 in Plug.Logger.call/2>], :phoenix_endpoint => Demo.Endpoint, :phoenix_format => "html", :phoenix_root_layout => %{"html" => {PhoenixPlayground.Layout, :root}}, :plug_skip_csrf_protection => true, :phoenix_recycled => false}, query_params: %Plug.Conn.Unfetched{aspect: :query_params}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %{}, req_headers: [], request_path: "/new", resp_body: "Unauthorized", resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"referrer-policy", "strict-origin-when-cross-origin"}, {"x-content-type-options", "nosniff"}, {"x-download-options", "noopen"}, {"x-frame-options", "SAMEORIGIN"}, {"x-permitted-cross-domain-policies", "none"}], scheme: :http, script_name: [], secret_key_base: :..., state: :sent, status: 401} | |
# 2 | |
"/new" | |
Attempted function clauses (showing 3 out of 3): | |
defp connect_from_static_token(%Plug.Conn{status: 200, assigns: %{live_module: live_module}} = conn, path) | |
defp connect_from_static_token(%Plug.Conn{status: 200}, _path) | |
defp connect_from_static_token(%Plug.Conn{status: redir} = conn, _path) when redir === 301 or redir === 302 | |
code: |> click_link("New") | |
stacktrace: | |
(phoenix_live_view 0.20.17) lib/phoenix_live_view/test/live_view_test.ex:318: Phoenix.LiveViewTest.connect_from_static_token/2 | |
(phoenix_test 0.3.2) lib/phoenix_test/live.ex:331: PhoenixTest.Live.maybe_redirect/2 | |
phoenix_test_example.exs:108: (test) | |
Finished in 0.06 seconds (0.02s on load, 0.00s async, 0.04s sync) | |
1 test, 1 failure |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment