@@ -841,6 +841,102 @@ describe('DatabaseController', function () {
841841 expect ( findOneAndUpdateSpy ) . toHaveBeenCalled ( ) ;
842842 } ) ;
843843 } ) ;
844+
845+ describe_only_db ( 'mongo' ) ( 'update with many' , ( ) => {
846+ it ( 'should return matchedCount and modifiedCount when multiple docs are updated' , async ( ) => {
847+ const config = Config . get ( Parse . applicationId ) ;
848+ const obj1 = new Parse . Object ( 'TestObject' ) ;
849+ const obj2 = new Parse . Object ( 'TestObject' ) ;
850+ const obj3 = new Parse . Object ( 'TestObject' ) ;
851+ obj1 . set ( 'status' , 'pending' ) ;
852+ obj2 . set ( 'status' , 'pending' ) ;
853+ obj3 . set ( 'status' , 'pending' ) ;
854+ await Parse . Object . saveAll ( [ obj1 , obj2 , obj3 ] ) ;
855+
856+ const result = await config . database . update (
857+ 'TestObject' ,
858+ { status : 'pending' } ,
859+ { status : 'done' } ,
860+ { many : true }
861+ ) ;
862+
863+ expect ( result . matchedCount ) . toBe ( 3 ) ;
864+ expect ( result . modifiedCount ) . toBe ( 3 ) ;
865+ } ) ;
866+
867+ it ( 'should return matchedCount > 0 and modifiedCount 0 when values are already current' , async ( ) => {
868+ const config = Config . get ( Parse . applicationId ) ;
869+ const obj1 = new Parse . Object ( 'TestObject' ) ;
870+ const obj2 = new Parse . Object ( 'TestObject' ) ;
871+ obj1 . set ( 'status' , 'done' ) ;
872+ obj2 . set ( 'status' , 'done' ) ;
873+ await Parse . Object . saveAll ( [ obj1 , obj2 ] ) ;
874+
875+ const result = await config . database . update (
876+ 'TestObject' ,
877+ { status : 'done' } ,
878+ { status : 'done' } ,
879+ { many : true }
880+ ) ;
881+
882+ expect ( result . matchedCount ) . toBe ( 2 ) ;
883+ expect ( result . modifiedCount ) . toBe ( 0 ) ;
884+ } ) ;
885+
886+ it ( 'should return matchedCount 0 and modifiedCount 0 when no docs match' , async ( ) => {
887+ const config = Config . get ( Parse . applicationId ) ;
888+ const result = await config . database . update (
889+ 'TestObject' ,
890+ { status : 'nonexistent' } ,
891+ { status : 'done' } ,
892+ { many : true }
893+ ) ;
894+
895+ expect ( result . matchedCount ) . toBe ( 0 ) ;
896+ expect ( result . modifiedCount ) . toBe ( 0 ) ;
897+ } ) ;
898+
899+ it ( 'should return only matchedCount and modifiedCount for op-based updates' , async ( ) => {
900+ const config = Config . get ( Parse . applicationId ) ;
901+ const obj1 = new Parse . Object ( 'TestObject' ) ;
902+ const obj2 = new Parse . Object ( 'TestObject' ) ;
903+ obj1 . set ( 'score' , 1 ) ;
904+ obj2 . set ( 'score' , 1 ) ;
905+ await Parse . Object . saveAll ( [ obj1 , obj2 ] ) ;
906+
907+ const result = await config . database . update (
908+ 'TestObject' ,
909+ { score : { $exists : true } } ,
910+ { score : { __op : 'Increment' , amount : 5 } } ,
911+ { many : true }
912+ ) ;
913+
914+ expect ( result . matchedCount ) . toBe ( 2 ) ;
915+ expect ( result . modifiedCount ) . toBe ( 2 ) ;
916+ expect ( Object . keys ( result ) ) . toEqual ( [ 'matchedCount' , 'modifiedCount' ] ) ;
917+ } ) ;
918+
919+ it ( 'should return raw adapter result when skipSanitization is true' , async ( ) => {
920+ const config = Config . get ( Parse . applicationId ) ;
921+ const obj1 = new Parse . Object ( 'TestObject' ) ;
922+ obj1 . set ( 'status' , 'pending' ) ;
923+ await obj1 . save ( ) ;
924+
925+ const result = await config . database . update (
926+ 'TestObject' ,
927+ { status : 'pending' } ,
928+ { status : 'done' } ,
929+ { many : true } ,
930+ true // skipSanitization
931+ ) ;
932+
933+ // skipSanitization returns raw adapter result, which for MongoDB
934+ // includes additional fields beyond matchedCount and modifiedCount
935+ expect ( result . matchedCount ) . toBe ( 1 ) ;
936+ expect ( result . modifiedCount ) . toBe ( 1 ) ;
937+ expect ( result . acknowledged ) . toBe ( true ) ;
938+ } ) ;
939+ } ) ;
844940} ) ;
845941
846942function buildCLP ( pointerNames ) {
0 commit comments