Reorganize tests for failure app and add entries to CHANGELOG.

This commit is contained in:
José Valim 2010-08-31 23:55:25 +02:00
parent c8bd965462
commit 31d7020637
3 changed files with 63 additions and 31 deletions

View File

@ -5,6 +5,7 @@
* enhancements * enhancements
* Added OAuth 2 support * Added OAuth 2 support
* sign_out_via is available in the router to configure the method used for sign out (by github.com/martinrehfeld) * sign_out_via is available in the router to configure the method used for sign out (by github.com/martinrehfeld)
* Improved Ajax requests handling in failure app (by github.com/spastorino)
* bugfix * bugfix
* after_sign_in_path_for always receives a resource * after_sign_in_path_for always receives a resource

View File

@ -33,7 +33,7 @@ module Devise
def http_auth def http_auth
self.status = 401 self.status = 401
self.headers["WWW-Authenticate"] = %(Basic realm=#{Devise.http_authentication_realm.inspect}) unless request.xhr? self.headers["WWW-Authenticate"] = %(Basic realm=#{Devise.http_authentication_realm.inspect}) if http_auth_header?
self.content_type = request.format.to_s self.content_type = request.format.to_s
self.response_body = http_auth_body self.response_body = http_auth_body
end end
@ -67,6 +67,14 @@ module Devise
send(:"new_#{scope}_session_path") send(:"new_#{scope}_session_path")
end end
# Choose whether we should respond in a http authentication fashion,
# including 401 and optional headers.
#
# This method allows the user to explicitly disable http authentication
# on ajax requests in case they want to redirect on failures instead of
# handling the errors on their own. This is useful in case your ajax API
# is the same as your public API and uses a format like JSON (so you
# cannot mark JSON as a navigational format).
def http_auth? def http_auth?
if request.xhr? if request.xhr?
Devise.http_authenticatable_on_xhr Devise.http_authenticatable_on_xhr
@ -75,6 +83,12 @@ module Devise
end end
end end
# It does not make sense to send authenticate headers in ajax requests
# or if the user disabled them.
def http_auth_header?
Devise.mappings[scope].to.http_authenticatable && !request.xhr?
end
def http_auth_body def http_auth_body
method = :"to_#{request.format.to_sym}" method = :"to_#{request.format.to_sym}"
{}.respond_to?(method) ? { :error => i18n_message }.send(method) : i18n_message {}.respond_to?(method) ? { :error => i18n_message }.send(method) : i18n_message

View File

@ -17,7 +17,7 @@ class FailureTest < ActiveSupport::TestCase
'rack.input' => "", 'rack.input' => "",
'warden' => OpenStruct.new(:message => nil) 'warden' => OpenStruct.new(:message => nil)
}.merge!(env_params) }.merge!(env_params)
@response = Devise::FailureApp.call(env).to_a @response = Devise::FailureApp.call(env).to_a
@request = ActionDispatch::Request.new(env) @request = ActionDispatch::Request.new(env)
end end
@ -72,48 +72,65 @@ class FailureTest < ActiveSupport::TestCase
assert_equal 401, @response.first assert_equal 401, @response.first
end end
test 'return WWW-authenticate headers' do test 'return WWW-authenticate headers if model allows' do
call_failure('formats' => :xml) call_failure('formats' => :xml)
assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"] assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
end end
test 'dont return WWW-authenticate on ajax call if http_authenticatable_on_xhr false' do test 'does not return WWW-authenticate headers if model does not allow' do
swap Devise, :http_authenticatable_on_xhr => false do swap Devise, :http_authenticatable => false do
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest') call_failure('formats' => :xml)
assert_equal 302, @response.first assert_nil @response.second["WWW-Authenticate"]
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
assert_nil @response.second['WWW-Authenticate']
end end
end end
test 'dont return WWW-authenticate on ajax call with formats => json if http_authenticatable_on_xhr false' do
swap Devise, :http_authenticatable_on_xhr => false do
call_failure('formats' => :json, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
assert_equal 302, @response.first
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
assert_nil @response.second['WWW-Authenticate']
end
end
test 'return WWW-authenticate on ajax call if http_authenticatable_on_xhr true' do
swap Devise, :http_authenticatable_on_xhr => true do
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
assert_equal 401, @response.first
assert_nil @response.second['WWW-Authenticate']
end
end
test 'uses the proxy failure message as response body' do
call_failure('formats' => :xml, 'warden' => OpenStruct.new(:message => :invalid))
assert_match '<error>Invalid email or password.</error>', @response.third.body
end
test 'works for any non navigational format' do test 'works for any non navigational format' do
swap Devise, :navigational_formats => [] do swap Devise, :navigational_formats => [] do
call_failure('formats' => :html) call_failure('formats' => :html)
assert_equal 401, @response.first assert_equal 401, @response.first
end end
end end
test 'uses the failure message as response body' do
call_failure('formats' => :xml, 'warden' => OpenStruct.new(:message => :invalid))
assert_match '<error>Invalid email or password.</error>', @response.third.body
end
context 'on ajax call' do
context 'when http_authenticatable_on_xhr is false' do
test 'dont return 401 with navigational formats' do
swap Devise, :http_authenticatable_on_xhr => false do
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
assert_equal 302, @response.first
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
end
end
test 'dont return 401 with non navigational formats' do
swap Devise, :http_authenticatable_on_xhr => false do
call_failure('formats' => :json, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
assert_equal 302, @response.first
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
end
end
end
context 'when http_authenticatable_on_xhr is true' do
test 'return 401' do
swap Devise, :http_authenticatable_on_xhr => true do
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
assert_equal 401, @response.first
end
end
test 'skip WWW-Authenticate header' do
swap Devise, :http_authenticatable_on_xhr => true do
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
assert_nil @response.second['WWW-Authenticate']
end
end
end
end
end end
context 'With recall' do context 'With recall' do