@@ -9,6 +9,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
99import { MongoClient , ObjectId } from "mongodb" ;
1010import { toIncludeAllMembers } from "jest-extended" ;
1111import config from "../../src/config.js" ;
12+ import { McpError } from "@modelcontextprotocol/sdk/types.js" ;
1213
1314interface ParameterInfo {
1415 name : string ;
@@ -226,10 +227,93 @@ export const dbOperationParameters: ParameterInfo[] = [
226227 { name : "collection" , type : "string" , description : "Collection name" , required : true } ,
227228] ;
228229
229- export function validateParameters ( tool : ToolInfo , parameters : ParameterInfo [ ] ) : void {
230- const toolParameters = getParameters ( tool ) ;
231- expect ( toolParameters ) . toHaveLength ( parameters . length ) ;
232- expect ( toolParameters ) . toIncludeAllMembers ( parameters ) ;
230+ export const dbOperationInvalidArgTests = [ { } , { database : 123 } , { foo : "bar" , database : "test" } , { database : [ ] } ] ;
231+
232+ export function validateToolMetadata (
233+ integration : IntegrationTest ,
234+ name : string ,
235+ description : string ,
236+ parameters : ParameterInfo [ ]
237+ ) : void {
238+ it ( "should have correct metadata" , async ( ) => {
239+ const { tools } = await integration . mcpClient ( ) . listTools ( ) ;
240+ const tool = tools . find ( ( tool ) => tool . name === name ) ! ;
241+ expect ( tool ) . toBeDefined ( ) ;
242+ expect ( tool . description ) . toBe ( description ) ;
243+
244+ const toolParameters = getParameters ( tool ) ;
245+ expect ( toolParameters ) . toHaveLength ( parameters . length ) ;
246+ expect ( toolParameters ) . toIncludeAllMembers ( parameters ) ;
247+ } ) ;
248+ }
249+
250+ export function validateAutoConnectBehavior (
251+ integration : IntegrationTest ,
252+ name : string ,
253+ validation : ( ) => {
254+ args : { [ x : string ] : unknown } ;
255+ expectedResponse ?: string ;
256+ validate ?: ( content : unknown ) => void ;
257+ } ,
258+ beforeEachImpl ?: ( ) => Promise < void >
259+ ) : void {
260+ describe ( "when not connected" , ( ) => {
261+ if ( beforeEachImpl ) {
262+ beforeEach ( ( ) => beforeEachImpl ( ) ) ;
263+ }
264+
265+ it ( "connects automatically if connection string is configured" , async ( ) => {
266+ config . connectionString = integration . connectionString ( ) ;
267+
268+ const validationInfo = validation ( ) ;
269+
270+ const response = await integration . mcpClient ( ) . callTool ( {
271+ name,
272+ arguments : validationInfo . args ,
273+ } ) ;
274+
275+ if ( validationInfo . expectedResponse ) {
276+ const content = getResponseContent ( response . content ) ;
277+ expect ( content ) . toContain ( validationInfo . expectedResponse ) ;
278+ }
279+
280+ if ( validationInfo . validate ) {
281+ validationInfo . validate ( response . content ) ;
282+ }
283+ } ) ;
284+
285+ it ( "throws an error if connection string is not configured" , async ( ) => {
286+ const response = await integration . mcpClient ( ) . callTool ( {
287+ name,
288+ arguments : validation ( ) . args ,
289+ } ) ;
290+ const content = getResponseContent ( response . content ) ;
291+ expect ( content ) . toContain ( "You need to connect to a MongoDB instance before you can access its data." ) ;
292+ } ) ;
293+ } ) ;
294+ }
295+
296+ export function validateThrowsForInvalidArguments (
297+ integration : IntegrationTest ,
298+ name : string ,
299+ args : { [ x : string ] : unknown } [ ]
300+ ) : void {
301+ describe ( "with invalid arguments" , ( ) => {
302+ for ( const arg of args ) {
303+ it ( `throws a schema error for: ${ JSON . stringify ( arg ) } ` , async ( ) => {
304+ await integration . connectMcpClient ( ) ;
305+ try {
306+ await integration . mcpClient ( ) . callTool ( { name, arguments : arg } ) ;
307+ expect . fail ( "Expected an error to be thrown" ) ;
308+ } catch ( error ) {
309+ expect ( error ) . toBeInstanceOf ( McpError ) ;
310+ const mcpError = error as McpError ;
311+ expect ( mcpError . code ) . toEqual ( - 32602 ) ;
312+ expect ( mcpError . message ) . toContain ( `Invalid arguments for tool ${ name } ` ) ;
313+ }
314+ } ) ;
315+ }
316+ } ) ;
233317}
234318
235319export function describeAtlas ( name : number | string | Function | jest . FunctionLike , fn : jest . EmptyFunction ) {
0 commit comments