55 getResponseContent ,
66 defaultTestConfig ,
77} from "../../../helpers.js" ;
8- import { describe , expect , it , vi } from "vitest" ;
8+ import { beforeEach , describe , expect , it , vi , afterEach } from "vitest" ;
99import { describeWithMongoDB , getDocsFromUntrustedContent , validateAutoConnectBehavior } from "../mongodbHelpers.js" ;
1010import * as constants from "../../../../../src/helpers/constants.js" ;
1111import { freshInsertDocuments } from "./find.test.js" ;
@@ -142,90 +142,94 @@ describeWithMongoDB("aggregate tool", (integration) => {
142142 expectedResponse : "The aggregation resulted in 0 documents" ,
143143 } ;
144144 } ) ;
145+
146+ describe ( "when counting documents exceed the configured count maxTimeMS" , ( ) => {
147+ beforeEach ( async ( ) => {
148+ await freshInsertDocuments ( {
149+ collection : integration . mongoClient ( ) . db ( integration . randomDbName ( ) ) . collection ( "people" ) ,
150+ count : 1000 ,
151+ documentMapper ( index ) {
152+ return { name : `Person ${ index } ` , age : index } ;
153+ } ,
154+ } ) ;
155+ } ) ;
156+
157+ afterEach ( ( ) => {
158+ vi . resetAllMocks ( ) ;
159+ } ) ;
160+
161+ it ( "should abort discard count operation and respond with indeterminable count" , async ( ) => {
162+ vi . spyOn ( constants , "AGG_COUNT_MAX_TIME_MS_CAP" , "get" ) . mockReturnValue ( 0.1 ) ;
163+ await integration . connectMcpClient ( ) ;
164+ const response = await integration . mcpClient ( ) . callTool ( {
165+ name : "aggregate" ,
166+ arguments : {
167+ database : integration . randomDbName ( ) ,
168+ collection : "people" ,
169+ pipeline : [ { $match : { age : { $gte : 10 } } } , { $sort : { name : - 1 } } ] ,
170+ } ,
171+ } ) ;
172+ const content = getResponseContent ( response ) ;
173+ expect ( content ) . toContain ( "The aggregation resulted in indeterminable number of documents" ) ;
174+ expect ( content ) . toContain ( `Returning 10 documents while respecting the applied limits.` ) ;
175+ const docs = getDocsFromUntrustedContent ( content ) ;
176+ expect ( docs [ 0 ] ) . toEqual (
177+ expect . objectContaining ( {
178+ _id : expect . any ( Object ) as object ,
179+ name : "Person 999" ,
180+ age : 999 ,
181+ } )
182+ ) ;
183+ expect ( docs [ 1 ] ) . toEqual (
184+ expect . objectContaining ( {
185+ _id : expect . any ( Object ) as object ,
186+ name : "Person 998" ,
187+ age : 998 ,
188+ } )
189+ ) ;
190+ } ) ;
191+ } ) ;
145192} ) ;
146193
147194describeWithMongoDB (
148195 "aggregate tool with configured max documents per query" ,
149196 ( integration ) => {
150- describe ( "when the aggregation results are larger than the configured limit" , ( ) => {
151- it ( "should return documents limited to the configured limit" , async ( ) => {
152- await freshInsertDocuments ( {
153- collection : integration . mongoClient ( ) . db ( integration . randomDbName ( ) ) . collection ( "people" ) ,
154- count : 1000 ,
155- documentMapper ( index ) {
156- return { name : `Person ${ index } ` , age : index } ;
157- } ,
158- } ) ;
159- await integration . connectMcpClient ( ) ;
160- const response = await integration . mcpClient ( ) . callTool ( {
161- name : "aggregate" ,
162- arguments : {
163- database : integration . randomDbName ( ) ,
164- collection : "people" ,
165- pipeline : [ { $match : { age : { $gte : 10 } } } , { $sort : { name : - 1 } } ] ,
166- } ,
167- } ) ;
168-
169- const content = getResponseContent ( response ) ;
170- expect ( content ) . toContain ( "The aggregation resulted in 990 documents" ) ;
171- expect ( content ) . toContain ( `Returning 20 documents while respecting the applied limits.` ) ;
172- const docs = getDocsFromUntrustedContent ( content ) ;
173- expect ( docs [ 0 ] ) . toEqual (
174- expect . objectContaining ( {
175- _id : expect . any ( Object ) as object ,
176- name : "Person 999" ,
177- age : 999 ,
178- } )
179- ) ;
180- expect ( docs [ 1 ] ) . toEqual (
181- expect . objectContaining ( {
182- _id : expect . any ( Object ) as object ,
183- name : "Person 998" ,
184- age : 998 ,
185- } )
186- ) ;
197+ it ( "should return documents limited to the configured limit" , async ( ) => {
198+ await freshInsertDocuments ( {
199+ collection : integration . mongoClient ( ) . db ( integration . randomDbName ( ) ) . collection ( "people" ) ,
200+ count : 1000 ,
201+ documentMapper ( index ) {
202+ return { name : `Person ${ index } ` , age : index } ;
203+ } ,
187204 } ) ;
188- } ) ;
189-
190- describe ( "when counting documents exceed the configured count maxTimeMS" , ( ) => {
191- it ( "should abort discard count operation and respond with indeterminable count" , async ( ) => {
192- vi . spyOn ( constants , "AGG_COUNT_MAX_TIME_MS_CAP" , "get" ) . mockReturnValue ( 0.1 ) ;
193- await freshInsertDocuments ( {
194- collection : integration . mongoClient ( ) . db ( integration . randomDbName ( ) ) . collection ( "people" ) ,
195- count : 1000 ,
196- documentMapper ( index ) {
197- return { name : `Person ${ index } ` , age : index } ;
198- } ,
199- } ) ;
200- await integration . connectMcpClient ( ) ;
201- const response = await integration . mcpClient ( ) . callTool ( {
202- name : "aggregate" ,
203- arguments : {
204- database : integration . randomDbName ( ) ,
205- collection : "people" ,
206- pipeline : [ { $match : { age : { $gte : 10 } } } , { $sort : { name : - 1 } } ] ,
207- } ,
208- } ) ;
209- const content = getResponseContent ( response ) ;
210- expect ( content ) . toContain ( "The aggregation resulted in indeterminable number of documents" ) ;
211- expect ( content ) . toContain ( `Returning 20 documents while respecting the applied limits.` ) ;
212- const docs = getDocsFromUntrustedContent ( content ) ;
213- expect ( docs [ 0 ] ) . toEqual (
214- expect . objectContaining ( {
215- _id : expect . any ( Object ) as object ,
216- name : "Person 999" ,
217- age : 999 ,
218- } )
219- ) ;
220- expect ( docs [ 1 ] ) . toEqual (
221- expect . objectContaining ( {
222- _id : expect . any ( Object ) as object ,
223- name : "Person 998" ,
224- age : 998 ,
225- } )
226- ) ;
227- vi . resetAllMocks ( ) ;
205+ await integration . connectMcpClient ( ) ;
206+ const response = await integration . mcpClient ( ) . callTool ( {
207+ name : "aggregate" ,
208+ arguments : {
209+ database : integration . randomDbName ( ) ,
210+ collection : "people" ,
211+ pipeline : [ { $match : { age : { $gte : 10 } } } , { $sort : { name : - 1 } } ] ,
212+ } ,
228213 } ) ;
214+
215+ const content = getResponseContent ( response ) ;
216+ expect ( content ) . toContain ( "The aggregation resulted in 990 documents" ) ;
217+ expect ( content ) . toContain ( `Returning 20 documents while respecting the applied limits.` ) ;
218+ const docs = getDocsFromUntrustedContent ( content ) ;
219+ expect ( docs [ 0 ] ) . toEqual (
220+ expect . objectContaining ( {
221+ _id : expect . any ( Object ) as object ,
222+ name : "Person 999" ,
223+ age : 999 ,
224+ } )
225+ ) ;
226+ expect ( docs [ 1 ] ) . toEqual (
227+ expect . objectContaining ( {
228+ _id : expect . any ( Object ) as object ,
229+ name : "Person 998" ,
230+ age : 998 ,
231+ } )
232+ ) ;
229233 } ) ;
230234 } ,
231235 ( ) => ( { ...defaultTestConfig , maxDocumentsPerQuery : 20 } )
@@ -234,30 +238,57 @@ describeWithMongoDB(
234238describeWithMongoDB (
235239 "aggregate tool with configured max bytes per query" ,
236240 ( integration ) => {
237- describe ( "when the provided maxBytesPerQuery is hit" , ( ) => {
238- it ( "should return only the documents that could fit in maxBytesPerQuery limit" , async ( ) => {
239- await freshInsertDocuments ( {
240- collection : integration . mongoClient ( ) . db ( integration . randomDbName ( ) ) . collection ( "people" ) ,
241- count : 1000 ,
242- documentMapper ( index ) {
243- return { name : `Person ${ index } ` , age : index } ;
244- } ,
245- } ) ;
246- await integration . connectMcpClient ( ) ;
247- const response = await integration . mcpClient ( ) . callTool ( {
248- name : "aggregate" ,
249- arguments : {
250- database : integration . randomDbName ( ) ,
251- collection : "people" ,
252- pipeline : [ { $match : { age : { $gte : 10 } } } , { $sort : { name : - 1 } } ] ,
253- } ,
254- } ) ;
255-
256- const content = getResponseContent ( response ) ;
257- expect ( content ) . toContain ( "The aggregation resulted in 990 documents" ) ;
258- expect ( content ) . toContain ( `Returning 1 documents while respecting the applied limits.` ) ;
241+ it ( "should return only the documents that could fit in maxBytesPerQuery limit" , async ( ) => {
242+ await freshInsertDocuments ( {
243+ collection : integration . mongoClient ( ) . db ( integration . randomDbName ( ) ) . collection ( "people" ) ,
244+ count : 1000 ,
245+ documentMapper ( index ) {
246+ return { name : `Person ${ index } ` , age : index } ;
247+ } ,
248+ } ) ;
249+ await integration . connectMcpClient ( ) ;
250+ const response = await integration . mcpClient ( ) . callTool ( {
251+ name : "aggregate" ,
252+ arguments : {
253+ database : integration . randomDbName ( ) ,
254+ collection : "people" ,
255+ pipeline : [ { $match : { age : { $gte : 10 } } } , { $sort : { name : - 1 } } ] ,
256+ } ,
259257 } ) ;
258+
259+ const content = getResponseContent ( response ) ;
260+ expect ( content ) . toContain ( "The aggregation resulted in 990 documents" ) ;
261+ expect ( content ) . toContain ( `Returning 1 documents while respecting the applied limits.` ) ;
260262 } ) ;
261263 } ,
262264 ( ) => ( { ...defaultTestConfig , maxBytesPerQuery : 100 } )
263265) ;
266+
267+ describeWithMongoDB (
268+ "aggregate tool with disabled max documents and max bytes per query" ,
269+ ( integration ) => {
270+ it ( "should return all the documents" , async ( ) => {
271+ await freshInsertDocuments ( {
272+ collection : integration . mongoClient ( ) . db ( integration . randomDbName ( ) ) . collection ( "people" ) ,
273+ count : 1000 ,
274+ documentMapper ( index ) {
275+ return { name : `Person ${ index } ` , age : index } ;
276+ } ,
277+ } ) ;
278+ await integration . connectMcpClient ( ) ;
279+ const response = await integration . mcpClient ( ) . callTool ( {
280+ name : "aggregate" ,
281+ arguments : {
282+ database : integration . randomDbName ( ) ,
283+ collection : "people" ,
284+ pipeline : [ { $match : { age : { $gte : 10 } } } , { $sort : { name : - 1 } } ] ,
285+ } ,
286+ } ) ;
287+
288+ const content = getResponseContent ( response ) ;
289+ expect ( content ) . toContain ( "The aggregation resulted in 990 documents" ) ;
290+ expect ( content ) . toContain ( `Returning 990 documents while respecting the applied limits.` ) ;
291+ } ) ;
292+ } ,
293+ ( ) => ( { ...defaultTestConfig , maxDocumentsPerQuery : - 1 , maxBytesPerQuery : - 1 } )
294+ ) ;
0 commit comments