diff --git a/test/integration/crud/document_validation.test.js b/test/integration/crud/document_validation.test.js deleted file mode 100644 index e17f93d8225..00000000000 --- a/test/integration/crud/document_validation.test.js +++ /dev/null @@ -1,345 +0,0 @@ -'use strict'; -const { assert: test, setupDatabase } = require('../shared'); -const { expect } = require('chai'); - -describe('Document Validation', function () { - before(function () { - return setupDatabase(this.configuration); - }); - - it('should allow bypassing document validation in 3.2 or higher on inserts', { - // Add a tag that our runner can trigger on - // in this case we are setting that node needs to be higher than 0.10.X to run - metadata: { - requires: { - mongodb: '>=3.1.7', - topology: ['single', 'replicaset', 'sharded'] - } - }, - - test: function (done) { - var configuration = this.configuration; - var client = configuration.newClient(configuration.writeConcernMax(), { maxPoolSize: 1 }); - client.connect(function (err, client) { - var db = client.db(configuration.db); - expect(err).to.not.exist; - - // Get collection - var col = db.collection('createValidationCollection'); - - // Drop the collection - col.drop(function () { - // Create a collection with a validator - db.createCollection( - 'createValidationCollection', - { validator: { a: { $exists: true } } }, - function (err) { - expect(err).to.not.exist; - - // Ensure validation was correctly applied - col.insert({ b: 1 }, function (err) { - test.ok(err != null); - - // Ensure validation was correctly applied - col.insert({ b: 1 }, { bypassDocumentValidation: true }, function (err) { - expect(err).to.not.exist; - - // Bypass valiation on insert - col.insertOne({ b: 1 }, { bypassDocumentValidation: true }, function (err) { - expect(err).to.not.exist; - - // Bypass valiation on insert - col.insertMany([{ b: 1 }], { bypassDocumentValidation: true }, function (err) { - expect(err).to.not.exist; - - client.close(done); - }); - }); - }); - }); - } - ); - }); - }); - } - }); - - it('should allow bypassing document validation in 3.2 or higher on updates', { - // Add a tag that our runner can trigger on - // in this case we are setting that node needs to be higher than 0.10.X to run - metadata: { - requires: { - mongodb: '>=3.1.7', - topology: ['single', 'replicaset', 'sharded'] - } - }, - - test: function (done) { - var configuration = this.configuration; - var client = configuration.newClient(configuration.writeConcernMax(), { maxPoolSize: 1 }); - client.connect(function (err, client) { - var db = client.db(configuration.db); - expect(err).to.not.exist; - - // Get collection - var col = db.collection('createValidationCollection'); - - // Drop the collection - col.drop(function () { - // Create a collection with a validator - db.createCollection( - 'createValidationCollection', - { validator: { a: { $exists: true } } }, - function (err) { - expect(err).to.not.exist; - - // Should fail - col.update({ b: 1 }, { $set: { b: 1 } }, { upsert: true }, function (err) { - expect(err).to.exist; - - // Ensure validation was correctly applied - col.update( - { b: 1 }, - { $set: { b: 1 } }, - { upsert: true, bypassDocumentValidation: true }, - function (err) { - expect(err).to.not.exist; - - // updateOne - col.updateOne( - { c: 1 }, - { $set: { c: 1 } }, - { upsert: true, bypassDocumentValidation: true }, - function (err) { - expect(err).to.not.exist; - - // updateMany - col.updateMany( - { d: 1 }, - { $set: { d: 1 } }, - { upsert: true, bypassDocumentValidation: true }, - function (err) { - expect(err).to.not.exist; - - // updateMany - col.replaceOne( - { e: 1 }, - { e: 1 }, - { upsert: true, bypassDocumentValidation: true }, - function (err) { - expect(err).to.not.exist; - - client.close(done); - } - ); - } - ); - } - ); - } - ); - }); - } - ); - }); - }); - } - }); - - it('should allow bypassing document validation in 3.2 or higher on bulkWrite', { - // Add a tag that our runner can trigger on - // in this case we are setting that node needs to be higher than 0.10.X to run - metadata: { - requires: { - mongodb: '>=3.1.7', - topology: ['single', 'replicaset', 'sharded'] - } - }, - - test: function (done) { - var configuration = this.configuration; - var client = configuration.newClient(configuration.writeConcernMax(), { maxPoolSize: 1 }); - client.connect(function (err, client) { - var db = client.db(configuration.db); - expect(err).to.not.exist; - - // Get collection - var col = db.collection('createValidationCollection'); - - // Drop the collection - col.drop(function () { - // Create a collection with a validator - db.createCollection( - 'createValidationCollection', - { validator: { a: { $exists: true } } }, - function (err) { - expect(err).to.not.exist; - - // Should fail - col.bulkWrite([{ insertOne: { b: 1 } }], function (err) { - test.ok(err != null); - - col.bulkWrite( - [{ insertOne: { b: 1 } }], - { bypassDocumentValidation: true }, - function (err) { - expect(err).to.not.exist; - - client.close(done); - } - ); - }); - } - ); - }); - }); - } - }); - - it('should allow bypassing document validation in 3.2 or higher on findAndModify', { - // Add a tag that our runner can trigger on - // in this case we are setting that node needs to be higher than 0.10.X to run - metadata: { - requires: { - mongodb: '>=3.1.7', - topology: ['single', 'replicaset', 'sharded'] - } - }, - - test: function (done) { - var configuration = this.configuration; - var client = configuration.newClient(configuration.writeConcernMax(), { maxPoolSize: 1 }); - client.connect(function (err, client) { - var db = client.db(configuration.db); - expect(err).to.not.exist; - - // Get collection - var col = db.collection('createValidationCollection'); - - // Drop the collection - col.drop(function () { - // Create a collection with a validator - db.createCollection( - 'createValidationCollection', - { validator: { a: { $exists: true } } }, - function (err) { - expect(err).to.not.exist; - - // Should fail - col.findOneAndUpdate({ b: 1 }, { $set: { b: 1 } }, { upsert: true }, function (err) { - test.ok(err != null); - - // Should pass - col.findOneAndUpdate( - { b: 1 }, - { $set: { b: 1 } }, - { upsert: true, bypassDocumentValidation: true }, - function (err) { - expect(err).to.not.exist; - - // Should pass - col.findOneAndReplace( - { c: 1 }, - { c: 1 }, - { upsert: true, bypassDocumentValidation: true }, - function (err) { - expect(err).to.not.exist; - - client.close(done); - } - ); - } - ); - }); - } - ); - }); - }); - } - }); - - it('should correctly bypass validation for aggregation using out', { - // Add a tag that our runner can trigger on - // in this case we are setting that node needs to be higher than 0.10.X to run - metadata: { - requires: { - mongodb: '>=3.1.7', - topology: ['single', 'replicaset', 'sharded'] - } - }, - - test: function (done) { - var configuration = this.configuration; - var client = configuration.newClient(configuration.writeConcernMax(), { maxPoolSize: 1 }); - client.connect(function (err, client) { - var db = client.db(configuration.db); - // Some docs for insertion - var docs = [ - { - title: 'this is my title', - author: 'bob', - posted: new Date(), - pageViews: 5, - tags: ['fun', 'good', 'fun'], - other: { foo: 5 }, - comments: [ - { author: 'joe', text: 'this is cool' }, - { author: 'sam', text: 'this is bad' } - ] - } - ]; - - // Get collection - var col = db.collection('createValidationCollectionOut'); - - // Drop the collection - col.drop(function () { - // Create a collection with a validator - db.createCollection( - 'createValidationCollectionOut', - { validator: { a: { $exists: true } } }, - function (err) { - expect(err).to.not.exist; - - // Insert the docs - col.insertMany( - docs, - { writeConcern: { w: 1 }, bypassDocumentValidation: true }, - function (err) { - expect(err).to.not.exist; - - // Execute aggregate, notice the pipeline is expressed as an Array - const cursor = col.aggregate( - [ - { - $project: { - author: 1, - tags: 1 - } - }, - { $unwind: '$tags' }, - { - $group: { - _id: { tags: '$tags' }, - authors: { $addToSet: '$author' } - } - }, - { $out: 'createValidationCollectionOut' } - ], - { bypassDocumentValidation: true } - ); - - cursor.toArray(function (err) { - expect(err).to.not.exist; - - client.close(done); - }); - } - ); - } - ); - }); - }); - } - }); -}); diff --git a/test/integration/crud/document_validation.test.ts b/test/integration/crud/document_validation.test.ts new file mode 100644 index 00000000000..3e74daaf4f4 --- /dev/null +++ b/test/integration/crud/document_validation.test.ts @@ -0,0 +1,210 @@ +import { expect } from 'chai'; + +import { MongoBulkWriteError, type MongoClient, MongoServerError } from '../../../src'; +import { assert as test, ignoreNsNotFound, setupDatabase } from '../shared'; + +describe('Document Validation', function () { + let client: MongoClient; + + before(function () { + return setupDatabase(this.configuration); + }); + + beforeEach(function () { + client = this.configuration.newClient(this.configuration.writeConcernMax(), { maxPoolSize: 1 }); + }); + + afterEach(async function () { + await client?.close(); + }); + + it('should allow bypassing document validation on inserts', { + metadata: { requires: { topology: ['single', 'replicaset', 'sharded'] } }, + + test: async function () { + const db = client.db(this.configuration.db); + + // Get collection + const col = db.collection('createValidationCollection'); + + // Drop the collection + await col.drop().catch(ignoreNsNotFound); + // Create a collection with a validator + await db.createCollection('createValidationCollection', { + validator: { a: { $exists: true } } + }); + + // Ensure validation was correctly applied + const err = await col.insertOne({ b: 1 }).catch(err => err); + test.ok(err instanceof MongoServerError); + + // Bypass valiation on insertOne + await col.insertOne({ b: 1 }, { bypassDocumentValidation: true }); + + // Bypass valiation on insertMany + await col.insertMany([{ b: 1 }], { bypassDocumentValidation: true }); + } + }); + + it('should allow bypassing document validation on updates', { + metadata: { requires: { topology: ['single', 'replicaset', 'sharded'] } }, + + test: async function () { + const db = client.db(this.configuration.db); + + // Get collection + const col = db.collection('createValidationCollection'); + + // Drop the collection + await col.drop().catch(ignoreNsNotFound); + // Create a collection with a validator + await db.createCollection('createValidationCollection', { + validator: { a: { $exists: true } } + }); + + // Should fail + const err = await col + .updateOne({ b: 1 }, { $set: { b: 1 } }, { upsert: true }) + .catch(err => err); + expect(err).to.be.instanceOf(MongoServerError); + + // Ensure validation was correctly applied + await col.updateOne( + { b: 1 }, + { $set: { b: 1 } }, + { upsert: true, bypassDocumentValidation: true } + ); + + // updateMany + await col.updateMany( + { d: 1 }, + { $set: { d: 1 } }, + { upsert: true, bypassDocumentValidation: true } + ); + + // replaceOne + await col.replaceOne({ e: 1 }, { e: 1 }, { upsert: true, bypassDocumentValidation: true }); + } + }); + + it('should allow bypassing document validation on bulkWrite', { + metadata: { requires: { topology: ['single', 'replicaset', 'sharded'] } }, + + test: async function () { + const db = client.db(this.configuration.db); + + // Get collection + const col = db.collection('createValidationCollection'); + + // Drop the collection + await col.drop().catch(ignoreNsNotFound); + // Create a collection with a validator + await db.createCollection('createValidationCollection', { + validator: { a: { $exists: true } } + }); + + // Should fail + const err = await col.bulkWrite([{ insertOne: { document: { b: 1 } } }]).catch(err => err); + expect(err).to.be.instanceOf(MongoBulkWriteError); + + await col.bulkWrite([{ insertOne: { document: { b: 1 } } }], { + bypassDocumentValidation: true + }); + } + }); + + it('should allow bypassing document validation on findAndModify', { + metadata: { requires: { topology: ['single', 'replicaset', 'sharded'] } }, + + test: async function () { + const db = client.db(this.configuration.db); + + // Get collection + const col = db.collection('createValidationCollection'); + + // Drop the collection + await col.drop().catch(ignoreNsNotFound); + // Create a collection with a validator + await db.createCollection('createValidationCollection', { + validator: { a: { $exists: true } } + }); + + // Should fail + const err = await col + .findOneAndUpdate({ b: 1 }, { $set: { b: 1 } }, { upsert: true }) + .catch(err => err); + expect(err).to.be.instanceOf(MongoServerError); + + // Should pass + await col.findOneAndUpdate( + { b: 1 }, + { $set: { b: 1 } }, + { upsert: true, bypassDocumentValidation: true } + ); + + // Should pass + await col.findOneAndReplace( + { c: 1 }, + { c: 1 }, + { upsert: true, bypassDocumentValidation: true } + ); + } + }); + + it('should correctly bypass validation for aggregation using out', { + metadata: { requires: { topology: ['single', 'replicaset', 'sharded'] } }, + + test: async function () { + const db = client.db(this.configuration.db); + // Some docs for insertion + const docs = [ + { + title: 'this is my title', + author: 'bob', + posted: new Date(), + pageViews: 5, + tags: ['fun', 'good', 'fun'], + other: { foo: 5 }, + comments: [ + { author: 'joe', text: 'this is cool' }, + { author: 'sam', text: 'this is bad' } + ] + } + ]; + + // Get collection + const col = db.collection('createValidationCollectionOut'); + + // Drop the collection + await col.drop().catch(ignoreNsNotFound); + // Create a collection with a validator + await db.createCollection('createValidationCollectionOut', { + validator: { a: { $exists: true } } + }); + // Insert the docs + await col.insertMany(docs, { writeConcern: { w: 1 }, bypassDocumentValidation: true }); + + // Execute aggregate, notice the pipeline is expressed as an Array + const cursor = col.aggregate( + [ + { + $project: { + author: 1, + tags: 1 + } + }, + { $unwind: '$tags' }, + { + $group: { + _id: { tags: '$tags' }, + authors: { $addToSet: '$author' } + } + }, + { $out: 'createValidationCollectionOut' } + ], + { bypassDocumentValidation: true } + ); + await cursor.toArray(); + } + }); +});