casbin-ruby 1.0.3 → 1.0.4

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +242 -0
  3. data/lib/casbin-ruby.rb +11 -0
  4. data/lib/casbin-ruby/config/config.rb +115 -0
  5. data/lib/casbin-ruby/core_enforcer.rb +356 -0
  6. data/lib/casbin-ruby/effect/allow_and_deny_effector.rb +23 -0
  7. data/lib/casbin-ruby/effect/allow_override_effector.rb +23 -0
  8. data/lib/casbin-ruby/effect/default_effector.rb +37 -0
  9. data/lib/casbin-ruby/effect/deny_override_effector.rb +23 -0
  10. data/lib/casbin-ruby/effect/effector.rb +18 -0
  11. data/lib/casbin-ruby/effect/priority_effector.rb +25 -0
  12. data/lib/casbin-ruby/enforcer.rb +189 -0
  13. data/lib/casbin-ruby/internal_enforcer.rb +73 -0
  14. data/lib/casbin-ruby/management_enforcer.rb +297 -0
  15. data/lib/casbin-ruby/model/assertion.rb +33 -0
  16. data/lib/casbin-ruby/model/function_map.rb +30 -0
  17. data/lib/casbin-ruby/model/model.rb +80 -0
  18. data/lib/casbin-ruby/model/policy.rb +161 -0
  19. data/lib/casbin-ruby/persist/adapter.rb +39 -0
  20. data/lib/casbin-ruby/persist/adapters/file_adapter.rb +53 -0
  21. data/lib/casbin-ruby/persist/batch_adapter.rb +16 -0
  22. data/lib/casbin-ruby/persist/filtered_adapter.rb +17 -0
  23. data/lib/casbin-ruby/rbac/default_role_manager/role.rb +54 -0
  24. data/lib/casbin-ruby/rbac/default_role_manager/role_manager.rb +146 -0
  25. data/lib/casbin-ruby/rbac/role_manager.rb +22 -0
  26. data/lib/casbin-ruby/synced_enforcer.rb +39 -0
  27. data/lib/casbin-ruby/util.rb +80 -0
  28. data/lib/casbin-ruby/util/builtin_operators.rb +105 -0
  29. data/lib/casbin-ruby/util/evaluator.rb +27 -0
  30. data/lib/casbin-ruby/util/thread_lock.rb +19 -0
  31. data/lib/casbin-ruby/version.rb +5 -0
  32. data/spec/casbin/config/config_spec.rb +66 -0
  33. data/spec/casbin/core_enforcer_spec.rb +473 -0
  34. data/spec/casbin/enforcer_spec.rb +302 -0
  35. data/spec/casbin/model/function_map_spec.rb +28 -0
  36. data/spec/casbin/rbac/default_role_manager/role_manager_spec.rb +131 -0
  37. data/spec/casbin/rbac/default_role_manager/role_spec.rb +84 -0
  38. data/spec/casbin/util/builtin_operators_spec.rb +205 -0
  39. data/spec/casbin/util_spec.rb +98 -0
  40. data/spec/support/model_helper.rb +9 -0
  41. metadata +51 -3
@@ -0,0 +1,302 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'casbin-ruby/enforcer'
4
+ require 'casbin-ruby/util'
5
+ require 'support/model_helper'
6
+
7
+ describe Casbin::Enforcer do
8
+ describe 'basic' do
9
+ let(:enf) { described_class.new(model_config('basic'), policy_file('basic')) }
10
+
11
+ it '#enforce' do
12
+ expect(enf.enforce('alice', 'data1', 'read')).to be_truthy
13
+ expect(enf.enforce('alice', 'data2', 'read')).to be_falsey
14
+ expect(enf.enforce('bob', 'data2', 'write')).to be_truthy
15
+ expect(enf.enforce('bob', 'data1', 'write')).to be_falsey
16
+ end
17
+
18
+ it '#enforce_ex' do
19
+ expect(enf.enforce_ex('alice', 'data1', 'read')).to match_array([true, %w[alice data1 read]])
20
+ expect(enf.enforce_ex('alice', 'data2', 'read')).to match_array([false, []])
21
+ expect(enf.enforce_ex('bob', 'data2', 'write')).to match_array([true, %w[bob data2 write]])
22
+ expect(enf.enforce_ex('bob', 'data1', 'write')).to match_array([false, []])
23
+ end
24
+
25
+ it '#load_model' do
26
+ enf.model = nil
27
+ expect(enf.model).to be_nil
28
+ enf.load_model
29
+ expect(enf.model).not_to be_nil
30
+ end
31
+ end
32
+
33
+ describe 'basic without spaces' do
34
+ let(:enf) { described_class.new(model_config('basic_without_spaces'), policy_file('basic')) }
35
+
36
+ it '#enforce' do
37
+ expect(enf.enforce('alice', 'data1', 'read')).to be_truthy
38
+ expect(enf.enforce('alice', 'data1', 'write')).to be_falsey
39
+ expect(enf.enforce('alice', 'data2', 'read')).to be_falsey
40
+ expect(enf.enforce('alice', 'data2', 'write')).to be_falsey
41
+ expect(enf.enforce('bob', 'data1', 'read')).to be_falsey
42
+ expect(enf.enforce('bob', 'data1', 'write')).to be_falsey
43
+ expect(enf.enforce('bob', 'data2', 'read')).to be_falsey
44
+ expect(enf.enforce('bob', 'data2', 'write')).to be_truthy
45
+ end
46
+ end
47
+
48
+ describe 'basic with root' do
49
+ let(:enf) { described_class.new(model_config('basic_with_root'), policy_file('basic')) }
50
+
51
+ it '#enforce' do
52
+ expect(enf.enforce('root', 'any', 'any')).to be_truthy
53
+ end
54
+ end
55
+
56
+ describe 'basic without resources' do
57
+ let(:enf) { described_class.new(model_config('basic_without_resources'), policy_file('basic_without_resources')) }
58
+
59
+ it '#enforce' do
60
+ expect(enf.enforce('alice', 'read')).to be_truthy
61
+ expect(enf.enforce('alice', 'write')).to be_falsey
62
+ expect(enf.enforce('bob', 'write')).to be_truthy
63
+ expect(enf.enforce('bob', 'read')).to be_falsey
64
+ end
65
+ end
66
+
67
+ describe 'basic without users' do
68
+ let(:enf) { described_class.new(model_config('basic_without_users'), policy_file('basic_without_users')) }
69
+
70
+ it '#enforce' do
71
+ expect(enf.enforce('data1', 'read')).to be_truthy
72
+ expect(enf.enforce('data1', 'write')).to be_falsey
73
+ expect(enf.enforce('data2', 'write')).to be_truthy
74
+ expect(enf.enforce('data2', 'read')).to be_falsey
75
+ end
76
+ end
77
+
78
+ describe 'ip match' do
79
+ let(:enf) { described_class.new(model_config('ip'), policy_file('ip')) }
80
+
81
+ it '#enforce' do
82
+ expect(enf.enforce('192.168.2.1', 'data1', 'read')).to be_truthy
83
+ expect(enf.enforce('192.168.3.1', 'data1', 'read')).to be_falsey
84
+ end
85
+ end
86
+
87
+ describe 'key match' do
88
+ let(:enf) { described_class.new(model_config('key'), policy_file('key')) }
89
+
90
+ it '#enforce' do
91
+ expect(enf.enforce('alice', '/alice_data/test', 'GET')).to be_truthy
92
+ expect(enf.enforce('alice', '/bob_data/test', 'GET')).to be_falsey
93
+ expect(enf.enforce('cathy', '/cathy_data', 'GET')).to be_truthy
94
+ expect(enf.enforce('cathy', '/cathy_data', 'POST')).to be_truthy
95
+ expect(enf.enforce('cathy', '/cathy_data/12', 'POST')).to be_falsey
96
+ end
97
+ end
98
+
99
+ describe 'key match2' do
100
+ let(:enf) { described_class.new(model_config('key2'), policy_file('key2')) }
101
+
102
+ it '#enforce' do
103
+ expect(enf.enforce('alice', '/alice_data/resource', 'GET')).to be_truthy
104
+ expect(enf.enforce('alice', '/alice_data2/123/using/456', 'GET')).to be_truthy
105
+ end
106
+ end
107
+
108
+ describe 'priority' do
109
+ let(:enf) { described_class.new(model_config('priorities/priority'), policy_file('priorities/priority')) }
110
+
111
+ it '#enforce' do
112
+ expect(enf.enforce('alice', 'data1', 'read')).to be_truthy
113
+ expect(enf.enforce('alice', 'data1', 'write')).to be_falsey
114
+ expect(enf.enforce('alice', 'data2', 'read')).to be_falsey
115
+ expect(enf.enforce('alice', 'data2', 'write')).to be_falsey
116
+
117
+ expect(enf.enforce('bob', 'data1', 'read')).to be_falsey
118
+ expect(enf.enforce('bob', 'data1', 'write')).to be_falsey
119
+ expect(enf.enforce('bob', 'data2', 'read')).to be_truthy
120
+ expect(enf.enforce('bob', 'data2', 'write')).to be_falsey
121
+ end
122
+ end
123
+
124
+ describe 'priority indeterminate' do
125
+ let(:enf) { described_class.new(model_config('priorities/priority'), policy_file('priorities/indeterminate')) }
126
+
127
+ it '#enforce' do
128
+ expect(enf.enforce('alice', 'data1', 'read')).to be_falsey
129
+ end
130
+ end
131
+
132
+ describe 'rbac' do
133
+ let(:enf) { described_class.new(model_config('rbac'), policy_file('rbac')) }
134
+
135
+ it '#enforce' do
136
+ expect(enf.enforce('alice', 'data1', 'read')).to be_truthy
137
+ expect(enf.enforce('bob', 'data1', 'read')).to be_falsey
138
+ expect(enf.enforce('bob', 'data2', 'write')).to be_truthy
139
+ expect(enf.enforce('alice', 'data2', 'read')).to be_truthy
140
+ expect(enf.enforce('alice', 'data2', 'write')).to be_truthy
141
+ expect(enf.enforce('bogus', 'data2', 'write')).to be_falsey
142
+ end
143
+ end
144
+
145
+ describe 'rbac empty policy' do
146
+ let(:enf) { described_class.new(model_config('rbac'), policy_file('empty')) }
147
+
148
+ it '#enforce' do
149
+ expect(enf.enforce('alice', 'data1', 'read')).to be_falsey
150
+ expect(enf.enforce('bob', 'data1', 'read')).to be_falsey
151
+ expect(enf.enforce('bob', 'data2', 'write')).to be_falsey
152
+ expect(enf.enforce('alice', 'data2', 'read')).to be_falsey
153
+ expect(enf.enforce('alice', 'data2', 'write')).to be_falsey
154
+ end
155
+ end
156
+
157
+ describe 'rbac with_deny' do
158
+ let(:enf) { described_class.new(model_config('rbac_with_deny'), policy_file('rbac_with_deny')) }
159
+
160
+ it '#enforce' do
161
+ expect(enf.enforce('alice', 'data1', 'read')).to be_truthy
162
+ expect(enf.enforce('bob', 'data2', 'write')).to be_truthy
163
+ expect(enf.enforce('alice', 'data2', 'read')).to be_truthy
164
+ expect(enf.enforce('alice', 'data2', 'write')).to be_falsey
165
+ end
166
+ end
167
+
168
+ describe 'rbac with domains' do
169
+ let(:enf) { described_class.new(model_config('rbac_with_domains'), policy_file('rbac_with_domains')) }
170
+
171
+ it '#enforce' do
172
+ expect(enf.enforce('alice', 'domain1', 'data1', 'read')).to be_truthy
173
+ expect(enf.enforce('alice', 'domain1', 'data1', 'write')).to be_truthy
174
+ expect(enf.enforce('alice', 'domain1', 'data2', 'read')).to be_falsey
175
+ expect(enf.enforce('alice', 'domain1', 'data2', 'write')).to be_falsey
176
+
177
+ expect(enf.enforce('bob', 'domain2', 'data1', 'read')).to be_falsey
178
+ expect(enf.enforce('bob', 'domain2', 'data1', 'write')).to be_falsey
179
+ expect(enf.enforce('bob', 'domain2', 'data2', 'read')).to be_truthy
180
+ expect(enf.enforce('bob', 'domain2', 'data2', 'write')).to be_truthy
181
+ end
182
+ end
183
+
184
+ describe 'rbac with not deny' do
185
+ let(:enf) { described_class.new(model_config('rbac_with_not_deny'), policy_file('rbac_with_deny')) }
186
+
187
+ it '#enforce' do
188
+ expect(enf.enforce('alice', 'data2', 'write')).to be_falsey
189
+ end
190
+ end
191
+
192
+ describe 'rbac with resource roles' do
193
+ let(:enf) { described_class.new(model_config('rbac_with_resource_roles'), policy_file('rbac_with_resource_roles')) }
194
+
195
+ it '#enforce' do
196
+ expect(enf.enforce('alice', 'data1', 'read')).to be_truthy
197
+ expect(enf.enforce('alice', 'data1', 'write')).to be_truthy
198
+ expect(enf.enforce('alice', 'data2', 'read')).to be_falsey
199
+ expect(enf.enforce('alice', 'data2', 'write')).to be_truthy
200
+
201
+ expect(enf.enforce('bob', 'data1', 'read')).to be_falsey
202
+ expect(enf.enforce('bob', 'data1', 'write')).to be_falsey
203
+ expect(enf.enforce('bob', 'data2', 'read')).to be_falsey
204
+ expect(enf.enforce('bob', 'data2', 'write')).to be_truthy
205
+ end
206
+ end
207
+
208
+ describe 'rbac with pattern' do
209
+ let(:enf) { described_class.new(model_config('rbac_with_pattern'), policy_file('rbac_with_pattern')) }
210
+
211
+ it '#enforce' do
212
+ # set matching function to key_match2
213
+ enf.add_named_matching_func('g2', ->(key1, key2) { Casbin::Util::BuiltinOperators.key_match2(key1, key2) })
214
+
215
+ expect(enf.enforce('alice', '/book/1', 'GET')).to be_truthy
216
+ expect(enf.enforce('alice', '/book/2', 'GET')).to be_truthy
217
+ expect(enf.enforce('alice', '/pen/1', 'GET')).to be_truthy
218
+ expect(enf.enforce('alice', '/pen/2', 'GET')).to be_falsey
219
+ expect(enf.enforce('bob', '/book/1', 'GET')).to be_falsey
220
+ expect(enf.enforce('bob', '/book/2', 'GET')).to be_falsey
221
+ expect(enf.enforce('bob', '/pen/1', 'GET')).to be_truthy
222
+ expect(enf.enforce('bob', '/pen/2', 'GET')).to be_truthy
223
+
224
+ # replace key_match2 with key_match3
225
+ enf.add_named_matching_func('g2', ->(key1, key2) { Casbin::Util::BuiltinOperators.key_match3(key1, key2) })
226
+ expect(enf.enforce('alice', '/book2/1', 'GET')).to be_truthy
227
+ expect(enf.enforce('alice', '/book2/2', 'GET')).to be_truthy
228
+ expect(enf.enforce('alice', '/pen2/1', 'GET')).to be_truthy
229
+ expect(enf.enforce('alice', '/pen2/2', 'GET')).to be_falsey
230
+ expect(enf.enforce('bob', '/book2/1', 'GET')).to be_falsey
231
+ expect(enf.enforce('bob', '/book2/2', 'GET')).to be_falsey
232
+ expect(enf.enforce('bob', '/pen2/1', 'GET')).to be_truthy
233
+ expect(enf.enforce('bob', '/pen2/2', 'GET')).to be_truthy
234
+ end
235
+ end
236
+
237
+ describe 'abac log enabled' do
238
+ let(:enf) { described_class.new(model_config('abac')) }
239
+
240
+ it '#enforce' do
241
+ sub = 'alice'
242
+ obj = { 'Owner' => 'alice', 'id' => 'data1' }
243
+ expect(enf.enforce(sub, obj, 'write')).to be_truthy
244
+ end
245
+ end
246
+
247
+ describe 'abac with sub rule' do
248
+ let(:enf) { described_class.new(model_config('abac_rule'), policy_file('abac_rule')) }
249
+
250
+ it '#enforce' do
251
+ sub1 = { 'name' => 'alice', 'age' => 16 }
252
+ sub2 = { 'name' => 'bob', 'age' => 20 }
253
+ sub3 = { 'name' => 'alice', 'age' => 65 }
254
+
255
+ expect(enf.enforce(sub1, '/data1', 'read')).to be_falsey
256
+ expect(enf.enforce(sub1, '/data2', 'read')).to be_falsey
257
+ expect(enf.enforce(sub1, '/data1', 'write')).to be_falsey
258
+ expect(enf.enforce(sub1, '/data2', 'write')).to be_truthy
259
+
260
+ expect(enf.enforce(sub2, '/data1', 'read')).to be_truthy
261
+ expect(enf.enforce(sub2, '/data2', 'read')).to be_falsey
262
+ expect(enf.enforce(sub2, '/data1', 'write')).to be_falsey
263
+ expect(enf.enforce(sub2, '/data2', 'write')).to be_truthy
264
+
265
+ expect(enf.enforce(sub3, '/data1', 'read')).to be_truthy
266
+ expect(enf.enforce(sub3, '/data2', 'read')).to be_falsey
267
+ expect(enf.enforce(sub3, '/data1', 'write')).to be_falsey
268
+ expect(enf.enforce(sub3, '/data2', 'write')).to be_falsey
269
+ end
270
+ end
271
+
272
+ describe 'abac with multiple sub rules' do
273
+ let(:enf) { described_class.new(model_config('abac_multiple_rules'), policy_file('abac_multiple_rules')) }
274
+
275
+ it '#enforce' do
276
+ sub1 = { 'name' => 'alice', 'age' => 16 }
277
+ sub2 = { 'name' => 'bob', 'age' => 20 }
278
+ sub3 = { 'name' => 'alice', 'age' => 65 }
279
+ sub4 = { 'name' => 'bob', 'age' => 35 }
280
+
281
+ expect(enf.enforce(sub1, '/data1', 'read')).to be_falsey
282
+ expect(enf.enforce(sub1, '/data2', 'read')).to be_falsey
283
+ expect(enf.enforce(sub1, '/data1', 'write')).to be_falsey
284
+ expect(enf.enforce(sub1, '/data2', 'write')).to be_falsey
285
+
286
+ expect(enf.enforce(sub2, '/data1', 'read')).to be_falsey
287
+ expect(enf.enforce(sub2, '/data2', 'read')).to be_falsey
288
+ expect(enf.enforce(sub2, '/data1', 'write')).to be_falsey
289
+ expect(enf.enforce(sub2, '/data2', 'write')).to be_truthy
290
+
291
+ expect(enf.enforce(sub3, '/data1', 'read')).to be_truthy
292
+ expect(enf.enforce(sub3, '/data2', 'read')).to be_falsey
293
+ expect(enf.enforce(sub3, '/data1', 'write')).to be_falsey
294
+ expect(enf.enforce(sub3, '/data2', 'write')).to be_falsey
295
+
296
+ expect(enf.enforce(sub4, '/data1', 'read')).to be_falsey
297
+ expect(enf.enforce(sub4, '/data2', 'read')).to be_falsey
298
+ expect(enf.enforce(sub4, '/data1', 'write')).to be_falsey
299
+ expect(enf.enforce(sub4, '/data2', 'write')).to be_truthy
300
+ end
301
+ end
302
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'casbin-ruby/model/function_map'
4
+ require 'casbin-ruby/util/builtin_operators'
5
+
6
+ describe Casbin::Model::FunctionMap do
7
+ describe '#load_function_map' do
8
+ let(:fm) { described_class.load_function_map.fm }
9
+ let(:args) { ['abc'] }
10
+
11
+ it 'returns function map' do
12
+ {
13
+ 'keyMatch' => :key_match_func,
14
+ 'keyMatch2' => :key_match2_func,
15
+ 'regexMatch' => :regex_match_func,
16
+ 'ipMatch' => :ip_match_func,
17
+ 'globMatch' => :glob_match_func
18
+ }.each do |key, meth|
19
+ f = fm[key]
20
+ expect(f).to be_a Proc
21
+ expect(f).to be_lambda
22
+
23
+ expect(Casbin::Util::BuiltinOperators).to receive(meth).with(*args)
24
+ f.call(*args)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+ require 'casbin-ruby/rbac/default_role_manager/role_manager'
5
+ require 'casbin-ruby/util/builtin_operators'
6
+
7
+ describe Casbin::Rbac::DefaultRoleManager::RoleManager do
8
+ let(:role_manager) { described_class.new(1) }
9
+
10
+ it '#add_matching_func' do
11
+ role_manager.add_matching_func(-> { 'simple' })
12
+ expect(role_manager.matching_func).not_to be_nil
13
+ end
14
+
15
+ describe '#create_role' do
16
+ it 'when no matching_func' do
17
+ role_manager.create_role('test_role')
18
+ expect(role_manager.all_roles).to have_key('test_role')
19
+ end
20
+
21
+ it 'when matching_func truthy' do
22
+ role_manager.add_matching_func(->(_name, _key) { true })
23
+ role_manager.create_role('test_role')
24
+ role_manager.create_role('test_role1')
25
+
26
+ expect(role_manager.all_roles['test_role1'].has_direct_role('test_role')).to be_truthy
27
+ end
28
+
29
+ it 'when matching_func falsey' do
30
+ role_manager.add_matching_func(->(_name, _key) { false })
31
+ role_manager.create_role('test_role')
32
+ role_manager.create_role('test_role1')
33
+ expect(role_manager.all_roles['test_role1'].has_direct_role('test_role')).to be_falsey
34
+ end
35
+ end
36
+
37
+ describe '#has_role' do
38
+ it 'when no matching_func' do
39
+ expect(role_manager.has_role('test_role')).to be_falsey
40
+ role_manager.create_role('test_role')
41
+ expect(role_manager.has_role('test_role')).to be_truthy
42
+ end
43
+
44
+ it 'when matching_func truthy' do
45
+ role_manager.add_matching_func(->(_name, _key) { true })
46
+ role_manager.create_role('test_role')
47
+ role_manager.create_role('test_role1')
48
+ expect(role_manager.all_roles['test_role1'].has_direct_role('test_role')).to be_truthy
49
+ end
50
+
51
+ it 'when matching_func falsey' do
52
+ role_manager.add_matching_func(->(_name, _key) { false })
53
+ role_manager.create_role('test_role')
54
+ role_manager.create_role('test_role1')
55
+ expect(role_manager.all_roles['test_role1'].has_direct_role('test_role')).to be_falsey
56
+ end
57
+ end
58
+
59
+ it '#clear' do
60
+ role_manager.create_role('test_role')
61
+ expect(role_manager.all_roles).not_to be_empty
62
+
63
+ role_manager.clear
64
+ expect(role_manager.all_roles).to be_empty
65
+ end
66
+
67
+ it '#add_link' do
68
+ role_manager.add_link('test1', 'test2', 'domain')
69
+ expect(role_manager.has_role('domain::test1')).to be_truthy
70
+ expect(role_manager.all_roles['domain::test1'].has_direct_role('domain::test2')).to be_truthy
71
+ end
72
+
73
+ it '#delete_link' do
74
+ role_manager.add_link('test1', 'test2', 'domain')
75
+ role_manager.delete_link('test1', 'test2', 'domain')
76
+ expect(role_manager.all_roles['domain::test1'].has_direct_role('domain::test2')).to be_falsey
77
+ end
78
+
79
+ describe '#has_link' do
80
+ it 'when same name' do
81
+ expect(role_manager.has_link('test1', 'test1', 'domain')).to be_truthy
82
+ end
83
+
84
+ it 'when not have role' do
85
+ expect(role_manager.has_link('test1', 'test2', 'domain')).to be_falsey
86
+ end
87
+
88
+ it 'when have role' do
89
+ role_manager.add_link('test1', 'test2', 'domain')
90
+ expect(role_manager.has_link('test1', 'test2', 'domain')).to be_truthy
91
+ end
92
+
93
+ context 'with matching function' do
94
+ before do
95
+ role_manager.add_matching_func ->(key1, key2) { Casbin::Util::BuiltinOperators.key_match2 key1, key2 }
96
+ role_manager.add_link '/book/:id', 'book_admin'
97
+ end
98
+
99
+ it 'correctly matches' do
100
+ expect(role_manager.has_link('/book/1', 'book_admin')).to be_truthy
101
+ expect(role_manager.has_link('/book/2', 'book_admin')).to be_truthy
102
+ expect(role_manager.has_link('/other/1', 'book_admin')).to be_falsey
103
+ end
104
+ end
105
+ end
106
+
107
+ it '#get_roles' do
108
+ role_manager.create_role('test_role')
109
+ role_manager.create_role('test_rol1')
110
+ role_manager.all_roles['test_role'].add_role(role_manager.create_role('test_role'))
111
+ role_manager.all_roles['test_rol1'].add_role(role_manager.create_role('test_role'))
112
+ roles = role_manager.get_roles('test_role')
113
+ expect(roles.size).to eq 1
114
+ expect(roles[0]).to eq 'test_role'
115
+ end
116
+
117
+ it '#get_users' do
118
+ role_manager.create_role('test_role')
119
+ role_manager.create_role('test_role1')
120
+ role_manager.all_roles['test_role'].add_role(role_manager.create_role('test_role'))
121
+ role_manager.all_roles['test_role1'].add_role(role_manager.create_role('test_role'))
122
+ expect(role_manager.get_users('test_role')).to match_array(%w[test_role test_role1])
123
+ end
124
+
125
+ it '#print_roles' do
126
+ role_manager.create_role('test_role')
127
+ role_manager.create_role('test_rol2')
128
+ allow(Logger).to receive(:info).with('test_role, test_rol2')
129
+ role_manager.print_roles
130
+ end
131
+ end