paper_trail 5.2.3 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. checksums.yaml +5 -5
  2. data/lib/generators/paper_trail/install/USAGE +3 -0
  3. data/lib/generators/paper_trail/install/install_generator.rb +75 -0
  4. data/lib/generators/paper_trail/{templates/add_object_changes_to_versions.rb → install/templates/add_object_changes_to_versions.rb.erb} +1 -1
  5. data/lib/generators/paper_trail/install/templates/create_versions.rb.erb +36 -0
  6. data/lib/generators/paper_trail/migration_generator.rb +38 -0
  7. data/lib/generators/paper_trail/update_item_subtype/USAGE +4 -0
  8. data/lib/generators/paper_trail/update_item_subtype/templates/update_versions_for_item_subtype.rb.erb +85 -0
  9. data/lib/generators/paper_trail/update_item_subtype/update_item_subtype_generator.rb +17 -0
  10. data/lib/paper_trail.rb +82 -130
  11. data/lib/paper_trail/attribute_serializers/attribute_serializer_factory.rb +27 -0
  12. data/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb +15 -44
  13. data/lib/paper_trail/attribute_serializers/object_attribute.rb +2 -0
  14. data/lib/paper_trail/attribute_serializers/object_changes_attribute.rb +2 -0
  15. data/lib/paper_trail/cleaner.rb +3 -1
  16. data/lib/paper_trail/compatibility.rb +51 -0
  17. data/lib/paper_trail/config.rb +11 -49
  18. data/lib/paper_trail/events/base.rb +323 -0
  19. data/lib/paper_trail/events/create.rb +32 -0
  20. data/lib/paper_trail/events/destroy.rb +42 -0
  21. data/lib/paper_trail/events/update.rb +60 -0
  22. data/lib/paper_trail/frameworks/active_record.rb +2 -1
  23. data/lib/paper_trail/frameworks/active_record/models/paper_trail/version.rb +8 -3
  24. data/lib/paper_trail/frameworks/cucumber.rb +5 -3
  25. data/lib/paper_trail/frameworks/rails.rb +2 -0
  26. data/lib/paper_trail/frameworks/rails/controller.rb +33 -43
  27. data/lib/paper_trail/frameworks/rails/engine.rb +34 -1
  28. data/lib/paper_trail/frameworks/rspec.rb +17 -4
  29. data/lib/paper_trail/frameworks/rspec/helpers.rb +2 -0
  30. data/lib/paper_trail/has_paper_trail.rb +22 -310
  31. data/lib/paper_trail/model_config.rb +157 -109
  32. data/lib/paper_trail/queries/versions/where_object.rb +65 -0
  33. data/lib/paper_trail/queries/versions/where_object_changes.rb +75 -0
  34. data/lib/paper_trail/record_history.rb +3 -9
  35. data/lib/paper_trail/record_trail.rb +169 -319
  36. data/lib/paper_trail/reifier.rb +53 -374
  37. data/lib/paper_trail/request.rb +166 -0
  38. data/lib/paper_trail/serializers/json.rb +9 -10
  39. data/lib/paper_trail/serializers/yaml.rb +15 -28
  40. data/lib/paper_trail/type_serializers/postgres_array_serializer.rb +48 -0
  41. data/lib/paper_trail/version_concern.rb +160 -155
  42. data/lib/paper_trail/version_number.rb +12 -4
  43. metadata +77 -372
  44. data/.github/CONTRIBUTING.md +0 -109
  45. data/.github/ISSUE_TEMPLATE.md +0 -13
  46. data/.gitignore +0 -23
  47. data/.rspec +0 -2
  48. data/.rubocop.yml +0 -99
  49. data/.rubocop_todo.yml +0 -22
  50. data/.travis.yml +0 -41
  51. data/Appraisals +0 -38
  52. data/CHANGELOG.md +0 -560
  53. data/Gemfile +0 -2
  54. data/MIT-LICENSE +0 -20
  55. data/README.md +0 -1654
  56. data/Rakefile +0 -30
  57. data/doc/bug_report_template.rb +0 -69
  58. data/doc/warning_about_not_setting_whodunnit.md +0 -32
  59. data/gemfiles/ar3.gemfile +0 -19
  60. data/gemfiles/ar4.gemfile +0 -8
  61. data/gemfiles/ar5.gemfile +0 -9
  62. data/lib/generators/paper_trail/USAGE +0 -2
  63. data/lib/generators/paper_trail/default_initializer.rb +0 -0
  64. data/lib/generators/paper_trail/install_generator.rb +0 -57
  65. data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +0 -13
  66. data/lib/generators/paper_trail/templates/create_version_associations.rb +0 -22
  67. data/lib/generators/paper_trail/templates/create_versions.rb +0 -80
  68. data/lib/paper_trail/attribute_serializers/legacy_active_record_shim.rb +0 -48
  69. data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +0 -11
  70. data/lib/paper_trail/frameworks/sinatra.rb +0 -40
  71. data/lib/paper_trail/version_association_concern.rb +0 -17
  72. data/paper_trail.gemspec +0 -56
  73. data/spec/generators/install_generator_spec.rb +0 -66
  74. data/spec/generators/paper_trail/templates/create_versions_spec.rb +0 -51
  75. data/spec/models/animal_spec.rb +0 -36
  76. data/spec/models/boolit_spec.rb +0 -48
  77. data/spec/models/callback_modifier_spec.rb +0 -96
  78. data/spec/models/car_spec.rb +0 -13
  79. data/spec/models/custom_primary_key_record_spec.rb +0 -18
  80. data/spec/models/fluxor_spec.rb +0 -17
  81. data/spec/models/gadget_spec.rb +0 -68
  82. data/spec/models/joined_version_spec.rb +0 -47
  83. data/spec/models/json_version_spec.rb +0 -102
  84. data/spec/models/kitchen/banana_spec.rb +0 -14
  85. data/spec/models/not_on_update_spec.rb +0 -22
  86. data/spec/models/post_with_status_spec.rb +0 -50
  87. data/spec/models/skipper_spec.rb +0 -46
  88. data/spec/models/thing_spec.rb +0 -11
  89. data/spec/models/truck_spec.rb +0 -5
  90. data/spec/models/vehicle_spec.rb +0 -5
  91. data/spec/models/version_spec.rb +0 -272
  92. data/spec/models/widget_spec.rb +0 -343
  93. data/spec/modules/paper_trail_spec.rb +0 -27
  94. data/spec/modules/version_concern_spec.rb +0 -31
  95. data/spec/modules/version_number_spec.rb +0 -43
  96. data/spec/paper_trail/config_spec.rb +0 -33
  97. data/spec/paper_trail_spec.rb +0 -79
  98. data/spec/rails_helper.rb +0 -34
  99. data/spec/requests/articles_spec.rb +0 -34
  100. data/spec/spec_helper.rb +0 -114
  101. data/spec/support/alt_db_init.rb +0 -54
  102. data/test/custom_json_serializer.rb +0 -13
  103. data/test/dummy/Rakefile +0 -7
  104. data/test/dummy/app/controllers/application_controller.rb +0 -33
  105. data/test/dummy/app/controllers/articles_controller.rb +0 -20
  106. data/test/dummy/app/controllers/test_controller.rb +0 -5
  107. data/test/dummy/app/controllers/widgets_controller.rb +0 -32
  108. data/test/dummy/app/helpers/application_helper.rb +0 -2
  109. data/test/dummy/app/models/animal.rb +0 -6
  110. data/test/dummy/app/models/article.rb +0 -24
  111. data/test/dummy/app/models/authorship.rb +0 -5
  112. data/test/dummy/app/models/bar_habtm.rb +0 -4
  113. data/test/dummy/app/models/book.rb +0 -9
  114. data/test/dummy/app/models/boolit.rb +0 -4
  115. data/test/dummy/app/models/callback_modifier.rb +0 -45
  116. data/test/dummy/app/models/car.rb +0 -3
  117. data/test/dummy/app/models/cat.rb +0 -2
  118. data/test/dummy/app/models/chapter.rb +0 -9
  119. data/test/dummy/app/models/citation.rb +0 -5
  120. data/test/dummy/app/models/custom_primary_key_record.rb +0 -13
  121. data/test/dummy/app/models/customer.rb +0 -4
  122. data/test/dummy/app/models/document.rb +0 -4
  123. data/test/dummy/app/models/dog.rb +0 -2
  124. data/test/dummy/app/models/editor.rb +0 -4
  125. data/test/dummy/app/models/editorship.rb +0 -5
  126. data/test/dummy/app/models/elephant.rb +0 -3
  127. data/test/dummy/app/models/fluxor.rb +0 -3
  128. data/test/dummy/app/models/foo_habtm.rb +0 -5
  129. data/test/dummy/app/models/foo_widget.rb +0 -2
  130. data/test/dummy/app/models/fruit.rb +0 -5
  131. data/test/dummy/app/models/gadget.rb +0 -3
  132. data/test/dummy/app/models/kitchen/banana.rb +0 -5
  133. data/test/dummy/app/models/legacy_widget.rb +0 -4
  134. data/test/dummy/app/models/line_item.rb +0 -4
  135. data/test/dummy/app/models/not_on_update.rb +0 -4
  136. data/test/dummy/app/models/order.rb +0 -5
  137. data/test/dummy/app/models/paragraph.rb +0 -5
  138. data/test/dummy/app/models/person.rb +0 -38
  139. data/test/dummy/app/models/post.rb +0 -3
  140. data/test/dummy/app/models/post_with_status.rb +0 -8
  141. data/test/dummy/app/models/protected_widget.rb +0 -3
  142. data/test/dummy/app/models/quotation.rb +0 -5
  143. data/test/dummy/app/models/section.rb +0 -6
  144. data/test/dummy/app/models/skipper.rb +0 -6
  145. data/test/dummy/app/models/song.rb +0 -41
  146. data/test/dummy/app/models/thing.rb +0 -3
  147. data/test/dummy/app/models/translation.rb +0 -4
  148. data/test/dummy/app/models/truck.rb +0 -4
  149. data/test/dummy/app/models/vehicle.rb +0 -4
  150. data/test/dummy/app/models/whatchamajigger.rb +0 -4
  151. data/test/dummy/app/models/widget.rb +0 -16
  152. data/test/dummy/app/models/wotsit.rb +0 -8
  153. data/test/dummy/app/versions/custom_primary_key_record_version.rb +0 -3
  154. data/test/dummy/app/versions/joined_version.rb +0 -6
  155. data/test/dummy/app/versions/json_version.rb +0 -3
  156. data/test/dummy/app/versions/kitchen/banana_version.rb +0 -5
  157. data/test/dummy/app/versions/post_version.rb +0 -3
  158. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  159. data/test/dummy/config.ru +0 -4
  160. data/test/dummy/config/application.rb +0 -80
  161. data/test/dummy/config/boot.rb +0 -10
  162. data/test/dummy/config/database.mysql.yml +0 -19
  163. data/test/dummy/config/database.postgres.yml +0 -15
  164. data/test/dummy/config/database.sqlite.yml +0 -15
  165. data/test/dummy/config/environment.rb +0 -5
  166. data/test/dummy/config/environments/development.rb +0 -41
  167. data/test/dummy/config/environments/production.rb +0 -74
  168. data/test/dummy/config/environments/test.rb +0 -51
  169. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -9
  170. data/test/dummy/config/initializers/inflections.rb +0 -10
  171. data/test/dummy/config/initializers/mime_types.rb +0 -5
  172. data/test/dummy/config/initializers/paper_trail.rb +0 -9
  173. data/test/dummy/config/initializers/secret_token.rb +0 -9
  174. data/test/dummy/config/initializers/session_store.rb +0 -8
  175. data/test/dummy/config/locales/en.yml +0 -5
  176. data/test/dummy/config/routes.rb +0 -4
  177. data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +0 -361
  178. data/test/dummy/db/schema.rb +0 -288
  179. data/test/dummy/script/rails +0 -8
  180. data/test/functional/controller_test.rb +0 -90
  181. data/test/functional/enabled_for_controller_test.rb +0 -28
  182. data/test/functional/modular_sinatra_test.rb +0 -46
  183. data/test/functional/sinatra_test.rb +0 -51
  184. data/test/functional/thread_safety_test.rb +0 -46
  185. data/test/test_helper.rb +0 -127
  186. data/test/time_travel_helper.rb +0 -1
  187. data/test/unit/associations_test.rb +0 -1016
  188. data/test/unit/cleaner_test.rb +0 -188
  189. data/test/unit/inheritance_column_test.rb +0 -43
  190. data/test/unit/model_test.rb +0 -1489
  191. data/test/unit/protected_attrs_test.rb +0 -52
  192. data/test/unit/serializer_test.rb +0 -119
  193. data/test/unit/serializers/json_test.rb +0 -95
  194. data/test/unit/serializers/mixin_json_test.rb +0 -37
  195. data/test/unit/serializers/mixin_yaml_test.rb +0 -53
  196. data/test/unit/serializers/yaml_test.rb +0 -54
  197. data/test/unit/timestamp_test.rb +0 -41
  198. data/test/unit/version_test.rb +0 -119
@@ -1,47 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe JoinedVersion, type: :model, versioning: true do
4
- it { expect(JoinedVersion.superclass).to be PaperTrail::Version }
5
-
6
- let(:widget) { Widget.create!(name: FFaker::Name.name) }
7
- let(:version) { JoinedVersion.first }
8
-
9
- describe "Scopes" do
10
- describe "default_scope" do
11
- it { expect(JoinedVersion.default_scopes).not_to be_empty }
12
- end
13
-
14
- describe "VersionConcern::ClassMethods" do
15
- before { widget } # persist a widget
16
-
17
- describe "#subsequent" do
18
- it "shouldn't error out when there is a default_scope that joins" do
19
- JoinedVersion.subsequent(version).first
20
- end
21
- end
22
-
23
- describe "#preceding" do
24
- it "shouldn't error out when there is a default scope that joins" do
25
- JoinedVersion.preceding(version).first
26
- end
27
- end
28
-
29
- describe "#between" do
30
- it "shouldn't error out when there is a default scope that joins" do
31
- JoinedVersion.between(Time.now, 1.minute.from_now).first
32
- end
33
- end
34
- end
35
- end
36
-
37
- describe "Methods" do
38
- describe "#index" do
39
- it { is_expected.to respond_to(:index) }
40
-
41
- it "shouldn't error out when there is a default scope that joins" do
42
- widget # persist a widget
43
- version.index
44
- end
45
- end
46
- end
47
- end
@@ -1,102 +0,0 @@
1
- require "rails_helper"
2
-
3
- # The `json_versions` table tests postgres' `json` data type. So, that
4
- # table is only created when testing against postgres and ActiveRecord >= 4.
5
- if JsonVersion.table_exists?
6
-
7
- describe JsonVersion, type: :model do
8
- it "should include the `VersionConcern` module to get base functionality" do
9
- expect(JsonVersion).to include(PaperTrail::VersionConcern)
10
- end
11
-
12
- describe "Methods" do
13
- describe "Class" do
14
- describe "#where_object" do
15
- it { expect(JsonVersion).to respond_to(:where_object) }
16
-
17
- it "escapes values" do
18
- f = Fruit.create(name: "Bobby")
19
- expect(
20
- f.
21
- versions.
22
- where_object(name: "Robert'; DROP TABLE Students;--").
23
- count
24
- ).to eq(0)
25
- end
26
-
27
- context "invalid arguments" do
28
- it "should raise an error" do
29
- expect { JsonVersion.where_object(:foo) }.to raise_error(ArgumentError)
30
- expect { JsonVersion.where_object([]) }.to raise_error(ArgumentError)
31
- end
32
- end
33
-
34
- context "valid arguments", versioning: true do
35
- let(:fruit_names) { %w(apple orange lemon banana lime coconut strawberry blueberry) }
36
- let(:fruit) { Fruit.new }
37
- let(:name) { "pomegranate" }
38
- let(:color) { FFaker::Color.name }
39
-
40
- before do
41
- fruit.update_attributes!(name: name)
42
- fruit.update_attributes!(name: fruit_names.sample, color: color)
43
- fruit.update_attributes!(name: fruit_names.sample, color: FFaker::Color.name)
44
- end
45
-
46
- it "should be able to locate versions according to their `object` contents" do
47
- expect(JsonVersion.where_object(name: name)).to eq([fruit.versions[1]])
48
- expect(JsonVersion.where_object(color: color)).to eq([fruit.versions[2]])
49
- end
50
- end
51
- end
52
-
53
- describe "#where_object_changes" do
54
- it { expect(JsonVersion).to respond_to(:where_object_changes) }
55
-
56
- it "escapes values" do
57
- f = Fruit.create(name: "Bobby")
58
- expect(
59
- f.
60
- versions.
61
- where_object_changes(name: "Robert'; DROP TABLE Students;--").
62
- count
63
- ).to eq(0)
64
- end
65
-
66
- context "invalid arguments" do
67
- it "should raise an error" do
68
- expect { JsonVersion.where_object_changes(:foo) }.to raise_error(ArgumentError)
69
- expect { JsonVersion.where_object_changes([]) }.to raise_error(ArgumentError)
70
- end
71
- end
72
-
73
- context "valid arguments", versioning: true do
74
- let(:color) { %w(red green) }
75
- let(:fruit) { Fruit.create!(name: name[0]) }
76
- let(:name) { %w(banana kiwi mango) }
77
-
78
- before do
79
- fruit.update_attributes!(name: name[1], color: color[0])
80
- fruit.update_attributes!(name: name[2], color: color[1])
81
- end
82
-
83
- it "finds versions according to their `object_changes` contents" do
84
- expect(
85
- fruit.versions.where_object_changes(name: name[0])
86
- ).to match_array(fruit.versions[0..1])
87
- expect(
88
- fruit.versions.where_object_changes(color: color[0])
89
- ).to match_array(fruit.versions[1..2])
90
- end
91
-
92
- it "finds versions with multiple attributes changed" do
93
- expect(
94
- fruit.versions.where_object_changes(color: color[0], name: name[0])
95
- ).to match_array([fruit.versions[1]])
96
- end
97
- end
98
- end
99
- end
100
- end
101
- end
102
- end
@@ -1,14 +0,0 @@
1
- require "rails_helper"
2
-
3
- module Kitchen
4
- describe Banana, type: :model do
5
- it { is_expected.to be_versioned }
6
-
7
- describe "#versions" do
8
- it "returns instances of Kitchen::BananaVersion", versioning: true do
9
- banana = described_class.create!
10
- expect(banana.versions.first).to be_a(Kitchen::BananaVersion)
11
- end
12
- end
13
- end
14
- end
@@ -1,22 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe NotOnUpdate, type: :model do
4
- describe "#touch_with_version", versioning: true do
5
- let!(:record) { described_class.create! }
6
-
7
- it "should create a version, regardless" do
8
- expect { record.paper_trail.touch_with_version }.to change {
9
- PaperTrail::Version.count
10
- }.by(+1)
11
- end
12
-
13
- it "increments the `:updated_at` timestamp" do
14
- before = record.updated_at
15
- # Travel 1 second because MySQL lacks sub-second resolution
16
- Timecop.travel(1) do
17
- record.paper_trail.touch_with_version
18
- end
19
- expect(record.updated_at).to be > before
20
- end
21
- end
22
- end
@@ -1,50 +0,0 @@
1
- require "rails_helper"
2
-
3
- # This model tests ActiveRecord::Enum, which was added in AR 4.1
4
- # http://edgeguides.rubyonrails.org/4_1_release_notes.html#active-record-enums
5
- describe PostWithStatus, type: :model do
6
- if defined?(ActiveRecord::Enum)
7
- with_versioning do
8
- let(:post) { described_class.create!(status: "draft") }
9
-
10
- it "should stash the enum value properly in versions" do
11
- post.published!
12
- post.archived!
13
- expect(post.paper_trail.previous_version.published?).to be true
14
- end
15
-
16
- it "can read enums in version records written by PT 4" do
17
- post = described_class.create(status: "draft")
18
- post.published!
19
- version = post.versions.last
20
- # Simulate behavior PT 4, which used to save the string version of
21
- # enums to `object_changes`
22
- version.update(object_changes: "---\nid:\n- \n- 1\nstatus:\n- draft\n- published\n")
23
- assert_equal %w(draft published), version.changeset["status"]
24
- end
25
-
26
- context "storing enum object_changes" do
27
- subject { post.versions.last }
28
-
29
- it "should stash the enum value properly in versions object_changes" do
30
- post.published!
31
- post.archived!
32
- expect(subject.changeset["status"]).to eql %w(published archived)
33
- end
34
- end
35
-
36
- describe "#touch_with_version" do
37
- it "preserves the enum value (and all other attributes)" do
38
- post = described_class.create(status: :draft)
39
- expect(post.versions.count).to eq(1)
40
- expect(post.status).to eq("draft")
41
- Timecop.travel 1.second.since # because MySQL lacks fractional seconds precision
42
- post.paper_trail.touch_with_version
43
- expect(post.versions.count).to eq(2)
44
- expect(post.versions.last[:object]).to include("status: 0")
45
- expect(post.paper_trail.previous_version.status).to eq("draft")
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,46 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe Skipper, type: :model do
4
- with_versioning do
5
- it { is_expected.to be_versioned }
6
-
7
- describe "#update_attributes!", versioning: true do
8
- context "updating a skipped attribute" do
9
- let(:t1) { Time.zone.local(2015, 7, 15, 20, 34, 0) }
10
- let(:t2) { Time.zone.local(2015, 7, 15, 20, 34, 30) }
11
-
12
- it "should not create a version" do
13
- skipper = Skipper.create!(another_timestamp: t1)
14
- expect {
15
- skipper.update_attributes!(another_timestamp: t2)
16
- }.to_not change { skipper.versions.length }
17
- end
18
- end
19
- end
20
-
21
- describe "reify" do
22
- context "reifying a with a skipped attribute" do
23
- let(:t1) { Time.zone.local(2015, 7, 15, 20, 34, 0) }
24
- let(:t2) { Time.zone.local(2015, 7, 15, 20, 34, 30) }
25
-
26
- context "without preserve (default)" do
27
- it "should have no timestamp" do
28
- skipper = Skipper.create!(another_timestamp: t1)
29
- skipper.update_attributes!(another_timestamp: t2, name: "Foobar")
30
- skipper = skipper.versions.last.reify
31
- expect(skipper.another_timestamp).to be(nil)
32
- end
33
- end
34
-
35
- context "with preserve" do
36
- it "should preserve its timestamp" do
37
- skipper = Skipper.create!(another_timestamp: t1)
38
- skipper.update_attributes!(another_timestamp: t2, name: "Foobar")
39
- skipper = skipper.versions.last.reify(unversioned_attributes: :preserve)
40
- expect(skipper.another_timestamp).to eq(t2)
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,11 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe Thing, type: :model do
4
- it { is_expected.to be_versioned }
5
-
6
- describe "should not store object_changes", versioning: true do
7
- let(:thing) { Thing.create(name: "pencil") }
8
-
9
- it { expect(thing.versions.last.object_changes).to be_nil }
10
- end
11
- end
@@ -1,5 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe Truck, type: :model do
4
- it { is_expected.to_not be_versioned }
5
- end
@@ -1,5 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe Vehicle, type: :model do
4
- it { is_expected.to_not be_versioned }
5
- end
@@ -1,272 +0,0 @@
1
- require "rails_helper"
2
-
3
- describe PaperTrail::Version, type: :model do
4
- it "should include the `VersionConcern` module to get base functionality" do
5
- expect(PaperTrail::Version).to include(PaperTrail::VersionConcern)
6
- end
7
-
8
- describe "Attributes" do
9
- describe "object_changes column", versioning: true do
10
- let(:widget) { Widget.create!(name: "Dashboard") }
11
- let(:value) { widget.versions.last.object_changes }
12
-
13
- context "serializer is YAML" do
14
- specify { expect(PaperTrail.serializer).to be PaperTrail::Serializers::YAML }
15
-
16
- it "should store out as a plain hash" do
17
- expect(value =~ /HashWithIndifferentAccess/).to be_nil
18
- end
19
- end
20
-
21
- context "serializer is JSON" do
22
- before(:all) { PaperTrail.serializer = PaperTrail::Serializers::JSON }
23
-
24
- it "should store out as a plain hash" do
25
- expect(value =~ /HashWithIndifferentAccess/).to be_nil
26
- end
27
-
28
- after(:all) { PaperTrail.serializer = PaperTrail::Serializers::YAML }
29
- end
30
- end
31
- end
32
-
33
- describe "Methods" do
34
- describe "Instance" do
35
- subject { PaperTrail::Version.new }
36
-
37
- describe "#paper_trail_originator" do
38
- it { is_expected.to respond_to(:paper_trail_originator) }
39
-
40
- context "No previous versions" do
41
- specify { expect(subject.previous).to be_nil }
42
-
43
- it "should return nil" do
44
- expect(subject.paper_trail_originator).to be_nil
45
- end
46
- end
47
-
48
- context "Has previous version", versioning: true do
49
- let(:name) { FFaker::Name.name }
50
- let(:widget) { Widget.create!(name: FFaker::Name.name) }
51
- before do
52
- widget.versions.first.update_attributes!(whodunnit: name)
53
- widget.update_attributes!(name: FFaker::Name.first_name)
54
- end
55
- subject { widget.versions.last }
56
-
57
- specify { expect(subject.previous).to be_instance_of(PaperTrail::Version) }
58
-
59
- it "should return nil" do
60
- expect(subject.paper_trail_originator).to eq(name)
61
- end
62
- end
63
- end
64
-
65
- describe "#originator" do
66
- it { is_expected.to respond_to(:originator) }
67
-
68
- it "should set the invoke `paper_trail_originator`" do
69
- allow(ActiveSupport::Deprecation).to receive(:warn)
70
- is_expected.to receive(:paper_trail_originator)
71
- subject.originator
72
- end
73
-
74
- it "should display a deprecation warning" do
75
- expect(ActiveSupport::Deprecation).to receive(:warn).
76
- with(/Use paper_trail_originator instead of originator/)
77
- subject.originator
78
- end
79
- end
80
-
81
- describe "#terminator" do
82
- let(:attributes) { { whodunnit: FFaker::Name.first_name } }
83
- subject { PaperTrail::Version.new attributes }
84
-
85
- it { is_expected.to respond_to(:terminator) }
86
-
87
- it "is an alias for the `whodunnit` attribute" do
88
- expect(subject.terminator).to eq(attributes[:whodunnit])
89
- end
90
- end
91
-
92
- describe "#version_author" do
93
- it { is_expected.to respond_to(:version_author) }
94
-
95
- it "should be an alias for the `terminator` method" do
96
- expect(subject.method(:version_author)).to eq(subject.method(:terminator))
97
- end
98
- end
99
- end
100
-
101
- describe "Class" do
102
- column_overrides = [false]
103
- if ENV["DB"] == "postgres" && ::ActiveRecord::VERSION::MAJOR >= 4
104
- column_overrides << "json"
105
- # 'jsonb' column types are only supported for ActiveRecord 4.2+
106
- column_overrides << "jsonb" if ::ActiveRecord::VERSION::STRING >= "4.2"
107
- end
108
-
109
- column_overrides.shuffle.each do |override|
110
- context "with a #{override || 'text'} column" do
111
- before do
112
- if override
113
- ActiveRecord::Base.connection.execute("SAVEPOINT pgtest;")
114
- %w(object object_changes).each do |column|
115
- ActiveRecord::Base.connection.execute(
116
- "ALTER TABLE versions DROP COLUMN #{column};"
117
- )
118
- ActiveRecord::Base.connection.execute(
119
- "ALTER TABLE versions ADD COLUMN #{column} #{override};"
120
- )
121
- end
122
- PaperTrail::Version.reset_column_information
123
- end
124
- end
125
- after do
126
- if override
127
- ActiveRecord::Base.connection.execute("ROLLBACK TO SAVEPOINT pgtest;")
128
- PaperTrail::Version.reset_column_information
129
- end
130
- end
131
-
132
- describe "#where_object" do
133
- it { expect(PaperTrail::Version).to respond_to(:where_object) }
134
-
135
- context "invalid arguments" do
136
- it "should raise an error" do
137
- expect {
138
- PaperTrail::Version.where_object(:foo)
139
- }.to raise_error(ArgumentError)
140
- expect {
141
- PaperTrail::Version.where_object([])
142
- }.to raise_error(ArgumentError)
143
- end
144
- end
145
-
146
- context "valid arguments", versioning: true do
147
- let(:widget) { Widget.new }
148
- let(:name) { FFaker::Name.first_name }
149
- let(:int) { rand(10) + 1 }
150
-
151
- before do
152
- widget.update_attributes!(name: name, an_integer: int)
153
- widget.update_attributes!(name: "foobar", an_integer: 100)
154
- widget.update_attributes!(name: FFaker::Name.last_name, an_integer: 15)
155
- end
156
-
157
- context "`serializer == YAML`" do
158
- specify do
159
- expect(PaperTrail.serializer).to be PaperTrail::Serializers::YAML
160
- end
161
-
162
- it "should be able to locate versions according to their `object` contents" do
163
- expect(
164
- PaperTrail::Version.where_object(name: name)
165
- ).to eq([widget.versions[1]])
166
- expect(
167
- PaperTrail::Version.where_object(an_integer: 100)
168
- ).to eq([widget.versions[2]])
169
- end
170
- end
171
-
172
- context "JSON serializer" do
173
- before(:all) do
174
- PaperTrail.serializer = PaperTrail::Serializers::JSON
175
- end
176
-
177
- specify do
178
- expect(PaperTrail.serializer).to be PaperTrail::Serializers::JSON
179
- end
180
-
181
- it "should be able to locate versions according to their `object` contents" do
182
- expect(
183
- PaperTrail::Version.where_object(name: name)
184
- ).to eq([widget.versions[1]])
185
- expect(
186
- PaperTrail::Version.where_object(an_integer: 100)
187
- ).to eq([widget.versions[2]])
188
- end
189
-
190
- after(:all) do
191
- PaperTrail.serializer = PaperTrail::Serializers::YAML
192
- end
193
- end
194
- end
195
- end
196
-
197
- describe "#where_object_changes" do
198
- context "invalid arguments" do
199
- it "should raise an error" do
200
- expect {
201
- PaperTrail::Version.where_object_changes(:foo)
202
- }.to raise_error(ArgumentError)
203
- expect {
204
- PaperTrail::Version.where_object_changes([])
205
- }.to raise_error(ArgumentError)
206
- end
207
- end
208
-
209
- context "valid arguments", versioning: true do
210
- let(:widget) { Widget.new }
211
- let(:name) { FFaker::Name.first_name }
212
- let(:int) { rand(5) + 2 }
213
-
214
- before do
215
- widget.update_attributes!(name: name, an_integer: 0)
216
- widget.update_attributes!(name: "foobar", an_integer: 77)
217
- widget.update_attributes!(name: FFaker::Name.last_name, an_integer: int)
218
- end
219
-
220
- context "YAML serializer" do
221
- specify { expect(PaperTrail.serializer).to be PaperTrail::Serializers::YAML }
222
-
223
- it "locates versions according to their `object_changes` contents" do
224
- expect(
225
- widget.versions.where_object_changes(name: name)
226
- ).to eq(widget.versions[0..1])
227
- expect(
228
- widget.versions.where_object_changes(an_integer: 77)
229
- ).to eq(widget.versions[1..2])
230
- expect(
231
- widget.versions.where_object_changes(an_integer: int)
232
- ).to eq([widget.versions.last])
233
- end
234
-
235
- it "handles queries for multiple attributes" do
236
- expect(
237
- widget.versions.where_object_changes(an_integer: 77, name: "foobar")
238
- ).to eq(widget.versions[1..2])
239
- end
240
- end
241
-
242
- context "JSON serializer" do
243
- before(:all) { PaperTrail.serializer = PaperTrail::Serializers::JSON }
244
- specify { expect(PaperTrail.serializer).to be PaperTrail::Serializers::JSON }
245
-
246
- it "locates versions according to their `object_changes` contents" do
247
- expect(
248
- widget.versions.where_object_changes(name: name)
249
- ).to eq(widget.versions[0..1])
250
- expect(
251
- widget.versions.where_object_changes(an_integer: 77)
252
- ).to eq(widget.versions[1..2])
253
- expect(
254
- widget.versions.where_object_changes(an_integer: int)
255
- ).to eq([widget.versions.last])
256
- end
257
-
258
- it "handles queries for multiple attributes" do
259
- expect(
260
- widget.versions.where_object_changes(an_integer: 77, name: "foobar")
261
- ).to eq(widget.versions[1..2])
262
- end
263
-
264
- after(:all) { PaperTrail.serializer = PaperTrail::Serializers::YAML }
265
- end
266
- end
267
- end
268
- end
269
- end
270
- end
271
- end
272
- end