# frozen_string_literal: true
# rubocop:todo all

require "spec_helper"

describe Mongoid::Criteria::Findable do

  describe "#find" do

    context "when finding by a document" do

      let(:band) do
        Band.create!(name: "Tool")
      end

      let!(:record) do
        band.records.create!(name: "Undertow")
      end

      context "when the document is the root" do

        let(:found) do
          Band.find(band)
        end

        it "returns the matching document" do
          expect(found).to eq(band)
        end
      end

      context "when the document is the proxy" do

        let(:found) do
          Band.find(band.records.first.band)
        end

        it "returns the matching document" do
          expect(found).to eq(band)
        end
      end

      context 'when criteria has additional conditions' do
        let(:band) do
          Band.create!(name: "Tool")
        end

        let(:found) do
          Band.where(name: 'Blah').find(band.id)
        end

        it 'respects conditions' do
          expect do
            found
          end.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
        end
      end

      context 'when criteria has additional conditions on id' do
        let(:band) do
          Band.create!(name: "Tool")
        end

        let(:other) do
          Band.create!(name: "Other")
        end

        let(:found) do
          Band.where(id: other.id).find(band.id)
        end

        it 'respects both conditions' do
          expect do
            found
          end.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
        end
      end
    end

    context "when using object ids" do

      let!(:band) do
        Band.create!
      end

      context "when providing a single id" do

        context "when the id matches" do

          let(:found) do
            Band.find(band.id)
          end

          it "returns the matching document" do
            expect(found).to eq(band)
          end

          context "when finding by a JSON-dumped id" do

            let(:found) do
              Band.find(JSON.load(JSON.dump(band.id)))
            end

            it "properly parses the id format" do
              expect(found).to eq(band)
            end
          end
        end

        context "when the id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(BSON::ObjectId.new)
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(BSON::ObjectId.new)
            end

            it "returns nil" do
              expect(found).to be_nil
            end
          end
        end
      end

      context "when providing a splat of ids" do

        let!(:band_two) do
          Band.create!(name: "Tool")
        end

        context "when all ids match" do

          let(:found) do
            Band.find(band.id, band_two.id)
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end

          context "when ids are duplicates" do

            let(:found) do
              Band.find(band.id, band.id)
            end

            it "contains only the first match" do
              expect(found).to eq([band])
            end
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(band.id, BSON::ObjectId.new)
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(band.id, BSON::ObjectId.new)
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end

      context "when providing an array of ids" do

        let!(:band_two) do
          Band.create!(name: "Tool")
        end

        context "when all ids match" do

          let(:found) do
            Band.find([ band.id, band_two.id ])
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end

          context "when ids are duplicates" do

            let(:found) do
              Band.find([ band.id, band.id ])
            end

            it "contains only the first match" do
              expect(found).to eq([band])
            end
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find([ band.id, BSON::ObjectId.new ])
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find([ band.id, BSON::ObjectId.new ])
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end

      context "when providing nested arrays of ids" do

        let!(:band_two) do
          Band.create!(name: "Tool")
        end

        context "when all ids match" do

          let(:found) do
            Band.find([ [ band.id ], [ [ band_two.id ] ] ])
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end

          context "when ids are duplicates" do

            let(:found) do
              Band.find([ [ band.id ], [ [ band.id ] ] ])
            end

            it "contains only the first match" do
              expect(found).to eq([band])
            end
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find([ [ band.id ], [ [ BSON::ObjectId.new ] ] ])
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find([ [ band.id ], [ [ BSON::ObjectId.new ] ] ])
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end

      context "when providing a Set of ids" do

        let!(:band_two) do
          Band.create!(name: "Tool")
        end

        context "when all ids match" do
          let(:found) do
            Band.find(Set[ band.id, band_two.id ])
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(Set[ band.id, BSON::ObjectId.new ])
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(Set[ band.id, BSON::ObjectId.new ])
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end

      context "when providing a Range of ids" do

        let!(:band_two) do
          Band.create!(name: "Tool")
        end

        context "when all ids match" do
          let(:found) do
            Band.find(band.id.to_s..band_two.id.to_s)
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end


          context "when any id does not match" do

            context "when raising a not found error" do
              config_override :raise_not_found_error, true

              let(:found) do
                Band.find(band_two.id.to_s..BSON::ObjectId.new)
              end

              it "does not raise error and returns only the matching documents" do
                expect(found).to eq([ band_two ])
              end
            end

            context "when raising no error" do
              config_override :raise_not_found_error, false

              let(:found) do
                Band.find(band_two.id.to_s..BSON::ObjectId.new)
              end

              it "returns only the matching documents" do
                expect(found).to eq([ band_two ])
              end
            end
          end
        end

        context "when all ids do not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(BSON::ObjectId.new..BSON::ObjectId.new)
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(BSON::ObjectId.new..BSON::ObjectId.new)
            end

            it "returns only the matching documents" do
              expect(found).to eq([])
            end
          end
        end
      end

      context "when providing a single id as extended json" do

        context "when the id matches" do

          let(:found) do
            Band.find(band.id.as_json)
          end

          it "returns the matching document" do
            expect(found).to eq(band)
          end
        end

        context "when the id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(BSON::ObjectId.new.as_json)
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(BSON::ObjectId.new.as_json)
            end

            it "returns nil" do
              expect(found).to be_nil
            end
          end
        end
      end

      context "when providing a splat of extended json ids" do

        let!(:band_two) do
          Band.create!(name: "Tool")
        end

        context "when all ids match" do

          let(:found) do
            Band.find(band.id.as_json, band_two.id.as_json)
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end

          context "when ids are duplicates" do

            let(:found) do
              Band.find(band.id, band.id)
            end

            it "contains only the first match" do
              expect(found).to eq([band])
            end
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(band.id.as_json, BSON::ObjectId.new.as_json)
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(band.id.as_json, BSON::ObjectId.new.as_json)
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end

      context "when providing an array of extended json ids" do

        let!(:band_two) do
          Band.create!(name: "Tool")
        end

        context "when all ids match" do

          let(:found) do
            Band.find([ band.id.as_json, band_two.id.as_json ])
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end

          context "when ids are duplicates" do

            let(:found) do
              Band.find([ band.id, band.id ])
            end

            it "contains only the first match" do
              expect(found).to eq([band])
            end
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find([ band.id.as_json, BSON::ObjectId.new.as_json ])
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find([ band.id.as_json, BSON::ObjectId.new.as_json ])
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end
    end

    context "when using string ids" do

      before(:all) do
        Band.field :_id, overwrite: true, type: String
      end

      after(:all) do
        Band.field :_id, overwrite: true, type: BSON::ObjectId, default: ->{ BSON::ObjectId.new }
      end

      let!(:band) do
        Band.create! do |band|
          band.id = "tool"
        end
      end

      context "when providing a single id" do

        context "when the id matches" do

          let(:found) do
            Band.find(band.id)
          end

          it "returns the matching document" do
            expect(found).to eq(band)
          end
        end

        context "when the id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find("depeche-mode")
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find("depeche-mode")
            end

            it "returns nil" do
              expect(found).to be_nil
            end
          end
        end
      end

      context "when providing a splat of ids" do

        let!(:band_two) do
          Band.create! do |band|
            band.id = "depeche-mode"
          end
        end

        context "when all ids match" do

          let(:found) do
            Band.find(band.id, band_two.id)
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(band.id, "new-order")
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(band.id, "new-order")
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end

      context "when providing an array of ids" do

        let!(:band_two) do
          Band.create! do |band|
            band.id = "depeche-mode"
          end
        end

        context "when all ids match" do

          let(:found) do
            Band.find([ band.id, band_two.id ])
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find([ band.id, "new-order" ])
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find([ band.id, "new-order" ])
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end
    end

    context "when using hash ids" do

      before(:all) do
        Band.field :_id, overwrite: true, type: Hash
      end

      after(:all) do
        Band.field :_id, overwrite: true, type: BSON::ObjectId, default: ->{ BSON::ObjectId.new }
      end

      let!(:band) do
        Band.create! do |band|
          band.id = {"new-order" => true, "Depeche Mode" => false}
        end
      end

      context "when providing a single id" do

        context "when the id matches" do

          let(:found) do
            Band.find(band.id)
          end

          it "returns the matching document" do
            expect(found).to eq(band)
          end
        end

        context "when the id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find({"new-order" => false, "Faith no More" => true})
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find({"new-order" => false, "Faith no More" => true})
            end

            it "returns nil" do
              expect(found).to be_nil
            end
          end
        end
      end

      context "when providing a splat of ids" do

        let!(:band_two) do
          Band.create! do |band|
            band.id = {"Radiohead" => false, "Nirvana"=> true}
          end
        end

        context "when all ids match" do

          let(:found) do
            Band.find(band.id, band_two.id)
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(band.id, {"Radiohead" => true, "Nirvana"=> false})
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(band.id, {"Radiohead" => true, "Nirvana"=> false})
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end

      context "when providing an array of ids" do

        let!(:band_two) do
          Band.create! do |band|
            band.id = {"Radiohead" => false, "Nirvana"=> true}
          end
        end

        context "when all ids match" do

          let(:found) do
            Band.find([ band.id, band_two.id ])
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find([ band.id, {"Radiohead" => true, "Nirvana"=> false} ])
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find([ band.id, {"Radiohead" => true, "Nirvana"=> false} ])
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end
    end

    context "when using integer ids" do

      before(:all) do
        Band.field :_id, overwrite: true, type: Integer
      end

      after(:all) do
        Band.field :_id, overwrite: true, type: BSON::ObjectId, default: ->{ BSON::ObjectId.new }
      end

      let!(:band) do
        Band.create! do |band|
          band.id = 1
        end
      end

      context "when providing a single id" do

        context "when the id matches" do

          let(:found) do
            Band.find(band.id)
          end

          it "returns the matching document" do
            expect(found).to eq(band)
          end
        end

        context "when the id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(3)
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(3)
            end

            it "returns nil" do
              expect(found).to be_nil
            end
          end
        end
      end

      context "when providing a splat of ids" do

        let!(:band_two) do
          Band.create! do |band|
            band.id = 2
          end
        end

        context "when all ids match" do

          let(:found) do
            Band.find(band.id, band_two.id)
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(band.id, 3)
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(band.id, 3)
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end

      context "when providing an array of ids" do

        let!(:band_two) do
          Band.create! do |band|
            band.id = 2
          end
        end

        context "when all ids match" do

          let(:found) do
            Band.find([ band.id, band_two.id ])
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find([ band.id, 3 ])
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find([ band.id, 3 ])
            end

            it "returns only the matching documents" do
              expect(found).to eq([ band ])
            end
          end
        end
      end

      context "when providing a range" do

        let!(:band_two) do
          Band.create! do |band|
            band.id = 2
          end
        end

        context "when all ids match" do

          let(:found) do
            Band.find(1..2)
          end

          it "contains the first match" do
            expect(found).to include(band)
          end

          it "contains the second match" do
            expect(found).to include(band_two)
          end
        end

        context "when any id does not match" do

          context "when raising a not found error" do
            config_override :raise_not_found_error, true

            let(:found) do
              Band.find(1..3)
            end

            it "raises an error" do
              expect {
                found
              }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
            end
          end

          context "when raising no error" do
            config_override :raise_not_found_error, false

            let(:found) do
              Band.find(1..3)
            end

            it "contains the first match" do
              expect(found).to include(band)
            end

            it "contains the second match" do
              expect(found).to include(band_two)
            end

            it "returns only the matches" do
              expect(found.count).to eq(2)
            end
          end
        end
      end
    end

    context "when using string and object ids" do

      let!(:band) do
        Band.create!
      end

      context "when providing multiple ids" do

        context "when ids are duplicates" do

          let(:found) do
            Band.find([ band.id.to_s, band.id ])
          end

          it "contains only the first match" do
            expect(found).to eq([band])
          end
        end
      end
    end

    context "when passing in a block" do

      let!(:band1) { Band.create!(name: '1') }
      let!(:band2) { Band.create!(name: '2') }
      let!(:band3) { Band.create!(name: '2') }

      it "yields the documents to the block" do
        doc = Band.find { |b| b.name == '2' }
        expect(doc).to eq(band2)
      end
    end

    context "when passing in ids and a block" do

      let!(:band1) { Band.create!(name: '1') }
      let!(:band2) { Band.create!(name: '2') }
      let!(:band3) { Band.create!(name: '2') }

      it "acts like findable find" do
        docs = Band.find(band1.id, band2.id) { |b| b.name == '2' }
        expect(docs).to eq([ band1, band2 ])
      end
    end

    context "when passing in a Proc and a block" do

      let!(:band1) { Band.create!(name: '1') }
      let!(:band2) { Band.create!(name: '2') }
      let!(:band3) { Band.create!(name: '2') }

      it "acts like findable find" do
        docs = Band.find(-> { 'default' }) { |b| b.name == '3' }
        expect(docs).to eq('default')
      end
    end
  end

  describe "#for_ids" do

    context "when only 1 id exists" do

      let(:id) do
        BSON::ObjectId.new
      end

      let(:criteria) do
        Band.queryable.for_ids([ id ])
      end

      it "does not turn the selector into an $in" do
        expect(criteria.selector).to eq({ "_id" => id })
      end
    end
  end

  describe "#multiple_from__db" do

    let!(:band) do
      Band.create!(name: "Depeche Mode")
    end

    let!(:band_two) do
      Band.create!(name: "Tool")
    end

    context "when providing a single id" do

      let(:criteria) do
        Band.where(_id: band.id)
      end

      let(:from_db) do
        criteria.multiple_from_db([ band.id ])
      end

      it "returns the document from the database" do
        expect(from_db.first).to_not equal(band)
      end

      it "returns the correct document" do
        expect(from_db.first).to eq(band)
      end
    end

    context "when providing multiple ids" do

      let(:criteria) do
        Band.where(:_id.in => [ band.id, band_two.id ])
      end

      let(:from_db) do
        criteria.multiple_from_db([ band.id, band_two.id ])
      end

      it "returns the document from the database" do
        expect(from_db.first).to_not equal(band)
      end

      it "returns the correct document" do
        expect(from_db.first).to eq(band)
      end
    end
  end

  describe '#from_database_selector' do
    let(:criteria) { Mongoid::Criteria.new(Band) }
    let(:result) { criteria.send(:from_database_selector, [1]) }

    context 'when criteria is empty' do
      it 'adds id' do
        expect(result.selector).to eq('_id' => 1)
      end
    end

    context 'when criteria is restricted by id' do
      let(:criteria) { Mongoid::Criteria.new(Band).where(id: 2) }

      it 'adds id' do
        expect(result.selector).to eq('_id' => 2, '$and' => [{'_id' => 1}])
      end
    end
  end
end
