Bypass_through/3 not working?

Heres the error.

  1) test checks if account is active authenticated?/2 halts if account is no longer active (Beffect.Plugs.AuthTest)
     test/beffect/plug/auth_test.exs:7
     ** (ArgumentError) flash not fetched, call fetch_flash/2
     code: |> Beffect.Plugs.Auth.authenticated?(%{})
     stacktrace:
       (phoenix) lib/phoenix/controller.ex:1228: Phoenix.Controller.get_flash/1
       (phoenix) lib/phoenix/controller.ex:1210: Phoenix.Controller.put_flash/3
       (beffect) lib/beffect/plugs/auth.ex:30: Beffect.Plugs.Auth.authenticated?/2
       test/beffect/plug/auth_test.exs:17: (test)

FYI lib/beffect/plugs/auth.ex:30 is the puts_flash

heres the test

test "authenticated?/2 halts if account is no longer active" do

  user = insert(:user, active: false)

  conn = build_conn()
  |> init_test_session(user_id: user.id)
  |> assign(:current_user, user)
  |> bypass_through(BeffectWeb.Router, :browser) # ? not sure if its really calling that pipeline
  |> Beffect.Plugs.Auth.authenticated?(%{})

  assert get_flash(conn, :error) =~ "Your account is no longer active"
  assert redirected_to(conn) =~ "/login"
end

Heres Beffect.Plugs.Auth.authenticated?

def authenticated?(conn, _opts) do
   cond do
     conn.assigns.current_user && conn.assigns.current_user.active ->
       conn
      conn.assigns.current_user ->
        assign(conn, :current_user, nil)
        conn
          |> put_flash(:error, "Your account is no longer active") # Setting the flash here
          |> redirect(to: Helpers.session_path(conn, :new,origin_path: conn.request_path))
          |> halt()
        ...
  end

Heres the pipeline for :brower

  pipeline :browser do
    ....
    plug :fetch_flash # calling it here....
    ...
  end

Also note that I IO.puts in the pipeline to see if its called and it looks as if it is being called.

Looks to me like it is working. You’re skipping the :browser pipeline, and as expected the flash is not fetched. Maybe you need to separate out your basic browser needs from your authentication needs.

bypass_through will only invoke the pipeline when you send a request against the router, so your tests should work with the following:

(note, you don’t need init_test_session since bypass_through will fetch the session in your browser pipeline:

  conn =
    build_conn()
    |> bypass_through(BeffectWeb.Router, :browser)
    |> get("/") # invoke the pipelines, bypassing router dispatch
    |> put_session(:user_id, user.id)
    |> assign(:current_user, user)
    |> Beffect.Plugs.Auth.authenticated?(%{})
1 Like

I totally missed what
“but you need to invoke the Endpoint plugs and :browser pipeline of your Router for session and flash related dependencies” meant.

Maybe a update to the doc that calls out that what the use of get(“/”) is doing in that case. ( Just a thought. )

https://hexdocs.pm/phoenix/Phoenix.ConnTest.html#bypass_through/1

Great opportunity for a PR :slight_smile: Maybe before the ## Examples make a note about a request being sent with get and friends is required to invoke the pipeline(s)?

2 Likes

Just about to ask if thats something I could do but then found it for me self. Will do :slight_smile:

1 Like

Opensource FTW

1 Like