|
3 | 3 | */ |
4 | 4 | package io.modelcontextprotocol.server; |
5 | 5 |
|
| 6 | +import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; |
6 | 7 | import static org.assertj.core.api.Assertions.assertThat; |
7 | 8 |
|
| 9 | +import java.net.URI; |
| 10 | +import java.net.http.HttpClient; |
| 11 | +import java.net.http.HttpRequest; |
| 12 | +import java.net.http.HttpResponse; |
8 | 13 | import java.time.Duration; |
9 | 14 | import java.util.stream.Stream; |
10 | 15 |
|
| 16 | +import io.modelcontextprotocol.AbstractStatelessIntegrationTests; |
| 17 | +import io.modelcontextprotocol.client.McpClient; |
| 18 | +import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport; |
| 19 | +import io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport; |
| 20 | +import io.modelcontextprotocol.server.McpServer.StatelessAsyncSpecification; |
| 21 | +import io.modelcontextprotocol.server.McpServer.StatelessSyncSpecification; |
| 22 | +import io.modelcontextprotocol.server.transport.WebMvcStatelessServerTransport; |
| 23 | +import io.modelcontextprotocol.spec.McpSchema; |
11 | 24 | import org.apache.catalina.LifecycleException; |
12 | 25 | import org.apache.catalina.LifecycleState; |
13 | 26 | import org.junit.jupiter.api.AfterEach; |
14 | 27 | import org.junit.jupiter.api.BeforeEach; |
15 | 28 | import org.junit.jupiter.api.Timeout; |
| 29 | +import org.junit.jupiter.params.ParameterizedTest; |
16 | 30 | import org.junit.jupiter.params.provider.Arguments; |
17 | 31 |
|
| 32 | +import org.junit.jupiter.params.provider.ValueSource; |
18 | 33 | import org.springframework.context.annotation.Bean; |
19 | 34 | import org.springframework.context.annotation.Configuration; |
20 | 35 | import org.springframework.web.reactive.function.client.WebClient; |
21 | 36 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; |
22 | 37 | import org.springframework.web.servlet.function.RouterFunction; |
23 | 38 | import org.springframework.web.servlet.function.ServerResponse; |
24 | | - |
25 | | -import io.modelcontextprotocol.AbstractStatelessIntegrationTests; |
26 | | -import io.modelcontextprotocol.client.McpClient; |
27 | | -import io.modelcontextprotocol.client.transport.HttpClientStreamableHttpTransport; |
28 | | -import io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport; |
29 | | -import io.modelcontextprotocol.server.McpServer.StatelessAsyncSpecification; |
30 | | -import io.modelcontextprotocol.server.McpServer.StatelessSyncSpecification; |
31 | | -import io.modelcontextprotocol.server.transport.WebMvcStatelessServerTransport; |
32 | 39 | import reactor.core.scheduler.Schedulers; |
33 | 40 |
|
34 | 41 | @Timeout(15) |
@@ -131,4 +138,37 @@ public void after() { |
131 | 138 | } |
132 | 139 | } |
133 | 140 |
|
| 141 | + @ParameterizedTest |
| 142 | + @ValueSource(strings = { "tools/list", "resources/list", "prompts/list" }) |
| 143 | + void testMissingHandlerReturnsMethodNotFoundError(String method) throws Exception { |
| 144 | + var mcpServer = prepareSyncServerBuilder().build(); |
| 145 | + |
| 146 | + HttpResponse<String> response; |
| 147 | + |
| 148 | + try { |
| 149 | + HttpRequest request = HttpRequest.newBuilder() |
| 150 | + .uri(URI.create("http://localhost:" + PORT + MESSAGE_ENDPOINT)) |
| 151 | + .header("Content-Type", "application/json") |
| 152 | + .header("Accept", "application/json, text/event-stream") |
| 153 | + .POST(HttpRequest.BodyPublishers.ofString(""" |
| 154 | + { |
| 155 | + "jsonrpc": "2.0", |
| 156 | + "method": "%s", |
| 157 | + "id": "test-request-123", |
| 158 | + "params": {} |
| 159 | + } |
| 160 | + """.formatted(method))) |
| 161 | + .build(); |
| 162 | + |
| 163 | + response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()); |
| 164 | + } |
| 165 | + finally { |
| 166 | + mcpServer.closeGracefully(); |
| 167 | + } |
| 168 | + |
| 169 | + final var responseBody = response.body(); |
| 170 | + assertThatJson(responseBody).inPath("error.code").isEqualTo(McpSchema.ErrorCodes.METHOD_NOT_FOUND); |
| 171 | + assertThatJson(responseBody).inPath("error.message").isEqualTo("Method not found: " + method); |
| 172 | + } |
| 173 | + |
134 | 174 | } |
0 commit comments