seed(\Database\Seeders\CmsBrandSeeder::class); }); // ======================================== // Kacheln auf der Startseite // ======================================== it('shows the maintained brands on the homepage', function () { $this->get('/') ->assertSuccessful() ->assertSee('CABINET') ->assertSee('Rotpunkt Küchen', false) ->assertSee('Febrü', false); }); it('links each tile to its detail page', function () { $this->get('/') ->assertSuccessful() ->assertSee('/marken/cabinet') ->assertSee('/marken/rotpunkt') ->assertSee('/marken/februe'); }); it('hides unpublished brands from the homepage', function () { CmsBrand::where('slug', 'februe')->update(['is_published' => false]); $this->get('/') ->assertSuccessful() ->assertSee('CABINET') ->assertDontSee('/marken/februe'); }); // ======================================== // Detailseite // ======================================== it('serves a detail page for every brand', function () { foreach (['cabinet', 'rotpunkt', 'februe'] as $slug) { $this->get('/marken/'.$slug)->assertSuccessful(); } }); it('renders the template sections from the concept', function () { $this->get('/marken/cabinet') ->assertSuccessful() ->assertSee('CABINET') // Header ->assertSee('Einbauschränke nach Maß', false) // Claim ->assertSee('Showroom Bielefeld') ->assertSee('Leistungen und Besonderheiten') // Leistungen ->assertSee('Aufmaß vor Ort', false) ->assertSee('Termin anfragen'); // CTA }); it('links to the other brands from a detail page', function () { $this->get('/marken/cabinet') ->assertSuccessful() ->assertSee('/marken/rotpunkt') ->assertSee('/marken/februe'); }); it('returns 404 for an unknown brand', function () { $this->get('/marken/gibt-es-nicht')->assertNotFound(); }); it('returns 404 for an unpublished brand', function () { CmsBrand::where('slug', 'februe')->update(['is_published' => false]); $this->get('/marken/februe')->assertNotFound(); }); it('carries a brand specific title and description', function () { $this->get('/marken/cabinet') ->assertSuccessful() ->assertSee('CABINET – Einbauschränke nach Maß. | B2in Interior', false) ->assertDontSee('Connecting Design and Property'); }); // ======================================== // CMS-Anbindung // ======================================== it('renders what is maintained in the CMS', function () { $cabinet = CmsBrand::where('slug', 'cabinet')->firstOrFail(); $cabinet->setTranslation('tagline', 'de', 'Im CMS geänderter Claim'); $cabinet->save(); $this->get('/')->assertSuccessful()->assertSee('Im CMS geänderter Claim'); $this->get('/marken/cabinet')->assertSuccessful()->assertSee('Im CMS geänderter Claim'); }); it('picks up a brand that was added in the CMS, without a code change', function () { CmsBrand::factory()->create([ 'slug' => 'neue-marke', 'name' => ['de' => 'Neue Marke', 'en' => 'New Brand'], 'order' => 9, ]); $this->get('/')->assertSuccessful()->assertSee('Neue Marke'); $this->get('/marken/neue-marke')->assertSuccessful()->assertSee('Neue Marke'); }); // ======================================== // Galerie: realisierte Projekte vs. Inspirationen // ======================================== it('shows no gallery section while no images are maintained', function () { $this->get('/marken/cabinet') ->assertSuccessful() ->assertDontSee('Referenzen und Inspirationen'); }); it('shows both groups with their own labels', function () { CmsBrand::where('slug', 'cabinet')->firstOrFail()->update([ 'gallery' => [ ['image' => 'projekt.webp', 'category' => 'project', 'caption' => 'Ankleide in Bielefeld'], ['image' => 'entwurf.webp', 'category' => 'inspiration', 'caption' => 'Entwurf Garderobe'], ], ]); $this->get('/marken/cabinet') ->assertSuccessful() ->assertSee('Referenzen und Inspirationen') ->assertSee('Realisierte Projekte') ->assertSee('Inspirationen und Entwürfe', false) ->assertSee('Realisiertes Projekt') ->assertSee('Visualisierung') ->assertSee('Ankleide in Bielefeld') ->assertSee('Entwurf Garderobe'); }); it('does not offer a tab switch when only one group is filled', function () { CmsBrand::where('slug', 'cabinet')->firstOrFail()->update([ 'gallery' => [ ['image' => 'projekt.webp', 'category' => 'project', 'caption' => 'Nur ein Projekt'], ], ]); $this->get('/marken/cabinet') ->assertSuccessful() ->assertSee('Realisierte Projekte') ->assertDontSee('Inspirationen und Entwürfe', false); }); it('marks an image without a category as visualisation, never as a completed project', function () { CmsBrand::where('slug', 'cabinet')->firstOrFail()->update([ 'gallery' => [ ['image' => 'ohne-kategorie.webp'], ], ]); $this->get('/marken/cabinet') ->assertSuccessful() ->assertSee('Visualisierung') ->assertDontSee('Realisiertes Projekt'); }); it('still separates inspirations from completed projects after the rewording', function () { CmsBrand::where('slug', 'cabinet')->firstOrFail()->update([ 'gallery' => [ ['image' => 'entwurf.webp', 'category' => 'inspiration'], ], ]); $this->get('/marken/cabinet') ->assertSuccessful() ->assertSee('Entwürfe und Visualisierungen', false) ->assertSee('Visualisierung') ->assertDontSee('Realisiertes Projekt'); }); it('fills the demo galleries with both categories', function () { $this->seed(\Database\Seeders\DemoBrandGallerySeeder::class); $grouped = CmsBrand::groupGallery(CmsBrand::where('slug', 'cabinet')->firstOrFail()->gallery); expect($grouped['projects'])->not->toBeEmpty() ->and($grouped['inspirations'])->not->toBeEmpty(); // Der Vermerk „BEISPIEL“ ist auf Kundenwunsch entfallen. Die Unterscheidung muss deshalb // an der Kategorie haengen – jedes Demobild braucht eine ausdrueckliche. foreach (CmsBrand::all() as $brand) { foreach ($brand->gallery ?? [] as $item) { expect($item['caption'])->not->toContain('BEISPIEL') ->and($item['category'])->toBeIn(CmsBrand::GALLERY_CATEGORIES); } } }); it('strips the old example prefix without touching image, category or order', function () { CmsBrand::where('slug', 'cabinet')->firstOrFail()->update([ 'gallery' => [ ['image' => 'a.webp', 'category' => 'project', 'caption' => 'BEISPIEL – Ankleide, Bielefeld'], ['image' => 'b.webp', 'category' => 'inspiration', 'caption' => 'Entwurf Garderobe'], ], ]); $this->seed(\Database\Seeders\BrandGalleryCaptionNormalizerSeeder::class); $gallery = CmsBrand::where('slug', 'cabinet')->firstOrFail()->gallery; expect($gallery)->toHaveCount(2) ->and($gallery[0]['caption'])->toBe('Ankleide, Bielefeld') ->and($gallery[0]['image'])->toBe('a.webp') ->and($gallery[0]['category'])->toBe('project') ->and($gallery[1]['caption'])->toBe('Entwurf Garderobe'); }); // ======================================== // Markenlogos // ======================================== it('shows the logo instead of the wordmark at the top of a brand page', function () { $html = $this->get('/marken/rotpunkt')->assertSuccessful()->getContent(); // Das Logo sitzt im