diff --git a/src/operations/aggregate.ts b/src/operations/aggregate.ts index 2b23b9acb67..e1ae2bbfcdd 100644 --- a/src/operations/aggregate.ts +++ b/src/operations/aggregate.ts @@ -80,12 +80,6 @@ export class AggregateOperation extends CommandOperation { delete this.options.writeConcern; } - if (this.explain && this.writeConcern) { - throw new MongoInvalidArgumentError( - 'Option "explain" cannot be used on an aggregate call with writeConcern' - ); - } - if (options?.cursor != null && typeof options.cursor !== 'object') { throw new MongoInvalidArgumentError('Cursor options must be an object'); } diff --git a/test/integration/crud/aggregation.test.ts b/test/integration/crud/aggregation.test.ts index f5c54aeae3c..92602f7b875 100644 --- a/test/integration/crud/aggregation.test.ts +++ b/test/integration/crud/aggregation.test.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; -import { MongoInvalidArgumentError } from '../../../src/error'; +import { MongoInvalidArgumentError, MongoServerError } from '../../../src/error'; import { type MongoClient } from '../../../src/mongo_client'; import { filterForCommands } from '../shared'; @@ -601,7 +601,7 @@ describe('Aggregation', function () { .toArray() .catch(error => error); - expect(error).to.be.instanceOf(MongoInvalidArgumentError); + expect(error).to.be.instanceOf(MongoServerError); }); it('should fail if you try to use explain flag with { writeConcern: { j: true } }', async function () { @@ -615,7 +615,7 @@ describe('Aggregation', function () { .toArray() .catch(error => error); - expect(error).to.be.instanceOf(MongoInvalidArgumentError); + expect(error).to.be.instanceOf(MongoServerError); }); it('should ensure MaxTimeMS is correctly passed down into command execution when using a cursor', async function () { diff --git a/test/unit/operations/aggregate.test.js b/test/unit/operations/aggregate.test.ts similarity index 55% rename from test/unit/operations/aggregate.test.js rename to test/unit/operations/aggregate.test.ts index f6aa95f5056..f02e83d7f51 100644 --- a/test/unit/operations/aggregate.test.js +++ b/test/unit/operations/aggregate.test.ts @@ -1,14 +1,14 @@ -'use strict'; +import { expect } from 'chai'; -const { expect } = require('chai'); -const { AggregateOperation } = require('../../../src/operations/aggregate'); +import { AggregateOperation } from '../../../src/operations/aggregate'; +import { MongoDBNamespace, WriteConcern } from '../../mongodb'; describe('AggregateOperation', function () { - const db = 'test'; + const ns = new MongoDBNamespace('test', 'coll'); describe('#constructor', function () { context('when out is in the options', function () { - const operation = new AggregateOperation(db, [], { out: 'test', dbName: db }); + const operation = new AggregateOperation(ns, [], { out: 'test', dbName: ns.db }); it('sets hasWriteStage to true', function () { expect(operation.hasWriteStage).to.be.true; @@ -16,7 +16,7 @@ describe('AggregateOperation', function () { }); context('when $out is the last stage', function () { - const operation = new AggregateOperation(db, [{ $out: 'test' }], { dbName: db }); + const operation = new AggregateOperation(ns, [{ $out: 'test' }], { dbName: ns.db }); it('sets hasWriteStage to true', function () { expect(operation.hasWriteStage).to.be.true; @@ -24,8 +24,8 @@ describe('AggregateOperation', function () { }); context('when $out is not the last stage', function () { - const operation = new AggregateOperation(db, [{ $out: 'test' }, { $project: { name: 1 } }], { - dbName: db + const operation = new AggregateOperation(ns, [{ $out: 'test' }, { $project: { name: 1 } }], { + dbName: ns.db }); it('sets hasWriteStage to false', function () { @@ -34,7 +34,9 @@ describe('AggregateOperation', function () { }); context('when $merge is the last stage', function () { - const operation = new AggregateOperation(db, [{ $merge: { into: 'test' } }], { dbName: db }); + const operation = new AggregateOperation(ns, [{ $merge: { into: 'test' } }], { + dbName: ns.db + }); it('sets hasWriteStage to true', function () { expect(operation.hasWriteStage).to.be.true; @@ -43,9 +45,9 @@ describe('AggregateOperation', function () { context('when $merge is not the last stage', function () { const operation = new AggregateOperation( - db, + ns, [{ $merge: { into: 'test' } }, { $project: { name: 1 } }], - { dbName: db } + { dbName: ns.db } ); it('sets hasWriteStage to false', function () { @@ -54,7 +56,7 @@ describe('AggregateOperation', function () { }); context('when no writable stages in empty pipeline', function () { - const operation = new AggregateOperation(db, [], { dbName: db }); + const operation = new AggregateOperation(ns, [], { dbName: ns.db }); it('sets hasWriteStage to false', function () { expect(operation.hasWriteStage).to.be.false; @@ -62,11 +64,25 @@ describe('AggregateOperation', function () { }); context('when no writable stages', function () { - const operation = new AggregateOperation(db, [{ $project: { name: 1 } }], { dbName: db }); + const operation = new AggregateOperation(ns, [{ $project: { name: 1 } }], { dbName: ns }); it('sets hasWriteStage to false', function () { expect(operation.hasWriteStage).to.be.false; }); }); + + context('when explain is set', function () { + context('when writeConcern is set', function () { + const operation = new AggregateOperation(ns, [], { + dbName: ns.db, + explain: true, + writeConcern: WriteConcern.fromOptions({ wtimeoutMS: 1000 }) + }); + + it('does not raise an error', function () { + expect(operation.explain).to.exist; + }); + }); + }); }); });