client = static::createClient(); $this->registry = new LandingRegistry(); } private function html(string $path): string { $this->client->request('GET', $path); return $this->client->getResponse()->getContent(); } public function testEveryLandingRenders(): void { foreach ($this->registry->all() as $slug => $page) { $html = $this->html('/' . $slug); self::assertSame(200, $this->client->getResponse()->getStatusCode(), "صفحهٔ «{$slug}» باز نشد"); self::assertStringContainsString('

' . $page->h1 . '

', $html); self::assertStringContainsString('' . $page->metaTitle . '', $html); self::assertStringContainsString('content="' . $page->metaDescription . '"', $html); } } public function testCanonicalPointsAtTheSamePage(): void { foreach (array_keys($this->registry->all()) as $slug) { $html = $this->html('/' . $slug); self::assertMatchesRegularExpression( '~~u', $html, "canonical صفحهٔ «{$slug}» به خودش اشاره نمی‌کند", ); } } public function testUnknownSlugIsNotFound(): void { $this->client->request('GET', '/یک-اسلاگ-که-وجود-ندارد'); self::assertSame(404, $this->client->getResponse()->getStatusCode()); } /** روت catch-all نباید صفحهٔ اصلی را بخورد. */ public function testHomePageStillWorks(): void { $html = $this->html('/'); self::assertSame(200, $this->client->getResponse()->getStatusCode()); self::assertStringContainsString('هوشمند، سریع و', $html); } public function testExistingRoutesAreNotShadowed(): void { foreach (['/sitemap.xml', '/health'] as $path) { $this->client->request('GET', $path); self::assertSame(200, $this->client->getResponse()->getStatusCode(), "{$path} گرفته شد"); } } public function testSitemapListsHomeAndEveryLanding(): void { $xml = $this->html('/sitemap.xml'); $doc = new \SimpleXMLElement($xml); self::assertCount(8, $doc->url, 'sitemap باید خانه و هفت لندینگ را داشته باشد'); foreach (array_keys($this->registry->all()) as $slug) { self::assertStringContainsString(rawurlencode($slug), $xml, "«{$slug}» در sitemap نیست"); } } /** بدون لینک داخلی، صفحات فقط از sitemap دیده می‌شوند. */ public function testFooterLinksToEveryLandingOnEveryPage(): void { foreach (['/', '/' . LandingRegistry::CRM] as $path) { $html = $this->html($path); foreach (array_keys($this->registry->all()) as $slug) { self::assertStringContainsString('href="/' . $slug . '"', $html, "لینک «{$slug}» در {$path} نیست"); } } } public function testStructuredDataIsValidJson(): void { foreach (array_keys($this->registry->all()) as $slug) { $html = $this->html('/' . $slug); preg_match('~~s', $html, $m); self::assertNotEmpty($m, "صفحهٔ «{$slug}» بلاک JSON-LD ندارد"); $data = json_decode(html_entity_decode($m[1]), true, flags: JSON_THROW_ON_ERROR); $types = array_column($data['@graph'], '@type'); self::assertContains('SoftwareApplication', $types); self::assertContains('BreadcrumbList', $types); self::assertContains('FAQPage', $types); } } /** تم مشترک است، پس همان CSS صفحهٔ اصلی باید بارگذاری شود. */ public function testLandingUsesTheHomepageTheme(): void { preg_match_all('~href="(/build/[^"]+\.css)"~', $this->html('/'), $home); preg_match_all('~href="(/build/[^"]+\.css)"~', $this->html('/' . LandingRegistry::BEAUTY), $landing); self::assertNotEmpty($home[1]); self::assertSame($home[1], $landing[1], 'لندینگ باید همان CSS صفحهٔ اصلی را بارگذاری کند'); } }