Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing POW session information to a LiveView in test? #607

Open
molenick opened this issue Mar 4, 2021 · 3 comments
Open

Passing POW session information to a LiveView in test? #607

molenick opened this issue Mar 4, 2021 · 3 comments

Comments

@molenick
Copy link

molenick commented Mar 4, 2021

Thanks for the great library! :)

I'm trying to pass an authenticated user to a LiveView so I can access current_user, with the end goal to authorize access to resources based on user. I've read a few of the (very helpful and detailed) issues on integrating Pow and LiveViews, and am able to get access to the user inside of the LiveView during mount by verifying their auth key from the session.

My issues arises when I try to replicate this behavior in test. I want to be able to simulate a log so that I can test authenticated and unauthenticated behaviors, but I've been struggling a bit to get this piece in place. In regular controllers, I've done this with a test callback:

  defp authenticate_user(%{conn: conn, user: user}) do
    auth_conn = Pow.Plug.assign_current_user(conn, user, otp_app: :euchre)

    %{auth_conn: auth_conn}
  end

I tried doing this in my LiveView tests but am having a bit of trouble. I noticed that during my test runs that session was always nil in my LiveView's mount. I did some searching and it seems like that's pretty normal for LiveView tests, and that it seemed like most people solved it by either piggybacking off another request where there is already a session, or injecting session data through test callbacks. I've been trying the "inject session data" approach.

How can I derive a user's auth key from their Pow user struct? My secondary question is: does this seem like a good approach for my goals, or is there a better way to go about passing a user to a LiveView and testing it? Thanks!

@johns10
Copy link

johns10 commented Mar 31, 2021

I just got done with this. I added this function to my setup macro:

defp setup_session(%{ conn: conn }) do
    conn = Plug.Test.init_test_session(conn, %{})
    opts = Pow.Plug.Session.init(otp_app: :userdocs_web)
    conn =
      conn
      |> Plug.Test.init_test_session(%{})
      |> Pow.Plug.Session.call(opts)
      |> Pow.Plug.Session.do_create(first_user(), opts)
    :timer.sleep(100)
    %{ conn: conn }
  end

I think the only thing that isn't covered by plug or pow is this function that gets the first user I created in my fixtures:

defp first_user(), do: Users.list_users() |> Enum.at(0)

Now I'm looking, that first conn = Plug.Test.init ... is not necessary, it's in the pipeline. You could also be smarter about the first_user() call and just get it from the args for the fixture.

If you dig around, you'll find this solution prosed previously in this repo.

I don't know how to access the auth key, but this covers getting the user logged in and the session created.

@kieraneglin
Copy link

Using @johns10's example above I documented my full auth/test helper setup for Pow with LiveViews. See it here.

I am piecing together various things I've found so it'd be worth consulting threads like this to ensure this follows best security practices before including in your app.

@johns10
Copy link

johns10 commented Aug 23, 2021

I'll have to check out your solution because I'm still having a hard time with my tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants