paper_trail 7.0.2 → 7.0.3

Sign up to get free protection for your applications and to get access to all the features.
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