Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
223
tests/Framework/Mcp/McpServerTest.php
Normal file
223
tests/Framework/Mcp/McpServerTest.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\DI\Container;
|
||||
use App\Framework\Mcp\McpResourceRegistry;
|
||||
use App\Framework\Mcp\McpServer;
|
||||
use App\Framework\Mcp\McpToolRegistry;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->container = Mockery::mock(Container::class);
|
||||
$this->toolRegistry = Mockery::mock(McpToolRegistry::class);
|
||||
$this->resourceRegistry = Mockery::mock(McpResourceRegistry::class);
|
||||
|
||||
$this->mcpServer = new McpServer(
|
||||
$this->container,
|
||||
$this->toolRegistry,
|
||||
$this->resourceRegistry
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
Mockery::close();
|
||||
});
|
||||
|
||||
test('initialize returns correct protocol response', function () {
|
||||
$request = json_encode([
|
||||
'jsonrpc' => '2.0',
|
||||
'method' => 'initialize',
|
||||
'params' => [],
|
||||
'id' => 1,
|
||||
]);
|
||||
|
||||
$response = $this->mcpServer->handleRequest($request);
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
expect($decoded)->toHaveKey('jsonrpc', '2.0')
|
||||
->and($decoded)->toHaveKey('id', 1)
|
||||
->and($decoded['result'])->toHaveKey('protocolVersion')
|
||||
->and($decoded['result'])->toHaveKey('capabilities')
|
||||
->and($decoded['result'])->toHaveKey('serverInfo')
|
||||
->and($decoded['result']['serverInfo']['name'])->toBe('Custom PHP Framework MCP Server');
|
||||
});
|
||||
|
||||
test('tools list returns registered tools', function () {
|
||||
$mockTools = [
|
||||
[
|
||||
'name' => 'test_tool',
|
||||
'description' => 'A test tool',
|
||||
'parameters' => [],
|
||||
'inputSchema' => null,
|
||||
],
|
||||
];
|
||||
|
||||
$this->toolRegistry
|
||||
->shouldReceive('getAllTools')
|
||||
->andReturn($mockTools);
|
||||
|
||||
$request = json_encode([
|
||||
'jsonrpc' => '2.0',
|
||||
'method' => 'tools/list',
|
||||
'id' => 1,
|
||||
]);
|
||||
|
||||
$response = $this->mcpServer->handleRequest($request);
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
expect($decoded)->toHaveKey('result')
|
||||
->and($decoded['result'])->toHaveKey('tools')
|
||||
->and($decoded['result']['tools'])->toHaveCount(1)
|
||||
->and($decoded['result']['tools'][0]['name'])->toBe('test_tool');
|
||||
});
|
||||
|
||||
test('resources list returns registered resources', function () {
|
||||
$mockResources = [
|
||||
[
|
||||
'uri' => 'framework://test',
|
||||
'name' => 'Test Resource',
|
||||
'description' => 'A test resource',
|
||||
'mimeType' => 'application/json',
|
||||
],
|
||||
];
|
||||
|
||||
$this->resourceRegistry
|
||||
->shouldReceive('getAllResources')
|
||||
->andReturn($mockResources);
|
||||
|
||||
$request = json_encode([
|
||||
'jsonrpc' => '2.0',
|
||||
'method' => 'resources/list',
|
||||
'id' => 1,
|
||||
]);
|
||||
|
||||
$response = $this->mcpServer->handleRequest($request);
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
expect($decoded)->toHaveKey('result')
|
||||
->and($decoded['result'])->toHaveKey('resources')
|
||||
->and($decoded['result']['resources'])->toHaveCount(1)
|
||||
->and($decoded['result']['resources'][0]['uri'])->toBe('framework://test');
|
||||
});
|
||||
|
||||
test('invalid json request returns error', function () {
|
||||
$invalidJson = '{"invalid": json}';
|
||||
|
||||
$response = $this->mcpServer->handleRequest($invalidJson);
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
expect($decoded)->toHaveKey('error')
|
||||
->and($decoded['error']['message'])->toContain('Invalid JSON');
|
||||
});
|
||||
|
||||
test('missing method returns error', function () {
|
||||
$request = json_encode([
|
||||
'jsonrpc' => '2.0',
|
||||
'id' => 1,
|
||||
// Missing 'method' field
|
||||
]);
|
||||
|
||||
$response = $this->mcpServer->handleRequest($request);
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
expect($decoded)->toHaveKey('error')
|
||||
->and($decoded['error']['message'])->toContain('method missing');
|
||||
});
|
||||
|
||||
test('unknown method returns error', function () {
|
||||
$request = json_encode([
|
||||
'jsonrpc' => '2.0',
|
||||
'method' => 'unknown/method',
|
||||
'id' => 1,
|
||||
]);
|
||||
|
||||
$response = $this->mcpServer->handleRequest($request);
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
expect($decoded)->toHaveKey('error')
|
||||
->and($decoded['error']['message'])->toContain('Unknown method');
|
||||
});
|
||||
|
||||
test('tool call executes registered tool', function () {
|
||||
$mockTool = [
|
||||
'name' => 'test_tool',
|
||||
'class' => 'TestToolClass',
|
||||
'method' => 'execute',
|
||||
'parameters' => [],
|
||||
];
|
||||
|
||||
$mockToolInstance = new class () {
|
||||
public function execute(array $params): array
|
||||
{
|
||||
return ['result' => 'success', 'data' => $params];
|
||||
}
|
||||
};
|
||||
|
||||
$this->toolRegistry
|
||||
->shouldReceive('getTool')
|
||||
->with('test_tool')
|
||||
->andReturn($mockTool);
|
||||
|
||||
$this->container
|
||||
->shouldReceive('get')
|
||||
->with('TestToolClass')
|
||||
->andReturn($mockToolInstance);
|
||||
|
||||
$request = json_encode([
|
||||
'jsonrpc' => '2.0',
|
||||
'method' => 'tools/call',
|
||||
'params' => [
|
||||
'name' => 'test_tool',
|
||||
'arguments' => ['param1' => 'value1'],
|
||||
],
|
||||
'id' => 1,
|
||||
]);
|
||||
|
||||
$response = $this->mcpServer->handleRequest($request);
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
expect($decoded)->toHaveKey('result')
|
||||
->and($decoded['result']['content'])->toHaveCount(1)
|
||||
->and($decoded['result']['content'][0]['type'])->toBe('text');
|
||||
});
|
||||
|
||||
test('resource read returns resource content', function () {
|
||||
$mockResource = [
|
||||
'uri' => 'framework://test',
|
||||
'class' => 'TestResourceClass',
|
||||
'method' => 'read',
|
||||
];
|
||||
|
||||
$mockResourceInstance = new class () {
|
||||
public function read(string $uri): array
|
||||
{
|
||||
return ['content' => 'test content', 'mimeType' => 'text/plain'];
|
||||
}
|
||||
};
|
||||
|
||||
$this->resourceRegistry
|
||||
->shouldReceive('getResource')
|
||||
->with('framework://test')
|
||||
->andReturn($mockResource);
|
||||
|
||||
$this->container
|
||||
->shouldReceive('get')
|
||||
->with('TestResourceClass')
|
||||
->andReturn($mockResourceInstance);
|
||||
|
||||
$request = json_encode([
|
||||
'jsonrpc' => '2.0',
|
||||
'method' => 'resources/read',
|
||||
'params' => [
|
||||
'uri' => 'framework://test',
|
||||
],
|
||||
'id' => 1,
|
||||
]);
|
||||
|
||||
$response = $this->mcpServer->handleRequest($request);
|
||||
$decoded = json_decode($response, true);
|
||||
|
||||
expect($decoded)->toHaveKey('result')
|
||||
->and($decoded['result']['contents'])->toHaveCount(1)
|
||||
->and($decoded['result']['contents'][0]['uri'])->toBe('framework://test');
|
||||
});
|
||||
Reference in New Issue
Block a user