1
0
Fork 0
mirror of https://github.com/paper-trail-gem/paper_trail.git synced 2022-11-09 11:33:19 -05:00
paper-trail-gem--paper_trail/spec/models/json_version_spec.rb
Edouard Chin 2b479a7f08 Support rails 6.0.0 (#1172)
* Change update_attributes to update

In Rails 6.0 update_attributes/update_attributes! is considered deprecated. Method update/update! is the replacement.

* CI: Don't use Bundler 1.16.1

- Bundler 1.16.1 has bug where dependencies can't be resolved properly
  when a gem is a release candidate or an alpha version.
  The underlying bundler issue can be found here https://github.com/bundler/bundler/issues/6449

* Disable eager_load in test env:

- In Rails 6.0, rails/rails@3b95478 made a change to eagerly define
  attribute methods of a Model when `eager_load` is enabled.
  This breaks our test suite because of the way we run migration.

  The TL;DR is that doing `People.attribute_names` will return an
  empty array instead of `[:id, time_zone, ...]`.
  You can find a failing build here https://travis-ci.org/paper-trail-gem/paper_trail/jobs/463369634

  Basically what happens is:

  1) The dummy app boot, attribute methods of each model are defined
     but since migration didn't run yet, the tables aren't even
     created resulting in a empty attribute set.
  2) Migration runs, but it's already too late.

  In this commit I disabled eager_loading in test, AFAIT there isn't
  much benefit in eager_loading the dummy app anyway.
  Also renaming the `user.rb` file to `postgres_user.rb` in order for
  rails autoloading to work correctly.
2018-12-04 16:10:35 -05:00

124 lines
4.6 KiB
Ruby

# frozen_string_literal: true
require "spec_helper"
# The `json_versions` table tests postgres' `json` data type. So, that
# table is only created when testing against postgres.
if JsonVersion.table_exists?
RSpec.describe JsonVersion, type: :model do
it "includes the VersionConcern module" do
expect(described_class).to include(PaperTrail::VersionConcern)
end
describe "#where_object" do
it { expect(described_class).to respond_to(:where_object) }
it "escapes values" do
f = Fruit.create(name: "Bobby")
expect(
f.
versions.
where_object(name: "Robert'; DROP TABLE Students;--").
count
).to eq(0)
end
context "invalid arguments" do
it "raises an error" do
expect { described_class.where_object(:foo) }.to raise_error(ArgumentError)
expect { described_class.where_object([]) }.to raise_error(ArgumentError)
end
end
context "valid arguments", versioning: true do
it "locates versions according to their `object` contents" do
fruit = Fruit.create!(name: "apple")
expect(fruit.versions.length).to eq(1)
fruit.update!(name: "banana", color: "aqua")
expect(fruit.versions.length).to eq(2)
fruit.update!(name: "coconut", color: "black")
expect(fruit.versions.length).to eq(3)
where_apple = described_class.where_object(name: "apple")
expect(where_apple.to_sql).to eq(
<<-SQL.squish
SELECT "json_versions".*
FROM "json_versions"
WHERE (object->>'name' = 'apple')
SQL
)
expect(where_apple).to eq([fruit.versions[1]])
expect(
described_class.where_object(color: "aqua")
).to eq([fruit.versions[2]])
end
end
end
describe "#where_object_changes" do
it "escapes values" do
f = Fruit.create(name: "Bobby")
expect(
f.
versions.
where_object_changes(name: "Robert'; DROP TABLE Students;--").
count
).to eq(0)
end
context "invalid arguments" do
it "raises an error" do
expect { described_class.where_object_changes(:foo) }.to raise_error(ArgumentError)
expect { described_class.where_object_changes([]) }.to raise_error(ArgumentError)
end
end
context "valid arguments", versioning: true do
it "finds versions according to their `object_changes` contents" do
fruit = Fruit.create!(name: "apple")
fruit.update!(name: "banana", color: "red")
fruit.update!(name: "coconut", color: "green")
where_apple = fruit.versions.where_object_changes(name: "apple")
expect(where_apple.to_sql.squish).to eq(
<<-SQL.squish
SELECT "json_versions".*
FROM "json_versions"
WHERE "json_versions"."item_id" = #{fruit.id}
AND "json_versions"."item_type" = 'Fruit'
AND
(((object_changes->>'name' ILIKE '["apple",%')
OR (object_changes->>'name' ILIKE '[%,"apple"]%')))
ORDER BY "json_versions"."created_at" ASC,
"json_versions"."id" ASC
SQL
)
expect(where_apple).to match_array(fruit.versions[0..1])
expect(
fruit.versions.where_object_changes(color: "red")
).to match_array(fruit.versions[1..2])
end
it "finds versions with multiple attributes changed" do
fruit = Fruit.create!(name: "apple")
fruit.update!(name: "banana", color: "red")
fruit.update!(name: "coconut", color: "green")
where_red_apple = fruit.versions.where_object_changes(color: "red", name: "apple")
expect(where_red_apple.to_sql.squish).to eq(
<<-SQL.squish
SELECT "json_versions".*
FROM "json_versions"
WHERE "json_versions"."item_id" = #{fruit.id}
AND "json_versions"."item_type" = 'Fruit'
AND (((object_changes->>'color' ILIKE '["red",%')
OR (object_changes->>'color' ILIKE '[%,"red"]%'))
and ((object_changes->>'name' ILIKE '["apple",%')
OR (object_changes->>'name' ILIKE '[%,"apple"]%')))
ORDER BY "json_versions"."created_at" ASC,
"json_versions"."id" ASC
SQL
)
expect(where_red_apple).to match_array([fruit.versions[1]])
end
end
end
end
end