Repository navigation
Add login_as(user) testing helper when generating authentication - #53708
Conversation
|
Would there be any value in adding a complimentary |
| def login_as(user) | ||
| session = user.sessions.create! | ||
| Current.session = session | ||
| request = ActionDispatch::Request.new(Rails.application.env_config) | ||
| cookies = request.cookie_jar | ||
| cookies.signed[:session_id] = { value: session.id, httponly: true, same_site: :lax } | ||
| end |
There was a problem hiding this comment.
I had success with logout locally.
| def login_as(user) | |
| session = user.sessions.create! | |
| Current.session = session | |
| request = ActionDispatch::Request.new(Rails.application.env_config) | |
| cookies = request.cookie_jar | |
| cookies.signed[:session_id] = { value: session.id, httponly: true, same_site: :lax } | |
| end | |
| def login_as(user) | |
| session = user.sessions.create! | |
| Current.session = session | |
| request = ActionDispatch::Request.new(Rails.application.env_config) | |
| cookies = request.cookie_jar | |
| cookies.signed[:session_id] = { value: session.id, httponly: true, same_site: :lax } | |
| end | |
| def logout | |
| Current.session.destroy | |
| request = ActionDispatch::Request.new(Rails.application.env_config) | |
| cookies = request.cookie_jar | |
| cookies.delete(:session_id) | |
| end |
|
Yes, this is good. We have a helper like this in our projects as well, which is very similar. But let's name these "sign_in_as" and "sign_out". And then let's instantiate the cookie jar directly. Here's our method: 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 |
|
Also, I would actually recommend that we add this in a dedicated file called SessionTestHelper and then include that via: class ActionDispatch::IntegrationTest
include SessionTestHelper
endListed below the |
|
@gobijan do you still plan to work on this? I can take over this task and co-author you |
|
I had serious problems getting the test suite to run tbh. Locally didn't work. The devcontainer environment was bugged and I had to rely on Github PR which was kind of unsatisfactory. |
|
@gobijan It should be pretty straightforward: cd railties
bundle
bin/testIf that doesn't work, please ask for help in the Discord server. |
|
I just refactored the PR according to @dhh The change:
Another note: |
flavorjones
left a comment
There was a problem hiding this comment.
I made some comments that should get you to green in CI
I think this would be nice as it would cut down on boilerplate requires whenever a test needs to sign in or sign out. In this PR I also used |
I agree it would be nice, but I also don't think it needs to be part of this PR. The failure in CI is unrelated, I'm tagging this for review by a core team member. |
|
Please add a changelog and squash your commits. |
|
|
||
| ActionDispatch::TestRequest.create.cookie_jar.tap do |cookie_jar| | ||
| cookie_jar.signed[:session_id] = Current.session.id | ||
| cookies[:session_id] = cookie_jar[:session_id] |
There was a problem hiding this comment.
Is this supposed to be added o system tests or request tests? I don't remember if system tests can access cookies
There was a problem hiding this comment.
This is for IntegrationTests (ActionDispatch::IntegrationTest).
There was a problem hiding this comment.
Should we have one for system tests too? I know @dhh is not a big fan of them, but for smoke tests, a set of system tests are useful. Should we let that for each app to implement? Maybe a initial implementation on the docs could be an alternative, if we don't want to ship it in the framework.
There was a problem hiding this comment.
Well good question. I think system tests are probably way simpler. These helpers here were not trivial because of the cookie jar problem mentioned in the referenced discussion.
For system tests it's pretty straightforward I guess. Something like:
visit new_session_url
fill_in "Email", with: "test@example.com"
fill_in "Password", with: "password123"
click_on "Sign in"
Where should logic for this go? Directly in the ApplicationSystemTestCase class?
Anyways I needed the IntegrationTest functionality as I was repeating it in all my projects. I let you guys decide how to move forward.
There was a problem hiding this comment.
I wonder if the system specs should actually login, or set cookies more "manually" too.
I'll defer to @dhh to say if this is necessary or not.
There was a problem hiding this comment.
For system tests, I needed to add in the following to get that solution to work:
page.instance_variable_set(:@touched, false)
page.reset!
However, this is pretty hacky, and I'm pretty sure there's a better solution for system tests
There was a problem hiding this comment.
I had something created for system specs before this PR:
def sign_in(user = users(:john))
session = user.sessions.create!
Current.session = session
request = ActionDispatch::Request.new(Rails.application.env_config)
cookies = request.cookie_jar
cookies.signed[:session_id] = { value: session.id, httponly: true, same_site: :lax }
endHope that helps
There was a problem hiding this comment.
Just an update, the solution in #53207 (comment) works better for me than the page resetting! I think there was a significant amount of flake introduced by using stock capybara fill_in to initiate the session
There was a problem hiding this comment.
Hah, @MatheusRich, your comment didn't seem to load for me in time, but I think we came to the same conclusion 😄
There was a problem hiding this comment.
If it is for ActionDispatch::IntegrationTest why is is being added to ActiveSupport::TestCase
…t` test helpers when running `rails g authentication`. Simplifies authentication in integration tests.
|
Nice work, all! This is a good upgrade 🎉 |
…ls#53708) * Add a `SessionTestHelper` module with `sign_in_as(user)` and `sign_out` test helpers when running `rails g authentication`. Simplifies authentication in integration tests. * Style --------- Co-authored-by: David Heinemeier Hansson <david@hey.com>
|
Should the template go into the
|
|
Wups, good catch @dwightwatson. We do need to use test/test_helpers. If you or anyone wants to fix that, cc me on the PR ✌️ |
Of course I can step in and fix it. Will look into it tomorrow :) |
Motivation / Background
This Pull Request has been created because the generated authentication logic does not offer a way to test when a user is authenticated. There is a discussion going in here I initialized: #53207
So this PR adds a
SessionTestHelpermodule withsign_in_as(user)andsign_outtest helpers whenrunning
rails g authentication. This simplifies authentication in integration tests.Detail
This Pull Request changes the generator for authentication to add described test helpers.
Additional information
There were a few discussions how to do it best and for now I settle with the approach from the PR.
Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]