Steuerkram/tests/97_InlineStyleBudgetTest.php

68 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
/**
* Test 97: Inline-Style-Budget für src/Views (Fix #160)
*
* Zählt alle style="-Vorkommen unter src/Views und schlägt fehl, wenn die
* Zahl über dem Budget liegt. Das Budget wird mit jedem weiteren
* Umsetzungsschritt aus Issue #160 gesenkt und verhindert, dass neue Views
* den Zähler wieder hochtreiben.
*
* Zusätzlich: keine onclick=/onchange=/oninput=-Attribute mehr in src/Views
* (Vorbedingung für eine CSP ohne unsafe-inline, siehe Issue #160).
*/
class InlineStyleBudgetTest extends TestCase
{
protected string $testName = 'Test 97: Inline-Style-Budget für src/Views';
/** Aktueller Stand nach Fix #160 (vorher: 1024). Bei weiteren Umsetzungsschritten senken. */
private const STYLE_BUDGET = 900;
public function run(): void
{
$viewDir = __DIR__ . '/../src/Views';
$files = $this->phpFilesIn($viewDir);
$this->assertGreaterThan(0, count($files), 'src/Views enthält PHP-Dateien');
$styleCount = 0;
$handlerFiles = [];
foreach ($files as $file) {
$content = file_get_contents($file);
if ($content === false) {
continue;
}
$styleCount += substr_count($content, 'style="');
if (preg_match('/\bon(click|change|input)=/', $content)) {
$handlerFiles[] = substr($file, strlen($viewDir) + 1);
}
}
$this->assert(
$styleCount <= self::STYLE_BUDGET,
"style=\"-Vorkommen unter src/Views bleiben im Budget (erhalten: $styleCount, Budget: " . self::STYLE_BUDGET . ')'
);
$this->assert(
$handlerFiles === [],
'Keine onclick=/onchange=/oninput=-Attribute mehr in src/Views (gefunden in: ' . implode(', ', $handlerFiles) . ')'
);
}
/** @return string[] */
private function phpFilesIn(string $dir): array
{
$files = [];
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS));
foreach ($it as $fileInfo) {
if ($fileInfo->isFile() && $fileInfo->getExtension() === 'php') {
$files[] = $fileInfo->getPathname();
}
}
return $files;
}
}