Skip to content

Commit

Permalink
Move the catch to the test level.
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Apr 17, 2011
1 parent 7a2d76d commit c6dd846
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 62 deletions.
11 changes: 0 additions & 11 deletions app/controllers/devise/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,6 @@ def new
# POST /resource/sign_in
def create
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")

# In the running app, the previous line would actually cause this method to
# exit by throwing `:warden` if the authentication failed. Unfortunately,
# this doesn't happen in the Rails test environment if you have included the
# Devise::TestHelpers (see `Devise::TestHelpers::TestWarden#authenticate!`),
# which makes it difficult to unit test extensions to this controller. Since
# the resource is nil if authentication fails, just short-circuit the method
# in that case. This should not affect the running app.

return if resource.nil?

set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => redirect_location(resource_name, resource)
Expand Down
76 changes: 33 additions & 43 deletions lib/devise/test_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,48 +13,11 @@ def self.included(base)
end
end

# This is a Warden::Proxy customized for functional tests. It's meant to
# some of Warden::Manager responsibilities, as retrieving configuration
# options and calling the FailureApp.
class TestWarden < Warden::Proxy #:nodoc:
attr_reader :controller

def initialize(controller)
@controller = controller
manager = Warden::Manager.new(nil) do |config|
config.merge! Devise.warden_config
end
super(controller.request.env, manager)
end

def authenticate!(*args)
catch_with_redirect { super }
end

def user(*args)
catch_with_redirect { super }
end

def catch_with_redirect(&block)
result = catch(:warden, &block)

if result.is_a?(Hash) && !custom_failure? && !@controller.send(:performed?)
result[:action] ||= :unauthenticated

env = @controller.request.env
env["PATH_INFO"] = "/#{result[:action]}"
env["warden.options"] = result
Warden::Manager._run_callbacks(:before_failure, env, result)

status, headers, body = Devise.warden_config[:failure_app].call(env).to_a
@controller.send :render, :status => status, :text => body,
:content_type => headers["Content-Type"], :location => headers["Location"]

nil
else
result
end
end
# Override process to consider warden.
def process(*)
result = nil
_catch_warden { result = super }
result
end

# We need to setup the environment variables and the response in the controller.
Expand All @@ -64,7 +27,12 @@ def setup_controller_for_warden #:nodoc:

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

# sign_in a given resource by storing its keys in the session.
Expand Down Expand Up @@ -96,5 +64,27 @@ def sign_out(resource_or_scope)
warden.session_serializer.delete(scope, user)
end

protected

def _catch_warden(&block)
result = catch(:warden, &block)

if result.is_a?(Hash) && !warden.custom_failure? && !@controller.send(:performed?)
result[:action] ||= :unauthenticated

env = @controller.request.env
env["PATH_INFO"] = "/#{result[:action]}"
env["warden.options"] = result
Warden::Manager._run_callbacks(:before_failure, env, result)

status, headers, body = Devise.warden_config[:failure_app].call(env).to_a
@controller.send :render, :status => status, :text => body,
:content_type => headers["Content-Type"], :location => headers["Location"]

nil
else
result
end
end
end
end
15 changes: 7 additions & 8 deletions test/controllers/sessions_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ class SessionsControllerTest < ActionController::TestCase
tests Devise::SessionsController
include Devise::TestHelpers

test "#create doesn't raise exception after Warden authentication fails " \
+ "when TestHelpers included" do
test "#create doesn't raise exception after Warden authentication fails when TestHelpers included" do
request.env["devise.mapping"] = Devise.mappings[:user]
assert_nothing_raised(NoMethodError) do
post :create, :user => {
:email => "[email protected]",
:password => "wevdude"
}
end
post :create, :user => {
:email => "[email protected]",
:password => "wevdude"
}
assert_equal 200, @response.status
assert_template "devise/sessions/new"
end
end

0 comments on commit c6dd846

Please sign in to comment.