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>
This commit is contained in:
2026-03-22 14:15:41 +01:00
parent 555199b217
commit be8bf496cb
5 changed files with 428 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
<?php
namespace MintyPHP\Tests\Architecture;
use PHPUnit\Framework\TestCase;
/**
* Views (.phtml) must be pure rendering — no database calls allowed.
* All data must be prepared in actions and passed via view variables.
*/
class ViewLayerNoDbCallsContractTest extends TestCase
{
use ProjectFileAssertionSupport;
/** @var list<string> */
private const DB_PATTERNS = [
'/->query\s*\(/',
'/->prepare\s*\(/',
'/->execute\s*\(/',
'/->fetch\s*\(/',
'/->fetchAll\s*\(/',
'/->fetchColumn\s*\(/',
'/\bnew\s+PDO\b/',
'/\$pdo\b/',
];
public function testCorePagesViewsContainNoDbCalls(): void
{
$this->assertNoDbCallsInViews('pages');
}
public function testModuleViewsContainNoDbCalls(): void
{
$root = $this->projectRootPath();
$modulesDir = $root . '/modules';
if (!is_dir($modulesDir)) {
self::markTestSkipped('modules/ directory missing.');
}
foreach (scandir($modulesDir) ?: [] as $entry) {
if ($entry === '.' || $entry === '..' || !is_dir($modulesDir . '/' . $entry)) {
continue;
}
$pagesRel = 'modules/' . $entry . '/pages';
if (is_dir($root . '/' . $pagesRel)) {
$this->assertNoDbCallsInViews($pagesRel);
}
}
}
public function testTemplatesContainNoDbCalls(): void
{
$this->assertNoDbCallsInViews('templates');
}
private function assertNoDbCallsInViews(string $relativeDirectory): void
{
$allViolations = [];
foreach (self::DB_PATTERNS as $pattern) {
$hits = $this->findPatternMatchesInFiles($relativeDirectory, $pattern, ['phtml']);
foreach ($hits as $file) {
$allViolations[$file] = true;
}
}
$violations = array_keys($allViolations);
sort($violations);
self::assertSame(
[],
$violations,
"Views must not contain database calls. Violations found:\n" . implode("\n", $violations)
);
}
}