spec/mongoid/persistable/destroyable_spec.rb in mongoid-8.1.7 vs spec/mongoid/persistable/destroyable_spec.rb in mongoid-9.0.0

- old
+ new

@@ -1,6 +1,7 @@ # frozen_string_literal: true +# rubocop:todo all require "spec_helper" describe Mongoid::Persistable::Destroyable do @@ -9,39 +10,19 @@ let!(:person) do Person.create! end context "when destroying a readonly document" do - - context "when legacy_attributes is true" do - config_override :legacy_readonly, true - - let(:from_db) do - Person.only(:_id).first - end - - it "raises an error" do - expect(from_db.readonly?).to be true - expect { - from_db.destroy - }.to raise_error(Mongoid::Errors::ReadonlyDocument) - end + let(:from_db) do + Person.first.tap(&:readonly!) end - context "when legacy_attributes is false" do - config_override :legacy_readonly, false - - let(:from_db) do - Person.first.tap(&:readonly!) - end - - it "raises an error" do - expect(from_db.readonly?).to be true - expect { - from_db.destroy - }.to raise_error(Mongoid::Errors::ReadonlyDocument) - end + it "raises an error" do + expect(from_db.readonly?).to be true + expect { + from_db.destroy + }.to raise_error(Mongoid::Errors::ReadonlyDocument) end end context 'when destroying a document that was not saved' do let(:unsaved_person) { Person.new(id: person.id) } @@ -49,17 +30,15 @@ before do unsaved_person.destroy end it 'deletes the matching document from the database' do - lambda do - person.reload - end.should raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Person with id\(s\)/) + expect { person.reload }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Person with id\(s\)/) end end - context "when removing a root document" do + context "when destroying a root document" do let!(:destroyed) do person.destroy end @@ -74,13 +53,32 @@ end it "resets the flagged for destroy flag" do expect(person).to_not be_flagged_for_destroy end + + context 'when :persist option false' do + + let!(:destroyed) do + person.destroy(persist: false) + end + + it "does not destroy the document from the collection" do + expect(Person.find(person.id)).to eq person + end + + it "returns true" do + expect(destroyed).to be true + end + + it "does not set the flagged for destroy flag" do + expect(person).to_not be_flagged_for_destroy + end + end end - context "when removing an embedded document" do + context "when destroying an embedded document" do let(:address) do person.addresses.build(street: "Bond Street") end @@ -112,17 +110,64 @@ let(:from_db) do Person.find(person.id) end - it "removes the object from the parent and database" do + it "removes the object from the parent" do + expect(person.addresses).to be_empty + end + + it "removes the object from the database" do expect(from_db.addresses).to be_empty end end - context 'when removing from a list of embedded documents' do + context 'when :persist option false' do + before do + address.save! + address.destroy(persist: false) + end + + let(:from_db) do + Person.find(person.id) + end + + it "does not remove the object from the parent" do + expect(person.addresses).to eq [address] + expect(person.addresses.first).to_not be_flagged_for_destroy + end + + it "does not remove the object from the database" do + expect(from_db.addresses).to eq [address] + expect(from_db.addresses.first).to_not be_flagged_for_destroy + end + end + + context 'when :suppress option true' do + + before do + address.save! + address.destroy(suppress: true) + end + + let(:from_db) do + Person.find(person.id) + end + + it "does not remove the object from the parent" do + expect(person.addresses).to eq [address] + expect(person.addresses.first).to_not be_flagged_for_destroy + end + + it "removes the object from the database" do + expect(from_db.addresses).to be_empty + end + end + + context 'when destroying from a list of embedded documents' do + context 'when the embedded documents list is reversed in memory' do let(:word) do Word.create!(name: 'driver') end @@ -147,11 +192,11 @@ end end end end - context "when removing deeply embedded documents" do + context "when destroying deeply embedded documents" do context "when the document has been saved" do let(:address) do person.addresses.create!(street: "Bond Street") @@ -211,13 +256,11 @@ Hole.create!(sealer: Sealer.create!) end it 'raises an exception' do Sealer.count.should == 1 - lambda do - parent.destroy - end.should raise_error(Mongoid::Errors::DeleteRestriction) + expect { parent.destroy }.to raise_error(Mongoid::Errors::DeleteRestriction) Sealer.count.should == 1 end end end @@ -252,28 +295,26 @@ Hole.create!(spacers: [Spacer.create!]) end it 'raises an exception' do Spacer.count.should == 1 - lambda do - parent.destroy - end.should raise_error(Mongoid::Errors::DeleteRestriction) + expect { parent.destroy }.to raise_error(Mongoid::Errors::DeleteRestriction) Spacer.count.should == 1 end end end end end describe "#destroy!" do + let(:person) do + Person.create! + end + context "when no validation callback returns false" do - let(:person) do - Person.create! - end - it "returns true" do expect(person.destroy!).to eq(true) end end @@ -295,10 +336,151 @@ expect { album.destroy! }.to raise_error(Mongoid::Errors::DocumentNotDestroyed) end end + + context 'when destroying a document that was not saved' do + let(:unsaved_person) { Person.new(id: person.id) } + + before do + unsaved_person.destroy! + end + + it 'deletes the matching document from the database' do + expect { person.reload }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Person with id\(s\)/) + end + end + + context "when destroying a root document" do + + let!(:destroyed) do + person.destroy! + end + + it "destroys the document from the collection" do + expect { + Person.find(person.id) + }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Person with id\(s\)/) + end + + it "returns true" do + expect(destroyed).to be true + end + + it "resets the flagged for destroy flag" do + expect(person).to_not be_flagged_for_destroy + end + + context 'when :persist option false' do + + let!(:destroyed) do + person.destroy!(persist: false) + end + + it "does not destroy the document from the collection" do + expect(Person.find(person.id)).to eq person + end + + it "returns true" do + expect(destroyed).to be true + end + + it "does not set the flagged for destroy flag" do + expect(person).to_not be_flagged_for_destroy + end + end + end + + context "when destroying an embedded document" do + + let(:address) do + person.addresses.build(street: "Bond Street") + end + + context "when the document is not yet saved" do + + before do + address.destroy! + end + + it "removes the document from the parent" do + expect(person.addresses).to be_empty + end + + it "removes the attributes from the parent" do + expect(person.raw_attributes["addresses"]).to be_nil + end + + it "resets the flagged for destroy flag" do + expect(address).to_not be_flagged_for_destroy + end + end + + context "when the document has been saved" do + + before do + address.save! + address.destroy! + end + + let(:from_db) do + Person.find(person.id) + end + + it "removes the object from the parent" do + expect(person.addresses).to be_empty + end + + it "removes the object from the database" do + expect(from_db.addresses).to be_empty + end + end + + context 'when :persist option false' do + + before do + address.save! + address.destroy!(persist: false) + end + + let(:from_db) do + Person.find(person.id) + end + + it "does not remove the object from the parent" do + expect(person.addresses).to eq [address] + expect(person.addresses.first).to_not be_flagged_for_destroy + end + + it "does not remove the object from the database" do + expect(from_db.addresses).to eq [address] + expect(from_db.addresses.first).to_not be_flagged_for_destroy + end + end + + context 'when :suppress option true' do + + before do + address.save! + address.destroy!(suppress: true) + end + + let(:from_db) do + Person.find(person.id) + end + + it "does not remove the object from the parent" do + expect(person.addresses).to eq [address] + expect(person.addresses.first).to_not be_flagged_for_destroy + end + + it "removes the object from the database" do + expect(from_db.addresses).to be_empty + end + end + end end describe "#destroy_all" do let!(:person) do @@ -359,11 +541,11 @@ it "returns 0" do expect(removed).to eq(0) end end - context 'when removing a list of embedded documents' do + context 'when destroying a list of embedded documents' do context 'when the embedded documents list is reversed in memory' do let(:word) do Word.create!(name: 'driver') @@ -420,13 +602,11 @@ end end it 'raises an exception' do Sealer.count.should == 1 - lambda do - Hole.destroy_all - end.should raise_error(Mongoid::Errors::DeleteRestriction) + expect { Hole.destroy_all }.to raise_error(Mongoid::Errors::DeleteRestriction) Sealer.count.should == 1 end end end @@ -461,12 +641,10 @@ Hole.create!(spacers: [Spacer.create!]) end it 'raises an exception' do Spacer.count.should == 1 - lambda do - Hole.destroy_all - end.should raise_error(Mongoid::Errors::DeleteRestriction) + expect { Hole.destroy_all }.to raise_error(Mongoid::Errors::DeleteRestriction) Spacer.count.should == 1 end end end end