Skip to content

Commit b9434c8

Browse files
author
klapaudius
committed
Add test cases for handleMessage JSON-RPC message handling
Introduces new tests to validate `handleMessage` behavior for valid requests, notifications, and error handling for invalid or unknown methods. Ensures compliance with JSON-RPC 2.0 specification by verifying error codes, response structures, and notification handling logic.
1 parent d78dbb1 commit b9434c8

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

tests/Protocol/MCPProtocolTest.php

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,124 @@ public function test_connect_sends_messages(): void
138138

139139
$this->mcpProtocol->connect();
140140
}
141+
142+
/**
143+
* Test that handleMessage handles invalid JSON-RPC messages by sending an error response
144+
*/
145+
public function test_handleMessage_handles_invalid_jsonrpc(): void
146+
{
147+
$clientId = 'client_1';
148+
$invalidMessage = ['id' => 1, 'method' => 'example.method'];
149+
150+
$this->mockTransport
151+
->expects($this->once())
152+
->method('pushMessage')
153+
->with(
154+
$clientId,
155+
$this->callback(function (array $response) {
156+
$this->assertEquals('2.0', $response['jsonrpc']);
157+
$this->assertEquals(-32600, $response['error']['code']);
158+
$this->assertEquals('Invalid Request: Not a valid JSON-RPC 2.0 message', $response['error']['message']);
159+
return true;
160+
})
161+
);
162+
163+
$this->mcpProtocol->handleMessage($clientId, $invalidMessage);
164+
}
165+
166+
/**
167+
* Test that handleMessage processes valid request messages and sends results using the transport
168+
*/
169+
public function test_handleMessage_handles_valid_request(): void
170+
{
171+
$clientId = 'client_1';
172+
$validRequestMessage = ['jsonrpc' => '2.0', 'id' => 1, 'method' => 'test.method', 'params' => ['param1' => 'value1']];
173+
174+
$mockHandler = $this->createMock(\KLP\KlpMcpServer\Protocol\Handlers\RequestHandler::class);
175+
$mockHandler->method('isHandle')->with('test.method')->willReturn(true);
176+
$mockHandler->method('execute')->with('test.method', ['param1' => 'value1'])->willReturn(['response' => 'ok']);
177+
$this->mcpProtocol->registerRequestHandler($mockHandler);
178+
179+
$this->mockTransport
180+
->expects($this->once())
181+
->method('pushMessage')
182+
->with(
183+
$clientId,
184+
$this->callback(function (array $response) {
185+
$this->assertEquals('2.0', $response['jsonrpc']);
186+
$this->assertEquals(1, $response['id']);
187+
$this->assertEquals(['response' => 'ok'], $response['result']);
188+
return true;
189+
})
190+
);
191+
192+
$this->mcpProtocol->handleMessage($clientId, $validRequestMessage);
193+
}
194+
195+
/**
196+
* Test that handleMessage processes valid notification messages without sending a response
197+
*/
198+
public function test_handleMessage_handles_valid_notification(): void
199+
{
200+
$clientId = 'client_1';
201+
$validNotificationMessage = ['jsonrpc' => '2.0', 'method' => 'notify.method', 'params' => ['param1' => 'value1']];
202+
203+
$mockHandler = $this->createMock(\KLP\KlpMcpServer\Protocol\Handlers\NotificationHandler::class);
204+
$mockHandler->method('isHandle')->with('notify.method')->willReturn(true);
205+
$mockHandler->expects($this->once())->method('execute')->with(['param1' => 'value1']);
206+
$this->mcpProtocol->registerNotificationHandler($mockHandler);
207+
208+
$this->mockTransport
209+
->expects($this->never())
210+
->method('pushMessage');
211+
212+
$this->mcpProtocol->handleMessage($clientId, $validNotificationMessage);
213+
}
214+
215+
/**
216+
* Test that handleMessage responds with an error for unknown methods in requests
217+
*/
218+
public function test_handleMessage_handles_unknown_method(): void
219+
{
220+
$clientId = 'client_1';
221+
$unknownRequestMessage = ['jsonrpc' => '2.0', 'id' => 1, 'method' => 'unknown.method'];
222+
223+
$this->mockTransport
224+
->expects($this->once())
225+
->method('pushMessage')
226+
->with($this->callback(function (...$args) use ($clientId) {
227+
$data = $args[1];
228+
$this->assertEquals($clientId, $args[0]);
229+
$this->assertEquals('2.0', $data['jsonrpc']);
230+
$this->assertEquals(1, $data['id']);
231+
$this->assertEquals(-32601, $data['error']['code']);
232+
$this->assertEquals('Method not found: unknown.method', $data['error']['message']);
233+
return true;
234+
}));
235+
236+
$this->mcpProtocol->handleMessage($clientId, $unknownRequestMessage);
237+
}
238+
239+
/**
240+
* Test that handleMessage responds with an error for unknown notification in requests
241+
*/
242+
public function test_handleMessage_handles_unknown_notification(): void
243+
{
244+
$clientId = 'client_1';
245+
$unknownNotificationMessage = ['jsonrpc' => '2.0', 'method' => 'unknown.notify'];
246+
247+
$this->mockTransport
248+
->expects($this->once())
249+
->method('pushMessage')
250+
->with($this->callback(function (...$args) use ($clientId) {
251+
$data = $args[1];
252+
$this->assertEquals($clientId, $args[0]);
253+
$this->assertEquals('2.0', $data['jsonrpc']);
254+
$this->assertEquals(-32601, $data['error']['code']);
255+
$this->assertEquals('Method not found: unknown.notify', $data['error']['message']);
256+
return true;
257+
}));
258+
259+
$this->mcpProtocol->handleMessage($clientId, $unknownNotificationMessage);
260+
}
141261
}

0 commit comments

Comments
 (0)