Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
205 lines
8.1 KiB
PHP
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\ReflectionLegacy\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);
|
|
}
|
|
}
|
|
}
|