require "spec_helper" describe Mongoid::Relations::Embedded::In do describe "#===" do let(:base) do Name.new end let(:target) do Person.new end let(:metadata) do Name.relations["namable"] end let(:relation) do described_class.new(base, target, metadata) end context "when the proxied document is same class" do context "when the document is a different instance" do it "returns false" do expect((relation === Person.new)).to be_false end end context "when the document is the same instance" do it "returns true" do expect((relation === target)).to be_true end end end end describe "#=" do context "when the inverse of an embeds one" do context "when the child is a new record" do let(:person) do Person.new end let(:name) do Name.new end before do name.namable = person end it "sets the target of the relation" do expect(name.namable).to eq(person) end it "sets the base on the inverse relation" do expect(person.name).to eq(name) end it "sets the same instance on the inverse relation" do expect(person.name).to eql(name) end it "does not save the target" do expect(person).to_not be_persisted end end context "when the parent is not a new record" do let(:person) do Person.create end let(:name) do Name.new end before do name.namable = person end it "sets the target of the relation" do expect(name.namable).to eq(person) end it "sets the base on the inverse relation" do expect(person.name).to eq(name) end it "sets the same instance on the inverse relation" do expect(person.name).to eql(name) end it "does not save the base" do expect(name).to_not be_persisted end end end context "when the inverse of an embeds many" do context "when the child is a new record" do let(:person) do Person.new end let(:address) do Address.new end before do address.addressable = person end it "sets the target of the relation" do expect(address.addressable).to eq(person) end it "appends the base on the inverse relation" do expect(person.addresses).to eq([ address ]) end it "sets the same instance in the inverse relation" do expect(person.addresses.first).to eql(address) end it "does not save the target" do expect(person).to_not be_persisted end end context "when the parent is not a new record" do let!(:person) do Person.create! end let(:address) do Address.new end before do address.addressable = person end it "sets the target of the relation" do expect(address.addressable).to eq(person) end it "sets the same instance in the inverse relation" do expect(person.addresses.first).to eql(address) end it "appends the base on the inverse relation" do expect(person.addresses).to eq([ address ]) end end end end describe "#= nil" do context "when the inverse of an embeds one" do context "when the parent is a new record" do let(:person) do Person.new end let(:name) do Name.new end before do name.namable = person name.namable = nil end it "sets the relation to nil" do expect(name.namable).to be_nil end it "removes the inverse relation" do expect(person.name).to be_nil end end context "when the inverse is already nil" do let(:person) do Person.new end let(:name) do Name.new end before do name.namable = nil end it "sets the relation to nil" do expect(name.namable).to be_nil end it "removes the inverse relation" do expect(person.name).to be_nil end end context "when the documents are not new records" do let(:person) do Person.create end let(:name) do Name.new end before do name.namable = person name.namable = nil end it "sets the relation to nil" do expect(name.namable).to be_nil end it "removed the inverse relation" do expect(person.name).to be_nil end it "deletes the child document" do expect(name).to be_destroyed end end end context "when the inverse of an embeds many" do context "when the parent is a new record" do let(:person) do Person.new end let(:address) do Address.new end before do address.addressable = person address.addressable = nil end it "sets the relation to nil" do expect(address.addressable).to be_nil end it "removes the inverse relation" do expect(person.addresses).to be_empty end end context "when the inverse is already nil" do let(:address) do Address.new end before do address.addressable = nil end it "sets the relation to nil" do expect(address.addressable).to be_nil end end context "when the documents are not new records" do let(:person) do Person.create end let(:address) do Address.new end before do address.addressable = person address.addressable = nil end it "sets the relation to nil" do expect(address.addressable).to be_nil end it "removed the inverse relation" do expect(person.addresses).to be_empty end it "deletes the child document" do expect(address).to be_destroyed end end context "when a child already exists on the parent" do let(:person) do Person.create end let(:address_one) do Address.new(street: "first") end let(:address_two) do Address.new(street: "second") end before do person.addresses = [ address_one, address_two ] address_one.addressable = nil end it "sets the relation to nil" do expect(address_one.addressable).to be_nil end it "removed the inverse relation" do expect(person.addresses).to eq([ address_two ]) end it "deletes the child document" do expect(address_one).to be_destroyed end it "reindexes the children" do expect(address_two._index).to eq(0) end end end end describe ".builder" do let(:builder_klass) do Mongoid::Relations::Builders::Embedded::In end let(:base) do Name.new end let(:target) do Person.new end let(:metadata) do Name.relations["namable"] end it "returns the embedded one builder" do expect(described_class.builder(base, metadata, target)).to be_a(builder_klass) end end describe ".embedded?" do it "returns true" do expect(described_class).to be_embedded end end describe ".foreign_key_suffix" do it "returns nil" do expect(described_class.foreign_key_suffix).to be_nil end end describe ".macro" do it "returns embeds_one" do expect(described_class.macro).to eq(:embedded_in) end end describe ".nested_builder" do let(:nested_builder_klass) do Mongoid::Relations::Builders::NestedAttributes::One end let(:metadata) do Name.relations["namable"] end let(:attributes) do {} end it "returns the single nested builder" do expect(described_class.nested_builder(metadata, attributes, {})).to be_a(nested_builder_klass) end end describe "#respond_to?" do let(:person) do Person.new end let!(:name) do person.build_name(first_name: "Tony") end let(:document) do name.namable end Mongoid::Document.public_instance_methods(true).each do |method| context "when checking #{method}" do it "returns true" do expect(document.respond_to?(method)).to be_true end end end end describe ".valid_options" do it "returns the valid options" do expect(described_class.valid_options).to eq( [ :autobuild, :cyclic, :polymorphic ] ) end end describe ".validation_default" do it "returns false" do expect(described_class.validation_default).to be_false end end context "when creating the tree through initialization" do let!(:person) do Person.create end let!(:address) do Address.create(addressable: person) end let!(:first_location) do Location.create(address: address) end let!(:second_location) do Location.create(address: address) end it "saves the child" do expect(Person.last.addresses.last).to eq(address) end it "indexes the child" do expect(address._index).to eq(0) end it "saves the first location with the correct index" do expect(first_location._index).to eq(0) end it "saves the second location with the correct index" do expect(second_location._index).to eq(1) end it "has the locations in the association array" do expect(Person.last.addresses.last.locations).to eq( [first_location, second_location] ) end end context "when instantiating a new child with a persisted parent" do let!(:person) do Person.create end let!(:address) do Address.new(addressable: person) end let!(:location) do Location.new(address: address) end it "does not save the child" do expect(address).to_not be_persisted end it "does not save the deeply embedded children" do expect(address.locations.first).to_not be_persisted end end context "when replacing the relation with another" do let!(:person) do Person.create end let!(:person_two) do Person.create end let!(:address) do person.addresses.create(street: "Kotbusser Damm") end let!(:name) do person_two.create_name(first_name: "Syd") end before do name.namable = address.addressable name.namable.save end it "sets the new parent" do expect(name.namable).to eq(person) end it "removes the previous parent relation" do expect(person_two.name).to be_nil end it "sets the new child relation" do expect(person.name).to eq(name) end context "when reloading" do before do person.reload end it "sets the new parent" do expect(name.namable).to eq(person) end it "removes the previous parent relation" do expect(person_two.name).to be_nil end it "sets the new child relation" do expect(person.name).to eq(name) end end end end