Module: Devise::Test::ControllerHelpers
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/devise/test/controller_helpers.rb
Overview
‘Devise::Test::ControllerHelpers` provides a facility to test controllers in isolation when using `ActionController::TestCase` allowing you to quickly sign_in or sign_out a user. Do not use `Devise::Test::ControllerHelpers` in integration tests.
Examples
class PostsTest < ActionController::TestCase
include Devise::Test::ControllerHelpers
test 'authenticated users can GET index' do
sign_in users(:bob)
get :index
assert_response :success
end
end
Important: you should not test Warden specific behavior (like callbacks) using ‘Devise::Test::ControllerHelpers` since it is a stub of the actual behavior. Such callbacks should be tested in your integration suite instead.
Instance Method Summary collapse
-
#_catch_warden(&block) ⇒ Object
protected
Catch warden continuations and handle like the middleware would.
- #_process_unauthenticated(env, options = {}) ⇒ Object protected
-
#process ⇒ Object
Override process to consider warden.
-
#setup_controller_for_warden ⇒ Object
We need to set up the environment variables and the response in the controller.
-
#sign_in(resource, deprecated = nil, scope: nil) ⇒ Object
sign_in a given resource by storing its keys in the session.
-
#sign_out(resource_or_scope) ⇒ Object
Sign out a given resource or scope by calling logout on Warden.
-
#warden ⇒ Object
Quick access to Warden::Proxy.
Instance Method Details
#_catch_warden(&block) ⇒ Object (protected)
Catch warden continuations and handle like the middleware would. Returns nil when interrupted, otherwise the normal result of the block.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/devise/test/controller_helpers.rb', line 101 def _catch_warden(&block) result = catch(:warden, &block) env = @controller.request.env result ||= {} # Set the response. In production, the rack result is returned # from Warden::Manager#call, which the following is modelled on. case result when Array if result.first == 401 && intercept_401?(env) # does this happen during testing? _process_unauthenticated(env) else result end when Hash _process_unauthenticated(env, result) else result end end |
#_process_unauthenticated(env, options = {}) ⇒ Object (protected)
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/devise/test/controller_helpers.rb', line 124 def _process_unauthenticated(env, = {}) [:action] ||= :unauthenticated proxy = request.env['warden'] result = [:result] || proxy.result ret = case result when :redirect body = proxy. || "You are being redirected to #{proxy.headers['Location']}" [proxy.status, proxy.headers, [body]] when :custom proxy.custom_response else request.env["PATH_INFO"] = "/#{[:action]}" request.env["warden.options"] = Warden::Manager._run_callbacks(:before_failure, env, ) status, headers, response = Devise.warden_config[:failure_app].call(env).to_a @controller.response.headers.merge!(headers) @controller.response.content_type = headers["Content-Type"] unless Rails.version.start_with?('5') @controller.status = status @controller.response.body = response.body nil # causes process return @response end # ensure that the controller response is set up. In production, this is # not necessary since warden returns the results to rack. However, at # testing time, we want the response to be available to the testing # framework to verify what would be returned to rack. if ret.is_a?(Array) status, headers, body = *ret # ensure the controller response is set to our response. @controller.response ||= @response @response.status = status @response.headers.merge!(headers) @response.body = body end ret end |
#process ⇒ Object
Override process to consider warden.
34 35 36 37 38 |
# File 'lib/devise/test/controller_helpers.rb', line 34 def process(*) _catch_warden { super } @response end |
#setup_controller_for_warden ⇒ Object
We need to set up the environment variables and the response in the controller.
41 42 43 |
# File 'lib/devise/test/controller_helpers.rb', line 41 def setup_controller_for_warden #:nodoc: @request.env['action_controller.instance'] = @controller end |
#sign_in(resource, deprecated = nil, scope: nil) ⇒ Object
sign_in a given resource by storing its keys in the session. This method bypass any warden authentication callback.
-
resource
- The resource that should be authenticated -
scope
- An optionalSymbol
with the scope where the resourceshould be signed in with.
Examples:
sign_in users(:alice) sign_in users(:alice), scope: :admin
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/devise/test/controller_helpers.rb', line 65 def sign_in(resource, deprecated = nil, scope: nil) if deprecated.present? scope = resource resource = deprecated ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc [Devise] sign_in(:#{scope}, resource) on controller tests is deprecated and will be removed from Devise. Please use sign_in(resource, scope: :#{scope}) instead. DEPRECATION end scope ||= Devise::Mapping.find_scope!(resource) warden.instance_variable_get(:@users).delete(scope) warden.session_serializer.store(resource, scope) end |
#sign_out(resource_or_scope) ⇒ Object
Sign out a given resource or scope by calling logout on Warden. This method bypass any warden logout callback.
Examples:
sign_out :user # sign_out(scope)
sign_out @user # sign_out(resource)
90 91 92 93 94 95 |
# File 'lib/devise/test/controller_helpers.rb', line 90 def sign_out(resource_or_scope) scope = Devise::Mapping.find_scope!(resource_or_scope) @controller.instance_variable_set(:"@current_#{scope}", nil) user = warden.instance_variable_get(:@users).delete(scope) warden.session_serializer.delete(scope, user) end |
#warden ⇒ Object
Quick access to Warden::Proxy.
46 47 48 49 50 51 52 53 |
# File 'lib/devise/test/controller_helpers.rb', line 46 def warden #:nodoc: @request.env['warden'] ||= begin manager = Warden::Manager.new(nil) do |config| config.merge! Devise.warden_config end Warden::Proxy.new(@request.env, manager) end end |