Files
michaelschiemer/tests/Framework/Http/MiddlewareDependencyResolverIntegrationTest.php
Michael Schiemer 55a330b223 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
2025-08-11 20:13:26 +02:00

205 lines
8.1 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Framework\Http;
use App\Framework\DI\DefaultContainer;
use App\Framework\Http\MiddlewareDependencyResolver;
use App\Framework\Reflection\CachedReflectionProvider;
use PHPUnit\Framework\TestCase;
/**
* Integration test for MiddlewareDependencyResolver with real system components
*/
final class MiddlewareDependencyResolverIntegrationTest extends TestCase
{
private MiddlewareDependencyResolver $resolver;
private array $testLog = [];
protected function setUp(): void
{
$container = new DefaultContainer();
$reflectionProvider = new CachedReflectionProvider();
// Create a test logger that captures logs
$logger = new class ($this->testLog) implements \App\Framework\Logging\Logger {
public function __construct(private array &$logCapture)
{
}
public function debug(string $message, array $context = []): void
{
$this->logCapture[] = ['level' => 'debug', 'message' => $message, 'context' => $context];
}
public function info(string $message, array $context = []): void
{
$this->logCapture[] = ['level' => 'info', 'message' => $message, 'context' => $context];
}
public function notice(string $message, array $context = []): void
{
$this->logCapture[] = ['level' => 'notice', 'message' => $message, 'context' => $context];
}
public function warning(string $message, array $context = []): void
{
$this->logCapture[] = ['level' => 'warning', 'message' => $message, 'context' => $context];
}
public function error(string $message, array $context = []): void
{
$this->logCapture[] = ['level' => 'error', 'message' => $message, 'context' => $context];
}
public function critical(string $message, array $context = []): void
{
$this->logCapture[] = ['level' => 'critical', 'message' => $message, 'context' => $context];
}
public function alert(string $message, array $context = []): void
{
$this->logCapture[] = ['level' => 'alert', 'message' => $message, 'context' => $context];
}
public function emergency(string $message, array $context = []): void
{
$this->logCapture[] = ['level' => 'emergency', 'message' => $message, 'context' => $context];
}
public function log(\App\Framework\Logging\LogLevel $level, string $message, array $context = []): void
{
$this->logCapture[] = ['level' => $level->value, 'message' => $message, 'context' => $context];
}
};
$this->resolver = new MiddlewareDependencyResolver(
$reflectionProvider,
$container,
$logger
);
}
public function test_resolves_existing_middlewares_and_filters_missing_ones(): void
{
$middlewares = [
// Critical middlewares (required by resolver)
\App\Framework\Http\Middlewares\ExceptionHandlingMiddleware::class,
\App\Framework\Http\Middlewares\RequestIdMiddleware::class,
\App\Framework\Http\Middlewares\RoutingMiddleware::class,
// Additional middlewares to test
\App\Framework\Http\Middlewares\AuthMiddleware::class,
// This doesn't exist
'NonExistentMiddleware',
// This might have missing dependencies
\App\Framework\Http\Middlewares\ResponseGeneratorMiddleware::class,
];
$result = $this->resolver->resolve($middlewares);
// Should have some middlewares resolved (at least the simple ones)
$this->assertGreaterThan(0, count($result->getMiddlewares()));
// Check that logging happened
$logMessages = array_column($this->testLog, 'message');
$combinedLog = implode(' ', $logMessages);
$this->assertStringContainsString(
'Class not found: NonExistentMiddleware',
$combinedLog
);
// Should log start and completion
$this->assertStringContainsString('Starting resolution for', implode(' ', $logMessages));
$this->assertStringContainsString('Resolution completed with', implode(' ', $logMessages));
}
public function test_identifies_middlewares_with_missing_dependencies(): void
{
// Test a middleware that likely has dependencies
$middlewares = [
// Critical middlewares (required by resolver)
\App\Framework\Http\Middlewares\ExceptionHandlingMiddleware::class,
\App\Framework\Http\Middlewares\RequestIdMiddleware::class,
\App\Framework\Http\Middlewares\RoutingMiddleware::class,
\App\Framework\Http\Middlewares\ResponseGeneratorMiddleware::class,
];
$result = $this->resolver->resolve($middlewares);
// Check if there are warnings about missing dependencies
$warningMessages = array_filter($this->testLog, fn ($log) => $log['level'] === 'warning');
if (count($result->getMiddlewares()) === 0) {
// If middleware was filtered out, should have warning about missing dependencies
$warningText = implode(' ', array_column($warningMessages, 'message'));
$this->assertStringContainsString('Missing dependencies for ResponseGeneratorMiddleware', $warningText);
}
}
public function test_logs_middleware_resolution_statistics(): void
{
$middlewares = [
// Critical middlewares (required by resolver)
\App\Framework\Http\Middlewares\ExceptionHandlingMiddleware::class,
\App\Framework\Http\Middlewares\RequestIdMiddleware::class,
\App\Framework\Http\Middlewares\RoutingMiddleware::class,
\App\Framework\Http\Middlewares\AuthMiddleware::class,
'NonExistentMiddleware1',
'NonExistentMiddleware2',
];
$result = $this->resolver->resolve($middlewares);
// Extract log messages
$logMessages = array_column($this->testLog, 'message');
$combinedLog = implode(' ', $logMessages);
// Should log how many middlewares we started with (only existing ones are counted)
$this->assertStringContainsString('Starting resolution for 4 middlewares', $combinedLog);
// Should log how many we ended up with
$this->assertStringContainsString('Resolution completed with', $combinedLog);
// Should have warnings about non-existent classes
$this->assertStringContainsString('Class not found: NonExistentMiddleware1', $combinedLog);
$this->assertStringContainsString('Class not found: NonExistentMiddleware2', $combinedLog);
}
public function test_dependency_graph_information(): void
{
$middlewares = [
// Critical middlewares (required by resolver)
\App\Framework\Http\Middlewares\ExceptionHandlingMiddleware::class,
\App\Framework\Http\Middlewares\RequestIdMiddleware::class,
\App\Framework\Http\Middlewares\RoutingMiddleware::class,
\App\Framework\Http\Middlewares\AuthMiddleware::class,
];
$result = $this->resolver->resolve($middlewares);
$dependencyInfo = $this->resolver->getDependencyInfo($middlewares);
// Should have dependency information for each middleware
$this->assertArrayHasKey(\App\Framework\Http\Middlewares\RequestIdMiddleware::class, $dependencyInfo);
$this->assertArrayHasKey(\App\Framework\Http\Middlewares\AuthMiddleware::class, $dependencyInfo);
// Each entry should have expected structure
foreach ($dependencyInfo as $className => $info) {
if (isset($info['error'])) {
continue; // Skip errored ones
}
$this->assertArrayHasKey('short_name', $info);
$this->assertArrayHasKey('exists', $info);
$this->assertArrayHasKey('can_instantiate', $info);
}
}
}