paper_trail 3.0.6 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +1 -2
  4. data/.travis.yml +14 -5
  5. data/CHANGELOG.md +215 -8
  6. data/CONTRIBUTING.md +84 -0
  7. data/README.md +922 -502
  8. data/Rakefile +2 -2
  9. data/doc/bug_report_template.rb +65 -0
  10. data/gemfiles/ar3.gemfile +61 -0
  11. data/lib/generators/paper_trail/install_generator.rb +22 -3
  12. data/lib/generators/paper_trail/templates/add_object_changes_to_versions.rb +6 -1
  13. data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +11 -0
  14. data/lib/generators/paper_trail/templates/create_version_associations.rb +17 -0
  15. data/lib/generators/paper_trail/templates/create_versions.rb +22 -1
  16. data/lib/paper_trail.rb +52 -22
  17. data/lib/paper_trail/attributes_serialization.rb +89 -0
  18. data/lib/paper_trail/cleaner.rb +32 -15
  19. data/lib/paper_trail/config.rb +35 -2
  20. data/lib/paper_trail/frameworks/active_record.rb +4 -5
  21. data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +7 -0
  22. data/lib/paper_trail/frameworks/rails.rb +1 -0
  23. data/lib/paper_trail/frameworks/rails/controller.rb +27 -11
  24. data/lib/paper_trail/frameworks/rspec.rb +5 -0
  25. data/lib/paper_trail/frameworks/sinatra.rb +3 -1
  26. data/lib/paper_trail/has_paper_trail.rb +304 -148
  27. data/lib/paper_trail/record_history.rb +59 -0
  28. data/lib/paper_trail/reifier.rb +270 -0
  29. data/lib/paper_trail/serializers/json.rb +13 -2
  30. data/lib/paper_trail/serializers/yaml.rb +16 -2
  31. data/lib/paper_trail/version_association_concern.rb +15 -0
  32. data/lib/paper_trail/version_concern.rb +160 -122
  33. data/lib/paper_trail/version_number.rb +3 -3
  34. data/paper_trail.gemspec +22 -9
  35. data/spec/generators/install_generator_spec.rb +4 -4
  36. data/spec/models/animal_spec.rb +36 -0
  37. data/spec/models/boolit_spec.rb +48 -0
  38. data/spec/models/callback_modifier_spec.rb +96 -0
  39. data/spec/models/fluxor_spec.rb +19 -0
  40. data/spec/models/gadget_spec.rb +14 -12
  41. data/spec/models/joined_version_spec.rb +9 -9
  42. data/spec/models/json_version_spec.rb +103 -0
  43. data/spec/models/kitchen/banana_spec.rb +14 -0
  44. data/spec/models/not_on_update_spec.rb +19 -0
  45. data/spec/models/post_with_status_spec.rb +3 -3
  46. data/spec/models/skipper_spec.rb +46 -0
  47. data/spec/models/thing_spec.rb +11 -0
  48. data/spec/models/version_spec.rb +195 -44
  49. data/spec/models/widget_spec.rb +136 -76
  50. data/spec/modules/paper_trail_spec.rb +27 -0
  51. data/spec/modules/version_concern_spec.rb +8 -8
  52. data/spec/modules/version_number_spec.rb +16 -16
  53. data/spec/paper_trail/config_spec.rb +52 -0
  54. data/spec/paper_trail_spec.rb +17 -17
  55. data/spec/rails_helper.rb +34 -0
  56. data/spec/requests/articles_spec.rb +10 -14
  57. data/spec/spec_helper.rb +81 -34
  58. data/spec/support/alt_db_init.rb +1 -1
  59. data/test/dummy/app/controllers/application_controller.rb +1 -1
  60. data/test/dummy/app/controllers/articles_controller.rb +4 -1
  61. data/test/dummy/app/models/animal.rb +2 -0
  62. data/test/dummy/app/models/book.rb +4 -0
  63. data/test/dummy/app/models/boolit.rb +4 -0
  64. data/test/dummy/app/models/callback_modifier.rb +45 -0
  65. data/test/dummy/app/models/chapter.rb +9 -0
  66. data/test/dummy/app/models/citation.rb +5 -0
  67. data/test/dummy/app/models/customer.rb +4 -0
  68. data/test/dummy/app/models/editor.rb +4 -0
  69. data/test/dummy/app/models/editorship.rb +5 -0
  70. data/test/dummy/app/models/fruit.rb +5 -0
  71. data/test/dummy/app/models/kitchen/banana.rb +5 -0
  72. data/test/dummy/app/models/line_item.rb +4 -0
  73. data/test/dummy/app/models/not_on_update.rb +4 -0
  74. data/test/dummy/app/models/order.rb +5 -0
  75. data/test/dummy/app/models/paragraph.rb +5 -0
  76. data/test/dummy/app/models/person.rb +13 -3
  77. data/test/dummy/app/models/post.rb +0 -1
  78. data/test/dummy/app/models/quotation.rb +5 -0
  79. data/test/dummy/app/models/section.rb +6 -0
  80. data/test/dummy/app/models/skipper.rb +6 -0
  81. data/test/dummy/app/models/song.rb +20 -0
  82. data/test/dummy/app/models/thing.rb +3 -0
  83. data/test/dummy/app/models/whatchamajigger.rb +4 -0
  84. data/test/dummy/app/models/widget.rb +5 -0
  85. data/test/dummy/app/versions/json_version.rb +3 -0
  86. data/test/dummy/app/versions/kitchen/banana_version.rb +5 -0
  87. data/test/dummy/config/application.rb +6 -0
  88. data/test/dummy/config/database.postgres.yml +1 -1
  89. data/test/dummy/config/environments/test.rb +5 -1
  90. data/test/dummy/config/initializers/paper_trail.rb +6 -1
  91. data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +143 -3
  92. data/test/dummy/db/schema.rb +169 -25
  93. data/test/functional/controller_test.rb +4 -2
  94. data/test/functional/modular_sinatra_test.rb +1 -1
  95. data/test/functional/sinatra_test.rb +1 -1
  96. data/test/paper_trail_test.rb +7 -0
  97. data/test/test_helper.rb +38 -2
  98. data/test/time_travel_helper.rb +15 -0
  99. data/test/unit/associations_test.rb +726 -0
  100. data/test/unit/inheritance_column_test.rb +6 -6
  101. data/test/unit/model_test.rb +109 -125
  102. data/test/unit/protected_attrs_test.rb +4 -3
  103. data/test/unit/serializer_test.rb +6 -6
  104. data/test/unit/serializers/json_test.rb +17 -4
  105. data/test/unit/serializers/yaml_test.rb +5 -1
  106. data/test/unit/version_test.rb +87 -69
  107. metadata +172 -75
  108. data/gemfiles/3.0.gemfile +0 -42
  109. data/test/dummy/public/404.html +0 -26
  110. data/test/dummy/public/422.html +0 -26
  111. data/test/dummy/public/500.html +0 -26
  112. data/test/dummy/public/favicon.ico +0 -0
  113. data/test/dummy/public/javascripts/application.js +0 -2
  114. data/test/dummy/public/javascripts/controls.js +0 -965
  115. data/test/dummy/public/javascripts/dragdrop.js +0 -974
  116. data/test/dummy/public/javascripts/effects.js +0 -1123
  117. data/test/dummy/public/javascripts/prototype.js +0 -6001
  118. data/test/dummy/public/javascripts/rails.js +0 -175
  119. data/test/dummy/public/stylesheets/.gitkeep +0 -0
@@ -1,7 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class InheritanceColumnTest < ActiveSupport::TestCase
4
-
5
4
  context 'STI models' do
6
5
  setup do
7
6
  @animal = Animal.create :name => 'Animal'
@@ -28,16 +27,17 @@ class InheritanceColumnTest < ActiveSupport::TestCase
28
27
 
29
28
  # For some reason `@dog.versions` doesn't include the final `destroy` version.
30
29
  # Neither do `@dog.versions.scoped` nor `@dog.versions(true)` nor `@dog.versions.reload`.
31
- dog_versions = PaperTrail::Version.where(:item_id => @dog.id)
30
+ dog_versions = PaperTrail::Version.where(:item_id => @dog.id).
31
+ order(PaperTrail.timestamp_field)
32
32
  assert_equal 4, dog_versions.count
33
33
  assert_nil dog_versions.first.reify
34
- dog_versions[1..-1].each { |v| assert_equal 'Dog', v.reify.class.name }
34
+ assert_equal %w[NilClass Dog Dog Dog], dog_versions.map { |v| v.reify.class.name }
35
35
 
36
- cat_versions = PaperTrail::Version.where(:item_id => @cat.id)
36
+ cat_versions = PaperTrail::Version.where(:item_id => @cat.id).
37
+ order(PaperTrail.timestamp_field)
37
38
  assert_equal 4, cat_versions.count
38
39
  assert_nil cat_versions.first.reify
39
- cat_versions[1..-1].each { |v| assert_equal 'Cat', v.reify.class.name }
40
+ assert_equal %w[NilClass Cat Cat Cat], cat_versions.map { |v| v.reify.class.name }
40
41
  end
41
42
  end
42
-
43
43
  end
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'time_travel_helper'
2
3
 
3
4
  class HasPaperTrailModelTest < ActiveSupport::TestCase
4
5
 
@@ -191,9 +192,8 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
191
192
  assert @widget.live?
192
193
  end
193
194
 
194
-
195
195
  context 'which is then created' do
196
- setup { @widget.update_attributes :name => 'Henry' }
196
+ setup { @widget.update_attributes :name => 'Henry', :created_at => Time.now - 1.day }
197
197
 
198
198
  should 'have one previous version' do
199
199
  assert_equal 1, @widget.versions.length
@@ -212,10 +212,14 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
212
212
  assert @widget.live?
213
213
  end
214
214
 
215
+ should "use the widget `updated_at` as the version's `created_at`" do
216
+ assert_equal @widget.updated_at.to_i, @widget.versions.first.created_at.to_i
217
+ end
218
+
215
219
  should 'have changes' do
216
220
 
217
- #TODO Postgres does not appear to pass back ActiveSupport::TimeWithZone,
218
- # so chosing the lowest common denominator to test.
221
+ #TODO Postgres does not appear to pass back ActiveSupport::TimeWithZone,
222
+ # so chosing the lowest common denominator to test.
219
223
 
220
224
  changes = {
221
225
  'name' => [nil, 'Henry'],
@@ -224,8 +228,8 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
224
228
  'id' => [nil, @widget.id]
225
229
  }
226
230
 
227
- assert_equal Time, @widget.versions.last.changeset['updated_at'][1].class
228
- assert_equal changes, @widget.versions.last.changeset
231
+ assert_kind_of Time, @widget.versions.last.changeset['updated_at'][1]
232
+ assert_changes_equal changes, @widget.versions.last.changeset
229
233
  end
230
234
 
231
235
  context 'and then updated without any changes' do
@@ -301,13 +305,13 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
301
305
  should 'not copy the has_one association by default when reifying' do
302
306
  reified_widget = @widget.versions.last.reify
303
307
  assert_equal @wotsit, reified_widget.wotsit # association hasn't been affected by reifying
304
- assert_equal @wotsit, @widget.wotsit # confirm that the association is correct
308
+ assert_equal @wotsit, @widget.wotsit(true) # confirm that the association is correct
305
309
  end
306
310
 
307
311
  should 'copy the has_one association when reifying with :has_one => true' do
308
312
  reified_widget = @widget.versions.last.reify(:has_one => true)
309
313
  assert_nil reified_widget.wotsit # wotsit wasn't there at the last version
310
- assert_equal @wotsit, @widget.wotsit # wotsit came into being on the live object
314
+ assert_equal @wotsit, @widget.wotsit(true) # wotsit should still exist on live object
311
315
  end
312
316
  end
313
317
 
@@ -328,6 +332,31 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
328
332
  end
329
333
  end
330
334
 
335
+ context 'and has many associated polymorphic objects' do
336
+ setup do
337
+ @f0 = @widget.whatchamajiggers.create :name => 'f-zero'
338
+ @f1 = @widget.whatchamajiggers.create :name => 'f-zero'
339
+ @reified_widget = @widget.versions.last.reify
340
+ end
341
+
342
+ should 'copy the has_many associations when reifying' do
343
+ assert_equal @widget.whatchamajiggers.length, @reified_widget.whatchamajiggers.length
344
+ assert_same_elements @widget.whatchamajiggers, @reified_widget.whatchamajiggers
345
+
346
+ assert_equal @widget.versions.length, @reified_widget.versions.length
347
+ assert_same_elements @widget.versions, @reified_widget.versions
348
+ end
349
+ end
350
+
351
+ context 'polymorphic objects by themselves' do
352
+ setup do
353
+ @widget = Whatchamajigger.new :name => 'f-zero'
354
+ end
355
+
356
+ should 'not fail with a nil pointer on the polymorphic association' do
357
+ @widget.save!
358
+ end
359
+ end
331
360
 
332
361
  context 'and then destroyed' do
333
362
  setup do
@@ -346,7 +375,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
346
375
 
347
376
  should 'be available in its previous version' do
348
377
  assert_equal @widget.id, @reified_widget.id
349
- assert_equal @widget.attributes, @reified_widget.attributes
378
+ assert_attributes_equal @widget.attributes, @reified_widget.attributes
350
379
  end
351
380
 
352
381
  should 'be re-creatable from its previous version' do
@@ -413,7 +442,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
413
442
  end
414
443
 
415
444
  should 'handle decimals' do
416
- assert_in_delta 2.71828, @previous.a_decimal, 0.00001
445
+ assert_in_delta 2.7183, @previous.a_decimal, 0.0001
417
446
  end
418
447
 
419
448
  should 'handle datetimes' do
@@ -442,7 +471,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
442
471
  @last = @widget.versions.last
443
472
  end
444
473
 
445
- teardown do
474
+ teardown do
446
475
  restore_schema
447
476
  end
448
477
 
@@ -455,7 +484,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
455
484
  assert_equal 'The quick brown fox', @last.reify.a_text
456
485
  assert_equal 42, @last.reify.an_integer
457
486
  assert_in_delta 153.01, @last.reify.a_float, 0.001
458
- assert_in_delta 2.71828, @last.reify.a_decimal, 0.00001
487
+ assert_in_delta 2.7183, @last.reify.a_decimal, 0.0001
459
488
  assert_equal @date_time.to_time.utc.to_i, @last.reify.a_datetime.to_time.utc.to_i
460
489
  assert_equal @time.utc.to_i, @last.reify.a_time.utc.to_i
461
490
  assert_equal @date, @last.reify.a_date
@@ -567,9 +596,9 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
567
596
 
568
597
  should 'track who made the change' do
569
598
  assert_equal 'Alice', @version.whodunnit
570
- assert_nil @version.originator
599
+ assert_nil @version.paper_trail_originator
571
600
  assert_equal 'Alice', @version.terminator
572
- assert_equal 'Alice', @widget.originator
601
+ assert_equal 'Alice', @widget.paper_trail_originator
573
602
  end
574
603
 
575
604
  context 'when a record is updated' do
@@ -581,9 +610,9 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
581
610
 
582
611
  should 'track who made the change' do
583
612
  assert_equal 'Bob', @version.whodunnit
584
- assert_equal 'Alice', @version.originator
613
+ assert_equal 'Alice', @version.paper_trail_originator
585
614
  assert_equal 'Bob', @version.terminator
586
- assert_equal 'Bob', @widget.originator
615
+ assert_equal 'Bob', @widget.paper_trail_originator
587
616
  end
588
617
 
589
618
  context 'when a record is destroyed' do
@@ -595,9 +624,9 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
595
624
 
596
625
  should 'track who made the change' do
597
626
  assert_equal 'Charlie', @version.whodunnit
598
- assert_equal 'Bob', @version.originator
627
+ assert_equal 'Bob', @version.paper_trail_originator
599
628
  assert_equal 'Charlie', @version.terminator
600
- assert_equal 'Charlie', @widget.originator
629
+ assert_equal 'Charlie', @widget.paper_trail_originator
601
630
  end
602
631
  end
603
632
  end
@@ -646,7 +675,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
646
675
  should 'should return the correct originator' do
647
676
  PaperTrail.whodunnit = 'Ben'
648
677
  @foo.update_attribute(:name, 'Geoffrey')
649
- assert_equal PaperTrail.whodunnit, @foo.originator
678
+ assert_equal PaperTrail.whodunnit, @foo.paper_trail_originator
650
679
  end
651
680
 
652
681
  context 'when destroyed' do
@@ -731,7 +760,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
731
760
  should 'return versions in the time period' do
732
761
  assert_equal ['Fidget'], @widget.versions_between(20.days.ago, 10.days.ago).map(&:name)
733
762
  assert_equal ['Widget', 'Fidget'], @widget.versions_between(45.days.ago, 10.days.ago).map(&:name)
734
- assert_equal ['Fidget', 'Digit'], @widget.versions_between(16.days.ago, 1.minute.ago).map(&:name)
763
+ assert_equal ['Fidget', 'Digit', 'Digit'], @widget.versions_between(16.days.ago, 1.minute.ago).map(&:name)
735
764
  assert_equal [], @widget.versions_between(60.days.ago, 45.days.ago).map(&:name)
736
765
  end
737
766
  end
@@ -795,8 +824,8 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
795
824
  assert_equal @article.action_data_provider_method, @article.versions.last.action
796
825
  end
797
826
 
798
- should 'store dynamic meta data based on an attribute of the item prior to creation' do
799
- assert_equal nil, @article.versions.last.title
827
+ should 'store dynamic meta data based on an attribute of the item at creation' do
828
+ assert_equal @initial_title, @article.versions.last.title
800
829
  end
801
830
 
802
831
 
@@ -927,7 +956,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
927
956
  count = PaperTrail::Version.count
928
957
  @book.authors.create :name => 'Tolstoy'
929
958
  assert_equal 2, PaperTrail::Version.count - count
930
- assert_same_elements [Person.last, Authorship.last], [PaperTrail::Version.all[-2].item, PaperTrail::Version.last.item]
959
+ assert_same_elements [Person.last, Authorship.last], [PaperTrail::Version.order(:id).to_a[-2].item, PaperTrail::Version.last.item]
931
960
  end
932
961
 
933
962
  should 'store version on join destroy' do
@@ -949,90 +978,10 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
949
978
  end
950
979
  end
951
980
 
952
-
953
- context 'A model with a has_one association' do
954
- setup { @widget = Widget.create :name => 'widget_0' }
955
-
956
- context 'before the associated was created' do
957
- setup do
958
- @widget.update_attributes :name => 'widget_1'
959
- @wotsit = @widget.create_wotsit :name => 'wotsit_0'
960
- end
961
-
962
- context 'when reified' do
963
- setup { @widget_0 = @widget.versions.last.reify(:has_one => 1) }
964
-
965
- should 'see the associated as it was at the time' do
966
- assert_nil @widget_0.wotsit
967
- end
968
- end
969
- end
970
-
971
- context 'where the association is created between model versions' do
972
- setup do
973
- @wotsit = @widget.create_wotsit :name => 'wotsit_0'
974
- make_last_version_earlier @wotsit
975
-
976
- @widget.update_attributes :name => 'widget_1'
977
- end
978
-
979
- context 'when reified' do
980
- setup { @widget_0 = @widget.versions.last.reify(:has_one => 1) }
981
-
982
- should 'see the associated as it was at the time' do
983
- assert_equal 'wotsit_0', @widget_0.wotsit.name
984
- end
985
- end
986
-
987
- context 'and then the associated is updated between model versions' do
988
- setup do
989
- @wotsit.update_attributes :name => 'wotsit_1'
990
- make_last_version_earlier @wotsit
991
- @wotsit.update_attributes :name => 'wotsit_2'
992
- make_last_version_earlier @wotsit
993
-
994
- @widget.update_attributes :name => 'widget_2'
995
- @wotsit.update_attributes :name => 'wotsit_3'
996
- end
997
-
998
- context 'when reified' do
999
- setup { @widget_1 = @widget.versions.last.reify(:has_one => 1) }
1000
-
1001
- should 'see the associated as it was at the time' do
1002
- assert_equal 'wotsit_2', @widget_1.wotsit.name
1003
- end
1004
- end
1005
-
1006
- context 'when reified opting out of has_one reification' do
1007
- setup { @widget_1 = @widget.versions.last.reify(:has_one => false) }
1008
-
1009
- should 'see the associated as it is live' do
1010
- assert_equal 'wotsit_3', @widget_1.wotsit.name
1011
- end
1012
- end
1013
- end
1014
-
1015
- context 'and then the associated is destroyed between model versions' do
1016
- setup do
1017
- @wotsit.destroy
1018
- make_last_version_earlier @wotsit
1019
-
1020
- @widget.update_attributes :name => 'widget_3'
1021
- end
1022
-
1023
- context 'when reified' do
1024
- setup { @widget_2 = @widget.versions.last.reify(:has_one => 1) }
1025
-
1026
- should 'see the associated as it was at the time' do
1027
- assert_nil @widget_2.wotsit
1028
- end
1029
- end
1030
- end
1031
- end
1032
- end
1033
-
1034
981
  context 'When an attribute has a custom serializer' do
1035
- setup { @person = Person.new(:time_zone => "Samoa") }
982
+ setup do
983
+ @person = Person.new(:time_zone => "Samoa")
984
+ end
1036
985
 
1037
986
  should "be an instance of ActiveSupport::TimeZone" do
1038
987
  assert_equal ActiveSupport::TimeZone, @person.time_zone.class
@@ -1052,12 +1001,14 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1052
1001
  should 'version.object_changes attribute should have stored the value returned by the attribute serializer' do
1053
1002
  as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object_changes)]
1054
1003
  assert_equal [nil, 'Samoa'], as_stored_in_version[:time_zone]
1055
- assert_equal @person.instance_variable_get(:@attributes)['time_zone'].serialized_value, as_stored_in_version[:time_zone].last
1004
+ serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
1005
+ assert_equal serialized_value, as_stored_in_version[:time_zone].last
1056
1006
  end
1057
1007
 
1058
1008
  # Tests for unserialization:
1059
1009
  should 'version.changeset should convert the attribute value back to its original, unserialized value' do
1060
- assert_equal @person.instance_variable_get(:@attributes)['time_zone'].unserialized_value, @person.versions.last.changeset[:time_zone].last
1010
+ unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
1011
+ assert_equal unserialized_value, @person.versions.last.changeset[:time_zone].last
1061
1012
  end
1062
1013
  should "record.changes (before save) returns the original, unserialized values" do
1063
1014
  assert_equal [NilClass, ActiveSupport::TimeZone], @changes_before_save[:time_zone].map(&:class)
@@ -1069,7 +1020,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1069
1020
 
1070
1021
  context 'when that attribute is updated' do
1071
1022
  setup do
1072
- @attribute_value_before_change = @person.instance_variable_get(:@attributes)['time_zone']
1023
+ @attribute_value_before_change = @person.time_zone
1073
1024
  @person.assign_attributes({ :time_zone => 'Pacific Time (US & Canada)' })
1074
1025
  @changes_before_save = @person.changes.dup
1075
1026
  @person.save!
@@ -1078,7 +1029,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1078
1029
  # Tests for serialization:
1079
1030
  # Before the serialized attributes fix, the object/object_changes value that was stored was ridiculously long (58723).
1080
1031
  should 'version.object should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
1081
- assert @person.versions.last.object. length < 105, "object length was #{@person.versions.last.object .length}"
1032
+ assert @person.versions.last.object.length < 105, "object length was #{@person.versions.last.object.length}"
1082
1033
  end
1083
1034
  # Need an additional clause to detect what version of ActiveRecord is being used for this test because AR4 injects the `updated_at` column into the changeset for updates to models
1084
1035
  should 'version.object_changes should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
@@ -1088,20 +1039,24 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1088
1039
  should 'version.object attribute should have stored the value returned by the attribute serializer' do
1089
1040
  as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object)]
1090
1041
  assert_equal 'Samoa', as_stored_in_version[:time_zone]
1091
- assert_equal @attribute_value_before_change.serialized_value, as_stored_in_version[:time_zone]
1042
+ serialized_value = Person::TimeZoneSerializer.dump(@attribute_value_before_change)
1043
+ assert_equal serialized_value, as_stored_in_version[:time_zone]
1092
1044
  end
1093
1045
  should 'version.object_changes attribute should have stored the value returned by the attribute serializer' do
1094
1046
  as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object_changes)]
1095
1047
  assert_equal ['Samoa', 'Pacific Time (US & Canada)'], as_stored_in_version[:time_zone]
1096
- assert_equal @person.instance_variable_get(:@attributes)['time_zone'].serialized_value, as_stored_in_version[:time_zone].last
1048
+ serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
1049
+ assert_equal serialized_value, as_stored_in_version[:time_zone].last
1097
1050
  end
1098
1051
 
1099
1052
  # Tests for unserialization:
1100
1053
  should 'version.reify should convert the attribute value back to its original, unserialized value' do
1101
- assert_equal @attribute_value_before_change.unserialized_value, @person.versions.last.reify.time_zone
1054
+ unserialized_value = Person::TimeZoneSerializer.load(@attribute_value_before_change)
1055
+ assert_equal unserialized_value, @person.versions.last.reify.time_zone
1102
1056
  end
1103
1057
  should 'version.changeset should convert the attribute value back to its original, unserialized value' do
1104
- assert_equal @person.instance_variable_get(:@attributes)['time_zone'].unserialized_value, @person.versions.last.changeset[:time_zone].last
1058
+ unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
1059
+ assert_equal unserialized_value, @person.versions.last.changeset[:time_zone].last
1105
1060
  end
1106
1061
  should "record.changes (before save) returns the original, unserialized values" do
1107
1062
  assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone], @changes_before_save[:time_zone].map(&:class)
@@ -1165,6 +1120,21 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1165
1120
  should 'return "overwritten" value on reified instance' do
1166
1121
  assert_equal 4, @song.versions.last.reify.length
1167
1122
  end
1123
+
1124
+ context 'Has a virtual attribute injected into the ActiveModel::Dirty changes' do
1125
+ setup do
1126
+ @song.name = 'Good Vibrations'
1127
+ @song.save
1128
+ @song.name = 'Yellow Submarine'
1129
+ end
1130
+
1131
+ should 'return persist the changes on the live instance properly' do
1132
+ assert_equal 'Yellow Submarine', @song.name
1133
+ end
1134
+ should 'return "overwritten" virtual attribute on the reified instance' do
1135
+ assert_equal 'Good Vibrations', @song.versions.last.reify.name
1136
+ end
1137
+ end
1168
1138
  end
1169
1139
 
1170
1140
 
@@ -1252,6 +1222,31 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1252
1222
  assert_equal 'destroy', @fluxor.versions.last.event
1253
1223
  end
1254
1224
  end
1225
+ context 'on []' do
1226
+ setup do
1227
+ Fluxor.reset_callbacks :create
1228
+ Fluxor.reset_callbacks :update
1229
+ Fluxor.reset_callbacks :destroy
1230
+ Fluxor.instance_eval <<-END
1231
+ has_paper_trail :on => []
1232
+ END
1233
+ @fluxor = Fluxor.create
1234
+ @fluxor.update_attributes :name => 'blah'
1235
+ end
1236
+
1237
+ teardown do
1238
+ @fluxor.destroy
1239
+ end
1240
+
1241
+ should 'not have any versions' do
1242
+ assert_equal 0, @fluxor.versions.length
1243
+ end
1244
+
1245
+ should 'still respond to touch_with_version' do
1246
+ @fluxor.touch_with_version
1247
+ assert_equal 1, @fluxor.versions.length
1248
+ end
1249
+ end
1255
1250
  context 'allows a symbol to be passed' do
1256
1251
  setup do
1257
1252
  Fluxor.reset_callbacks :create
@@ -1375,15 +1370,4 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
1375
1370
  assert_equal 3, @widget.versions.size
1376
1371
  end
1377
1372
  end
1378
-
1379
- private
1380
-
1381
- # Updates `model`'s last version so it looks like the version was
1382
- # created 2 seconds ago.
1383
- def make_last_version_earlier(model)
1384
- PaperTrail::Version.record_timestamps = false
1385
- model.versions.last.update_attributes :created_at => 2.seconds.ago
1386
- PaperTrail::Version.record_timestamps = true
1387
- end
1388
-
1389
1373
  end
@@ -35,9 +35,10 @@ class ProtectedAttrsTest < ActiveSupport::TestCase
35
35
  end
36
36
 
37
37
  should 'the previous version should contain right attributes' do
38
- # For some reason this test seems to be broken in JRuby 1.9 mode in the test env even though it works in the console. WTF?
39
- unless ActiveRecord::VERSION::MAJOR >= 4 && defined?(JRUBY_VERSION) && RUBY_VERSION.to_f >= 1.9
40
- assert_equal @widget.previous_version.attributes, @initial_attributes
38
+ # For some reason this test seems to be broken in JRuby 1.9 mode in the
39
+ # test env even though it works in the console. WTF?
40
+ unless ActiveRecord::VERSION::MAJOR >= 4 && defined?(JRUBY_VERSION) && RUBY_VERSION >= '1.9'
41
+ assert_attributes_equal @widget.previous_version.attributes, @initial_attributes
41
42
  end
42
43
  end
43
44
  end