Files
breadcrumb-the-shire/tests/Architecture/ModuleSessionKeyPrefixContractTest.php
fs be8bf496cb test: add architecture contract tests for layering, sessions, and asset versioning
New contracts enforce repository layer isolation, no HTML in services,
no DB calls in views, module session key prefixes, and asset versioning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:15:41 +01:00

65 lines
2.2 KiB
PHP

<?php
namespace MintyPHP\Tests\Architecture;
/**
* Module code must prefix session keys with "module.<id>." to prevent
* collisions between modules and with core session state.
*/
final class ModuleSessionKeyPrefixContractTest extends AbstractModuleStructureContractTestCase
{
/**
* Pattern matches direct $_SESSION access with a string key that does NOT
* start with "module.".
*/
private const SESSION_ACCESS_PATTERN = '/\$_SESSION\s*\[\s*[\'"](?!module\.)/';
public function testModulePhpFilesUseSessionPrefix(): void
{
$modulesDir = realpath(__DIR__ . '/../../modules');
self::assertNotFalse($modulesDir);
$violations = [];
foreach (self::$modules as $module) {
$moduleId = $module['id'];
foreach (['lib', 'pages'] as $subdir) {
$dir = $module['path'] . '/' . $subdir;
if (!is_dir($dir)) {
continue;
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
/** @var \SplFileInfo $file */
$ext = $file->getExtension();
if ($ext !== 'php' && $ext !== 'phtml') {
continue;
}
$content = file_get_contents($file->getPathname());
if ($content === false) {
continue;
}
if (preg_match(self::SESSION_ACCESS_PATTERN, $content)) {
$relativePath = 'modules/' . $moduleId . '/' . $subdir . '/' . str_replace($dir . '/', '', $file->getPathname());
$violations[] = $relativePath . " (module '{$moduleId}') — session keys must start with 'module.{$moduleId}.'";
}
}
}
}
self::assertSame(
[],
$violations,
"Module session keys must be prefixed with 'module.<id>.':\n" . implode("\n", $violations)
);
}
}