@@ -2,27 +2,33 @@ import fs from "fs/promises";
22import { beforeEach , describe , expect , it } from "vitest" ;
33import {
44 databaseCollectionParameters ,
5- timeout ,
5+ resourceChangedNotification ,
66 validateThrowsForInvalidArguments ,
77 validateToolMetadata ,
88} from "../../../helpers.js" ;
99import { describeWithMongoDB } from "../mongodbHelpers.js" ;
1010import { CallToolResult } from "@modelcontextprotocol/sdk/types.js" ;
1111import { Long } from "bson" ;
1212
13- function contentWithTextResourceURI ( content : CallToolResult [ "content" ] , namespace : string ) {
13+ export function contentWithTextResourceURI (
14+ content : CallToolResult [ "content" ]
15+ ) : CallToolResult [ "content" ] [ number ] | undefined {
1416 return content . find ( ( part ) => {
15- return part . type === "text" && part . text . startsWith ( `Data for namespace ${ namespace } ` ) ;
17+ return part . type === "text" && part . text . startsWith ( `Data for namespace` ) ;
1618 } ) ;
1719}
1820
19- function contentWithResourceURILink ( content : CallToolResult [ "content" ] , namespace : string ) {
21+ export function contentWithResourceURILink (
22+ content : CallToolResult [ "content" ]
23+ ) : CallToolResult [ "content" ] [ number ] | undefined {
2024 return content . find ( ( part ) => {
21- return part . type === "resource_link" && part . uri . startsWith ( `exported-data:// ${ namespace } ` ) ;
25+ return part . type === "resource_link" ;
2226 } ) ;
2327}
2428
25- function contentWithExportPath ( content : CallToolResult [ "content" ] ) {
29+ export function contentWithExportPath (
30+ content : CallToolResult [ "content" ]
31+ ) : CallToolResult [ "content" ] [ number ] | undefined {
2632 return content . find ( ( part ) => {
2733 return (
2834 part . type === "text" &&
@@ -89,20 +95,22 @@ describeWithMongoDB("export tool", (integration) => {
8995 { database : "test" , collection : "bar" , sort : [ ] , limit : 10 } ,
9096 ] ) ;
9197
92- it ( "when provided with incorrect namespace, export should have empty data" , async function ( ) {
98+ beforeEach ( async ( ) => {
9399 await integration . connectMcpClient ( ) ;
100+ } ) ;
101+
102+ it ( "when provided with incorrect namespace, export should have empty data" , async function ( ) {
94103 const response = await integration . mcpClient ( ) . callTool ( {
95104 name : "export" ,
96105 arguments : { database : "non-existent" , collection : "foos" } ,
97106 } ) ;
98- // Small timeout to let export finish
99- await timeout ( 10 ) ;
100-
101107 const content = response . content as CallToolResult [ "content" ] ;
102- const namespace = "non-existent.foos" ;
108+ const exportURI = contentWithResourceURILink ( content ) ?. uri as string ;
109+ await resourceChangedNotification ( integration . mcpClient ( ) , exportURI ) ;
110+
103111 expect ( content ) . toHaveLength ( 3 ) ;
104- expect ( contentWithTextResourceURI ( content , namespace ) ) . toBeDefined ( ) ;
105- expect ( contentWithResourceURILink ( content , namespace ) ) . toBeDefined ( ) ;
112+ expect ( contentWithTextResourceURI ( content ) ) . toBeDefined ( ) ;
113+ expect ( contentWithResourceURILink ( content ) ) . toBeDefined ( ) ;
106114
107115 const localPathPart = contentWithExportPath ( content ) ;
108116 expect ( localPathPart ) . toBeDefined ( ) ;
@@ -131,10 +139,11 @@ describeWithMongoDB("export tool", (integration) => {
131139 name : "export" ,
132140 arguments : { database : integration . randomDbName ( ) , collection : "foo" } ,
133141 } ) ;
134- // Small timeout to let export finish
135- await timeout ( 10 ) ;
142+ const content = response . content as CallToolResult [ "content" ] ;
143+ const exportURI = contentWithResourceURILink ( content ) ?. uri as string ;
144+ await resourceChangedNotification ( integration . mcpClient ( ) , exportURI ) ;
136145
137- const localPathPart = contentWithExportPath ( response . content as CallToolResult [ "content" ] ) ;
146+ const localPathPart = contentWithExportPath ( content ) ;
138147 expect ( localPathPart ) . toBeDefined ( ) ;
139148 const [ , localPath ] = / " ( .* ) " / . exec ( String ( localPathPart ?. text ) ) ?? [ ] ;
140149 expect ( localPath ) . toBeDefined ( ) ;
@@ -154,10 +163,11 @@ describeWithMongoDB("export tool", (integration) => {
154163 name : "export" ,
155164 arguments : { database : integration . randomDbName ( ) , collection : "foo" , filter : { name : "foo" } } ,
156165 } ) ;
157- // Small timeout to let export finish
158- await timeout ( 10 ) ;
166+ const content = response . content as CallToolResult [ "content" ] ;
167+ const exportURI = contentWithResourceURILink ( content ) ?. uri as string ;
168+ await resourceChangedNotification ( integration . mcpClient ( ) , exportURI ) ;
159169
160- const localPathPart = contentWithExportPath ( response . content as CallToolResult [ "content" ] ) ;
170+ const localPathPart = contentWithExportPath ( content ) ;
161171 expect ( localPathPart ) . toBeDefined ( ) ;
162172 const [ , localPath ] = / " ( .* ) " / . exec ( String ( localPathPart ?. text ) ) ?? [ ] ;
163173 expect ( localPath ) . toBeDefined ( ) ;
@@ -176,10 +186,11 @@ describeWithMongoDB("export tool", (integration) => {
176186 name : "export" ,
177187 arguments : { database : integration . randomDbName ( ) , collection : "foo" , limit : 1 } ,
178188 } ) ;
179- // Small timeout to let export finish
180- await timeout ( 10 ) ;
189+ const content = response . content as CallToolResult [ "content" ] ;
190+ const exportURI = contentWithResourceURILink ( content ) ?. uri as string ;
191+ await resourceChangedNotification ( integration . mcpClient ( ) , exportURI ) ;
181192
182- const localPathPart = contentWithExportPath ( response . content as CallToolResult [ "content" ] ) ;
193+ const localPathPart = contentWithExportPath ( content ) ;
183194 expect ( localPathPart ) . toBeDefined ( ) ;
184195 const [ , localPath ] = / " ( .* ) " / . exec ( String ( localPathPart ?. text ) ) ?? [ ] ;
185196 expect ( localPath ) . toBeDefined ( ) ;
@@ -203,10 +214,11 @@ describeWithMongoDB("export tool", (integration) => {
203214 sort : { longNumber : 1 } ,
204215 } ,
205216 } ) ;
206- // Small timeout to let export finish
207- await timeout ( 10 ) ;
217+ const content = response . content as CallToolResult [ "content" ] ;
218+ const exportURI = contentWithResourceURILink ( content ) ?. uri as string ;
219+ await resourceChangedNotification ( integration . mcpClient ( ) , exportURI ) ;
208220
209- const localPathPart = contentWithExportPath ( response . content as CallToolResult [ "content" ] ) ;
221+ const localPathPart = contentWithExportPath ( content ) ;
210222 expect ( localPathPart ) . toBeDefined ( ) ;
211223 const [ , localPath ] = / " ( .* ) " / . exec ( String ( localPathPart ?. text ) ) ?? [ ] ;
212224 expect ( localPath ) . toBeDefined ( ) ;
@@ -230,10 +242,11 @@ describeWithMongoDB("export tool", (integration) => {
230242 projection : { _id : 0 , name : 1 } ,
231243 } ,
232244 } ) ;
233- // Small timeout to let export finish
234- await timeout ( 10 ) ;
245+ const content = response . content as CallToolResult [ "content" ] ;
246+ const exportURI = contentWithResourceURILink ( content ) ?. uri as string ;
247+ await resourceChangedNotification ( integration . mcpClient ( ) , exportURI ) ;
235248
236- const localPathPart = contentWithExportPath ( response . content as CallToolResult [ "content" ] ) ;
249+ const localPathPart = contentWithExportPath ( content ) ;
237250 expect ( localPathPart ) . toBeDefined ( ) ;
238251 const [ , localPath ] = / " ( .* ) " / . exec ( String ( localPathPart ?. text ) ) ?? [ ] ;
239252 expect ( localPath ) . toBeDefined ( ) ;
@@ -261,10 +274,11 @@ describeWithMongoDB("export tool", (integration) => {
261274 jsonExportFormat : "relaxed" ,
262275 } ,
263276 } ) ;
264- // Small timeout to let export finish
265- await timeout ( 10 ) ;
277+ const content = response . content as CallToolResult [ "content" ] ;
278+ const exportURI = contentWithResourceURILink ( content ) ?. uri as string ;
279+ await resourceChangedNotification ( integration . mcpClient ( ) , exportURI ) ;
266280
267- const localPathPart = contentWithExportPath ( response . content as CallToolResult [ "content" ] ) ;
281+ const localPathPart = contentWithExportPath ( content ) ;
268282 expect ( localPathPart ) . toBeDefined ( ) ;
269283 const [ , localPath ] = / " ( .* ) " / . exec ( String ( localPathPart ?. text ) ) ?? [ ] ;
270284 expect ( localPath ) . toBeDefined ( ) ;
@@ -293,10 +307,11 @@ describeWithMongoDB("export tool", (integration) => {
293307 jsonExportFormat : "canonical" ,
294308 } ,
295309 } ) ;
296- // Small timeout to let export finish
297- await timeout ( 10 ) ;
310+ const content = response . content as CallToolResult [ "content" ] ;
311+ const exportURI = contentWithResourceURILink ( content ) ?. uri as string ;
312+ await resourceChangedNotification ( integration . mcpClient ( ) , exportURI ) ;
298313
299- const localPathPart = contentWithExportPath ( response . content as CallToolResult [ "content" ] ) ;
314+ const localPathPart = contentWithExportPath ( content ) ;
300315 expect ( localPathPart ) . toBeDefined ( ) ;
301316 const [ , localPath ] = / " ( .* ) " / . exec ( String ( localPathPart ?. text ) ) ?? [ ] ;
302317 expect ( localPath ) . toBeDefined ( ) ;
0 commit comments