$this->get('/')->assertSuccessful()); it('immobilien page loads', fn () => $this->get('/immobilien')->assertSuccessful()); it('immobilien expose loads', fn () => $this->get('/immobilien/azizi-creek-views-4')->assertSuccessful()); it('marken page loads', fn () => $this->get('/marken')->assertSuccessful()); it('magazin list loads', fn () => $this->get('/magazin')->assertSuccessful()); // Offline seit 08.10.2026: Beiträge aus der früheren Ausrichtung liefern 404. const OFFLINE_ARTICLES = ['supply-chain-management-vertragssicherheit', 'local-for-local-regionaler-moebelhandel']; it('every magazin article loads under its slug', function (string $slug) { $response = $this->get('/magazin/'.$slug); in_array($slug, OFFLINE_ARTICLES, true) ? $response->assertNotFound() : $response->assertSuccessful(); })->with(array_values(App\Models\CmsArticle::LEGACY_ID_TO_SLUG)); // Die alten numerischen URLs bleiben erreichbar – jetzt ueber eine 301 auf den Slug. it('every old numeric magazin URL still reaches its article', function (int $id) { $slug = App\Models\CmsArticle::slugForLegacyId($id); $this->get('/magazin/'.$id)->assertRedirect('/magazin/'.$slug); if (! in_array($slug, OFFLINE_ARTICLES, true)) { $this->get('/magazin/'.$slug)->assertSuccessful(); } })->with(array_keys(App\Models\CmsArticle::LEGACY_ID_TO_SLUG)); it('about page loads', fn () => $this->get('/about')->assertSuccessful()); it('contact page loads', fn () => $this->get('/contact')->assertSuccessful()); it('faq page loads', fn () => $this->get('/faq')->assertSuccessful()); // ======================================== // Redirects // ======================================== it('interior redirects to marken', fn () => $this->get('/interior')->assertRedirect('/marken')); it('partner redirects to marken', fn () => $this->get('/partner')->assertRedirect('/marken')); it('netzwerk redirects to marken', fn () => $this->get('/netzwerk')->assertRedirect('/marken')); it('ecosystem redirects to partner', fn () => $this->get('/ecosystem')->assertRedirect('/partner')); // ======================================== // Dev-Seiten // ======================================== it('dev sitemap loads', fn () => $this->get('/dev/sitemap')->assertSuccessful()); // ======================================== // 404 für ungültige Routen // ======================================== it('invalid immobilien slug returns 404', fn () => $this->get('/immobilien/nonexistent')->assertNotFound()); // ======================================== // Announcement Bar auf allen Seiten // ======================================== it('announcement bar visible on homepage', fn () => $this->get('/')->assertSee('B2in Interior')); it('announcement bar visible on about', fn () => $this->get('/about')->assertSee('B2in Interior')); // ======================================== // Kritische Inhalte vorhanden // ======================================== it('homepage has navigation', fn () => $this->get('/')->assertSee('Immobilien')->assertSee('Netzwerk')->assertSee('Magazin')); it('immobilien has all five sections', function () { $this->get('/immobilien') ->assertSee('Warum Dubai für Investoren relevant bleibt') ->assertSee('Der Kaufprozess mit B2in') ->assertSee('Passt Dubai zu Ihrer Investmentstrategie?') ->assertSee('Einrichtung mitdenken') ->assertSee('Investoren'); }); it('marken page lists the core brands', fn () => $this->get('/marken')->assertSee('CABINET')->assertSee('Febrü', false)); it('magazin has all published articles across both worlds', function () { $this->get('/magazin') ->assertSee('Nach Maß statt von der Stange') ->assertSee('Küche planen') ->assertDontSee('Supply-Chain') ->assertDontSee('Local for Local'); $this->get('/immobilien/magazin') ->assertSee('Escrow-System') ->assertSee('Al Jaddaf') ->assertSee('Turnkey'); }); // ======================================== // Verwaiste Seiten // ======================================== // // /service und /portfolio lieferten Status 500, weil ihre Content-Sektionen nicht mehr // existieren. Sie sind oeffentlich erreichbar und damit auch fuer Crawler sichtbar. it('service page no longer errors', fn () => $this->get('/service')->assertRedirect('/marken')); it('portfolio page no longer errors', fn () => $this->get('/portfolio')->assertRedirect('/immobilien')); // ======================================== // Inhalte auf den Interior-Auftritt umgestellt // ======================================== it('no longer sells dubai investments in the faq', function () { $response = $this->get('/faq')->assertSuccessful(); $response->assertDontSee('Dubai') ->assertSee('Für Ihr Zuhause', false) ->assertSee('Für Projekte und Objekte'); }); it('tells the interior story on the about page', function () { $this->get('/about') ->assertSuccessful() ->assertDontSee('Dubai') ->assertDontSee('digitale Werkzeuge') ->assertSee('Beratung statt Verkauf') ->assertSee('Regional verwurzelt'); }); it('offers interior subjects in the contact form', function () { $this->get('/contact') ->assertSuccessful() ->assertSee('Beratungstermin') ->assertSee('Maßanfertigung für mein Zuhause', false) ->assertSee('Küchenplanung', false); }); // ======================================== // Vorschau-Instanzen dürfen nicht indexiert werden // ======================================== it('allows indexing in production', function () { config()->set('app.indexable', true); $this->get('/') ->assertSuccessful() ->assertDontSee('noindex', false); }); it('blocks indexing on a preview instance', function () { config()->set('app.indexable', false); $this->get('/') ->assertSuccessful() ->assertSee('', false); }); it('defaults to noindex outside production', function () { // Gegenprobe zur Konfiguration selbst: ohne expliziten Schalter entscheidet APP_ENV. expect((bool) (env('SITE_INDEXABLE', env('APP_ENV', 'production') === 'production')))->toBeFalse(); });