1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00

Allow warden proxy to change with request in tests

The warden method in the Devise::TestHelpers module adds a Warden proxy
object to the request environment hash under the 'warden' key. Including
this module in your test case registers that method as a callback, which
runs before every test:
https://github.com/plataformatec/devise/blob/v3.4.1/lib/devise/test_helpers.rb#L12

The request object itself is created in a callback added by Rails:
https://github.com/rails/rails/blob/v4.2.0/actionpack/lib/action_controller/test_case.rb#L687

So before each test runs, the Rails callback creates the request object,
and then the Devise callback adds a Warden proxy object to it.

I was using the rspec-retry gem (https://github.com/y310/rspec-retry),
and noticed that my controller specs would always fail whenever they
were retried with this error:

NoMethodError: undefined method `authenticate!' for nil:NilClass

When rspec-retry re-runs a failed test, it runs the setup callbacks
again. The Rails callback creates a new request object, but because of
the memoization that was here before, the Devise callback wouldn't add a
Warden proxy to it, which was causing the error.

With this change, the Warden setup code will still only run once as long
as the request object stays the same, but if it changes a new Warden
proxy will be added to the new request object.
This commit is contained in:
Eugene Kenny 2015-01-05 00:34:54 +00:00
parent 7946f681a9
commit 8d9dd50e4a
2 changed files with 17 additions and 2 deletions

View file

@ -26,11 +26,11 @@ module Devise
# Quick access to Warden::Proxy.
def warden #:nodoc:
@warden ||= begin
@request.env['warden'] ||= begin
manager = Warden::Manager.new(nil) do |config|
config.merge! Devise.warden_config
end
@request.env['warden'] = Warden::Proxy.new(@request.env, manager)
Warden::Proxy.new(@request.env, manager)
end
end

View file

@ -160,4 +160,19 @@ class TestHelpersTest < ActionController::TestCase
get :index
assert_match /User ##{second_user.id}/, @response.body
end
test "creates a new warden proxy if the request object has changed" do
old_warden_proxy = warden
@request = ActionController::TestRequest.new
new_warden_proxy = warden
assert_not_equal old_warden_proxy, new_warden_proxy
end
test "doesn't create a new warden proxy if the request object hasn't changed" do
old_warden_proxy = warden
new_warden_proxy = warden
assert_equal old_warden_proxy, new_warden_proxy
end
end