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:
334
tests/Framework/Core/DynamicRoutingTest.php
Normal file
334
tests/Framework/Core/DynamicRoutingTest.php
Normal file
@@ -0,0 +1,334 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Core\DynamicRoute;
|
||||
use App\Framework\Core\RouteCompiler;
|
||||
use App\Framework\Discovery\Visitors\UnifiedRouteVisitor;
|
||||
use App\Framework\Router\Result\FileResult;
|
||||
use App\Framework\Router\Result\JsonResult;
|
||||
|
||||
// Test Controller Klassen für Dynamic Routing Tests
|
||||
class TestDynamicController
|
||||
{
|
||||
#[Route('/test/{id}')]
|
||||
public function showById(int $id): JsonResult
|
||||
{
|
||||
return new JsonResult(['id' => $id]);
|
||||
}
|
||||
|
||||
#[Route('/images/{filename}')]
|
||||
public function showImage(string $filename): FileResult
|
||||
{
|
||||
return new FileResult("/path/to/{$filename}");
|
||||
}
|
||||
|
||||
#[Route('/user/{userId}/post/{postId}')]
|
||||
public function showUserPost(int $userId, string $postId): JsonResult
|
||||
{
|
||||
return new JsonResult(['userId' => $userId, 'postId' => $postId]);
|
||||
}
|
||||
|
||||
#[Route('/api/search/{query?}')]
|
||||
public function search(?string $query = null): JsonResult
|
||||
{
|
||||
return new JsonResult(['query' => $query]);
|
||||
}
|
||||
}
|
||||
|
||||
describe('Dynamic Routing Parameter Extraction', function () {
|
||||
beforeEach(function () {
|
||||
$this->discoveryVisitor = new UnifiedRouteVisitor();
|
||||
$this->routeCompiler = new RouteCompiler();
|
||||
});
|
||||
|
||||
test('discovers routes with dynamic parameters', function () {
|
||||
$this->discoveryVisitor->onScanStart();
|
||||
// UnifiedRouteVisitor benötigt ClassName und FilePath Value Objects
|
||||
$className = \App\Framework\Core\ValueObjects\ClassName::fromString(TestDynamicController::class);
|
||||
$filePath = \App\Framework\Filesystem\FilePath::create('test-file.php');
|
||||
$reflection = new \App\Framework\Reflection\WrappedReflectionClass(new \ReflectionClass(TestDynamicController::class));
|
||||
|
||||
$this->discoveryVisitor->visitClass($className, $filePath, $reflection);
|
||||
|
||||
$routes = $this->discoveryVisitor->getResults();
|
||||
|
||||
expect($routes)->toHaveCount(4);
|
||||
|
||||
// Test route with single parameter
|
||||
$singleParamRoute = null;
|
||||
foreach ($routes as $route) {
|
||||
if ($route['path'] === '/test/{id}') {
|
||||
$singleParamRoute = $route;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect($singleParamRoute)->not->toBeNull();
|
||||
expect($singleParamRoute['controller'])->toBe(TestDynamicController::class);
|
||||
expect($singleParamRoute['action'])->toBe('showById');
|
||||
|
||||
// Test image route (the problematic one)
|
||||
$imageRoute = null;
|
||||
foreach ($routes as $route) {
|
||||
if ($route['path'] === '/images/{filename}') {
|
||||
$imageRoute = $route;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect($imageRoute)->not->toBeNull();
|
||||
expect($imageRoute['controller'])->toBe(TestDynamicController::class);
|
||||
expect($imageRoute['action'])->toBe('showImage');
|
||||
|
||||
// Test route with multiple parameters
|
||||
$multiParamRoute = null;
|
||||
foreach ($routes as $route) {
|
||||
if ($route['path'] === '/user/{userId}/post/{postId}') {
|
||||
$multiParamRoute = $route;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect($multiParamRoute)->not->toBeNull();
|
||||
});
|
||||
|
||||
test('extracts parameter information correctly', function () {
|
||||
$this->discoveryVisitor->onScanStart();
|
||||
// UnifiedRouteVisitor benötigt ClassName und FilePath Value Objects
|
||||
$className = \App\Framework\Core\ValueObjects\ClassName::fromString(TestDynamicController::class);
|
||||
$filePath = \App\Framework\Filesystem\FilePath::create('test-file.php');
|
||||
$reflection = new \App\Framework\Reflection\WrappedReflectionClass(new \ReflectionClass(TestDynamicController::class));
|
||||
|
||||
$this->discoveryVisitor->visitClass($className, $filePath, $reflection);
|
||||
|
||||
$routes = $this->discoveryVisitor->getResults();
|
||||
|
||||
// Suche die Image Route
|
||||
$imageRoute = null;
|
||||
foreach ($routes as $route) {
|
||||
if ($route['path'] === '/images/{filename}') {
|
||||
$imageRoute = $route;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prüfe ob Parameter-Informationen vorhanden sind
|
||||
if (isset($imageRoute['parameters'])) {
|
||||
expect($imageRoute['parameters'])->toBeArray();
|
||||
|
||||
// Debug: Zeige Parameter-Struktur
|
||||
error_log('Image Route Parameters: ' . json_encode($imageRoute['parameters']));
|
||||
|
||||
// Suche nach filename Parameter
|
||||
$filenameParam = null;
|
||||
foreach ($imageRoute['parameters'] as $param) {
|
||||
if ($param['name'] === 'filename') {
|
||||
$filenameParam = $param;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($filenameParam) {
|
||||
expect($filenameParam['name'])->toBe('filename');
|
||||
expect($filenameParam['type'])->toBe('string'); // Das ist wahrscheinlich null!
|
||||
expect($filenameParam['isBuiltin'])->toBeTrue();
|
||||
} else {
|
||||
error_log('Filename parameter not found in parameters array');
|
||||
}
|
||||
} else {
|
||||
error_log('No parameters found in route array');
|
||||
expect($imageRoute)->toHaveKey('parameters'); // Dieser Test wird wahrscheinlich fehlschlagen
|
||||
}
|
||||
});
|
||||
|
||||
test('compiles dynamic routes with parameter names', function () {
|
||||
$this->discoveryVisitor->onScanStart();
|
||||
// UnifiedRouteVisitor benötigt ClassName und FilePath Value Objects
|
||||
$className = \App\Framework\Core\ValueObjects\ClassName::fromString(TestDynamicController::class);
|
||||
$filePath = \App\Framework\Filesystem\FilePath::create('test-file.php');
|
||||
$reflection = new \App\Framework\Reflection\WrappedReflectionClass(new \ReflectionClass(TestDynamicController::class));
|
||||
|
||||
$this->discoveryVisitor->visitClass($className, $filePath, $reflection);
|
||||
|
||||
$routes = $this->discoveryVisitor->getResults();
|
||||
$compiledRoutes = $this->routeCompiler->compile($routes);
|
||||
|
||||
// Prüfe GET routes
|
||||
expect($compiledRoutes)->toHaveKey('GET');
|
||||
expect($compiledRoutes['GET'])->toHaveKey('dynamic');
|
||||
|
||||
$dynamicRoutes = $compiledRoutes['GET']['dynamic'];
|
||||
expect($dynamicRoutes)->toBeArray();
|
||||
expect(count($dynamicRoutes))->toBeGreaterThan(0);
|
||||
|
||||
// Suche Image Route in compilierten Routes
|
||||
$imageRoute = null;
|
||||
foreach ($dynamicRoutes as $route) {
|
||||
if ($route instanceof DynamicRoute && $route->path === '/images/{filename}') {
|
||||
$imageRoute = $route;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
expect($imageRoute)->not->toBeNull();
|
||||
expect($imageRoute)->toBeInstanceOf(DynamicRoute::class);
|
||||
|
||||
// Prüfe Parameter Names
|
||||
expect($imageRoute->paramNames)->toBe(['filename']);
|
||||
|
||||
// Prüfe compiled regex
|
||||
expect($imageRoute->regex)->toBeString();
|
||||
expect($imageRoute->regex)->toMatch('/^~.*\/images\/.*\$~/'); // Regex für /images/{filename}
|
||||
|
||||
// Prüfe Parameter Details
|
||||
error_log('Compiled Image Route Parameters: ' . json_encode($imageRoute->parameters));
|
||||
|
||||
if (! empty($imageRoute->parameters)) {
|
||||
$filenameParam = null;
|
||||
foreach ($imageRoute->parameters as $param) {
|
||||
if ($param['name'] === 'filename') {
|
||||
$filenameParam = $param;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($filenameParam) {
|
||||
expect($filenameParam['type'])->not->toBeNull(); // Das sollte nicht null sein!
|
||||
expect($filenameParam['type'])->toBe('string');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('handles multiple parameter types correctly', function () {
|
||||
$this->discoveryVisitor->onScanStart();
|
||||
// UnifiedRouteVisitor benötigt ClassName und FilePath Value Objects
|
||||
$className = \App\Framework\Core\ValueObjects\ClassName::fromString(TestDynamicController::class);
|
||||
$filePath = \App\Framework\Filesystem\FilePath::create('test-file.php');
|
||||
$reflection = new \App\Framework\Reflection\WrappedReflectionClass(new \ReflectionClass(TestDynamicController::class));
|
||||
|
||||
$this->discoveryVisitor->visitClass($className, $filePath, $reflection);
|
||||
|
||||
$routes = $this->discoveryVisitor->getResults();
|
||||
|
||||
// Test verschiedene Parameter-Typen
|
||||
$userPostRoute = null;
|
||||
foreach ($routes as $route) {
|
||||
if ($route['path'] === '/user/{userId}/post/{postId}') {
|
||||
$userPostRoute = $route;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($userPostRoute['parameters'])) {
|
||||
$parameters = $userPostRoute['parameters'];
|
||||
|
||||
// Suche nach userId (int) und postId (string) Parametern
|
||||
$userIdParam = null;
|
||||
$postIdParam = null;
|
||||
foreach ($parameters as $param) {
|
||||
if ($param['name'] === 'userId') {
|
||||
$userIdParam = $param;
|
||||
} elseif ($param['name'] === 'postId') {
|
||||
$postIdParam = $param;
|
||||
}
|
||||
}
|
||||
|
||||
if ($userIdParam) {
|
||||
expect($userIdParam['type'])->toBe('int');
|
||||
expect($userIdParam['isBuiltin'])->toBeTrue();
|
||||
}
|
||||
|
||||
if ($postIdParam) {
|
||||
expect($postIdParam['type'])->toBe('string');
|
||||
expect($postIdParam['isBuiltin'])->toBeTrue();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('handles optional parameters correctly', function () {
|
||||
$this->discoveryVisitor->onScanStart();
|
||||
// UnifiedRouteVisitor benötigt ClassName und FilePath Value Objects
|
||||
$className = \App\Framework\Core\ValueObjects\ClassName::fromString(TestDynamicController::class);
|
||||
$filePath = \App\Framework\Filesystem\FilePath::create('test-file.php');
|
||||
$reflection = new \App\Framework\Reflection\WrappedReflectionClass(new \ReflectionClass(TestDynamicController::class));
|
||||
|
||||
$this->discoveryVisitor->visitClass($className, $filePath, $reflection);
|
||||
|
||||
$routes = $this->discoveryVisitor->getResults();
|
||||
|
||||
// Test optionale Parameter
|
||||
$searchRoute = null;
|
||||
foreach ($routes as $route) {
|
||||
if ($route['path'] === '/api/search/{query?}') {
|
||||
$searchRoute = $route;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($searchRoute['parameters'])) {
|
||||
$parameters = $searchRoute['parameters'];
|
||||
|
||||
$queryParam = null;
|
||||
foreach ($parameters as $param) {
|
||||
if ($param['name'] === 'query') {
|
||||
$queryParam = $param;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($queryParam) {
|
||||
expect($queryParam['type'])->toBe('string');
|
||||
expect($queryParam['isOptional'])->toBeTrue();
|
||||
expect($queryParam['hasDefault'])->toBeTrue();
|
||||
expect($queryParam['default'])->toBeNull();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Dynamic Route Parameter Processing Debug', function () {
|
||||
test('shows current parameter extraction workflow', function () {
|
||||
$discoveryVisitor = new UnifiedRouteVisitor();
|
||||
$discoveryVisitor->onScanStart();
|
||||
$className = \App\Framework\Core\ValueObjects\ClassName::fromString(TestDynamicController::class);
|
||||
$filePath = \App\Framework\Filesystem\FilePath::create('test-file.php');
|
||||
$reflection = new \App\Framework\Reflection\WrappedReflectionClass(new \ReflectionClass(TestDynamicController::class));
|
||||
|
||||
$discoveryVisitor->visitClass($className, $filePath, $reflection);
|
||||
|
||||
$routes = $discoveryVisitor->getResults();
|
||||
|
||||
// Debug: Zeige alle gefundenen Routes
|
||||
error_log('=== All discovered routes ===');
|
||||
foreach ($routes as $i => $route) {
|
||||
error_log("Route {$i}: " . json_encode([
|
||||
'path' => $route['path'],
|
||||
'controller' => $route['controller'],
|
||||
'action' => $route['action'],
|
||||
'has_parameters' => isset($route['parameters']),
|
||||
'parameter_count' => isset($route['parameters']) ? count($route['parameters']) : 0,
|
||||
]));
|
||||
|
||||
if (isset($route['parameters'])) {
|
||||
foreach ($route['parameters'] as $j => $param) {
|
||||
error_log(" Parameter {$j}: " . json_encode($param));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Debug: Zeige RouteDiscoveryVisitor interne Struktur
|
||||
error_log('=== RouteDiscoveryVisitor internals ===');
|
||||
// Wir können nicht auf private Properties zugreifen, aber wir können testen
|
||||
|
||||
expect(true)->toBeTrue(); // Placeholder - der Test ist für Debug-Zwecke
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user