From 2fefcdbc7ee03618a3f467bb7dc9eacf347c9d56 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sun, 5 Apr 2020 19:55:29 -0400 Subject: [PATCH] Fix MONGOID-4865 include_root_in_json setting retrieval does not respect hierarchy --- lib/mongoid/serializable.rb | 11 ++- spec/mongoid/serializable_spec.rb | 147 ++++++++++++++++++++++++++---- spec/spec_helper.rb | 2 + spec/support/helpers.rb | 11 +++ 4 files changed, 150 insertions(+), 21 deletions(-) create mode 100644 spec/support/helpers.rb diff --git a/lib/mongoid/serializable.rb b/lib/mongoid/serializable.rb index c8e4086453..35498ba04e 100644 --- a/lib/mongoid/serializable.rb +++ b/lib/mongoid/serializable.rb @@ -13,10 +13,15 @@ module Serializable # We need to redefine where the JSON configuration is getting defined, # similar to +ActiveRecord+. included do - extend Forwardable - undef_method :include_root_in_json - def_delegator ::Mongoid, :include_root_in_json + class << self + extend Forwardable + + # Note that this intentionally only delegates :include_root_in_json + # and not :include_root_in_json? - delegating the latter produces + # wrong behavior. + def_delegators ::Mongoid, :include_root_in_json + end end # Gets the document as a serializable hash, used by ActiveModel's JSON diff --git a/spec/mongoid/serializable_spec.rb b/spec/mongoid/serializable_spec.rb index ec99d7664b..67af060263 100644 --- a/spec/mongoid/serializable_spec.rb +++ b/spec/mongoid/serializable_spec.rb @@ -16,31 +16,117 @@ end end - describe ".include_root_in_json" do + %i(include_root_in_json include_root_in_json?).each do |meth| + describe ".#{meth}" do - let(:person) do - Person.new - end + before do + reload_model(:Minim) + end - context "when config set to true" do + after do + Mongoid.include_root_in_json = false + reload_model(:Minim) + end - before do - Mongoid.include_root_in_json = true + context "when global config is set to true" do + + before do + Mongoid.include_root_in_json = true + end + + it "returns true" do + expect(Minim.public_send(meth)).to be true + end + + context 'when value is overridden to false in the model class' do + before do + Minim.include_root_in_json = false + end + + it 'returns false' do + expect(Minim.public_send(meth)).to be false + end + end end - it "returns true" do - expect(person.include_root_in_json).to be true + context "when global config set to false" do + + before do + Mongoid.include_root_in_json = false + end + + it "returns false" do + expect(Minim.public_send(meth)).to be false + end + + context 'when value is overridden to true in the model class' do + before do + Minim.include_root_in_json = true + end + + it 'returns true' do + expect(Minim.public_send(meth)).to be true + end + end end end - context "when config set to false" do + describe "#include_root_in_json" do before do + reload_model(:Minim) + end + + after do Mongoid.include_root_in_json = false + reload_model(:Minim) + end + + let(:minim) do + Minim.new + end + + context "when global config is set to true" do + + before do + Minim.include_root_in_json.should be false + Mongoid.include_root_in_json = true + end + + it "returns true" do + expect(minim.public_send(meth)).to be true + end + + context 'when value is overridden to false in the model class' do + before do + Minim.include_root_in_json = false + end + + it 'returns false' do + expect(minim.public_send(meth)).to be false + end + end end - it "returns false" do - expect(person.include_root_in_json).to be false + context "when global config set to false" do + + before do + Mongoid.include_root_in_json = false + end + + it "returns false" do + expect(minim.public_send(meth)).to be false + end + + context 'when value is overridden to true in the model class' do + before do + Minim.include_root_in_json = true + end + + it 'returns true' do + expect(minim.public_send(meth)).to be true + end + end end end end @@ -773,32 +859,57 @@ describe "#to_json" do - let(:person) do - Person.new + let(:account) do + Account.new end - context "when including root in json" do + context "when including root in json via Mongoid" do before do + account.include_root_in_json.should be false Mongoid.include_root_in_json = true end + after do + Mongoid.include_root_in_json = false + end + it "uses the mongoid configuration" do - expect(person.to_json).to include("person") + expect(JSON.parse(account.to_json)).to have_key("account") + end + end + + context "when including root in json via class" do + + before do + account.include_root_in_json.should be false + Account.include_root_in_json = true + end + + after do + Account.include_root_in_json = false + end + + it "uses the class configuration" do + expect(JSON.parse(account.to_json)).to have_key("account") end end context "when not including root in json" do before do - Mongoid.include_root_in_json = false + account.include_root_in_json.should be false end it "uses the mongoid configuration" do - expect(person.to_json).to_not include("person") + expect(JSON.parse(account.to_json)).not_to have_key("account") end end + let(:person) do + Person.new + end + context "when serializing a relation directly" do context "when serializing an embeds many" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b61d39571e..ef3e56469f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -31,6 +31,7 @@ def database_id_alt require 'support/authorization' require 'support/expectations' +require 'support/helpers' require 'support/macros' require 'support/cluster_config' require 'support/constraints' @@ -156,6 +157,7 @@ class Query RSpec.configure do |config| config.raise_errors_for_deprecations! + config.include(Helpers) config.include(Mongoid::Expectations) config.extend(Constraints) config.extend(Mongoid::Macros) diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb new file mode 100644 index 0000000000..3c1c944518 --- /dev/null +++ b/spec/support/helpers.rb @@ -0,0 +1,11 @@ +module Helpers + # Reloads the specified model class. + # + # @param [ String | Symbol ] name Class name to reload. + def reload_model(name) + Object.class_eval do + remove_const(name) + end + load "spec/app/models/#{name.to_s.underscore}.rb" + end +end