mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
92 lines
3.3 KiB
Ruby
92 lines
3.3 KiB
Ruby
require 'test_helper'
|
|
require 'ostruct'
|
|
require 'warden/strategies/base'
|
|
require 'devise/test_helpers'
|
|
|
|
class MyController < DeviseController
|
|
end
|
|
|
|
class CustomStrategyTest < ActionController::TestCase
|
|
tests MyController
|
|
|
|
include Devise::TestHelpers
|
|
|
|
# These tests are to prove that a warden strategy can successfully return a custom response, including a specific
|
|
# status code and custom http response headers. This does work in production, however, at the time of writing this,
|
|
# the Devise test helpers do not recognise the custom response and proceed to calling the Failure App. This makes
|
|
# it impossible to write tests for a strategy that return a custom response with Devise.
|
|
#
|
|
# The code this test needs to verify is in Devise::TestHelpers#_catch_warden (which appears to have no other test
|
|
# coverage at this point.) The functionality of this function should mirror Warden::Manager#call(env) and
|
|
# Warden::Manager#process_unauthenticated which correctly detects the custom response when set by a strategy.
|
|
#
|
|
class CustomStrategy < Warden::Strategies::Base
|
|
def authenticate!
|
|
custom_headers = { "X-FOO" => "BAR" }
|
|
response = Rack::Response.new("BAD REQUEST", 400, custom_headers)
|
|
custom! response.finish
|
|
end
|
|
end
|
|
|
|
# call the custom strategy, returning the rack result array
|
|
def call_custom(env_params={})
|
|
request.env ||= {}
|
|
request.env.merge! ({
|
|
'REQUEST_URI' => 'http://test.host/',
|
|
'HTTP_HOST' => 'test.host',
|
|
'REQUEST_METHOD' => 'GET',
|
|
'warden.options' => { :scope => :user },
|
|
'rack.session' => {},
|
|
'action_dispatch.request.formats' => Array(env_params.delete('formats') || Mime::HTML),
|
|
'rack.input' => "",
|
|
})
|
|
request.env.merge!(env_params)
|
|
env = request.env
|
|
|
|
# create a strategy instance
|
|
strategy = CustomStrategy.new env, :user
|
|
|
|
# processing a test request eventually calls _catch_warden:
|
|
ret = _catch_warden do
|
|
|
|
# when a controller action is triggered, its before filter would require authentication. Devise uses
|
|
# warden to execute the strategies.
|
|
|
|
# simulate its selection as the winning strategy (the custom response is read from .winning_strategy)
|
|
warden.winning_strategy = strategy
|
|
|
|
# And then the strategy is executed:
|
|
strategy.authenticate!
|
|
|
|
# after the strategy executes, halt! has been called (from in custom!) above which eventually results in
|
|
# the :warden symbol being thrown, which is caught in Devise::TestHelpers#_catch_warden
|
|
throw :warden
|
|
end
|
|
|
|
# after this point, @response should be set to the custom response when triggered by a custom strategy, or
|
|
# the response of the FailureApp as normal.
|
|
ret
|
|
end
|
|
|
|
|
|
test "custom strategy can return its own status code" do
|
|
ret = call_custom
|
|
|
|
# check the returned rack array
|
|
assert ret.is_a?(Array)
|
|
assert_equal 400, ret.first
|
|
|
|
# no need to test the saved response yet, that should be set by the correct processing of an action.
|
|
end
|
|
|
|
test "custom strategy can return custom headers" do
|
|
ret = call_custom
|
|
|
|
# check the returned rack array
|
|
assert ret.is_a?(Array)
|
|
assert_equal ret.third['X-FOO'], 'BAR'
|
|
|
|
# no need to test the saved response yet, that should be set by the correct processing of an action.
|
|
end
|
|
|
|
end
|