paper_trail 7.1.0 → 7.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/lib/paper_trail/record_trail.rb +1 -1
  3. data/lib/paper_trail/version_number.rb +1 -1
  4. metadata +3 -274
  5. data/.github/CONTRIBUTING.md +0 -151
  6. data/.github/ISSUE_TEMPLATE.md +0 -13
  7. data/.gitignore +0 -23
  8. data/.rspec +0 -2
  9. data/.rubocop.yml +0 -135
  10. data/.rubocop_todo.yml +0 -41
  11. data/.travis.yml +0 -41
  12. data/Appraisals +0 -26
  13. data/CHANGELOG.md +0 -739
  14. data/Gemfile +0 -2
  15. data/MIT-LICENSE +0 -20
  16. data/README.md +0 -1613
  17. data/Rakefile +0 -38
  18. data/doc/bug_report_template.rb +0 -73
  19. data/doc/triage.md +0 -27
  20. data/doc/warning_about_not_setting_whodunnit.md +0 -33
  21. data/gemfiles/ar_4.0.gemfile +0 -7
  22. data/gemfiles/ar_4.2.gemfile +0 -7
  23. data/gemfiles/ar_5.0.gemfile +0 -8
  24. data/gemfiles/ar_5.1.gemfile +0 -8
  25. data/gemfiles/ar_master.gemfile +0 -9
  26. data/lib/generators/paper_trail/default_initializer.rb +0 -0
  27. data/paper_trail.gemspec +0 -49
  28. data/spec/controllers/articles_controller_spec.rb +0 -28
  29. data/spec/controllers/widgets_controller_spec.rb +0 -85
  30. data/spec/dummy_app/Rakefile +0 -7
  31. data/spec/dummy_app/app/controllers/application_controller.rb +0 -30
  32. data/spec/dummy_app/app/controllers/articles_controller.rb +0 -16
  33. data/spec/dummy_app/app/controllers/test_controller.rb +0 -5
  34. data/spec/dummy_app/app/controllers/widgets_controller.rb +0 -28
  35. data/spec/dummy_app/app/models/animal.rb +0 -4
  36. data/spec/dummy_app/app/models/article.rb +0 -25
  37. data/spec/dummy_app/app/models/authorship.rb +0 -5
  38. data/spec/dummy_app/app/models/bar_habtm.rb +0 -4
  39. data/spec/dummy_app/app/models/book.rb +0 -9
  40. data/spec/dummy_app/app/models/boolit.rb +0 -4
  41. data/spec/dummy_app/app/models/callback_modifier.rb +0 -45
  42. data/spec/dummy_app/app/models/car.rb +0 -3
  43. data/spec/dummy_app/app/models/cat.rb +0 -2
  44. data/spec/dummy_app/app/models/chapter.rb +0 -9
  45. data/spec/dummy_app/app/models/citation.rb +0 -5
  46. data/spec/dummy_app/app/models/custom_primary_key_record.rb +0 -15
  47. data/spec/dummy_app/app/models/customer.rb +0 -4
  48. data/spec/dummy_app/app/models/document.rb +0 -8
  49. data/spec/dummy_app/app/models/dog.rb +0 -2
  50. data/spec/dummy_app/app/models/editor.rb +0 -4
  51. data/spec/dummy_app/app/models/editorship.rb +0 -5
  52. data/spec/dummy_app/app/models/elephant.rb +0 -3
  53. data/spec/dummy_app/app/models/fluxor.rb +0 -3
  54. data/spec/dummy_app/app/models/foo_habtm.rb +0 -5
  55. data/spec/dummy_app/app/models/foo_widget.rb +0 -2
  56. data/spec/dummy_app/app/models/fruit.rb +0 -5
  57. data/spec/dummy_app/app/models/gadget.rb +0 -3
  58. data/spec/dummy_app/app/models/kitchen/banana.rb +0 -5
  59. data/spec/dummy_app/app/models/legacy_widget.rb +0 -6
  60. data/spec/dummy_app/app/models/line_item.rb +0 -4
  61. data/spec/dummy_app/app/models/not_on_update.rb +0 -4
  62. data/spec/dummy_app/app/models/on/create.rb +0 -6
  63. data/spec/dummy_app/app/models/on/destroy.rb +0 -6
  64. data/spec/dummy_app/app/models/on/empty_array.rb +0 -6
  65. data/spec/dummy_app/app/models/on/update.rb +0 -6
  66. data/spec/dummy_app/app/models/order.rb +0 -5
  67. data/spec/dummy_app/app/models/paragraph.rb +0 -5
  68. data/spec/dummy_app/app/models/person.rb +0 -39
  69. data/spec/dummy_app/app/models/post.rb +0 -3
  70. data/spec/dummy_app/app/models/post_with_status.rb +0 -7
  71. data/spec/dummy_app/app/models/quotation.rb +0 -5
  72. data/spec/dummy_app/app/models/section.rb +0 -6
  73. data/spec/dummy_app/app/models/skipper.rb +0 -3
  74. data/spec/dummy_app/app/models/song.rb +0 -37
  75. data/spec/dummy_app/app/models/thing.rb +0 -3
  76. data/spec/dummy_app/app/models/translation.rb +0 -11
  77. data/spec/dummy_app/app/models/truck.rb +0 -4
  78. data/spec/dummy_app/app/models/vehicle.rb +0 -4
  79. data/spec/dummy_app/app/models/whatchamajigger.rb +0 -4
  80. data/spec/dummy_app/app/models/widget.rb +0 -8
  81. data/spec/dummy_app/app/models/wotsit.rb +0 -8
  82. data/spec/dummy_app/app/versions/custom_primary_key_record_version.rb +0 -3
  83. data/spec/dummy_app/app/versions/joined_version.rb +0 -6
  84. data/spec/dummy_app/app/versions/json_version.rb +0 -3
  85. data/spec/dummy_app/app/versions/kitchen/banana_version.rb +0 -5
  86. data/spec/dummy_app/app/versions/post_version.rb +0 -3
  87. data/spec/dummy_app/config.ru +0 -4
  88. data/spec/dummy_app/config/application.rb +0 -39
  89. data/spec/dummy_app/config/boot.rb +0 -24
  90. data/spec/dummy_app/config/database.mysql.yml +0 -19
  91. data/spec/dummy_app/config/database.postgres.yml +0 -15
  92. data/spec/dummy_app/config/database.sqlite.yml +0 -15
  93. data/spec/dummy_app/config/environment.rb +0 -5
  94. data/spec/dummy_app/config/environments/development.rb +0 -36
  95. data/spec/dummy_app/config/environments/production.rb +0 -74
  96. data/spec/dummy_app/config/environments/test.rb +0 -46
  97. data/spec/dummy_app/config/initializers/backtrace_silencers.rb +0 -9
  98. data/spec/dummy_app/config/initializers/inflections.rb +0 -10
  99. data/spec/dummy_app/config/initializers/mime_types.rb +0 -5
  100. data/spec/dummy_app/config/initializers/paper_trail.rb +0 -1
  101. data/spec/dummy_app/config/initializers/secret_token.rb +0 -9
  102. data/spec/dummy_app/config/initializers/session_store.rb +0 -8
  103. data/spec/dummy_app/config/locales/en.yml +0 -5
  104. data/spec/dummy_app/config/routes.rb +0 -4
  105. data/spec/dummy_app/db/migrate/20110208155312_set_up_test_tables.rb +0 -344
  106. data/spec/dummy_app/db/schema.rb +0 -298
  107. data/spec/generators/install_generator_spec.rb +0 -88
  108. data/spec/models/animal_spec.rb +0 -61
  109. data/spec/models/article_spec.rb +0 -186
  110. data/spec/models/boolit_spec.rb +0 -41
  111. data/spec/models/callback_modifier_spec.rb +0 -92
  112. data/spec/models/car_spec.rb +0 -13
  113. data/spec/models/custom_primary_key_record_spec.rb +0 -18
  114. data/spec/models/document_spec.rb +0 -57
  115. data/spec/models/gadget_spec.rb +0 -63
  116. data/spec/models/joined_version_spec.rb +0 -41
  117. data/spec/models/json_version_spec.rb +0 -101
  118. data/spec/models/kitchen/banana_spec.rb +0 -14
  119. data/spec/models/legacy_widget_spec.rb +0 -40
  120. data/spec/models/not_on_update_spec.rb +0 -22
  121. data/spec/models/on/create_spec.rb +0 -27
  122. data/spec/models/on/destroy_spec.rb +0 -27
  123. data/spec/models/on/empty_array_spec.rb +0 -30
  124. data/spec/models/on/update_spec.rb +0 -27
  125. data/spec/models/post_with_status_spec.rb +0 -46
  126. data/spec/models/skipper_spec.rb +0 -42
  127. data/spec/models/thing_spec.rb +0 -11
  128. data/spec/models/translation_spec.rb +0 -70
  129. data/spec/models/vehicle_spec.rb +0 -5
  130. data/spec/models/version_spec.rb +0 -282
  131. data/spec/models/widget_spec.rb +0 -338
  132. data/spec/modules/paper_trail_spec.rb +0 -27
  133. data/spec/modules/version_concern_spec.rb +0 -28
  134. data/spec/modules/version_number_spec.rb +0 -18
  135. data/spec/paper_trail/associations_spec.rb +0 -965
  136. data/spec/paper_trail/cleaner_spec.rb +0 -152
  137. data/spec/paper_trail/config_spec.rb +0 -45
  138. data/spec/paper_trail/model_spec.rb +0 -992
  139. data/spec/paper_trail/serializer_spec.rb +0 -85
  140. data/spec/paper_trail/serializers/custom_json_serializer_spec.rb +0 -18
  141. data/spec/paper_trail/serializers/custom_yaml_serializer_spec.rb +0 -45
  142. data/spec/paper_trail/serializers/json_spec.rb +0 -57
  143. data/spec/paper_trail/serializers/yaml_spec.rb +0 -42
  144. data/spec/paper_trail/thread_safety_spec.rb +0 -44
  145. data/spec/paper_trail/version_limit_spec.rb +0 -55
  146. data/spec/paper_trail/version_spec.rb +0 -96
  147. data/spec/paper_trail_spec.rb +0 -122
  148. data/spec/requests/articles_spec.rb +0 -34
  149. data/spec/spec_helper.rb +0 -78
  150. data/spec/support/alt_db_init.rb +0 -54
  151. data/spec/support/custom_json_serializer.rb +0 -13
@@ -1,152 +0,0 @@
1
- require "spec_helper"
2
-
3
- module PaperTrail
4
- ::RSpec.describe Cleaner, versioning: true do
5
- describe "clean_versions!" do
6
- let(:animal) { ::Animal.new }
7
- let(:dog) { ::Dog.new }
8
- let(:cat) { ::Cat.new }
9
- let(:animals) { [animal, dog, cat] }
10
-
11
- before do
12
- animals.each do |animal|
13
- 3.times do
14
- animal.update_attribute(:name, FFaker::Name.name)
15
- end
16
- end
17
- end
18
-
19
- it "baseline test setup" do
20
- expect(PaperTrail::Version.count).to(eq(9))
21
- animals.each { |animal| expect(animal.versions.size).to(eq(3)) }
22
- end
23
-
24
- context "no options provided" do
25
- it "removes extra versions for each item" do
26
- PaperTrail.clean_versions!
27
- expect(PaperTrail::Version.count).to(eq(3))
28
- animals.each { |animal| expect(animal.versions.size).to(eq(1)) }
29
- end
30
-
31
- it "removes the earliest version(s)" do
32
- before = animals.map { |animal| animal.versions.last.reify.name }
33
- PaperTrail.clean_versions!
34
- after = animals.map { |animal| animal.versions.last.reify.name }
35
- expect(after).to(eq(before))
36
- end
37
- end
38
-
39
- context "keeping 2" do
40
- it "keeps two records, instead of the usual one" do
41
- PaperTrail.clean_versions!(keeping: 2)
42
- expect(PaperTrail::Version.all.count).to(eq(6))
43
- animals.each { |animal| expect(animal.versions.size).to(eq(2)) }
44
- end
45
- end
46
-
47
- context "with the :date option" do
48
- it "only deletes versions created on the given date" do
49
- animal.versions.each do |ver|
50
- ver.update_attribute(:created_at, (ver.created_at - 1.day))
51
- end
52
- date = animal.versions.first.created_at.to_date
53
- animal.update_attribute(:name, FFaker::Name.name)
54
- expect(PaperTrail::Version.count).to(eq(10))
55
- expect(animal.versions.size).to(eq(4))
56
- expect(animal.paper_trail.versions_between(date, (date + 1.day)).size).to(eq(3))
57
- PaperTrail.clean_versions!(date: date)
58
- expect(PaperTrail::Version.count).to(eq(8))
59
- expect(animal.versions.reload.size).to(eq(2))
60
- expect(animal.versions.first.created_at.to_date).to(eq(date))
61
- # Why use `equal?` here instead of something less strict?
62
- # Doesn't `to_date` always produce a new date object?
63
- expect(date.equal?(animal.versions.last.created_at.to_date)).to eq(false)
64
- end
65
- end
66
-
67
- context "with the :item_id option" do
68
- context "single ID received" do
69
- it "only deletes the versions for the Item with that ID" do
70
- PaperTrail.clean_versions!(item_id: animal.id)
71
- expect(animal.versions.size).to(eq(1))
72
- expect(PaperTrail::Version.count).to(eq(7))
73
- end
74
- end
75
-
76
- context "collection of IDs received" do
77
- it "only deletes versions for the Item(s) with those IDs" do
78
- PaperTrail.clean_versions!(item_id: [animal.id, dog.id])
79
- expect(animal.versions.size).to(eq(1))
80
- expect(dog.versions.size).to(eq(1))
81
- expect(PaperTrail::Version.count).to(eq(5))
82
- end
83
- end
84
- end
85
-
86
- context "options combinations" do
87
- context ":date" do
88
- before do
89
- [animal, dog].each do |animal|
90
- animal.versions.each do |ver|
91
- ver.update_attribute(:created_at, (ver.created_at - 1.day))
92
- end
93
- animal.update_attribute(:name, FFaker::Name.name)
94
- end
95
- end
96
-
97
- it "baseline test setup" do
98
- date = animal.versions.first.created_at.to_date
99
- expect(PaperTrail::Version.count).to(eq(11))
100
- [animal, dog].each do |animal|
101
- expect(animal.versions.size).to(eq(4))
102
- expect(animal.versions.between(date, (date + 1.day)).size).to(eq(3))
103
- end
104
- end
105
-
106
- context "and :keeping" do
107
- it "restrict cleaning properly" do
108
- date = animal.versions.first.created_at.to_date
109
- PaperTrail.clean_versions!(date: date, keeping: 2)
110
- [animal, dog].each do |animal|
111
- animal.versions.reload
112
- expect(animal.versions.size).to(eq(3))
113
- expect(animal.versions.between(date, (date + 1.day)).size).to(eq(2))
114
- end
115
- expect(PaperTrail::Version.count).to(eq(9))
116
- end
117
- end
118
-
119
- context "and :item_id" do
120
- it "restrict cleaning properly" do
121
- date = animal.versions.first.created_at.to_date
122
- PaperTrail.clean_versions!(date: date, item_id: dog.id)
123
- dog.versions.reload
124
- expect(dog.versions.size).to(eq(2))
125
- expect(dog.versions.between(date, (date + 1.day)).size).to(eq(1))
126
- expect(PaperTrail::Version.count).to(eq(9))
127
- end
128
- end
129
-
130
- context ", :item_id, and :keeping" do
131
- it "restrict cleaning properly" do
132
- date = animal.versions.first.created_at.to_date
133
- PaperTrail.clean_versions!(date: date, item_id: dog.id, keeping: 2)
134
- dog.versions.reload
135
- expect(dog.versions.size).to(eq(3))
136
- expect(dog.versions.between(date, (date + 1.day)).size).to(eq(2))
137
- expect(PaperTrail::Version.count).to(eq(10))
138
- end
139
- end
140
- end
141
-
142
- context ":keeping and :item_id" do
143
- it "restrict cleaning properly" do
144
- PaperTrail.clean_versions!(keeping: 2, item_id: animal.id)
145
- expect(animal.versions.size).to(eq(2))
146
- expect(PaperTrail::Version.count).to(eq(8))
147
- end
148
- end
149
- end
150
- end
151
- end
152
- end
@@ -1,45 +0,0 @@
1
- require "spec_helper"
2
-
3
- module PaperTrail
4
- ::RSpec.describe Config do
5
- describe ".instance" do
6
- it "returns the singleton instance" do
7
- expect { described_class.instance }.not_to raise_error
8
- end
9
- end
10
-
11
- describe ".new" do
12
- it "raises NoMethodError" do
13
- expect { described_class.new }.to raise_error(NoMethodError)
14
- end
15
- end
16
-
17
- describe "track_associations?" do
18
- context "@track_associations is nil" do
19
- after do
20
- PaperTrail.config.track_associations = true
21
- end
22
-
23
- it "returns false and prints a deprecation warning" do
24
- config = described_class.instance
25
- config.track_associations = nil
26
- expect {
27
- expect(config.track_associations?).to eq(false)
28
- }.to output(/DEPRECATION WARNING/).to_stderr
29
- end
30
- end
31
- end
32
-
33
- describe ".version_limit", versioning: true do
34
- after { PaperTrail.config.version_limit = nil }
35
-
36
- it "limits the number of versions to 3 (2 plus the created at event)" do
37
- PaperTrail.config.version_limit = 2
38
- widget = Widget.create!(name: "Henry")
39
- 6.times { widget.update_attribute(:name, FFaker::Lorem.word) }
40
- expect(widget.versions.first.event).to(eq("create"))
41
- expect(widget.versions.size).to(eq(3))
42
- end
43
- end
44
- end
45
- end
@@ -1,992 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe(::PaperTrail, versioning: true) do
4
- context "A new record" do
5
- before { @widget = Widget.new }
6
-
7
- it "not have any previous versions" do
8
- expect(@widget.versions).to(eq([]))
9
- end
10
-
11
- it "be live" do
12
- expect(@widget.paper_trail.live?).to(eq(true))
13
- end
14
-
15
- context "which is then created" do
16
- before do
17
- @widget.update_attributes(name: "Henry", created_at: (Time.now - 1.day))
18
- end
19
-
20
- it "have one previous version" do
21
- expect(@widget.versions.length).to(eq(1))
22
- end
23
-
24
- it "be nil in its previous version" do
25
- expect(@widget.versions.first.object).to(be_nil)
26
- expect(@widget.versions.first.reify).to(be_nil)
27
- end
28
-
29
- it "record the correct event" do
30
- expect(@widget.versions.first.event).to(match(/create/i))
31
- end
32
-
33
- it "be live" do
34
- expect(@widget.paper_trail.live?).to(eq(true))
35
- end
36
-
37
- it "use the widget `updated_at` as the version's `created_at`" do
38
- expect(@widget.versions.first.created_at.to_i).to(eq(@widget.updated_at.to_i))
39
- end
40
-
41
- describe "#changeset" do
42
- it "has expected values" do
43
- changeset = @widget.versions.last.changeset
44
- expect(changeset["name"]).to eq([nil, "Henry"])
45
- expect(changeset["id"]).to eq([nil, @widget.id])
46
- # When comparing timestamps, round off to the nearest second, because
47
- # mysql doesn't do fractional seconds.
48
- expect(changeset["created_at"][0]).to be_nil
49
- expect(changeset["created_at"][1].to_i).to eq(@widget.created_at.to_i)
50
- expect(changeset["updated_at"][0]).to be_nil
51
- expect(changeset["updated_at"][1].to_i).to eq(@widget.updated_at.to_i)
52
- end
53
- end
54
-
55
- context "and then updated without any changes" do
56
- before { @widget.touch }
57
-
58
- it "not have a new version" do
59
- expect(@widget.versions.length).to(eq(1))
60
- end
61
- end
62
-
63
- context "and then updated with changes" do
64
- before { @widget.update_attributes(name: "Harry") }
65
-
66
- it "have two previous versions" do
67
- expect(@widget.versions.length).to(eq(2))
68
- end
69
-
70
- it "be available in its previous version" do
71
- expect(@widget.name).to(eq("Harry"))
72
- expect(@widget.versions.last.object).not_to(be_nil)
73
- widget = @widget.versions.last.reify
74
- expect(widget.name).to(eq("Henry"))
75
- expect(@widget.name).to(eq("Harry"))
76
- end
77
-
78
- it "have the same ID in its previous version" do
79
- expect(@widget.versions.last.reify.id).to(eq(@widget.id))
80
- end
81
-
82
- it "record the correct event" do
83
- expect(@widget.versions.last.event).to(match(/update/i))
84
- end
85
-
86
- it "have versions that are not live" do
87
- expect(
88
- @widget.versions.map(&:reify).compact.all? { |w| !w.paper_trail.live? }
89
- ).to(be_truthy)
90
- end
91
-
92
- it "have stored changes" do
93
- last_obj_changes = @widget.versions.last.object_changes
94
- actual = PaperTrail.serializer.load(last_obj_changes).reject do |k, _v|
95
- (k.to_sym == :updated_at)
96
- end
97
- expect(actual).to(eq("name" => %w[Henry Harry]))
98
- actual = @widget.versions.last.changeset.reject { |k, _v| (k.to_sym == :updated_at) }
99
- expect(actual).to(eq("name" => %w[Henry Harry]))
100
- end
101
-
102
- it "return changes with indifferent access" do
103
- expect(@widget.versions.last.changeset[:name]).to(eq(%w[Henry Harry]))
104
- expect(@widget.versions.last.changeset["name"]).to(eq(%w[Henry Harry]))
105
- end
106
-
107
- context "and has one associated object" do
108
- before { @wotsit = @widget.create_wotsit name: "John" }
109
-
110
- it "not copy the has_one association by default when reifying" do
111
- reified_widget = @widget.versions.last.reify
112
- expect(reified_widget.wotsit).to(eq(@wotsit))
113
- expect(@widget.reload.wotsit).to(eq(@wotsit))
114
- end
115
-
116
- it "copy the has_one association when reifying with :has_one => true" do
117
- reified_widget = @widget.versions.last.reify(has_one: true)
118
- expect(reified_widget.wotsit).to(be_nil)
119
- expect(@widget.reload.wotsit).to(eq(@wotsit))
120
- end
121
- end
122
-
123
- context "and has many associated objects" do
124
- before do
125
- @f0 = @widget.fluxors.create(name: "f-zero")
126
- @f1 = @widget.fluxors.create(name: "f-one")
127
- @reified_widget = @widget.versions.last.reify
128
- end
129
-
130
- it "copy the has_many associations when reifying" do
131
- expect(@reified_widget.fluxors.length).to(eq(@widget.fluxors.length))
132
- expect(@reified_widget.fluxors).to match_array(@widget.fluxors)
133
- expect(@reified_widget.versions.length).to(eq(@widget.versions.length))
134
- expect(@reified_widget.versions).to match_array(@widget.versions)
135
- end
136
- end
137
-
138
- context "and has many associated polymorphic objects" do
139
- before do
140
- @f0 = @widget.whatchamajiggers.create(name: "f-zero")
141
- @f1 = @widget.whatchamajiggers.create(name: "f-zero")
142
- @reified_widget = @widget.versions.last.reify
143
- end
144
-
145
- it "copy the has_many associations when reifying" do
146
- expect(@reified_widget.whatchamajiggers.length).to eq(@widget.whatchamajiggers.length)
147
- expect(@reified_widget.whatchamajiggers).to match_array(@widget.whatchamajiggers)
148
- expect(@reified_widget.versions.length).to(eq(@widget.versions.length))
149
- expect(@reified_widget.versions).to match_array(@widget.versions)
150
- end
151
- end
152
-
153
- context "polymorphic objects by themselves" do
154
- before { @widget = Whatchamajigger.new(name: "f-zero") }
155
-
156
- it "not fail with a nil pointer on the polymorphic association" do
157
- @widget.save!
158
- end
159
- end
160
-
161
- context "and then destroyed" do
162
- before do
163
- @fluxor = @widget.fluxors.create(name: "flux")
164
- @widget.destroy
165
- @reified_widget = PaperTrail::Version.last.reify
166
- end
167
-
168
- it "record the correct event" do
169
- expect(PaperTrail::Version.last.event).to(match(/destroy/i))
170
- end
171
-
172
- it "have three previous versions" do
173
- expect(PaperTrail::Version.with_item_keys("Widget", @widget.id).length).to(eq(3))
174
- end
175
-
176
- describe "#attributes" do
177
- it "returns the expected attributes for the reified widget" do
178
- expect(@reified_widget.id).to(eq(@widget.id))
179
- expected = @widget.attributes
180
- actual = @reified_widget.attributes
181
- expect(expected["id"]).to eq(actual["id"])
182
- expect(expected["name"]).to eq(actual["name"])
183
- expect(expected["a_text"]).to eq(actual["a_text"])
184
- expect(expected["an_integer"]).to eq(actual["an_integer"])
185
- expect(expected["a_float"]).to eq(actual["a_float"])
186
- expect(expected["a_decimal"]).to eq(actual["a_decimal"])
187
- expect(expected["a_datetime"]).to eq(actual["a_datetime"])
188
- expect(expected["a_time"]).to eq(actual["a_time"])
189
- expect(expected["a_date"]).to eq(actual["a_date"])
190
- expect(expected["a_boolean"]).to eq(actual["a_boolean"])
191
- expect(expected["type"]).to eq(actual["type"])
192
- expect(expected["created_at"].to_i).to eq(actual["created_at"].to_i)
193
- expect(expected["updated_at"].to_i).to eq(actual["updated_at"].to_i)
194
- end
195
- end
196
-
197
- it "be re-creatable from its previous version" do
198
- expect(@reified_widget.save).to(be_truthy)
199
- end
200
-
201
- it "restore its associations on its previous version" do
202
- @reified_widget.save
203
- expect(@reified_widget.fluxors.length).to(eq(1))
204
- end
205
-
206
- it "have nil item for last version" do
207
- expect(@widget.versions.last.item).to(be_nil)
208
- end
209
-
210
- it "not have changes" do
211
- expect(@widget.versions.last.changeset).to(eq({}))
212
- end
213
- end
214
- end
215
- end
216
- end
217
-
218
- context "A record's papertrail" do
219
- before do
220
- @date_time = DateTime.now.utc
221
- @time = Time.now
222
- @date = Date.new(2009, 5, 29)
223
- @widget = Widget.create(
224
- name: "Warble",
225
- a_text: "The quick brown fox",
226
- an_integer: 42,
227
- a_float: 153.01,
228
- a_decimal: 2.71828,
229
- a_datetime: @date_time,
230
- a_time: @time,
231
- a_date: @date,
232
- a_boolean: true
233
- )
234
- @widget.update_attributes(
235
- name: nil,
236
- a_text: nil,
237
- an_integer: nil,
238
- a_float: nil,
239
- a_decimal: nil,
240
- a_datetime: nil,
241
- a_time: nil,
242
- a_date: nil,
243
- a_boolean: false
244
- )
245
- @previous = @widget.versions.last.reify
246
- end
247
-
248
- it "handle strings" do
249
- expect(@previous.name).to(eq("Warble"))
250
- end
251
-
252
- it "handle text" do
253
- expect(@previous.a_text).to(eq("The quick brown fox"))
254
- end
255
-
256
- it "handle integers" do
257
- expect(@previous.an_integer).to(eq(42))
258
- end
259
-
260
- it "handle floats" do
261
- assert_in_delta(153.01, @previous.a_float, 0.001)
262
- end
263
-
264
- it "handle decimals" do
265
- assert_in_delta(2.7183, @previous.a_decimal, 0.0001)
266
- end
267
-
268
- it "handle datetimes" do
269
- expect(@previous.a_datetime.to_time.utc.to_i).to(eq(@date_time.to_time.utc.to_i))
270
- end
271
-
272
- it "handle times" do
273
- expect(@previous.a_time.utc.to_i).to(eq(@time.utc.to_i))
274
- end
275
-
276
- it "handle dates" do
277
- expect(@previous.a_date).to(eq(@date))
278
- end
279
-
280
- it "handle booleans" do
281
- expect(@previous.a_boolean).to(be_truthy)
282
- end
283
-
284
- context "after a column is removed from the record's schema" do
285
- before { @last = @widget.versions.last }
286
-
287
- it "reify previous version" do
288
- assert_kind_of(Widget, @last.reify)
289
- end
290
-
291
- it "restore all forward-compatible attributes" do
292
- expect(@last.reify.name).to(eq("Warble"))
293
- expect(@last.reify.a_text).to(eq("The quick brown fox"))
294
- expect(@last.reify.an_integer).to(eq(42))
295
- assert_in_delta(153.01, @last.reify.a_float, 0.001)
296
- assert_in_delta(2.7183, @last.reify.a_decimal, 0.0001)
297
- expect(@last.reify.a_datetime.to_time.utc.to_i).to(eq(@date_time.to_time.utc.to_i))
298
- expect(@last.reify.a_time.utc.to_i).to(eq(@time.utc.to_i))
299
- expect(@last.reify.a_date).to(eq(@date))
300
- expect(@last.reify.a_boolean).to(be_truthy)
301
- end
302
- end
303
- end
304
-
305
- context "A record" do
306
- before { @widget = Widget.create(name: "Zaphod") }
307
-
308
- context "with PaperTrail globally disabled" do
309
- before do
310
- PaperTrail.enabled = false
311
- @count = @widget.versions.length
312
- end
313
-
314
- after { PaperTrail.enabled = true }
315
-
316
- context "when updated" do
317
- before { @widget.update_attributes(name: "Beeblebrox") }
318
-
319
- it "not add to its trail" do
320
- expect(@widget.versions.length).to(eq(@count))
321
- end
322
- end
323
- end
324
-
325
- context "with its paper trail turned off" do
326
- before do
327
- Widget.paper_trail.disable
328
- @count = @widget.versions.length
329
- end
330
-
331
- after { Widget.paper_trail.enable }
332
-
333
- context "when updated" do
334
- before { @widget.update_attributes(name: "Beeblebrox") }
335
-
336
- it "not add to its trail" do
337
- expect(@widget.versions.length).to(eq(@count))
338
- end
339
- end
340
-
341
- context "when destroyed \"without versioning\"" do
342
- it "leave paper trail off after call" do
343
- @widget.paper_trail.without_versioning(:destroy)
344
- expect(Widget.paper_trail.enabled?).to(eq(false))
345
- end
346
- end
347
-
348
- context "and then its paper trail turned on" do
349
- before { Widget.paper_trail.enable }
350
-
351
- context "when updated" do
352
- before { @widget.update_attributes(name: "Ford") }
353
-
354
- it "add to its trail" do
355
- expect(@widget.versions.length).to(eq((@count + 1)))
356
- end
357
- end
358
-
359
- context "when updated \"without versioning\"" do
360
- before do
361
- @widget.paper_trail.without_versioning do
362
- @widget.update_attributes(name: "Ford")
363
- end
364
- @widget.paper_trail.without_versioning do |w|
365
- w.update_attributes(name: "Nixon")
366
- end
367
- end
368
-
369
- it "not create new version" do
370
- expect(@widget.versions.length).to(eq(@count))
371
- end
372
-
373
- it "enable paper trail after call" do
374
- expect(Widget.paper_trail.enabled?).to(eq(true))
375
- end
376
- end
377
-
378
- context "when receiving a method name as an argument" do
379
- before { @widget.paper_trail.without_versioning(:touch_with_version) }
380
-
381
- it "not create new version" do
382
- expect(@widget.versions.length).to(eq(@count))
383
- end
384
-
385
- it "enable paper trail after call" do
386
- expect(Widget.paper_trail.enabled?).to(eq(true))
387
- end
388
- end
389
- end
390
- end
391
- end
392
-
393
- context "A papertrail with somebody making changes" do
394
- before { @widget = Widget.new(name: "Fidget") }
395
-
396
- context "when a record is created" do
397
- before do
398
- PaperTrail.whodunnit = "Alice"
399
- @widget.save
400
- @version = @widget.versions.last
401
- end
402
-
403
- it "track who made the change" do
404
- expect(@version.whodunnit).to(eq("Alice"))
405
- expect(@version.paper_trail_originator).to(be_nil)
406
- expect(@version.terminator).to(eq("Alice"))
407
- expect(@widget.paper_trail.originator).to(eq("Alice"))
408
- end
409
-
410
- context "when a record is updated" do
411
- before do
412
- PaperTrail.whodunnit = "Bob"
413
- @widget.update_attributes(name: "Rivet")
414
- @version = @widget.versions.last
415
- end
416
-
417
- it "track who made the change" do
418
- expect(@version.whodunnit).to(eq("Bob"))
419
- expect(@version.paper_trail_originator).to(eq("Alice"))
420
- expect(@version.terminator).to(eq("Bob"))
421
- expect(@widget.paper_trail.originator).to(eq("Bob"))
422
- end
423
-
424
- context "when a record is destroyed" do
425
- before do
426
- PaperTrail.whodunnit = "Charlie"
427
- @widget.destroy
428
- @version = PaperTrail::Version.last
429
- end
430
-
431
- it "track who made the change" do
432
- expect(@version.whodunnit).to(eq("Charlie"))
433
- expect(@version.paper_trail_originator).to(eq("Bob"))
434
- expect(@version.terminator).to(eq("Charlie"))
435
- expect(@widget.paper_trail.originator).to(eq("Charlie"))
436
- end
437
- end
438
- end
439
- end
440
- end
441
-
442
- it "update_attributes! records timestamps" do
443
- wotsit = Wotsit.create!(name: "wotsit")
444
- wotsit.update_attributes!(name: "changed")
445
- reified = wotsit.versions.last.reify
446
- expect(reified.created_at).not_to(be_nil)
447
- expect(reified.updated_at).not_to(be_nil)
448
- end
449
-
450
- it "update_attributes! does not raise error" do
451
- wotsit = Wotsit.create!(name: "name1")
452
- expect { wotsit.update_attributes!(name: "name2") }.not_to(raise_error)
453
- end
454
-
455
- context "A subclass" do
456
- before do
457
- @foo = FooWidget.create
458
- @foo.update_attributes!(name: "Foo")
459
- end
460
-
461
- it "reify with the correct type" do
462
- if ActiveRecord::VERSION::MAJOR < 4
463
- assert_kind_of(FooWidget, @foo.versions.last.reify)
464
- end
465
- expect(PaperTrail::Version.last.previous).to(eq(@foo.versions.first))
466
- expect(PaperTrail::Version.last.next).to(be_nil)
467
- end
468
-
469
- it "returns the correct originator" do
470
- PaperTrail.whodunnit = "Ben"
471
- @foo.update_attribute(:name, "Geoffrey")
472
- expect(@foo.paper_trail.originator).to(eq(PaperTrail.whodunnit))
473
- end
474
-
475
- context "when destroyed" do
476
- before { @foo.destroy }
477
-
478
- it "reify with the correct type" do
479
- assert_kind_of(FooWidget, @foo.versions.last.reify)
480
- expect(PaperTrail::Version.last.previous).to(eq(@foo.versions[1]))
481
- expect(PaperTrail::Version.last.next).to(be_nil)
482
- end
483
- end
484
- end
485
-
486
- context "An item with versions" do
487
- before do
488
- @widget = Widget.create(name: "Widget")
489
- @widget.update_attributes(name: "Fidget")
490
- @widget.update_attributes(name: "Digit")
491
- end
492
-
493
- context "which were created over time" do
494
- before do
495
- @created = 2.days.ago
496
- @first_update = 1.day.ago
497
- @second_update = 1.hour.ago
498
- @widget.versions[0].update_attributes(created_at: @created)
499
- @widget.versions[1].update_attributes(created_at: @first_update)
500
- @widget.versions[2].update_attributes(created_at: @second_update)
501
- @widget.update_attribute(:updated_at, @second_update)
502
- end
503
-
504
- it "return nil for version_at before it was created" do
505
- expect(@widget.paper_trail.version_at((@created - 1))).to(be_nil)
506
- end
507
-
508
- it "return how it looked when created for version_at its creation" do
509
- expect(@widget.paper_trail.version_at(@created).name).to(eq("Widget"))
510
- end
511
-
512
- it "return how it looked before its first update" do
513
- expect(@widget.paper_trail.version_at((@first_update - 1)).name).to(eq("Widget"))
514
- end
515
-
516
- it "return how it looked after its first update" do
517
- expect(@widget.paper_trail.version_at(@first_update).name).to(eq("Fidget"))
518
- end
519
-
520
- it "return how it looked before its second update" do
521
- expect(@widget.paper_trail.version_at((@second_update - 1)).name).to(eq("Fidget"))
522
- end
523
-
524
- it "return how it looked after its second update" do
525
- expect(@widget.paper_trail.version_at(@second_update).name).to(eq("Digit"))
526
- end
527
-
528
- it "return the current object for version_at after latest update" do
529
- expect(@widget.paper_trail.version_at(1.day.from_now).name).to(eq("Digit"))
530
- end
531
-
532
- context "passing in a string representation of a timestamp" do
533
- it "still return a widget when appropriate" do
534
- expect(
535
- @widget.paper_trail.version_at((@created + 1.second).to_s).name
536
- ).to(eq("Widget"))
537
- expect(
538
- @widget.paper_trail.version_at((@first_update + 1.second).to_s).name
539
- ).to(eq("Fidget"))
540
- expect(
541
- @widget.paper_trail.version_at((@second_update + 1.second).to_s).name
542
- ).to(eq("Digit"))
543
- end
544
- end
545
- end
546
-
547
- context ".versions_between" do
548
- before do
549
- @created = 30.days.ago
550
- @first_update = 15.days.ago
551
- @second_update = 1.day.ago
552
- @widget.versions[0].update_attributes(created_at: @created)
553
- @widget.versions[1].update_attributes(created_at: @first_update)
554
- @widget.versions[2].update_attributes(created_at: @second_update)
555
- @widget.update_attribute(:updated_at, @second_update)
556
- end
557
-
558
- it "return versions in the time period" do
559
- expect(
560
- @widget.paper_trail.versions_between(20.days.ago, 10.days.ago).map(&:name)
561
- ).to(eq(["Fidget"]))
562
- expect(
563
- @widget.paper_trail.versions_between(45.days.ago, 10.days.ago).map(&:name)
564
- ).to(eq(%w[Widget Fidget]))
565
- expect(
566
- @widget.paper_trail.versions_between(16.days.ago, 1.minute.ago).map(&:name)
567
- ).to(eq(%w[Fidget Digit Digit]))
568
- expect(
569
- @widget.paper_trail.versions_between(60.days.ago, 45.days.ago).map(&:name)
570
- ).to(eq([]))
571
- end
572
- end
573
-
574
- context "on the first version" do
575
- before { @version = @widget.versions.first }
576
-
577
- it "have a nil previous version" do
578
- expect(@version.previous).to(be_nil)
579
- end
580
-
581
- it "return the next version" do
582
- expect(@version.next).to(eq(@widget.versions[1]))
583
- end
584
-
585
- it "return the correct index" do
586
- expect(@version.index).to(eq(0))
587
- end
588
- end
589
-
590
- context "on the last version" do
591
- before { @version = @widget.versions.last }
592
-
593
- it "return the previous version" do
594
- expect(@version.previous).to(eq(@widget.versions[(@widget.versions.length - 2)]))
595
- end
596
-
597
- it "have a nil next version" do
598
- expect(@version.next).to(be_nil)
599
- end
600
-
601
- it "return the correct index" do
602
- expect(@version.index).to(eq((@widget.versions.length - 1)))
603
- end
604
- end
605
- end
606
-
607
- context "An item" do
608
- before do
609
- @initial_title = "Foobar"
610
- @article = Article.new(title: @initial_title)
611
- end
612
-
613
- context "which is created" do
614
- before { @article.save }
615
-
616
- it "store fixed meta data" do
617
- expect(@article.versions.last.answer).to(eq(42))
618
- end
619
-
620
- it "store dynamic meta data which is independent of the item" do
621
- expect(@article.versions.last.question).to(eq("31 + 11 = 42"))
622
- end
623
-
624
- it "store dynamic meta data which depends on the item" do
625
- expect(@article.versions.last.article_id).to(eq(@article.id))
626
- end
627
-
628
- it "store dynamic meta data based on a method of the item" do
629
- expect(@article.versions.last.action).to(eq(@article.action_data_provider_method))
630
- end
631
-
632
- it "store dynamic meta data based on an attribute of the item at creation" do
633
- expect(@article.versions.last.title).to(eq(@initial_title))
634
- end
635
-
636
- context "and updated" do
637
- before do
638
- @article.update_attributes!(content: "Better text.", title: "Rhubarb")
639
- end
640
-
641
- it "store fixed meta data" do
642
- expect(@article.versions.last.answer).to(eq(42))
643
- end
644
-
645
- it "store dynamic meta data which is independent of the item" do
646
- expect(@article.versions.last.question).to(eq("31 + 11 = 42"))
647
- end
648
-
649
- it "store dynamic meta data which depends on the item" do
650
- expect(@article.versions.last.article_id).to(eq(@article.id))
651
- end
652
-
653
- it "store dynamic meta data based on an attribute of the item prior to the update" do
654
- expect(@article.versions.last.title).to(eq(@initial_title))
655
- end
656
- end
657
-
658
- context "and destroyed" do
659
- before { @article.destroy }
660
-
661
- it "store fixed metadata" do
662
- expect(@article.versions.last.answer).to(eq(42))
663
- end
664
-
665
- it "store dynamic metadata which is independent of the item" do
666
- expect(@article.versions.last.question).to(eq("31 + 11 = 42"))
667
- end
668
-
669
- it "store dynamic metadata which depends on the item" do
670
- expect(@article.versions.last.article_id).to(eq(@article.id))
671
- end
672
-
673
- it "store dynamic metadata based on attribute of item prior to destruction" do
674
- expect(@article.versions.last.title).to(eq(@initial_title))
675
- end
676
- end
677
- end
678
- end
679
-
680
- context "A reified item" do
681
- before do
682
- widget = Widget.create(name: "Bob")
683
- %w[Tom Dick Jane].each do |name|
684
- widget.update_attributes(name: name)
685
- end
686
- @version = widget.versions.last
687
- @widget = @version.reify
688
- end
689
-
690
- it "know which version it came from" do
691
- expect(@widget.version).to(eq(@version))
692
- end
693
-
694
- it "return its previous self" do
695
- expect(@widget.paper_trail.previous_version).to(eq(@widget.versions[-2].reify))
696
- end
697
- end
698
-
699
- context "A non-reified item" do
700
- before { @widget = Widget.new }
701
-
702
- it "not have a previous version" do
703
- expect(@widget.paper_trail.previous_version).to(be_nil)
704
- end
705
-
706
- it "not have a next version" do
707
- expect(@widget.paper_trail.next_version).to(be_nil)
708
- end
709
-
710
- context "with versions" do
711
- before do
712
- @widget.save
713
- %w[Tom Dick Jane].each do |name|
714
- @widget.update_attributes(name: name)
715
- end
716
- end
717
-
718
- it "have a previous version" do
719
- expect(@widget.paper_trail.previous_version.name).to(eq(@widget.versions.last.reify.name))
720
- end
721
-
722
- it "not have a next version" do
723
- expect(@widget.paper_trail.next_version).to(be_nil)
724
- end
725
- end
726
- end
727
-
728
- context "A reified item" do
729
- before do
730
- @widget = Widget.create(name: "Bob")
731
- %w[Tom Dick Jane].each do |name|
732
- @widget.update_attributes(name: name)
733
- end
734
- @second_widget = @widget.versions[1].reify
735
- @last_widget = @widget.versions.last.reify
736
- end
737
-
738
- it "have a previous version" do
739
- expect(@second_widget.paper_trail.previous_version).to(be_nil)
740
- expect(@last_widget.paper_trail.previous_version.name).to(eq(@widget.versions[-2].reify.name))
741
- end
742
-
743
- it "have a next version" do
744
- expect(@second_widget.paper_trail.next_version.name).to(eq(@widget.versions[2].reify.name))
745
- expect(@widget.name).to(eq(@last_widget.paper_trail.next_version.name))
746
- end
747
- end
748
-
749
- context ":has_many :through" do
750
- before do
751
- @book = Book.create(title: "War and Peace")
752
- @dostoyevsky = Person.create(name: "Dostoyevsky")
753
- @solzhenitsyn = Person.create(name: "Solzhenitsyn")
754
- end
755
-
756
- it "store version on source <<" do
757
- count = PaperTrail::Version.count
758
- (@book.authors << @dostoyevsky)
759
- expect((PaperTrail::Version.count - count)).to(eq(1))
760
- expect(@book.authorships.first.versions.first).to(eq(PaperTrail::Version.last))
761
- end
762
-
763
- it "store version on source create" do
764
- count = PaperTrail::Version.count
765
- @book.authors.create(name: "Tolstoy")
766
- expect((PaperTrail::Version.count - count)).to(eq(2))
767
- expect(
768
- [PaperTrail::Version.order(:id).to_a[-2].item, PaperTrail::Version.last.item]
769
- ).to match_array([Person.last, Authorship.last])
770
- end
771
-
772
- it "store version on join destroy" do
773
- (@book.authors << @dostoyevsky)
774
- count = PaperTrail::Version.count
775
- @book.authorships.reload.last.destroy
776
- expect((PaperTrail::Version.count - count)).to(eq(1))
777
- expect(PaperTrail::Version.last.reify.book).to(eq(@book))
778
- expect(PaperTrail::Version.last.reify.author).to(eq(@dostoyevsky))
779
- end
780
-
781
- it "store version on join clear" do
782
- (@book.authors << @dostoyevsky)
783
- count = PaperTrail::Version.count
784
- @book.authorships.reload.destroy_all
785
- expect((PaperTrail::Version.count - count)).to(eq(1))
786
- expect(PaperTrail::Version.last.reify.book).to(eq(@book))
787
- expect(PaperTrail::Version.last.reify.author).to(eq(@dostoyevsky))
788
- end
789
- end
790
-
791
- context "When an attribute has a custom serializer" do
792
- before { @person = Person.new(time_zone: "Samoa") }
793
-
794
- it "be an instance of ActiveSupport::TimeZone" do
795
- expect(@person.time_zone.class).to(eq(ActiveSupport::TimeZone))
796
- end
797
-
798
- context "when the model is saved" do
799
- before do
800
- @changes_before_save = @person.changes.dup
801
- @person.save!
802
- end
803
-
804
- it "version.object_changes should store long serialization of TimeZone object" do
805
- len = @person.versions.last.object_changes.length
806
- expect((len < 105)).to(be_truthy)
807
- end
808
-
809
- it "version.object_changes attribute should have stored the value from serializer" do
810
- as_stored_in_version = HashWithIndifferentAccess[
811
- YAML.load(@person.versions.last.object_changes)
812
- ]
813
- expect(as_stored_in_version[:time_zone]).to(eq([nil, "Samoa"]))
814
- serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
815
- expect(as_stored_in_version[:time_zone].last).to(eq(serialized_value))
816
- end
817
-
818
- it "version.changeset should convert attribute to original, unserialized value" do
819
- unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
820
- expect(@person.versions.last.changeset[:time_zone].last).to(eq(unserialized_value))
821
- end
822
-
823
- it "record.changes (before save) returns the original, unserialized values" do
824
- expect(
825
- @changes_before_save[:time_zone].map(&:class)
826
- ).to(eq([NilClass, ActiveSupport::TimeZone]))
827
- end
828
-
829
- it "version.changeset should be the same as record.changes was before the save" do
830
- actual = @person.versions.last.changeset.delete_if { |k, _v| (k.to_sym == :id) }
831
- expect(actual).to(eq(@changes_before_save))
832
- actual = @person.versions.last.changeset[:time_zone].map(&:class)
833
- expect(actual).to(eq([NilClass, ActiveSupport::TimeZone]))
834
- end
835
-
836
- context "when that attribute is updated" do
837
- before do
838
- @attribute_value_before_change = @person.time_zone
839
- @person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
840
- @changes_before_save = @person.changes.dup
841
- @person.save!
842
- end
843
-
844
- it "object should not store long serialization of TimeZone object" do
845
- len = @person.versions.last.object.length
846
- expect((len < 105)).to(be_truthy)
847
- end
848
-
849
- it "object_changes should not store long serialization of TimeZone object" do
850
- max_len = ActiveRecord::VERSION::MAJOR < 4 ? 105 : 118
851
- len = @person.versions.last.object_changes.length
852
- expect((len < max_len)).to(be_truthy)
853
- end
854
-
855
- it "version.object attribute should have stored value from serializer" do
856
- as_stored_in_version = HashWithIndifferentAccess[
857
- YAML.load(@person.versions.last.object)
858
- ]
859
- expect(as_stored_in_version[:time_zone]).to(eq("Samoa"))
860
- serialized_value = Person::TimeZoneSerializer.dump(@attribute_value_before_change)
861
- expect(as_stored_in_version[:time_zone]).to(eq(serialized_value))
862
- end
863
-
864
- it "version.object_changes attribute should have stored value from serializer" do
865
- as_stored_in_version = HashWithIndifferentAccess[
866
- YAML.load(@person.versions.last.object_changes)
867
- ]
868
- expect(as_stored_in_version[:time_zone]).to(eq(["Samoa", "Pacific Time (US & Canada)"]))
869
- serialized_value = Person::TimeZoneSerializer.dump(@person.time_zone)
870
- expect(as_stored_in_version[:time_zone].last).to(eq(serialized_value))
871
- end
872
-
873
- it "version.reify should convert attribute to original, unserialized value" do
874
- unserialized_value = Person::TimeZoneSerializer.load(@attribute_value_before_change)
875
- expect(@person.versions.last.reify.time_zone).to(eq(unserialized_value))
876
- end
877
-
878
- it "version.changeset should convert attribute to original, unserialized value" do
879
- unserialized_value = Person::TimeZoneSerializer.load(@person.time_zone)
880
- expect(@person.versions.last.changeset[:time_zone].last).to(eq(unserialized_value))
881
- end
882
-
883
- it "record.changes (before save) returns the original, unserialized values" do
884
- expect(
885
- @changes_before_save[:time_zone].map(&:class)
886
- ).to(eq([ActiveSupport::TimeZone, ActiveSupport::TimeZone]))
887
- end
888
-
889
- it "version.changeset should be the same as record.changes was before the save" do
890
- expect(@person.versions.last.changeset).to(eq(@changes_before_save))
891
- expect(
892
- @person.versions.last.changeset[:time_zone].map(&:class)
893
- ).to(eq([ActiveSupport::TimeZone, ActiveSupport::TimeZone]))
894
- end
895
- end
896
- end
897
- end
898
-
899
- context "A new model instance which uses a custom PaperTrail::Version class" do
900
- before { @post = Post.new }
901
-
902
- context "which is then saved" do
903
- before { @post.save }
904
-
905
- it "change the number of post versions" do
906
- expect(PostVersion.count).to(eq(1))
907
- end
908
-
909
- it "not change the number of versions" do
910
- expect(PaperTrail::Version.count).to(eq(0))
911
- end
912
- end
913
- end
914
-
915
- context "An existing model instance which uses a custom PaperTrail::Version class" do
916
- before { @post = Post.create }
917
-
918
- it "have one post version" do
919
- expect(PostVersion.count).to(eq(1))
920
- end
921
-
922
- context "on the first version" do
923
- before { @version = @post.versions.first }
924
-
925
- it "have the correct index" do
926
- expect(@version.index).to(eq(0))
927
- end
928
- end
929
-
930
- it "have versions of the custom class" do
931
- expect(@post.versions.first.class.name).to(eq("PostVersion"))
932
- end
933
-
934
- context "which is modified" do
935
- before { @post.update_attributes(content: "Some new content") }
936
-
937
- it "change the number of post versions" do
938
- expect(PostVersion.count).to(eq(2))
939
- end
940
-
941
- it "not change the number of versions" do
942
- expect(PaperTrail::Version.count).to(eq(0))
943
- end
944
-
945
- it "not have stored changes when object_changes column doesn't exist" do
946
- expect(@post.versions.last.changeset).to(be_nil)
947
- end
948
- end
949
- end
950
-
951
- context "An overwritten default accessor" do
952
- before do
953
- @song = Song.create(length: 4)
954
- @song.update_attributes(length: 5)
955
- end
956
-
957
- it "return \"overwritten\" value on live instance" do
958
- expect(@song.length).to(eq(5))
959
- end
960
-
961
- it "return \"overwritten\" value on reified instance" do
962
- expect(@song.versions.last.reify.length).to(eq(4))
963
- end
964
-
965
- context "Has a virtual attribute injected into the ActiveModel::Dirty changes" do
966
- before do
967
- @song.name = "Good Vibrations"
968
- @song.save
969
- @song.name = "Yellow Submarine"
970
- end
971
-
972
- it "return persist the changes on the live instance properly" do
973
- expect(@song.name).to(eq("Yellow Submarine"))
974
- end
975
-
976
- it "return \"overwritten\" virtual attribute on the reified instance" do
977
- expect(@song.versions.last.reify.name).to(eq("Good Vibrations"))
978
- end
979
- end
980
- end
981
-
982
- context "An unsaved record" do
983
- before do
984
- @widget = Widget.new
985
- @widget.destroy
986
- end
987
-
988
- it "not have a version created on destroy" do
989
- expect(@widget.versions.empty?).to(eq(true))
990
- end
991
- end
992
- end