rolify 3.2.0 → 3.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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