page_url aus dem anonymen Kontaktformular wird auf url:http,https validiert; das Admin-Backend rendert nur http(s)-Links klickbar, sonst als Text. Verhindert javascript:-URIs, die beim Admin-Klick im Admin-Kontext liefen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
238 lines
9 KiB
PHP
238 lines
9 KiB
PHP
<?php
|
|
|
|
use App\Enums\ContactMessageTopic;
|
|
use App\Mail\ContactRequestSubmitted;
|
|
use App\Models\ContactMessage;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use Tests\TestCase;
|
|
|
|
test('the hub landing renders the contact modal form', function () {
|
|
/** @var TestCase $this */
|
|
// Die frühere Kontakt-Seite wurde zurückgebaut; das Formular lebt im
|
|
// schwebenden Kontakt-Widget und postet weiter auf kontakt.store.
|
|
$this->get('https://pressekonto.test/')
|
|
->assertSuccessful()
|
|
->assertSee('name="name"', false)
|
|
->assertSee('name="email"', false)
|
|
->assertSee('name="message"', false)
|
|
->assertSee('Nachricht senden');
|
|
});
|
|
|
|
test('the spoke pages render the floating contact launcher', function () {
|
|
/** @var TestCase $this */
|
|
$this->get('https://businessportal24.test/de/faq')
|
|
->assertSuccessful()
|
|
->assertSee('open-contact-modal', false)
|
|
->assertSee(route('kontakt.store', ['edition' => 'de']), false)
|
|
->assertSee('Fehler melden')
|
|
->assertSee('Pressemitteilung melden');
|
|
});
|
|
|
|
test('the english edition renders the launcher with english strings', function () {
|
|
/** @var TestCase $this */
|
|
$this->get('https://businessportal24.test/en/suche')
|
|
->assertSuccessful()
|
|
->assertSee('Report a bug')
|
|
->assertSee('Report a press release')
|
|
->assertSee('Send message')
|
|
->assertDontSee('Fehler melden');
|
|
});
|
|
|
|
test('a submission on the english edition flashes an english confirmation', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
|
|
$this->post('https://businessportal24.test/en/kontakt', [
|
|
'name' => 'Paula Press',
|
|
'email' => 'paula@example.test',
|
|
'message' => 'I have a question about your platform, please get back to me.',
|
|
])->assertSessionHas('contact-status', __('web.launcher.success', [], 'en'));
|
|
});
|
|
|
|
test('the login page renders the floating contact launcher', function () {
|
|
/** @var TestCase $this */
|
|
$this->get('https://pressekonto.test/login')
|
|
->assertSuccessful()
|
|
->assertSee('open-contact-modal', false)
|
|
->assertSee(route('kontakt.store', ['edition' => 'de']), false);
|
|
});
|
|
|
|
test('a valid contact request sends a mail to the configured recipient', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
config()->set('domains.domains.businessportal24.brand.contact_email', 'redaktion@businessportal24.de');
|
|
|
|
$this->from('https://businessportal24.test/de')
|
|
->post('https://businessportal24.test/de/kontakt', [
|
|
'name' => 'Paula Presse',
|
|
'email' => 'paula@example.test',
|
|
'message' => 'Ich habe eine Frage zu Ihrer Plattform und bitte um Rückruf.',
|
|
])
|
|
->assertRedirect('https://businessportal24.test/de')
|
|
->assertSessionHas('contact-status');
|
|
|
|
Mail::assertQueued(ContactRequestSubmitted::class, function (ContactRequestSubmitted $mail) {
|
|
return $mail->hasTo('redaktion@businessportal24.de')
|
|
&& $mail->hasReplyTo('paula@example.test')
|
|
&& $mail->senderName === 'Paula Presse';
|
|
});
|
|
});
|
|
|
|
test('without a configured brand address the mail falls back to the from address', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
config()->set('domains.domains.businessportal24.brand.contact_email', null);
|
|
config()->set('mail.from.address', 'fallback@pressekonto.de');
|
|
|
|
$this->post('https://businessportal24.test/de/kontakt', [
|
|
'name' => 'Paula Presse',
|
|
'email' => 'paula@example.test',
|
|
'message' => 'Ich habe eine Frage zu Ihrer Plattform und bitte um Rückruf.',
|
|
])->assertSessionHas('contact-status');
|
|
|
|
Mail::assertQueued(ContactRequestSubmitted::class, fn (ContactRequestSubmitted $mail) => $mail->hasTo('fallback@pressekonto.de'));
|
|
});
|
|
|
|
test('a contact request from the hub domain goes to the pressekonto brand address', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
config()->set('domains.domains.pressekonto.brand.contact_email', 'kontakt@pressekonto.de');
|
|
|
|
$this->post('https://pressekonto.test/de/kontakt', [
|
|
'name' => 'Paula Presse',
|
|
'email' => 'paula@example.test',
|
|
'message' => 'Ich habe eine Frage zu Ihrer Plattform und bitte um Rückruf.',
|
|
])->assertSessionHas('contact-status');
|
|
|
|
Mail::assertQueued(ContactRequestSubmitted::class, fn (ContactRequestSubmitted $mail) => $mail->hasTo('kontakt@pressekonto.de'));
|
|
});
|
|
|
|
test('a contact request is stored in the contact queue', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
|
|
$this->post('https://businessportal24.test/de/kontakt', [
|
|
'name' => 'Paula Presse',
|
|
'email' => 'paula@example.test',
|
|
'message' => 'Ich habe eine Frage zu Ihrer Plattform und bitte um Rückruf.',
|
|
])->assertSessionHas('contact-status');
|
|
|
|
$message = ContactMessage::query()->sole();
|
|
|
|
expect($message->topic)->toBe(ContactMessageTopic::Contact)
|
|
->and($message->portal)->toBe('businessportal24')
|
|
->and($message->name)->toBe('Paula Presse')
|
|
->and($message->email)->toBe('paula@example.test')
|
|
->and($message->status->isOpen())->toBeTrue();
|
|
});
|
|
|
|
test('a widget submission stores topic and page url', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
|
|
$this->post('https://presseecho.test/de/kontakt', [
|
|
'name' => 'Bernd Bug',
|
|
'email' => 'bernd@example.test',
|
|
'message' => 'Die Suche liefert auf der Startseite einen Fehler 500.',
|
|
'topic' => 'bug_report',
|
|
'page_url' => 'https://presseecho.test/de/suche',
|
|
])->assertSessionHas('contact-status');
|
|
|
|
$message = ContactMessage::query()->sole();
|
|
|
|
expect($message->topic)->toBe(ContactMessageTopic::BugReport)
|
|
->and($message->portal)->toBe('presseecho')
|
|
->and($message->page_url)->toBe('https://presseecho.test/de/suche');
|
|
|
|
Mail::assertQueued(ContactRequestSubmitted::class, function (ContactRequestSubmitted $mail) {
|
|
return $mail->topicLabel === 'Fehlermeldung'
|
|
&& $mail->pageUrl === 'https://presseecho.test/de/suche';
|
|
});
|
|
});
|
|
|
|
test('a javascript page_url is rejected (stored XSS guard)', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
|
|
$this->post('https://presseecho.test/de/kontakt', [
|
|
'name' => 'Mallory',
|
|
'email' => 'mallory@example.test',
|
|
'message' => 'Ein ganz normal aussehender Text mit genug Zeichen.',
|
|
'topic' => 'bug_report',
|
|
'page_url' => 'javascript:alert(document.cookie)',
|
|
])->assertSessionHasErrors('page_url');
|
|
|
|
expect(ContactMessage::query()->count())->toBe(0);
|
|
Mail::assertNothingOutgoing();
|
|
});
|
|
|
|
test('an advertising enquiry from the ad slot stores the advertising topic', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
|
|
$this->post('https://presseecho.test/de/kontakt', [
|
|
'name' => 'Willi Werbung',
|
|
'email' => 'willi@example.test',
|
|
'message' => 'Ich interessiere mich für Werbeplätze auf Ihrem Portal.',
|
|
'topic' => 'advertising',
|
|
'page_url' => 'https://presseecho.test/de',
|
|
])->assertSessionHas('contact-status');
|
|
|
|
$message = ContactMessage::query()->sole();
|
|
|
|
expect($message->topic)->toBe(ContactMessageTopic::Advertising)
|
|
->and($message->portal)->toBe('presseecho');
|
|
|
|
Mail::assertQueued(ContactRequestSubmitted::class, fn (ContactRequestSubmitted $mail) => $mail->topicLabel === 'Werbeanfrage');
|
|
});
|
|
|
|
test('the spoke pages offer the advertising topic in the contact launcher', function () {
|
|
/** @var TestCase $this */
|
|
$this->get('https://businessportal24.test/de/faq')
|
|
->assertSuccessful()
|
|
->assertSee('Werbung buchen')
|
|
->assertSee('Werbeplätze und Konditionen anfragen');
|
|
});
|
|
|
|
test('an unknown topic is rejected', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
|
|
$this->post('https://businessportal24.test/de/kontakt', [
|
|
'name' => 'Paula Presse',
|
|
'email' => 'paula@example.test',
|
|
'message' => 'Ich habe eine Frage zu Ihrer Plattform und bitte um Rückruf.',
|
|
'topic' => 'not-a-topic',
|
|
])->assertSessionHasErrors(['topic']);
|
|
|
|
expect(ContactMessage::query()->count())->toBe(0);
|
|
Mail::assertNothingOutgoing();
|
|
});
|
|
|
|
test('honeypot submissions are silently accepted without sending mail', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
|
|
$this->post('https://businessportal24.test/de/kontakt', [
|
|
'name' => 'Bot',
|
|
'email' => 'bot@example.test',
|
|
'message' => 'Automatisierter Inhalt mit ausreichend Länge für die Validierung.',
|
|
'website' => 'https://spam.example',
|
|
])->assertSessionHas('contact-status');
|
|
|
|
Mail::assertNothingOutgoing();
|
|
expect(ContactMessage::query()->count())->toBe(0);
|
|
});
|
|
|
|
test('the contact form validates its inputs', function () {
|
|
/** @var TestCase $this */
|
|
Mail::fake();
|
|
|
|
$this->post('https://businessportal24.test/de/kontakt', [
|
|
'name' => '',
|
|
'email' => 'keine-mail',
|
|
'message' => 'kurz',
|
|
])->assertSessionHasErrors(['name', 'email', 'message']);
|
|
|
|
Mail::assertNothingOutgoing();
|
|
});
|