@@ -615,6 +615,76 @@ describe('DatabaseController', function () {
615615 expect ( result2 . length ) . toEqual ( 1 ) ;
616616 } ) ;
617617 } ) ;
618+
619+ describe ( 'update with validateOnly' , ( ) => {
620+ const mockStorageAdapter = {
621+ findOneAndUpdate : ( ) => Promise . resolve ( { } ) ,
622+ find : ( ) => Promise . resolve ( [ { objectId : 'test123' , testField : 'initialValue' } ] ) ,
623+ watch : ( ) => Promise . resolve ( ) ,
624+ getAllClasses : ( ) =>
625+ Promise . resolve ( [
626+ {
627+ className : 'TestObject' ,
628+ fields : { testField : 'String' } ,
629+ indexes : { } ,
630+ classLevelPermissions : { protectedFields : { } } ,
631+ } ,
632+ ] ) ,
633+ } ;
634+
635+ it ( 'should use primary readPreference when validateOnly is true' , async ( ) => {
636+ const databaseController = new DatabaseController ( mockStorageAdapter , { } ) ;
637+ const findSpy = spyOn ( mockStorageAdapter , 'find' ) . and . callThrough ( ) ;
638+ const findOneAndUpdateSpy = spyOn ( mockStorageAdapter , 'findOneAndUpdate' ) . and . callThrough ( ) ;
639+
640+ try {
641+ // Call update with validateOnly: true (same as RestWrite.runBeforeSaveTrigger)
642+ await databaseController . update (
643+ 'TestObject' ,
644+ { objectId : 'test123' } ,
645+ { testField : 'newValue' } ,
646+ { } ,
647+ true , // skipSanitization: true (matches RestWrite behavior)
648+ true // validateOnly: true
649+ ) ;
650+ } catch ( error ) {
651+ // validateOnly may throw, but we're checking the find call options
652+ }
653+
654+ // Verify that find was called with primary readPreference
655+ expect ( findSpy ) . toHaveBeenCalled ( ) ;
656+ const findCall = findSpy . calls . mostRecent ( ) ;
657+ expect ( findCall . args [ 3 ] ) . toEqual ( { readPreference : 'primary' } ) ; // options parameter
658+
659+ // Verify that findOneAndUpdate was NOT called (only validation, no actual update)
660+ expect ( findOneAndUpdateSpy ) . not . toHaveBeenCalled ( ) ;
661+ } ) ;
662+
663+ it ( 'should not use primary readPreference when validateOnly is false' , async ( ) => {
664+ const databaseController = new DatabaseController ( mockStorageAdapter , { } ) ;
665+ const findSpy = spyOn ( mockStorageAdapter , 'find' ) . and . callThrough ( ) ;
666+ const findOneAndUpdateSpy = spyOn ( mockStorageAdapter , 'findOneAndUpdate' ) . and . callThrough ( ) ;
667+
668+ try {
669+ // Call update with validateOnly: false
670+ await databaseController . update (
671+ 'TestObject' ,
672+ { objectId : 'test123' } ,
673+ { testField : 'newValue' } ,
674+ { } ,
675+ false , // skipSanitization
676+ false // validateOnly
677+ ) ;
678+ } catch ( error ) {
679+ // May throw for other reasons, but we're checking the call pattern
680+ }
681+
682+ // When validateOnly is false, find should not be called for validation
683+ // Instead, findOneAndUpdate should be called
684+ expect ( findSpy ) . not . toHaveBeenCalled ( ) ;
685+ expect ( findOneAndUpdateSpy ) . toHaveBeenCalled ( ) ;
686+ } ) ;
687+ } ) ;
618688} ) ;
619689
620690function buildCLP ( pointerNames ) {
0 commit comments