- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
194 lines
6.8 KiB
PHP
194 lines
6.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Framework\Mcp\Tools;
|
|
|
|
use App\Framework\DI\Container;
|
|
use App\Framework\DI\DefaultContainer;
|
|
use App\Framework\Discovery\UnifiedDiscoveryService;
|
|
use App\Framework\Mcp\Tools\FrameworkTools;
|
|
use App\Framework\Router\CompiledRoutes;
|
|
use Mockery;
|
|
|
|
describe('FrameworkTools MCP Integration', function () {
|
|
beforeEach(function () {
|
|
$this->container = new DefaultContainer();
|
|
$this->discoveryService = Mockery::mock(UnifiedDiscoveryService::class);
|
|
$this->compiledRoutes = Mockery::mock(CompiledRoutes::class);
|
|
|
|
$this->frameworkTools = new FrameworkTools(
|
|
$this->container,
|
|
$this->discoveryService,
|
|
$this->compiledRoutes
|
|
);
|
|
});
|
|
|
|
afterEach(function () {
|
|
Mockery::close();
|
|
});
|
|
|
|
it('can analyze routes', function () {
|
|
$this->compiledRoutes
|
|
->shouldReceive('getStaticRoutes')
|
|
->once()
|
|
->andReturn([
|
|
'/admin' => ['handler' => 'AdminController@dashboard'],
|
|
'/api/users' => ['handler' => 'UserController@index'],
|
|
]);
|
|
|
|
$this->compiledRoutes
|
|
->shouldReceive('getNamedRoutes')
|
|
->once()
|
|
->andReturn([
|
|
'admin.dashboard' => '/admin',
|
|
'api.users.index' => '/api/users',
|
|
]);
|
|
|
|
$result = $this->frameworkTools->analyzeRoutes();
|
|
|
|
expect($result)->toBeArray();
|
|
expect($result)->toHaveKey('named_routes');
|
|
expect($result)->toHaveKey('total_routes');
|
|
expect($result['total_routes'])->toBe(2);
|
|
});
|
|
|
|
it('can analyze container bindings', function () {
|
|
// Register some services in the container
|
|
$this->container->singleton('TestService', function () {
|
|
return new \stdClass();
|
|
});
|
|
|
|
$result = $this->frameworkTools->analyzeContainerBindings();
|
|
|
|
expect($result)->toBeArray();
|
|
expect($result)->toHaveKey('total_bindings');
|
|
expect($result)->toHaveKey('bindings');
|
|
expect($result['total_bindings'])->toBeGreaterThan(0);
|
|
});
|
|
|
|
it('can discover attributes', function () {
|
|
$mockRegistry = Mockery::mock(\App\Framework\Discovery\Results\DiscoveryRegistry::class);
|
|
$mockAttributeRegistry = Mockery::mock(\App\Framework\Discovery\Results\AttributeRegistry::class);
|
|
|
|
$mockRegistry->attributes = $mockAttributeRegistry;
|
|
|
|
$mockAttributeRegistry
|
|
->shouldReceive('get')
|
|
->with('App\\Framework\\Mcp\\McpTool')
|
|
->once()
|
|
->andReturn([
|
|
['className' => 'TestClass', 'methodName' => 'testMethod'],
|
|
['className' => 'AnotherClass', 'methodName' => 'anotherMethod'],
|
|
]);
|
|
|
|
$this->discoveryService
|
|
->shouldReceive('discover')
|
|
->once()
|
|
->andReturn($mockRegistry);
|
|
|
|
$result = $this->frameworkTools->discoverAttributes('App\\Framework\\Mcp\\McpTool');
|
|
|
|
expect($result)->toBeArray();
|
|
expect($result)->toHaveKey('attribute_class');
|
|
expect($result)->toHaveKey('count');
|
|
expect($result)->toHaveKey('discoveries');
|
|
expect($result['attribute_class'])->toBe('App\\Framework\\Mcp\\McpTool');
|
|
expect($result['count'])->toBe(2);
|
|
expect($result['discoveries'])->toHaveCount(2);
|
|
});
|
|
|
|
it('handles discovery errors gracefully', function () {
|
|
$this->discoveryService
|
|
->shouldReceive('discover')
|
|
->once()
|
|
->andThrow(new \Exception('Discovery failed'));
|
|
|
|
$result = $this->frameworkTools->discoverAttributes('NonExistentAttribute');
|
|
|
|
expect($result)->toBeArray();
|
|
expect($result)->toHaveKey('error');
|
|
expect($result)->toHaveKey('attribute_class');
|
|
expect($result['error'])->toBe('Discovery failed');
|
|
expect($result['attribute_class'])->toBe('NonExistentAttribute');
|
|
});
|
|
|
|
it('performs framework health check', function () {
|
|
$result = $this->frameworkTools->frameworkHealthCheck();
|
|
|
|
expect($result)->toBeArray();
|
|
expect($result)->toHaveKey('status');
|
|
expect($result)->toHaveKey('components');
|
|
expect($result)->toHaveKey('timestamp');
|
|
expect($result['status'])->toBe('completed');
|
|
expect($result['components'])->toHaveKey('container');
|
|
expect($result['components'])->toHaveKey('discovery_service');
|
|
});
|
|
|
|
it('lists framework modules', function () {
|
|
$result = $this->frameworkTools->listFrameworkModules();
|
|
|
|
expect($result)->toBeArray();
|
|
expect($result)->toHaveKey('core_modules');
|
|
expect($result)->toHaveKey('total_modules');
|
|
expect($result['core_modules'])->toBeArray();
|
|
expect($result['total_modules'])->toBeGreaterThan(0);
|
|
});
|
|
|
|
it('validates container health in health check', function () {
|
|
$result = $this->frameworkTools->frameworkHealthCheck();
|
|
|
|
expect($result['components']['container'])->toBe('healthy');
|
|
});
|
|
|
|
it('validates discovery service health in health check', function () {
|
|
$result = $this->frameworkTools->frameworkHealthCheck();
|
|
|
|
expect($result['components']['discovery_service'])->toBe('healthy');
|
|
});
|
|
|
|
it('handles container errors in health check', function () {
|
|
// Create a broken container scenario by triggering an error
|
|
$brokenContainer = Mockery::mock(Container::class);
|
|
$brokenContainer
|
|
->shouldReceive('get')
|
|
->andThrow(new \Exception('Container error'));
|
|
|
|
$frameworkTools = new FrameworkTools(
|
|
$brokenContainer,
|
|
$this->discoveryService,
|
|
$this->compiledRoutes
|
|
);
|
|
|
|
$result = $frameworkTools->frameworkHealthCheck();
|
|
|
|
expect($result['components']['container'])->toContain('error');
|
|
});
|
|
|
|
it('limits discovery results to prevent overwhelming output', function () {
|
|
$mockRegistry = Mockery::mock(\App\Framework\Discovery\Results\DiscoveryRegistry::class);
|
|
$mockAttributeRegistry = Mockery::mock(\App\Framework\Discovery\Results\AttributeRegistry::class);
|
|
|
|
$mockRegistry->attributes = $mockAttributeRegistry;
|
|
|
|
// Create 15 mock results
|
|
$manyResults = array_fill(0, 15, ['className' => 'TestClass', 'methodName' => 'testMethod']);
|
|
|
|
$mockAttributeRegistry
|
|
->shouldReceive('get')
|
|
->once()
|
|
->andReturn($manyResults);
|
|
|
|
$this->discoveryService
|
|
->shouldReceive('discover')
|
|
->once()
|
|
->andReturn($mockRegistry);
|
|
|
|
$result = $this->frameworkTools->discoverAttributes('SomeAttribute');
|
|
|
|
expect($result['total_found'])->toBe(15);
|
|
expect($result['discoveries'])->toHaveCount(10); // Limited to 10
|
|
expect($result['count'])->toBe(15); // But count shows total
|
|
});
|
|
});
|