spec/mongoid/association/depending_spec.rb in mongoid-7.0.1 vs spec/mongoid/association/depending_spec.rb in mongoid-7.0.2

- old
+ new

@@ -1,8 +1,261 @@ require "spec_helper" describe Mongoid::Association::Depending do + describe '#self.included' do + + context 'when a destroy dependent is defined' do + + context 'when the model is a subclass' do + + context 'when transitive dependents are defined' do + + let(:define_classes) do + class DependentReportCard + include Mongoid::Document + + belongs_to :dependent_student + end + + class DependentUser + include Mongoid::Document + end + + class DependentStudent < DependentUser + belongs_to :dependent_teacher + has_many :dependent_report_cards, dependent: :destroy + end + + class DependentDerivedStudent < DependentStudent; end + + class DependentTeacher + include Mongoid::Document + + has_many :dependent_students, dependent: :destroy + end + + class DependentCollegeUser < DependentUser; end + end + + it "does not add the dependent to superclass" do + define_classes + + expect(DependentUser.dependents).to be_empty + + u = DependentUser.create! + expect(u.dependents).to be_empty + end + + it 'does not impede destroying the superclass' do + define_classes + + u = DependentUser.create! + expect { u.destroy! }.not_to raise_error + end + + it 'adds the dependent' do + define_classes + + expect(DependentStudent.dependents.length).to be(1) + expect(DependentStudent.dependents.first.name).to be(:dependent_report_cards) + + s = DependentStudent.create! + expect(s.dependents.length).to be(1) + expect(s.dependents.first.name).to be(:dependent_report_cards) + end + + it 'facilitates proper destroying of the object' do + define_classes + + s = DependentStudent.create! + r = DependentReportCard.create!(dependent_student: s) + s.destroy! + + expect { DependentReportCard.find(r.id) }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + + it 'facilitates proper transitive destroying of the object' do + define_classes + + t = DependentTeacher.create! + s = DependentStudent.create!(dependent_teacher: t) + r = DependentReportCard.create!(dependent_student: s) + s.destroy! + + expect { DependentReportCard.find(r.id) }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + + it 'adds the dependent to subclasses' do + define_classes + + expect(DependentDerivedStudent.dependents.length).to be(1) + expect(DependentDerivedStudent.dependents.first.name).to be(:dependent_report_cards) + + s = DependentDerivedStudent.create! + expect(s.dependents.length).to be(1) + expect(s.dependents.first.name).to be(:dependent_report_cards) + end + + it 'facilitates proper destroying of the object from subclasses' do + define_classes + + s = DependentDerivedStudent.create! + r = DependentReportCard.create!(dependent_student: s) + s.destroy! + + expect { DependentReportCard.find(r.id) }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + + it "doesn't add the dependent to sibling classes" do + define_classes + + expect(DependentCollegeUser.dependents).to be_empty + + c = DependentCollegeUser.create! + expect(c.dependents).to be_empty + end + + it 'does not impede destroying the sibling class' do + define_classes + + c = DependentCollegeUser.create! + expect { c.destroy! }.not_to raise_error + end + end + + context 'when a superclass is reopened and a new dependent is added' do + let(:define_classes) do + class DependentOwnedOne + include Mongoid::Document + + belongs_to :dependent_superclass + end + + class DependentOwnedTwo + include Mongoid::Document + + belongs_to :dependent_superclass + end + + class DependentSuperclass + include Mongoid::Document + has_one :dependent_owned_one + has_one :dependent_owned_two + end + + class DependentSubclass < DependentSuperclass + has_one :dependent_owned_two, dependent: :nullify + end + + class DependentSuperclass + has_one :dependent_owned_one, dependent: :destroy + end + end + + it 'defines the dependent from the reopened superclass on the subclass' do + define_classes + + DependentSubclass.create!.destroy! + + expect(DependentSubclass.dependents.length).to be(1) + expect(DependentSubclass.dependents.last.name).to be(:dependent_owned_two) + expect(DependentSubclass.dependents.last.options[:dependent]).to be(:nullify) + + subclass = DependentSubclass.create! + expect(subclass.dependents.last.name).to be(:dependent_owned_two) + expect(subclass.dependents.last.options[:dependent]).to be(:nullify) + end + + it 'causes the destruction of the inherited destroy dependent' do + define_classes + + subclass = DependentSubclass.create! + owned = DependentOwnedOne.create!(dependent_superclass: subclass) + subclass.destroy! + + expect { + DependentOwnedOne.find(owned.id) + }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + end + + context 'when a separate subclass overrides the destroy dependent' do + let(:define_classes) do + class Dep + include Mongoid::Document + + belongs_to :double_assoc + end + + class DoubleAssoc + include Mongoid::Document + + has_many :deps, dependent: :destroy + end + + class DoubleAssocOne < DoubleAssoc + has_many :deps, dependent: :nullify, inverse_of: :double_assoc + end + + class DoubleAssocTwo < DoubleAssocOne + has_many :deps, dependent: :destroy, inverse_of: :double_assoc + end + + class DoubleAssocThree < DoubleAssoc; end + end + + it 'adds the non-destroy dependent correctly to the subclass with the override' do + define_classes + + expect(DoubleAssocOne.dependents.length).to be(1) + expect(DoubleAssocOne.dependents.first.name).to be(:deps) + expect(DoubleAssocOne.dependents.first.options[:dependent]).to be(:nullify) + + one = DoubleAssocOne.create! + expect(one.dependents.length).to be(1) + expect(one.dependents.first.name).to be(:deps) + expect(one.dependents.first.options[:dependent]).to be(:nullify) + end + + it 'does not cause the destruction of the non-destroy dependent' do + define_classes + + one = DoubleAssocOne.create! + dep = Dep.create!(double_assoc: one) + one.destroy! + + expect { Dep.find(dep.id) }.not_to raise_error + expect(dep.double_assoc).to be_nil + end + + it 'adds the destroy dependent correctly to the subclass without the override' do + define_classes + + expect(DoubleAssocTwo.dependents.length).to be(1) + expect(DoubleAssocTwo.dependents.first.name).to be(:deps) + expect(DoubleAssocTwo.dependents.first.options[:dependent]).to be(:destroy) + + two = DoubleAssocTwo.create! + expect(two.dependents.length).to be(1) + expect(two.dependents.first.name).to be(:deps) + expect(two.dependents.first.options[:dependent]).to be(:destroy) + end + + it 'causes the destruction of the destroy dependent' do + define_classes + + two = DoubleAssocTwo.create! + dep = Dep.create!(double_assoc: two) + two.destroy! + + expect { Dep.find(dep.id) }.to raise_error(Mongoid::Errors::DocumentNotFound) + end + end + end + end + end + around(:each) do |example| relations_before = Person.relations example.run Person.relations = relations_before end