Files
KantSites/tests/SiteOriginCommandTest.php
T
kantarciandClaude Fable 5.1 7eb462ac7b Redirect the other www spelling to SITE_ORIGIN, hold roles to the role help and fix the audit findings
SITE_ORIGIN alone decides whether the site is www or not: CanonicalHostSubscriber
sends the other spelling there with 301, cms:site:origin writes the setting, the
system screen shows it. The roles now match the role help (editor: drafts,
publisher: live content, admin: design, settings, users, system). The installer no
longer reopens on an unreachable database, the session cookie follows ADMIN_PATH,
percent-encoded credentials no longer break the container, consent only accepts
same-site decisions, JSON-LD is HTML-safe, own CSS stays in its block, plus the
editor, updater, download and public-output findings from the full review
(ADR 099, ADR 100).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 20:15:20 +02:00

75 lines
3.1 KiB
PHP

<?php
namespace App\Tests;
use App\Command\SiteOriginCommand;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Dotenv\Dotenv;
final class SiteOriginCommandTest extends TestCase
{
private string $root;
protected function setUp(): void
{
$this->root = sys_get_temp_dir().'/kant-origin-'.bin2hex(random_bytes(6));
mkdir($this->root);
file_put_contents($this->root.'/.env', "APP_ENV=\"prod\"\nSITE_ORIGIN=\"https://alt.example\"\nAPP_SECRET=\"bleibt\"\n");
}
protected function tearDown(): void
{
foreach (glob($this->root.'/.env*') ?: [] as $file) {
unlink($file);
}
rmdir($this->root);
}
/** @return iterable<string, array{string, ?string}> */
public static function addresses(): iterable
{
yield 'mit www' => ['https://www.meine-firma.de', 'https://www.meine-firma.de'];
yield 'ohne www' => ['https://meine-firma.de', 'https://meine-firma.de'];
yield 'Schraegstrich und Grossschreibung werden bereinigt' => [' HTTPS://WWW.Meine-Firma.DE/ ', 'https://www.meine-firma.de'];
yield 'ein Port bleibt' => ['http://127.0.0.1:8080', 'http://127.0.0.1:8080'];
yield 'ohne Schema' => ['meine-firma.de', null];
yield 'mit Pfad' => ['https://meine-firma.de/start', null];
yield 'mit Abfrage' => ['https://meine-firma.de/?x=1', null];
yield 'mit Zugangsdaten' => ['https://user:pass@meine-firma.de', null];
yield 'falsches Schema' => ['ftp://meine-firma.de', null];
}
#[DataProvider('addresses')]
public function testOnlySchemeAndHostAreAccepted(string $input, ?string $expected): void
{
if (null === $expected) {
$this->expectException(\InvalidArgumentException::class);
}
self::assertSame($expected, SiteOriginCommand::normalize($input));
}
public function testTheCommandShowsAndWritesTheAddress(): void
{
$tester = new CommandTester(new SiteOriginCommand($this->root, 'https://alt.example'));
self::assertSame(0, $tester->execute([]));
self::assertStringContainsString('https://alt.example', $tester->getDisplay());
self::assertSame('https://alt.example', $this->values()['SITE_ORIGIN'], 'Anzeigen schreibt nichts.');
self::assertSame(0, $tester->execute(['adresse' => 'https://www.neu.example/']));
self::assertStringContainsString('ohne www leitet dorthin um', $tester->getDisplay());
self::assertSame('https://www.neu.example', $this->values()['SITE_ORIGIN']);
self::assertSame('bleibt', $this->values()['APP_SECRET'], 'Die uebrigen Einstellungen bleiben erhalten.');
self::assertSame(1, $tester->execute(['adresse' => 'neu.example']));
self::assertStringContainsString('beginnt mit https://', $tester->getDisplay());
self::assertSame('https://www.neu.example', $this->values()['SITE_ORIGIN'], 'Eine abgelehnte Adresse aendert nichts.');
}
private function values(): array
{
return (new Dotenv())->parse((string) file_get_contents($this->root.'/.env'));
}
}