approvable 0.0.1 → 0.0.2
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 +4 -4
- data/app/models/approvable/change_request.rb +28 -13
- data/db/migrate/20140807145534_create_approvable_change_requests.rb +1 -1
- data/db/migrate/20140809183112_add_notes_to_approvable_change_requests.rb +5 -0
- data/lib/approvable/acts_as_approvable.rb +101 -36
- data/lib/approvable/engine.rb +4 -16
- data/lib/approvable/version.rb +1 -1
- data/spec/dummy/app/models/foobar.rb +6 -0
- data/spec/dummy/app/models/listing.rb +2 -0
- data/spec/dummy/db/migrate/20140816143802_create_foobars.rb +9 -0
- data/spec/dummy/db/schema.rb +33 -1
- data/spec/factories/change_requests.rb +5 -28
- data/spec/factories/listing.rb +4 -1
- data/spec/models/acts_as_approvable_spec.rb +344 -159
- data/spec/models/approvable/change_request_spec.rb +19 -20
- metadata +23 -9
- data/README.rdoc +0 -3
- data/spec/dummy/log/development.log +0 -339
- data/spec/dummy/log/test.log +0 -33704
data/spec/factories/listing.rb
CHANGED
@@ -2,191 +2,376 @@ require 'rails_helper'
|
|
2
2
|
|
3
3
|
module Approvable
|
4
4
|
describe ActsAsApprovable do
|
5
|
-
before do
|
5
|
+
before(:each) do
|
6
|
+
Approvable.auto_approve = false
|
6
7
|
@listing = create(:listing, :approved)
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
it 'responds to with_changes method' do
|
14
|
-
expect(@listing).to respond_to :with_changes
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'has_many change_requests' do
|
18
|
-
expect(@listing).to respond_to :change_requests
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'has_one current_change_request' do
|
22
|
-
expect(@listing).to respond_to :current_change_request
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'returns last unapproved change request' do
|
26
|
-
create(:change_request, :approved, approvable: @listing )
|
27
|
-
create(:change_request, :approved, approvable: @listing )
|
28
|
-
change_request = create(:change_request, :submitted, approvable: @listing )
|
29
|
-
@listing.reload
|
10
|
+
context ".acts_as_approvable" do
|
11
|
+
it 'responds' do
|
12
|
+
expect(Listing).to respond_to :acts_as_approvable
|
13
|
+
end
|
30
14
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
15
|
+
it 'applies changes and auto approves' do
|
16
|
+
Approvable.auto_approve = true
|
17
|
+
|
18
|
+
@listing.update(title: 'a brand new title')
|
19
|
+
@listing.reload
|
20
|
+
|
21
|
+
expect(@listing.title).to eq 'a brand new title'
|
22
|
+
end
|
37
23
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
24
|
+
it 'doesnt track attribute excluded by except option' do
|
25
|
+
Listing.class_eval { acts_as_approvable except: :title }
|
26
|
+
|
27
|
+
expect{
|
28
|
+
@listing.update(title: 'a brand new title')
|
29
|
+
}.not_to change {@listing.change_requests.count}
|
30
|
+
@listing.reload
|
31
|
+
|
32
|
+
expect(@listing.title).to eq 'a brand new title'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'doesnt track attribute array excluded by except option' do
|
36
|
+
Listing.class_eval { acts_as_approvable except: [:title, :image]}
|
37
|
+
expect{
|
38
|
+
@listing.update(title: 'a brand new title', image: 'me.jpg')
|
39
|
+
}.not_to change {@listing.change_requests.count}
|
40
|
+
@listing.reload
|
41
|
+
expect(@listing.title).to eq 'a brand new title'
|
42
|
+
expect(@listing.image).to eq 'me.jpg'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'doesnt track attribute not included by only option' do
|
46
|
+
Listing.class_eval { acts_as_approvable only: :image }
|
47
|
+
|
48
|
+
expect{
|
49
|
+
@listing.update(title: 'a brand new title')
|
50
|
+
}.not_to change {@listing.change_requests.count}
|
51
|
+
@listing.reload
|
52
|
+
|
53
|
+
expect(@listing.title).to eq 'a brand new title'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'doesnt track attributes not included by only array' do
|
57
|
+
Listing.class_eval { acts_as_approvable only: [:description, :deleted]}
|
58
|
+
expect{
|
59
|
+
@listing.update(title: 'a brand new title', image: 'me.jpg')
|
60
|
+
}.not_to change {@listing.change_requests.count}
|
61
|
+
@listing.reload
|
62
|
+
expect(@listing.title).to eq 'a brand new title'
|
63
|
+
expect(@listing.image).to eq 'me.jpg'
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'tracks attributes not excluded by except' do
|
67
|
+
|
68
|
+
Listing.class_eval { acts_as_approvable except: :description }
|
69
|
+
|
70
|
+
expect{
|
71
|
+
@listing.update(title: 'a brand new title')
|
72
|
+
}.to change {@listing.change_requests.count}.by(1)
|
73
|
+
|
74
|
+
expect(@listing.title).not_to eq 'a brand new title'
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'tracks attributes included by only' do
|
78
|
+
Listing.class_eval { acts_as_approvable only: :title }
|
79
|
+
|
80
|
+
expect{
|
81
|
+
@listing.update(title: 'a brand new title')
|
82
|
+
}.to change {@listing.change_requests.count}.by(1)
|
83
|
+
|
84
|
+
expect(@listing.title).not_to eq 'a brand new title'
|
85
|
+
end
|
45
86
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
87
|
+
it 'accepts nested except attribtues' do
|
88
|
+
Foobar.class_eval { acts_as_approvable except: [foo: [:image, :title], bar: :description ] }
|
89
|
+
|
90
|
+
foobar = Foobar.new(
|
91
|
+
foo: {image: 'photo.jpg', title: 'me, on the hill', tags: ['me', 'hill', 'on']},
|
92
|
+
bar: {description: 'test test test', title: 'blahhhh'}
|
93
|
+
)
|
94
|
+
|
95
|
+
expect(foobar.foo).to eq({image: 'photo.jpg', title: 'me, on the hill'})
|
96
|
+
expect(foobar.bar).to eq({description: 'test test test'})
|
97
|
+
|
98
|
+
expect(foobar.requested_changes).to match(foo: {tags: ['me', 'hill', 'on']}, bar: {title: 'blahhhh'})
|
99
|
+
end
|
52
100
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
101
|
+
it 'accepts nested only attribtues' do
|
102
|
+
Foobar.class_eval { acts_as_approvable only: [foo: [:image, :title], bar: :description ] }
|
103
|
+
|
104
|
+
foobar = Foobar.new(
|
105
|
+
foo: {image: 'photo.jpg', title: 'me, on the hill', tags: ['me', 'hill', 'on']},
|
106
|
+
bar: {description: 'test test test', title: 'blahhhh'}
|
107
|
+
)
|
108
|
+
|
109
|
+
expect(foobar.foo).to eq({tags: ['me', 'hill', 'on']})
|
110
|
+
expect(foobar.bar).to eq({title: 'blahhhh'})
|
111
|
+
expect(foobar.requested_changes).to match(foo: {image: 'photo.jpg', title: 'me, on the hill'}, bar: {description: 'test test test'} )
|
112
|
+
end
|
60
113
|
|
61
|
-
expect{
|
62
|
-
create(:change_request, :submitted, approvable: @listing )
|
63
|
-
}.to raise_error ActiveRecord::RecordInvalid
|
64
114
|
end
|
65
115
|
|
66
|
-
it '
|
67
|
-
expect
|
68
|
-
@listing.update(title: 'a brand new title')
|
69
|
-
}.to change {@listing.change_requests.count}.by(1)
|
116
|
+
it 'has_many change_requests' do
|
117
|
+
expect(@listing).to respond_to :change_requests
|
70
118
|
end
|
71
|
-
|
72
|
-
it 'returns listing with requested changes' do
|
73
|
-
@listing.update(title: 'a brand new title')
|
74
119
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
expect{
|
82
|
-
@listing.update(title: 'a brand new title')
|
83
|
-
}.to change {@listing.change_requests.count}.by(1)
|
84
|
-
|
85
|
-
change_request.reload
|
86
|
-
expect(change_request.changed_attributes).not_to match title: 'a brand new title'
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'updates a pending change request for a pending listing' do
|
90
|
-
change_request = create(:change_request, :pending, approvable: @listing )
|
91
|
-
@listing.reload
|
92
|
-
|
93
|
-
expect{
|
120
|
+
context '#apply_changes' do
|
121
|
+
it 'responds' do
|
122
|
+
expect(@listing).to respond_to :apply_changes
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'returns listing with requested changes' do
|
94
126
|
@listing.update(title: 'a brand new title')
|
95
|
-
}.not_to change {@listing.change_requests.count}
|
96
127
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
expect{
|
107
|
-
@listing.update(description: 'a hot bod')
|
108
|
-
}.not_to change {@listing.change_requests.count}
|
128
|
+
expect(@listing.title).not_to eq 'a brand new title'
|
129
|
+
expect(@listing.apply_changes.title).to eq 'a brand new title'
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
it 'returns listing as is if no current_change_request ' do
|
134
|
+
expect(@listing.apply_changes.title).to eq @listing.title
|
135
|
+
end
|
109
136
|
|
110
|
-
change_request.reload
|
111
|
-
expect(change_request.requested_changes).to match "title" => 'a brand new title', "description" => 'a hot bod'
|
112
|
-
expect(change_request.state).to eq 'pending'
|
113
137
|
end
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
@listing.
|
121
|
-
|
122
|
-
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
context '#current_change_request' do
|
142
|
+
|
143
|
+
it 'has_one' do
|
144
|
+
expect(@listing).to respond_to :current_change_request
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
it 'returns last unapproved change request' do
|
149
|
+
create(:change_request, :approved, approvable: @listing )
|
150
|
+
create(:change_request, :approved, approvable: @listing )
|
123
151
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
}.not_to change {@listing.change_requests.count}
|
152
|
+
change_request = create(:change_request, :submitted, approvable: @listing )
|
153
|
+
|
154
|
+
@listing.reload
|
155
|
+
|
156
|
+
expect(@listing.current_change_request).to eq change_request
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'returns nil if no unapproved change request' do
|
160
|
+
create(:change_request, :approved, approvable: @listing )
|
161
|
+
create(:change_request, :approved, approvable: @listing )
|
162
|
+
|
163
|
+
expect(@listing.current_change_request).to be nil
|
164
|
+
end
|
138
165
|
|
139
|
-
change_request.reload
|
140
|
-
|
141
|
-
expect(change_request.requested_changes).to match "title" => 'a brand new title'
|
142
|
-
expect(change_request.state).to eq 'pending'
|
143
|
-
end
|
144
|
-
|
145
|
-
it 'submits changes' do
|
146
|
-
@listing.update(title: 'a brand new title')
|
147
|
-
@listing.submit_changes
|
148
|
-
|
149
|
-
expect(@listing.change_status).to eq 'submitted'
|
150
|
-
@listing.reload
|
151
|
-
|
152
|
-
expect(@listing.title).not_to eq 'a brand new title'
|
153
166
|
end
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
167
|
+
|
168
|
+
context '#change_status' do
|
169
|
+
it 'delegates to current_change_request' do
|
170
|
+
create(:change_request, :approved, approvable: @listing )
|
171
|
+
create(:change_request, :submitted, approvable: @listing )
|
172
|
+
@listing.reload
|
173
|
+
|
174
|
+
expect(@listing.change_status).to eq 'submitted'
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'returns approved if no current_change_request' do
|
178
|
+
create(:change_request, :approved, approvable: @listing )
|
179
|
+
create(:change_request, :approved, approvable: @listing )
|
180
|
+
|
181
|
+
expect(@listing.change_status).to eq 'approved'
|
182
|
+
end
|
164
183
|
end
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
184
|
+
|
185
|
+
context '#save/#update' do
|
186
|
+
|
187
|
+
it 'creates a new change request for an new listing' do
|
188
|
+
expect{
|
189
|
+
@listing.update(title: 'a brand new title')
|
190
|
+
}.to change {@listing.change_requests.count}.by(1)
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'creates a new change request for an approved listing and doesnt change exiting' do
|
194
|
+
change_request = create(:change_request, :approved, approvable: @listing )
|
195
|
+
expect{
|
196
|
+
@listing.update(title: 'a brand new title')
|
197
|
+
}.to change {@listing.change_requests.count}.by(1)
|
198
|
+
|
199
|
+
change_request.reload
|
200
|
+
expect(change_request.changed_attributes).not_to match title: 'a brand new title'
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
it 'updates a pending change request for a listing' do
|
205
|
+
@listing.update title: 'blah blah', description: 'another one'
|
206
|
+
@listing.reload
|
207
|
+
expect(@listing.requested_changes).to eq 'title' => 'blah blah', "description" => 'another one'
|
208
|
+
|
209
|
+
expect{
|
210
|
+
@listing.update(title: 'new title!!!')
|
211
|
+
}.not_to change {@listing.change_requests.count}
|
212
|
+
|
213
|
+
@listing.reload
|
214
|
+
expect(@listing.requested_changes).to eq 'title' => 'new title!!!', "description" => 'another one'
|
215
|
+
expect(@listing.change_status).to eq 'pending'
|
216
|
+
end
|
172
217
|
|
173
|
-
|
174
|
-
|
175
|
-
|
218
|
+
it 'reverts changed attribute back to original' do
|
219
|
+
original_title = @listing.title
|
220
|
+
@listing.update title: 'blah blah', description: 'another one'
|
221
|
+
|
222
|
+
@listing.reload
|
223
|
+
expect(@listing.requested_changes).to include "title" => 'blah blah'
|
224
|
+
|
225
|
+
expect{
|
226
|
+
@listing.update(title: original_title)
|
227
|
+
}.not_to change {@listing.change_requests.count}
|
228
|
+
|
229
|
+
@listing.reload
|
230
|
+
expect(@listing.requested_changes).to eq "title" => original_title, "description" => 'another one'
|
231
|
+
expect(@listing.change_status).to eq 'pending'
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'updates a change request for a rejected listing' do
|
235
|
+
@listing.update title: 'blah blah', description: 'another one'
|
236
|
+
|
237
|
+
@listing.submit_changes
|
238
|
+
@listing.reject_changes
|
239
|
+
|
240
|
+
expect{
|
241
|
+
@listing.update(title: 'a brand new title')
|
242
|
+
}.not_to change {@listing.change_requests.count}
|
243
|
+
|
244
|
+
@listing.reload
|
245
|
+
expect(@listing.requested_changes).to match "title" => 'a brand new title', 'description' => 'another one'
|
246
|
+
expect(@listing.change_status).to eq 'pending'
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'keeps previous changes and adds new changes' do
|
250
|
+
change_request = create(:change_request, :pending, requested_changes: {"title" => 'a brand new title'}, approvable: @listing )
|
251
|
+
@listing.reload
|
252
|
+
|
253
|
+
expect{
|
254
|
+
@listing.update(description: 'a hot bod')
|
255
|
+
}.not_to change {@listing.change_requests.count}
|
256
|
+
|
257
|
+
change_request.reload
|
258
|
+
expect(change_request.requested_changes).to match "title" => 'a brand new title', "description" => 'a hot bod'
|
259
|
+
expect(change_request.state).to eq 'pending'
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'updates an existing change request for a rejected listing and changes the status to pending' do
|
263
|
+
change_request = create(:change_request, :rejected, approvable: @listing )
|
264
|
+
@listing.reload
|
265
|
+
|
266
|
+
expect{
|
267
|
+
@listing.update(title: 'a brand new title')
|
268
|
+
}.not_to change {@listing.change_requests.count}
|
269
|
+
|
270
|
+
change_request.reload
|
271
|
+
|
272
|
+
expect(change_request.requested_changes).to match "title" => 'a brand new title'
|
273
|
+
expect(change_request.state).to eq 'pending'
|
274
|
+
end
|
176
275
|
end
|
177
|
-
|
178
276
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
277
|
+
context '#submit/#unsubmit/#approve/#reject' do
|
278
|
+
it 'submits changes' do
|
279
|
+
@listing.update(title: 'a brand new title')
|
280
|
+
@listing.submit_changes
|
281
|
+
|
282
|
+
expect(@listing.change_status).to eq 'submitted'
|
283
|
+
@listing.reload
|
284
|
+
|
285
|
+
expect(@listing.title).not_to eq 'a brand new title'
|
286
|
+
end
|
287
|
+
|
288
|
+
it 'unsubmits changes' do
|
289
|
+
@listing.update(title: 'a brand new title')
|
290
|
+
@listing.submit_changes
|
291
|
+
@listing.unsubmit_changes
|
292
|
+
|
293
|
+
expect(@listing.change_status).to eq 'pending'
|
294
|
+
@listing.reload
|
295
|
+
|
296
|
+
expect(@listing.title).not_to eq 'a brand new title'
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'approves changes' do
|
300
|
+
@listing.update(title: 'a brand new title')
|
301
|
+
@listing.submit_changes
|
302
|
+
|
303
|
+
@listing.approve_changes
|
304
|
+
@listing.reload
|
305
|
+
|
306
|
+
expect(@listing.title).to eq 'a brand new title'
|
307
|
+
expect(@listing.current_change_request).to be nil
|
308
|
+
expect(@listing.change_status).to eq 'approved'
|
309
|
+
end
|
310
|
+
|
311
|
+
it 'rejects changes' do
|
312
|
+
@listing.update(title: 'a brand new title')
|
313
|
+
@listing.submit_changes
|
314
|
+
@listing.reject_changes
|
315
|
+
@listing.reload
|
316
|
+
|
317
|
+
expect(@listing.title).not_to eq 'a brand new title'
|
318
|
+
expect(@listing.change_status).to eq 'rejected'
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'rejects with notes' do
|
322
|
+
@listing.update(title: 'a brand new title')
|
323
|
+
@listing.submit_changes
|
324
|
+
@listing.reject_changes(note: 'i dont like it')
|
325
|
+
@listing.reload
|
326
|
+
|
327
|
+
expect(@listing.title).not_to eq 'a brand new title'
|
328
|
+
expect(@listing.change_status).to eq 'rejected'
|
329
|
+
|
330
|
+
notes = @listing.change_status_notes
|
331
|
+
expect(notes).to be_kind_of Hash
|
332
|
+
expect(Time.parse(notes.keys.first)).to be_kind_of Time
|
333
|
+
expect(notes.values.first).to eq 'i dont like it'
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'rejects and adds to existing notes' do
|
337
|
+
@listing.update(title: 'a brand new title')
|
338
|
+
@listing.submit_changes
|
339
|
+
@listing.reject_changes(note: 'i dont like it')
|
340
|
+
@listing.update(title: 'something else')
|
341
|
+
@listing.submit_changes
|
342
|
+
sleep 1
|
343
|
+
@listing.reject_changes(note: 'even worse!!')
|
344
|
+
|
345
|
+
@listing.reload
|
346
|
+
|
347
|
+
expect(@listing.title).not_to eq 'a brand new title'
|
348
|
+
expect(@listing.title).not_to eq 'something else'
|
349
|
+
expect(@listing.change_status).to eq 'rejected'
|
350
|
+
|
351
|
+
notes = @listing.change_status_notes
|
352
|
+
expect(notes.count).to eq 2
|
353
|
+
expect(notes.values.first).to eq 'i dont like it'
|
354
|
+
expect(notes.values.last).to eq 'even worse!!'
|
355
|
+
end
|
187
356
|
end
|
188
357
|
|
189
358
|
|
359
|
+
context '#store_accessor' do
|
360
|
+
it 'also captures store_accessor methods' do
|
361
|
+
foobar = create(:foobar)
|
362
|
+
foobar.update(foo: 'test', bar: 'sets')
|
363
|
+
foobar.reload
|
364
|
+
|
365
|
+
expect(foobar.foo).to be nil
|
366
|
+
expect(foobar.bar).to be nil
|
367
|
+
|
368
|
+
foobar.apply_changes
|
369
|
+
|
370
|
+
expect(foobar.foo).to eq 'test'
|
371
|
+
expect(foobar.bar).to eq 'sets'
|
372
|
+
|
373
|
+
end
|
374
|
+
end
|
190
375
|
|
191
376
|
end
|
192
377
|
end
|