mongoid_ability 0.3.12 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,50 +5,63 @@ module MongoidAbility
5
5
  let(:owner) { MyOwner.new }
6
6
  let(:ability) { Ability.new(owner) }
7
7
 
8
+ let(:my_subject_default_locks) { [] }
9
+ let(:my_subject_1_default_locks) { [] }
10
+ let(:my_subject_2_default_locks) { [] }
11
+
8
12
  it 'exposes owner' do
9
13
  ability.owner.must_equal owner
10
14
  end
11
15
 
12
16
  describe 'default locks' do
13
- before do
14
- # NOTE: we might need to use the .default_lock macro in case we propagate down directly
15
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :update, outcome: true)]
16
- MySubject1.default_locks = []
17
- MySubject2.default_locks = []
18
- end
17
+ # NOTE: we might need to use the .default_lock macro in case we propagate down directly
18
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :update, outcome: true)] }
19
19
 
20
20
  it 'propagates from superclass to all subclasses' do
21
- ability.can?(:update, MySubject).must_equal true
22
- ability.can?(:update, MySubject1).must_equal true
23
- ability.can?(:update, MySubject2).must_equal true
21
+ MySubject.stub :default_locks, my_subject_default_locks do
22
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
23
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
24
+ ability.can?(:update, MySubject).must_equal true
25
+ ability.can?(:update, MySubject1).must_equal true
26
+ ability.can?(:update, MySubject2).must_equal true
27
+ end
28
+ end
29
+ end
24
30
  end
25
31
  end
26
32
 
27
33
  describe 'when defined for all superclasses' do
28
- before do
29
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: false)]
30
- MySubject1.default_locks = [MyLock.new(subject_type: MySubject1, action: :read, outcome: true)]
31
- MySubject2.default_locks = [MyLock.new(subject_type: MySubject2, action: :read, outcome: false)]
32
- end
34
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: false)] }
35
+ let(:my_subject_1_default_locks) { [MyLock.new(subject_type: MySubject1, action: :read, outcome: true)] }
36
+ let(:my_subject_2_default_locks) { [MyLock.new(subject_type: MySubject2, action: :read, outcome: false)] }
33
37
 
34
38
  it 'respects the definitions' do
35
- ability.can?(:read, MySubject).must_equal false
36
- ability.can?(:read, MySubject1).must_equal true
37
- ability.can?(:read, MySubject2).must_equal false
39
+ MySubject.stub :default_locks, my_subject_default_locks do
40
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
41
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
42
+ ability.can?(:read, MySubject).must_equal false
43
+ ability.can?(:read, MySubject1).must_equal true
44
+ ability.can?(:read, MySubject2).must_equal false
45
+ end
46
+ end
47
+ end
38
48
  end
39
49
  end
40
50
 
41
51
  describe 'when defined for some superclasses' do
42
- before do
43
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: false)]
44
- MySubject1.default_locks = []
45
- MySubject2.default_locks = [MyLock.new(subject_type: MySubject2, action: :read, outcome: true)]
46
- end
52
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: false)] }
53
+ let(:my_subject_2_default_locks) { [MyLock.new(subject_type: MySubject2, action: :read, outcome: true)] }
47
54
 
48
55
  it 'propagates default locks to subclasses' do
49
- ability.can?(:read, MySubject).must_equal false
50
- ability.can?(:read, MySubject1).must_equal false
51
- ability.can?(:read, MySubject2).must_equal true
56
+ MySubject.stub :default_locks, my_subject_default_locks do
57
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
58
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
59
+ ability.can?(:read, MySubject).must_equal false
60
+ ability.can?(:read, MySubject1).must_equal false
61
+ ability.can?(:read, MySubject2).must_equal true
62
+ end
63
+ end
64
+ end
52
65
  end
53
66
  end
54
67
 
@@ -56,15 +69,20 @@ module MongoidAbility
56
69
 
57
70
  describe 'user locks' do
58
71
  describe 'when defined for superclass' do
72
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: false)] }
73
+
59
74
  before do
60
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: false)]
61
- MySubject1.default_locks = []
62
- MySubject2.default_locks = []
63
75
  owner.my_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: true)]
64
76
  end
65
77
 
66
78
  it 'applies the superclass lock' do
67
- ability.can?(:read, MySubject2).must_equal true
79
+ MySubject.stub :default_locks, my_subject_default_locks do
80
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
81
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
82
+ ability.can?(:read, MySubject2).must_equal true
83
+ end
84
+ end
85
+ end
68
86
  end
69
87
  end
70
88
  end
@@ -73,8 +91,9 @@ module MongoidAbility
73
91
 
74
92
  describe 'inherited owner locks' do
75
93
  describe 'when multiple inherited owners' do
94
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: false)] }
95
+
76
96
  before do
77
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: false)]
78
97
  owner.my_roles = [
79
98
  MyRole.new(my_locks: [MyLock.new(subject_type: MySubject, action: :read, outcome: true)]),
80
99
  MyRole.new(my_locks: [MyLock.new(subject_type: MySubject, action: :read, outcome: false)])
@@ -82,20 +101,31 @@ module MongoidAbility
82
101
  end
83
102
 
84
103
  it 'prefers positive outcome' do
85
- ability.can?(:read, MySubject).must_equal true
104
+ MySubject.stub :default_locks, my_subject_default_locks do
105
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
106
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
107
+ ability.can?(:read, MySubject).must_equal true
108
+ end
109
+ end
110
+ end
86
111
  end
87
112
  end
88
113
 
89
114
  describe 'when defined for superclass' do
115
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: false)] }
116
+
90
117
  before do
91
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: false)]
92
- MySubject1.default_locks = []
93
- MySubject2.default_locks = []
94
118
  owner.my_roles = [MyRole.new(my_locks: [MyLock.new(subject_type: MySubject, action: :read, outcome: true)])]
95
119
  end
96
120
 
97
121
  it 'applies the superclass lock' do
98
- ability.can?(:read, MySubject2).must_equal true
122
+ MySubject.stub :default_locks, my_subject_default_locks do
123
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
124
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
125
+ ability.can?(:read, MySubject2).must_equal true
126
+ end
127
+ end
128
+ end
99
129
  end
100
130
  end
101
131
  end
@@ -104,25 +134,39 @@ module MongoidAbility
104
134
 
105
135
  describe 'combined locks' do
106
136
  describe 'user and role locks' do
137
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: false)] }
138
+
107
139
  before do
108
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: false)]
109
140
  owner.my_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: false)]
110
141
  owner.my_roles = [MyRole.new(my_locks: [MyLock.new(subject_type: MySubject, action: :read, outcome: true)])]
111
142
  end
112
143
 
113
144
  it 'prefers user locks' do
114
- ability.can?(:read, MySubject).must_equal false
145
+ MySubject.stub :default_locks, my_subject_default_locks do
146
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
147
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
148
+ ability.can?(:read, MySubject).must_equal false
149
+ end
150
+ end
151
+ end
115
152
  end
116
153
  end
117
154
 
118
155
  describe 'roles and default locks' do
156
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: false)] }
157
+
119
158
  before do
120
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: false)]
121
159
  owner.my_roles = [MyRole.new(my_locks: [MyLock.new(subject_type: MySubject, action: :read, outcome: true)])]
122
160
  end
123
161
 
124
162
  it 'prefers role locks' do
125
- ability.can?(:read, MySubject).must_equal true
163
+ MySubject.stub :default_locks, my_subject_default_locks do
164
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
165
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
166
+ ability.can?(:read, MySubject).must_equal true
167
+ end
168
+ end
169
+ end
126
170
  end
127
171
  end
128
172
  end
@@ -8,19 +8,43 @@ module MongoidAbility
8
8
  let(:action) { :read }
9
9
  let(:options) { Hash.new }
10
10
 
11
- before do
12
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: true)]
13
- end
11
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: true)] }
12
+ let(:my_subject_1_default_locks) { [MyLock.new(subject_type: MySubject1, action: :false, outcome: true)] }
13
+ let(:my_subject_2_default_locks) { [] }
14
14
 
15
15
  subject { AccessibleQueryBuilder.call(base_class, ability, action, options) }
16
16
 
17
17
  it 'returns Mongoid::Criteria' do
18
- subject.must_be_kind_of Mongoid::Criteria
18
+ MySubject.stub :default_locks, my_subject_default_locks do
19
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
20
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
21
+ subject.must_be_kind_of Mongoid::Criteria
22
+ end
23
+ end
24
+ end
19
25
  end
20
26
 
21
- it 'allows to pass prefix' do
22
- skip 'not sure how to best test this'
23
- selector = AccessibleQueryBuilder.call(base_class, ability, action, prefix: :foo).selector
27
+ describe 'prefix' do
28
+ let(:my_subject) { MySubject.create! }
29
+ let(:my_subject_1) { MySubject1.create! }
30
+ let(:my_subject_2) { MySubject2.create! }
31
+ let(:prefix) { :foo }
32
+
33
+ before do
34
+ my_subject; my_subject_1
35
+ owner.my_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: false)]
36
+ end
37
+
38
+ it 'allows to pass prefix' do
39
+ MySubject.stub :default_locks, my_subject_default_locks do
40
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
41
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
42
+ selector = AccessibleQueryBuilder.call(base_class, ability, action, prefix: prefix).selector
43
+ selector.must_equal('$and' => [{ '$or' => [{ "#{prefix}_type" => { '$nin' => ['MongoidAbility::MySubject', 'MongoidAbility::MySubject1', 'MongoidAbility::MySubject2'] } }, { "#{prefix}_type" => { '$in' => [] }, "#{prefix}_id" => { '$in' => [] } }] }, { "#{prefix}_id" => { '$nin' => [] } }])
44
+ end
45
+ end
46
+ end
47
+ end
24
48
  end
25
49
 
26
50
  # ---------------------------------------------------------------------
@@ -35,9 +59,15 @@ module MongoidAbility
35
59
  end
36
60
 
37
61
  it 'does not return subject with that id' do
38
- MySubject.accessible_by(ability, :read).wont_include my_subject
39
- MySubject.accessible_by(ability, :read).wont_include my_subject_1
40
- MySubject1.accessible_by(ability, :read).wont_include my_subject_1
62
+ MySubject.stub :default_locks, my_subject_default_locks do
63
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
64
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
65
+ MySubject.accessible_by(ability, :read).wont_include my_subject
66
+ MySubject.accessible_by(ability, :read).wont_include my_subject_1
67
+ MySubject1.accessible_by(ability, :read).wont_include my_subject_1
68
+ end
69
+ end
70
+ end
41
71
  end
42
72
  end
43
73
 
@@ -51,8 +81,14 @@ module MongoidAbility
51
81
  end
52
82
 
53
83
  it 'does not return subject with that id' do
54
- MySubject.accessible_by(ability, :read).wont_include my_subject_a
55
- MySubject.accessible_by(ability, :read).must_include my_subject_b
84
+ MySubject.stub :default_locks, my_subject_default_locks do
85
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
86
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
87
+ MySubject.accessible_by(ability, :read).wont_include my_subject_a
88
+ MySubject.accessible_by(ability, :read).must_include my_subject_b
89
+ end
90
+ end
91
+ end
56
92
  end
57
93
  end
58
94
 
@@ -69,8 +105,14 @@ module MongoidAbility
69
105
  end
70
106
 
71
107
  it 'does not return subject with that id' do
72
- MySubject.accessible_by(ability, :read).must_include my_subject
73
- MySubject.accessible_by(ability, :read).must_include my_subject_1
108
+ MySubject.stub :default_locks, my_subject_default_locks do
109
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
110
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
111
+ MySubject.accessible_by(ability, :read).must_include my_subject
112
+ MySubject.accessible_by(ability, :read).must_include my_subject_1
113
+ end
114
+ end
115
+ end
74
116
  end
75
117
  end
76
118
  end
@@ -5,13 +5,13 @@ module MongoidAbility
5
5
  let(:owner) { MyOwner.new }
6
6
  let(:ability) { Ability.new(owner) }
7
7
 
8
- before do
9
- MySubject.default_locks = [ MyLock1.new(action: :read, outcome: false) ]
10
- end
8
+ let(:default_locks) { [MyLock1.new(action: :read, outcome: false)] }
11
9
 
12
10
  it 'allows to pass options to a can? block' do
13
- ability.can?(:read, MySubject, {}).must_equal false
14
- ability.can?(:read, MySubject, { override: true }).must_equal true
11
+ MySubject.stub :default_locks, default_locks do
12
+ ability.can?(:read, MySubject, {}).must_equal false
13
+ ability.can?(:read, MySubject, override: true).must_equal true
14
+ end
15
15
  end
16
16
  end
17
17
  end
@@ -6,11 +6,9 @@ module MongoidAbility
6
6
  let(:my_subject) { MySubject.new }
7
7
  let(:inherited_lock) { MyLock1.new }
8
8
 
9
- # ---------------------------------------------------------------------
10
-
11
- before do
12
- MySubject.default_locks = [MyLock.new(action: :read, outcome: true), MyLock.new(action: :update, outcome: false)]
13
- end
9
+ let(:my_subject_default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: true)] }
10
+ let(:my_subject_1_default_locks) { [MyLock.new(subject_type: MySubject1, action: :false, outcome: true)] }
11
+ let(:my_subject_2_default_locks) { [] }
14
12
 
15
13
  # ---------------------------------------------------------------------
16
14
 
@@ -51,7 +49,7 @@ module MongoidAbility
51
49
 
52
50
  it 'converts empty String to nil' do
53
51
  id = ''
54
- MyLock.for_subject_id(id.to_s).selector['subject_id'].must_equal nil
52
+ MyLock.for_subject_id(id.to_s).selector['subject_id'].must_be_nil
55
53
  end
56
54
  end
57
55
 
@@ -68,17 +66,35 @@ module MongoidAbility
68
66
  end
69
67
 
70
68
  it 'does not affect calculated_outcome' do
71
- @ability.can?(:read, my_subject).must_equal true
69
+ MySubject.stub :default_locks, my_subject_default_locks do
70
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
71
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
72
+ @ability.can?(:read, my_subject).must_equal true
73
+ end
74
+ end
75
+ end
72
76
  end
73
77
 
74
78
  it 'returns calculated_outcome without this lock' do
75
- subject_lock.inherited_outcome.must_equal false
76
- subject_type_lock.inherited_outcome.must_equal true
79
+ MySubject.stub :default_locks, my_subject_default_locks do
80
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
81
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
82
+ subject_lock.inherited_outcome.must_equal false
83
+ subject_type_lock.inherited_outcome.must_equal true
84
+ end
85
+ end
86
+ end
77
87
  end
78
88
 
79
89
  it 'returns calculated_outcome for default locks' do
80
- lock = MySubject.default_locks.detect { |l| l.action == :read }
81
- lock.inherited_outcome.must_equal true
90
+ MySubject.stub :default_locks, my_subject_default_locks do
91
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
92
+ MySubject2.stub :default_locks, my_subject_2_default_locks do
93
+ lock = MySubject.default_locks.detect { |l| l.action == :read }
94
+ lock.inherited_outcome.must_equal true
95
+ end
96
+ end
97
+ end
82
98
  end
83
99
  end
84
100
  end
@@ -10,31 +10,27 @@ module MongoidAbility
10
10
  let(:owner) { MyOwner.new }
11
11
  let(:ability) { Ability.new(owner) }
12
12
 
13
- # ---------------------------------------------------------------------
14
-
15
- before do
16
- MySubject.default_locks = [MyLock.new(subject_type: MySubject, action: :read, outcome: true)]
17
- end
18
-
19
- # ---------------------------------------------------------------------
13
+ let(:default_locks) { [MyLock.new(subject_type: MySubject, action: :read, outcome: true)] }
20
14
 
21
15
  describe 'when lock for subject' do
22
16
  before { owner.my_locks = [subject_lock] }
23
17
 
24
18
  it 'applies it' do
25
- ability.can?(:read, subject.class).must_equal true
26
- ability.can?(:read, subject).must_equal false
19
+ MySubject.stub :default_locks, default_locks do
20
+ ability.can?(:read, subject.class).must_equal true
21
+ ability.can?(:read, subject).must_equal false
22
+ end
27
23
  end
28
24
  end
29
25
 
30
- # ---------------------------------------------------------------------
31
-
32
26
  describe 'when lock for subject type' do
33
27
  before { owner.my_locks = [subject_type_lock] }
34
28
 
35
29
  it 'applies it' do
36
- ability.can?(:read, subject.class).must_equal false
37
- ability.can?(:read, subject).must_equal false
30
+ MySubject.stub :default_locks, default_locks do
31
+ ability.can?(:read, subject.class).must_equal false
32
+ ability.can?(:read, subject).must_equal false
33
+ end
38
34
  end
39
35
  end
40
36
  end
@@ -1,27 +1,41 @@
1
- require "test_helper"
1
+ require 'test_helper'
2
2
 
3
3
  module MongoidAbility
4
4
  describe ResolveDefaultLocks do
5
-
6
5
  describe '.call' do
7
- before do
8
- MySubject.default_locks = [
6
+ let(:options) { {} }
7
+
8
+ let(:my_subject_default_locks) do
9
+ [
9
10
  MyLock.new(subject_type: MySubject, action: :read, outcome: true),
10
11
  MyLock.new(subject_type: MySubject, action: :update, outcome: false)
11
12
  ]
13
+ end
12
14
 
13
- MySubject1.default_locks = [
15
+ let(:my_subject_1_default_locks) do
16
+ [
14
17
  MyLock.new(subject_type: MySubject1, action: :read, outcome: false),
15
18
  MyLock.new(subject_type: MySubject1, action: :update, outcome: true)
16
19
  ]
17
20
  end
18
21
 
19
- it { ResolveDefaultLocks.call(nil, :read, MySubject, nil, {}).must_equal true }
20
- it { ResolveDefaultLocks.call(nil, :update, MySubject, nil, {}).must_equal false }
22
+ it 'resolves on self' do
23
+ MySubject.stub :default_locks, my_subject_default_locks do
24
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
25
+ ResolveDefaultLocks.call(nil, :read, MySubject, nil, options).must_equal MySubject.default_locks.first
26
+ ResolveDefaultLocks.call(nil, :update, MySubject, nil, options).must_equal MySubject.default_locks.last
27
+ end
28
+ end
29
+ end
21
30
 
22
- it { ResolveDefaultLocks.call(nil, :read, MySubject1, nil, {}).must_equal false }
23
- it { ResolveDefaultLocks.call(nil, :update, MySubject1, nil, {}).must_equal true }
31
+ it 'resolves on subclass' do
32
+ MySubject.stub :default_locks, my_subject_default_locks do
33
+ MySubject1.stub :default_locks, my_subject_1_default_locks do
34
+ ResolveDefaultLocks.call(nil, :read, MySubject1, nil, options).must_equal MySubject1.default_locks.first
35
+ ResolveDefaultLocks.call(nil, :update, MySubject1, nil, options).must_equal MySubject1.default_locks.last
36
+ end
37
+ end
38
+ end
24
39
  end
25
-
26
40
  end
27
41
  end