Nachtrag 11: Herkunfts-Sektion liest Ort, Entfernung und Rolle aus der Markenverwaltung (drei neue Felder an cms_brands, BrandOriginSeeder), Kartenpositionen im Code, „Marken“ in der Sidebar. Nachtrag 12: Inhalte-Editor zeigt die Seiten der Website mit ihren Sektionen in Reihenfolge (config/cms_pages.php, CmsPageTree), Felder in Klartext, fehlende Sektionen aus der Sprachdatei anlegbar, Vorschau der echten Seite im iframe mit Sprung zur Sektion; Anker an allen lebenden Sektionen nachgezogen. Nachtrag 13: Referenzen als eigenes Modul (CmsReference, Portal-Seite, /referenzen mit Fallback auf die Markengalerien); Immobilien-Projekte aus Sidebar und CMS-Übersicht genommen, Route bleibt. Dazu .gitignore für _b2in_interior_shop/ und docs/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
137 lines
5.1 KiB
PHP
137 lines
5.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\CmsBrand;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
$this->seed(\Database\Seeders\CmsBrandSeeder::class);
|
|
});
|
|
|
|
it('loads and carries its own title', function () {
|
|
$this->get('/referenzen')
|
|
->assertSuccessful()
|
|
->assertSee('Unsere <span class="text-secondary">Referenzen', false)
|
|
->assertSee('Realisierte <span class="text-secondary">Projekte', false);
|
|
});
|
|
|
|
it('appears in the main navigation', function () {
|
|
$this->get('/')
|
|
->assertSuccessful()
|
|
->assertSee('/referenzen');
|
|
});
|
|
|
|
it('shows the completed projects from every brand gallery', function () {
|
|
CmsBrand::where('slug', 'cabinet')->firstOrFail()->update([
|
|
'gallery' => [
|
|
['image' => 'a.webp', 'category' => 'project', 'caption' => 'Ankleide in Bielefeld'],
|
|
['image' => 'b.webp', 'category' => 'inspiration', 'caption' => 'Entwurf Garderobe'],
|
|
],
|
|
]);
|
|
CmsBrand::where('slug', 'rotpunkt')->firstOrFail()->update([
|
|
'gallery' => [
|
|
['image' => 'c.webp', 'category' => 'project', 'caption' => 'Küche in Hiddenhausen'],
|
|
],
|
|
]);
|
|
|
|
$this->get('/referenzen')
|
|
->assertSuccessful()
|
|
->assertSee('Ankleide in Bielefeld')
|
|
->assertSee('Küche in Hiddenhausen', false);
|
|
});
|
|
|
|
it('keeps visualisations out of the references', function () {
|
|
CmsBrand::where('slug', 'cabinet')->firstOrFail()->update([
|
|
'gallery' => [
|
|
['image' => 'entwurf.webp', 'category' => 'inspiration', 'caption' => 'Nur ein Entwurf'],
|
|
],
|
|
]);
|
|
|
|
$this->get('/referenzen')
|
|
->assertSuccessful()
|
|
->assertDontSee('Nur ein Entwurf');
|
|
});
|
|
|
|
it('links each project back to its brand page', function () {
|
|
CmsBrand::where('slug', 'cabinet')->firstOrFail()->update([
|
|
'gallery' => [['image' => 'a.webp', 'category' => 'project', 'caption' => 'Ankleide']],
|
|
]);
|
|
|
|
$this->get('/referenzen')
|
|
->assertSuccessful()
|
|
->assertSee('/marken/cabinet');
|
|
});
|
|
|
|
it('says so plainly when there is nothing to show yet', function () {
|
|
CmsBrand::query()->update(['gallery' => null]);
|
|
|
|
$this->get('/referenzen')
|
|
->assertSuccessful()
|
|
->assertSee('sobald wir sie zeigen dürfen', false)
|
|
->assertSee('Termin anfragen');
|
|
});
|
|
|
|
// ========================================
|
|
// Eigene Referenzen aus dem Portal (Nachtrag 13)
|
|
// ========================================
|
|
|
|
it('prefers maintained references over the brand galleries', function () {
|
|
CmsBrand::where('slug', 'cabinet')->firstOrFail()->update([
|
|
'gallery' => [['image' => 'a.webp', 'category' => 'project', 'caption' => 'Aus der Galerie']],
|
|
]);
|
|
\App\Models\CmsReference::factory()->forBrands(['cabinet', 'tischlerei'])->withGallery(2)->create([
|
|
'title' => ['de' => 'Ankleide unter der Dachschräge'],
|
|
'location' => 'Bielefeld',
|
|
'year' => '2025',
|
|
'description' => ['de' => 'Maßschrank bis unter den First.'],
|
|
'image' => 'referenzen/ankleide.webp',
|
|
]);
|
|
|
|
$html = $this->get('/referenzen')->assertSuccessful()->getContent();
|
|
|
|
expect($html)->toContain('Ankleide unter der Dachschräge')
|
|
->toContain('Bielefeld · 2025')
|
|
->toContain('Maßschrank bis unter den First.')
|
|
->toContain('referenzen/bild-1.webp')
|
|
->toContain('href="/marken/cabinet"')
|
|
->toContain('href="/marken/tischlerei"')
|
|
->not->toContain('Aus der Galerie');
|
|
});
|
|
|
|
it('hides unpublished references and falls back to the galleries when none is published', function () {
|
|
CmsBrand::where('slug', 'rotpunkt')->firstOrFail()->update([
|
|
'gallery' => [['image' => 'c.webp', 'category' => 'project', 'caption' => 'Küche in Hiddenhausen']],
|
|
]);
|
|
\App\Models\CmsReference::factory()->unpublished()->create(['title' => ['de' => 'Noch nicht freigegeben']]);
|
|
|
|
$this->get('/referenzen')
|
|
->assertSuccessful()
|
|
->assertDontSee('Noch nicht freigegeben')
|
|
->assertSee('Küche in Hiddenhausen', false);
|
|
});
|
|
|
|
it('drops a brand that is unpublished and skips a reference without any image', function () {
|
|
CmsBrand::where('slug', 'februe')->firstOrFail()->update(['is_published' => false]);
|
|
\App\Models\CmsReference::factory()->forBrands(['februe', 'cabinet'])->create(['title' => ['de' => 'Büro in Herford']]);
|
|
\App\Models\CmsReference::factory()->create(['title' => ['de' => 'Ohne Bild'], 'image' => null, 'gallery' => []]);
|
|
|
|
$html = $this->get('/referenzen')->assertSuccessful()->getContent();
|
|
|
|
expect($html)->toContain('Büro in Herford')
|
|
->toContain('href="/marken/cabinet"')
|
|
->not->toContain('/marken/februe')
|
|
->not->toContain('Ohne Bild');
|
|
});
|
|
|
|
it('uses the first gallery image as cover when no cover is set', function () {
|
|
\App\Models\CmsReference::factory()->withGallery(2)->create(['title' => ['de' => 'Nur Galerie'], 'image' => null]);
|
|
|
|
$html = $this->get('/referenzen')->assertSuccessful()->getContent();
|
|
|
|
expect($html)->toContain('Nur Galerie')
|
|
->toContain('referenzen/bild-1.webp');
|
|
expect(substr_count($html, 'referenzen/bild-1.webp'))->toBe(1);
|
|
});
|