ueberauth / guardian

Elixir Authentication
MIT License
3.44k stars 381 forks source link

Testing browser sign-in #267

Closed jonathanraes closed 7 years ago

jonathanraes commented 7 years ago

Hi, Im was following the guide mentioned in the readme for implementing the browser login. I get it to work but when I try to test it I get errors. I used the helper function they gave:

def guardian_login(user, token \\ :token, opts \\ []) do
     conn()
         |> bypass_through(MyApp.Router, [:browser])
         |> get("/")
         |> Guardian.Plug.sign_in(user, token, opts)
         |> send_resp(200, "Flush the session yo")
         |> recycle()
 end

The problem is, at the line |> Guardian.Plug.sign_in(user, token, opts) I get the error, ** (Plug.Conn.AlreadySentError) the response was already sent, specifically when its trying to put something in the session. Is there something else I need to do to log in in tests?

doomspork commented 7 years ago

Hi @jonathanraes, isn't the get("/") performing a request? This is the code I use in my test helper for sign in:

@secret String.duplicate("abcdef0123456789", 8)
@signing_opts Plug.Session.init(Keyword.put(@default_opts, :encrypt, false))

def conn_with_fetched_session(the_conn) do
  put_in(the_conn.secret_key_base, @secret)
  |> Plug.Session.call(@signing_opts)
  |> Plug.Conn.fetch_session
end

def sign_in(conn, resource, perms \\ %{default: Guardian.Permissions.max}) do
  conn
  |> conn_with_fetched_session
  |> Guardian.Plug.sign_in(resource, :token, perms: perms)
  |> Guardian.Plug.VerifySession.call(%{})
end
scrogson commented 7 years ago

@jonathanraes do you have hooks defined? Guardian.Plug.sign_in calls hooks_module.after_sign_in last:

https://github.com/ueberauth/guardian/blob/master/lib/guardian/plug.ex#L125

The default functionality is to just return the conn:

https://github.com/ueberauth/guardian/blob/master/lib/guardian/hooks.ex#L14

If you have it set to to send a response in a hook, you will probably need to define a separate hook module for use in test and configure in config/test.exs.

I'd love to hear if this is the case.