paper_trail 4.2.0 → 5.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.
- checksums.yaml +4 -4
- data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +28 -9
- data/.github/ISSUE_TEMPLATE.md +13 -0
- data/.gitignore +2 -1
- data/.rubocop.yml +100 -0
- data/.rubocop_todo.yml +14 -0
- data/.travis.yml +8 -9
- data/Appraisals +41 -0
- data/CHANGELOG.md +49 -9
- data/Gemfile +1 -1
- data/README.md +130 -109
- data/Rakefile +19 -19
- data/doc/bug_report_template.rb +20 -14
- data/gemfiles/ar3.gemfile +10 -53
- data/gemfiles/ar4.gemfile +7 -0
- data/gemfiles/ar5.gemfile +13 -0
- data/lib/generators/paper_trail/install_generator.rb +26 -18
- data/lib/generators/paper_trail/templates/add_object_changes_to_versions.rb +4 -2
- data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +2 -0
- data/lib/generators/paper_trail/templates/create_version_associations.rb +9 -4
- data/lib/generators/paper_trail/templates/create_versions.rb +39 -5
- data/lib/paper_trail.rb +169 -146
- data/lib/paper_trail/attributes_serialization.rb +89 -17
- data/lib/paper_trail/cleaner.rb +15 -9
- data/lib/paper_trail/config.rb +28 -11
- data/lib/paper_trail/frameworks/active_record.rb +4 -0
- data/lib/paper_trail/frameworks/active_record/models/paper_trail/version.rb +5 -1
- data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +6 -2
- data/lib/paper_trail/frameworks/cucumber.rb +1 -0
- data/lib/paper_trail/frameworks/rails.rb +2 -7
- data/lib/paper_trail/frameworks/rails/controller.rb +29 -9
- data/lib/paper_trail/frameworks/rails/engine.rb +7 -1
- data/lib/paper_trail/frameworks/rspec.rb +5 -5
- data/lib/paper_trail/frameworks/rspec/helpers.rb +3 -1
- data/lib/paper_trail/frameworks/sinatra.rb +6 -4
- data/lib/paper_trail/has_paper_trail.rb +199 -106
- data/lib/paper_trail/record_history.rb +1 -3
- data/lib/paper_trail/reifier.rb +297 -118
- data/lib/paper_trail/serializers/json.rb +3 -3
- data/lib/paper_trail/serializers/yaml.rb +27 -8
- data/lib/paper_trail/version_association_concern.rb +3 -1
- data/lib/paper_trail/version_concern.rb +75 -35
- data/lib/paper_trail/version_number.rb +6 -9
- data/paper_trail.gemspec +44 -51
- data/spec/generators/install_generator_spec.rb +24 -25
- data/spec/generators/paper_trail/templates/create_versions_spec.rb +51 -0
- data/spec/models/animal_spec.rb +12 -12
- data/spec/models/boolit_spec.rb +8 -8
- data/spec/models/callback_modifier_spec.rb +47 -47
- data/spec/models/car_spec.rb +13 -0
- data/spec/models/fluxor_spec.rb +3 -3
- data/spec/models/gadget_spec.rb +19 -19
- data/spec/models/joined_version_spec.rb +3 -3
- data/spec/models/json_version_spec.rb +23 -24
- data/spec/models/kitchen/banana_spec.rb +3 -3
- data/spec/models/not_on_update_spec.rb +7 -4
- data/spec/models/post_with_status_spec.rb +13 -3
- data/spec/models/skipper_spec.rb +10 -10
- data/spec/models/thing_spec.rb +4 -4
- data/spec/models/truck_spec.rb +5 -0
- data/spec/models/vehicle_spec.rb +5 -0
- data/spec/models/version_spec.rb +103 -59
- data/spec/models/widget_spec.rb +82 -52
- data/spec/modules/paper_trail_spec.rb +2 -2
- data/spec/modules/version_concern_spec.rb +11 -12
- data/spec/modules/version_number_spec.rb +2 -4
- data/spec/paper_trail/config_spec.rb +10 -29
- data/spec/paper_trail_spec.rb +16 -14
- data/spec/rails_helper.rb +10 -9
- data/spec/requests/articles_spec.rb +11 -7
- data/spec/spec_helper.rb +41 -22
- data/spec/support/alt_db_init.rb +8 -13
- data/test/custom_json_serializer.rb +3 -3
- data/test/dummy/Rakefile +2 -2
- data/test/dummy/app/controllers/application_controller.rb +21 -8
- data/test/dummy/app/controllers/articles_controller.rb +11 -8
- data/test/dummy/app/controllers/widgets_controller.rb +13 -12
- data/test/dummy/app/models/animal.rb +1 -1
- data/test/dummy/app/models/article.rb +19 -11
- data/test/dummy/app/models/authorship.rb +1 -1
- data/test/dummy/app/models/bar_habtm.rb +4 -0
- data/test/dummy/app/models/book.rb +4 -4
- data/test/dummy/app/models/boolit.rb +1 -1
- data/test/dummy/app/models/callback_modifier.rb +6 -6
- data/test/dummy/app/models/car.rb +3 -0
- data/test/dummy/app/models/chapter.rb +4 -4
- data/test/dummy/app/models/customer.rb +1 -1
- data/test/dummy/app/models/document.rb +2 -2
- data/test/dummy/app/models/editor.rb +1 -1
- data/test/dummy/app/models/foo_habtm.rb +4 -0
- data/test/dummy/app/models/fruit.rb +2 -2
- data/test/dummy/app/models/gadget.rb +1 -1
- data/test/dummy/app/models/kitchen/banana.rb +1 -1
- data/test/dummy/app/models/legacy_widget.rb +2 -2
- data/test/dummy/app/models/line_item.rb +1 -1
- data/test/dummy/app/models/not_on_update.rb +1 -1
- data/test/dummy/app/models/person.rb +6 -6
- data/test/dummy/app/models/post.rb +1 -1
- data/test/dummy/app/models/post_with_status.rb +1 -1
- data/test/dummy/app/models/quotation.rb +1 -1
- data/test/dummy/app/models/section.rb +1 -1
- data/test/dummy/app/models/skipper.rb +2 -2
- data/test/dummy/app/models/song.rb +13 -4
- data/test/dummy/app/models/thing.rb +2 -2
- data/test/dummy/app/models/translation.rb +2 -2
- data/test/dummy/app/models/truck.rb +4 -0
- data/test/dummy/app/models/vehicle.rb +4 -0
- data/test/dummy/app/models/whatchamajigger.rb +1 -1
- data/test/dummy/app/models/widget.rb +7 -6
- data/test/dummy/app/versions/joined_version.rb +4 -3
- data/test/dummy/app/versions/json_version.rb +1 -1
- data/test/dummy/app/versions/kitchen/banana_version.rb +1 -1
- data/test/dummy/app/versions/post_version.rb +2 -2
- data/test/dummy/config.ru +1 -1
- data/test/dummy/config/application.rb +20 -9
- data/test/dummy/config/boot.rb +5 -5
- data/test/dummy/config/environment.rb +1 -1
- data/test/dummy/config/environments/development.rb +4 -3
- data/test/dummy/config/environments/production.rb +3 -2
- data/test/dummy/config/environments/test.rb +15 -5
- data/test/dummy/config/initializers/backtrace_silencers.rb +4 -2
- data/test/dummy/config/initializers/paper_trail.rb +1 -2
- data/test/dummy/config/initializers/secret_token.rb +3 -1
- data/test/dummy/config/initializers/session_store.rb +1 -1
- data/test/dummy/config/routes.rb +2 -2
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +120 -74
- data/test/dummy/db/schema.rb +29 -6
- data/test/dummy/script/rails +6 -4
- data/test/functional/controller_test.rb +34 -35
- data/test/functional/enabled_for_controller_test.rb +6 -7
- data/test/functional/modular_sinatra_test.rb +43 -38
- data/test/functional/sinatra_test.rb +49 -40
- data/test/functional/thread_safety_test.rb +4 -6
- data/test/paper_trail_test.rb +15 -14
- data/test/test_helper.rb +68 -44
- data/test/time_travel_helper.rb +1 -15
- data/test/unit/associations_test.rb +517 -251
- data/test/unit/cleaner_test.rb +66 -60
- data/test/unit/inheritance_column_test.rb +17 -17
- data/test/unit/model_test.rb +611 -504
- data/test/unit/protected_attrs_test.rb +16 -12
- data/test/unit/serializer_test.rb +44 -43
- data/test/unit/serializers/json_test.rb +17 -18
- data/test/unit/serializers/mixin_json_test.rb +15 -14
- data/test/unit/serializers/mixin_yaml_test.rb +20 -16
- data/test/unit/serializers/yaml_test.rb +12 -13
- data/test/unit/timestamp_test.rb +10 -12
- data/test/unit/version_test.rb +7 -7
- metadata +92 -40
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
|
-
describe JoinedVersion, :
|
3
|
+
describe JoinedVersion, type: :model, versioning: true do
|
4
4
|
it { expect(JoinedVersion.superclass).to be PaperTrail::Version }
|
5
5
|
|
6
|
-
let(:widget) { Widget.create!(:
|
6
|
+
let(:widget) { Widget.create!(name: FFaker::Name.name) }
|
7
7
|
let(:version) { JoinedVersion.first }
|
8
8
|
|
9
9
|
describe "Scopes" do
|
@@ -1,26 +1,25 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
3
|
# The `json_versions` table tests postgres' `json` data type. So, that
|
4
4
|
# table is only created when testing against postgres and ActiveRecord >= 4.
|
5
5
|
if JsonVersion.table_exists?
|
6
6
|
|
7
|
-
describe JsonVersion, :
|
7
|
+
describe JsonVersion, type: :model do
|
8
8
|
it "should include the `VersionConcern` module to get base functionality" do
|
9
9
|
expect(JsonVersion).to include(PaperTrail::VersionConcern)
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "Methods" do
|
13
13
|
describe "Class" do
|
14
|
-
|
15
14
|
describe '#where_object' do
|
16
15
|
it { expect(JsonVersion).to respond_to(:where_object) }
|
17
16
|
|
18
17
|
it "escapes values" do
|
19
|
-
f = Fruit.create(:
|
18
|
+
f = Fruit.create(name: "Bobby")
|
20
19
|
expect(
|
21
20
|
f.
|
22
21
|
versions.
|
23
|
-
where_object(:
|
22
|
+
where_object(name: "Robert'; DROP TABLE Students;--").
|
24
23
|
count
|
25
24
|
).to eq(0)
|
26
25
|
end
|
@@ -32,21 +31,21 @@ if JsonVersion.table_exists?
|
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
35
|
-
context "valid arguments", :
|
34
|
+
context "valid arguments", versioning: true do
|
36
35
|
let(:fruit_names) { %w(apple orange lemon banana lime coconut strawberry blueberry) }
|
37
36
|
let(:fruit) { Fruit.new }
|
38
|
-
let(:name) {
|
39
|
-
let(:color) {
|
37
|
+
let(:name) { "pomegranate" }
|
38
|
+
let(:color) { FFaker::Color.name }
|
40
39
|
|
41
40
|
before do
|
42
|
-
fruit.update_attributes!(:
|
43
|
-
fruit.update_attributes!(:
|
44
|
-
fruit.update_attributes!(:
|
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)
|
45
44
|
end
|
46
45
|
|
47
46
|
it "should be able to locate versions according to their `object` contents" do
|
48
|
-
expect(JsonVersion.where_object(:
|
49
|
-
expect(JsonVersion.where_object(:
|
47
|
+
expect(JsonVersion.where_object(name: name)).to eq([fruit.versions[1]])
|
48
|
+
expect(JsonVersion.where_object(color: color)).to eq([fruit.versions[2]])
|
50
49
|
end
|
51
50
|
end
|
52
51
|
end
|
@@ -55,11 +54,11 @@ if JsonVersion.table_exists?
|
|
55
54
|
it { expect(JsonVersion).to respond_to(:where_object_changes) }
|
56
55
|
|
57
56
|
it "escapes values" do
|
58
|
-
f = Fruit.create(:
|
57
|
+
f = Fruit.create(name: "Bobby")
|
59
58
|
expect(
|
60
59
|
f.
|
61
60
|
versions.
|
62
|
-
where_object_changes(:
|
61
|
+
where_object_changes(name: "Robert'; DROP TABLE Students;--").
|
63
62
|
count
|
64
63
|
).to eq(0)
|
65
64
|
end
|
@@ -71,28 +70,28 @@ if JsonVersion.table_exists?
|
|
71
70
|
end
|
72
71
|
end
|
73
72
|
|
74
|
-
context "valid arguments", :
|
75
|
-
let(:color) { %w
|
76
|
-
let(:fruit) { Fruit.create!(:
|
77
|
-
let(:name) { %w
|
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) }
|
78
77
|
|
79
78
|
before do
|
80
|
-
fruit.update_attributes!(:
|
81
|
-
fruit.update_attributes!(:
|
79
|
+
fruit.update_attributes!(name: name[1], color: color[0])
|
80
|
+
fruit.update_attributes!(name: name[2], color: color[1])
|
82
81
|
end
|
83
82
|
|
84
83
|
it "finds versions according to their `object_changes` contents" do
|
85
84
|
expect(
|
86
|
-
fruit.versions.where_object_changes(:
|
85
|
+
fruit.versions.where_object_changes(name: name[0])
|
87
86
|
).to match_array(fruit.versions[0..1])
|
88
87
|
expect(
|
89
|
-
fruit.versions.where_object_changes(:
|
88
|
+
fruit.versions.where_object_changes(color: color[0])
|
90
89
|
).to match_array(fruit.versions[1..2])
|
91
90
|
end
|
92
91
|
|
93
92
|
it "finds versions with multiple attributes changed" do
|
94
93
|
expect(
|
95
|
-
fruit.versions.where_object_changes(:
|
94
|
+
fruit.versions.where_object_changes(color: color[0], name: name[0])
|
96
95
|
).to match_array([fruit.versions[1]])
|
97
96
|
end
|
98
97
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
3
|
module Kitchen
|
4
|
-
describe Banana, :
|
4
|
+
describe Banana, type: :model do
|
5
5
|
it { is_expected.to be_versioned }
|
6
6
|
|
7
7
|
describe '#versions' do
|
8
|
-
it "returns instances of Kitchen::BananaVersion", :
|
8
|
+
it "returns instances of Kitchen::BananaVersion", versioning: true do
|
9
9
|
banana = described_class.create!
|
10
10
|
expect(banana.versions.first).to be_a(Kitchen::BananaVersion)
|
11
11
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
|
-
describe NotOnUpdate, :
|
4
|
-
describe "#touch_with_version", :
|
3
|
+
describe NotOnUpdate, type: :model do
|
4
|
+
describe "#touch_with_version", versioning: true do
|
5
5
|
let!(:record) { described_class.create! }
|
6
6
|
|
7
7
|
it "should create a version, regardless" do
|
@@ -12,7 +12,10 @@ describe NotOnUpdate, :type => :model do
|
|
12
12
|
|
13
13
|
it "increments the `:updated_at` timestamp" do
|
14
14
|
before = record.updated_at
|
15
|
-
|
15
|
+
# Travel 1 second because MySQL lacks sub-second resolution
|
16
|
+
Timecop.travel(1) do
|
17
|
+
record.touch_with_version
|
18
|
+
end
|
16
19
|
expect(record.updated_at).to be > before
|
17
20
|
end
|
18
21
|
end
|
@@ -1,17 +1,27 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
3
|
# This model is in the test suite soley for the purpose of testing ActiveRecord::Enum,
|
4
4
|
# which is available in ActiveRecord4+ only
|
5
|
-
describe PostWithStatus, :
|
5
|
+
describe PostWithStatus, type: :model do
|
6
6
|
if defined?(ActiveRecord::Enum)
|
7
7
|
with_versioning do
|
8
|
-
let(:post) { PostWithStatus.create!(:
|
8
|
+
let(:post) { PostWithStatus.create!(status: "draft") }
|
9
9
|
|
10
10
|
it "should stash the enum value properly in versions" do
|
11
11
|
post.published!
|
12
12
|
post.archived!
|
13
13
|
expect(post.previous_version.published?).to be true
|
14
14
|
end
|
15
|
+
|
16
|
+
context "storing enum object_changes" do
|
17
|
+
subject { post.versions.last }
|
18
|
+
|
19
|
+
it "should stash the enum value properly in versions object_changes" do
|
20
|
+
post.published!
|
21
|
+
post.archived!
|
22
|
+
expect(subject.changeset["status"]).to eql %w(published archived)
|
23
|
+
end
|
24
|
+
end
|
15
25
|
end
|
16
26
|
end
|
17
27
|
end
|
data/spec/models/skipper_spec.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
|
-
describe Skipper, :
|
3
|
+
describe Skipper, type: :model do
|
4
4
|
with_versioning do
|
5
5
|
it { is_expected.to be_versioned }
|
6
6
|
|
7
|
-
describe "#update_attributes!", :
|
7
|
+
describe "#update_attributes!", versioning: true do
|
8
8
|
context "updating a skipped attribute" do
|
9
9
|
let(:t1) { Time.zone.local(2015, 7, 15, 20, 34, 0) }
|
10
10
|
let(:t2) { Time.zone.local(2015, 7, 15, 20, 34, 30) }
|
11
11
|
|
12
12
|
it "should not create a version" do
|
13
|
-
skipper = Skipper.create!(:
|
13
|
+
skipper = Skipper.create!(another_timestamp: t1)
|
14
14
|
expect {
|
15
|
-
skipper.update_attributes!(:
|
15
|
+
skipper.update_attributes!(another_timestamp: t2)
|
16
16
|
}.to_not change { skipper.versions.length }
|
17
17
|
end
|
18
18
|
end
|
@@ -25,8 +25,8 @@ describe Skipper, :type => :model do
|
|
25
25
|
|
26
26
|
context "without preserve (default)" do
|
27
27
|
it "should have no timestamp" do
|
28
|
-
skipper = Skipper.create!(:
|
29
|
-
skipper.update_attributes!(:
|
28
|
+
skipper = Skipper.create!(another_timestamp: t1)
|
29
|
+
skipper.update_attributes!(another_timestamp: t2, name: "Foobar")
|
30
30
|
skipper = skipper.versions.last.reify
|
31
31
|
expect(skipper.another_timestamp).to be(nil)
|
32
32
|
end
|
@@ -34,9 +34,9 @@ describe Skipper, :type => :model do
|
|
34
34
|
|
35
35
|
context "with preserve" do
|
36
36
|
it "should preserve its timestamp" do
|
37
|
-
skipper = Skipper.create!(:
|
38
|
-
skipper.update_attributes!(:
|
39
|
-
skipper = skipper.versions.last.reify(:
|
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
40
|
expect(skipper.another_timestamp).to eq(t2)
|
41
41
|
end
|
42
42
|
end
|
data/spec/models/thing_spec.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
|
-
describe Thing, :
|
3
|
+
describe Thing, type: :model do
|
4
4
|
it { is_expected.to be_versioned }
|
5
5
|
|
6
|
-
describe "should not store object_changes", :
|
7
|
-
let(:thing) { Thing.create(:
|
6
|
+
describe "should not store object_changes", versioning: true do
|
7
|
+
let(:thing) { Thing.create(name: "pencil") }
|
8
8
|
|
9
9
|
it { expect(thing.versions.last.object_changes).to be_nil }
|
10
10
|
end
|
data/spec/models/version_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
|
-
describe PaperTrail::Version, :
|
3
|
+
describe PaperTrail::Version, type: :model do
|
4
4
|
it "should include the `VersionConcern` module to get base functionality" do
|
5
5
|
expect(PaperTrail::Version).to include(PaperTrail::VersionConcern)
|
6
6
|
end
|
@@ -13,8 +13,8 @@ describe PaperTrail::Version, :type => :model do
|
|
13
13
|
it { is_expected.to have_db_column(:object).of_type(:text) }
|
14
14
|
it { is_expected.to have_db_column(:created_at).of_type(:datetime) }
|
15
15
|
|
16
|
-
describe "object_changes column", :
|
17
|
-
let(:widget) { Widget.create!(:
|
16
|
+
describe "object_changes column", versioning: true do
|
17
|
+
let(:widget) { Widget.create!(name: "Dashboard") }
|
18
18
|
let(:value) { widget.versions.last.object_changes }
|
19
19
|
|
20
20
|
context "serializer is YAML" do
|
@@ -43,7 +43,7 @@ describe PaperTrail::Version, :type => :model do
|
|
43
43
|
|
44
44
|
describe "Methods" do
|
45
45
|
describe "Instance" do
|
46
|
-
subject { PaperTrail::Version.new
|
46
|
+
subject { PaperTrail::Version.new }
|
47
47
|
|
48
48
|
describe '#paper_trail_originator' do
|
49
49
|
it { is_expected.to respond_to(:paper_trail_originator) }
|
@@ -56,12 +56,12 @@ describe PaperTrail::Version, :type => :model do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
context "Has previous version", :
|
60
|
-
let(:name) {
|
61
|
-
let(:widget) { Widget.create!(:
|
59
|
+
context "Has previous version", versioning: true do
|
60
|
+
let(:name) { FFaker::Name.name }
|
61
|
+
let(:widget) { Widget.create!(name: FFaker::Name.name) }
|
62
62
|
before do
|
63
|
-
widget.versions.first.update_attributes!(:
|
64
|
-
widget.update_attributes!(:
|
63
|
+
widget.versions.first.update_attributes!(whodunnit: name)
|
64
|
+
widget.update_attributes!(name: FFaker::Name.first_name)
|
65
65
|
end
|
66
66
|
subject { widget.versions.last }
|
67
67
|
|
@@ -76,13 +76,13 @@ describe PaperTrail::Version, :type => :model do
|
|
76
76
|
describe "#originator" do
|
77
77
|
it { is_expected.to respond_to(:originator) }
|
78
78
|
|
79
|
-
it
|
79
|
+
it "should set the invoke `paper_trail_originator`" do
|
80
80
|
allow(ActiveSupport::Deprecation).to receive(:warn)
|
81
81
|
is_expected.to receive(:paper_trail_originator)
|
82
82
|
subject.originator
|
83
83
|
end
|
84
84
|
|
85
|
-
it
|
85
|
+
it "should display a deprecation warning" do
|
86
86
|
expect(ActiveSupport::Deprecation).to receive(:warn).
|
87
87
|
with(/Use paper_trail_originator instead of originator/)
|
88
88
|
subject.originator
|
@@ -90,9 +90,10 @@ describe PaperTrail::Version, :type => :model do
|
|
90
90
|
end
|
91
91
|
|
92
92
|
describe '#terminator' do
|
93
|
-
|
93
|
+
let(:attributes) { { whodunnit: FFaker::Name.first_name } }
|
94
|
+
subject { PaperTrail::Version.new attributes }
|
94
95
|
|
95
|
-
|
96
|
+
it { is_expected.to respond_to(:terminator) }
|
96
97
|
|
97
98
|
it "is an alias for the `whodunnit` attribute" do
|
98
99
|
expect(subject.terminator).to eq(attributes[:whodunnit])
|
@@ -110,10 +111,10 @@ describe PaperTrail::Version, :type => :model do
|
|
110
111
|
|
111
112
|
describe "Class" do
|
112
113
|
column_overrides = [false]
|
113
|
-
if ENV[
|
114
|
-
column_overrides <<
|
114
|
+
if ENV["DB"] == "postgres" && ::ActiveRecord::VERSION::MAJOR >= 4
|
115
|
+
column_overrides << "json"
|
115
116
|
# 'jsonb' column types are only supported for ActiveRecord 4.2+
|
116
|
-
column_overrides <<
|
117
|
+
column_overrides << "jsonb" if ::ActiveRecord::VERSION::STRING >= "4.2"
|
117
118
|
end
|
118
119
|
|
119
120
|
column_overrides.shuffle.each do |override|
|
@@ -121,9 +122,13 @@ describe PaperTrail::Version, :type => :model do
|
|
121
122
|
before do
|
122
123
|
if override
|
123
124
|
ActiveRecord::Base.connection.execute("SAVEPOINT pgtest;")
|
124
|
-
%w
|
125
|
-
ActiveRecord::Base.connection.execute(
|
126
|
-
|
125
|
+
%w(object object_changes).each do |column|
|
126
|
+
ActiveRecord::Base.connection.execute(
|
127
|
+
"ALTER TABLE versions DROP COLUMN #{column};"
|
128
|
+
)
|
129
|
+
ActiveRecord::Base.connection.execute(
|
130
|
+
"ALTER TABLE versions ADD COLUMN #{column} #{override};"
|
131
|
+
)
|
127
132
|
end
|
128
133
|
PaperTrail::Version.reset_column_information
|
129
134
|
end
|
@@ -140,92 +145,131 @@ describe PaperTrail::Version, :type => :model do
|
|
140
145
|
|
141
146
|
context "invalid arguments" do
|
142
147
|
it "should raise an error" do
|
143
|
-
expect {
|
144
|
-
|
148
|
+
expect {
|
149
|
+
PaperTrail::Version.where_object(:foo)
|
150
|
+
}.to raise_error(ArgumentError)
|
151
|
+
expect {
|
152
|
+
PaperTrail::Version.where_object([])
|
153
|
+
}.to raise_error(ArgumentError)
|
145
154
|
end
|
146
155
|
end
|
147
156
|
|
148
|
-
context "valid arguments", :
|
157
|
+
context "valid arguments", versioning: true do
|
149
158
|
let(:widget) { Widget.new }
|
150
|
-
let(:name) {
|
159
|
+
let(:name) { FFaker::Name.first_name }
|
151
160
|
let(:int) { rand(10) + 1 }
|
152
161
|
|
153
162
|
before do
|
154
|
-
widget.update_attributes!(:
|
155
|
-
widget.update_attributes!(:
|
156
|
-
widget.update_attributes!(:
|
163
|
+
widget.update_attributes!(name: name, an_integer: int)
|
164
|
+
widget.update_attributes!(name: "foobar", an_integer: 100)
|
165
|
+
widget.update_attributes!(name: FFaker::Name.last_name, an_integer: 15)
|
157
166
|
end
|
158
167
|
|
159
168
|
context "`serializer == YAML`" do
|
160
|
-
specify
|
169
|
+
specify do
|
170
|
+
expect(PaperTrail.serializer).to be PaperTrail::Serializers::YAML
|
171
|
+
end
|
161
172
|
|
162
173
|
it "should be able to locate versions according to their `object` contents" do
|
163
|
-
expect(
|
164
|
-
|
174
|
+
expect(
|
175
|
+
PaperTrail::Version.where_object(name: name)
|
176
|
+
).to eq([widget.versions[1]])
|
177
|
+
expect(
|
178
|
+
PaperTrail::Version.where_object(an_integer: 100)
|
179
|
+
).to eq([widget.versions[2]])
|
165
180
|
end
|
166
181
|
end
|
167
182
|
|
168
|
-
context "
|
169
|
-
before(:all)
|
170
|
-
|
183
|
+
context "JSON serializer" do
|
184
|
+
before(:all) do
|
185
|
+
PaperTrail.serializer = PaperTrail::Serializers::JSON
|
186
|
+
end
|
187
|
+
|
188
|
+
specify do
|
189
|
+
expect(PaperTrail.serializer).to be PaperTrail::Serializers::JSON
|
190
|
+
end
|
171
191
|
|
172
192
|
it "should be able to locate versions according to their `object` contents" do
|
173
|
-
expect(
|
174
|
-
|
193
|
+
expect(
|
194
|
+
PaperTrail::Version.where_object(name: name)
|
195
|
+
).to eq([widget.versions[1]])
|
196
|
+
expect(
|
197
|
+
PaperTrail::Version.where_object(an_integer: 100)
|
198
|
+
).to eq([widget.versions[2]])
|
175
199
|
end
|
176
200
|
|
177
|
-
after(:all)
|
201
|
+
after(:all) do
|
202
|
+
PaperTrail.serializer = PaperTrail::Serializers::YAML
|
203
|
+
end
|
178
204
|
end
|
179
205
|
end
|
180
206
|
end
|
181
207
|
|
182
208
|
describe '#where_object_changes' do
|
183
|
-
it { expect(PaperTrail::Version).to respond_to(:where_object_changes) }
|
184
|
-
|
185
209
|
context "invalid arguments" do
|
186
210
|
it "should raise an error" do
|
187
|
-
expect {
|
188
|
-
|
211
|
+
expect {
|
212
|
+
PaperTrail::Version.where_object_changes(:foo)
|
213
|
+
}.to raise_error(ArgumentError)
|
214
|
+
expect {
|
215
|
+
PaperTrail::Version.where_object_changes([])
|
216
|
+
}.to raise_error(ArgumentError)
|
189
217
|
end
|
190
218
|
end
|
191
219
|
|
192
|
-
context "valid arguments", :
|
220
|
+
context "valid arguments", versioning: true do
|
193
221
|
let(:widget) { Widget.new }
|
194
|
-
let(:name) {
|
222
|
+
let(:name) { FFaker::Name.first_name }
|
195
223
|
let(:int) { rand(5) + 2 }
|
196
224
|
|
197
225
|
before do
|
198
|
-
widget.update_attributes!(:
|
199
|
-
widget.update_attributes!(:
|
200
|
-
widget.update_attributes!(:
|
226
|
+
widget.update_attributes!(name: name, an_integer: 0)
|
227
|
+
widget.update_attributes!(name: "foobar", an_integer: 77)
|
228
|
+
widget.update_attributes!(name: FFaker::Name.last_name, an_integer: int)
|
201
229
|
end
|
202
230
|
|
203
|
-
context "
|
231
|
+
context "YAML serializer" do
|
204
232
|
specify { expect(PaperTrail.serializer).to be PaperTrail::Serializers::YAML }
|
205
233
|
|
206
|
-
it "
|
207
|
-
expect(
|
208
|
-
|
209
|
-
|
234
|
+
it "locates versions according to their `object_changes` contents" do
|
235
|
+
expect(
|
236
|
+
widget.versions.where_object_changes(name: name)
|
237
|
+
).to eq(widget.versions[0..1])
|
238
|
+
expect(
|
239
|
+
widget.versions.where_object_changes(an_integer: 77)
|
240
|
+
).to eq(widget.versions[1..2])
|
241
|
+
expect(
|
242
|
+
widget.versions.where_object_changes(an_integer: int)
|
243
|
+
).to eq([widget.versions.last])
|
210
244
|
end
|
211
245
|
|
212
|
-
it "
|
213
|
-
expect(
|
246
|
+
it "handles queries for multiple attributes" do
|
247
|
+
expect(
|
248
|
+
widget.versions.where_object_changes(an_integer: 77, name: "foobar")
|
249
|
+
).to eq(widget.versions[1..2])
|
214
250
|
end
|
215
251
|
end
|
216
252
|
|
217
|
-
context "
|
253
|
+
context "JSON serializer" do
|
218
254
|
before(:all) { PaperTrail.serializer = PaperTrail::Serializers::JSON }
|
219
255
|
specify { expect(PaperTrail.serializer).to be PaperTrail::Serializers::JSON }
|
220
256
|
|
221
|
-
it "
|
222
|
-
expect(
|
223
|
-
|
224
|
-
|
257
|
+
it "locates versions according to their `object_changes` contents" do
|
258
|
+
expect(
|
259
|
+
widget.versions.where_object_changes(name: name)
|
260
|
+
).to eq(widget.versions[0..1])
|
261
|
+
expect(
|
262
|
+
widget.versions.where_object_changes(an_integer: 77)
|
263
|
+
).to eq(widget.versions[1..2])
|
264
|
+
expect(
|
265
|
+
widget.versions.where_object_changes(an_integer: int)
|
266
|
+
).to eq([widget.versions.last])
|
225
267
|
end
|
226
268
|
|
227
|
-
it "
|
228
|
-
expect(
|
269
|
+
it "handles queries for multiple attributes" do
|
270
|
+
expect(
|
271
|
+
widget.versions.where_object_changes(an_integer: 77, name: "foobar")
|
272
|
+
).to eq(widget.versions[1..2])
|
229
273
|
end
|
230
274
|
|
231
275
|
after(:all) { PaperTrail.serializer = PaperTrail::Serializers::YAML }
|