module Devise::TestHelpers

def self.included(base)

def self.included(base)
  base.class_eval do
    setup :setup_controller_for_warden, :warden if respond_to?(:setup)
  end
end

def _catch_warden(&block)

Returns nil when interrupted, otherwise the normal result of the block.
Catch warden continuations and handle like the middleware would.
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

def _process_unauthenticated(env, options = {})

def _process_unauthenticated(env, options = {})
  options[:action] ||= :unauthenticated
  proxy = env['warden']
  result = options[:result] || proxy.result
  ret = case result
  when :redirect
    body = proxy.message || "You are being redirected to #{proxy.headers['Location']}"
    [proxy.status, proxy.headers, [body]]
  when :custom
    proxy.custom_response
  else
    env["PATH_INFO"] = "/#{options[:action]}"
    env["warden.options"] = options
    Warden::Manager._run_callbacks(:before_failure, env, options)
    status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
    @controller.send :render, :status => status, :text => response.body,
      :content_type => headers["Content-Type"], :location => headers["Location"]
    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)
    # ensure the controller response is set to our response.
    @controller.response ||= @response
    @response.status = ret.first
    @response.headers = ret.second
    @response.body = ret.third
  end
  ret
end

def process(*)

Override process to consider warden.
def process(*)
  # Make sure we always return @response, a la ActionController::TestCase::Behaviour#process, even if warden interrupts
  _catch_warden { super } || @response
end

def setup_controller_for_warden #:nodoc:

:nodoc:
We need to setup the environment variables and the response in the controller.
def setup_controller_for_warden #:nodoc:
  @request.env['action_controller.instance'] = @controller
end

def sign_in(resource_or_scope, resource=nil)


sign_in @user # sign_in(resource)
sign_in :user, @user # sign_in(scope, resource)

Examples:

This method bypass any warden authentication callback.
sign_in a given resource by storing its keys in the session.
def sign_in(resource_or_scope, resource=nil)
  scope    ||= Devise::Mapping.find_scope!(resource_or_scope)
  resource ||= resource_or_scope
  warden.instance_variable_get(:@users).delete(scope)
  warden.session_serializer.store(resource, scope)
end

def sign_out(resource_or_scope)


sign_out @user # sign_out(resource)
sign_out :user # sign_out(scope)

Examples:

This method bypass any warden logout callback.
Sign out a given resource or scope by calling logout on Warden.
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

def warden #:nodoc:

:nodoc:
Quick access to Warden::Proxy.
def warden #:nodoc:
  @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