Skip to content

Commit

Permalink
Merge pull request #78 from mkouba/simplify-tests
Browse files Browse the repository at this point in the history
tests: simplify sending messages to the server
  • Loading branch information
mkouba authored Jan 21, 2025
2 parents 212326f + 65376b2 commit b1eb2f4
Show file tree
Hide file tree
Showing 23 changed files with 104 additions and 379 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.quarkiverse.mcp.server.test;

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

Expand All @@ -13,7 +12,7 @@

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.common.http.TestHTTPResource;
import io.restassured.http.ContentType;
import io.restassured.RestAssured;
import io.vertx.core.json.JsonObject;

public abstract class McpServerTest {
Expand All @@ -23,7 +22,8 @@ public abstract class McpServerTest {
@TestHTTPResource
URI testUri;

private McpSseClient client;
private volatile McpSseClient client;
private volatile URI messageEndpoint;

public static QuarkusUnitTest defaultConfig() {
// TODO in theory, we should also add SseClient to all test archives
Expand All @@ -38,6 +38,7 @@ public static QuarkusUnitTest defaultConfig() {
@AfterEach
void cleanup() {
client = null;
messageEndpoint = null;
}

protected URI initClient() throws URISyntaxException {
Expand All @@ -52,6 +53,18 @@ protected McpSseClient client() {
return client;
}

public void send(JsonObject data) {
if (messageEndpoint == null || client == null) {
throw new IllegalStateException("SSE client not initialized");
}
RestAssured.given()
.when()
.body(data.encode())
.post(messageEndpoint)
.then()
.statusCode(200);
}

protected URI initClient(Consumer<JsonObject> initResultAssert) throws URISyntaxException {
String testUriStr = testUri.toString();
if (testUriStr.endsWith("/")) {
Expand All @@ -62,6 +75,7 @@ protected URI initClient(Consumer<JsonObject> initResultAssert) throws URISyntax
var event = client.waitForFirstEvent();
String messagesUri = testUriStr + event.data().strip();
URI endpoint = URI.create(messagesUri);
this.messageEndpoint = endpoint;

LOG.infof("Client received endpoint: %s", endpoint);

Expand All @@ -73,13 +87,7 @@ protected URI initClient(Consumer<JsonObject> initResultAssert) throws URISyntax
.put("version", "1.0"))
.put("protocolVersion", "2024-11-05"));

given()
.contentType(ContentType.JSON)
.when()
.body(initMessage.encode())
.post(endpoint)
.then()
.statusCode(200);
send(initMessage);

JsonObject initResponse = waitForLastResponse();

Expand All @@ -92,15 +100,9 @@ protected URI initClient(Consumer<JsonObject> initResultAssert) throws URISyntax
}

// Send "notifications/initialized"
given()
.contentType(ContentType.JSON)
.when()
.body(new JsonObject()
.put("jsonrpc", "2.0")
.put("method", "notifications/initialized").encode())
.post(endpoint)
.then()
.statusCode(200);
send(new JsonObject()
.put("jsonrpc", "2.0")
.put("method", "notifications/initialized"));

return endpoint;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,7 @@ public void testCloseMessage() throws URISyntaxException {
URI endpoint = initClient();

JsonObject closeMessage = newMessage("q/close");

given()
.contentType(ContentType.JSON)
.when()
.body(closeMessage.encode())
.post(endpoint)
.then()
.statusCode(200);
send(closeMessage);

given()
.contentType(ContentType.JSON)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package io.quarkiverse.mcp.server.test.complete;

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.net.URI;
import java.net.URISyntaxException;

import org.junit.jupiter.api.Test;
Expand All @@ -12,7 +10,6 @@
import io.quarkiverse.mcp.server.runtime.JsonRPC;
import io.quarkiverse.mcp.server.test.McpServerTest;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.http.ContentType;
import io.vertx.core.json.JsonObject;

public class InvalidPromptCompleteTest extends McpServerTest {
Expand All @@ -24,8 +21,7 @@ public class InvalidPromptCompleteTest extends McpServerTest {

@Test
public void testError() throws URISyntaxException {
URI endpoint = initClient();

initClient();
JsonObject completeMessage = newMessage("completion/complete")
.put("params", new JsonObject()
.put("ref", new JsonObject()
Expand All @@ -34,14 +30,7 @@ public void testError() throws URISyntaxException {
.put("argument", new JsonObject()
.put("name", "name")
.put("value", "Vo")));

given().contentType(ContentType.JSON)
.when()
.body(completeMessage.encode())
.post(endpoint)
.then()
.statusCode(200);

send(completeMessage);
JsonObject response = waitForLastResponse();
assertEquals(JsonRPC.INVALID_PARAMS, response.getJsonObject("error").getInteger("code"));
assertEquals("Prompt completion does not exist: bar_name", response.getJsonObject("error").getString("message"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package io.quarkiverse.mcp.server.test.complete;

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.net.URI;
import java.net.URISyntaxException;

import org.junit.jupiter.api.Test;
Expand All @@ -12,7 +10,6 @@
import io.quarkiverse.mcp.server.runtime.JsonRPC;
import io.quarkiverse.mcp.server.test.McpServerTest;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.http.ContentType;
import io.vertx.core.json.JsonObject;

public class InvalidResourceTemplateCompleteTest extends McpServerTest {
Expand All @@ -24,8 +21,7 @@ public class InvalidResourceTemplateCompleteTest extends McpServerTest {

@Test
public void testError() throws URISyntaxException {
URI endpoint = initClient();

initClient();
JsonObject completeMessage = newMessage("completion/complete")
.put("params", new JsonObject()
.put("ref", new JsonObject()
Expand All @@ -34,14 +30,7 @@ public void testError() throws URISyntaxException {
.put("argument", new JsonObject()
.put("name", "name")
.put("value", "Vo")));

given().contentType(ContentType.JSON)
.when()
.body(completeMessage.encode())
.post(endpoint)
.then()
.statusCode(200);

send(completeMessage);
JsonObject response = waitForLastResponse();
assertEquals(JsonRPC.INVALID_PARAMS, response.getJsonObject("error").getInteger("code"));
assertEquals("Prompt completion does not exist: bar_name", response.getJsonObject("error").getString("message"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package io.quarkiverse.mcp.server.test.complete;

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.net.URI;
import java.net.URISyntaxException;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkiverse.mcp.server.test.McpServerTest;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.http.ContentType;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

Expand All @@ -25,8 +22,7 @@ public class PromptCompleteTest extends McpServerTest {

@Test
public void testCompletion() throws URISyntaxException {
URI endpoint = initClient();

initClient();
JsonObject completeMessage = newMessage("completion/complete")
.put("params", new JsonObject()
.put("ref", new JsonObject()
Expand All @@ -35,13 +31,7 @@ public void testCompletion() throws URISyntaxException {
.put("argument", new JsonObject()
.put("name", "name")
.put("value", "Vo")));

given().contentType(ContentType.JSON)
.when()
.body(completeMessage.encode())
.post(endpoint)
.then()
.statusCode(200);
send(completeMessage);

JsonObject completeResponse = waitForLastResponse();

Expand All @@ -59,13 +49,7 @@ public void testCompletion() throws URISyntaxException {
.put("argument", new JsonObject()
.put("name", "suffix")
.put("value", "Vo")));

given().contentType(ContentType.JSON)
.when()
.body(completeMessage.encode())
.post(endpoint)
.then()
.statusCode(200);
send(completeMessage);

completeResponse = waitForLastResponse();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package io.quarkiverse.mcp.server.test.complete;

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.net.URI;
import java.net.URISyntaxException;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkiverse.mcp.server.test.McpServerTest;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.http.ContentType;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

Expand All @@ -25,8 +22,7 @@ public class ResourceTemplateCompleteTest extends McpServerTest {

@Test
public void testCompletion() throws URISyntaxException {
URI endpoint = initClient();

initClient();
JsonObject completeMessage = newMessage("completion/complete")
.put("params", new JsonObject()
.put("ref", new JsonObject()
Expand All @@ -35,13 +31,7 @@ public void testCompletion() throws URISyntaxException {
.put("argument", new JsonObject()
.put("name", "foo")
.put("value", "Ja")));

given().contentType(ContentType.JSON)
.when()
.body(completeMessage.encode())
.post(endpoint)
.then()
.statusCode(200);
send(completeMessage);

JsonObject completeResponse = waitForLastResponse();

Expand All @@ -59,13 +49,7 @@ public void testCompletion() throws URISyntaxException {
.put("argument", new JsonObject()
.put("name", "bar")
.put("value", "Ja")));

given().contentType(ContentType.JSON)
.when()
.body(completeMessage.encode())
.post(endpoint)
.then()
.statusCode(200);
send(completeMessage);

completeResponse = waitForLastResponse();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package io.quarkiverse.mcp.server.test.logging;

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.net.URI;
import java.net.URISyntaxException;
import java.time.DayOfWeek;
import java.util.List;
Expand All @@ -15,7 +13,6 @@
import io.quarkiverse.mcp.server.McpLog.LogLevel;
import io.quarkiverse.mcp.server.test.McpServerTest;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.http.ContentType;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

Expand All @@ -27,27 +24,20 @@ public class LoggingSetLevelTest extends McpServerTest {

@Test
public void testLog() throws URISyntaxException {
URI endpoint = initClient();
initClient();

assertToolCall("monday:INFO", endpoint, "charlie", DayOfWeek.MONDAY);
assertToolCall("monday:INFO", "charlie", DayOfWeek.MONDAY);

List<JsonObject> notifications = client().waitForNotifications(1);
assertLog(notifications.get(0), LogLevel.INFO, "tool:charlie", "Charlie does not work on MONDAY");

JsonObject setLogLevelMessage = newMessage("logging/setLevel")
.put("params", new JsonObject()
.put("level", LogLevel.CRITICAL.toString().toLowerCase()));
send(setLogLevelMessage);

given()
.contentType(ContentType.JSON)
.when()
.body(setLogLevelMessage.encode())
.post(endpoint)
.then()
.statusCode(200);

assertToolCall("monday:CRITICAL", endpoint, "charlie", DayOfWeek.MONDAY);
assertToolCall("wednesday:CRITICAL", endpoint, "charlie", DayOfWeek.WEDNESDAY);
assertToolCall("monday:CRITICAL", "charlie", DayOfWeek.MONDAY);
assertToolCall("wednesday:CRITICAL", "charlie", DayOfWeek.WEDNESDAY);
client().waitForNotifications(2);
}

Expand All @@ -58,19 +48,12 @@ private void assertLog(JsonObject log, LogLevel level, String logger, String mes
assertEquals(message, params.getString("data"));
}

private void assertToolCall(String expectedText, URI endpoint, String name, DayOfWeek day) {
private void assertToolCall(String expectedText, String name, DayOfWeek day) {
JsonObject toolGetMessage = newMessage("tools/call")
.put("params", new JsonObject()
.put("name", name)
.put("arguments", new JsonObject().put("day", day)));

given()
.contentType(ContentType.JSON)
.when()
.body(toolGetMessage.encode())
.post(endpoint)
.then()
.statusCode(200);
send(toolGetMessage);

JsonObject toolGetResponse = waitForLastResponse();

Expand Down
Loading

0 comments on commit b1eb2f4

Please sign in to comment.