mongoid_ability 0.1.9 → 0.1.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0c87d76d294916f069dcdb8a809d9870b1c87a6
4
- data.tar.gz: b130d99ea2c2e54ecfd341ce7ccb880144e4399a
3
+ metadata.gz: 5b22befcca304fbace4cd22f72704b7d5a109a0b
4
+ data.tar.gz: 56a19a326bdb60d7d462558c51cd0d7196146d8b
5
5
  SHA512:
6
- metadata.gz: 7d097c614650c1898fee81b49fd967e8bc7f1f2790d3b306ba07a59079b7533d27a79fec4a02b55cc68ab3ab7399e715bbc330f6fd5169f740d6cfc7815ba8ef
7
- data.tar.gz: 023453a517e10711cafc17a6a4efbe7ff4a0ead1dd90b820c7cfa5ae493badc2b69e98d26acded7a297ca2bc1d854cedaf0059dbfc7f7a4fdc9b330629b59558
6
+ metadata.gz: 740466111f499e95e981197abc5567740c7ecb829126a863bf6720cddadb5f4b9a75ad9fc851f93bfecb8e90e55ce73a40b20ee8d7741b893412270a7ac71c3b
7
+ data.tar.gz: 83f00db0cdb31b4f1ebd024c40f5b1390059a0b686119bcf7e27d97a081f4e5d7208286920cf929b55253e73450182201133c63c1dcf882bc10b4ca24e2ab35b
@@ -45,7 +45,7 @@ module MongoidAbility
45
45
  return calculated_outcome unless owner.present?
46
46
  cloned_owner = owner.clone
47
47
  cloned_owner.locks_relation = cloned_owner.locks_relation - [self]
48
- MongoidAbility::Ability.new(cloned_owner).can? action, (id_lock? ? subject : subject_class)
48
+ MongoidAbility::Ability.new(cloned_owner).can? action, (subject.present? ? subject : subject_class)
49
49
  end
50
50
 
51
51
  # ---------------------------------------------------------------------
@@ -38,6 +38,12 @@ module MongoidAbility
38
38
  @ability ||= MongoidAbility::Ability.new(self)
39
39
  end
40
40
 
41
+ # ---------------------------------------------------------------------
42
+
43
+ def has_lock? lock
44
+ locks_relation.where(action: lock.action, subject_type: lock.subject_type, subject_id: lock.subject_id.presence).exists?
45
+ end
46
+
41
47
  private # =============================================================
42
48
 
43
49
  def cleanup_locks
@@ -7,8 +7,6 @@ module MongoidAbility
7
7
  end
8
8
  end
9
9
 
10
- # ---------------------------------------------------------------------
11
-
12
10
  module ClassMethods
13
11
  def default_locks
14
12
  @default_locks ||= []
@@ -19,15 +17,25 @@ module MongoidAbility
19
17
  end
20
18
 
21
19
  def default_lock lock_cls, action, outcome, attrs={}
20
+ unless is_root_class?
21
+ unless root_class.has_default_lock_for_action?(action)
22
+ raise StandardError, "action is not defined on root class (#{root_class})"
23
+ end
24
+ end
25
+
22
26
  lock = lock_cls.new( { subject_type: self.to_s, action: action, outcome: outcome }.merge(attrs))
23
27
 
24
- if existing_lock = default_locks.detect{ |l| l.action.to_s == lock.action.to_s }
28
+ # remove any existing locks
29
+ if existing_lock = default_locks.detect{ |l| l.action == lock.action }
25
30
  default_locks.delete(existing_lock)
26
31
  end
27
32
 
33
+ # add new lock
28
34
  default_locks.push lock
29
35
  end
30
36
 
37
+ # ---------------------------------------------------------------------
38
+
31
39
  def self_and_ancestors_with_default_locks
32
40
  ancestors.select { |a| a.is_a?(Class) && a.respond_to?(:default_locks) }
33
41
  end
@@ -36,6 +44,26 @@ module MongoidAbility
36
44
  self_and_ancestors_with_default_locks - [self]
37
45
  end
38
46
 
47
+ def is_root_class?
48
+ root_class == self
49
+ end
50
+
51
+ def root_class
52
+ self_and_ancestors_with_default_locks.last
53
+ end
54
+
55
+ # ---------------------------------------------------------------------
56
+
57
+ def default_lock_for_action action
58
+ default_locks.detect{ |lock| lock.action == action.to_sym }
59
+ end
60
+
61
+ def has_default_lock_for_action? action
62
+ default_lock_for_action(action).present?
63
+ end
64
+
65
+ # ---------------------------------------------------------------------
66
+
39
67
  def accessible_by ability, action=:read, options={}
40
68
  AccessibleQueryBuilder.call(self, ability, action, options)
41
69
  end
@@ -1,3 +1,3 @@
1
1
  module MongoidAbility
2
- VERSION = "0.1.9"
2
+ VERSION = "0.1.10"
3
3
  end
@@ -6,6 +6,11 @@ module MongoidAbility
6
6
  subject { MyLock.new }
7
7
  let(:my_subject) { MySubject.new }
8
8
  let(:inherited_lock) { MyLock1.new }
9
+ # ---------------------------------------------------------------------
10
+
11
+ before do
12
+ MySubject.default_locks = [ MyLock.new(action: :read, outcome: true), MyLock.new(action: :update, outcome: false) ]
13
+ end
9
14
 
10
15
  # ---------------------------------------------------------------------
11
16
 
@@ -54,12 +59,13 @@ module MongoidAbility
54
59
  let(:subject_type_lock) { MyLock.new(subject_type: MySubject, action: :read, outcome: false) }
55
60
  let(:subject_lock) { MyLock.new(subject: my_subject, action: :read, outcome: true) }
56
61
  let(:owner) { MyOwner.new(my_locks: [subject_type_lock, subject_lock]) }
57
- let(:ability) { Ability.new(owner) }
58
62
 
59
- before { ability } # initialize owner
63
+ before do
64
+ @ability = Ability.new(owner) # initialize owner
65
+ end
60
66
 
61
67
  it 'does not affect calculated_outcome' do
62
- ability.can?(:read, my_subject).must_equal true
68
+ @ability.can?(:read, my_subject).must_equal true
63
69
  end
64
70
 
65
71
  it 'returns calculated_outcome without this lock' do
@@ -76,11 +82,11 @@ module MongoidAbility
76
82
  # ---------------------------------------------------------------------
77
83
 
78
84
  describe '#criteria' do
79
- let(:open_subject_type_lock) { MyLock.new(subject_type: MySubject, action: :read, outcome: true) }
80
- let(:closed_subject_type_lock) { MyLock.new(subject_type: MySubject, action: :read, outcome: false) }
85
+ let(:open_subject_type_lock) { MyLock.new(subject_type: MySubject, action: :read, outcome: true) }
86
+ let(:closed_subject_type_lock) { MyLock.new(subject_type: MySubject, action: :read, outcome: false) }
81
87
 
82
- let(:open_subject_lock) { MyLock.new(subject: my_subject, action: :read, outcome: true) }
83
- let(:closed_subject_lock) { MyLock.new(subject: my_subject, action: :read, outcome: false) }
88
+ let(:open_subject_lock) { MyLock.new(subject: my_subject, action: :read, outcome: true) }
89
+ let(:closed_subject_lock) { MyLock.new(subject: my_subject, action: :read, outcome: false) }
84
90
 
85
91
  it 'returns conditions Hash' do
86
92
  open_subject_type_lock.conditions.must_be_kind_of Hash
@@ -22,5 +22,25 @@ module MongoidAbility
22
22
  it { subject.locks_relation.metadata[:name].must_equal :my_locks }
23
23
  end
24
24
  end
25
+
26
+ describe '#has_lock?' do
27
+ let(:subject_type_lock) { MyLock.new(action: :read, subject_type: MySubject) }
28
+ let(:subject_lock) { MyLock.new(action: :read, subject: MySubject.new) }
29
+ let(:other_lock) { MyLock.new(action: :update, subject: MySubject.new) }
30
+ let(:owner) { MyOwner.new(my_locks: [subject_type_lock, subject_lock]) }
31
+
32
+ it 'returns true when lock for same action & subject_type' do
33
+ owner.has_lock?(subject_type_lock).must_equal true
34
+ end
35
+
36
+ it 'returns true when lock for same action & subject' do
37
+ owner.has_lock?(subject_lock).must_equal true
38
+ end
39
+
40
+ it 'returns false for non existing lock' do
41
+ owner.has_lock?(other_lock).must_equal false
42
+ end
43
+ end
44
+
25
45
  end
26
46
  end
@@ -2,41 +2,66 @@ require 'test_helper'
2
2
 
3
3
  module MongoidAbility
4
4
  describe Subject do
5
- describe '.default_locks' do
6
5
 
6
+ describe '.default_lock' do
7
7
  before do
8
8
  MySubject.default_locks = []
9
9
  MySubject1.default_locks = []
10
+ MySubject2.default_locks = []
10
11
 
11
12
  MySubject.default_lock MyLock, :read, true
13
+ MySubject.default_lock MyLock, :update, true
12
14
  MySubject1.default_lock MyLock1, :update, false
13
15
  end
14
16
 
15
17
  it 'stores them' do
16
- MySubject.default_locks.map(&:action).map(&:to_s).sort.must_equal %w(read)
18
+ MySubject.default_locks.map(&:action).map(&:to_s).sort.must_equal %w(read update)
17
19
  MySubject1.default_locks.map(&:action).map(&:to_s).sort.must_equal %w(update)
18
20
  end
21
+ end
22
+
23
+ describe 'when lock not defined on superclass' do
24
+ before do
25
+ MySubject.default_locks = []
26
+ MySubject1.default_locks = []
27
+ end
28
+
29
+ it 'must raise error' do
30
+ -> { MySubject1.default_lock MyLock, :test, true }.must_raise StandardError
31
+ end
32
+ end
19
33
 
20
- describe 'prevents conflicts' do
21
- before do
22
- # FIXME: this permanently adjusts the default test locks – ideally do this other way, stubs etc.
23
- MySubject.default_lock MyLock, :read, false
24
- MySubject.default_lock MyLock1, :read, false
25
- end
34
+ describe 'prevents conflicts' do
35
+ before do
36
+ MySubject.default_locks = []
37
+ MySubject.default_lock MyLock, :read, false
38
+ MySubject.default_lock MyLock1, :read, false
39
+ end
26
40
 
27
- it 'does not allow multiple locks for same action' do
28
- MySubject.default_locks.select{ |l| l.action == :read }.count.must_equal 1
29
- end
41
+ it 'does not allow multiple locks for same action' do
42
+ MySubject.default_locks.select{ |l| l.action == :read }.count.must_equal 1
43
+ end
30
44
 
31
- it 'replace existing locks with new attributes' do
32
- MySubject.default_locks.detect{ |l| l.action == :read }.outcome.must_equal false
33
- end
45
+ it 'replace existing locks with new attributes' do
46
+ MySubject.default_locks.detect{ |l| l.action == :read }.outcome.must_equal false
47
+ end
34
48
 
35
- it 'replaces existing locks with new one' do
36
- MySubject.default_locks.detect{ |l| l.action == :read }.class.must_equal MyLock1
37
- end
49
+ it 'replaces existing locks with new one' do
50
+ MySubject.default_locks.detect{ |l| l.action == :read }.class.must_equal MyLock1
38
51
  end
52
+ end
53
+
54
+ describe '.is_root_class?' do
55
+ it { MySubject.is_root_class?.must_equal true }
56
+ it { MySubject1.is_root_class?.must_equal false }
57
+ it { MySubject2.is_root_class?.must_equal false }
58
+ end
39
59
 
60
+ describe ".root_class" do
61
+ it { MySubject.root_class.must_equal MySubject }
62
+ it { MySubject1.root_class.must_equal MySubject }
63
+ it { MySubject2.root_class.must_equal MySubject }
40
64
  end
65
+
41
66
  end
42
67
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_ability
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomas Celizna
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-05 00:00:00.000000000 Z
11
+ date: 2015-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cancancan