paper_trail 4.0.2 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +27 -0
- data/CONTRIBUTING.md +78 -5
- data/README.md +328 -268
- data/doc/bug_report_template.rb +65 -0
- data/gemfiles/3.0.gemfile +7 -4
- data/lib/generators/paper_trail/templates/add_object_changes_to_versions.rb +1 -1
- data/lib/generators/paper_trail/templates/create_versions.rb +14 -0
- data/lib/paper_trail.rb +11 -9
- data/lib/paper_trail/attributes_serialization.rb +89 -0
- data/lib/paper_trail/cleaner.rb +8 -1
- data/lib/paper_trail/config.rb +15 -18
- data/lib/paper_trail/frameworks/rails/controller.rb +16 -2
- data/lib/paper_trail/has_paper_trail.rb +102 -99
- data/lib/paper_trail/record_history.rb +59 -0
- data/lib/paper_trail/reifier.rb +270 -0
- data/lib/paper_trail/version_association_concern.rb +3 -1
- data/lib/paper_trail/version_concern.rb +60 -226
- data/lib/paper_trail/version_number.rb +2 -2
- data/paper_trail.gemspec +7 -10
- data/spec/models/animal_spec.rb +17 -0
- data/spec/models/callback_modifier_spec.rb +96 -0
- data/spec/models/json_version_spec.rb +20 -17
- data/spec/paper_trail/config_spec.rb +52 -0
- data/spec/spec_helper.rb +6 -0
- data/test/dummy/app/models/callback_modifier.rb +45 -0
- data/test/dummy/app/models/chapter.rb +9 -0
- data/test/dummy/app/models/citation.rb +5 -0
- data/test/dummy/app/models/paragraph.rb +5 -0
- data/test/dummy/app/models/quotation.rb +5 -0
- data/test/dummy/app/models/section.rb +6 -0
- data/test/dummy/config/database.postgres.yml +1 -1
- data/test/dummy/config/initializers/paper_trail.rb +3 -1
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +33 -0
- data/test/dummy/db/schema.rb +27 -0
- data/test/test_helper.rb +36 -0
- data/test/unit/associations_test.rb +726 -0
- data/test/unit/inheritance_column_test.rb +6 -6
- data/test/unit/model_test.rb +62 -594
- data/test/unit/protected_attrs_test.rb +3 -2
- data/test/unit/version_test.rb +87 -69
- metadata +38 -2
@@ -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
|
-
|
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
|
-
|
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
|
data/test/unit/model_test.rb
CHANGED
@@ -228,8 +228,8 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
228
228
|
'id' => [nil, @widget.id]
|
229
229
|
}
|
230
230
|
|
231
|
-
|
232
|
-
|
231
|
+
assert_kind_of Time, @widget.versions.last.changeset['updated_at'][1]
|
232
|
+
assert_changes_equal changes, @widget.versions.last.changeset
|
233
233
|
end
|
234
234
|
|
235
235
|
context 'and then updated without any changes' do
|
@@ -375,7 +375,7 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
375
375
|
|
376
376
|
should 'be available in its previous version' do
|
377
377
|
assert_equal @widget.id, @reified_widget.id
|
378
|
-
|
378
|
+
assert_attributes_equal @widget.attributes, @reified_widget.attributes
|
379
379
|
end
|
380
380
|
|
381
381
|
should 'be re-creatable from its previous version' do
|
@@ -978,100 +978,94 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
978
978
|
end
|
979
979
|
end
|
980
980
|
|
981
|
-
|
982
|
-
|
983
|
-
|
981
|
+
context 'When an attribute has a custom serializer' do
|
982
|
+
setup do
|
983
|
+
@person = Person.new(:time_zone => "Samoa")
|
984
|
+
end
|
985
|
+
|
986
|
+
should "be an instance of ActiveSupport::TimeZone" do
|
987
|
+
assert_equal ActiveSupport::TimeZone, @person.time_zone.class
|
988
|
+
end
|
989
|
+
|
990
|
+
context 'when the model is saved' do
|
984
991
|
setup do
|
985
|
-
|
986
|
-
@person
|
992
|
+
@changes_before_save = @person.changes.dup
|
993
|
+
@person.save!
|
987
994
|
end
|
988
995
|
|
989
|
-
|
996
|
+
# Test for serialization:
|
997
|
+
should 'version.object_changes should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
|
998
|
+
assert @person.versions.last.object_changes.length < 105, "object_changes length was #{@person.versions.last.object_changes.length}"
|
999
|
+
end
|
1000
|
+
# It should store the serialized value.
|
1001
|
+
should 'version.object_changes attribute should have stored the value returned by the attribute serializer' do
|
1002
|
+
as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object_changes)]
|
1003
|
+
assert_equal [nil, 'Samoa'], as_stored_in_version[:time_zone]
|
1004
|
+
serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
|
1005
|
+
assert_equal serialized_value, as_stored_in_version[:time_zone].last
|
1006
|
+
end
|
990
1007
|
|
991
|
-
|
992
|
-
|
1008
|
+
# Tests for unserialization:
|
1009
|
+
should 'version.changeset should convert the attribute value back to its original, unserialized value' do
|
1010
|
+
unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
|
1011
|
+
assert_equal unserialized_value, @person.versions.last.changeset[:time_zone].last
|
1012
|
+
end
|
1013
|
+
should "record.changes (before save) returns the original, unserialized values" do
|
1014
|
+
assert_equal [NilClass, ActiveSupport::TimeZone], @changes_before_save[:time_zone].map(&:class)
|
1015
|
+
end
|
1016
|
+
should 'version.changeset should be the same as record.changes was before the save' do
|
1017
|
+
assert_equal @changes_before_save, @person.versions.last.changeset.delete_if { |key, val| key.to_sym == :id }
|
1018
|
+
assert_equal [NilClass, ActiveSupport::TimeZone], @person.versions.last.changeset[:time_zone].map(&:class)
|
993
1019
|
end
|
994
1020
|
|
995
|
-
context 'when
|
1021
|
+
context 'when that attribute is updated' do
|
996
1022
|
setup do
|
1023
|
+
@attribute_value_before_change = @person.time_zone
|
1024
|
+
@person.assign_attributes({ :time_zone => 'Pacific Time (US & Canada)' })
|
997
1025
|
@changes_before_save = @person.changes.dup
|
998
1026
|
@person.save!
|
999
1027
|
end
|
1000
1028
|
|
1001
|
-
#
|
1029
|
+
# Tests for serialization:
|
1030
|
+
# Before the serialized attributes fix, the object/object_changes value that was stored was ridiculously long (58723).
|
1031
|
+
should 'version.object should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
|
1032
|
+
assert @person.versions.last.object.length < 105, "object length was #{@person.versions.last.object.length}"
|
1033
|
+
end
|
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
|
1002
1035
|
should 'version.object_changes should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
|
1003
|
-
assert @person.versions.last.object_changes.length < 105, "object_changes length was #{@person.versions.last.object_changes.length}"
|
1036
|
+
assert @person.versions.last.object_changes.length < (ActiveRecord::VERSION::MAJOR < 4 ? 105 : 118), "object_changes length was #{@person.versions.last.object_changes.length}"
|
1037
|
+
end
|
1038
|
+
# But now it stores the short, serialized value.
|
1039
|
+
should 'version.object attribute should have stored the value returned by the attribute serializer' do
|
1040
|
+
as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object)]
|
1041
|
+
assert_equal 'Samoa', 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]
|
1004
1044
|
end
|
1005
|
-
# It should store the serialized value.
|
1006
1045
|
should 'version.object_changes attribute should have stored the value returned by the attribute serializer' do
|
1007
1046
|
as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object_changes)]
|
1008
|
-
assert_equal [
|
1047
|
+
assert_equal ['Samoa', 'Pacific Time (US & Canada)'], as_stored_in_version[:time_zone]
|
1009
1048
|
serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
|
1010
1049
|
assert_equal serialized_value, as_stored_in_version[:time_zone].last
|
1011
1050
|
end
|
1012
1051
|
|
1013
1052
|
# Tests for unserialization:
|
1053
|
+
should 'version.reify should convert the attribute value back to its original, unserialized value' do
|
1054
|
+
unserialized_value = Person::TimeZoneSerializer.load(@attribute_value_before_change)
|
1055
|
+
assert_equal unserialized_value, @person.versions.last.reify.time_zone
|
1056
|
+
end
|
1014
1057
|
should 'version.changeset should convert the attribute value back to its original, unserialized value' do
|
1015
1058
|
unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
|
1016
1059
|
assert_equal unserialized_value, @person.versions.last.changeset[:time_zone].last
|
1017
1060
|
end
|
1018
1061
|
should "record.changes (before save) returns the original, unserialized values" do
|
1019
|
-
assert_equal [
|
1062
|
+
assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone], @changes_before_save[:time_zone].map(&:class)
|
1020
1063
|
end
|
1021
1064
|
should 'version.changeset should be the same as record.changes was before the save' do
|
1022
|
-
assert_equal @changes_before_save, @person.versions.last.changeset
|
1023
|
-
assert_equal [
|
1065
|
+
assert_equal @changes_before_save, @person.versions.last.changeset
|
1066
|
+
assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone], @person.versions.last.changeset[:time_zone].map(&:class)
|
1024
1067
|
end
|
1025
1068
|
|
1026
|
-
context 'when that attribute is updated' do
|
1027
|
-
setup do
|
1028
|
-
@attribute_value_before_change = @person.time_zone
|
1029
|
-
@person.assign_attributes({ :time_zone => 'Pacific Time (US & Canada)' })
|
1030
|
-
@changes_before_save = @person.changes.dup
|
1031
|
-
@person.save!
|
1032
|
-
end
|
1033
|
-
|
1034
|
-
# Tests for serialization:
|
1035
|
-
# Before the serialized attributes fix, the object/object_changes value that was stored was ridiculously long (58723).
|
1036
|
-
should 'version.object should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
|
1037
|
-
assert @person.versions.last.object.length < 105, "object length was #{@person.versions.last.object.length}"
|
1038
|
-
end
|
1039
|
-
# 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
|
1040
|
-
should 'version.object_changes should not have stored the default, ridiculously long (to_yaml) serialization of the TimeZone object' do
|
1041
|
-
assert @person.versions.last.object_changes.length < (ActiveRecord::VERSION::MAJOR < 4 ? 105 : 118), "object_changes length was #{@person.versions.last.object_changes.length}"
|
1042
|
-
end
|
1043
|
-
# But now it stores the short, serialized value.
|
1044
|
-
should 'version.object attribute should have stored the value returned by the attribute serializer' do
|
1045
|
-
as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object)]
|
1046
|
-
assert_equal 'Samoa', as_stored_in_version[:time_zone]
|
1047
|
-
serialized_value = Person::TimeZoneSerializer.dump(@attribute_value_before_change)
|
1048
|
-
assert_equal serialized_value, as_stored_in_version[:time_zone]
|
1049
|
-
end
|
1050
|
-
should 'version.object_changes attribute should have stored the value returned by the attribute serializer' do
|
1051
|
-
as_stored_in_version = HashWithIndifferentAccess[YAML::load(@person.versions.last.object_changes)]
|
1052
|
-
assert_equal ['Samoa', 'Pacific Time (US & Canada)'], as_stored_in_version[:time_zone]
|
1053
|
-
serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
|
1054
|
-
assert_equal serialized_value, as_stored_in_version[:time_zone].last
|
1055
|
-
end
|
1056
|
-
|
1057
|
-
# Tests for unserialization:
|
1058
|
-
should 'version.reify should convert the attribute value back to its original, unserialized value' do
|
1059
|
-
unserialized_value = Person::TimeZoneSerializer.load(@attribute_value_before_change)
|
1060
|
-
assert_equal unserialized_value, @person.versions.last.reify.time_zone
|
1061
|
-
end
|
1062
|
-
should 'version.changeset should convert the attribute value back to its original, unserialized value' do
|
1063
|
-
unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
|
1064
|
-
assert_equal unserialized_value, @person.versions.last.changeset[:time_zone].last
|
1065
|
-
end
|
1066
|
-
should "record.changes (before save) returns the original, unserialized values" do
|
1067
|
-
assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone], @changes_before_save[:time_zone].map(&:class)
|
1068
|
-
end
|
1069
|
-
should 'version.changeset should be the same as record.changes was before the save' do
|
1070
|
-
assert_equal @changes_before_save, @person.versions.last.changeset
|
1071
|
-
assert_equal [ActiveSupport::TimeZone, ActiveSupport::TimeZone], @person.versions.last.changeset[:time_zone].map(&:class)
|
1072
|
-
end
|
1073
|
-
|
1074
|
-
end
|
1075
1069
|
end
|
1076
1070
|
end
|
1077
1071
|
end
|
@@ -1377,529 +1371,3 @@ class HasPaperTrailModelTest < ActiveSupport::TestCase
|
|
1377
1371
|
end
|
1378
1372
|
end
|
1379
1373
|
end
|
1380
|
-
|
1381
|
-
|
1382
|
-
class HasPaperTrailModelTransactionalTest < ActiveSupport::TestCase
|
1383
|
-
# These would have been done in test_helper.rb if using_mysql? is true
|
1384
|
-
unless using_mysql?
|
1385
|
-
self.use_transactional_fixtures = false
|
1386
|
-
setup { DatabaseCleaner.start }
|
1387
|
-
end
|
1388
|
-
|
1389
|
-
teardown do
|
1390
|
-
Timecop.return
|
1391
|
-
# This would have been done in test_helper.rb if using_mysql? is true
|
1392
|
-
DatabaseCleaner.clean unless using_mysql?
|
1393
|
-
end
|
1394
|
-
|
1395
|
-
context 'A model with a has_one association' do
|
1396
|
-
setup { @widget = Widget.create :name => 'widget_0' }
|
1397
|
-
|
1398
|
-
context 'before the associated was created' do
|
1399
|
-
setup do
|
1400
|
-
@widget.update_attributes :name => 'widget_1'
|
1401
|
-
@wotsit = @widget.create_wotsit :name => 'wotsit_0'
|
1402
|
-
end
|
1403
|
-
|
1404
|
-
context 'when reified' do
|
1405
|
-
setup { @widget_0 = @widget.versions.last.reify(:has_one => true) }
|
1406
|
-
|
1407
|
-
should 'see the associated as it was at the time' do
|
1408
|
-
assert_nil @widget_0.wotsit
|
1409
|
-
end
|
1410
|
-
|
1411
|
-
should 'not persist changes to the live association' do
|
1412
|
-
assert_equal @wotsit, @widget.wotsit(true)
|
1413
|
-
end
|
1414
|
-
end
|
1415
|
-
end
|
1416
|
-
|
1417
|
-
context 'where the association is created between model versions' do
|
1418
|
-
setup do
|
1419
|
-
@wotsit = @widget.create_wotsit :name => 'wotsit_0'
|
1420
|
-
Timecop.travel 1.second.since
|
1421
|
-
@widget.update_attributes :name => 'widget_1'
|
1422
|
-
end
|
1423
|
-
|
1424
|
-
context 'when reified' do
|
1425
|
-
setup { @widget_0 = @widget.versions.last.reify(:has_one => true) }
|
1426
|
-
|
1427
|
-
should 'see the associated as it was at the time' do
|
1428
|
-
assert_equal 'wotsit_0', @widget_0.wotsit.name
|
1429
|
-
end
|
1430
|
-
|
1431
|
-
should 'not persist changes to the live association' do
|
1432
|
-
assert_equal @wotsit, @widget.wotsit(true)
|
1433
|
-
end
|
1434
|
-
end
|
1435
|
-
|
1436
|
-
context 'and then the associated is updated between model versions' do
|
1437
|
-
setup do
|
1438
|
-
@wotsit.update_attributes :name => 'wotsit_1'
|
1439
|
-
@wotsit.update_attributes :name => 'wotsit_2'
|
1440
|
-
Timecop.travel 1.second.since
|
1441
|
-
@widget.update_attributes :name => 'widget_2'
|
1442
|
-
@wotsit.update_attributes :name => 'wotsit_3'
|
1443
|
-
end
|
1444
|
-
|
1445
|
-
context 'when reified' do
|
1446
|
-
setup { @widget_1 = @widget.versions.last.reify(:has_one => true) }
|
1447
|
-
|
1448
|
-
should 'see the associated as it was at the time' do
|
1449
|
-
assert_equal 'wotsit_2', @widget_1.wotsit.name
|
1450
|
-
end
|
1451
|
-
|
1452
|
-
should 'not persist changes to the live association' do
|
1453
|
-
assert_equal 'wotsit_3', @widget.wotsit(true).name
|
1454
|
-
end
|
1455
|
-
end
|
1456
|
-
|
1457
|
-
context 'when reified opting out of has_one reification' do
|
1458
|
-
setup { @widget_1 = @widget.versions.last.reify(:has_one => false) }
|
1459
|
-
|
1460
|
-
should 'see the associated as it is live' do
|
1461
|
-
assert_equal 'wotsit_3', @widget_1.wotsit.name
|
1462
|
-
end
|
1463
|
-
end
|
1464
|
-
end
|
1465
|
-
|
1466
|
-
context 'and then the associated is destroyed' do
|
1467
|
-
setup do
|
1468
|
-
@wotsit.destroy
|
1469
|
-
end
|
1470
|
-
|
1471
|
-
context 'when reify' do
|
1472
|
-
setup { @widget_1 = @widget.versions.last.reify(:has_one => true) }
|
1473
|
-
|
1474
|
-
should 'see the associated as it was at the time' do
|
1475
|
-
assert_equal @wotsit, @widget_1.wotsit
|
1476
|
-
end
|
1477
|
-
|
1478
|
-
should 'not persist changes to the live association' do
|
1479
|
-
assert_nil @widget.wotsit(true)
|
1480
|
-
end
|
1481
|
-
end
|
1482
|
-
|
1483
|
-
context 'and then the model is updated' do
|
1484
|
-
setup do
|
1485
|
-
Timecop.travel 1.second.since
|
1486
|
-
@widget.update_attributes :name => 'widget_3'
|
1487
|
-
end
|
1488
|
-
|
1489
|
-
context 'when reified' do
|
1490
|
-
setup { @widget_2 = @widget.versions.last.reify(:has_one => true) }
|
1491
|
-
|
1492
|
-
should 'see the associated as it was at the time' do
|
1493
|
-
assert_nil @widget_2.wotsit
|
1494
|
-
end
|
1495
|
-
end
|
1496
|
-
end
|
1497
|
-
end
|
1498
|
-
end
|
1499
|
-
end
|
1500
|
-
|
1501
|
-
context 'A model with a has_many association' do
|
1502
|
-
setup { @customer = Customer.create :name => 'customer_0' }
|
1503
|
-
|
1504
|
-
context 'updated before the associated was created' do
|
1505
|
-
setup do
|
1506
|
-
@customer.update_attributes! :name => 'customer_1'
|
1507
|
-
@customer.orders.create! :order_date => Date.today
|
1508
|
-
end
|
1509
|
-
|
1510
|
-
context 'when reified' do
|
1511
|
-
setup { @customer_0 = @customer.versions.last.reify(:has_many => true) }
|
1512
|
-
|
1513
|
-
should 'see the associated as it was at the time' do
|
1514
|
-
assert_equal [], @customer_0.orders
|
1515
|
-
end
|
1516
|
-
|
1517
|
-
should 'not persist changes to the live association' do
|
1518
|
-
assert_not_equal [], @customer.orders(true)
|
1519
|
-
end
|
1520
|
-
end
|
1521
|
-
|
1522
|
-
context 'when reified with option mark_for_destruction' do
|
1523
|
-
setup { @customer_0 = @customer.versions.last.reify(:has_many => true, :mark_for_destruction => true) }
|
1524
|
-
|
1525
|
-
should 'mark the associated for destruction' do
|
1526
|
-
assert_equal [true], @customer_0.orders.map(&:marked_for_destruction?)
|
1527
|
-
end
|
1528
|
-
end
|
1529
|
-
end
|
1530
|
-
|
1531
|
-
context 'where the association is created between model versions' do
|
1532
|
-
setup do
|
1533
|
-
@order = @customer.orders.create! :order_date => 'order_date_0'
|
1534
|
-
Timecop.travel 1.second.since
|
1535
|
-
@customer.update_attributes :name => 'customer_1'
|
1536
|
-
end
|
1537
|
-
|
1538
|
-
context 'when reified' do
|
1539
|
-
setup { @customer_0 = @customer.versions.last.reify(:has_many => true) }
|
1540
|
-
|
1541
|
-
should 'see the associated as it was at the time' do
|
1542
|
-
assert_equal ['order_date_0'], @customer_0.orders.map(&:order_date)
|
1543
|
-
end
|
1544
|
-
end
|
1545
|
-
|
1546
|
-
context 'and then a nested has_many association is created' do
|
1547
|
-
setup do
|
1548
|
-
@order.line_items.create! :product => 'product_0'
|
1549
|
-
end
|
1550
|
-
|
1551
|
-
context 'when reified' do
|
1552
|
-
setup { @customer_0 = @customer.versions.last.reify(:has_many => true) }
|
1553
|
-
|
1554
|
-
should 'see the live version of the nested association' do
|
1555
|
-
assert_equal ['product_0'], @customer_0.orders.first.line_items.map(&:product)
|
1556
|
-
end
|
1557
|
-
end
|
1558
|
-
end
|
1559
|
-
|
1560
|
-
context 'and then the associated is updated between model versions' do
|
1561
|
-
setup do
|
1562
|
-
@order.update_attributes :order_date => 'order_date_1'
|
1563
|
-
@order.update_attributes :order_date => 'order_date_2'
|
1564
|
-
Timecop.travel 1.second.since
|
1565
|
-
@customer.update_attributes :name => 'customer_2'
|
1566
|
-
@order.update_attributes :order_date => 'order_date_3'
|
1567
|
-
end
|
1568
|
-
|
1569
|
-
context 'when reified' do
|
1570
|
-
setup { @customer_1 = @customer.versions.last.reify(:has_many => true) }
|
1571
|
-
|
1572
|
-
should 'see the associated as it was at the time' do
|
1573
|
-
assert_equal ['order_date_2'], @customer_1.orders.map(&:order_date)
|
1574
|
-
end
|
1575
|
-
|
1576
|
-
should 'not persist changes to the live association' do
|
1577
|
-
assert_equal ['order_date_3'], @customer.orders(true).map(&:order_date)
|
1578
|
-
end
|
1579
|
-
end
|
1580
|
-
|
1581
|
-
context 'when reified opting out of has_many reification' do
|
1582
|
-
setup { @customer_1 = @customer.versions.last.reify(:has_many => false) }
|
1583
|
-
|
1584
|
-
should 'see the associated as it is live' do
|
1585
|
-
assert_equal ['order_date_3'], @customer_1.orders.map(&:order_date)
|
1586
|
-
end
|
1587
|
-
end
|
1588
|
-
|
1589
|
-
context 'and then the associated is destroyed' do
|
1590
|
-
setup do
|
1591
|
-
@order.destroy
|
1592
|
-
end
|
1593
|
-
|
1594
|
-
context 'when reified' do
|
1595
|
-
setup { @customer_1 = @customer.versions.last.reify(:has_many => true) }
|
1596
|
-
|
1597
|
-
should 'see the associated as it was at the time' do
|
1598
|
-
assert_equal ['order_date_2'], @customer_1.orders.map(&:order_date)
|
1599
|
-
end
|
1600
|
-
|
1601
|
-
should 'not persist changes to the live association' do
|
1602
|
-
assert_equal [], @customer.orders(true)
|
1603
|
-
end
|
1604
|
-
end
|
1605
|
-
end
|
1606
|
-
end
|
1607
|
-
|
1608
|
-
context 'and then the associated is destroyed' do
|
1609
|
-
setup do
|
1610
|
-
@order.destroy
|
1611
|
-
end
|
1612
|
-
|
1613
|
-
context 'when reified' do
|
1614
|
-
setup { @customer_1 = @customer.versions.last.reify(:has_many => true) }
|
1615
|
-
|
1616
|
-
should 'see the associated as it was at the time' do
|
1617
|
-
assert_equal [@order.order_date], @customer_1.orders.map(&:order_date)
|
1618
|
-
end
|
1619
|
-
|
1620
|
-
should 'not persist changes to the live association' do
|
1621
|
-
assert_equal [], @customer.orders(true)
|
1622
|
-
end
|
1623
|
-
end
|
1624
|
-
end
|
1625
|
-
|
1626
|
-
context 'and then the associated is destroyed between model versions' do
|
1627
|
-
setup do
|
1628
|
-
@order.destroy
|
1629
|
-
Timecop.travel 1.second.since
|
1630
|
-
@customer.update_attributes :name => 'customer_2'
|
1631
|
-
end
|
1632
|
-
|
1633
|
-
context 'when reified' do
|
1634
|
-
setup { @customer_1 = @customer.versions.last.reify(:has_many => true) }
|
1635
|
-
|
1636
|
-
should 'see the associated as it was at the time' do
|
1637
|
-
assert_equal [], @customer_1.orders
|
1638
|
-
end
|
1639
|
-
end
|
1640
|
-
end
|
1641
|
-
|
1642
|
-
context 'and then another association is added' do
|
1643
|
-
setup do
|
1644
|
-
@customer.orders.create! :order_date => 'order_date_1'
|
1645
|
-
end
|
1646
|
-
|
1647
|
-
context 'when reified' do
|
1648
|
-
setup { @customer_0 = @customer.versions.last.reify(:has_many => true) }
|
1649
|
-
|
1650
|
-
should 'see the associated as it was at the time' do
|
1651
|
-
assert_equal ['order_date_0'], @customer_0.orders.map(&:order_date)
|
1652
|
-
end
|
1653
|
-
|
1654
|
-
should 'not persist changes to the live association' do
|
1655
|
-
assert_equal ['order_date_0', 'order_date_1'], @customer.orders(true).map(&:order_date).sort
|
1656
|
-
end
|
1657
|
-
end
|
1658
|
-
|
1659
|
-
context 'when reified with option mark_for_destruction' do
|
1660
|
-
setup { @customer_0 = @customer.versions.last.reify(:has_many => true, :mark_for_destruction => true) }
|
1661
|
-
|
1662
|
-
should 'mark the newly associated for destruction' do
|
1663
|
-
assert @customer_0.orders.detect { |o| o.order_date == 'order_date_1'}.marked_for_destruction?
|
1664
|
-
end
|
1665
|
-
end
|
1666
|
-
end
|
1667
|
-
end
|
1668
|
-
end
|
1669
|
-
|
1670
|
-
context 'A model with a has_many through association' do
|
1671
|
-
setup { @book = Book.create :title => 'book_0' }
|
1672
|
-
|
1673
|
-
context 'updated before the associated was created' do
|
1674
|
-
setup do
|
1675
|
-
@book.update_attributes! :title => 'book_1'
|
1676
|
-
@book.authors.create! :name => 'author_0'
|
1677
|
-
end
|
1678
|
-
|
1679
|
-
context 'when reified' do
|
1680
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true) }
|
1681
|
-
|
1682
|
-
should 'see the associated as it was at the time' do
|
1683
|
-
assert_equal [], @book_0.authors
|
1684
|
-
end
|
1685
|
-
|
1686
|
-
should 'not persist changes to the live association' do
|
1687
|
-
assert_equal ['author_0'], @book.authors(true).map(&:name)
|
1688
|
-
end
|
1689
|
-
end
|
1690
|
-
|
1691
|
-
context 'when reified with option mark_for_destruction' do
|
1692
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true, :mark_for_destruction => true) }
|
1693
|
-
|
1694
|
-
should 'mark the associated for destruction' do
|
1695
|
-
assert_equal [true], @book_0.authors.map(&:marked_for_destruction?)
|
1696
|
-
end
|
1697
|
-
|
1698
|
-
should 'mark the associated-through for destruction' do
|
1699
|
-
assert_equal [true], @book_0.authorships.map(&:marked_for_destruction?)
|
1700
|
-
end
|
1701
|
-
end
|
1702
|
-
end
|
1703
|
-
|
1704
|
-
context 'updated before it is associated with an existing one' do
|
1705
|
-
setup do
|
1706
|
-
person_existing = Person.create(:name => 'person_existing')
|
1707
|
-
Timecop.travel 1.second.since
|
1708
|
-
@book.update_attributes! :title => 'book_1'
|
1709
|
-
@book.authors << person_existing
|
1710
|
-
end
|
1711
|
-
|
1712
|
-
context 'when reified' do
|
1713
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true) }
|
1714
|
-
|
1715
|
-
should 'see the associated as it was at the time' do
|
1716
|
-
assert_equal [], @book_0.authors
|
1717
|
-
end
|
1718
|
-
end
|
1719
|
-
|
1720
|
-
context 'when reified with option mark_for_destruction' do
|
1721
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true, :mark_for_destruction => true) }
|
1722
|
-
|
1723
|
-
should 'not mark the associated for destruction' do
|
1724
|
-
assert_equal [false], @book_0.authors.map(&:marked_for_destruction?)
|
1725
|
-
end
|
1726
|
-
|
1727
|
-
should 'mark the associated-through for destruction' do
|
1728
|
-
assert_equal [true], @book_0.authorships.map(&:marked_for_destruction?)
|
1729
|
-
end
|
1730
|
-
end
|
1731
|
-
end
|
1732
|
-
|
1733
|
-
context 'where the association is created between model versions' do
|
1734
|
-
setup do
|
1735
|
-
@author = @book.authors.create! :name => 'author_0'
|
1736
|
-
@person_existing = Person.create(:name => 'person_existing')
|
1737
|
-
Timecop.travel 1.second.since
|
1738
|
-
@book.update_attributes! :title => 'book_1'
|
1739
|
-
end
|
1740
|
-
|
1741
|
-
context 'when reified' do
|
1742
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true) }
|
1743
|
-
|
1744
|
-
should 'see the associated as it was at the time' do
|
1745
|
-
assert_equal ['author_0'], @book_0.authors.map(&:name)
|
1746
|
-
end
|
1747
|
-
end
|
1748
|
-
|
1749
|
-
context 'and then the associated is updated between model versions' do
|
1750
|
-
setup do
|
1751
|
-
@author.update_attributes :name => 'author_1'
|
1752
|
-
@author.update_attributes :name => 'author_2'
|
1753
|
-
Timecop.travel 1.second.since
|
1754
|
-
@book.update_attributes :title => 'book_2'
|
1755
|
-
@author.update_attributes :name => 'author_3'
|
1756
|
-
end
|
1757
|
-
|
1758
|
-
context 'when reified' do
|
1759
|
-
setup { @book_1 = @book.versions.last.reify(:has_many => true) }
|
1760
|
-
|
1761
|
-
should 'see the associated as it was at the time' do
|
1762
|
-
assert_equal ['author_2'], @book_1.authors.map(&:name)
|
1763
|
-
end
|
1764
|
-
|
1765
|
-
should 'not persist changes to the live association' do
|
1766
|
-
assert_equal ['author_3'], @book.authors(true).map(&:name)
|
1767
|
-
end
|
1768
|
-
end
|
1769
|
-
|
1770
|
-
context 'when reified opting out of has_many reification' do
|
1771
|
-
setup { @book_1 = @book.versions.last.reify(:has_many => false) }
|
1772
|
-
|
1773
|
-
should 'see the associated as it is live' do
|
1774
|
-
assert_equal ['author_3'], @book_1.authors.map(&:name)
|
1775
|
-
end
|
1776
|
-
end
|
1777
|
-
end
|
1778
|
-
|
1779
|
-
context 'and then the associated is destroyed' do
|
1780
|
-
setup do
|
1781
|
-
@author.destroy
|
1782
|
-
end
|
1783
|
-
|
1784
|
-
context 'when reified' do
|
1785
|
-
setup { @book_1 = @book.versions.last.reify(:has_many => true) }
|
1786
|
-
|
1787
|
-
should 'see the associated as it was at the time' do
|
1788
|
-
assert_equal [@author.name], @book_1.authors.map(&:name)
|
1789
|
-
end
|
1790
|
-
|
1791
|
-
should 'not persist changes to the live association' do
|
1792
|
-
assert_equal [], @book.authors(true)
|
1793
|
-
end
|
1794
|
-
end
|
1795
|
-
end
|
1796
|
-
|
1797
|
-
context 'and then the associated is destroyed between model versions' do
|
1798
|
-
setup do
|
1799
|
-
@author.destroy
|
1800
|
-
Timecop.travel 1.second.since
|
1801
|
-
@book.update_attributes :title => 'book_2'
|
1802
|
-
end
|
1803
|
-
|
1804
|
-
context 'when reified' do
|
1805
|
-
setup { @book_1 = @book.versions.last.reify(:has_many => true) }
|
1806
|
-
|
1807
|
-
should 'see the associated as it was at the time' do
|
1808
|
-
assert_equal [], @book_1.authors
|
1809
|
-
end
|
1810
|
-
end
|
1811
|
-
end
|
1812
|
-
|
1813
|
-
context 'and then the associated is dissociated between model versions' do
|
1814
|
-
setup do
|
1815
|
-
@book.authors = []
|
1816
|
-
Timecop.travel 1.second.since
|
1817
|
-
@book.update_attributes :title => 'book_2'
|
1818
|
-
end
|
1819
|
-
|
1820
|
-
context 'when reified' do
|
1821
|
-
setup { @book_1 = @book.versions.last.reify(:has_many => true) }
|
1822
|
-
|
1823
|
-
should 'see the associated as it was at the time' do
|
1824
|
-
assert_equal [], @book_1.authors
|
1825
|
-
end
|
1826
|
-
end
|
1827
|
-
end
|
1828
|
-
|
1829
|
-
context 'and then another associated is created' do
|
1830
|
-
setup do
|
1831
|
-
@book.authors.create! :name => 'author_1'
|
1832
|
-
end
|
1833
|
-
|
1834
|
-
context 'when reified' do
|
1835
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true) }
|
1836
|
-
|
1837
|
-
should 'only see the first associated' do
|
1838
|
-
assert_equal ['author_0'], @book_0.authors.map(&:name)
|
1839
|
-
end
|
1840
|
-
|
1841
|
-
should 'not persist changes to the live association' do
|
1842
|
-
assert_equal ['author_0', 'author_1'], @book.authors(true).map(&:name)
|
1843
|
-
end
|
1844
|
-
end
|
1845
|
-
|
1846
|
-
context 'when reified with option mark_for_destruction' do
|
1847
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true, :mark_for_destruction => true) }
|
1848
|
-
|
1849
|
-
should 'mark the newly associated for destruction' do
|
1850
|
-
assert @book_0.authors.detect { |a| a.name == 'author_1' }.marked_for_destruction?
|
1851
|
-
end
|
1852
|
-
|
1853
|
-
should 'mark the newly associated-through for destruction' do
|
1854
|
-
assert @book_0.authorships.detect { |as| as.person.name == 'author_1' }.marked_for_destruction?
|
1855
|
-
end
|
1856
|
-
end
|
1857
|
-
end
|
1858
|
-
|
1859
|
-
context 'and then an existing one is associated' do
|
1860
|
-
setup do
|
1861
|
-
@book.authors << @person_existing
|
1862
|
-
end
|
1863
|
-
|
1864
|
-
context 'when reified' do
|
1865
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true) }
|
1866
|
-
|
1867
|
-
should 'only see the first associated' do
|
1868
|
-
assert_equal ['author_0'], @book_0.authors.map(&:name)
|
1869
|
-
end
|
1870
|
-
|
1871
|
-
should 'not persist changes to the live association' do
|
1872
|
-
assert_equal ['author_0', 'person_existing'], @book.authors(true).map(&:name).sort
|
1873
|
-
end
|
1874
|
-
end
|
1875
|
-
|
1876
|
-
context 'when reified with option mark_for_destruction' do
|
1877
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true, :mark_for_destruction => true) }
|
1878
|
-
|
1879
|
-
should 'not mark the newly associated for destruction' do
|
1880
|
-
assert !@book_0.authors.detect { |a| a.name == 'person_existing' }.marked_for_destruction?
|
1881
|
-
end
|
1882
|
-
|
1883
|
-
should 'mark the newly associated-through for destruction' do
|
1884
|
-
assert @book_0.authorships.detect { |as| as.person.name == 'person_existing' }.marked_for_destruction?
|
1885
|
-
end
|
1886
|
-
end
|
1887
|
-
end
|
1888
|
-
end
|
1889
|
-
|
1890
|
-
context 'updated before the associated without paper_trail was created' do
|
1891
|
-
setup do
|
1892
|
-
@book.update_attributes! :title => 'book_1'
|
1893
|
-
@book.editors.create! :name => 'editor_0'
|
1894
|
-
end
|
1895
|
-
|
1896
|
-
context 'when reified' do
|
1897
|
-
setup { @book_0 = @book.versions.last.reify(:has_many => true) }
|
1898
|
-
|
1899
|
-
should 'see the live association' do
|
1900
|
-
assert_equal ['editor_0'], @book_0.editors.map(&:name)
|
1901
|
-
end
|
1902
|
-
end
|
1903
|
-
end
|
1904
|
-
end
|
1905
|
-
end
|