mongoid_ability 0.3.12 → 0.4.3

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.
@@ -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