coreAliasPathsWithDifferentTargets(); $this->assertNotSame([], $aliases, 'Expected at least one core route alias with path != target.'); $scanTargets = ['core', 'pages', 'templates', 'modules']; $extensions = ['php', 'phtml']; $violations = []; foreach ($this->runtimeSourceFiles($scanTargets, $extensions) as $relativePath) { $content = $this->readProjectFile($relativePath); foreach ($aliases as $aliasPath) { $quotedAlias = preg_quote($aliasPath, '#'); if (preg_match("#(?:lurl|Request::withLocale|Router::redirect)\\(\\s*['\"]{$quotedAlias}\\?#", $content) === 1) { $violations[] = $relativePath . " uses alias '{$aliasPath}' with query string."; } } } sort($violations); $this->assertSame([], $violations, "Alias+query routing anti-pattern found:\n" . implode("\n", $violations)); } public function testAccessControlUsesConcreteLoginTargetPathForReturnToRedirect(): void { $content = $this->readProjectFile('core/Http/AccessControl.php'); $this->assertStringContainsString( "Request::withLocale('auth/login', \$locale)", $content ); $this->assertStringNotContainsString( "Request::withLocale('login', \$locale)", $content ); } /** * @return list */ private function coreAliasPathsWithDifferentTargets(): array { $routesFile = $this->projectRootPath() . '/config/routes.php'; $this->assertFileExists($routesFile, 'Missing config/routes.php'); $routes = require $routesFile; $this->assertIsArray($routes, 'config/routes.php must return an array'); $aliases = []; foreach ($routes as $entry) { if (!is_array($entry)) { continue; } $path = trim((string) ($entry['path'] ?? '')); $target = trim((string) ($entry['target'] ?? '')); if ($path === '' || $target === '' || $path === $target) { continue; } $aliases[] = $path; } $aliases = array_values(array_unique($aliases)); sort($aliases); return $aliases; } /** * @param list $scanTargets * @param list $extensions * @return list */ private function runtimeSourceFiles(array $scanTargets, array $extensions): array { $root = $this->projectRootPath(); $files = []; foreach ($scanTargets as $target) { $fullPath = $root . '/' . $target; if (!is_dir($fullPath)) { continue; } $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($fullPath, \FilesystemIterator::SKIP_DOTS) ); foreach ($iterator as $file) { if (!$file->isFile()) { continue; } $extension = strtolower((string) $file->getExtension()); if (!in_array($extension, $extensions, true)) { continue; } $files[] = str_replace($root . '/', '', $file->getPathname()); } } $files = array_values(array_unique($files)); sort($files); return $files; } }