migrate(); $this->settings = new SettingRepository($db); $this->checker = new DomainChecker($this->settings); } /** * @param array $extra * @return array */ private function domain(string $baseUrl, array $extra = []): array { return ['id' => 1, 'base_url' => $baseUrl, 'host' => '', 'is_default' => 0] + $extra; } public function testSecretIsStableAcrossCalls(): void { $first = $this->settings->secret(); self::assertSame($first, $this->settings->secret()); self::assertGreaterThanOrEqual(32, strlen($first)); } public function testResultHasTheExpectedShape(): void { $result = $this->checker->check($this->domain('http://127.0.0.1:1')); self::assertArrayHasKey('status', $result); self::assertArrayHasKey('summary', $result); self::assertArrayHasKey('checks', $result); self::assertArrayHasKey('hint', $result); self::assertContains($result['status'], [DomainChecker::OK, DomainChecker::WARNING, DomainChecker::ERROR]); foreach ($result['checks'] as $check) { self::assertArrayHasKey('label', $check); self::assertArrayHasKey('status', $check); self::assertArrayHasKey('text', $check); self::assertNotSame('', $check['text']); } } public function testIpAddressNeedsNoDnsEntry(): void { $result = $this->checker->check($this->domain('http://127.0.0.1:1')); self::assertSame('DNS', $result['checks'][0]['label']); self::assertSame(DomainChecker::OK, $result['checks'][0]['status']); self::assertStringContainsString('kein DNS-Eintrag', $result['checks'][0]['text']); } public function testUnreachableDomainIsReportedAsError(): void { // Auf Port 1 lauscht nichts. $result = $this->checker->check($this->domain('http://127.0.0.1:1')); self::assertSame(DomainChecker::ERROR, $result['status']); self::assertStringContainsString('nicht auf diese Installation', $result['summary']); self::assertNotNull($result['hint'], 'Bei Misserfolg muss der Hairpinning-Hinweis erscheinen.'); } public function testNonResolvableHostFails(): void { // ".invalid" ist laut RFC 2606 reserviert und existiert nie. $result = $this->checker->check($this->domain('https://gibt-es-nicht.invalid')); self::assertSame(DomainChecker::ERROR, $result['status']); // Je nach Resolver scheitert schon DNS oder erst der Abruf - // in beiden Faellen darf die Domain nicht als in Ordnung gelten. $labels = array_column($result['checks'], 'label'); self::assertContains('DNS', $labels); } public function testPortIsStrippedBeforeDnsLookup(): void { // Enthielte der Hostname noch den Port, waere die Auflösung // zwangslaeufig fehlgeschlagen. $result = $this->checker->check($this->domain('http://localhost:1')); self::assertSame('DNS', $result['checks'][0]['label']); self::assertSame(DomainChecker::OK, $result['checks'][0]['status'], $result['checks'][0]['text']); self::assertStringContainsString('localhost', $result['checks'][0]['text']); self::assertStringNotContainsString('localhost:1', $result['checks'][0]['text']); } public function testCheckDoesNotThrowOnOddInput(): void { foreach ([ 'http://127.0.0.1:1', 'https://gibt-es-nicht.invalid', 'http://localhost:1/unterverzeichnis', ] as $baseUrl) { $result = $this->checker->check($this->domain($baseUrl)); self::assertIsArray($result, $baseUrl); self::assertNotSame('', $result['summary'], $baseUrl); } } }