From f1cecacc99a0f5bef6e86841614522fccfc8cae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 12 Oct 2009 21:49:51 -0300 Subject: [PATCH] Move mappings to routes. --- config/routes.rb | 20 ------ lib/devise.rb | 7 +- lib/devise/mapping.rb | 32 +++++---- lib/devise/routes.rb | 44 ++++++++++++ test/mapping_test.rb | 70 +++++++------------- test/rails_app/app/models/admin.rb | 2 +- test/rails_app/config/initializers/devise.rb | 2 - test/rails_app/config/routes.rb | 5 +- test/routes_test.rb | 8 +-- test/support/integration_tests_helper.rb | 1 - 10 files changed, 91 insertions(+), 100 deletions(-) delete mode 100644 config/routes.rb create mode 100644 lib/devise/routes.rb delete mode 100644 test/rails_app/config/initializers/devise.rb diff --git a/config/routes.rb b/config/routes.rb deleted file mode 100644 index 3debe2c8..00000000 --- a/config/routes.rb +++ /dev/null @@ -1,20 +0,0 @@ -ActionController::Routing::Routes.draw do |map| - Devise.mappings.each_value do |mapping| - map.namespace mapping.name, :namespace => nil, :path_prefix => mapping.as do |m| - if mapping.authenticable? - m.resource :session, - :only => [:new, :create, :destroy] - end - - if mapping.recoverable? - m.resource :password, - :only => [:new, :create, :edit, :update] - end - - if mapping.confirmable? - m.resource :confirmation, - :only => [:new, :create, :show] - end - end - end -end diff --git a/lib/devise.rb b/lib/devise.rb index c9d97bf9..fdfffe0e 100644 --- a/lib/devise.rb +++ b/lib/devise.rb @@ -7,6 +7,7 @@ end require 'devise/initializers/warden' require 'devise/mapping' +require 'devise/routes' # Ensure to include Devise modules only after Rails initialization. # This way application should have already defined Devise mappings and we are @@ -14,10 +15,4 @@ require 'devise/mapping' # Rails.configuration.after_initialize do ActiveRecord::Base.extend Devise::ActiveRecord - - ActionController::Base.send :include, Devise::Controllers::Filters - ActionController::Base.send :include, Devise::Controllers::Helpers - ActionController::Base.send :include, Devise::Controllers::UrlHelpers - - ActionView::Base.send :include, Devise::Controllers::UrlHelpers end diff --git a/lib/devise/mapping.rb b/lib/devise/mapping.rb index 64be6d03..d268eac5 100644 --- a/lib/devise/mapping.rb +++ b/lib/devise/mapping.rb @@ -6,17 +6,20 @@ module Devise }.freeze class Mapping - attr_reader :name, :as, :for + attr_reader :name, :as def initialize(name, options) - @name = name - @for = Array(options[:for]) - @klass = (options[:to] || name.to_s.classify).to_s - @as = (options[:as] || name.to_s.pluralize).to_sym + @as = (options[:as] || name).to_sym + @klass = (options[:class_name] || name.to_s.classify).to_s + @name = (options[:singular] || name.to_s.singularize).to_sym + end + + # Return modules for the mapping. + def for + @for ||= to.devise_modules end # Reload mapped class each time when cache_classes is false. - # def to return @to if @to klass = @klass.constantize @@ -24,28 +27,23 @@ module Devise klass end + # Check if the respective controller has a module in the mapping class. + def allows?(controller) + self.for.include?(CONTROLLERS[controller.to_sym]) + end + CONTROLLERS.values.each do |m| class_eval <<-METHOD, __FILE__, __LINE__ def #{m}? - @for.include?(:#{m}) + self.for.include?(:#{m}) end METHOD end - - def allows?(controller) - @for.include?(CONTROLLERS[controller.to_sym]) - end end mattr_accessor :mappings self.mappings = {} - def self.map(mapping, options={}) - raise ArgumentError, "Need to provide :for option for Devise.map" unless options.key?(:for) - options.assert_valid_keys(:to, :for, :as) - self.mappings[mapping] = Mapping.new(mapping, options) - end - def self.find_mapping_by_path(path) route = path.split("/")[1] return nil unless route diff --git a/lib/devise/routes.rb b/lib/devise/routes.rb new file mode 100644 index 00000000..d9973a92 --- /dev/null +++ b/lib/devise/routes.rb @@ -0,0 +1,44 @@ +module ActionController::Routing + class RouteSet #:nodoc: + + def load_routes_with_devise! + load_routes_without_devise! + + ActionController::Base.send :include, Devise::Controllers::Filters + ActionController::Base.send :include, Devise::Controllers::Helpers + ActionController::Base.send :include, Devise::Controllers::UrlHelpers + + ActionView::Base.send :include, Devise::Controllers::UrlHelpers + end + alias_method_chain :load_routes!, :devise + + class Mapper #:doc: + def devise_for(*resources) + options = resources.extract_options! + + resources.map!(&:to_sym) + options.assert_valid_keys(:class_name, :as) + + resources.each do |resource| + mapping = Devise::Mapping.new(resource, options) + Devise.mappings[mapping.name] = mapping + + namespace mapping.name, :namespace => nil, :path_prefix => mapping.as do |m| + if mapping.authenticable? + m.resource :session, :only => [:new, :create, :destroy] + end + + if mapping.recoverable? + m.resource :password, :only => [:new, :create, :edit, :update] + end + + if mapping.confirmable? + m.resource :confirmation, :only => [:new, :create, :show] + end + end + end + end + end + + end +end diff --git a/test/mapping_test.rb b/test/mapping_test.rb index 1dbc723c..4b3d8d19 100644 --- a/test/mapping_test.rb +++ b/test/mapping_test.rb @@ -1,71 +1,49 @@ require 'test/test_helper' -class Participant < User; end -class Organizer < User; end - class MapTest < ActiveSupport::TestCase - def setup - @mappings = Devise.mappings - Devise.mappings = {} - end - - def teardown - Devise.mappings = @mappings - end - test 'store options' do - Devise.map :participant, :to => Participant, :for => :authenticable + mapping = Devise.mappings[:user] - mappings = Devise.mappings - assert_not mappings.empty? - - assert_equal Participant, mappings[:participant].to - assert_equal [:authenticable], mappings[:participant].for - assert_equal :participants, mappings[:participant].as + assert_equal User, mapping.to + assert_equal User.devise_modules, mapping.for + assert_equal :users, mapping.as end - test 'require :for option' do - assert_raise ArgumentError do - Devise.map :participant, :to => Participant - end - end - - test 'assert valid keys in options' do - assert_raise ArgumentError do - Devise.map :participant, :to => Participant, :for => [:authenticable], :other => 123 - end - end - - test 'use map name pluralized to :as option if none is given' do - Devise.map :participant, :for => [:authenticable] - assert_equal :participants, Devise.mappings[:participant].as + test 'allows as to be given' do + assert_equal :admin_area, Devise.mappings[:admin].as end test 'allows a controller depending on the mapping' do - Devise.map :participant, :for => [:authenticable, :confirmable] + mapping = Devise.mappings[:user] + assert mapping.allows?(:sessions) + assert mapping.allows?(:confirmations) + assert mapping.allows?(:passwords) - assert Devise.mappings[:participant].allows?(:sessions) - assert Devise.mappings[:participant].allows?(:confirmations) - assert_not Devise.mappings[:participant].allows?(:passwords) + mapping = Devise.mappings[:admin] + assert mapping.allows?(:sessions) + assert_not mapping.allows?(:confirmations) + assert_not mapping.allows?(:passwords) end test 'return mapping by path' do - Devise.map :participant, :for => [:authenticable, :confirmable] - assert_equal Devise.mappings[:participant], Devise.find_mapping_by_path("/participants/session") - assert_nil Devise.find_mapping_by_path("/foo/bar") + assert_nil Devise.find_mapping_by_path("/foo/bar") + assert_equal Devise.mappings[:user], Devise.find_mapping_by_path("/users/session") end test 'return mapping by customized path' do - Devise.map :participant, :for => [:authenticable, :confirmable], :as => "participantes" - assert_equal Devise.mappings[:participant], Devise.find_mapping_by_path("/participantes/session") + assert_equal Devise.mappings[:admin], Devise.find_mapping_by_path("/admin_area/session") end test 'magic predicates' do - Devise.map :participant, :for => [:authenticable, :confirmable] - mapping = Devise.mappings[:participant] + mapping = Devise.mappings[:user] assert mapping.authenticable? assert mapping.confirmable? - assert !mapping.recoverable? + assert mapping.recoverable? + + mapping = Devise.mappings[:admin] + assert mapping.authenticable? + assert_not mapping.confirmable? + assert_not mapping.recoverable? end end diff --git a/test/rails_app/app/models/admin.rb b/test/rails_app/app/models/admin.rb index 3a87055c..bff2dae8 100644 --- a/test/rails_app/app/models/admin.rb +++ b/test/rails_app/app/models/admin.rb @@ -1,3 +1,3 @@ class Admin < ActiveRecord::Base - devise :all + devise :validatable end diff --git a/test/rails_app/config/initializers/devise.rb b/test/rails_app/config/initializers/devise.rb deleted file mode 100644 index 671e1cb2..00000000 --- a/test/rails_app/config/initializers/devise.rb +++ /dev/null @@ -1,2 +0,0 @@ -Devise.map :user, :for => [:authenticable, :recoverable, :confirmable, :validatable] -Devise.map :admin, :for => [:authenticable, :confirmable, :validatable], :as => 'admin_area' diff --git a/test/rails_app/config/routes.rb b/test/rails_app/config/routes.rb index 7282caca..f98d99d1 100644 --- a/test/rails_app/config/routes.rb +++ b/test/rails_app/config/routes.rb @@ -1,9 +1,12 @@ ActionController::Routing::Routes.draw do |map| + map.devise_for :users + map.devise_for :admin, :as => 'admin_area' + map.resources :users, :only => :index map.resources :admins, :only => :index map.root :controller => :home - map.connect '/users/password/new', :controller => "passwords", :action => "new" + map.connect '/admin_area/password/new', :controller => "passwords", :action => "new" map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end diff --git a/test/routes_test.rb b/test/routes_test.rb index 392bab0d..41ecddf3 100644 --- a/test/routes_test.rb +++ b/test/routes_test.rb @@ -18,13 +18,9 @@ class MapRoutingTest < ActionController::TestCase assert_recognizes({:controller => 'sessions', :action => 'new'}, 'admin_area/session/new') end - test 'map devise admin confirmation with :as option' do - assert_recognizes({:controller => 'confirmations', :action => 'new'}, 'admin_area/confirmation/new') - end - - test 'map devise admin password with :as option' do + test 'does not map devise admin confirmation' do assert_raise ActionController::RoutingError do - assert_recognizes({:controller => 'passwords', :action => 'new'}, 'admin_area/password/new') + assert_recognizes({:controller => 'confirmations', :action => 'new'}, 'admin_area/confirmation/new') end end diff --git a/test/support/integration_tests_helper.rb b/test/support/integration_tests_helper.rb index 5d07f263..b4016f36 100644 --- a/test/support/integration_tests_helper.rb +++ b/test/support/integration_tests_helper.rb @@ -19,7 +19,6 @@ class ActionController::IntegrationTest admin = Admin.create!( :email => 'admin@test.com', :password => '123456', :password_confirmation => '123456' ) - admin.confirm! unless options[:confirm] == false admin end end