2727import io .modelcontextprotocol .modern .server .McpRequestContext ;
2828import io .modelcontextprotocol .modern .server .McpServer ;
2929import io .modelcontextprotocol .modern .server .McpSyncResponse ;
30+ import io .modelcontextprotocol .modern .server .feature .repository .InMemorySyncPromptRepository ;
31+ import io .modelcontextprotocol .modern .server .feature .repository .InMemorySyncResourceRepository ;
3032import org .junit .jupiter .api .Test ;
3133import reactor .core .publisher .Mono ;
3234
@@ -69,56 +71,24 @@ class CompletionsFeatureTests {
6971 "shop" .equals (context .get ("database" )) ? List .of ("orders" , "customers" ) : List .of ()));
7072 };
7173
72- private final McpSyncPromptRepository prompts = new McpSyncPromptRepository () {
73- @ Override
74- public PromptsPage list (McpRequestContext ctx , String cursor ) {
75- return PromptsPage .of (List .of (CODE_REVIEW , PLAIN ));
76- }
77-
78- @ Override
79- public McpSyncPrompt find (McpRequestContext ctx , String name ) {
80- return switch (name ) {
81- case "code_review" -> prompt (CODE_REVIEW ).withCompletionHandler (languages );
82- case "plain" -> prompt (PLAIN );
83- default -> null ;
84- };
85- }
86-
87- @ Override
88- public boolean supportsCompletion () {
89- return true ;
90- }
91- };
74+ // Completion never reads the templates, so their reader is never called.
75+ private static final McpSyncResource NOT_READ = McpSyncResource .of ((ctx , request ) -> {
76+ throw new AssertionError ("completion must not read the resource" );
77+ });
9278
93- private final McpSyncResourceRepository resources = new McpSyncResourceRepository () {
94- @ Override
95- public ResourcesPage list (McpRequestContext ctx , String cursor ) {
96- return ResourcesPage .of (List .of ());
97- }
98-
99- @ Override
100- public ResourceTemplatesPage listTemplates (McpRequestContext ctx , String cursor ) {
101- return ResourceTemplatesPage .of (List .of (TABLE , FILE ));
102- }
103-
104- @ Override
105- public McpSyncResource find (McpRequestContext ctx , String uri ) {
106- return null ;
107- }
108-
109- @ Override
110- public McpSyncResourceTemplate findTemplate (McpRequestContext ctx , String uriTemplate ) {
111- if (TABLE .uriTemplate ().equals (uriTemplate )) {
112- return McpSyncResourceTemplate .of (TABLE ).withCompletionHandler (tables );
113- }
114- return FILE .uriTemplate ().equals (uriTemplate ) ? McpSyncResourceTemplate .of (FILE ) : null ;
115- }
79+ private final McpSyncResourceRepository resources = InMemorySyncResourceRepository .builder ()
80+ .template (McpSyncResourceTemplate .of (TABLE ).withCompletionHandler (this .tables ), NOT_READ )
81+ .template (McpSyncResourceTemplate .of (FILE ), NOT_READ )
82+ .supportsCompletion (true )
83+ .build ();
11684
117- @ Override
118- public boolean supportsCompletion () {
119- return true ;
120- }
121- };
85+ private McpSyncPromptRepository prompts (boolean supportsCompletion ) {
86+ return InMemorySyncPromptRepository .builder ()
87+ .prompt (prompt (CODE_REVIEW ).withCompletionHandler (this .languages ))
88+ .prompt (prompt (PLAIN ))
89+ .supportsCompletion (supportsCompletion )
90+ .build ();
91+ }
12292
12393 private static McpSyncPrompt prompt (Prompt definition ) {
12494 return McpSyncPrompt .of (definition ,
@@ -130,7 +100,7 @@ private static McpServer server(McpFeature... features) {
130100 }
131101
132102 private McpServer server () {
133- return server (PromptsFeature .ofSync (this . prompts ), ResourcesFeature .ofSync (this .resources ));
103+ return server (PromptsFeature .ofSync (prompts ( true ) ), ResourcesFeature .ofSync (this .resources ));
134104 }
135105
136106 private static JSONRPCResponse complete (McpServer server , Map <String , Object > ref , String argument , String value ,
@@ -227,7 +197,7 @@ void variableTheTemplateDoesNotDeclareIsInvalidParams() {
227197
228198 @ Test
229199 void refTypeNoFeatureCompletesIsInvalidParams () {
230- McpServer server = server (PromptsFeature .ofSync (this . prompts ));
200+ McpServer server = server (PromptsFeature .ofSync (prompts ( true ) ));
231201
232202 JSONRPCResponse response = complete (server , resource (TABLE .uriTemplate ()), "table" , "" , null );
233203
@@ -237,19 +207,7 @@ void refTypeNoFeatureCompletesIsInvalidParams() {
237207
238208 @ Test
239209 void completionIsNotServedWhenNoRepositorySupportsIt () {
240- McpSyncPromptRepository withoutCompletion = new McpSyncPromptRepository () {
241- @ Override
242- public PromptsPage list (McpRequestContext ctx , String cursor ) {
243- return prompts .list (ctx , cursor );
244- }
245-
246- @ Override
247- public McpSyncPrompt find (McpRequestContext ctx , String name ) {
248- return prompts .find (ctx , name );
249- }
250- };
251-
252- JSONRPCResponse response = complete (server (PromptsFeature .ofSync (withoutCompletion )), prompt ("code_review" ),
210+ JSONRPCResponse response = complete (server (PromptsFeature .ofSync (prompts (false ))), prompt ("code_review" ),
253211 "language" , "ja" , null );
254212
255213 assertThat (response .error ().code ()).isEqualTo (ErrorCodes .METHOD_NOT_FOUND );
@@ -274,7 +232,8 @@ public Set<String> completionRefTypes() {
274232 }
275233 };
276234
277- assertThatIllegalStateException ().isThrownBy (() -> server (PromptsFeature .ofSync (this .prompts ), promptCompleter ))
235+ assertThatIllegalStateException ()
236+ .isThrownBy (() -> server (PromptsFeature .ofSync (prompts (true )), promptCompleter ))
278237 .withMessageContaining ("ref/prompt" );
279238 }
280239
@@ -295,23 +254,10 @@ void missingArgumentIsRejectedAsInvalidParams() {
295254 }
296255
297256 private static McpServer serverCompleting (CompleteResult .Completion completion ) {
298- McpSyncPromptRepository prompts = new McpSyncPromptRepository () {
299- @ Override
300- public PromptsPage list (McpRequestContext ctx , String cursor ) {
301- return PromptsPage .of (List .of (PLAIN ));
302- }
303-
304- @ Override
305- public McpSyncPrompt find (McpRequestContext ctx , String name ) {
306- return prompt (PLAIN ).withCompletionHandler ((c , request ) -> CompleteResult .of (completion ));
307- }
308-
309- @ Override
310- public boolean supportsCompletion () {
311- return true ;
312- }
313- };
314- return server (PromptsFeature .ofSync (prompts ));
257+ return server (PromptsFeature .ofSync (InMemorySyncPromptRepository .builder ()
258+ .prompt (prompt (PLAIN ).withCompletionHandler ((c , request ) -> CompleteResult .of (completion )))
259+ .supportsCompletion (true )
260+ .build ()));
315261 }
316262
317263 private static List <String > values (int count ) {
0 commit comments