-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Devise::TestHelpers inclusion in Rails 5 #3913
Comments
Excellent bug report, @holman! ❤️ It seems controller tests in Rails 5 are integration tests, so we may not have a "backdoor" to sign the user in. We will either need to go explicitly through the sign in page OR build a session cookie that we'll store directly in the request. We will explore the options but I hope this is enough information for you to progress! If not, just ask! |
Thanks, @josevalim! Real helpful. For those of you who may be following along at home, I'm tossing this in class ActionDispatch::IntegrationTest
def sign_in(user)
post user_session_path \
"user[email]" => user.email,
"user[password]" => user.password
end
end Seems to be the easiest thing to do that allows future drop-in support. Small app too so far, so not a huge deal to add the extra overhead for me. |
@holman are you actively working on this? Let me know if there's anything I can do to help. Currently working on several Rails 5 apps and have done the same workaround as you posted in your last comment. Would love to help patch this. |
Probbbbbably not. Don't think I know enough of the internals to jump in and figure out which direction to take this. (If there's a consensus on what approach makes the most sense I can probably hop in and build it out though). |
Thanks @holman for posting the work around, it helped me a lot. Although I don't have a solution I thought I'd add a little more information that might help someone else out. I'm pretty new to testing and rails in general so sorry if this isn't much use. It looks like in Rails 5 you can add When I tried the solution @holman posted here, it didn't work without providing a password. I don't really understand why. Here is what did work for me eventually: My
My
My first test file
I hope it helps a little. |
I'm working on a Rails 5 app as well and ran in to these issues. I slotted in @holman's code to my ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
fixtures :all
def sign_in(user)
post user_session_path \
'user[email]' => user.email,
'user[password]' => user.password
end
end And then I've got a controller test: require 'test_helper'
class KlassesControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in users(:one)
@klass = klasses(:one)
end
test 'should get index' do
get klasses_url
assert_response :success
end
end My user fixture: one:
name: 'Lachlan'
email: 'atlachlanjc@gmail.com'
encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %> When I run the test, however, I get this:
How can I fix this issue (even temporarily) so that I can test my app? Thanks 😀 |
I could have sworn I ran into that problem when I was initially looking into this, but for the life of me I can't remember what the specifics were or how to reproduce it. Guessing it might have something to do with your routes, maybe? |
Hmm. My routes are pretty straightforward: devise_for :users, controllers: { registrations: 'registrations' }
as :user do
get '/login', to: 'devise/sessions#new'
get '/signin', to: 'devise/sessions#new'
get '/signup', to: 'devise/registrations#new'
get '/settings', to: 'devise/registrations#edit'
end And in case you were wondering, the registrations controller: class RegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
resource.update_without_password(params)
end
end Really confused as to my next step 😬 — thanks for helping out, though! |
@lachlanjc is the |
@twe4ked Source location is confirming the method is from |
I got the same error as you no matter what I tried so I gave up trying to
use a fixture and created the user in the test setup. (see my previous
comment)
|
Ok, so I've updated my def sign_in(user)
@user = User.create(email: "#{rand(50000)}@example.com",
password: 'password')
post user_registration_path, params: { 'user[email]': user.email, 'user[password]': 'password' }
puts current_user.email # Line 12 — test authentication state
end But this isn't actually working:
|
You should have access to a |
@twe4ked The |
@lachlanjc Try |
@twe4ked Yeah, that took a while! When I created a user on the fly instead of using a fixture everything worked, but then the class ActionDispatch::IntegrationTest
def sign_in(user)
post user_session_path \
"user[email]" => user.email,
"user[password]" => user.password
end
def sign_in_for(subject)
@user = User.create(email: "#{rand(50000)}@example.com", password: 'password')
sign_in @user
subject.update_attribute(:user_id, @user.id)
end
end And an example for using it (likely inside the setup do
@post = posts(:one)
sign_in_for(@post)
end |
This worked for me and I wanted to get some feedback on the solution. I used Warden's test helpers directly as instructed here, https://github.com/hassox/warden/wiki/Testing. In test_helper.rb
In fixtures/users.yml
In my controller test:
|
@cwsaylor I'm using a similar implementation on a small here, I think we can wrap this up inside a |
Merged #4071 introducing a new |
Not trying to re-animate this thread, but is there any documentation on how to get
|
@tirdadc have you checked the updated Test helpers section from the README? If it doesn't work for you, please create a new issue following our CONTRIBUTING.md recommendations. |
refer to this issue before modification; heartcombo/devise#3913
Hey @tirdadc, this might be a bit late but can help others: According to the README, in RAILS 5 you should do this:
Instead of how we use to do it on RAILS 4 (
|
Also, very late to the party, but if you use class ActionController::TestCase
include Devise::Test::ControllerHelpers
end otherwise you will start getting these |
In case anyone finds this useful, I have a slightly different approach to logging in users during testing. If you wish to skip over the devise functionality you can use some middleware, similar to how the clearance gem works. This prevents you from having to make a whole other request to sign in and should speed up specs.
# Usage:
#
# visit new_feedback_path(as: user)
class BackDoor
def initialize(app, &block)
@app = app
@block = block
end
def call(env)
sign_in_through_the_back_door(env)
@app.call(env)
end
private
def sign_in_through_the_back_door(env)
params = Rack::Utils.parse_query(env['QUERY_STRING'])
user_param = params['as']
return unless user_param.present?
user = User.find(user_param)
return unless user
env['warden'].set_user(user)
end
end
require_relative '../../spec/support/back_door'
config.middleware.use BackDoor In specs: user = # get_user_here
get '/url', as: user |
I got stuck on this for quite a bit. I'm using Rails 5.2.3 with a JWT Devise Strategy and came up against numerous issues with all the options above. My solution was the following:
|
I'm running into an inconsistency in how Devise suggests doing controller tests in Rails 5.0.0.beta1.
I set up a minimal app on Devise b97b3e6 for you to reproduce, if you'd like:
In master's
README
, we're currently suggesting this to be added totest/test_helper.rb
:Running the tests will result in:
Greenfield Rails 5 generated controllers now inherit from
ActionDispatch::IntegrationTest
:Modifying the
test_helper.rb
to include from within the new class causes another problem, though:That's currently this line, which doesn't have the
@request
ivar available.Likely missing something obvious here! If I am, we should likely update the
README
to account for bonehead developers like myself. 🎆The text was updated successfully, but these errors were encountered: