paper_trail 7.0.2 → 7.0.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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +1 -1
  3. data/.rubocop_todo.yml +10 -0
  4. data/.travis.yml +4 -4
  5. data/Appraisals +3 -5
  6. data/CHANGELOG.md +16 -1
  7. data/README.md +70 -119
  8. data/Rakefile +6 -1
  9. data/doc/bug_report_template.rb +4 -2
  10. data/doc/warning_about_not_setting_whodunnit.md +6 -5
  11. data/gemfiles/ar_4.0.gemfile +1 -1
  12. data/gemfiles/ar_4.2.gemfile +1 -1
  13. data/gemfiles/ar_5.0.gemfile +2 -3
  14. data/gemfiles/ar_5.1.gemfile +8 -0
  15. data/gemfiles/ar_master.gemfile +2 -2
  16. data/lib/generators/paper_trail/templates/add_object_changes_to_versions.rb.erb +1 -1
  17. data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb.erb +1 -1
  18. data/lib/generators/paper_trail/templates/create_version_associations.rb.erb +1 -1
  19. data/lib/paper_trail/model_config.rb +4 -4
  20. data/lib/paper_trail/version_concern.rb +4 -4
  21. data/lib/paper_trail/version_number.rb +1 -1
  22. data/paper_trail.gemspec +5 -5
  23. data/spec/controllers/articles_controller_spec.rb +1 -1
  24. data/spec/generators/install_generator_spec.rb +2 -2
  25. data/spec/models/animal_spec.rb +5 -5
  26. data/spec/models/boolit_spec.rb +2 -2
  27. data/spec/models/callback_modifier_spec.rb +2 -2
  28. data/spec/models/car_spec.rb +2 -2
  29. data/spec/models/custom_primary_key_record_spec.rb +2 -2
  30. data/spec/models/document_spec.rb +2 -2
  31. data/spec/models/gadget_spec.rb +2 -2
  32. data/spec/models/joined_version_spec.rb +1 -1
  33. data/spec/models/json_version_spec.rb +4 -4
  34. data/spec/models/kitchen/banana_spec.rb +2 -2
  35. data/spec/models/not_on_update_spec.rb +2 -2
  36. data/spec/models/post_with_status_spec.rb +4 -4
  37. data/spec/models/skipper_spec.rb +1 -1
  38. data/spec/models/thing_spec.rb +2 -2
  39. data/spec/models/vehicle_spec.rb +2 -2
  40. data/spec/models/version_spec.rb +26 -5
  41. data/spec/models/widget_spec.rb +10 -2
  42. data/spec/modules/paper_trail_spec.rb +2 -2
  43. data/spec/modules/version_concern_spec.rb +2 -2
  44. data/spec/modules/version_number_spec.rb +1 -1
  45. data/spec/paper_trail/associations_spec.rb +965 -0
  46. data/spec/paper_trail/cleaner_spec.rb +2 -2
  47. data/spec/paper_trail/config_spec.rb +2 -2
  48. data/spec/paper_trail/model_spec.rb +1421 -0
  49. data/spec/paper_trail/serializer_spec.rb +85 -0
  50. data/spec/paper_trail/serializers/custom_yaml_serializer_spec.rb +1 -1
  51. data/spec/paper_trail/serializers/json_spec.rb +2 -2
  52. data/spec/paper_trail/serializers/yaml_spec.rb +42 -0
  53. data/spec/paper_trail/version_limit_spec.rb +2 -2
  54. data/spec/paper_trail/version_spec.rb +96 -0
  55. data/spec/paper_trail_spec.rb +1 -1
  56. data/spec/requests/articles_spec.rb +2 -2
  57. data/spec/spec_helper.rb +47 -79
  58. data/{test → spec/support}/custom_json_serializer.rb +0 -0
  59. data/test/dummy/app/models/document.rb +1 -1
  60. data/test/dummy/app/models/not_on_update.rb +1 -1
  61. data/test/dummy/app/models/widget.rb +1 -1
  62. data/test/dummy/config/routes.rb +1 -1
  63. data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +18 -9
  64. data/test/dummy/db/schema.rb +64 -64
  65. data/test/test_helper.rb +1 -33
  66. data/test/unit/serializers/mixin_json_test.rb +1 -1
  67. metadata +27 -32
  68. data/spec/models/truck_spec.rb +0 -5
  69. data/spec/rails_helper.rb +0 -34
  70. data/test/time_travel_helper.rb +0 -1
  71. data/test/unit/associations_test.rb +0 -1032
  72. data/test/unit/model_test.rb +0 -1416
  73. data/test/unit/serializer_test.rb +0 -107
  74. data/test/unit/serializers/yaml_test.rb +0 -50
  75. data/test/unit/version_test.rb +0 -112
@@ -1,1416 +0,0 @@
1
- require "test_helper"
2
- require "time_travel_helper"
3
-
4
- class HasPaperTrailModelTest < ActiveSupport::TestCase
5
- context "A record with defined 'only' and 'ignore' attributes" do
6
- setup { @article = Article.create }
7
-
8
- should "creation should change the number of versions" do
9
- assert_equal(1, PaperTrail::Version.count)
10
- end
11
-
12
- context "which updates an ignored column" do
13
- should "not change the number of versions" do
14
- @article.update_attributes title: "My first title"
15
- assert_equal(1, PaperTrail::Version.count)
16
- end
17
- end
18
-
19
- context "which updates an ignored column with truly Proc" do
20
- should "not change the number of versions" do
21
- @article.update_attributes abstract: "ignore abstract"
22
- assert_equal(1, PaperTrail::Version.count)
23
- end
24
- end
25
-
26
- context "which updates an ignored column with falsy Proc" do
27
- should "change the number of versions" do
28
- @article.update_attributes abstract: "do not ignore abstract!"
29
- assert_equal(2, PaperTrail::Version.count)
30
- end
31
- end
32
-
33
- context "which updates an ignored column, ignored with truly Proc and a selected column" do
34
- setup do
35
- @article.update_attributes(
36
- title: "My first title",
37
- content: "Some text here.",
38
- abstract: "ignore abstract"
39
- )
40
- end
41
-
42
- should "change the number of versions" do
43
- assert_equal(2, PaperTrail::Version.count)
44
- end
45
-
46
- should "show the new version in the model's `versions` association" do
47
- assert_equal(2, @article.versions.size)
48
- end
49
-
50
- should "have stored only non-ignored attributes" do
51
- expected = { "content" => [nil, "Some text here."] }
52
- assert_equal expected, @article.versions.last.changeset
53
- end
54
- end
55
-
56
- context "which updates an ignored column, ignored with falsy Proc and a selected column" do
57
- setup do
58
- @article.update_attributes(
59
- title: "My first title",
60
- content: "Some text here.",
61
- abstract: "do not ignore abstract"
62
- )
63
- end
64
-
65
- should "change the number of versions" do
66
- assert_equal(2, PaperTrail::Version.count)
67
- end
68
-
69
- should "show the new version in the model's `versions` association" do
70
- assert_equal(2, @article.versions.size)
71
- end
72
-
73
- should "have stored only non-ignored attributes" do
74
- expected = {
75
- "content" => [nil, "Some text here."],
76
- "abstract" => [nil, "do not ignore abstract"]
77
- }
78
- assert_equal expected, @article.versions.last.changeset
79
- end
80
- end
81
-
82
- context "which updates a selected column" do
83
- setup { @article.update_attributes content: "Some text here." }
84
- should "change the number of versions" do
85
- assert_equal(2, PaperTrail::Version.count)
86
- end
87
-
88
- should "show the new version in the model's `versions` association" do
89
- assert_equal(2, @article.versions.size)
90
- end
91
- end
92
-
93
- context "which updates a non-ignored and non-selected column" do
94
- should "not change the number of versions" do
95
- @article.update_attributes abstract: "Other abstract"
96
- assert_equal(1, PaperTrail::Version.count)
97
- end
98
- end
99
-
100
- context "which updates a skipped column" do
101
- should "not change the number of versions" do
102
- @article.update_attributes file_upload: "Your data goes here"
103
- assert_equal(1, PaperTrail::Version.count)
104
- end
105
- end
106
-
107
- context "which updates a skipped column and a selected column" do
108
- setup do
109
- @article.update_attributes(
110
- file_upload: "Your data goes here",
111
- content: "Some text here."
112
- )
113
- end
114
-
115
- should "change the number of versions" do
116
- assert_equal(2, PaperTrail::Version.count)
117
- end
118
-
119
- should "show the new version in the model's `versions` association" do
120
- assert_equal(2, @article.versions.size)
121
- end
122
-
123
- should "have stored only non-skipped attributes" do
124
- assert_equal ({ "content" => [nil, "Some text here."] }),
125
- @article.versions.last.changeset
126
- end
127
-
128
- context "and when updated again" do
129
- setup do
130
- @article.update_attributes(
131
- file_upload: "More data goes here",
132
- content: "More text here."
133
- )
134
- @old_article = @article.versions.last
135
- end
136
-
137
- should "have removed the skipped attributes when saving the previous version" do
138
- assert_nil PaperTrail.serializer.load(@old_article.object)["file_upload"]
139
- end
140
-
141
- should "have kept the non-skipped attributes in the previous version" do
142
- assert_equal "Some text here.", PaperTrail.serializer.load(@old_article.object)["content"]
143
- end
144
- end
145
- end
146
-
147
- context "which gets destroyed" do
148
- setup { @article.destroy }
149
- should "change the number of versions" do assert_equal(2, PaperTrail::Version.count) end
150
-
151
- should "show the new version in the model's `versions` association" do
152
- assert_equal(2, @article.versions.size)
153
- end
154
- end
155
- end
156
-
157
- context "A record with defined 'ignore' attribute" do
158
- setup { @legacy_widget = LegacyWidget.create }
159
-
160
- context "which updates an ignored column" do
161
- setup { @legacy_widget.update_attributes version: 1 }
162
- should "not change the number of versions" do assert_equal(1, PaperTrail::Version.count) end
163
- end
164
- end
165
-
166
- context 'A record with defined "if" and "unless" attributes' do
167
- setup { @translation = Translation.new headline: "Headline" }
168
-
169
- context "for non-US translations" do
170
- setup { @translation.save }
171
- should "not change the number of versions" do assert_equal(0, PaperTrail::Version.count) end
172
-
173
- context "after update" do
174
- setup { @translation.update_attributes content: "Content" }
175
- should "not change the number of versions" do assert_equal(0, PaperTrail::Version.count) end
176
- end
177
-
178
- context "after destroy" do
179
- setup { @translation.destroy }
180
- should "not change the number of versions" do assert_equal(0, PaperTrail::Version.count) end
181
- end
182
- end
183
-
184
- context "for US translations" do
185
- setup { @translation.language_code = "US" }
186
-
187
- context "that are drafts" do
188
- setup do
189
- @translation.type = "DRAFT"
190
- @translation.save
191
- end
192
-
193
- should "not change the number of versions" do
194
- assert_equal(0, PaperTrail::Version.count)
195
- end
196
-
197
- context "after update" do
198
- setup { @translation.update_attributes content: "Content" }
199
- should "not change the number of versions" do
200
- assert_equal(0, PaperTrail::Version.count)
201
- end
202
- end
203
- end
204
-
205
- context "that are not drafts" do
206
- setup { @translation.save }
207
-
208
- should "change the number of versions" do
209
- assert_equal(1, PaperTrail::Version.count)
210
- end
211
-
212
- context "after update" do
213
- setup { @translation.update_attributes content: "Content" }
214
- should "change the number of versions" do
215
- assert_equal(2, PaperTrail::Version.count)
216
- end
217
-
218
- should "show the new version in the model's `versions` association" do
219
- assert_equal(2, @translation.versions.size)
220
- end
221
- end
222
-
223
- context "after destroy" do
224
- setup { @translation.destroy }
225
- should "change the number of versions" do
226
- assert_equal(2, PaperTrail::Version.count)
227
- end
228
-
229
- should "show the new version in the model's `versions` association" do
230
- assert_equal(2, @translation.versions.size)
231
- end
232
- end
233
- end
234
- end
235
- end
236
-
237
- context "A new record" do
238
- setup { @widget = Widget.new }
239
-
240
- should "not have any previous versions" do
241
- assert_equal [], @widget.versions
242
- end
243
-
244
- should "be live" do
245
- assert @widget.paper_trail.live?
246
- end
247
-
248
- context "which is then created" do
249
- setup { @widget.update_attributes name: "Henry", created_at: Time.now - 1.day }
250
-
251
- should "have one previous version" do
252
- assert_equal 1, @widget.versions.length
253
- end
254
-
255
- should "be nil in its previous version" do
256
- assert_nil @widget.versions.first.object
257
- assert_nil @widget.versions.first.reify
258
- end
259
-
260
- should "record the correct event" do
261
- assert_match(/create/i, @widget.versions.first.event)
262
- end
263
-
264
- should "be live" do
265
- assert @widget.paper_trail.live?
266
- end
267
-
268
- should "use the widget `updated_at` as the version's `created_at`" do
269
- assert_equal @widget.updated_at.to_i, @widget.versions.first.created_at.to_i
270
- end
271
-
272
- should "have changes" do
273
- # TODO: Postgres does not appear to pass back
274
- # ActiveSupport::TimeWithZone, so choosing the lowest common denominator
275
- # to test.
276
-
277
- changes = {
278
- "name" => [nil, "Henry"],
279
- "created_at" => [nil, @widget.created_at.to_time.utc],
280
- "updated_at" => [nil, @widget.updated_at.to_time.utc],
281
- "id" => [nil, @widget.id]
282
- }
283
-
284
- assert_kind_of Time, @widget.versions.last.changeset["updated_at"][1]
285
- assert_changes_equal changes, @widget.versions.last.changeset
286
- end
287
-
288
- context "and then updated without any changes" do
289
- setup { @widget.touch }
290
-
291
- should "not have a new version" do
292
- assert_equal 1, @widget.versions.length
293
- end
294
- end
295
-
296
- context "and then updated with changes" do
297
- setup { @widget.update_attributes name: "Harry" }
298
-
299
- should "have two previous versions" do
300
- assert_equal 2, @widget.versions.length
301
- end
302
-
303
- should "be available in its previous version" do
304
- assert_equal "Harry", @widget.name
305
- assert_not_nil @widget.versions.last.object
306
- widget = @widget.versions.last.reify
307
- assert_equal "Henry", widget.name
308
- assert_equal "Harry", @widget.name
309
- end
310
-
311
- should "have the same ID in its previous version" do
312
- assert_equal @widget.id, @widget.versions.last.reify.id
313
- end
314
-
315
- should "record the correct event" do
316
- assert_match(/update/i, @widget.versions.last.event)
317
- end
318
-
319
- should "have versions that are not live" do
320
- assert(@widget.versions.map(&:reify).compact.all? { |w| !w.paper_trail.live? })
321
- end
322
-
323
- should "have stored changes" do
324
- # Behavior for ActiveRecord 4 is different than ActiveRecord 3;
325
- # AR4 includes the `updated_at` column in changes for updates, which
326
- # is why we reject it from the right side of this assertion.
327
- last_obj_changes = @widget.versions.last.object_changes
328
- actual = PaperTrail.serializer.load(last_obj_changes).reject { |k, _v|
329
- k.to_sym == :updated_at
330
- }
331
- assert_equal ({ "name" => %w(Henry Harry) }), actual
332
- actual = @widget.versions.last.changeset.reject { |k, _v|
333
- k.to_sym == :updated_at
334
- }
335
- assert_equal ({ "name" => %w(Henry Harry) }), actual
336
- end
337
-
338
- should "return changes with indifferent access" do
339
- assert_equal %w(Henry Harry), @widget.versions.last.changeset[:name]
340
- assert_equal %w(Henry Harry), @widget.versions.last.changeset["name"]
341
- end
342
-
343
- context "and has one associated object" do
344
- setup do
345
- @wotsit = @widget.create_wotsit name: "John"
346
- end
347
-
348
- should "not copy the has_one association by default when reifying" do
349
- reified_widget = @widget.versions.last.reify
350
- # association hasn't been affected by reifying
351
- assert_equal @wotsit, reified_widget.wotsit
352
- # confirm that the association is correct
353
- assert_equal @wotsit, @widget.reload.wotsit
354
- end
355
-
356
- should "copy the has_one association when reifying with :has_one => true" do
357
- reified_widget = @widget.versions.last.reify(has_one: true)
358
- # wotsit wasn't there at the last version
359
- assert_nil reified_widget.wotsit
360
- # wotsit should still exist on live object
361
- assert_equal @wotsit, @widget.reload.wotsit
362
- end
363
- end
364
-
365
- context "and has many associated objects" do
366
- setup do
367
- @f0 = @widget.fluxors.create name: "f-zero"
368
- @f1 = @widget.fluxors.create name: "f-one"
369
- @reified_widget = @widget.versions.last.reify
370
- end
371
-
372
- should "copy the has_many associations when reifying" do
373
- assert_equal @widget.fluxors.length, @reified_widget.fluxors.length
374
- assert_same_elements @widget.fluxors, @reified_widget.fluxors
375
-
376
- assert_equal @widget.versions.length, @reified_widget.versions.length
377
- assert_same_elements @widget.versions, @reified_widget.versions
378
- end
379
- end
380
-
381
- context "and has many associated polymorphic objects" do
382
- setup do
383
- @f0 = @widget.whatchamajiggers.create name: "f-zero"
384
- @f1 = @widget.whatchamajiggers.create name: "f-zero"
385
- @reified_widget = @widget.versions.last.reify
386
- end
387
-
388
- should "copy the has_many associations when reifying" do
389
- assert_equal @widget.whatchamajiggers.length, @reified_widget.whatchamajiggers.length
390
- assert_same_elements @widget.whatchamajiggers, @reified_widget.whatchamajiggers
391
-
392
- assert_equal @widget.versions.length, @reified_widget.versions.length
393
- assert_same_elements @widget.versions, @reified_widget.versions
394
- end
395
- end
396
-
397
- context "polymorphic objects by themselves" do
398
- setup do
399
- @widget = Whatchamajigger.new name: "f-zero"
400
- end
401
-
402
- should "not fail with a nil pointer on the polymorphic association" do
403
- @widget.save!
404
- end
405
- end
406
-
407
- context "and then destroyed" do
408
- setup do
409
- @fluxor = @widget.fluxors.create name: "flux"
410
- @widget.destroy
411
- @reified_widget = PaperTrail::Version.last.reify
412
- end
413
-
414
- should "record the correct event" do
415
- assert_match(/destroy/i, PaperTrail::Version.last.event)
416
- end
417
-
418
- should "have three previous versions" do
419
- assert_equal 3, PaperTrail::Version.with_item_keys("Widget", @widget.id).length
420
- end
421
-
422
- should "be available in its previous version" do
423
- assert_equal @widget.id, @reified_widget.id
424
- assert_attributes_equal @widget.attributes, @reified_widget.attributes
425
- end
426
-
427
- should "be re-creatable from its previous version" do
428
- assert @reified_widget.save
429
- end
430
-
431
- should "restore its associations on its previous version" do
432
- @reified_widget.save
433
- assert_equal 1, @reified_widget.fluxors.length
434
- end
435
-
436
- should "have nil item for last version" do
437
- assert_nil(@widget.versions.last.item)
438
- end
439
-
440
- should "not have changes" do
441
- assert_equal({}, @widget.versions.last.changeset)
442
- end
443
- end
444
- end
445
- end
446
- end
447
-
448
- # Test the serialisation and deserialisation.
449
- # TODO: binary
450
- context "A record's papertrail" do
451
- setup do
452
- @date_time = DateTime.now.utc
453
- @time = Time.now
454
- @date = Date.new 2009, 5, 29
455
- @widget = Widget.create(
456
- name: "Warble",
457
- a_text: "The quick brown fox",
458
- an_integer: 42,
459
- a_float: 153.01,
460
- a_decimal: 2.71828,
461
- a_datetime: @date_time,
462
- a_time: @time,
463
- a_date: @date,
464
- a_boolean: true
465
- )
466
- @widget.update_attributes(
467
- name: nil,
468
- a_text: nil,
469
- an_integer: nil,
470
- a_float: nil,
471
- a_decimal: nil,
472
- a_datetime: nil,
473
- a_time: nil,
474
- a_date: nil,
475
- a_boolean: false
476
- )
477
- @previous = @widget.versions.last.reify
478
- end
479
-
480
- should "handle strings" do
481
- assert_equal "Warble", @previous.name
482
- end
483
-
484
- should "handle text" do
485
- assert_equal "The quick brown fox", @previous.a_text
486
- end
487
-
488
- should "handle integers" do
489
- assert_equal 42, @previous.an_integer
490
- end
491
-
492
- should "handle floats" do
493
- assert_in_delta 153.01, @previous.a_float, 0.001
494
- end
495
-
496
- should "handle decimals" do
497
- assert_in_delta 2.7183, @previous.a_decimal, 0.0001
498
- end
499
-
500
- should "handle datetimes" do
501
- assert_equal @date_time.to_time.utc.to_i, @previous.a_datetime.to_time.utc.to_i
502
- end
503
-
504
- should "handle times" do
505
- assert_equal @time.utc.to_i, @previous.a_time.utc.to_i
506
- end
507
-
508
- should "handle dates" do
509
- assert_equal @date, @previous.a_date
510
- end
511
-
512
- should "handle booleans" do
513
- assert @previous.a_boolean
514
- end
515
-
516
- context "after a column is removed from the record's schema" do
517
- setup do
518
- @last = @widget.versions.last
519
- end
520
-
521
- should "reify previous version" do
522
- assert_kind_of Widget, @last.reify
523
- end
524
-
525
- should "restore all forward-compatible attributes" do
526
- assert_equal "Warble", @last.reify.name
527
- assert_equal "The quick brown fox", @last.reify.a_text
528
- assert_equal 42, @last.reify.an_integer
529
- assert_in_delta 153.01, @last.reify.a_float, 0.001
530
- assert_in_delta 2.7183, @last.reify.a_decimal, 0.0001
531
- assert_equal @date_time.to_time.utc.to_i, @last.reify.a_datetime.to_time.utc.to_i
532
- assert_equal @time.utc.to_i, @last.reify.a_time.utc.to_i
533
- assert_equal @date, @last.reify.a_date
534
- assert @last.reify.a_boolean
535
- end
536
- end
537
- end
538
-
539
- context "A record" do
540
- setup { @widget = Widget.create name: "Zaphod" }
541
-
542
- context "with PaperTrail globally disabled" do
543
- setup do
544
- PaperTrail.enabled = false
545
- @count = @widget.versions.length
546
- end
547
-
548
- teardown { PaperTrail.enabled = true }
549
-
550
- context "when updated" do
551
- setup { @widget.update_attributes name: "Beeblebrox" }
552
-
553
- should "not add to its trail" do
554
- assert_equal @count, @widget.versions.length
555
- end
556
- end
557
- end
558
-
559
- context "with its paper trail turned off" do
560
- setup do
561
- Widget.paper_trail.disable
562
- @count = @widget.versions.length
563
- end
564
-
565
- teardown { Widget.paper_trail.enable }
566
-
567
- context "when updated" do
568
- setup { @widget.update_attributes name: "Beeblebrox" }
569
-
570
- should "not add to its trail" do
571
- assert_equal @count, @widget.versions.length
572
- end
573
- end
574
-
575
- context 'when destroyed "without versioning"' do
576
- should "leave paper trail off after call" do
577
- @widget.paper_trail.without_versioning :destroy
578
- assert_equal false, Widget.paper_trail.enabled?
579
- end
580
- end
581
-
582
- context "and then its paper trail turned on" do
583
- setup { Widget.paper_trail.enable }
584
-
585
- context "when updated" do
586
- setup { @widget.update_attributes name: "Ford" }
587
-
588
- should "add to its trail" do
589
- assert_equal @count + 1, @widget.versions.length
590
- end
591
- end
592
-
593
- context 'when updated "without versioning"' do
594
- setup do
595
- @widget.paper_trail.without_versioning do
596
- @widget.update_attributes name: "Ford"
597
- end
598
- # The model instance should yield itself for convenience purposes
599
- @widget.paper_trail.without_versioning { |w| w.update_attributes name: "Nixon" }
600
- end
601
-
602
- should "not create new version" do
603
- assert_equal @count, @widget.versions.length
604
- end
605
-
606
- should "enable paper trail after call" do
607
- assert Widget.paper_trail.enabled?
608
- end
609
- end
610
-
611
- context "when receiving a method name as an argument" do
612
- setup { @widget.paper_trail.without_versioning(:touch_with_version) }
613
-
614
- should "not create new version" do
615
- assert_equal @count, @widget.versions.length
616
- end
617
-
618
- should "enable paper trail after call" do
619
- assert Widget.paper_trail.enabled?
620
- end
621
- end
622
- end
623
- end
624
- end
625
-
626
- context "A papertrail with somebody making changes" do
627
- setup do
628
- @widget = Widget.new name: "Fidget"
629
- end
630
-
631
- context "when a record is created" do
632
- setup do
633
- PaperTrail.whodunnit = "Alice"
634
- @widget.save
635
- @version = @widget.versions.last # only 1 version
636
- end
637
-
638
- should "track who made the change" do
639
- assert_equal "Alice", @version.whodunnit
640
- assert_nil @version.paper_trail_originator
641
- assert_equal "Alice", @version.terminator
642
- assert_equal "Alice", @widget.paper_trail.originator
643
- end
644
-
645
- context "when a record is updated" do
646
- setup do
647
- PaperTrail.whodunnit = "Bob"
648
- @widget.update_attributes name: "Rivet"
649
- @version = @widget.versions.last
650
- end
651
-
652
- should "track who made the change" do
653
- assert_equal "Bob", @version.whodunnit
654
- assert_equal "Alice", @version.paper_trail_originator
655
- assert_equal "Bob", @version.terminator
656
- assert_equal "Bob", @widget.paper_trail.originator
657
- end
658
-
659
- context "when a record is destroyed" do
660
- setup do
661
- PaperTrail.whodunnit = "Charlie"
662
- @widget.destroy
663
- @version = PaperTrail::Version.last
664
- end
665
-
666
- should "track who made the change" do
667
- assert_equal "Charlie", @version.whodunnit
668
- assert_equal "Bob", @version.paper_trail_originator
669
- assert_equal "Charlie", @version.terminator
670
- assert_equal "Charlie", @widget.paper_trail.originator
671
- end
672
- end
673
- end
674
- end
675
- end
676
-
677
- test "update_attributes! records timestamps" do
678
- wotsit = Wotsit.create! name: "wotsit"
679
- wotsit.update_attributes! name: "changed"
680
- reified = wotsit.versions.last.reify
681
- assert_not_nil reified.created_at
682
- assert_not_nil reified.updated_at
683
- end
684
-
685
- # Tests that it doesn't try to write created_on as an attribute just because
686
- # a created_on method exists.
687
- #
688
- # - ActiveModel::MissingAttributeError in Rails 4
689
- #
690
- test "update_attributes! does not raise error" do
691
- wotsit = Wotsit.create! name: "name1"
692
- assert_nothing_raised { wotsit.update_attributes! name: "name2" }
693
- end
694
-
695
- context "A subclass" do
696
- setup do
697
- @foo = FooWidget.create
698
- @foo.update_attributes! name: "Foo"
699
- end
700
-
701
- should "reify with the correct type" do
702
- # For some reason this test appears to be broken on AR4 in the test env.
703
- # Executing it manually in the Rails console seems to work.. not sure what
704
- # the issues is here.
705
- assert_kind_of FooWidget, @foo.versions.last.reify if ActiveRecord::VERSION::MAJOR < 4
706
- assert_equal @foo.versions.first, PaperTrail::Version.last.previous
707
- assert_nil PaperTrail::Version.last.next
708
- end
709
-
710
- should "should return the correct originator" do
711
- PaperTrail.whodunnit = "Ben"
712
- @foo.update_attribute(:name, "Geoffrey")
713
- assert_equal PaperTrail.whodunnit, @foo.paper_trail.originator
714
- end
715
-
716
- context "when destroyed" do
717
- setup { @foo.destroy }
718
-
719
- should "reify with the correct type" do
720
- assert_kind_of FooWidget, @foo.versions.last.reify
721
- assert_equal @foo.versions[1], PaperTrail::Version.last.previous
722
- assert_nil PaperTrail::Version.last.next
723
- end
724
- end
725
- end
726
-
727
- context "An item with versions" do
728
- setup do
729
- @widget = Widget.create name: "Widget"
730
- @widget.update_attributes name: "Fidget"
731
- @widget.update_attributes name: "Digit"
732
- end
733
-
734
- context "which were created over time" do
735
- setup do
736
- @created = 2.days.ago
737
- @first_update = 1.day.ago
738
- @second_update = 1.hour.ago
739
- @widget.versions[0].update_attributes created_at: @created
740
- @widget.versions[1].update_attributes created_at: @first_update
741
- @widget.versions[2].update_attributes created_at: @second_update
742
- @widget.update_attribute :updated_at, @second_update
743
- end
744
-
745
- should "return nil for version_at before it was created" do
746
- assert_nil @widget.paper_trail.version_at(@created - 1)
747
- end
748
-
749
- should "return how it looked when created for version_at its creation" do
750
- assert_equal "Widget", @widget.paper_trail.version_at(@created).name
751
- end
752
-
753
- should "return how it looked before its first update" do
754
- assert_equal "Widget", @widget.paper_trail.version_at(@first_update - 1).name
755
- end
756
-
757
- should "return how it looked after its first update" do
758
- assert_equal "Fidget", @widget.paper_trail.version_at(@first_update).name
759
- end
760
-
761
- should "return how it looked before its second update" do
762
- assert_equal "Fidget", @widget.paper_trail.version_at(@second_update - 1).name
763
- end
764
-
765
- should "return how it looked after its second update" do
766
- assert_equal "Digit", @widget.paper_trail.version_at(@second_update).name
767
- end
768
-
769
- should "return the current object for version_at after latest update" do
770
- assert_equal "Digit", @widget.paper_trail.version_at(1.day.from_now).name
771
- end
772
-
773
- context "passing in a string representation of a timestamp" do
774
- should "still return a widget when appropriate" do
775
- # need to add 1 second onto the timestamps before casting to a string,
776
- # since casting a Time to a string drops the microseconds
777
- assert_equal "Widget",
778
- @widget.paper_trail.version_at((@created + 1.second).to_s).name
779
- assert_equal "Fidget",
780
- @widget.paper_trail.version_at((@first_update + 1.second).to_s).name
781
- assert_equal "Digit",
782
- @widget.paper_trail.version_at((@second_update + 1.second).to_s).name
783
- end
784
- end
785
- end
786
-
787
- context ".versions_between" do
788
- setup do
789
- @created = 30.days.ago
790
- @first_update = 15.days.ago
791
- @second_update = 1.day.ago
792
- @widget.versions[0].update_attributes created_at: @created
793
- @widget.versions[1].update_attributes created_at: @first_update
794
- @widget.versions[2].update_attributes created_at: @second_update
795
- @widget.update_attribute :updated_at, @second_update
796
- end
797
-
798
- should "return versions in the time period" do
799
- assert_equal ["Fidget"],
800
- @widget.paper_trail.versions_between(20.days.ago, 10.days.ago).map(&:name)
801
- assert_equal %w(Widget Fidget),
802
- @widget.paper_trail.versions_between(45.days.ago, 10.days.ago).map(&:name)
803
- assert_equal %w(Fidget Digit Digit),
804
- @widget.paper_trail.versions_between(16.days.ago, 1.minute.ago).map(&:name)
805
- assert_equal [],
806
- @widget.paper_trail.versions_between(60.days.ago, 45.days.ago).map(&:name)
807
- end
808
- end
809
-
810
- context "on the first version" do
811
- setup { @version = @widget.versions.first }
812
-
813
- should "have a nil previous version" do
814
- assert_nil @version.previous
815
- end
816
-
817
- should "return the next version" do
818
- assert_equal @widget.versions[1], @version.next
819
- end
820
-
821
- should "return the correct index" do
822
- assert_equal 0, @version.index
823
- end
824
- end
825
-
826
- context "on the last version" do
827
- setup { @version = @widget.versions.last }
828
-
829
- should "return the previous version" do
830
- assert_equal @widget.versions[@widget.versions.length - 2], @version.previous
831
- end
832
-
833
- should "have a nil next version" do
834
- assert_nil @version.next
835
- end
836
-
837
- should "return the correct index" do
838
- assert_equal @widget.versions.length - 1, @version.index
839
- end
840
- end
841
- end
842
-
843
- context "An item" do
844
- setup do
845
- @initial_title = "Foobar"
846
- @article = Article.new title: @initial_title
847
- end
848
-
849
- context "which is created" do
850
- setup { @article.save }
851
-
852
- should "store fixed meta data" do
853
- assert_equal 42, @article.versions.last.answer
854
- end
855
-
856
- should "store dynamic meta data which is independent of the item" do
857
- assert_equal "31 + 11 = 42", @article.versions.last.question
858
- end
859
-
860
- should "store dynamic meta data which depends on the item" do
861
- assert_equal @article.id, @article.versions.last.article_id
862
- end
863
-
864
- should "store dynamic meta data based on a method of the item" do
865
- assert_equal @article.action_data_provider_method, @article.versions.last.action
866
- end
867
-
868
- should "store dynamic meta data based on an attribute of the item at creation" do
869
- assert_equal @initial_title, @article.versions.last.title
870
- end
871
-
872
- context "and updated" do
873
- setup do
874
- @article.update_attributes! content: "Better text.", title: "Rhubarb"
875
- end
876
-
877
- should "store fixed meta data" do
878
- assert_equal 42, @article.versions.last.answer
879
- end
880
-
881
- should "store dynamic meta data which is independent of the item" do
882
- assert_equal "31 + 11 = 42", @article.versions.last.question
883
- end
884
-
885
- should "store dynamic meta data which depends on the item" do
886
- assert_equal @article.id, @article.versions.last.article_id
887
- end
888
-
889
- should "store dynamic meta data based on an attribute of the item prior to the update" do
890
- assert_equal @initial_title, @article.versions.last.title
891
- end
892
- end
893
-
894
- context "and destroyed" do
895
- setup { @article.destroy }
896
-
897
- should "store fixed metadata" do
898
- assert_equal 42, @article.versions.last.answer
899
- end
900
-
901
- should "store dynamic metadata which is independent of the item" do
902
- assert_equal "31 + 11 = 42", @article.versions.last.question
903
- end
904
-
905
- should "store dynamic metadata which depends on the item" do
906
- assert_equal @article.id, @article.versions.last.article_id
907
- end
908
-
909
- should "store dynamic metadata based on attribute of item prior to destruction" do
910
- assert_equal @initial_title, @article.versions.last.title
911
- end
912
- end
913
- end
914
- end
915
-
916
- context "A reified item" do
917
- setup do
918
- widget = Widget.create name: "Bob"
919
- %w(Tom Dick Jane).each { |name| widget.update_attributes name: name }
920
- @version = widget.versions.last
921
- @widget = @version.reify
922
- end
923
-
924
- should "know which version it came from" do
925
- assert_equal @version, @widget.version
926
- end
927
-
928
- should "return its previous self" do
929
- assert_equal @widget.versions[-2].reify,
930
- @widget.paper_trail.previous_version
931
- end
932
- end
933
-
934
- context "A non-reified item" do
935
- setup { @widget = Widget.new }
936
-
937
- should "not have a previous version" do
938
- assert_nil @widget.paper_trail.previous_version
939
- end
940
-
941
- should "not have a next version" do
942
- assert_nil @widget.paper_trail.next_version
943
- end
944
-
945
- context "with versions" do
946
- setup do
947
- @widget.save
948
- %w(Tom Dick Jane).each { |name| @widget.update_attributes name: name }
949
- end
950
-
951
- should "have a previous version" do
952
- assert_equal @widget.versions.last.reify.name,
953
- @widget.paper_trail.previous_version.name
954
- end
955
-
956
- should "not have a next version" do
957
- assert_nil @widget.paper_trail.next_version
958
- end
959
- end
960
- end
961
-
962
- context "A reified item" do
963
- setup do
964
- @widget = Widget.create name: "Bob"
965
- %w(Tom Dick Jane).each { |name| @widget.update_attributes name: name }
966
- @second_widget = @widget.versions[1].reify # first widget is `nil`
967
- @last_widget = @widget.versions.last.reify
968
- end
969
-
970
- should "have a previous version" do
971
- # `create` events return `nil` for `reify`
972
- assert_nil @second_widget.paper_trail.previous_version
973
- assert_equal @widget.versions[-2].reify.name,
974
- @last_widget.paper_trail.previous_version.name
975
- end
976
-
977
- should "have a next version" do
978
- assert_equal @widget.versions[2].reify.name, @second_widget.paper_trail.next_version.name
979
- assert_equal @last_widget.paper_trail.next_version.name, @widget.name
980
- end
981
- end
982
-
983
- context ":has_many :through" do
984
- setup do
985
- @book = Book.create title: "War and Peace"
986
- @dostoyevsky = Person.create name: "Dostoyevsky"
987
- @solzhenitsyn = Person.create name: "Solzhenitsyn"
988
- end
989
-
990
- should "store version on source <<" do
991
- count = PaperTrail::Version.count
992
- @book.authors << @dostoyevsky
993
- assert_equal 1, PaperTrail::Version.count - count
994
- assert_equal PaperTrail::Version.last, @book.authorships.first.versions.first
995
- end
996
-
997
- should "store version on source create" do
998
- count = PaperTrail::Version.count
999
- @book.authors.create name: "Tolstoy"
1000
- assert_equal 2, PaperTrail::Version.count - count
1001
- actual = [
1002
- PaperTrail::Version.order(:id).to_a[-2].item,
1003
- PaperTrail::Version.last.item
1004
- ]
1005
- assert_same_elements [Person.last, Authorship.last], actual
1006
- end
1007
-
1008
- should "store version on join destroy" do
1009
- @book.authors << @dostoyevsky
1010
- count = PaperTrail::Version.count
1011
- @book.authorships.reload.last.destroy
1012
- assert_equal 1, PaperTrail::Version.count - count
1013
- assert_equal @book, PaperTrail::Version.last.reify.book
1014
- assert_equal @dostoyevsky, PaperTrail::Version.last.reify.author
1015
- end
1016
-
1017
- should "store version on join clear" do
1018
- @book.authors << @dostoyevsky
1019
- count = PaperTrail::Version.count
1020
- @book.authorships.reload.destroy_all
1021
- assert_equal 1, PaperTrail::Version.count - count
1022
- assert_equal @book, PaperTrail::Version.last.reify.book
1023
- assert_equal @dostoyevsky, PaperTrail::Version.last.reify.author
1024
- end
1025
- end
1026
-
1027
- context "When an attribute has a custom serializer" do
1028
- setup do
1029
- @person = Person.new(time_zone: "Samoa")
1030
- end
1031
-
1032
- should "be an instance of ActiveSupport::TimeZone" do
1033
- assert_equal ActiveSupport::TimeZone, @person.time_zone.class
1034
- end
1035
-
1036
- context "when the model is saved" do
1037
- setup do
1038
- @changes_before_save = @person.changes.dup
1039
- @person.save!
1040
- end
1041
-
1042
- # Test for serialization:
1043
- should "version.object_changes should store long serialization of TimeZone object" do
1044
- len = @person.versions.last.object_changes.length
1045
- assert len < 105, "object_changes length was #{len}"
1046
- end
1047
-
1048
- # It should store the serialized value.
1049
- should "version.object_changes attribute should have stored the value from serializer" do
1050
- as_stored_in_version = HashWithIndifferentAccess[
1051
- YAML.load(@person.versions.last.object_changes)
1052
- ]
1053
- assert_equal [nil, "Samoa"], as_stored_in_version[:time_zone]
1054
- serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
1055
- assert_equal serialized_value, as_stored_in_version[:time_zone].last
1056
- end
1057
-
1058
- # Tests for unserialization:
1059
- should "version.changeset should convert attribute to original, unserialized value" do
1060
- unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
1061
- assert_equal unserialized_value,
1062
- @person.versions.last.changeset[:time_zone].last
1063
- end
1064
-
1065
- should "record.changes (before save) returns the original, unserialized values" do
1066
- assert_equal [NilClass, ActiveSupport::TimeZone],
1067
- @changes_before_save[:time_zone].map(&:class)
1068
- end
1069
-
1070
- should "version.changeset should be the same as record.changes was before the save" do
1071
- actual = @person.versions.last.changeset.delete_if { |k, _v| k.to_sym == :id }
1072
- assert_equal @changes_before_save, actual
1073
- actual = @person.versions.last.changeset[:time_zone].map(&:class)
1074
- assert_equal [NilClass, ActiveSupport::TimeZone], actual
1075
- end
1076
-
1077
- context "when that attribute is updated" do
1078
- setup do
1079
- @attribute_value_before_change = @person.time_zone
1080
- @person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
1081
- @changes_before_save = @person.changes.dup
1082
- @person.save!
1083
- end
1084
-
1085
- # Tests for serialization
1086
- # -----------------------
1087
- #
1088
- # Before the serialized attributes fix, the object/object_changes value
1089
- # that was stored was ridiculously long (58723).
1090
- #
1091
- # version.object should not have stored the default, ridiculously long
1092
- # (to_yaml) serialization of the TimeZone object.
1093
- should "object should not store long serialization of TimeZone object" do
1094
- len = @person.versions.last.object.length
1095
- assert len < 105, "object length was #{len}"
1096
- end
1097
-
1098
- # Need an additional clause to detect what version of ActiveRecord is
1099
- # being used for this test because AR4 injects the `updated_at` column
1100
- # into the changeset for updates to models.
1101
- #
1102
- # version.object_changes should not have stored the default,
1103
- # ridiculously long (to_yaml) serialization of the TimeZone object
1104
- should "object_changes should not store long serialization of TimeZone object" do
1105
- max_len = ActiveRecord::VERSION::MAJOR < 4 ? 105 : 118
1106
- len = @person.versions.last.object_changes.length
1107
- assert len < max_len, "object_changes length was #{len}"
1108
- end
1109
-
1110
- # But now it stores the short, serialized value.
1111
- should "version.object attribute should have stored value from serializer" do
1112
- as_stored_in_version = HashWithIndifferentAccess[
1113
- YAML.load(@person.versions.last.object)
1114
- ]
1115
- assert_equal "Samoa", as_stored_in_version[:time_zone]
1116
- serialized_value = Person::TimeZoneSerializer.dump(@attribute_value_before_change)
1117
- assert_equal serialized_value, as_stored_in_version[:time_zone]
1118
- end
1119
-
1120
- should "version.object_changes attribute should have stored value from serializer" do
1121
- as_stored_in_version = HashWithIndifferentAccess[
1122
- YAML.load(@person.versions.last.object_changes)
1123
- ]
1124
- assert_equal ["Samoa", "Pacific Time (US & Canada)"], as_stored_in_version[:time_zone]
1125
- serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
1126
- assert_equal serialized_value, as_stored_in_version[:time_zone].last
1127
- end
1128
-
1129
- # Tests for unserialization:
1130
- should "version.reify should convert attribute to original, unserialized value" do
1131
- unserialized_value = Person::TimeZoneSerializer.load(@attribute_value_before_change)
1132
- assert_equal unserialized_value,
1133
- @person.versions.last.reify.time_zone
1134
- end
1135
-
1136
- should "version.changeset should convert attribute to original, unserialized value" do
1137
- unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
1138
- assert_equal unserialized_value,
1139
- @person.versions.last.changeset[:time_zone].last
1140
- end
1141
-
1142
- should "record.changes (before save) returns the original, unserialized values" do
1143
- assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone],
1144
- @changes_before_save[:time_zone].map(&:class)
1145
- end
1146
-
1147
- should "version.changeset should be the same as record.changes was before the save" do
1148
- assert_equal @changes_before_save, @person.versions.last.changeset
1149
- assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone],
1150
- @person.versions.last.changeset[:time_zone].map(&:class)
1151
- end
1152
- end
1153
- end
1154
- end
1155
-
1156
- context "A new model instance which uses a custom PaperTrail::Version class" do
1157
- setup { @post = Post.new }
1158
-
1159
- context "which is then saved" do
1160
- setup { @post.save }
1161
- should "change the number of post versions" do assert_equal 1, PostVersion.count end
1162
- should "not change the number of versions" do assert_equal(0, PaperTrail::Version.count) end
1163
- end
1164
- end
1165
-
1166
- context "An existing model instance which uses a custom PaperTrail::Version class" do
1167
- setup { @post = Post.create }
1168
- should "have one post version" do assert_equal(1, PostVersion.count) end
1169
-
1170
- context "on the first version" do
1171
- setup { @version = @post.versions.first }
1172
-
1173
- should "have the correct index" do
1174
- assert_equal 0, @version.index
1175
- end
1176
- end
1177
-
1178
- should "have versions of the custom class" do
1179
- assert_equal "PostVersion", @post.versions.first.class.name
1180
- end
1181
-
1182
- context "which is modified" do
1183
- setup do
1184
- @post.update_attributes(content: "Some new content")
1185
- end
1186
-
1187
- should "change the number of post versions" do
1188
- assert_equal(2, PostVersion.count)
1189
- end
1190
-
1191
- should "not change the number of versions" do
1192
- assert_equal(0, PaperTrail::Version.count)
1193
- end
1194
-
1195
- should "not have stored changes when object_changes column doesn't exist" do
1196
- assert_nil @post.versions.last.changeset
1197
- end
1198
- end
1199
- end
1200
-
1201
- context "An overwritten default accessor" do
1202
- setup do
1203
- @song = Song.create length: 4
1204
- @song.update_attributes length: 5
1205
- end
1206
-
1207
- should 'return "overwritten" value on live instance' do
1208
- assert_equal 5, @song.length
1209
- end
1210
- should 'return "overwritten" value on reified instance' do
1211
- assert_equal 4, @song.versions.last.reify.length
1212
- end
1213
-
1214
- context "Has a virtual attribute injected into the ActiveModel::Dirty changes" do
1215
- setup do
1216
- @song.name = "Good Vibrations"
1217
- @song.save
1218
- @song.name = "Yellow Submarine"
1219
- end
1220
-
1221
- should "return persist the changes on the live instance properly" do
1222
- assert_equal "Yellow Submarine", @song.name
1223
- end
1224
- should 'return "overwritten" virtual attribute on the reified instance' do
1225
- assert_equal "Good Vibrations", @song.versions.last.reify.name
1226
- end
1227
- end
1228
- end
1229
-
1230
- context "An unsaved record" do
1231
- setup do
1232
- @widget = Widget.new
1233
- @widget.destroy
1234
- end
1235
- should "not have a version created on destroy" do
1236
- assert @widget.versions.empty?
1237
- end
1238
- end
1239
-
1240
- context "A model with a custom association" do
1241
- setup do
1242
- @doc = Document.create
1243
- @doc.update_attributes name: "Doc 1"
1244
- end
1245
-
1246
- should "not respond to versions method" do
1247
- assert !@doc.respond_to?(:versions)
1248
- end
1249
-
1250
- should "create a new version record" do
1251
- assert_equal 2, @doc.paper_trail_versions.length
1252
- end
1253
-
1254
- should "respond to `next_version` as normal" do
1255
- reified = @doc.paper_trail_versions.last.reify
1256
- assert_equal reified.paper_trail.next_version.name, @doc.name
1257
- end
1258
-
1259
- should "respond to `previous_version` as normal" do
1260
- @doc.update_attributes name: "Doc 2"
1261
- assert_equal 3, @doc.paper_trail_versions.length
1262
- assert_equal "Doc 1", @doc.paper_trail.previous_version.name
1263
- end
1264
- end
1265
-
1266
- context "The `on` option" do
1267
- context "on create" do
1268
- should "only have a version for the create event" do
1269
- record = ::On::Create.create(name: "Alice")
1270
- record.update_attributes name: "blah"
1271
- record.destroy
1272
- assert_equal 1, record.versions.length
1273
- assert_equal "create", record.versions.last.event
1274
- end
1275
- end
1276
-
1277
- context "on update" do
1278
- should "only have a version for the update event" do
1279
- record = ::On::Update.create(name: "Alice")
1280
- record.update_attributes name: "blah"
1281
- record.destroy
1282
- assert_equal 1, record.versions.length
1283
- assert_equal "update", record.versions.last.event
1284
- end
1285
- end
1286
-
1287
- context "on destroy" do
1288
- should "only have a version for the destroy event" do
1289
- record = ::On::Destroy.create(name: "Alice")
1290
- record.update_attributes name: "blah"
1291
- record.destroy
1292
- assert_equal 1, record.versions.length
1293
- assert_equal "destroy", record.versions.last.event
1294
- end
1295
- end
1296
-
1297
- context "on []" do
1298
- setup do
1299
- @record = ::On::EmptyArray.create(name: "Alice")
1300
- @record.update_attributes name: "blah"
1301
- end
1302
-
1303
- teardown do
1304
- @record.destroy
1305
- end
1306
-
1307
- should "not have any versions" do
1308
- assert_equal 0, @record.versions.length
1309
- end
1310
-
1311
- should "still respond to touch_with_version" do
1312
- @record.paper_trail.touch_with_version
1313
- assert_equal 1, @record.versions.length
1314
- end
1315
- end
1316
-
1317
- context "allows a symbol to be passed" do
1318
- should "only have a version for hte create event" do
1319
- record = ::On::Create.create(name: "Alice")
1320
- record.update_attributes name: "blah"
1321
- record.destroy
1322
- assert_equal 1, record.versions.length
1323
- assert_equal "create", record.versions.last.event
1324
- end
1325
- end
1326
- end
1327
-
1328
- context "A model with column version and custom version_method" do
1329
- setup do
1330
- @legacy_widget = LegacyWidget.create(name: "foo", version: 2)
1331
- end
1332
-
1333
- should "set version on create" do
1334
- assert_equal 2, @legacy_widget.version
1335
- end
1336
-
1337
- should "allow version updates" do
1338
- @legacy_widget.update_attributes version: 3
1339
- assert_equal 3, @legacy_widget.version
1340
- end
1341
-
1342
- should "create a new version record" do
1343
- assert_equal 1, @legacy_widget.versions.size
1344
- end
1345
- end
1346
-
1347
- context "A reified item with a column -version- and custom version_method" do
1348
- setup do
1349
- widget = LegacyWidget.create(name: "foo", version: 2)
1350
- %w(bar baz).each { |name| widget.update_attributes name: name }
1351
- @version = widget.versions.last
1352
- @widget = @version.reify
1353
- end
1354
-
1355
- should "know which version it came from" do
1356
- assert_equal @version, @widget.custom_version
1357
- end
1358
-
1359
- should "return its previous self" do
1360
- assert_equal @widget.versions[-2].reify, @widget.paper_trail.previous_version
1361
- end
1362
- end
1363
-
1364
- context "custom events" do
1365
- context "on create" do
1366
- should "only have a version for the created event" do
1367
- record = ::On::Create.new.tap { |model|
1368
- model.paper_trail_event = "created"
1369
- }
1370
- record.update_attributes name: "blah"
1371
- record.destroy
1372
- assert_equal 1, record.versions.length
1373
- assert_equal "created", record.versions.last.event
1374
- end
1375
- end
1376
-
1377
- context "on update" do
1378
- should "only have a version for the name_updated event" do
1379
- record = ::On::Update.create(name: "Alice").tap { |model|
1380
- model.paper_trail_event = "name_updated"
1381
- }
1382
- record.update_attributes name: "blah"
1383
- record.destroy
1384
- assert_equal 1, record.versions.length
1385
- assert_equal "name_updated", record.versions.last.event
1386
- end
1387
- end
1388
-
1389
- context "on destroy" do
1390
- should "only have a version for the destroy event" do
1391
- record = ::On::Destroy.create(name: "Alice").tap { |model|
1392
- model.paper_trail_event = "destroyed"
1393
- }
1394
- record.update_attributes name: "blah"
1395
- record.destroy
1396
- assert_equal 1, record.versions.length
1397
- assert_equal "destroyed", record.versions.last.event
1398
- end
1399
- end
1400
- end
1401
-
1402
- context "`PaperTrail::Config.version_limit` set" do
1403
- setup do
1404
- PaperTrail.config.version_limit = 2
1405
- @widget = Widget.create! name: "Henry"
1406
- 6.times { @widget.update_attribute(:name, FFaker::Lorem.word) }
1407
- end
1408
-
1409
- teardown { PaperTrail.config.version_limit = nil }
1410
-
1411
- should "limit the number of versions to 3 (2 plus the created at event)" do
1412
- assert_equal "create", @widget.versions.first.event
1413
- assert_equal 3, @widget.versions.size
1414
- end
1415
- end
1416
- end