This will be a quick one, but it was tough for me to find.
Just some background: I used phx_gen_auth
for authentication in my app. This little tidbit is going to play an important role in my "no duh" moment.
After using phx.gen.html
or phx.gen.live
to do some heavy lifting, Phoenix is nice enough to write out some tests for me as well.
Only problem is when I require an authenticated user for a certain route or resource. My nicely passing out-of-the-box tests no longer pass.
Well, jumping into the code, I just started by fixing one test at a time. I looked in the user_session_controller_test.exs
file generated from running phx.gen.auth
and found how they created the user:
import MyAwesomeProject.AccountsFixtures
setup do
%{user: user_fixture()}
end
Okay, great! That means I can easily run user_fixture()
to create a user and pass it into each test.
I then looked how the user was logged in in the test:
test "redirects if already logged in", %{conn: conn, user: user} do
conn = conn
|> log_in_user(user)
|> get(Routes.user_session_path(conn, :new))
assert redirected_to(conn) == "/"
end
Okay, simple enough. There's nice conveniently named function called log_in_user/2
that takes conn
and user
as parameters. Nice. I can do that on each of my tests too. But wait, that's not very DRY at all. Well, let's not even pass in the user
to each test when I can just pass in an updated conn
after logging in the user with log_in_user/2
.
defp log_in_user(%{conn: conn}) do
%{conn: log_in_user(conn, user_fixture())}
end
...
describe "MyAwesomeTest" do
setup [:log_in_user]
...
But wait, where did log_in_user/2
come from. I had just made an assumption that it came from my import of MyAwesomeProject.AccountsFixtures
. It actually came from MyAwesomeProject.ConnCase
. It's that phx.gen.auth
magic at work again!
And you know what I found when I just looked around in conn_case.exs
?
@doc """
Setup helper that registers and logs in users.
setup :register_and_log_in_user
It stores an updated connection and a registered user in the
test context.
"""
def register_and_log_in_user(%{conn: conn}) do
user = GrokTheGreeks.AccountsFixtures.user_fixture()
%{conn: log_in_user(conn, user), user: user}
end
I've never been happier knowing I wasted my time writing throw-away code.
Top comments (0)