Arbeitsplan 14.09.2026, Punkte 1.1 bis 1.4 (Nachträge 6 bis 10 im Entwicklungsplan): - Farbwelt Interior (Tanne, Creme, Sand, Ocker, Clay) als Standard, Immobilien-Welt behält das bisherige Blau über body.world-immobilien; Logo je Welt, Favicons neu, Welten-Wechsler in Kopf- und Fußzeile. - Saubere Trennung der Welten: eigene Navigation, Ankündigungsleiste, Magazinliste, Über-uns-Seite, FAQ, Kontaktseite und Abschluss-CTA für Immobilien; Beiträge tragen eine Welt (Migration + Admin-Feld). Abschluss-CTA Ton in Ton statt Grün-zu-Ocker. - Kontakt: Betreffe in Gruppen Interior / Immobilien / B2in, Marken darin. Terminanfrage-Buttons öffnen das Widget mit vorgewähltem Anliegen; Select-Felder einheitlich gestaltet. - Tischlerei als vierte Kernmarke (Platzhalter), Kachelraster 2×2. - Herkunfts-Sektion „Aus der Region gefertigt“ mit schematischer Standortkarte und Ablauf CABINET (Beratung Bielefeld, Fertigung Köln, Aufbau mit Tischlerei). Deployment: migrate, WorldSplitCmsSeeder, CmsBrandSeeder, OriginSectionCmsSeeder (Abschnitt 8 im Entwicklungsplan). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
177 lines
6 KiB
PHP
177 lines
6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Acme\ContactForm\ContactFormService;
|
|
use App\Livewire\Web\Components\Sections\ImmobilienContactForm;
|
|
use App\Livewire\Web\Components\Ui\ContactForm;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Livewire\Livewire;
|
|
|
|
it('contact page loads with contact form component', function () {
|
|
$this->get('/contact')
|
|
->assertSuccessful()
|
|
->assertSeeLivewire(ContactForm::class);
|
|
});
|
|
|
|
it('contact form renders with privacy checkbox', function () {
|
|
Livewire::test(ContactForm::class)
|
|
->assertSee('Datenschutzerklärung');
|
|
});
|
|
|
|
it('contact form validates required fields', function () {
|
|
Livewire::test(ContactForm::class)
|
|
->call('submit')
|
|
->assertHasErrors(['firstName', 'lastName', 'email', 'subject', 'message', 'privacy']);
|
|
});
|
|
|
|
it('contact form requires privacy acceptance', function () {
|
|
Livewire::test(ContactForm::class)
|
|
->set('firstName', 'Max')
|
|
->set('lastName', 'Mustermann')
|
|
->set('email', 'max@example.com')
|
|
->set('subject', 'general')
|
|
->set('message', 'Testnachricht')
|
|
->set('privacy', false)
|
|
->call('submit')
|
|
->assertHasErrors(['privacy']);
|
|
});
|
|
|
|
it('contact form sends email on valid submission', function () {
|
|
Mail::fake();
|
|
|
|
$service = $this->mock(ContactFormService::class);
|
|
$service->shouldReceive('handle')->once();
|
|
|
|
Livewire::test(ContactForm::class)
|
|
->set('firstName', 'Max')
|
|
->set('lastName', 'Mustermann')
|
|
->set('email', 'max@example.com')
|
|
->set('subject', 'general')
|
|
->set('message', 'Testnachricht für das Kontaktformular')
|
|
->set('privacy', true)
|
|
->call('submit')
|
|
->assertHasNoErrors()
|
|
->assertSet('success', true);
|
|
});
|
|
|
|
it('contact form resets after successful submission', function () {
|
|
Mail::fake();
|
|
|
|
$service = $this->mock(ContactFormService::class);
|
|
$service->shouldReceive('handle')->once();
|
|
|
|
Livewire::test(ContactForm::class)
|
|
->set('firstName', 'Max')
|
|
->set('lastName', 'Mustermann')
|
|
->set('email', 'max@example.com')
|
|
->set('subject', 'general')
|
|
->set('message', 'Testnachricht')
|
|
->set('privacy', true)
|
|
->call('submit')
|
|
->assertSet('firstName', '')
|
|
->assertSet('lastName', '')
|
|
->assertSet('email', '')
|
|
->assertSet('message', '')
|
|
->assertSet('privacy', false);
|
|
});
|
|
|
|
it('contact form blocks honeypot spam', function () {
|
|
Livewire::test(ContactForm::class)
|
|
->set('firstName', 'Max')
|
|
->set('lastName', 'Mustermann')
|
|
->set('email', 'max@example.com')
|
|
->set('subject', 'general')
|
|
->set('message', 'Testnachricht')
|
|
->set('privacy', true)
|
|
->set('website', 'https://spam.com')
|
|
->call('submit')
|
|
->assertHasErrors(['website']);
|
|
});
|
|
|
|
it('immobilien contact form renders with privacy checkbox', function () {
|
|
Livewire::test(ImmobilienContactForm::class, [
|
|
'projectSlug' => 'test-projekt',
|
|
'projectTitle' => 'Testprojekt Dubai',
|
|
'interestOptions' => ['kauf' => 'Kauf', 'miete' => 'Miete'],
|
|
])
|
|
->assertSee('Datenschutzerklärung')
|
|
->assertSee('Exposé');
|
|
});
|
|
|
|
it('immobilien contact form can hide interest selection', function () {
|
|
Livewire::test(ImmobilienContactForm::class, [
|
|
'projectSlug' => 'test-projekt',
|
|
'projectTitle' => 'Testprojekt Dubai',
|
|
'interestOptions' => ['kauf' => 'Kauf', 'miete' => 'Miete'],
|
|
'showInterest' => false,
|
|
'submitLabel' => 'Anfrage absenden',
|
|
'syncFromAlpineProject' => true,
|
|
])
|
|
->assertDontSee('Bitte wählen')
|
|
->assertDontSee('Kauf')
|
|
->assertSee('Anfrage absenden')
|
|
->assertSee('Datenschutzerklärung');
|
|
});
|
|
|
|
it('immobilien contact form updates selected project from modal event', function () {
|
|
Livewire::test(ImmobilienContactForm::class)
|
|
->dispatch('azizi-project-selected', slug: 'azizi-amir', title: 'Azizi Amir')
|
|
->assertSet('projectSlug', 'azizi-amir')
|
|
->assertSet('projectTitle', 'Azizi Amir');
|
|
});
|
|
|
|
it('immobilien contact form validates required fields', function () {
|
|
Livewire::test(ImmobilienContactForm::class)
|
|
->call('submit')
|
|
->assertHasErrors(['firstName', 'lastName', 'email', 'privacy']);
|
|
});
|
|
|
|
it('immobilien contact form requires privacy acceptance', function () {
|
|
Livewire::test(ImmobilienContactForm::class)
|
|
->set('firstName', 'Max')
|
|
->set('lastName', 'Mustermann')
|
|
->set('email', 'max@example.com')
|
|
->set('privacy', false)
|
|
->call('submit')
|
|
->assertHasErrors(['privacy']);
|
|
});
|
|
|
|
it('immobilien contact form sends inquiry on valid submission', function () {
|
|
Mail::fake();
|
|
|
|
$service = $this->mock(ContactFormService::class);
|
|
$service
|
|
->shouldReceive('handle')
|
|
->once()
|
|
->withArgs(function (array $payload, string $subject, string $source): bool {
|
|
expect($payload['project'])->toBe('azizi-creek-views-4')
|
|
->and($payload['project_title'])->toBe('Creek Views 4')
|
|
->and($subject)->toBe('Immobilien-Anfrage: Creek Views 4')
|
|
->and($source)->toBe('immobilien-contact-form');
|
|
|
|
return true;
|
|
});
|
|
|
|
Livewire::test(ImmobilienContactForm::class, [
|
|
'projectSlug' => 'azizi-creek-views-4',
|
|
'projectTitle' => 'Creek Views 4',
|
|
'interestOptions' => ['kauf' => 'Kauf'],
|
|
])
|
|
->set('firstName', 'Max')
|
|
->set('lastName', 'Mustermann')
|
|
->set('email', 'max@example.com')
|
|
->set('phone', '+49 123 456789')
|
|
->set('interest', 'kauf')
|
|
->set('message', 'Ich interessiere mich für diese Immobilie.')
|
|
->set('privacy', true)
|
|
->call('submit')
|
|
->assertHasNoErrors()
|
|
->assertSet('success', true);
|
|
});
|
|
|
|
it('immobilien show page renders livewire contact form component', function () {
|
|
$this->get('/immobilien/azizi-creek-views-4')
|
|
->assertSuccessful()
|
|
->assertSeeLivewire(ImmobilienContactForm::class);
|
|
});
|