spec/mongo/collection_spec.rb in mongo-2.1.2 vs spec/mongo/collection_spec.rb in mongo-2.2.0.rc0
- old
+ new
@@ -2,15 +2,22 @@
describe Mongo::Collection do
after do
authorized_collection.delete_many
+ collection_with_validator.drop()
end
let(:collection_invalid_write_concern) do
authorized_collection.client.with(write: { w: (WRITE_CONCERN[:w] + 1) })[authorized_collection.name]
end
+ let(:collection_with_validator) do
+ authorized_client[:validating,
+ :validator => { :a => { '$exists' => true } }].tap do |c|
+ c.create
+ end
+ end
describe '#==' do
let(:database) do
Mongo::Database.new(authorized_client, :test)
@@ -338,10 +345,14 @@
let!(:response) do
collection.create
end
+ let(:options) do
+ { :capped => true, :size => 1024 }
+ end
+
after do
collection.drop
end
it 'executes the command' do
@@ -355,26 +366,66 @@
it 'creates the collection in the database' do
expect(database.collection_names).to include('specs')
end
end
+ shared_examples 'a validated collection command' do
+
+ let!(:response) do
+ collection.create
+ end
+
+ let(:options) do
+ { :validator => { fieldName: { '$gte' => 1024 } },
+ :validationLevel => 'strict' }
+ end
+
+ let(:collection_info) do
+ database.list_collections.find { |i| i['name'] == 'specs' }
+ end
+
+ after do
+ collection.drop
+ end
+
+ it 'executes the command' do
+ expect(response).to be_successful
+ end
+
+ it 'sets the collection with validators' do
+ expect(collection_info['options']['validator']).to eq({ 'fieldName' => { '$gte' => 1024 } })
+ end
+
+ it 'creates the collection in the database' do
+ expect(database.collection_names).to include('specs')
+ end
+ end
+
context 'when instantiating a collection directly' do
let(:collection) do
- described_class.new(database, :specs, :capped => true, :size => 1024)
+ described_class.new(database, :specs, options)
end
it_behaves_like 'a capped collection command'
+
+ context 'when validators can be set', if: find_command_enabled? do
+ it_behaves_like 'a validated collection command'
+ end
end
context 'when instantiating a collection through the database' do
let(:collection) do
- authorized_client[:specs, :capped => true, :size => 1024]
+ authorized_client[:specs, options]
end
it_behaves_like 'a capped collection command'
+
+ context 'when validators can be set', if: find_command_enabled? do
+ it_behaves_like 'a validated collection command'
+ end
end
end
end
end
@@ -412,33 +463,33 @@
end
end
describe '#find' do
- context 'when provided a selector' do
+ context 'when provided a filter' do
let(:view) do
authorized_collection.find(name: 1)
end
- it 'returns a authorized_collection view for the selector' do
- expect(view.selector).to eq(name: 1)
+ it 'returns a authorized_collection view for the filter' do
+ expect(view.filter).to eq('name' => 1)
end
end
- context 'when provided no selector' do
+ context 'when provided no filter' do
let(:view) do
authorized_collection.find
end
- it 'returns a authorized_collection view with an empty selector' do
- expect(view.selector).to be_empty
+ it 'returns a authorized_collection view with an empty filter' do
+ expect(view.filter).to be_empty
end
end
- context 'when providing a bad selector' do
+ context 'when providing a bad filter' do
let(:view) do
authorized_collection.find('$or' => [])
end
@@ -578,11 +629,11 @@
end
context 'when provided :modifiers' do
let(:options) do
- { modifiers: { :$orderby => Mongo::Index::ASCENDING } }
+ { modifiers: { '$orderby' => Mongo::Index::ASCENDING } }
end
it 'returns a view with modifiers set' do
expect(view.modifiers).to eq(options[:modifiers])
end
@@ -651,10 +702,11 @@
describe '#insert_many' do
after do
authorized_collection.delete_many
+ collection_with_validator.delete_many
end
let(:result) do
authorized_collection.insert_many([{ name: 'test1' }, { name: 'test2' }])
end
@@ -665,10 +717,41 @@
it 'contains the ids in the result' do
expect(result.inserted_ids.size).to eq(2)
end
+ context 'when the client has a custom id generator' do
+
+ let(:generator) do
+ Class.new do
+ def generate
+ 1
+ end
+ end.new
+ end
+
+ let(:custom_client) do
+ authorized_client.with(id_generator: generator)
+ end
+
+ let(:custom_collection) do
+ custom_client[TEST_COLL]
+ end
+
+ before do
+ custom_collection.insert_many([{ name: 'testing' }])
+ end
+
+ after do
+ custom_client.close
+ end
+
+ it 'inserts with the custom id' do
+ expect(custom_collection.find.first[:_id]).to eq(1)
+ end
+ end
+
context 'when the inserts fail' do
let(:result) do
authorized_collection.insert_many([{ _id: 1 }, { _id: 1 }])
end
@@ -677,16 +760,72 @@
expect {
result
}.to raise_exception(Mongo::Error::BulkWriteError)
end
end
+
+ context "when the documents exceed the max bson size" do
+
+ let(:documents) do
+ [{ '_id' => 1, 'name' => '1'*17000000 }]
+ end
+
+ it 'raises a MaxBSONSize error' do
+ expect {
+ authorized_collection.insert_many(documents)
+ }.to raise_error(Mongo::Error::MaxBSONSize)
+ end
+ end
+
+ context 'when collection has a validator', if: find_command_enabled? do
+
+ context 'when the document is valid' do
+
+ let(:result) do
+ collection_with_validator.insert_many([{ a: 1 }, { a: 2 }])
+ end
+
+ it 'inserts successfully' do
+ expect(result.inserted_count).to eq(2)
+ end
+ end
+
+ context 'when the document is invalid' do
+
+ context 'when bypass_document_validation is not set' do
+
+ let(:result2) do
+ collection_with_validator.insert_many([{ x: 1 }, { x: 2 }])
+ end
+
+ it 'raises a BulkWriteError' do
+ expect {
+ result2
+ }.to raise_exception(Mongo::Error::BulkWriteError)
+ end
+ end
+
+ context 'when bypass_document_validation is true' do
+
+ let(:result3) do
+ collection_with_validator.insert_many(
+ [{ x: 1 }, { x: 2 }], :bypass_document_validation => true)
+ end
+
+ it 'inserts successfully' do
+ expect(result3.inserted_count).to eq(2)
+ end
+ end
+ end
+ end
end
describe '#insert_one' do
after do
authorized_collection.delete_many
+ collection_with_validator.delete_many
end
let(:result) do
authorized_collection.insert_one({ name: 'testing' })
end
@@ -714,10 +853,83 @@
expect {
result
}.to raise_exception(Mongo::Error::OperationFailure)
end
end
+
+ context 'when the client has a custom id generator' do
+
+ let(:generator) do
+ Class.new do
+ def generate
+ 1
+ end
+ end.new
+ end
+
+ let(:custom_client) do
+ authorized_client.with(id_generator: generator)
+ end
+
+ let(:custom_collection) do
+ custom_client[TEST_COLL]
+ end
+
+ before do
+ custom_collection.insert_one({ name: 'testing' })
+ end
+
+ after do
+ custom_client.close
+ end
+
+ it 'inserts with the custom id' do
+ expect(custom_collection.find.first[:_id]).to eq(1)
+ end
+ end
+
+ context 'when collection has a validator', if: find_command_enabled? do
+
+ context 'when the document is valid' do
+
+ let(:result) do
+ collection_with_validator.insert_one({ a: 1 })
+ end
+
+ it 'inserts successfully' do
+ expect(result.written_count).to eq(1)
+ end
+ end
+
+ context 'when the document is invalid' do
+
+ context 'when bypass_document_validation is not set' do
+
+ let(:result2) do
+ collection_with_validator.insert_one({ x: 1 })
+ end
+
+ it 'raises a OperationFailure' do
+ expect {
+ result2
+ }.to raise_exception(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when bypass_document_validation is true' do
+
+ let(:result3) do
+ collection_with_validator.insert_one(
+ { x: 1 }, :bypass_document_validation => true)
+ end
+
+ it 'inserts successfully' do
+ expect(result3.written_count).to eq(1)
+ end
+ end
+ end
+ end
end
describe '#inspect' do
it 'includes the object id' do
@@ -770,11 +982,11 @@
end
context 'when options are provided' do
let(:options) do
- { :allow_disk_use => true }
+ { :allow_disk_use => true, :bypass_document_validation => true }
end
it 'sets the options on the Aggregation object' do
expect(authorized_collection.aggregate([], options).options).to eq(options)
end
@@ -971,10 +1183,41 @@
it 'raises an error', unless: write_command_enabled? do
expect {
cursors
}.to raise_error(Mongo::Error::OperationFailure)
end
+
+ context 'when a read concern is provided', if: find_command_enabled? do
+
+ let(:result) do
+ authorized_collection.with(options).parallel_scan(2)
+ end
+
+ context 'when the read concern is valid' do
+
+ let(:options) do
+ { read_concern: { level: 'local' }}
+ end
+
+ it 'sends the read concern' do
+ expect { result }.to_not raise_error
+ end
+ end
+
+ context 'when the read concern is not valid' do
+
+ let(:options) do
+ { read_concern: { level: 'idontknow' }}
+ end
+
+ it 'raises an exception' do
+ expect {
+ result
+ }.to raise_error(Mongo::Error::OperationFailure)
+ end
+ end
+ end
end
describe '#replace_one' do
let(:selector) do
@@ -1079,10 +1322,60 @@
expect {
result
}.to raise_exception(Mongo::Error::OperationFailure)
end
end
+
+ context 'when collection has a validator', if: find_command_enabled? do
+
+ before do
+ collection_with_validator.insert_one({ a: 1 })
+ end
+
+ after do
+ collection_with_validator.delete_many
+ end
+
+ context 'when the document is valid' do
+
+ let(:result) do
+ collection_with_validator.replace_one({ a: 1 }, { a: 5 })
+ end
+
+ it 'replaces successfully' do
+ expect(result.modified_count).to eq(1)
+ end
+ end
+
+ context 'when the document is invalid' do
+
+ context 'when bypass_document_validation is not set' do
+
+ let(:result2) do
+ collection_with_validator.replace_one({ a: 1 }, { x: 5 })
+ end
+
+ it 'raises OperationFailure' do
+ expect {
+ result2
+ }.to raise_exception(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when bypass_document_validation is true' do
+
+ let(:result3) do
+ collection_with_validator.replace_one(
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true)
+ end
+
+ it 'replaces successfully' do
+ expect(result3.written_count).to eq(1)
+ end
+ end
+ end
+ end
end
describe '#update_many' do
let(:selector) do
@@ -1185,10 +1478,63 @@
expect {
result
}.to raise_exception(Mongo::Error::OperationFailure)
end
end
+
+ context 'when collection has a validator', if: find_command_enabled? do
+
+ before do
+ collection_with_validator.insert_many([{ a: 1 }, { a: 2 }])
+ end
+
+ after do
+ collection_with_validator.delete_many
+ end
+
+ context 'when the document is valid' do
+
+ let(:result) do
+ collection_with_validator.update_many(
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
+ end
+
+ it 'updates successfully' do
+ expect(result.modified_count).to eq(2)
+ end
+ end
+
+ context 'when the document is invalid' do
+
+ context 'when bypass_document_validation is not set' do
+
+ let(:result2) do
+ collection_with_validator.update_many(
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
+ end
+
+ it 'raises OperationFailure' do
+ expect {
+ result2
+ }.to raise_exception(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when bypass_document_validation is true' do
+
+ let(:result3) do
+ collection_with_validator.update_many(
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
+ :bypass_document_validation => true)
+ end
+
+ it 'updates successfully' do
+ expect(result3.written_count).to eq(2)
+ end
+ end
+ end
+ end
end
describe '#update_one' do
let(:selector) do
@@ -1287,10 +1633,63 @@
expect {
result
}.to raise_exception(Mongo::Error::OperationFailure)
end
end
+
+ context 'when collection has a validator', if: find_command_enabled? do
+
+ before do
+ collection_with_validator.insert_one({ a: 1 })
+ end
+
+ after do
+ collection_with_validator.delete_many
+ end
+
+ context 'when the document is valid' do
+
+ let(:result) do
+ collection_with_validator.update_one(
+ { :a => { '$gt' => 0 } }, '$inc' => { :a => 1 } )
+ end
+
+ it 'updates successfully' do
+ expect(result.modified_count).to eq(1)
+ end
+ end
+
+ context 'when the document is invalid' do
+
+ context 'when bypass_document_validation is not set' do
+
+ let(:result2) do
+ collection_with_validator.update_one(
+ { :a => { '$gt' => 0 } }, '$unset' => { :a => '' })
+ end
+
+ it 'raises OperationFailure' do
+ expect {
+ result2
+ }.to raise_exception(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when bypass_document_validation is true' do
+
+ let(:result3) do
+ collection_with_validator.update_one(
+ { :a => { '$gt' => 0 } }, { '$unset' => { :a => '' } },
+ :bypass_document_validation => true)
+ end
+
+ it 'updates successfully' do
+ expect(result3.written_count).to eq(1)
+ end
+ end
+ end
+ end
end
describe '#find_one_and_delete' do
before do
@@ -1384,10 +1783,34 @@
expect {
result
}.to raise_exception(Mongo::Error::OperationFailure)
end
end
+
+ context 'when write_concern is provided', if: find_command_enabled? && standalone? do
+
+ it 'uses the write concern' do
+ expect {
+ authorized_collection.find_one_and_delete(selector,
+ write_concern: { w: 2 })
+ }.to raise_error(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
+
+ let(:collection) do
+ authorized_collection.with(write: { w: 2 })
+ end
+
+ it 'uses the write concern' do
+ expect {
+ collection.find_one_and_delete(selector,
+ write_concern: { w: 2 })
+ }.to raise_error(Mongo::Error::OperationFailure)
+ end
+ end
end
describe '#find_one_and_update' do
let(:selector) do
@@ -1538,10 +1961,90 @@
expect {
result
}.to raise_exception(Mongo::Error::OperationFailure)
end
end
+
+ context 'when collection has a validator', if: find_command_enabled? do
+
+ before do
+ collection_with_validator.insert_one({ a: 1 })
+ end
+
+ after do
+ collection_with_validator.delete_many
+ end
+
+ context 'when the document is valid' do
+
+ let(:result) do
+ collection_with_validator.find_one_and_update(
+ { a: 1 }, { '$inc' => { :a => 1 } }, :return_document => :after)
+ end
+
+ it 'updates successfully' do
+ expect(result['a']).to eq(2)
+ end
+ end
+
+ context 'when the document is invalid' do
+
+ context 'when bypass_document_validation is not set' do
+
+ let(:result2) do
+ collection_with_validator.find_one_and_update(
+ { a: 1 }, { '$unset' => { :a => '' } }, :return_document => :after)
+ end
+
+ it 'raises OperationFailure' do
+ expect {
+ result2
+ }.to raise_exception(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when bypass_document_validation is true' do
+
+ let(:result3) do
+ collection_with_validator.find_one_and_update(
+ { a: 1 }, { '$unset' => { :a => '' } },
+ :bypass_document_validation => true,
+ :return_document => :after)
+ end
+
+ it 'updates successfully' do
+ expect(result3['a']).to be_nil
+ end
+ end
+ end
+ end
+
+ context 'when write_concern is provided', if: find_command_enabled? && standalone? do
+
+ it 'uses the write concern' do
+ expect {
+ authorized_collection.find_one_and_update(selector,
+ { '$set' => { field: 'testing' }},
+ write_concern: { w: 2 })
+ }.to raise_error(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
+
+ let(:collection) do
+ authorized_collection.with(write: { w: 2 })
+ end
+
+ it 'uses the write concern' do
+ expect {
+ collection.find_one_and_update(selector,
+ { '$set' => { field: 'testing' }},
+ write_concern: { w: 2 })
+ }.to raise_error(Mongo::Error::OperationFailure)
+ end
+ end
end
describe '#find_one_and_replace' do
before do
@@ -1664,9 +2167,89 @@
it 'raises an OperationFailure' do
expect {
result
}.to raise_exception(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when collection has a validator', if: find_command_enabled? do
+
+ before do
+ collection_with_validator.insert_one({ a: 1 })
+ end
+
+ after do
+ collection_with_validator.delete_many
+ end
+
+ context 'when the document is valid' do
+
+ let(:result) do
+ collection_with_validator.find_one_and_replace(
+ { a: 1 }, { a: 5 }, :return_document => :after)
+ end
+
+ it 'replaces successfully when document is valid' do
+ expect(result[:a]).to eq(5)
+ end
+ end
+
+ context 'when the document is invalid' do
+
+ context 'when bypass_document_validation is not set' do
+
+ let(:result2) do
+ collection_with_validator.find_one_and_replace(
+ { a: 1 }, { x: 5 }, :return_document => :after)
+ end
+
+ it 'raises OperationFailure' do
+ expect {
+ result2
+ }.to raise_exception(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when bypass_document_validation is true' do
+
+ let(:result3) do
+ collection_with_validator.find_one_and_replace(
+ { a: 1 }, { x: 1 }, :bypass_document_validation => true,
+ :return_document => :after)
+ end
+
+ it 'replaces successfully' do
+ expect(result3[:x]).to eq(1)
+ expect(result3[:a]).to be_nil
+ end
+ end
+ end
+ end
+
+ context 'when write_concern is provided', if: find_command_enabled? && standalone? do
+
+ it 'uses the write concern' do
+ expect {
+ authorized_collection.find_one_and_replace(selector,
+ { field: 'testing' },
+ write_concern: { w: 2 })
+ }.to raise_error(Mongo::Error::OperationFailure)
+ end
+ end
+
+ context 'when the collection has a write concern', if: find_command_enabled? && standalone? do
+
+ let(:collection) do
+ authorized_collection.with(write: { w: 2 })
+ end
+
+ it 'uses the write concern' do
+ expect {
+ collection.find_one_and_replace(selector,
+ { field: 'testing' },
+ write_concern: { w: 2 })
+ }.to raise_error(Mongo::Error::OperationFailure)
end
end
end
end