@@ -162,6 +162,7 @@ describe('request complexity', () => {
162162 includeDepth : - 1 ,
163163 includeCount : - 1 ,
164164 subqueryDepth : - 1 ,
165+ subqueryLimit : - 1 ,
165166 queryDepth : - 1 ,
166167 graphQLDepth : - 1 ,
167168 graphQLFields : - 1 ,
@@ -732,4 +733,123 @@ describe('request complexity', () => {
732733 } ) ;
733734 } ) ;
734735 } ) ;
736+
737+ describe ( 'subquery result limit' , ( ) => {
738+ let config ;
739+ const totalObjects = 5 ;
740+ const resultLimit = 3 ;
741+
742+ beforeEach ( async ( ) => {
743+ await reconfigureServer ( {
744+ requestComplexity : { subqueryLimit : resultLimit } ,
745+ } ) ;
746+ config = Config . get ( 'test' ) ;
747+ // Create target objects
748+ const targets = [ ] ;
749+ for ( let i = 0 ; i < totalObjects ; i ++ ) {
750+ const obj = new Parse . Object ( 'Target' ) ;
751+ obj . set ( 'value' , `v${ i } ` ) ;
752+ targets . push ( obj ) ;
753+ }
754+ await Parse . Object . saveAll ( targets ) ;
755+ // Create source objects, each pointing to a target
756+ const sources = [ ] ;
757+ for ( let i = 0 ; i < totalObjects ; i ++ ) {
758+ const obj = new Parse . Object ( 'Source' ) ;
759+ obj . set ( 'ref' , targets [ i ] ) ;
760+ obj . set ( 'value' , targets [ i ] . get ( 'value' ) ) ;
761+ sources . push ( obj ) ;
762+ }
763+ await Parse . Object . saveAll ( sources ) ;
764+ } ) ;
765+
766+ it ( 'should limit $inQuery subquery results' , async ( ) => {
767+ const where = {
768+ ref : {
769+ $inQuery : { className : 'Target' , where : { } } ,
770+ } ,
771+ } ;
772+ const result = await rest . find ( config , auth . nobody ( config ) , 'Source' , where ) ;
773+ expect ( result . results . length ) . toBe ( resultLimit ) ;
774+ } ) ;
775+
776+ it ( 'should limit $notInQuery subquery results' , async ( ) => {
777+ const where = {
778+ ref : {
779+ $notInQuery : { className : 'Target' , where : { } } ,
780+ } ,
781+ } ;
782+ const result = await rest . find ( config , auth . nobody ( config ) , 'Source' , where ) ;
783+ // With limit, only `resultLimit` targets are excluded, so (totalObjects - resultLimit) sources remain
784+ expect ( result . results . length ) . toBe ( totalObjects - resultLimit ) ;
785+ } ) ;
786+
787+ it ( 'should limit $select subquery results' , async ( ) => {
788+ const where = {
789+ value : {
790+ $select : { query : { className : 'Target' , where : { } } , key : 'value' } ,
791+ } ,
792+ } ;
793+ const result = await rest . find ( config , auth . nobody ( config ) , 'Source' , where ) ;
794+ expect ( result . results . length ) . toBe ( resultLimit ) ;
795+ } ) ;
796+
797+ it ( 'should limit $dontSelect subquery results' , async ( ) => {
798+ const where = {
799+ value : {
800+ $dontSelect : { query : { className : 'Target' , where : { } } , key : 'value' } ,
801+ } ,
802+ } ;
803+ const result = await rest . find ( config , auth . nobody ( config ) , 'Source' , where ) ;
804+ expect ( result . results . length ) . toBe ( totalObjects - resultLimit ) ;
805+ } ) ;
806+
807+ it ( 'should allow unlimited subquery results with master key' , async ( ) => {
808+ const where = {
809+ ref : {
810+ $inQuery : { className : 'Target' , where : { } } ,
811+ } ,
812+ } ;
813+ const result = await rest . find ( config , auth . master ( config ) , 'Source' , where ) ;
814+ expect ( result . results . length ) . toBe ( totalObjects ) ;
815+ } ) ;
816+
817+ it ( 'should allow unlimited subquery results with maintenance key' , async ( ) => {
818+ const where = {
819+ ref : {
820+ $inQuery : { className : 'Target' , where : { } } ,
821+ } ,
822+ } ;
823+ const result = await rest . find ( config , auth . maintenance ( config ) , 'Source' , where ) ;
824+ expect ( result . results . length ) . toBe ( totalObjects ) ;
825+ } ) ;
826+
827+ it ( 'should allow unlimited subquery results when subqueryLimit is -1' , async ( ) => {
828+ await reconfigureServer ( {
829+ requestComplexity : { subqueryLimit : - 1 } ,
830+ } ) ;
831+ config = Config . get ( 'test' ) ;
832+ const where = {
833+ ref : {
834+ $inQuery : { className : 'Target' , where : { } } ,
835+ } ,
836+ } ;
837+ const result = await rest . find ( config , auth . nobody ( config ) , 'Source' , where ) ;
838+ expect ( result . results . length ) . toBe ( totalObjects ) ;
839+ } ) ;
840+
841+ it ( 'should include subqueryLimit in config defaults' , async ( ) => {
842+ await reconfigureServer ( { } ) ;
843+ config = Config . get ( 'test' ) ;
844+ expect ( config . requestComplexity . subqueryLimit ) . toBe ( - 1 ) ;
845+ } ) ;
846+
847+ it ( 'should accept subqueryLimit in config validation' , async ( ) => {
848+ await expectAsync (
849+ reconfigureServer ( {
850+ requestComplexity : { subqueryLimit : 100 } ,
851+ } )
852+ ) . toBeResolved ( ) ;
853+ } ) ;
854+ } ) ;
735855} ) ;
0 commit comments