presseportale/tests/Feature/Web/SitemapRobotsTest.php
Kevin Adametz c2d22c6d65 SEO: host-aware sitemap.xml + dynamische robots.txt je Domain
Sitemap pro Host (1h-Cache): Hub listet Landing + Rechts-/Info-Seiten,
Spokes zusaetzlich Kategorien (lokalisierte Slugs), oeffentliche
Newsrooms und alle im Archiv sichtbaren PMs des Portals (explizit ohne
PortalScope, forPortalValues). Suche und Marketing-Platzhalterseiten
bleiben draussen. Statische public/robots.txt entfernt (haette die
Route verschattet); robots.txt jetzt dynamisch mit Sitemap-Verweis
und Disallow fuer /admin, /login, /register, Suche.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 12:34:12 +00:00

88 lines
3.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
use App\Enums\Portal;
use App\Models\Category;
use App\Models\Company;
use App\Models\PressRelease;
use Tests\TestCase;
test('robots.txt is served per host with the matching sitemap reference', function () {
/** @var TestCase $this */
$this->get('https://presseecho.test/robots.txt')
->assertSuccessful()
->assertHeader('Content-Type', 'text/plain; charset=UTF-8')
->assertSee('Disallow: /admin', false)
->assertSee('Sitemap: https://presseecho.test/sitemap.xml', false);
$this->get('https://pressekonto.test/robots.txt')
->assertSuccessful()
->assertSee('Sitemap: https://pressekonto.test/sitemap.xml', false);
});
test('the spoke sitemap lists static pages, categories, newsrooms and archive releases of its portal', function () {
/** @var TestCase $this */
$category = Category::factory()->create(['portal' => Portal::Presseecho, 'is_active' => true]);
$category->translations()->create(['locale' => 'de', 'name' => 'Technologie', 'slug' => 'technologie']);
$company = Company::factory()->presseecho()->create(['is_active' => true]);
PressRelease::factory()
->published()
->forPortal(Portal::Presseecho)
->for($category)
->for($company)
->create(['slug' => 'ki-report', 'published_at' => now()->subDay()]);
// Fremd-Portal-PM darf nicht in der presseecho-Sitemap auftauchen.
$bpCategory = Category::factory()->create(['portal' => Portal::Businessportal24]);
PressRelease::factory()
->published()
->forPortal(Portal::Businessportal24)
->for($bpCategory)
->for(Company::factory()->businessportal24()->create())
->create(['slug' => 'bp24-only', 'published_at' => now()->subDay()]);
$response = $this->get('https://presseecho.test/sitemap.xml')->assertSuccessful();
expect($response->headers->get('Content-Type'))->toContain('application/xml');
expect($response->getContent())
->toContain('<loc>https://presseecho.test/de</loc>')
->toContain('<loc>https://presseecho.test/de/preise</loc>')
->toContain('<loc>https://presseecho.test/de/impressum</loc>')
->toContain('<loc>https://presseecho.test/de/category/technologie</loc>')
->toContain('<loc>https://presseecho.test/de/newsroom/'.$company->slug.'</loc>')
->toContain('<loc>https://presseecho.test/de/press-release/ki-report</loc>')
->not->toContain('bp24-only')
// Suche und Marketing-Platzhalterseiten bleiben draußen.
->not->toContain('/de/suche')
->not->toContain('/de/team');
});
test('the hub sitemap lists the landing and legal pages but no archive content', function () {
/** @var TestCase $this */
PressRelease::factory()
->published()
->forPortal(Portal::Presseecho)
->for(Category::factory()->create(['portal' => Portal::Presseecho]))
->for(Company::factory()->presseecho()->create())
->create(['slug' => 'nicht-im-hub', 'published_at' => now()->subDay()]);
$response = $this->get('https://pressekonto.test/sitemap.xml')->assertSuccessful();
expect($response->getContent())
->toContain('<loc>https://pressekonto.test/</loc>')
->toContain('<loc>https://pressekonto.test/de/impressum</loc>')
->toContain('<loc>https://pressekonto.test/de/kuendigung</loc>')
->not->toContain('press-release')
->not->toContain('newsroom');
});
test('marketing pages carry brand-aware titles instead of the hardcoded legacy brand', function () {
/** @var TestCase $this */
$response = $this->get('https://presseecho.test/de/team')->assertSuccessful();
expect($response->getContent())
->toContain('<title>Unser Team – presseecho</title>')
->not->toContain('Business Portal 24');
});