canard 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ pkg/*
4
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in canard.gemspec
4
+ gemspec
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ canard (0.0.1)
5
+ cancan
6
+ role_model
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ activemodel (3.1.0)
12
+ activesupport (= 3.1.0)
13
+ bcrypt-ruby (~> 3.0.0)
14
+ builder (~> 3.0.0)
15
+ i18n (~> 0.6)
16
+ activerecord (3.1.0)
17
+ activemodel (= 3.1.0)
18
+ activesupport (= 3.1.0)
19
+ arel (~> 2.2.1)
20
+ tzinfo (~> 0.3.29)
21
+ activesupport (3.1.0)
22
+ multi_json (~> 1.0)
23
+ arel (2.2.1)
24
+ bcrypt-ruby (3.0.0)
25
+ builder (3.0.0)
26
+ cancan (1.6.5)
27
+ i18n (0.6.0)
28
+ minitest (2.5.1)
29
+ multi_json (1.0.3)
30
+ role_model (0.7.0)
31
+ sqlite3 (1.3.4)
32
+ tzinfo (0.3.29)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ activerecord
39
+ canard!
40
+ minitest (~> 2)
41
+ sqlite3
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,128 @@
1
+ = Canard
2
+
3
+ Canard brings CanCan and RoleModel together to make role based authorization in Rails easy. Your ability
4
+ definitions gain their own folder and a little structure. The easiest way to get started is with the
5
+ Canard generator. Canard progressively enhances the abilities of the model by applying role abilities on
6
+ top of the models base abilities.
7
+
8
+ A User model with :admin and :manger roles would be defined:
9
+
10
+ class User < ActiveRecord::Base
11
+
12
+ acts_as_user :roles => :admin, :manager
13
+
14
+ end
15
+
16
+ Lets generate some abilities for the User.
17
+
18
+ $ rails g canard:ability user can:[read,create]:[account,statement] cannot:destroy:account
19
+ create abilities/users.rb
20
+ invoke rspec
21
+ create spec/abilities/user_spec.rb
22
+
23
+ Generates an ability folder in Rails root and an associated spec;
24
+
25
+ abilities/
26
+ users.rb
27
+ spec/abilities/
28
+ users_spec.rb
29
+
30
+ The resulting abilities/users.rb will look something like this;
31
+
32
+ abilities_for(:user) do
33
+
34
+ can [:read, :create], Account
35
+ cannot [:destroy], Account
36
+ can [:read, :create], Statement
37
+
38
+ end
39
+
40
+ And it's associated test spec/abilities/users_spec.rb;
41
+
42
+ require_relative '../spec_helper'
43
+ require "cancan/matchers"
44
+
45
+ describe Ability, "for :user" do
46
+
47
+ before do
48
+ @user = Factory.create(:user_user)
49
+ end
50
+
51
+ subject { Ability.new(@user) }
52
+
53
+ describe 'on Account' do
54
+
55
+ before do
56
+ @account = Factory.create(:account)
57
+ end
58
+
59
+ it { should be_able_to( :read, @account ) }
60
+ it { should be_able_to( :create, @account ) }
61
+ it { should_not be_able_to( :destroy, @account ) }
62
+
63
+ end
64
+ # on Account
65
+
66
+ describe 'on Statement' do
67
+
68
+ before do
69
+ @statement = Factory.create(:statement)
70
+ end
71
+
72
+ it { should be_able_to( :read, @statement ) }
73
+ it { should be_able_to( :create, @statement ) }
74
+
75
+ end
76
+ # on Statement
77
+
78
+ end
79
+
80
+ Now lets generate some abilities for the manager and admin.
81
+
82
+ $ rails g canard:ability admin can:manage:[account,statement]
83
+ $ rails g canard:ability manager can:edit:statement
84
+
85
+ Will give us two new sets of abilities in the abilities folder. Canard will apply these abilities by first
86
+ loading the ability for the User model and then apply the abilities for each role the current user has.
87
+
88
+ Canard also creates a guest ability by default so:
89
+
90
+ $ rails g canard:ability guest can:create:user
91
+
92
+ Would generate an ability for a not logged in user to signup.
93
+
94
+ Obviously the generators are just a starting point and should not be used only to get you going. I strongly
95
+ suggest that every new model you create you add to the abilities as the specs are so easy to write and CanCan
96
+ definitions are so clear and simple.
97
+
98
+ == Installation
99
+
100
+ === Rails 3.x
101
+
102
+ Add the canard gem to your Gemfile. In Gemfile:
103
+
104
+ gem "canard"
105
+
106
+ That's it!
107
+
108
+ === Rails 2.x
109
+
110
+ Sorry you are out of luck with Rails 2.x Canard has only been written and tested with Rails 3.x. I'll be happy
111
+ to accept pull requests for tested Rails 2.x updates if anybody is game.
112
+
113
+ == Note on Patches/Pull Request
114
+
115
+ * Fork the project.
116
+ * Make your feature addition or bug fix.
117
+ * Add tests for it (when I have some). This is important so I don't break it in a future version unintentionally.
118
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but
119
+ bump version in a commit by itself I can ignore it when I pull)
120
+ * Send me a pull request. Bonus points for topic branches.
121
+
122
+ == Credits
123
+
124
+ Thanks to Ryan Bates for creating the awesome CanCan (http://wiki.github.com/ryanb/cancan/role-based-authorization)
125
+ and Martin Rehfeld for implementing Role Based Authorization in the form of RoleModel (http://github.com/martinrehfeld/role_model).
126
+
127
+ == Copyright
128
+ Copyright (c) 2011 James McCarthy, released under the MIT license
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'lib' << "test"
7
+ t.pattern = 'test/*_test.rb'
8
+ t.verbose = true
9
+ end
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ * create ability generator for a new model e.g. rails g canard:abilitiy user:manage
2
+ * Test the ability class.
3
+ * Test the generators.
4
+ * Test the railtie
5
+ * Add scopes by default and :scopes => false to acts_as_user
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "canard/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "canard"
7
+ s.version = Canard::VERSION
8
+ s.authors = ["James McCarthy"]
9
+ s.email = ["james2mccarthy@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Adds RoleModel roles to CanCan.}
12
+ s.description = %q{Wraps CanCan and RoleModel up with some scopes}
13
+
14
+ s.rubyforge_project = "canard"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "minitest", "~> 2"
22
+ s.add_development_dependency "sqlite3"
23
+ s.add_development_dependency "activerecord"
24
+ s.add_runtime_dependency "cancan"
25
+ s.add_runtime_dependency "role_model"
26
+ end
@@ -0,0 +1,41 @@
1
+ class Ability
2
+
3
+ include CanCan::Ability
4
+
5
+ def initialize(object=nil)
6
+
7
+ # If a user was passed set the user from it.
8
+ @user = object.is_a?(Account) ? object.user : object
9
+
10
+ if @user
11
+ # Add the base user abilities.
12
+ load_abilities @user.class.name.underscore.to_sym
13
+ else
14
+ # If user not set then lets create a guest
15
+ @user = Object.new
16
+ load_abilities :guest
17
+ end
18
+
19
+ # If user has roles get those abilities
20
+ if @user.respond_to?(:roles)
21
+ # Add roles on top of the base user abilities
22
+ @user.roles.each { |role| load_abilities(role) }
23
+ end
24
+
25
+ end
26
+
27
+ private
28
+
29
+ def user
30
+ @user
31
+ end
32
+
33
+ def ability_definitions
34
+ Canard.ability_definitions
35
+ end
36
+
37
+ def load_abilities(role)
38
+ instance_eval(&ability_definitions[role]) if ability_definitions.has_key?(role)
39
+ end
40
+
41
+ end
@@ -0,0 +1,12 @@
1
+ require 'cancan'
2
+ require 'role_model'
3
+ require "canard/version"
4
+ require "canard/find_abilities"
5
+ require "ability"
6
+
7
+ module Canard
8
+ autoload :UserModel, 'canard/user_model'
9
+ end
10
+
11
+ require 'canard/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
12
+
@@ -0,0 +1,31 @@
1
+ module Canard
2
+
3
+ class << self
4
+ # A string specifying the location that should be searched for ability
5
+ # definitions. By default, Canard will attempt to load abilities from
6
+ # Rails.root + /abilities/.
7
+ attr_accessor :abilities_path
8
+
9
+ def ability_definitions
10
+ @ability_definitions ||= {}
11
+ end
12
+
13
+ def abilities_for(role, &block)
14
+ ability_definitions[role] = block
15
+ end
16
+
17
+ end
18
+
19
+ def self.find_abilities #:nodoc:
20
+
21
+ absolute_abilities_path = File.expand_path(abilities_path)
22
+
23
+ if File.directory? absolute_abilities_path
24
+ Dir[File.join(absolute_abilities_path, '**', '*.rb')].sort.each do |file|
25
+ self.class_eval File.read(file)
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,20 @@
1
+ require 'canard'
2
+ require 'rails'
3
+
4
+ module Canard
5
+ class Railtie < Rails::Railtie
6
+
7
+ initializer "canard.active_record" do |app|
8
+ ActiveSupport.on_load :active_record do
9
+ extend Canard::UserModel
10
+ Canard.abilities_path ||= File.expand_path('abilities', Rails.root)
11
+ Canard.find_abilities
12
+ end
13
+ end
14
+
15
+ initializer "canard.abilities_reloading", :after => "action_dispatch.configure" do |app|
16
+ ActionDispatch::Reloader.to_prepare { Canard.find_abilities }
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module Canard
2
+
3
+ module UserModel
4
+
5
+ def acts_as_user(*args)
6
+ include RoleModel
7
+
8
+ options = args.extract_options!.symbolize_keys
9
+
10
+ roles options[:roles] if options.has_key?(:roles) && column_names.include?(roles_attribute_name.to_s)
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,3 @@
1
+ module Canard
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,43 @@
1
+ require 'active_support/inflector'
2
+
3
+ class AbilityDefinition
4
+
5
+ attr_accessor :cans, :cannots
6
+
7
+ def self.parse(definitions)
8
+ @@ability_definitions ||= {}
9
+ limitation, ability_names, model_names = *definitions.split(':')
10
+ abilities, models = extract(ability_names), extract(model_names)
11
+ models.each do |model|
12
+ definition = @@ability_definitions[model] || AbilityDefinition.new
13
+ definition.merge(limitation.pluralize, abilities)
14
+ @@ability_definitions[model] = definition
15
+ end
16
+ end
17
+
18
+ def self.extract(string)
19
+ return *string.gsub(/[\[\]\s]/, '').split(',')
20
+ end
21
+
22
+ def self.models
23
+ @@ability_definitions
24
+ end
25
+
26
+ def initialize
27
+ @cans, @cannots = [], []
28
+ end
29
+
30
+ def merge(limitation, abilities)
31
+ combined_abilities = instance_variable_get("@#{limitation}") | abilities
32
+ instance_variable_set("@#{limitation}", combined_abilities)
33
+ end
34
+
35
+ def can
36
+ @cans
37
+ end
38
+
39
+ def cannot
40
+ @cannots
41
+ end
42
+
43
+ end
@@ -0,0 +1,3 @@
1
+ Description:
2
+ The canard:ability generator creates an Ability definition in the abilities
3
+ directory. It also creates the shell of a spec for testing those abilities.
@@ -0,0 +1,27 @@
1
+ require_relative '../../ability_definition'
2
+
3
+ module Canard
4
+ module Generators
5
+ class AbilityGenerator < Rails::Generators::NamedBase
6
+ source_root File.expand_path('../templates', __FILE__)
7
+ argument :ability_definitions, :type => :array, :default => [], :banner => "can:[read,update]:[user,account] cannot:[create,destroy]:user"
8
+
9
+ def generate_ability
10
+ template "abilities.rb.erb", Canard.abilities_path + "/#{file_name.pluralize}.rb"
11
+ end
12
+
13
+ hook_for :test_framework, :as => 'ability'
14
+
15
+ private
16
+
17
+ def definitions(&block)
18
+ ability_definitions.each { |definition| AbilityDefinition.parse(definition) }
19
+
20
+ AbilityDefinition.models.sort.each do |model, definition|
21
+ yield model, definition
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ abilities_for(<%= ":#{name}" -%>) do
2
+
3
+ <% if ability_definitions.empty? -%>
4
+ # Define abilities for the user role here. For example:
5
+ #
6
+ # if user.admin?
7
+ # can :manage, :all
8
+ # else
9
+ # can :read, :all
10
+ # end
11
+ #
12
+ # The first argument to `can` is the action you are giving the user permission to do.
13
+ # If you pass :manage it will apply to every action. Other common actions here are
14
+ # :read, :create, :update and :destroy.
15
+ #
16
+ # The second argument is the resource the user can perform the action on. If you pass
17
+ # :all it will apply to every resource. Otherwise pass a Ruby class of the resource.
18
+ #
19
+ # The third argument is an optional hash of conditions to further filter the objects.
20
+ # For example, here the user can only update published articles.
21
+ #
22
+ # can :update, Article, :published => true
23
+ #
24
+ # See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
25
+ <% else -%>
26
+ <% definitions do |model, definition| -%>
27
+ <%= "can".ljust(8, ' ') + "#{definition.cans.map(&:to_sym)}, #{model.classify}" unless definition.cans.empty? %>
28
+ <%= "cannot".ljust(8, ' ') + "#{definition.cannots.map(&:to_sym)}, #{model.classify}" unless definition.cannots.empty? %>
29
+ <% end -%>
30
+ <% end -%>
31
+
32
+ end
@@ -0,0 +1,31 @@
1
+ require 'generators/rspec'
2
+ require_relative '../../ability_definition'
3
+
4
+ module Rspec
5
+ module Generators
6
+ class AbilityGenerator < Base
7
+ @_rspec_source_root = File.expand_path('../templates', __FILE__)
8
+ argument :ability_definitions, :type => :array, :default => [], :banner => "can:abilities:models cannot:abilities:models"
9
+
10
+ def generate_ability_spec
11
+ template "abilities_spec.rb.erb", "spec/abilities/#{file_name}_spec.rb"
12
+ end
13
+
14
+ private
15
+
16
+ def add_new_abilities
17
+ gsub_file "spec/abilities/#{file_name}_spec.rb", /^(\s*end\s*\Z)/, 'wibble' + '\1'
18
+ end
19
+
20
+ def definitions(&block)
21
+ ability_definitions.each { |definition| AbilityDefinition.parse(definition) }
22
+
23
+ AbilityDefinition.models.sort.each do |model, definition|
24
+ yield model, definition
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,55 @@
1
+ require_relative '../spec_helper'
2
+
3
+ require "cancan/matchers"
4
+
5
+ describe Ability, "for :<%= name %>" do
6
+
7
+ before do
8
+ @<%= name %> = Factory.create(:<%= name %>_user)
9
+ end
10
+
11
+ subject { Ability.new(@<%= name -%>) }
12
+
13
+ <% if ability_definitions.empty? -%>
14
+ # Define your ability tests thus;
15
+ #
16
+ # describe 'on Activity' do
17
+ #
18
+ # before do
19
+ # @activity = Factory.create(:activity)
20
+ # end
21
+ #
22
+ # it { should be_able_to( :index, Activity ) }
23
+ # it { should be_able_to( :show, @activity ) }
24
+ # it { should be_able_to( :read, @activity ) }
25
+ # it { should be_able_to( :new, @activity ) }
26
+ # it { should be_able_to( :create, @activity ) }
27
+ # it { should be_able_to( :edit, @activity ) }
28
+ # it { should be_able_to( :update, @activity ) }
29
+ # it { should be_able_to( :destroy, @activity ) }
30
+ #
31
+ # end
32
+ # # on Activity
33
+ <% else -%>
34
+ <% definitions do |model, definition| -%>
35
+
36
+ describe 'on <%= model.camelize -%>' do
37
+
38
+ before do
39
+ @<%= model -%> = Factory.create(:<%= model -%>)
40
+ end
41
+
42
+ <% definition.cans.each do |can| -%>
43
+ it { should be_able_to( <%= ":#{can},".ljust(12, ' ') + (can == 'index' ? model.camelize : "@#{model}") -%> ) }
44
+ <% end -%>
45
+ <%- definition.cannots.each do |cannot| -%>
46
+ it { should_not be_able_to( <%= ":#{cannot},".ljust(12, ' ') + (cannot == 'index' ? model.camelize : "@#{model}") -%> ) }
47
+ <% end -%>
48
+
49
+ end
50
+ # on <%= model.camelize %>
51
+ <% end -%>
52
+
53
+ <% end -%>
54
+ end
55
+
@@ -0,0 +1,9 @@
1
+ abilities_for(:admin) do
2
+
3
+ can :manage, [Activity, User, Variation, Year]
4
+
5
+ cannot :destroy, User do |u|
6
+ (user == u)
7
+ end
8
+
9
+ end
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+ require_relative '../lib/canard.rb'
3
+
4
+ describe Canard do
5
+
6
+ before do
7
+ class User < ActiveRecord::Base
8
+ end
9
+
10
+ Canard.abilities_path = File.expand_path('../abilities', __FILE__)
11
+ end
12
+
13
+ # Sanity test
14
+ it "must be an user" do
15
+ user = User.new
16
+ user.must_be_instance_of User
17
+ end
18
+
19
+ describe "abilities_path" do
20
+
21
+ it "should be mutable" do
22
+ Canard.abilities_path = 'app/abilities'
23
+ Canard.abilities_path.must_equal 'app/abilities'
24
+ end
25
+
26
+ end
27
+
28
+ describe "ability_definitions" do
29
+
30
+ it "should be an accessor" do
31
+ Canard.must_respond_to(:ability_definitions)
32
+ end
33
+
34
+ it "should be a hash" do
35
+ Canard.ability_definitions.must_be_instance_of Hash
36
+ end
37
+
38
+ end
39
+
40
+ describe "find_abilities" do
41
+
42
+ it "should load the abilities into ability_definitions" do
43
+ Canard.find_abilities
44
+
45
+ Canard.ability_definitions.keys.must_include :admin
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,4 @@
1
+ class User < ActiveRecord::Base
2
+ extend Canard::UserModel
3
+ acts_as_user :roles => [:admin, :author, :viewer]
4
+ end
@@ -0,0 +1,5 @@
1
+ class UserWithoutRole < ActiveRecord::Base
2
+ extend Canard::UserModel
3
+ acts_as_user
4
+ end
5
+
@@ -0,0 +1,4 @@
1
+ class UserWithoutRoleMask < ActiveRecord::Base
2
+ extend Canard::UserModel
3
+ acts_as_user
4
+ end
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ gem 'minitest'
3
+ require 'active_record'
4
+ require 'minitest/autorun'
5
+
6
+ module MiniTestWithHooks
7
+ class Unit < MiniTest::Unit
8
+ def before_suites
9
+ end
10
+
11
+ def after_suites
12
+ end
13
+
14
+ def _run_suites(suites, type)
15
+ begin
16
+ before_suites
17
+ super(suites, type)
18
+ ensure
19
+ after_suites
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ module MiniTestWithActiveRecord
26
+ class Unit < MiniTestWithHooks::Unit
27
+
28
+ def before_suites
29
+ super
30
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
31
+ ActiveRecord::Migration.verbose = false
32
+
33
+ @migration = Class.new(ActiveRecord::Migration) do
34
+
35
+ def change
36
+ create_table :users, :force => true do |t|
37
+ t.string :roles_mask
38
+ end
39
+ create_table :user_without_roles, :force => true do |t|
40
+ t.string :roles_mask
41
+ end
42
+ create_table :user_without_role_masks, :force => true do |t|
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ @migration.new.migrate(:up)
49
+ end
50
+
51
+ def after_suites
52
+ @migration.new.migrate(:down)
53
+ super
54
+ end
55
+ end
56
+ end
57
+
58
+ MiniTest::Unit.runner = MiniTestWithActiveRecord::Unit.new
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+ require 'canard'
3
+
4
+ describe Canard::UserModel do
5
+
6
+ before do
7
+ Canard.abilities_path = 'abilities'
8
+ require 'models/user'
9
+ require 'models/user_without_role'
10
+ require 'models/user_without_role_mask'
11
+ end
12
+
13
+ # Sanity test
14
+ it "must be an user" do
15
+ user = User.new
16
+ user.must_be_instance_of User
17
+ user = UserWithoutRole.new
18
+ user.must_be_instance_of UserWithoutRole
19
+ user = UserWithoutRoleMask.new
20
+ user.must_be_instance_of UserWithoutRoleMask
21
+ end
22
+
23
+ describe 'acts_as_user' do
24
+
25
+ it 'should add role_model to this model' do
26
+ User.included_modules.must_include RoleModel
27
+ User.must_respond_to :roles
28
+ end
29
+
30
+ describe 'on a model with a role mask' do
31
+
32
+ describe 'and :roles => [] specified' do
33
+
34
+ it 'should set the valid_roles for the class' do
35
+ User.valid_roles.must_equal [:admin, :author, :viewer]
36
+ end
37
+
38
+ end
39
+
40
+ describe 'with no :roles => [] specified' do
41
+
42
+ it 'should not set any roles' do
43
+ UserWithoutRole.valid_roles.must_equal []
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ describe 'with no roles_mask' do
50
+
51
+ it 'should not set any roles' do
52
+ UserWithoutRole.valid_roles.must_equal []
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: canard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James McCarthy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-02 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: &2153074000 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2153074000
25
+ - !ruby/object:Gem::Dependency
26
+ name: sqlite3
27
+ requirement: &2153073580 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2153073580
36
+ - !ruby/object:Gem::Dependency
37
+ name: activerecord
38
+ requirement: &2153073120 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2153073120
47
+ - !ruby/object:Gem::Dependency
48
+ name: cancan
49
+ requirement: &2153072700 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *2153072700
58
+ - !ruby/object:Gem::Dependency
59
+ name: role_model
60
+ requirement: &2153072280 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *2153072280
69
+ description: Wraps CanCan and RoleModel up with some scopes
70
+ email:
71
+ - james2mccarthy@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - MIT-LICENSE
80
+ - README.rdoc
81
+ - Rakefile
82
+ - TODO
83
+ - canard.gemspec
84
+ - lib/ability.rb
85
+ - lib/canard.rb
86
+ - lib/canard/find_abilities.rb
87
+ - lib/canard/railtie.rb
88
+ - lib/canard/user_model.rb
89
+ - lib/canard/version.rb
90
+ - lib/generators/ability_definition.rb
91
+ - lib/generators/canard/ability/USAGE
92
+ - lib/generators/canard/ability/ability_generator.rb
93
+ - lib/generators/canard/ability/templates/abilities.rb.erb
94
+ - lib/generators/rspec/ability/ability_generator.rb
95
+ - lib/generators/rspec/ability/templates/abilities_spec.rb.erb
96
+ - test/abilities/admins.rb
97
+ - test/canard_test.rb
98
+ - test/models/user.rb
99
+ - test/models/user_without_role.rb
100
+ - test/models/user_without_role_mask.rb
101
+ - test/test_helper.rb
102
+ - test/user_model_test.rb
103
+ homepage: ''
104
+ licenses: []
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project: canard
123
+ rubygems_version: 1.8.6
124
+ signing_key:
125
+ specification_version: 3
126
+ summary: Adds RoleModel roles to CanCan.
127
+ test_files:
128
+ - test/abilities/admins.rb
129
+ - test/canard_test.rb
130
+ - test/models/user.rb
131
+ - test/models/user_without_role.rb
132
+ - test/models/user_without_role_mask.rb
133
+ - test/test_helper.rb
134
+ - test/user_model_test.rb