seed(\Database\Seeders\CmsBrandSeeder::class); }); // ======================================== // Aufbau laut unterseite_marke.md // ======================================== it('renders the page sections in the order from the spec', function () { $html = markenBody($this->get('/marken')->assertSuccessful()->getContent()); $order = [ 'Unsere Marken', // 1. Seitenkopf 'CABINET', // 2. Kernmarken 'Rotpunkt Küchen', 'Febrü', 'unser Netzwerk', // 3. Partnernetzwerk 'Markenwelt wächst', // 4. Marken werden ergänzt 'Lernen Sie unsere', // 5. Abschluss-CTA ]; $last = -1; foreach ($order as $needle) { $pos = strpos($html, $needle); expect($pos)->not->toBeFalse("Nicht gefunden: {$needle}"); expect($pos)->toBeGreaterThan($last, "Falsche Reihenfolge bei: {$needle}"); $last = $pos; } }); it('shows no breadcrumb in the page hero (07.10.2026)', function () { $this->get('/marken') ->assertSuccessful() ->assertDontSee('aria-label="Breadcrumb"', false); }); it('carries the title and description from the spec', function () { $this->get('/marken') ->assertSuccessful() ->assertSee('Unsere Marken – CABINET, Rotpunkt Küchen, Febrü & Otterpohl | B2in Interior', false) ->assertSee('Ausgewählte Hersteller statt beliebiger Kataloge', false); }); // ======================================== // Marken-Abschnitt // ======================================== it('shows the longer text and the three highlights per brand', function () { $this->get('/marken') ->assertSuccessful() ->assertSee('Wo Standardmaße an ihre Grenzen stoßen', false) ->assertSee('Millimetergenaue Planung') ->assertSee('Individuelle Fronten und Innenausstattung') ->assertSee('Persönliche Beratung vor Ort', false); }); it('links every brand to its detail page', function () { $this->get('/marken') ->assertSuccessful() ->assertSee('/marken/cabinet') ->assertSee('/marken/rotpunkt') ->assertSee('/marken/februe'); }); it('keeps the brand order from the CMS', function () { $headings = function (string $html): array { preg_match_all('#wire:key="brand-([a-z-]+)"#', $html, $matches); return $matches[1]; }; expect($headings($this->get('/marken')->assertSuccessful()->getContent())) ->toBe(['cabinet', 'rotpunkt', 'februe', 'tischlerei']); CmsBrand::where('slug', 'februe')->update(['order' => 0]); expect($headings($this->get('/marken')->getContent())) ->toBe(['februe', 'cabinet', 'rotpunkt', 'tischlerei']); }); it('hides unpublished brands', function () { CmsBrand::where('slug', 'februe')->update(['is_published' => false]); $this->get('/marken') ->assertSuccessful() ->assertSee('CABINET') ->assertDontSee('/marken/februe'); }); // ======================================== // WhatsApp // ======================================== it('hides the whatsapp button while no number is stored', function () { // Lieber kein Button als einer auf eine erfundene Nummer. $this->get('/marken') ->assertSuccessful() ->assertSee('Termin anfragen') ->assertDontSee('wa.me'); }); it('shows the whatsapp button once a number is stored', function () { CmsContent::create([ 'group' => 'global', 'key' => 'contact', 'type' => 'json', 'value' => ['de' => ['whatsapp' => '+49 151 51002992']], 'order' => 0, ]); $this->get('/marken') ->assertSuccessful() ->assertSee('https://wa.me/4915151002992') ->assertSee('Per WhatsApp schreiben'); }); // ======================================== // Abgrenzung der Blöcke // ======================================== it('sets the page header on the same offset surface as the other heroes', function () { $html = markenBody($this->get('/marken')->assertSuccessful()->getContent()); // Dieselbe Fläche wie Startseite und Netzwerkseite. expect($html)->toContain('bg-hero-container'); }); it('frames every brand block so it reads as one unit', function () { $html = markenBody($this->get('/marken')->assertSuccessful()->getContent()); expect(substr_count($html, 'card-elevated rounded-3xl'))->toBe(CmsBrand::query()->published()->count()); }); it('places a smaller image beside the page header text', function () { $html = markenBody($this->get('/marken')->assertSuccessful()->getContent()); // Text 3, Bild 2 Spalten – das Bild begleitet, es dominiert nicht. expect($html)->toContain('lg:col-span-3') ->and($html)->toContain('lg:col-span-2'); }); it('leaves out the image frame entirely when no motif is maintained', function () { CmsContent::create([ 'group' => 'marken', 'key' => 'hero', 'type' => 'json', 'value' => ['de' => ['title' => 'Unsere Marken', 'text' => 'Kurztext.', 'image' => '']], 'order' => 0, ]); $html = markenBody($this->get('/marken')->assertSuccessful()->getContent()); expect($html)->toContain('Unsere Marken') ->and($html)->not->toContain('lg:col-span-2'); }); it('sets the brand blocks off from the origin section with an image break (07.10.2026)', function () { $html = $this->get('/marken')->assertSuccessful()->getContent(); $image = strpos($html, 'id="bild"'); $origin = strpos($html, 'id="herkunft"'); expect($image)->not->toBeFalse() ->and($origin)->toBeGreaterThan($image) ->and(substr($html, $image, 2500))->toContain('slideshow/rotpunkt-bad-mk04.webp') ->toContain('Hinter jeder unserer Marken stehe ich persönlich. Ich kenne die Werke und die Menschen, die dort arbeiten.') ->toContain('– Marcel Scheibe'); expect(config('cms_section_map.sections.marken_image_break'))->toBe(['marken', 'image_break']); });