Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added test helpers.

  • Loading branch information...
commit 97a7f0ed5161085ba714706dab6deb00b94f44b1 1 parent ffbc9c6
@josevalim josevalim authored
View
5 CHANGELOG.rdoc
@@ -1,12 +1,13 @@
* enhancements
* [#28] Improved sign_in and sign_out helpers to accepts resources
* [#28] Added stored_location_for as a helper
+ * [#20] Added test helpers
== 0.5.1
* enhancements
- * Added serializers based on Warden ones
- * Allow authentication keys to be set
+ * Added serializers based on Warden ones
+ * Allow authentication keys to be set
== 0.5.0
View
12 README.rdoc
@@ -228,6 +228,18 @@ Devise mailer uses the same pattern to create subject messages:
Take a look at our locale file to check all available messages.
+== Test helpers
+
+Devise includes some tests helpers for functional specs. To use them, you just
+need to include Devise::TestHelpers in your test class and use the sign_in and
+sign_out method. Such methods have the same signature as in controllers:
+
+ sign_in :user, @user # sign_in(scope, resource)
+ sign_in @user # sign_in(resource)
+
+ sign_out :user # sign_out(scope)
+ sign_out @user # sign_out(resource)
+
== Migrating from other solutions
Devise implements encryption strategies for Clearance, Authlogic and Restful-Authentication. To make use of it set the desired encryptor in the encryptor initializer config option. You might also need to rename your encrypted password and salt columns to match Devises's one (encrypted_password and password_salt).
View
1  TODO
@@ -1,5 +1,4 @@
* Devise::Timeoutable
-* Devise::TestHelper
* Use request_ip in session cookies
* Devise::BruteForceProtection
* Devise::MagicColumns
View
6 lib/devise/controllers/filters.rb
@@ -54,8 +54,8 @@ def signed_in?(scope)
#
# Examples:
#
- # sign_in :user, @user # sign_in(scope, resource)
- # sign_in @user # sign_in(resource)
+ # sign_in :user, @user # sign_in(scope, resource)
+ # sign_in @user # sign_in(resource)
#
def sign_in(resource_or_scope, resource=nil)
scope ||= find_devise_scope(resource_or_scope)
@@ -136,7 +136,7 @@ def #{mapping}_session
protected
- def find_devise_scope(resource_or_scope)
+ def find_devise_scope(resource_or_scope) #:nodoc:
if resource_or_scope.is_a?(Symbol)
resource_or_scope
else
View
95 lib/devise/test_helpers.rb
@@ -0,0 +1,95 @@
+module Devise
+ module TestHelpers
+ def self.included(base)
+ base.class_eval do
+ setup :setup_controller_for_warden, :warden if respond_to?(:setup)
+ end
+ end
+
+ # This is a Warden::Proxy customized for functional tests. It's meant to
+ # some of Warden::Manager resposnabilities, 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 |manager|
+ Devise.configure_warden_manager(manager)
+ end
+ super(controller.request.env, manager.config)
+ end
+
+ def authenticate!(*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._before_failure.each{ |hook| hook.call(env, result) }
+
+ status, headers, body = Devise::FailureApp.call(env).to_a
+ @controller.send :redirect_to, headers["Location"]
+ else
+ result
+ end
+ end
+ end
+
+ # We need to setup the environment variables and the response in the controller.
+ def setup_controller_for_warden #:nodoc:
+ @request.env['action_controller.rescue.request'] = @request
+ @request.env['action_controller.rescue.response'] = @response
+ @request.env['rack.session'] = session
+ @controller.response = @response
+ end
+
+ # Quick access to Warden::Proxy.
+ def warden #:nodoc:
+ @warden ||= (@request.env['warden'] = TestWarden.new(@controller))
+ end
+
+ # sign_in a given resource by storing its keys in the session.
+ #
+ # Examples:
+ #
+ # sign_in :user, @user # sign_in(scope, resource)
+ # sign_in @user # sign_in(resource)
+ #
+ def sign_in(resource_or_scope, resource=nil)
+ scope ||= find_devise_scope(resource_or_scope)
+ resource ||= resource_or_scope
+ session["warden.user.#{scope}.key"] = resource.class.serialize_into_session(resource)
+ end
+
+ # Sign out a given resource or scope by calling logout on Warden.
+ #
+ # Examples:
+ #
+ # sign_out :user # sign_out(scope)
+ # sign_out @user # sign_out(resource)
+ #
+ def sign_out(resource_or_scope)
+ scope = find_devise_scope(resource_or_scope)
+ warden.logout(scope)
+ end
+
+ protected
+
+ def find_devise_scope(resource_or_scope) #:nodoc:
+ if resource_or_scope.is_a?(Symbol)
+ resource_or_scope
+ else
+ Devise::Mapping.find_by_class!(resource_or_scope.class).name
+ end
+ end
+
+ end
+end
View
44 test/test_helpers_test.rb
@@ -0,0 +1,44 @@
+require 'test/test_helper'
+
+class TestHelpersTest < ActionController::TestCase
+ tests UsersController
+ include Devise::TestHelpers
+
+ test "redirects if attempting to access a page unauthenticated" do
+ get :index
+ assert_redirected_to "/users/sign_in?unauthenticated=true"
+ end
+
+ test "redirects if attempting to access a page with a unconfirmed account" do
+ swap Devise, :confirm_within => 0 do
+ sign_in create_user
+ get :index
+ assert_redirected_to "/users/sign_in?unconfirmed=true"
+ end
+ end
+
+ test "does not redirect with valid user" do
+ user = create_user
+ user.confirm!
+
+ sign_in user
+ get :index
+ assert_response :success
+ end
+
+ test "redirects if valid user signed out" do
+ user = create_user
+ user.confirm!
+
+ sign_in user
+ get :index
+
+ sign_out user
+ get :index
+ assert_redirected_to "/users/sign_in?unauthenticated=true"
+ end
+
+ def create_user
+ User.create!(:email => "jose.valim@plataformatec.com", :password => "123456")
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.