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