Phoenix: Mix Test - Generate Token to add into header request

Created on 17 Apr 2016  路  5Comments  路  Source: phoenixframework/phoenix

I try to set a Token into the header to validate my API

setup %{conn: conn} do
   conn = conn
      |> put_req_header("accept", "application/json")
      |> put_req_header("Bearer ", Phoenix.Token.sign(conn, "user", 1))

   {:ok, conn: conn}
end

Console

1) test creates and renders resource when data is valid (TestPhoenix.UserControllerTest)
test/controllers/user_controller_test.exs:40
** (KeyError) key :phoenix_endpoint not found in: %{phoenix_recycled: true, plug_skip_csrf_protection: true}
stacktrace:
(phoenix) lib/phoenix/controller.ex:155: Phoenix.Controller.endpoint_module/1
(phoenix) lib/phoenix/token.ex:74: Phoenix.Token.sign/4
test/controllers/user_controller_test.exs:12: TestPhoenix.UserControllerTest.ex_unit_setup_1/1
test/controllers/user_controller_test.exs:1: TestPhoenix.UserControllerTest.__ex_unit
/2

Environment

  • Elixir 1.2.3
  • Phoenix:
* idna 1.1.0
* mimerl 1.0.2
* connection 1.0.2
* fs 0.9.1
* gettext 0.10.0
* ssl_verify_hostname 1.0.5
* ranch 1.2.1
* poolboy 1.5.1
* decimal 1.1.1
* poison 1.5.2
* comeonin 2.1.1
* certifi 0.3.0
* hackney 1.4.10
* db_connection 0.2.4
* httpoison 0.8.1
* cowlib 1.0.2
* cowboy 1.0.4
* plug 1.1.2
* phoenix_html 2.5.0
* phoenix 1.1.4
* phoenix_live_reload 1.0.3
* postgrex 0.11.1
* ecto 1.1.4
* geo 1.0.1
* phoenix_ecto 2.0.1
  • NodeJS v5.6.0
  • NPM v3.6.0
  • Operating system: Mac OS 10.11.4

Most helpful comment

Hi @Douvi,

I don't think you need bypass_through. Try just passing the endpoint instead in your initial example:

setup %{conn: conn} do
   conn = conn
      |> put_req_header("accept", "application/json")
      |> put_req_header("Bearer ", Phoenix.Token.sign(NameOfYourEndpoint, "user", 1))

   {:ok, conn: conn}
end

If you are not certain something is a Phoenix issue, we recommend you to use the phoenix mailing list, because others there will be able to help you faster and more effectively than we can.

Have a good week!

All 5 comments

Hi chris,

Thanks for your response, but It's not very clear how to use 'bypass_through'. I found one example with 'bypass_through' but for the pipe ':browser'

code:

test "setting session manually" do
       conn = conn
           |> bypass_through(PhoenixTestSession.Router, [:browser])
           |> get("/")
           |> put_session(:current_username, "John Doe")
           |> send_resp(:ok, "")
           |> recycle
           |> get("/")

           assert conn.resp_body =~ "Welcome, John Doe"
  end

So with this example I try to do the same but for the pipe ":api"

conn = conn
      |> bypass_through(PhoenixTestSession.Router, [:browser])
      |> get("/")
      |> send_resp(:ok, "")
      |> recycle()
      |> bypass_through(PhoenixTestSession.Router, [:api, :auth])
      |> put_req_header("Bearer ", Phoenix.Token.sign(conn, "user", 1))
      |> post(user_path(conn, :create), user: @valid_attrs)

But I got :

1) test creates and renders resource when data is valid (TestPhoenix.UserControllerTest)
     test/controllers/user_controller_test.exs:40
     ** (Plug.Conn.AlreadySentError) the response was already sent
     stacktrace:
       (plug) lib/plug/conn.ex:442: Plug.Conn.resp/3
       (plug) lib/plug/conn.ex:429: Plug.Conn.send_resp/3
       test/controllers/user_controller_test.exs:45

It's possible to init a Token with passing "conn" ?

Thanks
Edouard

ok found a solution but it's not great one. Basically, I open a connection with pipe :browser to GET "/" then with this connection I will be able to generate a Token Phoenix.Token.sign(browser_conn, "user", 1)

test "creates and renders resource when data is valid", %{conn: conn} do
  browser_conn = conn
      |> bypass_through(PhoenixTestSession.Router, [:browser])
      |> get("/")

  api_conn = conn()
      |> bypass_through(PhoenixTestSession.Router, [:api, :auth])
      |> put_req_header("authorization", "Bearer " <> Phoenix.Token.sign(browser_conn, "user", 1))
      |> post(user_path(conn, :create), user: @valid_attrs)
end

It will be much more issuer to use the conn passing into the method to generate a Token, why It not possible ?

Hi @Douvi,

I don't think you need bypass_through. Try just passing the endpoint instead in your initial example:

setup %{conn: conn} do
   conn = conn
      |> put_req_header("accept", "application/json")
      |> put_req_header("Bearer ", Phoenix.Token.sign(NameOfYourEndpoint, "user", 1))

   {:ok, conn: conn}
end

If you are not certain something is a Phoenix issue, we recommend you to use the phoenix mailing list, because others there will be able to help you faster and more effectively than we can.

Have a good week!

Hi @josevalim, I am new to elixir and I wanna update conn for my local where I wanna pass accept and Bearer as you mentioned but I am clueless where to write that piece of code.

Was this page helpful?
0 / 5 - 0 ratings