axelclark

axelclark

Controller Test with Pow

I’ve added Pow into my project for authentication. Now I’m trying to update the tests Phoenix generated when I created my contexts.

I’ve added all my resource routes to the protected pipeline.

I used Pow.Plug.assign_current_user/3 to add a current user to my conn.

    test "redirects to show when data is valid", %{conn: conn} do
      user = %Golf.Accounts.User{email: "test@example.com", id: 1}
      conn = Pow.Plug.assign_current_user(conn, user, [])

      conn = post(conn, Routes.course_path(conn, :create), course: @create_attrs)

      assert %{id: id} = redirected_params(conn)
      assert redirected_to(conn) == Routes.course_path(conn, :show, id)

      conn = get(conn, Routes.course_path(conn, :show, id))
      assert html_response(conn, 200) =~ "Show Course"
    end

My assertions about the create action all pass.

      assert %{id: id} = redirected_params(conn)
      assert redirected_to(conn) == Routes.course_path(conn, :show, id)

However, the final show action

      conn = get(conn, Routes.course_path(conn, :show, id))
      assert html_response(conn, 200) =~ "Show Course"

fails because it gets redirected to the new_session path:

     ** (RuntimeError) expected response with status 200, got: 302, with body:
     <html><body>You are being <a href="/session/new?request_path=%2Fcourses">redirected</a>.</body></html>

If I reuse the original conn after I assign the current user, but before the create action, my tests pass.

    test "redirects to show when data is valid", %{conn: conn} do
      user = %Golf.Accounts.User{email: "test@example.com", id: 1}
      new_conn = Pow.Plug.assign_current_user(conn, user, [])

      conn = post(new_conn, Routes.course_path(new_conn, :create), course: @create_attrs)

      assert %{id: id} = redirected_params(conn)
      assert redirected_to(conn) == Routes.course_path(conn, :show, id)

      conn = get(new_conn, Routes.course_path(new_conn, :show, id))
      assert html_response(conn, 200) =~ "Show Course"
    end

Can someone help me out with how I need to update my tests?

Thanks!

Axel

Marked As Solved

danschultzer

danschultzer

Pow Core Team

Your second example is the way to go. This could also be done in a setup macro like so:

    setup %{conn: conn} do
      user = %Golf.Accounts.User{email: "test@example.com", id: 1}
      authed_conn = Pow.Plug.assign_current_user(conn, user, [])

      {:ok, conn: conn, authed_conn: authed_conn}
    end

    test "redirects to show when data is valid", %{authed_conn: authed_conn} do
      conn = post(authed_conn, Routes.course_path(authed_conn, :create), course: @create_attrs)

      assert %{id: id} = redirected_params(conn)
      assert redirected_to(conn) == Routes.course_path(conn, :show, id)

      conn = get(authed_conn, Routes.course_path(authed_conn, :show, id))
      assert html_response(conn, 200) =~ "Show Course"
    end

It’s because of how phoenix recycles connections in tests. The response conn will have a :state key set to :sent so when it’s reused the test helpers in Phoenix will build a new connection and only copy over headers e.g. cookies. Assigns will not be preserved.

Also Liked

danschultzer

danschultzer

Pow Core Team

Yeah, you would only ever need to do that if you are testing the session controller itself. Assigning :current_user is sufficient for all other controllers/routes.

juanma1331

juanma1331

Fixed. Had to recycle the conn manually.

test "redirects to show when data is valid", %{authed_conn: conn} do
      conn = post(conn, Routes.product_path(conn, :create), product: @create_attrs)
      assert %{id: id} = redirected_params(conn)
      assert redirected_to(conn) == Routes.product_path(conn, :show, id)

      conn = recycle_conn(conn) <-- Added

      conn = get(conn, Routes.product_path(conn, :show, id))
      assert html_response(conn, 200) =~ "Show Product"
    end
defp recycle_conn(conn) do
    saved_assigns = conn.assigns
    conn =
      conn
      |> recycle()
      |> Map.put(:assigns, saved_assigns)
    conn
  end

All the tests are passing now, but i have defined the recycle_conn function on the controller_test, what if i want to test another authed controller? Need to redefine again, or create another helper module and define it there to ease reuse.
Im pretty new to elixir/phoenix and web dev in general. Sorry for my english

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: &lt;h1&gt;Create Post&lt;/h1&gt; &lt;%= ...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
hariharasudhan94
Lets say i have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; "XXX...
New

Other popular topics Top

New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New

We're in Beta

About us Mission Statement