@@ -324,6 +324,190 @@ describe('Collection (#findOneAnd...)', function () {
324324 } ) ;
325325 } ) ;
326326 } ) ;
327+
328+ context ( 'when updating with an aggregation pipeline' , function ( ) {
329+ context ( 'when passing includeResultMetadata: true' , function ( ) {
330+ let client ;
331+ let collection ;
332+
333+ beforeEach ( async function ( ) {
334+ client = this . configuration . newClient ( { } , { maxPoolSize : 1 } ) ;
335+ collection = client . db ( 'test' ) . collection ( 'findAndModifyTest' ) ;
336+ await collection . insertMany ( [ { a : 1 , b : 1 } ] , { writeConcern : { w : 1 } } ) ;
337+ } ) ;
338+
339+ afterEach ( async function ( ) {
340+ await collection . drop ( ) ;
341+ await client ?. close ( ) ;
342+ } ) ;
343+
344+ it ( 'returns the raw result' , async function ( ) {
345+ const result = await collection . findOneAndUpdate (
346+ { a : 1 } ,
347+ [ { $set : { a : { $add : [ 0 , '$a' ] } } } ] ,
348+ { includeResultMetadata : true }
349+ ) ;
350+ expect ( result . value . b ) . to . equal ( 1 ) ;
351+ } ) ;
352+ } ) ;
353+
354+ context ( 'when no options are passed' , function ( ) {
355+ let client ;
356+ let collection ;
357+
358+ beforeEach ( async function ( ) {
359+ client = this . configuration . newClient ( { } , { maxPoolSize : 1 } ) ;
360+ collection = client . db ( 'test' ) . collection ( 'findAndModifyTest' ) ;
361+ await collection . insertMany ( [ { a : 1 , b : 1 } ] , { writeConcern : { w : 1 } } ) ;
362+ } ) ;
363+
364+ afterEach ( async function ( ) {
365+ await collection . drop ( ) ;
366+ await client ?. close ( ) ;
367+ } ) ;
368+
369+ context ( 'when there is a match' , function ( ) {
370+ it ( 'returns the modified document' , async function ( ) {
371+ const result = await collection . findOneAndUpdate ( { a : 1 } , [
372+ { $set : { a : { $add : [ 0 , '$a' ] } } }
373+ ] ) ;
374+ expect ( result . b ) . to . equal ( 1 ) ;
375+ } ) ;
376+ } ) ;
377+
378+ context ( 'when there is no match' , function ( ) {
379+ it ( 'returns null' , async function ( ) {
380+ const result = await collection . findOneAndUpdate ( { a : 2 } , [
381+ { $set : { a : { $add : [ 0 , '$a' ] } } }
382+ ] ) ;
383+ expect ( result ) . to . equal ( null ) ;
384+ } ) ;
385+ } ) ;
386+ } ) ;
387+
388+ context ( 'when passing an object id filter' , function ( ) {
389+ let client ;
390+ let collection ;
391+ const started : CommandStartedEvent [ ] = [ ] ;
392+
393+ beforeEach ( async function ( ) {
394+ client = this . configuration . newClient ( { } , { maxPoolSize : 1 , monitorCommands : true } ) ;
395+ client . on ( 'commandStarted' , function ( event ) {
396+ if ( event . commandName === 'findAndModify' ) started . push ( event ) ;
397+ } ) ;
398+ collection = client . db ( 'test' ) . collection ( 'findAndModifyTest' ) ;
399+ await collection . insertMany ( [ { a : 1 , b : 1 } ] , { writeConcern : { w : 1 } } ) ;
400+ } ) ;
401+
402+ afterEach ( async function ( ) {
403+ await collection . drop ( ) ;
404+ await client ?. close ( ) ;
405+ } ) ;
406+
407+ it ( 'does not support object ids as a query predicate' , async function ( ) {
408+ const oid = new ObjectId ( ) ;
409+ const error = await collection
410+ . findOneAndUpdate ( oid , [ { $set : { a : { $add : [ 0 , '$a' ] } } } ] )
411+ . catch ( error => error ) ;
412+ expect ( error ) . to . be . instanceOf ( MongoServerError ) ;
413+ expect ( started ) . to . have . lengthOf ( 1 ) ;
414+ expect ( started [ 0 ] . command ) . to . have . property ( 'query' , oid ) ;
415+ } ) ;
416+ } ) ;
417+
418+ context ( 'when passing in a non-primary read preference' , {
419+ metadata : {
420+ requires : { topology : [ 'replicaset' ] }
421+ } ,
422+ test : function ( ) {
423+ let client ;
424+ let collection ;
425+
426+ beforeEach ( async function ( ) {
427+ client = this . configuration . newClient (
428+ { readPreference : 'secondary' } ,
429+ { maxPoolSize : 1 }
430+ ) ;
431+ collection = client . db ( 'test' ) . collection ( 'findAndModifyTest' ) ;
432+ await collection . insertMany ( [ { a : 1 , b : 1 } ] , { writeConcern : { w : 1 } } ) ;
433+ } ) ;
434+
435+ afterEach ( async function ( ) {
436+ await collection . drop ( ) ;
437+ await client ?. close ( ) ;
438+ } ) ;
439+
440+ it ( 'returns the raw result' , async function ( ) {
441+ const result = await collection . findOneAndUpdate (
442+ { a : 1 } ,
443+ [ { $set : { a : { $add : [ 0 , '$a' ] } } } ] ,
444+ { includeResultMetadata : true }
445+ ) ;
446+ expect ( result . value . b ) . to . equal ( 1 ) ;
447+ } ) ;
448+ }
449+ } ) ;
450+
451+ context ( 'when passing in writeConcern' , function ( ) {
452+ let client ;
453+ let collection ;
454+ const started : CommandStartedEvent [ ] = [ ] ;
455+
456+ beforeEach ( async function ( ) {
457+ client = this . configuration . newClient ( { } , { maxPoolSize : 1 , monitorCommands : true } ) ;
458+ client . on ( 'commandStarted' , function ( event ) {
459+ if ( event . commandName === 'findAndModify' ) started . push ( event ) ;
460+ } ) ;
461+ } ) ;
462+
463+ afterEach ( async function ( ) {
464+ await collection . drop ( ) ;
465+ await client ?. close ( ) ;
466+ } ) ;
467+
468+ context ( 'when provided at the operation level' , function ( ) {
469+ beforeEach ( async function ( ) {
470+ collection = client . db ( 'test' ) . collection ( 'findAndModifyTest' ) ;
471+ await collection . insertMany ( [ { a : 1 , b : 1 } ] , { writeConcern : { w : 1 } } ) ;
472+ } ) ;
473+
474+ it ( 'passes through the writeConcern' , async function ( ) {
475+ await collection . findOneAndUpdate ( { } , [ { $set : { a : { $add : [ 0 , '$a' ] } } } ] , {
476+ writeConcern : { j : 1 }
477+ } ) ;
478+ expect ( started [ 0 ] . command . writeConcern ) . to . deep . equal ( { j : 1 } ) ;
479+ } ) ;
480+ } ) ;
481+
482+ context ( 'when provided at the collection level' , function ( ) {
483+ beforeEach ( async function ( ) {
484+ collection = client
485+ . db ( 'test' )
486+ . collection ( 'findAndModifyTest' , { writeConcern : { j : 1 } } ) ;
487+ await collection . insertMany ( [ { a : 1 , b : 1 } ] , { writeConcern : { w : 1 } } ) ;
488+ } ) ;
489+
490+ it ( 'passes through the writeConcern' , async function ( ) {
491+ await collection . findOneAndUpdate ( { } , [ { $set : { a : { $add : [ 0 , '$a' ] } } } ] ) ;
492+ expect ( started [ 0 ] . command . writeConcern ) . to . deep . equal ( { j : 1 } ) ;
493+ } ) ;
494+ } ) ;
495+
496+ context ( 'when provided at the db level' , function ( ) {
497+ beforeEach ( async function ( ) {
498+ collection = client
499+ . db ( 'test' , { writeConcern : { j : 1 } } )
500+ . collection ( 'findAndModifyTest' ) ;
501+ await collection . insertMany ( [ { a : 1 , b : 1 } ] , { writeConcern : { w : 1 } } ) ;
502+ } ) ;
503+
504+ it ( 'passes through the writeConcern' , async function ( ) {
505+ await collection . findOneAndUpdate ( { } , [ { $set : { a : { $add : [ 0 , '$a' ] } } } ] ) ;
506+ expect ( started [ 0 ] . command . writeConcern ) . to . deep . equal ( { j : 1 } ) ;
507+ } ) ;
508+ } ) ;
509+ } ) ;
510+ } ) ;
327511 } ) ;
328512
329513 describe ( '#findOneAndReplace' , function ( ) {
0 commit comments