This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git

commit 7e4ca741b63b453f65c21b8c315a75de9754a98c
Author: James Bognar <[email protected]>
AuthorDate: Tue Jul 28 17:44:42 2026 -0400

    test: add the permanent fake-McpRevision architecture acceptance test
    
    A revision written from scratch in the core module's own test tree serves a 
full
    request through both the servlet-subclass and mixin paths. Its 
classpath-isolation
    assertion is disabled until core's dependency on the v1 bean module is 
dropped.
    
    Co-authored-by: Cursor <[email protected]>
---
 .../rest/server/mcp/FakeMcpRevision_Test.java      | 115 +++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git 
a/juneau-rest/juneau-rest-server-mcp/src/test/java/org/apache/juneau/rest/server/mcp/FakeMcpRevision_Test.java
 
b/juneau-rest/juneau-rest-server-mcp/src/test/java/org/apache/juneau/rest/server/mcp/FakeMcpRevision_Test.java
new file mode 100644
index 0000000000..80ec9c80de
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server-mcp/src/test/java/org/apache/juneau/rest/server/mcp/FakeMcpRevision_Test.java
@@ -0,0 +1,115 @@
+package org.apache.juneau.rest.server.mcp;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.bean.jsonrpc.*;
+import org.apache.juneau.commons.inject.*;
+import org.apache.juneau.marshall.json.*;
+import org.apache.juneau.rest.mock.classic.*;
+import org.apache.juneau.rest.server.*;
+import org.apache.juneau.rest.server.servlet.*;
+import org.junit.jupiter.api.*;
+
+/**
+ * The architecture acceptance test for the revision-neutral core.
+ *
+ * <p>
+ * A revision implementation written entirely from scratch, inside the core 
module's own test tree,
+ * with no access to any revision-specific module, must be able to serve a 
full MCP request through
+ * both integration paths. If this ever stops compiling or stops passing, some 
revision-specific
+ * assumption has leaked into the core — which is precisely the regression 
this test exists to catch.
+ * Keep it permanently.
+ */
+@SuppressWarnings({
+       "resource" // MockRestClient is a Closeable test helper; lifetime is 
bounded by the test method.
+})
+class FakeMcpRevision_Test extends TestBase {
+
+       /** Records what it received and returns a canned response. */
+       static class FakeRevision implements McpRevision {
+               McpExchange lastExchange;
+               McpServerConfig lastConfig;
+               BeanStore lastCtx;
+               int calls;
+
+               @Override
+               public String protocolVersion() {
+                       return "0000-00-00";
+               }
+
+               @Override
+               public JsonRpcResponse dispatch(McpExchange exchange, 
McpServerConfig config, BeanStore ctx) {
+                       calls++;
+                       lastExchange = exchange;
+                       lastConfig = config;
+                       lastCtx = ctx;
+                       return JsonRpcResponse.ok(exchange.request().getId(), 
Map.of("fake", protocolVersion()));
+               }
+
+               @Override
+               public int errorCode(McpErrorKind kind) {
+                       return -1;
+               }
+       }
+
+       static final FakeRevision SERVLET_REVISION = new FakeRevision();
+       static final FakeRevision MIXIN_REVISION = new FakeRevision();
+
+       @Rest(serializers = JsonSerializer.class, parsers = JsonParser.class, 
defaultAccept = "application/json")
+       public static class A extends McpRestServlet {
+               private static final long serialVersionUID = 1L;
+               @Override protected McpServerConfig createMcpConfig() { return 
new McpServerConfig().setInstructions("fake"); }
+               @Override protected McpRevision revision() { return 
SERVLET_REVISION; }
+       }
+
+       @Rest(path = "/api", serializers = JsonSerializer.class, parsers = 
JsonParser.class, defaultAccept = "application/json")
+       public static class B extends BasicRestServlet implements McpEndpoint {
+               private static final long serialVersionUID = 1L;
+               @Override public McpServerConfig getMcpConfig() { return new 
McpServerConfig().setInstructions("fake-mixin"); }
+               @Override public McpRevision revision() { return 
MIXIN_REVISION; }
+       }
+
+       @Test
+       void a01_servletPath_reachesTheFakeRevision() throws Exception {
+               var c = 
MockRestClient.create(A.class).json().contentType("application/json").accept("application/json").build();
+               var res = 
c.post("/").contentString("{\"jsonrpc\":\"2.0\",\"id\":9,\"method\":\"anything\"}").run()
+                       .assertStatus(200).getContent().asString();
+               assertTrue(res.contains("0000-00-00"), res);
+               assertEquals(1, SERVLET_REVISION.calls);
+               assertEquals("anything", 
SERVLET_REVISION.lastExchange.request().getMethod());
+               assertEquals("fake", 
SERVLET_REVISION.lastConfig.getInstructions());
+               
assertTrue(SERVLET_REVISION.lastCtx.getBean(RestRequest.class).isPresent());
+       }
+
+       @Test
+       void a02_mixinPath_reachesTheFakeRevision() throws Exception {
+               var c = 
MockRestClient.create(B.class).json().contentType("application/json").accept("application/json").build();
+               var res = 
c.post("/mcp").contentString("{\"jsonrpc\":\"2.0\",\"id\":9,\"method\":\"anything\"}").run()
+                       .assertStatus(200).getContent().asString();
+               assertTrue(res.contains("0000-00-00"), res);
+               assertEquals(1, MIXIN_REVISION.calls);
+               assertEquals("fake-mixin", 
MIXIN_REVISION.lastConfig.getInstructions());
+       }
+
+       @Test
+       void a03_headerAccessorReachesTheHttpHeaders() throws Exception {
+               var c = 
MockRestClient.create(A.class).json().contentType("application/json").accept("application/json").build();
+               
c.post("/").contentString("{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"anything\"}").header("Mcp-Method",
 "tools/call").run().assertStatus(200);
+               assertEquals("tools/call", 
SERVLET_REVISION.lastExchange.header("Mcp-Method"));
+               
assertNull(SERVLET_REVISION.lastExchange.header("Absent-Header"));
+       }
+
+       @Test
+       @org.junit.jupiter.api.Disabled("Enabled by the task that drops core's 
dependency on juneau-bean-mcp-2025-06-18.")
+       void a04_coreTestTreeSeesNoRevisionModule() {
+               assertThrows(ClassNotFoundException.class,
+                       () -> 
Class.forName("org.apache.juneau.rest.server.mcp.v20250618.Mcp20250618Revision"),
+                       "the core module's test classpath must not contain any 
revision adapter");
+               assertThrows(ClassNotFoundException.class,
+                       () -> 
Class.forName("org.apache.juneau.bean.mcp.v20250618.Tool"),
+                       "the core module's test classpath must not contain any 
revision's wire beans");
+       }
+}

Reply via email to