rolify 3.1.0 → 4.0.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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -1
  3. data/.travis.yml +44 -11
  4. data/CHANGELOG.rdoc +70 -0
  5. data/CONTRIBUTORS +6 -0
  6. data/Gemfile +21 -2
  7. data/README.md +130 -68
  8. data/Rakefile +29 -4
  9. data/UPGRADE.rdoc +22 -0
  10. data/circle.yml +13 -0
  11. data/gemfiles/Gemfile.rails-3.2 +27 -0
  12. data/gemfiles/Gemfile.rails-4.0 +33 -0
  13. data/gemfiles/Gemfile.rails-4.1 +37 -0
  14. data/lib/generators/active_record/rolify_generator.rb +54 -0
  15. data/lib/generators/active_record/templates/README +8 -0
  16. data/lib/generators/active_record/templates/migration.rb +19 -0
  17. data/lib/generators/mongoid/rolify_generator.rb +55 -0
  18. data/lib/generators/mongoid/templates/README-mongoid +4 -0
  19. data/lib/generators/rolify/rolify_generator.rb +35 -0
  20. data/lib/generators/rolify/{role/templates/README-mongoid → templates/README} +1 -5
  21. data/lib/generators/rolify/templates/initializer.rb +7 -0
  22. data/lib/generators/rolify/templates/role-active_record.rb +11 -0
  23. data/lib/generators/rolify/{role/templates → templates}/role-mongoid.rb +9 -9
  24. data/lib/generators/rolify/user_generator.rb +39 -0
  25. data/lib/rolify/adapters/active_record/resource_adapter.rb +36 -6
  26. data/lib/rolify/adapters/active_record/role_adapter.rb +25 -13
  27. data/lib/rolify/adapters/active_record/scopes.rb +27 -0
  28. data/lib/rolify/adapters/base.rb +9 -0
  29. data/lib/rolify/adapters/mongoid/resource_adapter.rb +27 -6
  30. data/lib/rolify/adapters/mongoid/role_adapter.rb +35 -11
  31. data/lib/rolify/adapters/mongoid/scopes.rb +27 -0
  32. data/lib/rolify/configure.rb +36 -5
  33. data/lib/rolify/finders.rb +40 -0
  34. data/lib/rolify/matchers.rb +31 -0
  35. data/lib/rolify/railtie.rb +1 -1
  36. data/lib/rolify/resource.rb +19 -10
  37. data/lib/rolify/role.rb +33 -13
  38. data/lib/rolify/version.rb +1 -1
  39. data/lib/rolify.rb +46 -20
  40. data/rolify.gemspec +18 -24
  41. data/spec/README.rdoc +24 -0
  42. data/spec/generators/rolify/rolify_activerecord_generator_spec.rb +165 -0
  43. data/spec/generators/rolify/rolify_mongoid_generator_spec.rb +113 -0
  44. data/spec/generators_helper.rb +27 -0
  45. data/spec/rolify/config_spec.rb +20 -21
  46. data/spec/rolify/custom_spec.rb +11 -6
  47. data/spec/rolify/matchers_spec.rb +24 -0
  48. data/spec/rolify/namespace_spec.rb +24 -0
  49. data/spec/rolify/resource_spec.rb +135 -37
  50. data/spec/rolify/resourcifed_and_rolifed_spec.rb +24 -0
  51. data/spec/rolify/role_spec.rb +8 -9
  52. data/spec/rolify/shared_contexts.rb +22 -3
  53. data/spec/rolify/shared_examples/shared_examples_for_add_role.rb +10 -17
  54. data/spec/rolify/shared_examples/shared_examples_for_callbacks.rb +65 -0
  55. data/spec/rolify/shared_examples/shared_examples_for_dynamic.rb +64 -27
  56. data/spec/rolify/shared_examples/shared_examples_for_finders.rb +81 -0
  57. data/spec/rolify/shared_examples/shared_examples_for_has_all_roles.rb +29 -29
  58. data/spec/rolify/shared_examples/shared_examples_for_has_any_role.rb +35 -35
  59. data/spec/rolify/shared_examples/shared_examples_for_has_role.rb +38 -38
  60. data/spec/rolify/shared_examples/shared_examples_for_only_has_role.rb +174 -0
  61. data/spec/rolify/shared_examples/shared_examples_for_remove_role.rb +28 -59
  62. data/spec/rolify/shared_examples/shared_examples_for_roles.rb +58 -32
  63. data/spec/rolify/shared_examples/shared_examples_for_scopes.rb +38 -0
  64. data/spec/spec_helper.rb +39 -3
  65. data/spec/support/adapters/active_record.rb +58 -7
  66. data/spec/support/adapters/mongoid.rb +110 -17
  67. data/spec/support/adapters/mongoid.yml +6 -0
  68. data/spec/support/data.rb +18 -15
  69. data/spec/support/schema.rb +31 -16
  70. data/spec/support/stream_helpers.rb +18 -0
  71. metadata +88 -84
  72. data/lib/generators/rolify/role/role_generator.rb +0 -41
  73. data/lib/generators/rolify/role/templates/README +0 -11
  74. data/lib/generators/rolify/role/templates/README-active_record +0 -21
  75. data/lib/generators/rolify/role/templates/initializer.rb +0 -7
  76. data/lib/generators/rolify/role/templates/migration.rb +0 -19
  77. data/lib/generators/rolify/role/templates/role-active_record.rb +0 -4
  78. data/spec/generators/rolify/role/role_generator_spec.rb +0 -197
@@ -0,0 +1,113 @@
1
+ require 'generators_helper'
2
+
3
+ # Generators are not automatically loaded by Rails
4
+ require 'generators/rolify/rolify_generator'
5
+
6
+ describe Rolify::Generators::RolifyGenerator, :if => ENV['ADAPTER'] == 'mongoid' do
7
+ # Tell the generator where to put its output (what it thinks of as Rails.root)
8
+ destination File.expand_path("../../../../tmp", __FILE__)
9
+ teardown :cleanup_destination_root
10
+
11
+ before {
12
+ prepare_destination
13
+ }
14
+
15
+ def cleanup_destination_root
16
+ FileUtils.rm_rf destination_root
17
+ end
18
+
19
+ describe 'specifying ORM adapter' do
20
+ before(:all) { arguments [ "Role", "User", "--orm=mongoid" ] }
21
+
22
+ before {
23
+ capture(:stdout) {
24
+ generator.create_file "app/models/user.rb" do
25
+ <<-RUBY
26
+ class User
27
+ include Mongoid::Document
28
+
29
+ field :login, :type => String
30
+ end
31
+ RUBY
32
+ end
33
+ }
34
+ require File.join(destination_root, "app/models/user.rb")
35
+ run_generator
36
+ }
37
+
38
+ describe 'config/initializers/rolify.rb' do
39
+ subject { file('config/initializers/rolify.rb') }
40
+ it { should exist }
41
+ it { should contain "Rolify.configure do |config|"}
42
+ it { should_not contain "# config.use_mongoid" }
43
+ it { should contain "# config.use_dynamic_shortcuts" }
44
+ end
45
+
46
+ describe 'app/models/role.rb' do
47
+ subject { file('app/models/role.rb') }
48
+ it { should exist }
49
+ it { should contain "class Role\n" }
50
+ it { should contain "has_and_belongs_to_many :users\n" }
51
+ it { should contain "belongs_to :resource, :polymorphic => true" }
52
+ it { should contain "field :name, :type => String" }
53
+ it { should contain " index({\n"
54
+ " { :name => 1 },\n"
55
+ " { :resource_type => 1 },\n"
56
+ " { :resource_id => 1 }\n"
57
+ " },\n"
58
+ " { unique => true })"}
59
+ it { should contain "validates :resource_type,\n"
60
+ " :inclusion => { :in => Rolify.resource_types },\n"
61
+ " :allow_nil => true" }
62
+ end
63
+
64
+ describe 'app/models/user.rb' do
65
+ subject { file('app/models/user.rb') }
66
+ it { should contain /class User\n include Mongoid::Document\n rolify\n/ }
67
+ end
68
+ end
69
+
70
+ describe 'specifying namespaced User and Role class names and ORM adapter' do
71
+ before(:all) { arguments %w(Admin::Role Admin::User --orm=mongoid) }
72
+
73
+ before {
74
+ capture(:stdout) {
75
+ generator.create_file "app/models/admin/user.rb" do
76
+ <<-RUBY
77
+ module Admin
78
+ class User
79
+ include Mongoid::Document
80
+ end
81
+ end
82
+ RUBY
83
+ end
84
+ }
85
+ require File.join(destination_root, "app/models/admin/user.rb")
86
+ run_generator
87
+ }
88
+
89
+ describe 'config/initializers/rolify.rb' do
90
+ subject { file('config/initializers/rolify.rb') }
91
+
92
+ it { should exist }
93
+ it { should contain "Rolify.configure(\"Admin::Role\") do |config|"}
94
+ it { should contain "# config.use_dynamic_shortcuts" }
95
+ it { should_not contain "# config.use_mongoid" }
96
+ end
97
+
98
+ describe 'app/models/admin/role.rb' do
99
+ subject { file('app/models/admin/role.rb') }
100
+
101
+ it { should exist }
102
+ it { should contain "class Admin::Role" }
103
+ it { should contain "has_and_belongs_to_many :admin_users" }
104
+ it { should contain "belongs_to :resource, :polymorphic => true" }
105
+ end
106
+
107
+ describe 'app/models/admin/user.rb' do
108
+ subject { file('app/models/admin/user.rb') }
109
+
110
+ it { should contain /class User\n include Mongoid::Document\n rolify :role_cname => 'Admin::Role'\n/ }
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require "bundler/setup"
3
+
4
+ require 'rolify'
5
+ require 'rolify/matchers'
6
+ require 'rails'
7
+ require_relative 'support/stream_helpers'
8
+ include StreamHelpers
9
+
10
+ require 'coveralls'
11
+ Coveralls.wear_merged!
12
+
13
+ ENV['ADAPTER'] ||= 'active_record'
14
+
15
+ if ENV['ADAPTER'] == 'active_record'
16
+ require 'active_record/railtie'
17
+ else
18
+ require 'mongoid'
19
+ end
20
+
21
+ module TestApp
22
+ class Application < ::Rails::Application
23
+ config.root = File.dirname(__FILE__)
24
+ end
25
+ end
26
+
27
+ require 'ammeter/init'
@@ -1,14 +1,14 @@
1
1
  require "spec_helper"
2
- require "active_record"
3
- require "mongoid"
4
2
 
5
- class ARUser < ActiveRecord::Base
6
- extend Rolify
7
- end
8
-
9
- class MUser
10
- include Mongoid::Document
11
- extend Rolify
3
+ if ENV['ADAPTER'] == 'active_record'
4
+ class ARUser < ActiveRecord::Base
5
+ extend Rolify
6
+ end
7
+ else
8
+ class MUser
9
+ include Mongoid::Document
10
+ extend Rolify
11
+ end
12
12
  end
13
13
 
14
14
  describe Rolify do
@@ -20,7 +20,7 @@ describe Rolify do
20
20
  context "using defaults values" do
21
21
  subject { Rolify.dynamic_shortcuts }
22
22
 
23
- it { should be_false }
23
+ it { should be_falsey }
24
24
  end
25
25
 
26
26
  context "using custom values" do
@@ -30,19 +30,19 @@ describe Rolify do
30
30
 
31
31
  subject { Rolify.dynamic_shortcuts }
32
32
 
33
- it { should be_true }
33
+ it { should be_truthy }
34
34
  end
35
35
  end
36
36
 
37
37
  describe :orm do
38
- context "using defaults values" do
38
+ context "using defaults values", :if => ENV['ADAPTER'] == 'active_record' do
39
39
  subject { Rolify.orm }
40
40
 
41
41
  it { should eq("active_record") }
42
42
 
43
43
  context "on the User class" do
44
44
  before do
45
- ARUser.rolify
45
+ subject.rolify
46
46
  end
47
47
 
48
48
  subject { ARUser }
@@ -52,7 +52,7 @@ describe Rolify do
52
52
 
53
53
  context "on the Forum class" do
54
54
  before do
55
- Forum.resourcify
55
+ subject.resourcify
56
56
  end
57
57
 
58
58
  subject { Forum }
@@ -61,7 +61,7 @@ describe Rolify do
61
61
  end
62
62
  end
63
63
 
64
- context "using custom values" do
64
+ context "using custom values", :if => ENV['ADAPTER'] == 'mongoid' do
65
65
  context "using :orm setter method" do
66
66
  before do
67
67
  Rolify.orm = "mongoid"
@@ -127,7 +127,7 @@ describe Rolify do
127
127
  context "using defaults values" do
128
128
  subject { Rolify.dynamic_shortcuts }
129
129
 
130
- it { should be_false }
130
+ it { should be_falsey }
131
131
  end
132
132
 
133
133
  context "using custom values" do
@@ -138,7 +138,7 @@ describe Rolify do
138
138
 
139
139
  subject { Rolify.dynamic_shortcuts }
140
140
 
141
- it { should be_true }
141
+ it { should be_truthy }
142
142
  end
143
143
 
144
144
  context "using :use_dynamic_shortcuts method" do
@@ -148,7 +148,7 @@ describe Rolify do
148
148
 
149
149
  subject { Rolify.dynamic_shortcuts }
150
150
 
151
- it { should be_true }
151
+ it { should be_truthy }
152
152
  end
153
153
  end
154
154
  end
@@ -162,10 +162,10 @@ describe Rolify do
162
162
  end
163
163
  end
164
164
 
165
- its(:dynamic_shortcuts) { should be_true }
165
+ its(:dynamic_shortcuts) { should be_truthy }
166
166
  its(:orm) { should eq("mongoid") }
167
167
 
168
- context "on the User class" do
168
+ context "on the User class", :if => ENV['ADAPTER'] == 'mongoid' do
169
169
  before do
170
170
  MUser.rolify
171
171
  end
@@ -183,7 +183,6 @@ describe Rolify do
183
183
  end
184
184
 
185
185
  subject { Forum }
186
-
187
186
  it { should satisfy { |u| u.include? Rolify::Resource }}
188
187
  its("adapter.class") { should be(Rolify::Adapter::ResourceAdapter) }
189
188
  end
@@ -1,15 +1,20 @@
1
1
  require "spec_helper"
2
2
  require "rolify/shared_examples/shared_examples_for_roles"
3
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"
4
6
 
5
7
  describe "Using Rolify with custom User and Role class names" do
6
- it_behaves_like Rolify::Role do
7
- let(:user_class) { Customer }
8
- let(:role_class) { Privilege }
8
+ def user_class
9
+ Customer
9
10
  end
10
11
 
11
- it_behaves_like Rolify::Dynamic do
12
- let(:user_class) { Customer }
13
- let(:role_class) { Privilege }
12
+ def role_class
13
+ Privilege
14
14
  end
15
+
16
+ it_behaves_like Rolify::Role
17
+ it_behaves_like "Role.scopes"
18
+ it_behaves_like Rolify::Dynamic
19
+ it_behaves_like "Rolify.callbacks"
15
20
  end
@@ -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,24 @@
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
+ def user_class
9
+ Admin::Moderator
10
+ end
11
+
12
+ def role_class
13
+ Admin::Right
14
+ end
15
+
16
+ def join_table
17
+ "moderators_rights"
18
+ end
19
+
20
+ it_behaves_like Rolify::Role
21
+ it_behaves_like "Role.scopes"
22
+ it_behaves_like Rolify::Dynamic
23
+ it_behaves_like "Rolify.callbacks"
24
+ end
@@ -3,21 +3,29 @@ 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
+ silence_warnings { User.rolify }
7
+ Forum.resourcify
8
+ Group.resourcify
9
+ Team.resourcify
10
+ Organization.resourcify
11
+ Role.destroy_all
9
12
  end
10
13
 
11
14
  # Users
12
15
  let(:admin) { User.first }
13
16
  let(:tourist) { User.last }
14
-
17
+ let(:captain) { User.where(:login => "god").first }
18
+
15
19
  # roles
16
20
  let!(:forum_role) { admin.add_role(:forum, Forum.first) }
17
21
  let!(:godfather_role) { admin.add_role(:godfather, Forum) }
18
22
  let!(:group_role) { admin.add_role(:group, Group.last) }
23
+ let!(:grouper_role) { admin.add_role(:grouper, Group.first) }
19
24
  let!(:tourist_role) { tourist.add_role(:forum, Forum.last) }
20
25
  let!(:sneaky_role) { tourist.add_role(:group, Forum.first) }
26
+ let!(:captain_role) { captain.add_role(:captain, Team.first) }
27
+ let!(:player_role) { captain.add_role(:player, Team.last) }
28
+ let!(:company_role) { admin.add_role(:owner, Company.first) }
21
29
 
22
30
  describe ".with_roles" do
23
31
  subject { Group }
@@ -25,42 +33,66 @@ describe Rolify::Resource do
25
33
  it { should respond_to(:find_roles).with(1).arguments }
26
34
  it { should respond_to(:find_roles).with(2).arguments }
27
35
 
28
- context "with a role name as argument" do
29
- context "on the Forum class" do
36
+ context "with a role name as argument" do
37
+ context "on the Forum class" do
30
38
  subject { Forum }
31
39
 
32
- it "should include Forum instances with forum role" do
33
- subject.with_role(:forum).should include(Forum.first, Forum.last)
40
+ it "should include Forum instances with forum role" do
41
+ subject.with_role(:forum).should =~ [ Forum.first, Forum.last ]
42
+ end
43
+
44
+ it "should include Forum instances with godfather role" do
45
+ subject.with_role(:godfather).should =~ Forum.all.to_a
34
46
  end
35
- it "should include Forum instances with godfather role" do
36
- subject.with_role(:godfather).should eq(Forum.all)
47
+
48
+ it "should be able to modify the resource", :if => ENV['ADAPTER'] == 'active_record' do
49
+ forum_resource = subject.with_role(:forum).first
50
+ forum_resource.name = "modified name"
51
+ expect { forum_resource.save }.not_to raise_error
37
52
  end
38
53
  end
39
54
 
40
- context "on the Group class" do
55
+ context "on the Group class" do
41
56
  subject { Group }
42
57
 
43
58
  it "should include Group instances with group role" do
44
- subject.with_role(:group).should include(Group.last)
59
+ subject.with_role(:group).should =~ [ Group.last ]
45
60
  end
46
61
  end
47
62
 
63
+ context "on a Group instance" do
64
+ subject { Group.last }
65
+
66
+ it "should ignore nil entries" do
67
+ subject.subgroups.with_role(:group).should =~ [ ]
68
+ end
69
+ end
70
+ end
71
+
72
+ context "with an array of role names as argument" do
73
+ context "on the Group class" do
74
+ subject { Group }
75
+
76
+ it "should include Group instances with both group and grouper roles" do
77
+ subject.with_roles([:group, :grouper]).should =~ [ Group.first, Group.last ]
78
+ end
79
+ end
48
80
  end
49
81
 
50
82
  context "with a role name and a user as arguments" do
51
- context "on the Forum class" do
83
+ context "on the Forum class" do
52
84
  subject { Forum }
53
85
 
54
86
  it "should get all Forum instances binded to the forum role and the admin user" do
55
- subject.with_role(:forum, admin).should include(Forum.first)
87
+ subject.with_role(:forum, admin).should =~ [ Forum.first ]
56
88
  end
57
89
 
58
90
  it "should get all Forum instances binded to the forum role and the tourist user" do
59
- subject.with_role(:forum, tourist).should include(Forum.last)
91
+ subject.with_role(:forum, tourist).should =~ [ Forum.last ]
60
92
  end
61
93
 
62
94
  it "should get all Forum instances binded to the godfather role and the admin user" do
63
- subject.with_role(:godfather, admin).should == Forum.all
95
+ subject.with_role(:godfather, admin).should =~ Forum.all.to_a
64
96
  end
65
97
 
66
98
  it "should get all Forum instances binded to the godfather role and the tourist user" do
@@ -68,7 +100,7 @@ describe Rolify::Resource do
68
100
  end
69
101
 
70
102
  it "should get Forum instances binded to the group role and the tourist user" do
71
- subject.with_role(:group, tourist).should include(Forum.first)
103
+ subject.with_role(:group, tourist).should =~ [ Forum.first ]
72
104
  end
73
105
 
74
106
  it "should not get Forum instances not binded to the group role and the tourist user" do
@@ -76,11 +108,11 @@ describe Rolify::Resource do
76
108
  end
77
109
  end
78
110
 
79
- context "on the Group class" do
111
+ context "on the Group class" do
80
112
  subject { Group }
81
113
 
82
114
  it "should get all resources binded to the group role and the admin user" do
83
- subject.with_role(:group, admin).should include(Group.last)
115
+ subject.with_role(:group, admin).should =~ [ Group.last ]
84
116
  end
85
117
 
86
118
  it "should not get resources not binded to the group role and the admin user" do
@@ -88,17 +120,52 @@ describe Rolify::Resource do
88
120
  end
89
121
  end
90
122
  end
123
+
124
+ context "with an array of role names and a user as arguments" do
125
+ context "on the Forum class" do
126
+ subject { Forum }
127
+
128
+ it "should get Forum instances binded to the forum and group roles and the tourist user" do
129
+ subject.with_roles([:forum, :group], tourist).should =~ [ Forum.first, Forum.last ]
130
+ end
131
+
132
+ end
133
+
134
+ context "on the Group class" do
135
+ subject { Group }
136
+
137
+ it "should get Group instances binded to the group and grouper roles and the admin user" do
138
+ subject.with_roles([:group, :grouper], admin).should =~ [ Group.first, Group.last ]
139
+ end
140
+
141
+ end
142
+ end
143
+
144
+ context "with a model not having ID column" do
145
+ subject { Team }
146
+
147
+ it "should find Team instance using team_code column" do
148
+ subject.with_roles([:captain, :player], captain).should =~ [ Team.first, Team.last ]
149
+ end
150
+ end
151
+
152
+ context "with a resource using STI" do
153
+ subject { Organization }
154
+ it "should find instances of children classes" do
155
+ subject.with_roles(:owner, admin).should =~ [ Company.first ]
156
+ end
157
+ end
91
158
  end
92
159
 
93
160
  describe ".find_role" do
94
161
 
95
- context "without using a role name parameter" do
96
-
162
+ context "without using a role name parameter" do
163
+
97
164
  context "on the Forum class" do
98
165
  subject { Forum }
99
166
 
100
167
  it "should get all roles binded to a Forum class or instance" do
101
- subject.find_roles.should include(forum_role, godfather_role, tourist_role, sneaky_role)
168
+ subject.find_roles.to_a.should =~ [ forum_role, godfather_role, tourist_role, sneaky_role ]
102
169
  end
103
170
 
104
171
  it "should not get roles not binded to a Forum class or instance" do
@@ -107,7 +174,7 @@ describe Rolify::Resource do
107
174
 
108
175
  context "using :any parameter" do
109
176
  it "should get all roles binded to any Forum class or instance" do
110
- subject.find_roles(:any, :any).should include(forum_role, godfather_role, tourist_role, sneaky_role)
177
+ subject.find_roles(:any, :any).to_a.should =~ [ forum_role, godfather_role, tourist_role, sneaky_role ]
111
178
  end
112
179
 
113
180
  it "should not get roles not binded to a Forum class or instance" do
@@ -118,9 +185,9 @@ describe Rolify::Resource do
118
185
 
119
186
  context "on the Group class" do
120
187
  subject { Group }
121
-
188
+
122
189
  it "should get all roles binded to a Group class or instance" do
123
- subject.find_roles.should include(group_role)
190
+ subject.find_roles.to_a.should =~ [ group_role, grouper_role ]
124
191
  end
125
192
 
126
193
  it "should not get roles not binded to a Group class or instance" do
@@ -129,7 +196,7 @@ describe Rolify::Resource do
129
196
 
130
197
  context "using :any parameter" do
131
198
  it "should get all roles binded to Group class or instance" do
132
- subject.find_roles(:any, :any).should include(group_role)
199
+ subject.find_roles(:any, :any).to_a.should =~ [ group_role, grouper_role ]
133
200
  end
134
201
 
135
202
  it "should not get roles not binded to a Group class or instance" do
@@ -139,7 +206,7 @@ describe Rolify::Resource do
139
206
  end
140
207
  end
141
208
 
142
- context "using a role name parameter" do
209
+ context "using a role name parameter" do
143
210
  context "on the Forum class" do
144
211
  subject { Forum }
145
212
 
@@ -155,7 +222,7 @@ describe Rolify::Resource do
155
222
 
156
223
  context "using a user parameter" do
157
224
  it "should get all roles binded to any resource" do
158
- subject.find_roles(:forum, admin).should include(forum_role)
225
+ subject.find_roles(:forum, admin).to_a.should =~ [ forum_role ]
159
226
  end
160
227
 
161
228
  it "should not get roles not binded to the admin user and forum role name" do
@@ -176,7 +243,7 @@ describe Rolify::Resource do
176
243
 
177
244
  context "on the Group class" do
178
245
  subject { Group }
179
-
246
+
180
247
  context "without using a user parameter" do
181
248
  it "should get all roles binded to a Group class or instance and group role name" do
182
249
  subject.find_roles(:group).should include(group_role)
@@ -209,7 +276,7 @@ describe Rolify::Resource do
209
276
  end
210
277
  end
211
278
 
212
- context "using :any as role name parameter" do
279
+ context "using :any as role name parameter" do
213
280
  context "on the Forum class" do
214
281
  subject { Forum }
215
282
 
@@ -278,23 +345,46 @@ describe Rolify::Resource do
278
345
  end
279
346
  end
280
347
  end
348
+
349
+ context "with a resource using STI" do
350
+ subject{ Organization }
351
+ it "should find instances of children classes" do
352
+ subject.find_roles(:owner, admin).should =~ [company_role]
353
+ end
354
+ end
281
355
  end
282
356
 
283
357
  describe "#roles" do
358
+ before(:all) { Role.destroy_all }
284
359
  subject { Forum.first }
285
360
 
286
361
  it { should respond_to :roles }
287
362
 
288
- context "on a Forum instance" do
289
- its(:roles) { should include(forum_role, sneaky_role) }
290
- its(:roles) { subject.should_not include(group_role, godfather_role, tourist_role) }
363
+ context "on a Forum instance" do
364
+ its(:roles) { should match_array( [ forum_role, sneaky_role ]) }
365
+ its(:roles) { should_not include(group_role, godfather_role, tourist_role) }
291
366
  end
292
367
 
293
368
  context "on a Group instance" do
294
369
  subject { Group.last }
295
370
 
296
- its(:roles) { should include(group_role) }
371
+ its(:roles) { should eq([ group_role ]) }
297
372
  its(:roles) { should_not include(forum_role, godfather_role, sneaky_role, tourist_role) }
373
+
374
+ context "when deleting a Group instance" do
375
+ subject do
376
+ Group.create(:name => "to delete")
377
+ end
378
+
379
+ before do
380
+ subject.roles.create :name => "group_role1"
381
+ subject.roles.create :name => "group_role2"
382
+ end
383
+
384
+ it "should remove the roles binded to this instance" do
385
+ expect { subject.destroy }.to change { Role.count }.by(-2)
386
+ end
387
+ end
298
388
  end
299
389
  end
300
390
 
@@ -302,15 +392,23 @@ describe Rolify::Resource do
302
392
  context "on a Forum instance" do
303
393
  subject { Forum.first }
304
394
 
305
- its(:applied_roles) { should include(forum_role, godfather_role, sneaky_role) }
395
+ its(:applied_roles) { should =~ [ forum_role, godfather_role, sneaky_role ] }
306
396
  its(:applied_roles) { should_not include(group_role, tourist_role) }
307
397
  end
308
398
 
309
399
  context "on a Group instance" do
310
400
  subject { Group.last }
311
401
 
312
- its(:applied_roles) { should include(group_role) }
402
+ its(:applied_roles) { should =~ [ group_role ] }
313
403
  its(:applied_roles) { should_not include(forum_role, godfather_role, sneaky_role, tourist_role) }
314
404
  end
315
405
  end
316
- end
406
+
407
+ describe '.resource_types' do
408
+
409
+ it 'include all models that call resourcify' do
410
+ Rolify.resource_types.should include("HumanResource", "Forum", "Group",
411
+ "Team", "Organization")
412
+ end
413
+ end
414
+ end