mirror of
https://github.com/paper-trail-gem/paper_trail.git
synced 2022-11-09 11:33:19 -05:00
2b479a7f08
* 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.
180 lines
7.2 KiB
Ruby
180 lines
7.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "spec_helper"
|
|
|
|
# The `Person` model:
|
|
#
|
|
# - has a dozen associations of various types
|
|
# - has a custom serializer, TimeZoneSerializer, for its `time_zone` attribute
|
|
RSpec.describe Person, type: :model, versioning: true do
|
|
describe "#time_zone" do
|
|
it "returns an ActiveSupport::TimeZone" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
expect(person.time_zone.class).to(eq(ActiveSupport::TimeZone))
|
|
end
|
|
end
|
|
|
|
context "when the model is saved" do
|
|
it "version.object_changes should store long serialization of TimeZone object" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
len = person.versions.last.object_changes.length
|
|
expect((len < 105)).to(be_truthy)
|
|
end
|
|
|
|
it "version.object_changes attribute should have stored the value from serializer" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
as_stored_in_version = HashWithIndifferentAccess[
|
|
YAML.load(person.versions.last.object_changes)
|
|
]
|
|
expect(as_stored_in_version[:time_zone]).to(eq([nil, "Samoa"]))
|
|
serialized_value = Person::TimeZoneSerializer.dump(person.time_zone)
|
|
expect(as_stored_in_version[:time_zone].last).to(eq(serialized_value))
|
|
end
|
|
|
|
it "version.changeset should convert attribute to original, unserialized value" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
unserialized_value = Person::TimeZoneSerializer.load(person.time_zone)
|
|
expect(person.versions.last.changeset[:time_zone].last).to(eq(unserialized_value))
|
|
end
|
|
|
|
it "record.changes (before save) returns the original, unserialized values" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
changes_before_save = person.changes.dup
|
|
person.save!
|
|
expect(
|
|
changes_before_save[:time_zone].map(&:class)
|
|
).to(eq([NilClass, ActiveSupport::TimeZone]))
|
|
end
|
|
|
|
it "version.changeset should be the same as record.changes was before the save" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
changes_before_save = person.changes.dup
|
|
person.save!
|
|
actual = person.versions.last.changeset.delete_if { |k, _v| (k.to_sym == :id) }
|
|
expect(actual).to(eq(changes_before_save))
|
|
actual = person.versions.last.changeset[:time_zone].map(&:class)
|
|
expect(actual).to(eq([NilClass, ActiveSupport::TimeZone]))
|
|
end
|
|
|
|
context "when that attribute is updated" do
|
|
it "object should not store long serialization of TimeZone object" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
|
|
person.save!
|
|
len = person.versions.last.object.length
|
|
expect((len < 105)).to(be_truthy)
|
|
end
|
|
|
|
it "object_changes should not store long serialization of TimeZone object" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
|
|
person.save!
|
|
max_len = ActiveRecord::VERSION::MAJOR < 4 ? 105 : 118
|
|
len = person.versions.last.object_changes.length
|
|
expect((len < max_len)).to(be_truthy)
|
|
end
|
|
|
|
it "version.object attribute should have stored value from serializer" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
attribute_value_before_change = person.time_zone
|
|
person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
|
|
person.save!
|
|
as_stored_in_version = HashWithIndifferentAccess[
|
|
YAML.load(person.versions.last.object)
|
|
]
|
|
expect(as_stored_in_version[:time_zone]).to(eq("Samoa"))
|
|
serialized_value = Person::TimeZoneSerializer.dump(attribute_value_before_change)
|
|
expect(as_stored_in_version[:time_zone]).to(eq(serialized_value))
|
|
end
|
|
|
|
it "version.object_changes attribute should have stored value from serializer" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
|
|
person.save!
|
|
as_stored_in_version = HashWithIndifferentAccess[
|
|
YAML.load(person.versions.last.object_changes)
|
|
]
|
|
expect(as_stored_in_version[:time_zone]).to(eq(["Samoa", "Pacific Time (US & Canada)"]))
|
|
serialized_value = Person::TimeZoneSerializer.dump(person.time_zone)
|
|
expect(as_stored_in_version[:time_zone].last).to(eq(serialized_value))
|
|
end
|
|
|
|
it "version.reify should convert attribute to original, unserialized value" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
attribute_value_before_change = person.time_zone
|
|
person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
|
|
person.save!
|
|
unserialized_value = Person::TimeZoneSerializer.load(attribute_value_before_change)
|
|
expect(person.versions.last.reify.time_zone).to(eq(unserialized_value))
|
|
end
|
|
|
|
it "version.changeset should convert attribute to original, unserialized value" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
|
|
person.save!
|
|
unserialized_value = Person::TimeZoneSerializer.load(person.time_zone)
|
|
expect(person.versions.last.changeset[:time_zone].last).to(eq(unserialized_value))
|
|
end
|
|
|
|
it "record.changes (before save) returns the original, unserialized values" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
|
|
changes_before_save = person.changes.dup
|
|
person.save!
|
|
expect(
|
|
changes_before_save[:time_zone].map(&:class)
|
|
).to(eq([ActiveSupport::TimeZone, ActiveSupport::TimeZone]))
|
|
end
|
|
|
|
it "version.changeset should be the same as record.changes was before the save" do
|
|
person = Person.new(time_zone: "Samoa")
|
|
person.save!
|
|
person.assign_attributes(time_zone: "Pacific Time (US & Canada)")
|
|
changes_before_save = person.changes.dup
|
|
person.save!
|
|
expect(person.versions.last.changeset).to(eq(changes_before_save))
|
|
expect(
|
|
person.versions.last.changeset[:time_zone].map(&:class)
|
|
).to(eq([ActiveSupport::TimeZone, ActiveSupport::TimeZone]))
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#cars and bicycles" do
|
|
it "can be reified" do
|
|
person = Person.create(name: "Frank")
|
|
car = Car.create(name: "BMW 325")
|
|
bicycle = Bicycle.create(name: "BMX 1.0")
|
|
|
|
person.car = car
|
|
person.bicycle = bicycle
|
|
person.update(name: "Steve")
|
|
|
|
car.update(name: "BMW 330")
|
|
bicycle.update(name: "BMX 2.0")
|
|
person.update(name: "Peter")
|
|
|
|
expect(person.reload.versions.length).to(eq(3))
|
|
|
|
# These will work when PT-AT adds support for the new `item_subtype` column
|
|
#
|
|
# - https://github.com/westonganger/paper_trail-association_tracking/pull/5
|
|
# - https://github.com/paper-trail-gem/paper_trail/pull/1143
|
|
# - https://github.com/paper-trail-gem/paper_trail/issues/594
|
|
#
|
|
# second_version = person.reload.versions.second.reify(has_one: true)
|
|
# expect(second_version.car.name).to(eq("BMW 325"))
|
|
# expect(second_version.bicycle.name).to(eq("BMX 1.0"))
|
|
end
|
|
end
|
|
end
|