Adding SessionTestHelper to Existing Rails Project
Hello 👋
With Rails 8, built-in authentication has been introduced. Although it seems like a small and simple step, for a developer like me who uses Devise in every project, even for basic authentication, it is a significant initiative. I am not going to talk about the Rails Authentication Generator. Instead, I’d like to focus on a small update related to testing in it.
I was very happy to use a small authentication generator for my project (bloud.me), but at that time, the documentation was not sufficient. I found a blog post about adding Rails Authentication to my tests.
I had a small method to authenticate a user, which I used in my tests whenever I needed to sign in a user.
1
2
3
4
# test/test_helper.rb
def sign_in(user, password: "password")
post session_url, params: { email_address: user.email_address, password: }
end
1
2
3
4
5
class HomeControllerTest < ActionDispatch::IntegrationTest
....
sign_in(user, password: "password")
...
end
There was a problem—I couldn’t run system tests. I needed another solution, but I couldn’t find or create one. So, I ended up removing all system tests. To be honest, I don’t really enjoy writing system tests, but that’s a topic for another blog post 😬.
One week ago, a PR was merged into the main branch of the Rails project. I am using Rails main in my project and always keep it up to date. So, I decided to update my tests according to that PR.
First of all, I needed to add SessionTestHelper
to the test_helpers
folder.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# test/test_helpers/session_test_helper.rb
module SessionTestHelper
def sign_in_as(user)
Current.session = user.sessions.create!
ActionDispatch::TestRequest.create.cookie_jar.tap do |cookie_jar|
cookie_jar.signed[:session_id] = Current.session.id
cookies[:session_id] = cookie_jar[:session_id]
end
end
def sign_out
Current.session&.destroy!
cookies.delete(:session_id)
end
end
Update test_helper.rb
1
2
3
4
5
6
7
8
9
10
11
# test/test_helper.rb
...
require_relative "test_helpers/session_test_helper"
...
module ActiveSupport
class TestCase
include SessionTestHelper
...
end
I removed all my old testing helpers from the codebase and added a new one.
1
2
3
4
5
6
7
8
9
require "test_helper"
class HomeControllerTest < ActionDispatch::IntegrationTest
test "..." do
user = users(:one)
sign_in_as(user)
...
end
end
Run the test again and see the test is pass.
❤️