0

I'm trying to test my controller but I keep hitting a guardian "Unauthenticated" error. I think I know where it's going wrong but I'm just not sure why it's not working. Here is what I have.

  setup %{conn: conn} do
    user = insert(:user)
    {:ok, jwt, _} = Guardian.encode_and_sign(user, :api)
    conn = conn
    |> put_req_header("accept", "application/json")
    |> put_req_header("authorization", "bearer: " <> jwt)

    {:ok, conn: conn}
  end

  test "creates and renders resource when data is valid", %{conn: conn} do
    conn = post(conn, league_path(conn, :create), league: @valid_attrs)
    body = json_response(conn, 201)
    assert body["name"]
    assert Repo.get_by(League, name: "Obama's League")
  end

This is correctly creating and signing the JWT but for some reason it's not authenticating it in the router. Here is the router.

pipeline :authenticated do
  plug(Guardian.Plug.EnsureAuthenticated)
end

scope "/api/v1", Statcasters do
  pipe_through([:api, :authenticated])

  resources("/leagues", LeagueController, only: [:create])
end

I think this is where I'm going wrong because documentation shows that this error will arise if this router plug is not resolved:

ERROR:

** (RuntimeError) expected response with status 201, got: 401, with body:
     {"errors":["Unauthenticated"]}
     code: body = json_response(conn, 201)

How can I successfully use guardian in a controller test?

Bitwise
  • 8,021
  • 22
  • 70
  • 161
  • Wouldn’t `pipe_through([:authenticated, :api])` work? The order of plug matters, with what you have it gets to `api` plug _before_ authenticated. – Aleksei Matiushkin Apr 21 '18 at 07:15
  • That is good to know. However, but I still get the same result if I switch the order around. – Bitwise Apr 21 '18 at 14:38
  • Maybe you should not use the plug directly in :authenticated pipeline. Maybe you should build a guardian pipeline and use that. From the docs "All plugs need to be in a pipeline" https://hexdocs.pm/guardian/readme.html#plugs – voger Apr 21 '18 at 20:34

1 Answers1

0

Although you don't specify your guardian version in your question, for version ~> 2.0, Bearer is the default realm argument for the verify_header plug.

You should replace:

|> put_req_header("authorization", "bearer: " <> jwt)

with

|> put_req_header("authorization", "Bearer " <> jwt)

unless you explicitly defined the verify_header plug with bearer:

 plug Guardian.Plug.VerifyHeader, realm: "bearer:"
cristiano2lopes
  • 3,168
  • 2
  • 18
  • 22