paper_trail 7.1.0 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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