# frozen_string_literal: true # encoding: utf-8 require "spec_helper" describe Mongoid::Persistable::Destroyable do describe "#destroy" do let!(:person) do Person.create end context "when destroying a readonly document" do let(:from_db) do Person.only(:_id).first end it "raises an error" do expect { from_db.destroy }.to raise_error(Mongoid::Errors::ReadonlyDocument) end end context "when removing a root document" do let!(:destroyd) do person.destroy end it "destroys the document from the collection" do expect { Person.find(person.id) }.to raise_error(Mongoid::Errors::DocumentNotFound) end it "returns true" do expect(destroyd).to be true end it "resets the flagged for destroy flag" do expect(person).to_not be_flagged_for_destroy end end context "when removing 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 and database" do expect(from_db.addresses).to be_empty end end context 'when removing 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 let(:from_db) do Word.find(word.id) end before do word.definitions.find_or_create_by(description: 'database connector') word.definitions.find_or_create_by(description: 'chauffeur') word.definitions = word.definitions.reverse word.definitions.last.destroy end it 'removes the embedded document in memory' do expect(word.definitions.size).to eq(1) end it 'removes the embedded document in the database' do expect(from_db.definitions.size).to eq(1) end end end end context "when removing deeply embedded documents" do context "when the document has been saved" do let(:address) do person.addresses.create(street: "Bond Street") end let(:location) do address.locations.create(name: "Home") end let(:from_db) do Person.find(person.id) end before do location.destroy end it "removes the object from the parent and database" do expect(from_db.addresses.first.locations).to be_empty end it "resets the flagged for destroy flag" do expect(location).to_not be_flagged_for_destroy end end end end describe "#destroy!" do 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 context "when a validation callback returns false" do let(:album) do Album.create end before do Album.before_destroy(:set_parent_name_fail) end after do Album.reset_callbacks(:destroy) end it "raises an exception" do expect { album.destroy! }.to raise_error(Mongoid::Errors::DocumentNotDestroyed) end end end describe "#destroy_all" do let!(:person) do Person.create(title: "sir") end context "when no conditions are provided" do let!(:removed) do Person.destroy_all end it "removes all the documents" do expect(Person.count).to eq(0) end it "returns the number of documents removed" do expect(removed).to eq(1) end end context "when conditions are provided" do let!(:person_two) do Person.create end context "when no conditions attribute provided" do let!(:removed) do Person.destroy_all(title: "sir") end it "removes the matching documents" do expect(Person.count).to eq(1) end it "returns the number of documents removed" do expect(removed).to eq(1) end end end context 'when the write concern is unacknowledged' do before do Person.create(title: 'miss') end let!(:removed) do Person.with(write: { w: 0 }) { |klass| klass.destroy_all(title: "sir") } end it "removes the matching documents" do expect(Person.where(title: 'miss').count).to eq(1) end it "returns 0" do expect(removed).to eq(0) end end context 'when removing 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 before do word.definitions.find_or_create_by(description: 'database connector') word.definitions.find_or_create_by(description: 'chauffeur') word.definitions = word.definitions.reverse word.definitions.destroy_all end it 'removes all embedded documents' do expect(word.definitions.size).to eq(0) end end end end end