Backend-WIP: Kontakt-Queue, Page-Cache, Validierungs-Feedback, i18n

Gebuendelt, da ueber gemeinsame lang-/Service-Dateien verschraenkt:
- Kontakt-Nachrichten: contact_messages-Tabelle + Model/Enums/Factory,
  Admin-Queue (livewire/admin/contact-messages), ContactController
  persistiert das Anliegen zusaetzlich zur Brand-Mail
- Page-Data-Cache (Services/Web/*PageData) + web-archive-Indizes auf
  press_releases
- Validierungs-Feedback + Company-Portal-Restriction (Feature-Tests)
- i18n-Auslagerung lang/de|en (auth, passwords, validation, static)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-09 15:38:11 +00:00
parent ef5de54300
commit 72e6a3c210
60 changed files with 3963 additions and 327 deletions

View file

@ -75,6 +75,18 @@ test('the terms render the b2b version with cancellation and archive rules', fun
->assertDontSeeText('Business Portal GmbH');
});
test('the terms state that subscriptions renew for the chosen term instead of switching to monthly billing', function () {
/** @var TestCase $this */
// Jahresabos verlängern sich um jeweils zwölf Monate und sind zum
// Laufzeitende kündbar — kein Wechsel auf monatliche Abrechnung mehr.
$this->get('https://pressekonto.test/de/agb')
->assertSuccessful()
->assertSeeText('verlängert sich jeweils automatisch um die')
->assertSeeText('zum Ende des jeweiligen Zwölfmonats-Zeitraums')
->assertDontSeeText('auf unbestimmte Zeit')
->assertDontSeeText('erfolgt die Abrechnung nach Ablauf der Erstlaufzeit monatlich');
});
test('the guidelines list the rejection categories with anchors', function () {
/** @var TestCase $this */
// Kategorien kommen live aus rejection_categories (E3) — neue Zeilen
@ -108,7 +120,11 @@ test('the reporting page separates free legal paths from the paid takedown servi
->assertSeeText('Ausübung gesetzlicher Rechte')
// Depublikations-Preis (O6, 06.07.: 35 € netto) im Doppelausweis.
->assertSeeText('35,00 € zzgl. USt.')
->assertSeeText('41,65 € inkl. 19');
->assertSeeText('41,65 € inkl. 19')
// Keine Melde-E-Mail-Adresse mehr auf der Seite: alle Wege verweisen
// auf das Kontakt-Widget (Badge unten rechts, wie im Footer).
->assertDontSee('mailto:', false)
->assertSeeText('Kontaktformular');
});
test('the reporting page falls back to the neutral price wording when depublication is disabled', function () {
@ -152,3 +168,76 @@ test('the help center shows quick links and topics', function () {
->assertSee(route('faq'), false)
->assertSee(route('veroeffentlichen'), false);
});
dataset('static pages in english', [
'faq' => ['en/faq', 'Frequently asked questions'],
'hilfe' => ['en/hilfe', 'Help center'],
'api' => ['en/api', 'API documentation'],
'impressum' => ['en/impressum', 'Imprint'],
'melden' => ['en/melden', 'Report content or request changes'],
'kuendigung' => ['en/kuendigung', 'Cancel contracts here'],
]);
test('the translated static pages render in english on the en edition', function (string $path, string $heading) {
/** @var TestCase $this */
$this->get("https://businessportal24.test/{$path}")
->assertSuccessful()
->assertSeeText($heading)
// Kein deutsches Seiten-Gerüst mehr auf der EN-Ausgabe.
->assertDontSeeText('Häufig gestellte Fragen')
->assertDontSeeText('Hilfe-Center');
})->with('static pages in english');
test('the publish page renders in english with an en hreflang alternate', function () {
/** @var TestCase $this */
$this->get('https://businessportal24.test/en/veroeffentlichen')
->assertSuccessful()
->assertSeeText('Publish a press release.')
->assertSeeText('Four principles that carry this platform')
->assertSee('hreflang="en"', false)
->assertDontSeeText('Pressemitteilung veröffentlichen.');
});
test('the report forms render in english on the en edition', function () {
/** @var TestCase $this */
$this->get('https://businessportal24.test/en/melden/rechtswidrig')
->assertSuccessful()
->assertSeeText('Report illegal content')
->assertSeeText('Submit report');
$this->get('https://businessportal24.test/en/melden/kontaktdaten')
->assertSuccessful()
->assertSeeText('Have your own contact details removed')
->assertSeeText('Submit request');
});
test('the binding legal texts stay german but show an english language notice on the en edition', function () {
/** @var TestCase $this */
// AGB/Datenschutz/Richtlinien bleiben deutsch (O-C: EN-Fassungen erst
// nach fachanwaltlicher Prüfung) — die EN-Ausgabe erklärt das sichtbar.
$this->get('https://businessportal24.test/en/agb')
->assertSuccessful()
->assertSeeText('The German version is authoritative and legally binding.')
->assertSeeText('Allgemeine Geschäftsbedingungen');
$this->get('https://businessportal24.test/en/datenschutz')
->assertSuccessful()
->assertSeeText('The German version is authoritative and legally binding.');
// Auf der deutschen Ausgabe erscheint kein Hinweis.
$this->get('https://businessportal24.test/de/agb')
->assertSuccessful()
->assertDontSeeText('The German version is authoritative and legally binding.');
});
test('german validation messages are used on the de edition forms', function () {
/** @var TestCase $this */
$response = $this->from('https://businessportal24.test/de/melden/rechtswidrig')
->post('https://businessportal24.test/de/melden/rechtswidrig', []);
$response->assertSessionHasErrors(['reported_url', 'requester_name', 'requester_email', 'message']);
$messages = collect(session('errors')->all())->implode(' ');
expect($messages)->toContain('muss ausgefüllt werden')
->not->toContain('field is required');
});