rolify 3.2.0 → 3.3.0.rc1

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.
Files changed (32) hide show
  1. data/.travis.yml +2 -0
  2. data/README.md +9 -5
  3. data/lib/generators/rolify/role/role_generator.rb +4 -1
  4. data/lib/generators/rolify/role/templates/README +8 -6
  5. data/lib/generators/rolify/role/templates/README-active_record +2 -15
  6. data/lib/generators/rolify/role/templates/README-mongoid +2 -15
  7. data/lib/generators/rolify/role/templates/role-mongoid.rb +0 -2
  8. data/lib/rolify.rb +13 -10
  9. data/lib/rolify/adapters/active_record/resource_adapter.rb +1 -1
  10. data/lib/rolify/adapters/active_record/role_adapter.rb +5 -4
  11. data/lib/rolify/adapters/base.rb +1 -1
  12. data/lib/rolify/adapters/mongoid/resource_adapter.rb +2 -2
  13. data/lib/rolify/adapters/mongoid/role_adapter.rb +24 -14
  14. data/lib/rolify/finders.rb +17 -16
  15. data/lib/rolify/matchers.rb +13 -0
  16. data/lib/rolify/resource.rb +1 -1
  17. data/lib/rolify/version.rb +1 -1
  18. data/spec/generators/rolify/role/role_generator_spec.rb +0 -1
  19. data/spec/rolify/custom_spec.rb +1 -1
  20. data/spec/rolify/matchers_spec.rb +24 -0
  21. data/spec/rolify/namespace_spec.rb +27 -0
  22. data/spec/rolify/resource_spec.rb +36 -29
  23. data/spec/rolify/resourcifed_and_rolifed_spec.rb +20 -0
  24. data/spec/rolify/shared_examples/shared_examples_for_dynamic.rb +2 -2
  25. data/spec/rolify/shared_examples/shared_examples_for_remove_role.rb +59 -59
  26. data/spec/rolify/shared_examples/shared_examples_for_roles.rb +2 -2
  27. data/spec/spec_helper.rb +2 -1
  28. data/spec/support/adapters/active_record.rb +40 -9
  29. data/spec/support/adapters/mongoid.rb +77 -20
  30. data/spec/support/data.rb +12 -15
  31. data/spec/support/schema.rb +24 -18
  32. metadata +83 -26
@@ -12,3 +12,5 @@ before_install:
12
12
  - gem update --system
13
13
  - gem --version
14
14
  - ruby -v
15
+
16
+ services: mongodb
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # rolify [![build status](https://secure.travis-ci.org/EppO/rolify.png?branch=master)](http://travis-ci.org/EppO/rolify) [![dependency status](https://gemnasium.com/EppO/rolify.png)](https://gemnasium.com/EppO/rolify)
1
+ # rolify [![Gem Version](https://badge.fury.io/rb/rolify.png)](http://badge.fury.io/rb/rolify) [![build status](https://secure.travis-ci.org/EppO/rolify.png?branch=master)](http://travis-ci.org/EppO/rolify) [![dependency status](https://gemnasium.com/EppO/rolify.png)](https://gemnasium.com/EppO/rolify) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/EppO/rolify)
2
2
 
3
3
  Very simple Roles library without any authorization enforcement supporting scope on resource object.
4
4
 
@@ -9,7 +9,9 @@ user.has_role?(:moderator, Forum.first)
9
9
  => false # if user is moderator of another Forum
10
10
  ```
11
11
 
12
- This library was intended to be used with [CanCan](https://github.com/ryanb/cancan) and [devise](https://github.com/plataformatec/devise) but should be generic enough to be used by any other authentication/authorization solutions.
12
+ This library can be easily integrated with any authentication gem ([devise](https://github.com/plataformatec/devise), [Authlogic](https://github.com/binarylogic/authlogic), [Clearance](https://github.com/thoughtbot/clearance)) and authorization gem<span style="color: red"><strong>*</strong></span> ([CanCan](https://github.com/ryanb/cancan), [authority](https://github.com/nathanl/authority))
13
+
14
+ <span style="color: red"><strong>*</strong></span>: authorization gem that doesn't provide a role class
13
15
 
14
16
  ## Requirements
15
17
 
@@ -194,9 +196,11 @@ Starting from rolify 3.0, you can search roles on instance level or class level
194
196
 
195
197
  * [Wiki](https://github.com/EppO/rolify/wiki)
196
198
  * [Usage](https://github.com/EppO/rolify/wiki/Usage): all the available commands
197
- * [Tutorial](https://github.com/EppO/rolify/wiki/Tutorial): how to use [rolify](http://eppo.github.com/rolify) with [Devise](https://github.com/plataformatec/devise) and [CanCan](https://github.com/ryanb/cancan).
198
- * [Amazing tutorial](http://railsapps.github.com/tutorial-rails-bootstrap-devise-cancan.html) provided by [RailsApps](http://railsapps.github.com/)
199
+ * [Tutorials](https://github.com/EppO/rolify/wiki#wiki-tutorials):
200
+ * [How-To use rolify with Devise and CanCan](https://github.com/EppO/rolify/wiki/Tutorial)
201
+ * [Using rolify with Devise and Authority](https://github.com/EppO/rolify/wiki/Using-rolify-with-Devise-and-Authority)
202
+ * [Step-by-step tutorial](http://railsapps.github.com/tutorial-rails-bootstrap-devise-cancan.html) provided by [RailsApps](http://railsapps.github.com/)
199
203
 
200
204
  ## Questions or Problems?
201
205
 
202
- If you have any issue or feature request with/for rolify, please add an [issue on GitHub](https://github.com/EppO/rolify/issues) or fork the project and send a pull request.
206
+ If you have any issue or feature request with/for rolify, please add an [issue on GitHub](https://github.com/EppO/rolify/issues) or fork the project and send a pull request.
@@ -34,7 +34,10 @@ module Rolify
34
34
  end
35
35
 
36
36
  def show_readme
37
- readme "README-#{orm_adapter}" if behavior == :invoke
37
+ if behavior == :invoke
38
+ readme "README"
39
+ readme "README-#{orm_adapter}"
40
+ end
38
41
  end
39
42
 
40
43
  def inject_rolify_method
@@ -1,11 +1,13 @@
1
1
  ===============================================================================
2
2
 
3
- Now, you just have to run the migration using rake command:
3
+ An initializer file has been created here: config/initializers/rolify.rb, you
4
+ can change rolify settings to match your needs.
5
+ Defaults values are commented out.
4
6
 
5
- rake db:migrate
7
+ A Role class has been been created in app/models (with the name you gave as
8
+ argument otherwise the default is role.rb), you can add your own business logic
9
+ inside.
6
10
 
7
- An initializer file has been created here: config/initializers/rolify.rb,
8
- you can change rolify settings to match your needs.
9
- Defaults values are commented out.
11
+ Inside your User class (or the name you gave as argument otherwise the default
12
+ is user.rb), rolify method has been inserted to provide rolify methods.
10
13
 
11
- ===============================================================================
@@ -1,21 +1,8 @@
1
- ===============================================================================
2
-
3
- An initializer file has been created here: config/initializers/rolify.rb, you
4
- can change rolify settings to match your needs.
5
- Defaults values are commented out.
6
-
7
- A Role class has been been created in app/models (with the name you gave as
8
- argument otherwise the default is role.rb), you can add your own business logic
9
- inside.
10
-
11
- Inside your User class (or the name you gave as argument otherwise the default
12
- is user.rb), rolify method has been inserted to provide rolify methods.
13
-
14
- Now, if you just have to run the migration using rake command:
1
+ Now, you just have to run the migration using rake command:
15
2
 
16
3
  rake db:migrate
17
4
 
18
5
  and you will be able to add the resourcify method inside all models you want
19
6
  scoped by a role.
20
7
 
21
- ===============================================================================
8
+ ===============================================================================
@@ -1,17 +1,4 @@
1
- ===============================================================================
2
-
3
- An initializer file has been created here: config/initializers/rolify.rb, you
4
- can change rolify settings to match your needs.
5
- Defaults values are commented out.
6
-
7
- A Role class has been been created in app/models (with the name you gave as
8
- argument otherwise the default is role.rb), you can add your own business logic
9
- inside.
10
-
11
- Inside your User class (or the name you gave as argument otherwise the default
12
- is user.rb), rolify method has been inserted to provide rolify methods.
13
-
14
- Now, if you are able to add the resourcify method inside all models you want
1
+ Now, you are able to add the resourcify method inside all models you want
15
2
  scoped by a role.
16
3
 
17
- ===============================================================================
4
+ ===============================================================================
@@ -5,8 +5,6 @@ class <%= role_cname.camelize %>
5
5
  belongs_to :resource, :polymorphic => true
6
6
 
7
7
  field :name, :type => String
8
- index({ :name => 1 }, { :unique => true })
9
-
10
8
 
11
9
  index({
12
10
  :name => 1,
@@ -9,35 +9,38 @@ require 'rolify/adapters/base'
9
9
  module Rolify
10
10
  extend Configure
11
11
 
12
- attr_accessor :role_cname, :adapter
12
+ attr_accessor :role_cname, :adapter, :role_table_name
13
13
 
14
14
  def rolify(options = {})
15
15
  include Role
16
16
  extend Dynamic if Rolify.dynamic_shortcuts
17
17
 
18
18
  options.reverse_merge!({:role_cname => 'Role'})
19
+ self.role_cname = options[:role_cname]
20
+ self.role_table_name = self.role_cname.tableize.gsub(/\//, "_")
19
21
 
22
+ join_table = "#{self.to_s.tableize.gsub(/\//, "_")}_#{self.role_table_name}"
20
23
  rolify_options = { :class_name => options[:role_cname].camelize }
21
- rolify_options.merge!({ :join_table => "#{self.to_s.tableize}_#{options[:role_cname].tableize}" }) if Rolify.orm == "active_record"
22
- rolify_options.merge!(options.select{ |k,v| [:before_add, :after_add, :before_remove, :after_remove].include? k.to_sym }) if Rolify.orm == "active_record"
24
+ rolify_options.merge!({ :join_table => join_table }) if Rolify.orm == "active_record"
25
+ rolify_options.merge!(options.reject{ |k,v| ![:before_add, :after_add, :before_remove, :after_remove].include? k.to_sym }) if Rolify.orm == "active_record"
23
26
 
24
27
  has_and_belongs_to_many :roles, rolify_options
25
28
 
26
- self.adapter = Rolify::Adapter::Base.create("role_adapter", options[:role_cname], self.name)
27
- self.role_cname = options[:role_cname]
28
-
29
+ self.adapter = Rolify::Adapter::Base.create("role_adapter", self.role_cname, self.name)
29
30
  load_dynamic_methods if Rolify.dynamic_shortcuts
30
31
  end
31
32
 
32
- def resourcify(options = {})
33
+ def resourcify(association_name = :roles, options = {})
33
34
  include Resource
34
35
 
35
36
  options.reverse_merge!({ :role_cname => 'Role', :dependent => :destroy })
36
37
  resourcify_options = { :class_name => options[:role_cname].camelize, :as => :resource, :dependent => options[:dependent] }
37
- has_many :roles, resourcify_options
38
-
39
- self.adapter = Rolify::Adapter::Base.create("resource_adapter", options[:role_cname], self.name)
40
38
  self.role_cname = options[:role_cname]
39
+ self.role_table_name = self.role_cname.tableize.gsub(/\//, "_")
40
+
41
+ has_many association_name, resourcify_options
42
+
43
+ self.adapter = Rolify::Adapter::Base.create("resource_adapter", self.role_cname, self.name)
41
44
  end
42
45
 
43
46
  def scopify
@@ -12,7 +12,7 @@ module Rolify
12
12
 
13
13
  def in(relation, user, role_names)
14
14
  roles = user.roles.where(:name => role_names)
15
- relation.where("#{quote(role_class.to_s.tableize)}.id IN (?) AND ((resource_id = #{quote(relation.table_name)}.id) OR (resource_id IS NULL))", roles)
15
+ relation.where("#{quote(role_class.table_name)}.id IN (?) AND ((resource_id = #{quote(relation.table_name)}.id) OR (resource_id IS NULL))", roles)
16
16
  end
17
17
 
18
18
  private
@@ -17,13 +17,14 @@ module Rolify
17
17
  end
18
18
 
19
19
  def remove(relation, role_name, resource = nil)
20
- roles = relation.roles.where(:name => role_name)
21
- roles = roles.where(:resource_type => (resource.is_a?(Class) ? resource.to_s : resource.class.name)) if resource
22
- roles = roles.where(:resource_id => resource.id) if resource && !resource.is_a?(Class)
20
+ cond = { :name => role_name }
21
+ cond[:resource_type] = (resource.is_a?(Class) ? resource.to_s : resource.class.name) if resource
22
+ cond[:resource_id] = resource.id if resource && !resource.is_a?(Class)
23
+ roles = relation.roles.where(cond)
23
24
  if roles
24
25
  relation.roles.delete(roles)
25
26
  roles.each do |role|
26
- role.destroy if role.send(user_class.table_name.to_sym).empty?
27
+ role.destroy if role.send(ActiveSupport::Inflector.demodulize(user_class).tableize.to_sym).empty?
27
28
  end
28
29
  end
29
30
  roles
@@ -15,7 +15,7 @@ module Rolify
15
15
  end
16
16
 
17
17
  def role_table
18
- @role_cname.tableize
18
+ role_class.table_name
19
19
  end
20
20
 
21
21
  def self.create(adapter, role_cname, user_cname)
@@ -1,7 +1,7 @@
1
1
  require 'rolify/adapters/base'
2
2
 
3
3
  module Rolify
4
- module Adapter
4
+ module Adapter
5
5
  class ResourceAdapter < ResourceAdapterBase
6
6
  def resources_find(roles_table, relation, role_name)
7
7
  roles = roles_table.classify.constantize.where(:name.in => Array(role_name), :resource_type => relation.to_s)
@@ -13,7 +13,7 @@ module Rolify
13
13
  resources << role.resource
14
14
  end
15
15
  end
16
- resources.uniq
16
+ resources.compact.uniq
17
17
  end
18
18
 
19
19
  def in(resources, user, role_names)
@@ -19,20 +19,30 @@ module Rolify
19
19
  end
20
20
 
21
21
  def remove(relation, role_name, resource = nil)
22
- roles = { :name => role_name }
23
- roles.merge!({:resource_type => (resource.is_a?(Class) ? resource.to_s : resource.class.name)}) if resource
24
- roles.merge!({ :resource_id => resource.id }) if resource && !resource.is_a?(Class)
25
- roles_to_remove = relation.roles.where(roles)
26
- roles_to_remove.each do |role|
27
- # Deletion in n-n relations is unreliable. Sometimes it works, sometimes not.
28
- # So, this does not work all the time: `relation.roles.delete(role)`
29
- # @see http://stackoverflow.com/questions/9132596/rails3-mongoid-many-to-many-relation-and-delete-operation
30
- # We instead remove ids from the Role object and the relation object.
31
- relation.role_ids.delete(role.id)
32
- role.send((user_class.to_s.underscore + '_ids').to_sym).delete(relation.id)
33
-
34
- role.destroy if role.send(user_class.to_s.tableize.to_sym).empty?
35
- end
22
+ #roles = { :name => role_name }
23
+ #roles.merge!({:resource_type => (resource.is_a?(Class) ? resource.to_s : resource.class.name)}) if resource
24
+ #roles.merge!({ :resource_id => resource.id }) if resource && !resource.is_a?(Class)
25
+ #roles_to_remove = relation.roles.where(roles)
26
+ #roles_to_remove.each do |role|
27
+ # # Deletion in n-n relations is unreliable. Sometimes it works, sometimes not.
28
+ # # So, this does not work all the time: `relation.roles.delete(role)`
29
+ # # @see http://stackoverflow.com/questions/9132596/rails3-mongoid-many-to-many-relation-and-delete-operation
30
+ # # We instead remove ids from the Role object and the relation object.
31
+ # relation.role_ids.delete(role.id)
32
+ # role.send((user_class.to_s.underscore + '_ids').to_sym).delete(relation.id)
33
+ #
34
+ # role.destroy if role.send(user_class.to_s.tableize.to_sym).empty?
35
+ #end
36
+ cond = { :name => role_name }
37
+ cond[:resource_type] = (resource.is_a?(Class) ? resource.to_s : resource.class.name) if resource
38
+ cond[:resource_id] = resource.id if resource && !resource.is_a?(Class)
39
+ roles = relation.roles.where(cond)
40
+ roles.each do |role|
41
+ relation.roles.delete(role)
42
+ role.send(ActiveSupport::Inflector.demodulize(user_class).tableize.to_sym).delete(relation)
43
+ role.destroy if role.send(ActiveSupport::Inflector.demodulize(user_class).tableize.to_sym).empty?
44
+ end if roles
45
+ roles
36
46
  end
37
47
 
38
48
  def exists?(relation, column)
@@ -6,14 +6,7 @@ module Rolify
6
6
 
7
7
  def with_all_roles(*args)
8
8
  users = []
9
- args.each do |arg|
10
- if arg.is_a? Hash
11
- users_to_add = self.with_role(arg[:name], arg[:resource])
12
- elsif arg.is_a?(String) || arg.is_a?(Symbol)
13
- users_to_add = self.with_role(arg)
14
- else
15
- raise ArgumentError, "Invalid argument type: only hash or string or symbol allowed"
16
- end
9
+ parse_args(args, users) do |users_to_add|
17
10
  users = users_to_add if users.empty?
18
11
  users &= users_to_add
19
12
  return [] if users.empty?
@@ -23,17 +16,25 @@ module Rolify
23
16
 
24
17
  def with_any_role(*args)
25
18
  users = []
26
- args.each do |arg|
27
- if arg.is_a? Hash
28
- users_to_add = self.with_role(arg[:name], arg[:resource])
29
- elsif arg.is_a?(String) || arg.is_a?(Symbol)
30
- users_to_add = self.with_role(arg)
31
- else
32
- raise ArgumentError, "Invalid argument type: only hash or string or symbol allowed"
33
- end
19
+ parse_args(args, users) do |users_to_add|
34
20
  users += users_to_add
35
21
  end
36
22
  users.uniq
37
23
  end
38
24
  end
25
+
26
+ private
27
+
28
+ def parse_args(args, users, &block)
29
+ args.each do |arg|
30
+ if arg.is_a? Hash
31
+ users_to_add = self.with_role(arg[:name], arg[:resource])
32
+ elsif arg.is_a?(String) || arg.is_a?(Symbol)
33
+ users_to_add = self.with_role(arg)
34
+ else
35
+ raise ArgumentError, "Invalid argument type: only hash or string or symbol allowed"
36
+ end
37
+ block.call(users_to_add)
38
+ end
39
+ end
39
40
  end
@@ -0,0 +1,13 @@
1
+ RSpec::Matchers.define :have_role do |*args|
2
+ match do |resource|
3
+ resource.has_role?(*args)
4
+ end
5
+
6
+ failure_message_for_should do |resource|
7
+ "expected to have role #{args.map(&:inspect).join(" ")}"
8
+ end
9
+
10
+ failure_message_for_should_not do |resource|
11
+ "expected not to have role #{args.map(&:inspect).join(" ")}"
12
+ end
13
+ end
@@ -13,7 +13,7 @@ module Rolify
13
13
  end
14
14
 
15
15
  def with_role(role_name, user = nil)
16
- resources = self.adapter.resources_find(self.role_class.to_s.tableize, self, role_name)
16
+ resources = self.adapter.resources_find(self.role_table_name, self, role_name)
17
17
  user ? self.adapter.in(resources, user, role_name) : resources
18
18
  end
19
19
  alias :with_roles :with_role
@@ -1,3 +1,3 @@
1
1
  module Rolify
2
- VERSION = "3.2.0"
2
+ VERSION = "3.3.0.rc1"
3
3
  end
@@ -136,7 +136,6 @@ CLASS
136
136
  it { should contain "has_and_belongs_to_many :users\n" }
137
137
  it { should contain "belongs_to :resource, :polymorphic => true" }
138
138
  it { should contain "field :name, :type => String" }
139
- it { should contain "index({ :name => 1 }, { :unique => true })" }
140
139
  it { should contain " index({\n"
141
140
  " { :name => 1 },\n"
142
141
  " { :resource_type => 1 },\n"
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
  require "rolify/shared_examples/shared_examples_for_roles"
3
3
  require "rolify/shared_examples/shared_examples_for_dynamic"
4
4
  require "rolify/shared_examples/shared_examples_for_scopes"
5
- require "rolify/shared_examples/shared_examples_for_callbacks"
5
+ require "rolify/shared_examples/shared_examples_for_callbacks"
6
6
 
7
7
  describe "Using Rolify with custom User and Role class names" do
8
8
  it_behaves_like Rolify::Role do
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'have_role', focus: true do
4
+ let(:object) { Object.new }
5
+
6
+ it 'delegates to has_role?' do
7
+ object.should_receive(:has_role?).with(:read, 'Resource') { true }
8
+ object.should have_role(:read, 'Resource')
9
+ end
10
+
11
+ it 'reports a nice failure message for should' do
12
+ object.should_receive(:has_role?) { false }
13
+ expect{
14
+ object.should have_role(:read, 'Resource')
15
+ }.to raise_error('expected to have role :read "Resource"')
16
+ end
17
+
18
+ it 'reports a nice failure message for should_not' do
19
+ object.should_receive(:has_role?) { true }
20
+ expect{
21
+ object.should_not have_role(:read, 'Resource')
22
+ }.to raise_error('expected not to have role :read "Resource"')
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+ require "rolify/shared_examples/shared_examples_for_roles"
3
+ require "rolify/shared_examples/shared_examples_for_dynamic"
4
+ require "rolify/shared_examples/shared_examples_for_scopes"
5
+ require "rolify/shared_examples/shared_examples_for_callbacks"
6
+
7
+ describe "Rolify.namespace" do
8
+ it_behaves_like Rolify::Role do
9
+ let(:user_class) { Admin::Moderator }
10
+ let(:role_class) { Admin::Right }
11
+ end
12
+
13
+ it_behaves_like "Role.scopes" do
14
+ let(:user_class) { Admin::Moderator }
15
+ let(:role_class) { Admin::Right }
16
+ end
17
+
18
+ it_behaves_like Rolify::Dynamic do
19
+ let(:user_class) { Admin::Moderator }
20
+ let(:role_class) { Admin::Right }
21
+ end
22
+
23
+ it_behaves_like "Rolify.callbacks" do
24
+ let(:user_class) { Admin::Moderator }
25
+ let(:role_class) { Admin::Right }
26
+ end
27
+ end
@@ -3,16 +3,16 @@ require "spec_helper"
3
3
  describe Rolify::Resource do
4
4
  before(:all) do
5
5
  reset_defaults
6
- User.rolify :role_cname => "Role"
7
- Forum.resourcify :role_cname => "Role"
8
- Group.resourcify :role_cname => "Role"
6
+ User.rolify
7
+ Forum.resourcify
8
+ Group.resourcify
9
9
  Role.destroy_all
10
10
  end
11
11
 
12
12
  # Users
13
13
  let(:admin) { User.first }
14
14
  let(:tourist) { User.last }
15
-
15
+
16
16
  # roles
17
17
  let!(:forum_role) { admin.add_role(:forum, Forum.first) }
18
18
  let!(:godfather_role) { admin.add_role(:godfather, Forum) }
@@ -27,19 +27,19 @@ describe Rolify::Resource do
27
27
  it { should respond_to(:find_roles).with(1).arguments }
28
28
  it { should respond_to(:find_roles).with(2).arguments }
29
29
 
30
- context "with a role name as argument" do
31
- context "on the Forum class" do
30
+ context "with a role name as argument" do
31
+ context "on the Forum class" do
32
32
  subject { Forum }
33
33
 
34
- it "should include Forum instances with forum role" do
34
+ it "should include Forum instances with forum role" do
35
35
  subject.with_role(:forum).should =~ [ Forum.first, Forum.last ]
36
36
  end
37
- it "should include Forum instances with godfather role" do
37
+ it "should include Forum instances with godfather role" do
38
38
  subject.with_role(:godfather).should =~ Forum.all.to_a
39
39
  end
40
40
  end
41
41
 
42
- context "on the Group class" do
42
+ context "on the Group class" do
43
43
  subject { Group }
44
44
 
45
45
  it "should include Group instances with group role" do
@@ -47,20 +47,27 @@ describe Rolify::Resource do
47
47
  end
48
48
  end
49
49
 
50
+ context "on a Group instance" do
51
+ subject { Group.last }
52
+
53
+ it "should ignore nil entries" do
54
+ subject.subgroups.with_role(:group).should =~ [ ]
55
+ end
56
+ end
50
57
  end
51
58
 
52
- context "with an array of role names as argument" do
53
- context "on the Group class" do
59
+ context "with an array of role names as argument" do
60
+ context "on the Group class" do
54
61
  subject { Group }
55
-
56
- it "should include Group instances with both group and grouper roles" do
62
+
63
+ it "should include Group instances with both group and grouper roles" do
57
64
  subject.with_roles([:group, :grouper]).should =~ [ Group.first, Group.last ]
58
65
  end
59
66
  end
60
67
  end
61
68
 
62
69
  context "with a role name and a user as arguments" do
63
- context "on the Forum class" do
70
+ context "on the Forum class" do
64
71
  subject { Forum }
65
72
 
66
73
  it "should get all Forum instances binded to the forum role and the admin user" do
@@ -88,7 +95,7 @@ describe Rolify::Resource do
88
95
  end
89
96
  end
90
97
 
91
- context "on the Group class" do
98
+ context "on the Group class" do
92
99
  subject { Group }
93
100
 
94
101
  it "should get all resources binded to the group role and the admin user" do
@@ -102,7 +109,7 @@ describe Rolify::Resource do
102
109
  end
103
110
 
104
111
  context "with an array of role names and a user as arguments" do
105
- context "on the Forum class" do
112
+ context "on the Forum class" do
106
113
  subject { Forum }
107
114
 
108
115
  it "should get Forum instances binded to the forum and group roles and the tourist user" do
@@ -111,7 +118,7 @@ describe Rolify::Resource do
111
118
 
112
119
  end
113
120
 
114
- context "on the Group class" do
121
+ context "on the Group class" do
115
122
  subject { Group }
116
123
 
117
124
  it "should get Group instances binded to the group and grouper roles and the admin user" do
@@ -125,8 +132,8 @@ describe Rolify::Resource do
125
132
 
126
133
  describe ".find_role" do
127
134
 
128
- context "without using a role name parameter" do
129
-
135
+ context "without using a role name parameter" do
136
+
130
137
  context "on the Forum class" do
131
138
  subject { Forum }
132
139
 
@@ -151,7 +158,7 @@ describe Rolify::Resource do
151
158
 
152
159
  context "on the Group class" do
153
160
  subject { Group }
154
-
161
+
155
162
  it "should get all roles binded to a Group class or instance" do
156
163
  subject.find_roles.to_a.should =~ [ group_role, grouper_role ]
157
164
  end
@@ -172,7 +179,7 @@ describe Rolify::Resource do
172
179
  end
173
180
  end
174
181
 
175
- context "using a role name parameter" do
182
+ context "using a role name parameter" do
176
183
  context "on the Forum class" do
177
184
  subject { Forum }
178
185
 
@@ -209,7 +216,7 @@ describe Rolify::Resource do
209
216
 
210
217
  context "on the Group class" do
211
218
  subject { Group }
212
-
219
+
213
220
  context "without using a user parameter" do
214
221
  it "should get all roles binded to a Group class or instance and group role name" do
215
222
  subject.find_roles(:group).should include(group_role)
@@ -242,7 +249,7 @@ describe Rolify::Resource do
242
249
  end
243
250
  end
244
251
 
245
- context "using :any as role name parameter" do
252
+ context "using :any as role name parameter" do
246
253
  context "on the Forum class" do
247
254
  subject { Forum }
248
255
 
@@ -318,7 +325,7 @@ describe Rolify::Resource do
318
325
 
319
326
  it { should respond_to :roles }
320
327
 
321
- context "on a Forum instance" do
328
+ context "on a Forum instance" do
322
329
  its(:roles) { should eq([ forum_role, sneaky_role ]) }
323
330
  its(:roles) { subject.should_not include(group_role, godfather_role, tourist_role) }
324
331
  end
@@ -326,19 +333,19 @@ describe Rolify::Resource do
326
333
  context "on a Group instance" do
327
334
  subject { Group.last }
328
335
 
329
- its(:roles) { should eq([ group_role ]) }
336
+ its(:roles) { should eq([ group_role ]) }
330
337
  its(:roles) { should_not include(forum_role, godfather_role, sneaky_role, tourist_role) }
331
-
338
+
332
339
  context "when deleting a Group instance" do
333
- subject do
340
+ subject do
334
341
  Group.create(:name => "to delete")
335
342
  end
336
-
343
+
337
344
  before do
338
345
  subject.roles.create :name => "group_role1"
339
346
  subject.roles.create :name => "group_role2"
340
347
  end
341
-
348
+
342
349
  it "should remove the roles binded to this instance" do
343
350
  expect { subject.destroy }.to change { Role.count }.by(-2)
344
351
  end