@@ -2,17 +2,14 @@ import { beforeEach, afterEach, describe, expect, it, vi, type MockInstance } fr
22import {
33 databaseCollectionInvalidArgs ,
44 databaseCollectionParameters ,
5- defaultDriverOptions ,
6- defaultTestConfig ,
75 getResponseContent ,
8- setupIntegrationTest ,
96 validateThrowsForInvalidArguments ,
107 validateToolMetadata ,
118 waitUntilSearchManagementServiceIsReady ,
129 waitUntilSearchIndexIsListed ,
1310 getDataFromUntrustedContent ,
1411} from "../../../helpers.js" ;
15- import { describeWithMongoDB , setupMongoDBIntegrationTest } from "../mongodbHelpers.js" ;
12+ import { describeWithMongoDB } from "../mongodbHelpers.js" ;
1613import type { Collection } from "mongodb" ;
1714import { createMockElicitInput } from "../../../../utils/elicitationMocks.js" ;
1815import { Elicitation } from "../../../../../src/elicitation.js" ;
@@ -122,89 +119,90 @@ describeWithMongoDB(
122119 } ) ;
123120 } ) ;
124121 } ,
125- undefined ,
126- undefined ,
127- { search : true }
122+ {
123+ downloadOptions : { search : true } ,
124+ }
128125) ;
129126
130- describe ( "drop-search-index tool - when invoked via an elicitation enabled client" , ( ) => {
131- const mockElicitInput = createMockElicitInput ( ) ;
132- const mdbIntegration = setupMongoDBIntegrationTest ( { search : true } ) ;
133- const integration = setupIntegrationTest (
134- ( ) => defaultTestConfig ,
135- ( ) => defaultDriverOptions ,
136- { elicitInput : mockElicitInput }
137- ) ;
127+ const mockElicitInput = createMockElicitInput ( ) ;
128+ describeWithMongoDB (
129+ "drop-search-index tool - when invoked via an elicitation enabled client" ,
130+ ( integration ) => {
131+ let moviesCollection : Collection ;
132+ let dropSearchIndexSpy : MockInstance ;
133+
134+ beforeEach ( async ( { signal } ) => {
135+ const mongoClient = integration . mongoClient ( ) ;
136+ moviesCollection = mongoClient . db ( "mflix" ) . collection ( "movies" ) ;
137+ await moviesCollection . insertMany ( [
138+ {
139+ name : "Movie1" ,
140+ plot : "This is a horrible movie about a database called BongoDB and how it tried to copy the OG MangoDB." ,
141+ } ,
142+ ] ) ;
143+ await waitUntilSearchManagementServiceIsReady ( moviesCollection , signal ) ;
144+ await moviesCollection . createSearchIndex ( {
145+ name : "searchIdx" ,
146+ definition : { mappings : { dynamic : true } } ,
147+ } ) ;
148+ await waitUntilSearchIndexIsListed ( moviesCollection , "searchIdx" , signal ) ;
138149
139- let moviesCollection : Collection ;
140- let dropSearchIndexSpy : MockInstance ;
150+ await integration . mcpClient ( ) . callTool ( {
151+ name : "connect" ,
152+ arguments : {
153+ connectionString : integration . connectionString ( ) ,
154+ } ,
155+ } ) ;
141156
142- beforeEach ( async ( { signal } ) => {
143- const mongoClient = mdbIntegration . mongoClient ( ) ;
144- moviesCollection = mongoClient . db ( "mflix" ) . collection ( "movies" ) ;
145- await moviesCollection . insertMany ( [
146- {
147- name : "Movie1" ,
148- plot : "This is a horrible movie about a database called BongoDB and how it tried to copy the OG MangoDB." ,
149- } ,
150- ] ) ;
151- await waitUntilSearchManagementServiceIsReady ( moviesCollection , signal ) ;
152- await moviesCollection . createSearchIndex ( {
153- name : "searchIdx" ,
154- definition : { mappings : { dynamic : true } } ,
157+ // Note: Unlike drop-index tool test, we don't test the final state of
158+ // indexes because of possible longer wait periods for changes to
159+ // reflect, at-times taking >30 seconds.
160+ dropSearchIndexSpy = vi . spyOn ( integration . mcpServer ( ) . session . serviceProvider , "dropSearchIndex" ) ;
155161 } ) ;
156- await waitUntilSearchIndexIsListed ( moviesCollection , "searchIdx" , signal ) ;
157162
158- await integration . mcpClient ( ) . callTool ( {
159- name : "connect" ,
160- arguments : {
161- connectionString : mdbIntegration . connectionString ( ) ,
162- } ,
163+ afterEach ( async ( ) => {
164+ mockElicitInput . clear ( ) ;
165+ // dropping collection also drops the associated search indexes
166+ await moviesCollection . drop ( ) ;
163167 } ) ;
164168
165- // Note: Unlike drop-index tool test, we don't test the final state of
166- // indexes because of possible longer wait periods for changes to
167- // reflect, at-times taking >30 seconds.
168- dropSearchIndexSpy = vi . spyOn ( integration . mcpServer ( ) . session . serviceProvider , "dropSearchIndex" ) ;
169- } ) ;
170-
171- afterEach ( async ( ) => {
172- // dropping collection also drops the associated search indexes
173- await moviesCollection . drop ( ) ;
174- } ) ;
169+ it ( "should ask for confirmation before proceeding with tool call" , async ( ) => {
170+ mockElicitInput . confirmYes ( ) ;
171+ await integration . mcpClient ( ) . callTool ( {
172+ name : "drop-search-index" ,
173+ arguments : { database : "mflix" , collection : "movies" , indexName : "searchIdx" } ,
174+ } ) ;
175+ expect ( mockElicitInput . mock ) . toHaveBeenCalledTimes ( 1 ) ;
176+ expect ( mockElicitInput . mock ) . toHaveBeenCalledWith ( {
177+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
178+ message : expect . stringContaining (
179+ "You are about to drop the `searchIdx` index from the `mflix.movies` namespace"
180+ ) ,
181+ requestedSchema : Elicitation . CONFIRMATION_SCHEMA ,
182+ } ) ;
175183
176- it ( "should ask for confirmation before proceeding with tool call" , async ( ) => {
177- mockElicitInput . confirmYes ( ) ;
178- await integration . mcpClient ( ) . callTool ( {
179- name : "drop-search-index" ,
180- arguments : { database : "mflix" , collection : "movies" , indexName : "searchIdx" } ,
181- } ) ;
182- expect ( mockElicitInput . mock ) . toHaveBeenCalledTimes ( 1 ) ;
183- expect ( mockElicitInput . mock ) . toHaveBeenCalledWith ( {
184- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
185- message : expect . stringContaining (
186- "You are about to drop the `searchIdx` index from the `mflix.movies` namespace"
187- ) ,
188- requestedSchema : Elicitation . CONFIRMATION_SCHEMA ,
184+ expect ( dropSearchIndexSpy ) . toHaveBeenCalledExactlyOnceWith ( "mflix" , "movies" , "searchIdx" ) ;
189185 } ) ;
190186
191- expect ( dropSearchIndexSpy ) . toHaveBeenCalledExactlyOnceWith ( "mflix" , "movies" , "searchIdx" ) ;
192- } ) ;
193-
194- it ( "should not drop the index if the confirmation was not provided" , async ( ) => {
195- mockElicitInput . confirmNo ( ) ;
196- await integration . mcpClient ( ) . callTool ( {
197- name : "drop-search-index" ,
198- arguments : { database : "mflix" , collection : "movies" , indexName : "searchIdx" } ,
199- } ) ;
200- expect ( mockElicitInput . mock ) . toHaveBeenCalledTimes ( 1 ) ;
201- expect ( mockElicitInput . mock ) . toHaveBeenCalledWith ( {
202- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
203- message : expect . stringContaining (
204- "You are about to drop the `searchIdx` index from the `mflix.movies` namespace"
205- ) ,
206- requestedSchema : Elicitation . CONFIRMATION_SCHEMA ,
187+ it ( "should not drop the index if the confirmation was not provided" , async ( ) => {
188+ mockElicitInput . confirmNo ( ) ;
189+ await integration . mcpClient ( ) . callTool ( {
190+ name : "drop-search-index" ,
191+ arguments : { database : "mflix" , collection : "movies" , indexName : "searchIdx" } ,
192+ } ) ;
193+ expect ( mockElicitInput . mock ) . toHaveBeenCalledTimes ( 1 ) ;
194+ expect ( mockElicitInput . mock ) . toHaveBeenCalledWith ( {
195+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
196+ message : expect . stringContaining (
197+ "You are about to drop the `searchIdx` index from the `mflix.movies` namespace"
198+ ) ,
199+ requestedSchema : Elicitation . CONFIRMATION_SCHEMA ,
200+ } ) ;
201+ expect ( dropSearchIndexSpy ) . not . toHaveBeenCalled ( ) ;
207202 } ) ;
208- expect ( dropSearchIndexSpy ) . not . toHaveBeenCalled ( ) ;
209- } ) ;
210- } ) ;
203+ } ,
204+ {
205+ downloadOptions : { search : true } ,
206+ getMockElicitationInput : ( ) => mockElicitInput ,
207+ }
208+ ) ;
0 commit comments