acts-as-approvable 0.6.7 → 0.6.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.gitignore +2 -5
  2. data/.rspec +2 -0
  3. data/.travis.yml +5 -0
  4. data/Appraisals +14 -10
  5. data/CHANGELOG +16 -0
  6. data/Gemfile.lock +60 -20
  7. data/README.md +1 -2
  8. data/Rakefile +44 -16
  9. data/VERSION +1 -1
  10. data/acts-as-approvable.gemspec +21 -11
  11. data/features/create_approval.feature +26 -0
  12. data/features/step_definitions/cucumber_steps.rb +86 -0
  13. data/features/support/env.rb +14 -0
  14. data/features/support/large.txt +29943 -0
  15. data/features/support/second_large.txt +31798 -0
  16. data/features/update_approval.feature +34 -0
  17. data/gemfiles/Gemfile.ci +14 -0
  18. data/gemfiles/Gemfile.ci.lock +98 -0
  19. data/gemfiles/mysql2.gemfile +7 -0
  20. data/gemfiles/mysql2.gemfile.lock +92 -0
  21. data/gemfiles/rails2.gemfile +1 -0
  22. data/gemfiles/rails2.gemfile.lock +59 -17
  23. data/gemfiles/rails30.gemfile +1 -0
  24. data/gemfiles/rails30.gemfile.lock +54 -14
  25. data/gemfiles/rails31.gemfile +1 -0
  26. data/gemfiles/rails31.gemfile.lock +54 -14
  27. data/gemfiles/sqlite.gemfile +7 -0
  28. data/generators/acts_as_approvable/templates/create_approvals.rb +8 -7
  29. data/lib/acts-as-approvable.rb +2 -3
  30. data/lib/acts_as_approvable/approval.rb +3 -2
  31. data/lib/acts_as_approvable/model.rb +55 -0
  32. data/lib/acts_as_approvable/model/class_methods.rb +63 -0
  33. data/lib/acts_as_approvable/model/create_instance_methods.rb +83 -0
  34. data/lib/acts_as_approvable/model/instance_methods.rb +89 -0
  35. data/lib/acts_as_approvable/model/update_instance_methods.rb +61 -0
  36. data/lib/acts_as_approvable/railtie.rb +1 -1
  37. data/lib/generators/acts_as_approvable/templates/create_approvals.rb +8 -7
  38. data/spec/acts_as_approvable/approval_spec.rb +475 -0
  39. data/spec/acts_as_approvable/model/class_methods_spec.rb +219 -0
  40. data/spec/acts_as_approvable/model/create_instance_methods_spec.rb +149 -0
  41. data/spec/acts_as_approvable/model/instance_methods_spec.rb +328 -0
  42. data/spec/acts_as_approvable/model/update_instance_methods_spec.rb +111 -0
  43. data/spec/acts_as_approvable/model_spec.rb +90 -0
  44. data/spec/acts_as_approvable/ownership/class_methods_spec.rb +101 -0
  45. data/spec/acts_as_approvable/ownership/instance_methods_spec.rb +32 -0
  46. data/spec/acts_as_approvable/ownership_spec.rb +51 -0
  47. data/spec/acts_as_approvable_spec.rb +29 -0
  48. data/spec/spec_helper.rb +51 -0
  49. data/spec/support/database.rb +46 -0
  50. data/spec/support/database.yml +12 -0
  51. data/spec/support/matchers.rb +87 -0
  52. data/spec/support/models.rb +60 -0
  53. data/{test → spec/support}/schema.rb +15 -9
  54. metadata +156 -53
  55. data/gemfiles/rails32.gemfile +0 -8
  56. data/gemfiles/rails32.gemfile.lock +0 -99
  57. data/lib/acts_as_approvable/acts_as_approvable.rb +0 -291
  58. data/test/acts_as_approvable_model_test.rb +0 -459
  59. data/test/acts_as_approvable_ownership_test.rb +0 -132
  60. data/test/acts_as_approvable_schema_test.rb +0 -13
  61. data/test/acts_as_approvable_test.rb +0 -8
  62. data/test/database.yml +0 -7
  63. data/test/support.rb +0 -19
  64. data/test/test_helper.rb +0 -62
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "http://rubygems.org"
4
-
5
- gem "activerecord", "~> 3.2.0"
6
- gem "railties", "~> 3.2.0"
7
-
8
- gemspec :path=>"../"
@@ -1,99 +0,0 @@
1
- PATH
2
- remote: /Users/jlogsdon/Code/acts_as_approvable/acts_as_approvable
3
- specs:
4
- acts-as-approvable (0.6.7)
5
-
6
- GEM
7
- remote: http://rubygems.org/
8
- specs:
9
- actionpack (3.2.1)
10
- activemodel (= 3.2.1)
11
- activesupport (= 3.2.1)
12
- builder (~> 3.0.0)
13
- erubis (~> 2.7.0)
14
- journey (~> 1.0.1)
15
- rack (~> 1.4.0)
16
- rack-cache (~> 1.1)
17
- rack-test (~> 0.6.1)
18
- sprockets (~> 2.1.2)
19
- activemodel (3.2.1)
20
- activesupport (= 3.2.1)
21
- builder (~> 3.0.0)
22
- activerecord (3.2.1)
23
- activemodel (= 3.2.1)
24
- activesupport (= 3.2.1)
25
- arel (~> 3.0.0)
26
- tzinfo (~> 0.3.29)
27
- activesupport (3.2.1)
28
- i18n (~> 0.6)
29
- multi_json (~> 1.0)
30
- appraisal (0.4.1)
31
- bundler
32
- rake
33
- arel (3.0.0)
34
- builder (3.0.0)
35
- coderay (1.0.5)
36
- erubis (2.7.0)
37
- hike (1.2.1)
38
- i18n (0.6.0)
39
- journey (1.0.1)
40
- json (1.6.5)
41
- metaclass (0.0.1)
42
- method_source (0.7.0)
43
- mocha (0.10.4)
44
- metaclass (~> 0.0.1)
45
- multi_json (1.0.4)
46
- pry (0.9.8)
47
- coderay (~> 1.0.5)
48
- method_source (~> 0.7)
49
- slop (>= 2.4.3, < 3)
50
- rack (1.4.1)
51
- rack-cache (1.1)
52
- rack (>= 0.4)
53
- rack-ssl (1.3.2)
54
- rack
55
- rack-test (0.6.1)
56
- rack (>= 1.0)
57
- railties (3.2.1)
58
- actionpack (= 3.2.1)
59
- activesupport (= 3.2.1)
60
- rack-ssl (~> 1.3.2)
61
- rake (>= 0.8.7)
62
- rdoc (~> 3.4)
63
- thor (~> 0.14.6)
64
- rake (0.9.2.2)
65
- rdoc (3.12)
66
- json (~> 1.4)
67
- redcarpet (2.1.0)
68
- shoulda (2.11.3)
69
- simplecov (0.5.4)
70
- multi_json (~> 1.0.3)
71
- simplecov-html (~> 0.5.3)
72
- simplecov-html (0.5.3)
73
- slop (2.4.3)
74
- sprockets (2.1.2)
75
- hike (~> 1.2)
76
- rack (~> 1.0)
77
- tilt (~> 1.1, != 1.3.0)
78
- sqlite3 (1.3.5)
79
- thor (0.14.6)
80
- tilt (1.3.3)
81
- tzinfo (0.3.31)
82
- yard (0.7.5)
83
-
84
- PLATFORMS
85
- ruby
86
-
87
- DEPENDENCIES
88
- activerecord (~> 3.2.0)
89
- acts-as-approvable!
90
- appraisal
91
- mocha
92
- pry
93
- railties (~> 3.2.0)
94
- rake
95
- redcarpet
96
- shoulda
97
- simplecov
98
- sqlite3
99
- yard
@@ -1,291 +0,0 @@
1
- module ActsAsApprovable
2
- ##
3
- # The meat of {ActsAsApprovable}. This applies methods for the configured approval events
4
- # and configures the required relationships.
5
- module Model
6
- def self.included(base)
7
- base.send :extend, ClassMethods
8
- end
9
-
10
- ##
11
- # Class methods added to `ActiveRecord::Base`.
12
- module ClassMethods
13
- # Declare this in your model to require approval on new records or changes to fields.
14
- #
15
- # @param [Hash] options the options for this models approval workflow.
16
- # @option options [Symbol,Array] :on The events to require approval on (`:create` or `:update`).
17
- # @option options [String] :state_field The local field to store `:create` approval state.
18
- # @option options [Array] :ignore A list of fields to ignore. By default we ignore `:created_at`, `:updated_at` and
19
- # the field specified in `:state_field`.
20
- # @option options [Array] :only A list of fields to explicitly require approval on. This list supercedes `:ignore`.
21
- def acts_as_approvable(options = {})
22
- include InstanceMethods
23
-
24
- cattr_accessor :approvable_on
25
- self.approvable_on = Array.wrap(options.delete(:on) { [:create, :update] })
26
-
27
- cattr_accessor :approvable_field
28
- self.approvable_field = options.delete(:state_field)
29
-
30
- cattr_accessor :approvable_ignore
31
- ignores = Array.wrap(options.delete(:ignore) { [] })
32
- ignores.push('created_at', 'updated_at', self.approvable_field)
33
- self.approvable_ignore = ignores.compact.uniq.map(&:to_s)
34
-
35
- cattr_accessor :approvable_only
36
- self.approvable_only = Array.wrap(options.delete(:only) { [] }).uniq.map(&:to_s)
37
-
38
- cattr_accessor :approvals_active
39
- self.approvals_active = true
40
-
41
- has_many :approvals, :as => :item, :dependent => :destroy
42
-
43
- if self.approvable_on.include?(:update)
44
- include UpdateInstanceMethods
45
- before_update :approvable_update, :if => :approvable_update?
46
- end
47
-
48
- if self.approvable_on.include?(:create)
49
- include CreateInstanceMethods
50
- before_create :approvable_create, :if => :approvable_create?
51
- end
52
-
53
- after_save :approvable_save, :if => :approvals_enabled?
54
- end
55
-
56
- ##
57
- # Enable the approval queue for this model.
58
- def approvals_on
59
- self.approvals_active = true
60
- end
61
-
62
- ##
63
- # Disable the approval queue for this model.
64
- def approvals_off
65
- self.approvals_active = false
66
- end
67
-
68
- ##
69
- # Execute a code block while the approval queue is temporarily disabled. The
70
- # queue state will be returned to it's previous value, either on or off.
71
- def without_approval(&block)
72
- enable = self.approvals_active
73
- approvals_off
74
- yield(self)
75
- ensure
76
- approvals_on if enable
77
- end
78
- end
79
-
80
- ##
81
- # Instance methods that apply to the `:create` event specifically.
82
- module CreateInstanceMethods
83
- ##
84
- # Retrieve approval record for the creation event.
85
- #
86
- # @return [Approval]
87
- def approval
88
- approvals.find_by_event('create')
89
- end
90
-
91
- ##
92
- # Get the approval state of the current record from either the local state
93
- # field or, if no state field exists, the creation approval object.
94
- #
95
- # @return [String] one of `'pending'`, `'approved`' or `'rejected'`.
96
- def approval_state
97
- if self.class.approvable_field
98
- send(self.class.approvable_field)
99
- elsif approval.present?
100
- approval.state
101
- end
102
- end
103
-
104
- ##
105
- # Set the records local approval state.
106
- #
107
- # @param [String] state one of `'pending'`, `'approved`' or `'rejected'`.
108
- def set_approval_state(state)
109
- return unless self.class.approvable_field
110
- send("#{self.class.approvable_field}=".to_sym, state)
111
- end
112
-
113
- ##
114
- # Returns true if the record is pending approval.
115
- def pending?
116
- approval_state == 'pending' or approval.try(:pending?)
117
- end
118
-
119
- ##
120
- # Returns true if the record has been approved.
121
- def approved?
122
- approval_state == 'approved' or approval.try(:approved?)
123
- end
124
-
125
- ##
126
- # Returns true if the record has been rejected.
127
- def rejected?
128
- approval_state == 'rejected' or approval.try(:rejected?)
129
- end
130
-
131
- ##
132
- # Approves the record through {Approval#approve!}
133
- #
134
- # @return [Boolean]
135
- def approve!
136
- return unless approvable_on?(:create) && approval.present?
137
- approval.approve!
138
- end
139
-
140
- ##
141
- # Rejects the record through {Approval#reject!}
142
- #
143
- # @return [Boolean]
144
- def reject!
145
- return unless approvable_on?(:create) && approval.present?
146
- approval.reject!
147
- end
148
-
149
- private
150
- def approvable_create?
151
- approvals_enabled? and approvable_on?(:create)
152
- end
153
-
154
- def approvable_create
155
- @approval = approvals.build(:event => 'create', :state => 'pending')
156
- set_approval_state('pending')
157
- end
158
- end
159
-
160
- ##
161
- # Instance methods that apply to the :update event specifically.
162
- module UpdateInstanceMethods
163
- ##
164
- # Retrieve all approval records for `:update` events.
165
- def update_approvals(all = true)
166
- all ? approvals.find_all_by_event('update') : approvals.find_all_by_event_and_state('update', 0)
167
- end
168
-
169
- ##
170
- # Returns true if the record has any `#update_approvals` that are pending
171
- # approval.
172
- def pending_changes?
173
- !update_approvals(false).empty?
174
- end
175
-
176
- ##
177
- # Returns true if any notable (eg. not ignored) fields have been changed.
178
- def changed_notably?
179
- notably_changed.any?
180
- end
181
-
182
- ##
183
- # Returns an array of any notable (eg. not ignored) fields that have not
184
- # been changed.
185
- #
186
- # @return [Array] a list of changed fields.
187
- def notably_changed
188
- unless self.class.approvable_only.empty?
189
- self.class.approvable_only.select { |field| changed.include?(field) }
190
- else
191
- changed - self.class.approvable_ignore
192
- end
193
- end
194
-
195
- private
196
- def approvable_update?
197
- approvals_enabled? and approvable_on?(:update) and changed_notably?
198
- end
199
-
200
- def approvable_update
201
- changed = {}
202
- notably_changed.each do |attr|
203
- original, changed_to = changes[attr]
204
-
205
- write_attribute(attr.to_s, original)
206
- changed[attr] = changed_to
207
- end
208
-
209
- @approval = approvals.build(:event => 'update', :state => 'pending', :object => changed)
210
- end
211
- end
212
-
213
- ##
214
- # Instance methods that apply to both `:update` and `:create` events.
215
- module InstanceMethods
216
- ##
217
- # Returns true if the approval queue is active at both the local and global
218
- # level. Note that the global level supercedes the local level.
219
- def approvals_enabled?
220
- ActsAsApprovable.enabled? and self.class.approvals_active and approvals_on?
221
- end
222
-
223
- ##
224
- # Returns the inverse of `#approvals_enabled?`
225
- def approvals_disabled?
226
- !approvals_enabled?
227
- end
228
-
229
- def approvals_off
230
- @approvals_disabled = true
231
- end
232
-
233
- def approvals_on
234
- @approvals_disabled = false
235
- end
236
-
237
- def approvals_on?
238
- not @approvals_disabled
239
- end
240
-
241
- ##
242
- # Returns true if the model is configured to use the approval queue on the
243
- # given event (`:create` or `:update`).
244
- def approvable_on?(event)
245
- self.class.approvable_on.include?(event)
246
- end
247
-
248
- ##
249
- # A filter that is run before the record can be approved. Returning false
250
- # stops the approval process from completing.
251
- def before_approve(approval); end
252
-
253
- ##
254
- # A filter that is run after the record has been approved.
255
- def after_approve(approval); end
256
-
257
- ##
258
- # A filter that is run before the record can be rejected. Returning false
259
- # stops the rejection process from completing.
260
- def before_reject(approval); end
261
-
262
- ##
263
- # A filter that is run after the record has been rejected.
264
- def after_reject(approval); end
265
-
266
- ##
267
- # Execute a code block while the approval queue is temporarily disabled. The
268
- # queue state will be returned to it's previous value, either on or off.
269
- def without_approval(&block)
270
- enable = approvals_on? # If we use #approvals_enabled? the global state might be incorrectly applied.
271
- approvals_off
272
- yield(self)
273
- ensure
274
- approvals_on if enable
275
- end
276
-
277
- def save_without_approval(*args)
278
- without_approval { |i| save(*args) }
279
- end
280
-
281
- def save_without_approval!(*args)
282
- without_approval { |i| save!(*args) }
283
- end
284
-
285
- private
286
- def approvable_save
287
- @approval.save if @approval.present? && @approval.new_record?
288
- end
289
- end
290
- end
291
- end
@@ -1,459 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ActsAsApprovableModelTest < Test::Unit::TestCase
4
- load_schema
5
-
6
- def teardown
7
- truncate
8
- end
9
-
10
- context 'A record with update only approval' do
11
- context 'and ignored fields' do
12
- setup { @project = Project.create }
13
-
14
- should 'have no approvals' do
15
- assert @project.approvals.empty?
16
- end
17
-
18
- context 'which updates an ignored column' do
19
- setup { @project.update_attribute(:title, 'Ignore Me') }
20
-
21
- should 'not have an approval' do
22
- assert @project.approvals.empty?
23
- end
24
- end
25
-
26
- context 'which updates an ignore column and a non-ignored column' do
27
- setup { @project.update_attributes(:title => 'Ignore Me', :description => 'Must Review') }
28
-
29
- should 'have one approval' do
30
- assert_equal 1, @project.approvals.size
31
- end
32
-
33
- should 'not update the records ignored column' do
34
- assert_equal nil, @project.description
35
- end
36
-
37
- should 'update the records non-ignored columns' do
38
- assert_equal 'Ignore Me', @project.title
39
- end
40
-
41
- should 'have the description on the approval' do
42
- assert @project.approvals.last.object.key?('description')
43
- assert_equal 'Must Review', @project.approvals.last.object['description']
44
- end
45
- end
46
-
47
- context 'that is altered using #without_approval' do
48
- should 'not have an approval object' do
49
- @project.without_approval { |i| i.update_attribute(:description, 'updated') }
50
- assert @project.approvals.empty?
51
- end
52
-
53
- should 'correctly restore approval queue state' do
54
- assert @project.approvals_on?
55
- @project.approvals_off
56
- assert !@project.approvals_on?
57
- @project.without_approval { |i| i.update_attribute(:description, 'updated') }
58
- assert !@project.approvals_on?
59
- end
60
- end
61
- end
62
-
63
- context 'and "only" fields' do
64
- setup { @game = Game.create }
65
-
66
- should 'have no approvals' do
67
- assert @game.approvals.empty?
68
- end
69
-
70
- context 'which updates an only column' do
71
- setup { @game.update_attribute(:title, 'review') }
72
-
73
- should 'have an approval' do
74
- assert_equal 1, @game.approvals.size
75
- end
76
-
77
- should 'have pending changes' do
78
- assert @game.pending_changes?
79
- end
80
- end
81
-
82
- context 'which updates an only column and another column' do
83
- setup { @game.update_attributes(:title => 'review', :description => 'no review') }
84
-
85
- should 'have one approval' do
86
- assert_equal 1, @game.approvals.size
87
- end
88
-
89
- should 'not update the records only column' do
90
- assert_equal nil, @game.title
91
- end
92
-
93
- should 'update the records other fields' do
94
- assert_equal 'no review', @game.description
95
- end
96
-
97
- should 'have the title on the approval' do
98
- assert @game.approvals.last.object.key?('title')
99
- assert_equal 'review', @game.approvals.last.object['title']
100
- end
101
- end
102
-
103
- context 'that has approved, rejected and pending update approvals' do
104
- setup do
105
- @game.update_attributes(:title => 'review1')
106
- @game.update_approvals.last.approve!(true)
107
-
108
- @game.update_attributes(:title => 'review2')
109
- @game.update_approvals.last.reject!
110
-
111
- @game.update_attributes(:title => 'review3')
112
- @game.update_attributes(:title => 'review4')
113
- end
114
-
115
- should 'have #pending_changes?' do
116
- assert @game.pending_changes?
117
- end
118
- end
119
-
120
- context 'that has approved and rejected, but no pending update approvals' do
121
- setup do
122
- @game.update_attributes(:title => 'review1')
123
- @game.update_approvals.last.approve!(true)
124
-
125
- @game.update_attributes(:title => 'review2')
126
- @game.update_approvals.last.reject!
127
- end
128
-
129
- should 'have #pending_changes?' do
130
- assert !@game.pending_changes?
131
- end
132
- end
133
-
134
- context 'that is altered using #without_approval' do
135
- setup { @game.without_approval { |i| i.update_attribute(:title, 'updated') } }
136
-
137
- should 'not have an approval object' do
138
- assert @game.approvals.empty?
139
- end
140
- end
141
-
142
- context 'with approval queue disabled' do
143
- context 'at the record level' do
144
- setup do
145
- @game.approvals_off
146
- @game.update_attributes(:title => 'review')
147
- end
148
-
149
- teardown { @game.approvals_on }
150
-
151
- should 'have approvals off' do
152
- assert @game.approvals_disabled?
153
- end
154
-
155
- should 'not have an approval object' do
156
- assert @game.approvals.empty?
157
- end
158
- end
159
-
160
- context 'at the model level' do
161
- setup do
162
- Game.approvals_off
163
- @game.update_attributes(:title => 'review')
164
- end
165
-
166
- teardown { Game.approvals_on }
167
-
168
- should 'have approvals off' do
169
- assert @game.approvals_disabled?
170
- end
171
-
172
- should 'not have an approval object' do
173
- assert @game.approvals.empty?
174
- end
175
- end
176
-
177
- context 'at the global level' do
178
- setup do
179
- ActsAsApprovable.disable
180
- @game.update_attributes(:title => 'review')
181
- end
182
-
183
- teardown { ActsAsApprovable.enable }
184
-
185
- should 'have approvals off' do
186
- assert @game.approvals_disabled?
187
- end
188
-
189
- should 'not have an approval object' do
190
- assert @game.approvals.empty?
191
- end
192
- end
193
- end
194
- end
195
- end
196
-
197
- context 'An approval record' do
198
- setup do
199
- @project = Project.create
200
- @project.update_attribute(:description, 'review')
201
- @approval = @project.approvals.last
202
- end
203
-
204
- should 'not be locked by default' do
205
- assert @approval.unlocked?
206
- assert !@approval.locked?
207
- end
208
-
209
- should 'be pending' do
210
- assert @approval.pending?
211
- assert !@approval.approved?
212
- assert !@approval.rejected?
213
- end
214
-
215
- should 'check attributes in object' do
216
- @approval.object['foo'] = 'bar'
217
- @approval.approve!
218
- assert_equal @approval.object['description'], @approval.item.description
219
- end
220
-
221
- context 'that is accepted' do
222
- setup { @approval.approve! }
223
-
224
- should 'be locked' do
225
- assert @approval.locked?
226
- assert !@approval.unlocked?
227
- end
228
-
229
- should 'be approved' do
230
- assert @approval.approved?
231
- assert !@approval.rejected?
232
- assert !@approval.pending?
233
- end
234
-
235
- should 'update the target item' do
236
- assert_equal @approval.object['description'], @approval.item.description
237
- end
238
-
239
- should 'raise an error if approved again' do
240
- assert_raise(ActsAsApprovable::Error::Locked) { @approval.approve! }
241
- end
242
-
243
- should 'raise an error if rejected' do
244
- assert_raise(ActsAsApprovable::Error::Locked) { @approval.reject! }
245
- end
246
- end
247
-
248
- context 'that is rejected' do
249
- setup { @approval.reject! }
250
-
251
- should 'be locked' do
252
- assert @approval.locked?
253
- assert !@approval.unlocked?
254
- end
255
-
256
- should 'be rejected' do
257
- assert @approval.rejected?
258
- assert !@approval.approved?
259
- assert !@approval.pending?
260
- end
261
-
262
- should 'not update the target item' do
263
- assert_equal nil, @approval.item.description
264
- end
265
-
266
- should 'raise an error if approved' do
267
- assert_raise(ActsAsApprovable::Error::Locked) { @approval.approve! }
268
- end
269
-
270
- should 'raise an error if rejected again' do
271
- assert_raise(ActsAsApprovable::Error::Locked) { @approval.reject! }
272
- end
273
- end
274
-
275
- context 'that is stale' do
276
- setup { @approval.update_attributes(:created_at => 10.days.ago) }
277
-
278
- should 'be stale' do
279
- assert @approval.stale?
280
- assert !@approval.fresh?
281
- end
282
-
283
- should 'raise an error if approved' do
284
- assert_raise(ActsAsApprovable::Error::Stale) { @approval.approve! }
285
- assert @approval.pending?
286
- end
287
-
288
- should 'not raise an error if rejected' do
289
- assert_nothing_raised { @approval.reject! }
290
- assert @approval.rejected?
291
- end
292
-
293
- should 'allow approval when forced' do
294
- assert_nothing_raised { @approval.approve!(true) }
295
- assert @approval.approved?
296
- end
297
- end
298
- end
299
-
300
- context 'A record with create only approval' do
301
- setup { @user = User.create }
302
-
303
- should 'be pending by default' do
304
- assert @user.pending?
305
- assert !@user.approved?
306
- assert !@user.rejected?
307
- end
308
-
309
- should 'have an approval object' do
310
- assert_equal 1, @user.approvals.size
311
- end
312
-
313
- should 'set the local state' do
314
- assert_equal 'pending', @user.state
315
- end
316
-
317
- context 'when approved' do
318
- setup do
319
- @user.approve!
320
- @user.reload
321
- end
322
-
323
- should 'be approved' do
324
- assert @user.approved?
325
- assert !@user.rejected?
326
- assert !@user.pending?
327
- end
328
-
329
- should 'update the local state' do
330
- assert_equal 'approved', @user.state
331
- end
332
- end
333
-
334
- context 'when rejected' do
335
- setup do
336
- @user.reject!
337
- @user.reload
338
- end
339
-
340
- should 'be rejected' do
341
- assert @user.rejected?
342
- assert !@user.approved?
343
- assert !@user.pending?
344
- end
345
-
346
- should 'update the local state' do
347
- assert_equal 'rejected', @user.state
348
- end
349
- end
350
-
351
- context '.without_approval' do
352
- should 'disable approvals for the given block' do
353
- @user = User.without_approval { |m| m.create }
354
- assert @user.approval.nil?
355
- end
356
- end
357
- end
358
-
359
- context 'A record with default settings' do
360
- setup { @employee = Employee.create }
361
-
362
- should 'be pending by default' do
363
- assert @employee.pending?
364
- assert !@employee.approved?
365
- assert !@employee.rejected?
366
- end
367
-
368
- should 'get the state from the approval record' do
369
- assert_equal @employee.approval_state, @employee.approval.state
370
- end
371
-
372
- context 'when updated' do
373
- setup { @employee.update_attributes(:name => 'John Doe') }
374
-
375
- should 'not update the attribute' do
376
- assert_equal nil, @employee.name
377
- end
378
-
379
- should 'create an approval record' do
380
- assert_equal 1, @employee.update_approvals.size
381
- end
382
- end
383
-
384
- context 'when approving' do
385
- setup { @approval = @employee.approval }
386
-
387
- should 'call before_approve hook' do
388
- @approval.item.expects(:before_approve).once
389
- @approval.approve!
390
- end
391
-
392
- should 'call after_approve hook' do
393
- @approval.item.expects(:after_approve).once
394
- @approval.approve!
395
- end
396
-
397
- should 'halt if before_approve returns false' do
398
- @approval.item.stubs(:before_approve).returns(false)
399
- @approval.approve!
400
- assert @approval.item.pending?
401
- end
402
- end
403
-
404
- context 'when rejecting' do
405
- setup { @approval = @employee.approval }
406
-
407
- should 'call before_reject hook' do
408
- @approval.item.expects(:before_reject).once
409
- @approval.reject!
410
- end
411
-
412
- should 'call after_reject hook' do
413
- @approval.item.expects(:after_reject).once
414
- @approval.reject!
415
- end
416
-
417
- should 'halt if before_reject returns false' do
418
- @approval.item.stubs(:before_reject).returns(false)
419
- @approval.reject!
420
- assert @approval.item.pending?
421
- end
422
- end
423
- end
424
-
425
- context '.options_for_state' do
426
- should 'return an array' do
427
- assert_kind_of Array, Approval.options_for_state
428
- end
429
-
430
- should 'contain our states' do
431
- assert Approval.options_for_state.include?(['All', -1])
432
- assert Approval.options_for_state.include?(['Pending', 0])
433
- assert Approval.options_for_state.include?(['Approved', 1])
434
- assert Approval.options_for_state.include?(['Rejected', 2])
435
- end
436
- end
437
-
438
- context '.options_for_type' do
439
- context 'without approval records' do
440
- should 'be empty' do
441
- assert Approval.options_for_type.empty?
442
- end
443
- end
444
-
445
- context 'with approval records' do
446
- setup do
447
- Project.create.update_attributes(:description => 'review')
448
- Game.create.update_attributes(:title => 'review')
449
- User.create
450
- end
451
-
452
- should 'contain all types with approvals' do
453
- assert Approval.options_for_type.include?('Project')
454
- assert Approval.options_for_type.include?('Game')
455
- assert Approval.options_for_type.include?('User')
456
- end
457
- end
458
- end
459
- end