paper-trail-gem--paper_trail/spec/models/version_spec.rb

298 lines
11 KiB
Ruby
Raw Normal View History

require "spec_helper"
module PaperTrail
::RSpec.describe Version, type: :model do
2016-02-16 03:32:40 +00:00
describe "object_changes column", versioning: true do
let(:widget) { Widget.create!(name: "Dashboard") }
let(:value) { widget.versions.last.object_changes }
context "serializer is YAML" do
specify { expect(PaperTrail.serializer).to be PaperTrail::Serializers::YAML }
2017-04-01 05:50:13 +00:00
it "store out as a plain hash" do
expect(value =~ /HashWithIndifferentAccess/).to be_nil
end
end
context "serializer is JSON" do
before(:all) { PaperTrail.serializer = PaperTrail::Serializers::JSON }
2017-04-01 05:50:13 +00:00
it "store out as a plain hash" do
expect(value =~ /HashWithIndifferentAccess/).to be_nil
end
after(:all) { PaperTrail.serializer = PaperTrail::Serializers::YAML }
end
end
describe "#paper_trail_originator" do
context "no previous versions" do
it "returns nil" do
expect(PaperTrail::Version.new.paper_trail_originator).to be_nil
end
end
context "has previous version", versioning: true do
it "returns name of whodunnit" do
name = FFaker::Name.name
widget = Widget.create!(name: FFaker::Name.name)
widget.versions.first.update_attributes!(whodunnit: name)
widget.update_attributes!(name: FFaker::Name.first_name)
expect(widget.versions.last.paper_trail_originator).to eq(name)
end
end
end
describe "#previous" do
context "no previous versions" do
it "returns nil" do
expect(PaperTrail::Version.new.previous).to be_nil
end
end
context "has previous version", versioning: true do
it "returns a PaperTrail::Version" do
name = FFaker::Name.name
widget = Widget.create!(name: FFaker::Name.name)
widget.versions.first.update_attributes!(whodunnit: name)
widget.update_attributes!(name: FFaker::Name.first_name)
expect(widget.versions.last.previous).to be_instance_of(PaperTrail::Version)
end
end
end
describe "#originator" do
it "sets the invoke `paper_trail_originator`" do
allow(ActiveSupport::Deprecation).to receive(:warn)
subject = PaperTrail::Version.new
allow(subject).to receive(:paper_trail_originator)
subject.originator
expect(subject).to have_received(:paper_trail_originator)
end
it "displays a deprecation warning" do
allow(ActiveSupport::Deprecation).to receive(:warn)
PaperTrail::Version.new.originator
expect(ActiveSupport::Deprecation).to have_received(:warn).
with(/Use paper_trail_originator instead of originator/)
end
end
describe "#terminator" do
it "is an alias for the `whodunnit` attribute" do
attributes = { whodunnit: FFaker::Name.first_name }
subject = PaperTrail::Version.new(attributes)
expect(subject.terminator).to eq(attributes[:whodunnit])
end
end
describe "#version_author" do
it "is an alias for the `terminator` method" do
subject = PaperTrail::Version.new
expect(subject.method(:version_author)).to eq(subject.method(:terminator))
end
end
describe "Methods" do
# TODO: Changing the data type of these database columns in the middle
# of the test suite adds a fair amount of complication. Is there a better
# way? We already have a `json_versions` table in our tests, maybe we
# could use that and add a `jsonb_versions` table?
column_overrides = [false]
if ENV["DB"] == "postgres" && ::ActiveRecord::VERSION::MAJOR >= 4
column_overrides << "json"
# 'jsonb' column types are only supported for ActiveRecord 4.2+
column_overrides << "jsonb" if ::ActiveRecord::VERSION::STRING >= "4.2"
end
column_overrides.shuffle.each do |column_datatype_override|
context "with a #{column_datatype_override || 'text'} column" do
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
let(:widget) { Widget.new }
let(:name) { FFaker::Name.first_name }
let(:int) { column_datatype_override ? 1 : rand(5) + 2 }
before do
if column_datatype_override
# In rails < 5, we use truncation, ie. there is no transaction
# around the tests, so we can't use a savepoint.
if active_record_gem_version >= ::Gem::Version.new("5")
ActiveRecord::Base.connection.execute("SAVEPOINT pgtest;")
end
2017-05-21 06:40:23 +00:00
%w[object object_changes].each do |column|
ActiveRecord::Base.connection.execute(
"ALTER TABLE versions DROP COLUMN #{column};"
)
ActiveRecord::Base.connection.execute(
"ALTER TABLE versions ADD COLUMN #{column} #{column_datatype_override};"
)
end
PaperTrail::Version.reset_column_information
end
end
after do
if column_datatype_override
# In rails < 5, we use truncation, ie. there is no transaction
# around the tests, so we can't use a savepoint.
if active_record_gem_version >= ::Gem::Version.new("5")
ActiveRecord::Base.connection.execute("ROLLBACK TO SAVEPOINT pgtest;")
else
%w[object object_changes].each do |column|
ActiveRecord::Base.connection.execute(
"ALTER TABLE versions DROP COLUMN #{column};"
)
ActiveRecord::Base.connection.execute(
"ALTER TABLE versions ADD COLUMN #{column} text;"
)
end
end
PaperTrail::Version.reset_column_information
end
end
describe "#where_object", versioning: true do
before do
widget.update_attributes!(name: name, an_integer: int)
widget.update_attributes!(name: "foobar", an_integer: 100)
widget.update_attributes!(name: FFaker::Name.last_name, an_integer: 15)
end
it "requires its argument to be a Hash" do
expect {
PaperTrail::Version.where_object(:foo)
}.to raise_error(ArgumentError)
expect {
PaperTrail::Version.where_object([])
}.to raise_error(ArgumentError)
end
context "`serializer == YAML`" do
specify do
expect(PaperTrail.serializer).to be PaperTrail::Serializers::YAML
end
it "locates versions according to their `object` contents" do
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
expect(
PaperTrail::Version.where_object(an_integer: int)
).to eq([widget.versions[1]])
expect(
PaperTrail::Version.where_object(name: name)
).to eq([widget.versions[1]])
expect(
PaperTrail::Version.where_object(an_integer: 100)
).to eq([widget.versions[2]])
end
end
context "JSON serializer" do
before(:all) do
PaperTrail.serializer = PaperTrail::Serializers::JSON
end
specify do
expect(PaperTrail.serializer).to be PaperTrail::Serializers::JSON
end
it "locates versions according to their `object` contents" do
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
expect(
PaperTrail::Version.where_object(an_integer: int)
).to eq([widget.versions[1]])
expect(
PaperTrail::Version.where_object(name: name)
).to eq([widget.versions[1]])
expect(
PaperTrail::Version.where_object(an_integer: 100)
).to eq([widget.versions[2]])
end
after(:all) do
PaperTrail.serializer = PaperTrail::Serializers::YAML
end
end
end
describe "#where_object_changes", versioning: true do
before do
widget.update_attributes!(name: name, an_integer: 0)
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
widget.update_attributes!(name: "foobar", an_integer: 100)
widget.update_attributes!(name: FFaker::Name.last_name, an_integer: int)
end
it "requires its argument to be a Hash" do
expect {
PaperTrail::Version.where_object_changes(:foo)
}.to raise_error(ArgumentError)
expect {
PaperTrail::Version.where_object_changes([])
}.to raise_error(ArgumentError)
end
context "YAML serializer" do
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
before do
unless column_datatype_override
allow(ActiveSupport::Deprecation).to receive(:warn)
end
end
it "locates versions according to their `object_changes` contents" do
expect(
widget.versions.where_object_changes(name: name)
).to eq(widget.versions[0..1])
expect(
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
widget.versions.where_object_changes(an_integer: 100)
).to eq(widget.versions[1..2])
expect(
widget.versions.where_object_changes(an_integer: int)
).to eq([widget.versions.last])
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
unless column_datatype_override
expect(ActiveSupport::Deprecation).to have_received(:warn).
exactly(3).times.with(/^where_object_changes/)
end
end
it "handles queries for multiple attributes" do
expect(
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
widget.versions.where_object_changes(an_integer: 100, name: "foobar")
).to eq(widget.versions[1..2])
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
unless column_datatype_override
expect(ActiveSupport::Deprecation).to have_received(:warn).
at_least(:once).with(/^where_object_changes/)
end
end
end
# Only test the JSON serializer against where_object_changes
# for json and jsonb columns, not for text columns, which are
# no longer supported.
if column_datatype_override
context "JSON serializer" do
before(:all) { PaperTrail.serializer = PaperTrail::Serializers::JSON }
it "locates versions according to their `object_changes` contents" do
expect(
widget.versions.where_object_changes(name: name)
).to eq(widget.versions[0..1])
expect(
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
widget.versions.where_object_changes(an_integer: 100)
).to eq(widget.versions[1..2])
expect(
widget.versions.where_object_changes(an_integer: int)
).to eq([widget.versions.last])
end
it "handles queries for multiple attributes" do
expect(
Deprecate where_object_changes reading YAML from text column * clarify the issue with `where_object_changes` for numeric values History --- [The first problem mention](https://github.com/airblade/paper_trail/commit/1ad78383aa58d6b74e237f84310f7440712710ab). [The major issue](https://github.com/airblade/paper_trail/issues/803) with relevant discussions. Details --- I see the problem only with one specific case – when the method is `where_object_changes` and the serializer is YAML. Which is a default configuration. I see there are 6 types of queries with a numeric value for `where_object_changes` and `where_object` (grabbed from `version_spec.rb`): ``` .where_object_changes N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (object_changes @> '{"an_integer":[1]}') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N1 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND ("versions"."object_changes" ILIKE '% an_integer: - 1 %' OR "versions"."object_changes" ILIKE '% an_integer: -% - 1 %') ORDER BY "versions"."created_at" ASC, "versions"."id" ASC N3 SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = 1 AND "versions"."item_type" = 'Widget' AND (((object_changes->>'an_integer' ILIKE '[1,%') OR (object_changes->>'an_integer' ILIKE '[%,1]%'))) ORDER BY "versions"."created_at" ASC, "versions"."id" ASC .where_object N4 SELECT "versions".* FROM "versions" WHERE (object @> '{"an_integer":1}') N5 SELECT "versions".* FROM "versions" WHERE (object->>'an_integer' = '1') N6 SELECT "versions".* FROM "versions" WHERE ("versions"."object" ILIKE '% an_integer: 1 %') ``` The only problematic one is N2. It incorrectly matches `object_changes` like ``` --- name: - - Kimberli an_integer: - - 0 created_at: - - 2017-09-28 18:30:13.369889000 Z updated_at: - - 2017-09-28 18:30:13.369889000 Z id: - - 1 --- name: - foobar - Hayes an_integer: - 77 - 1 updated_at: - 2017-09-28 18:30:13.383966000 Z - 2017-09-28 18:30:13.395539000 Z ```
2017-10-23 17:07:27 +00:00
widget.versions.where_object_changes(an_integer: 100, name: "foobar")
).to eq(widget.versions[1..2])
end
after(:all) { PaperTrail.serializer = PaperTrail::Serializers::YAML }
end
end
end
end
end
end
end
end