Aufrufe/Teilen je Meldung, Abrufe durch Such-, KI- und Feed-Dienste, Konversionsschritte: Umfang ohne IP, Zweck, Art. 6 Abs. 1 lit. f, Löschung nach 395 Tagen in Abschnitt 13. Text vom Betreiber abgenommen (21.09.2026); gilt für Hub und beide Portale. 0.7 in Roadmap und Protokoll abgehakt. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
277 lines
13 KiB
PHP
277 lines
13 KiB
PHP
<?php
|
|
|
|
use App\Models\RejectionCategory;
|
|
use Database\Seeders\RejectionCategorySeeder;
|
|
use Illuminate\Support\Str;
|
|
use Tests\TestCase;
|
|
|
|
dataset('static pages', [
|
|
'impressum' => ['de/impressum', 'Impressum'],
|
|
'datenschutz' => ['de/datenschutz', 'Datenschutzerklärung'],
|
|
'agb' => ['de/agb', 'Allgemeine Geschäftsbedingungen'],
|
|
'faq' => ['de/faq', 'Häufig gestellte Fragen'],
|
|
'hilfe' => ['de/hilfe', 'Hilfe-Center'],
|
|
'gute-pressemitteilung' => ['de/gute-pressemitteilung', 'Was eine gute Pressemitteilung ausmacht'],
|
|
'api' => ['de/api', 'API-Dokumentation'],
|
|
'rss' => ['de/rss', 'RSS-Feeds'],
|
|
'richtlinien' => ['de/richtlinien', 'Veröffentlichungsrichtlinien'],
|
|
'melden' => ['de/melden', 'Inhalte melden oder Änderungen beantragen'],
|
|
]);
|
|
|
|
test('static pages render in the editorial design', function (string $path, string $heading) {
|
|
/** @var TestCase $this */
|
|
$response = $this->get("https://businessportal24.test/{$path}");
|
|
|
|
$response->assertSuccessful()
|
|
->assertSeeText($heading)
|
|
// Editorial-Shell (Token aus den neuen Komponenten) statt altem Theme.
|
|
->assertSee('bg-bg', false)
|
|
// Altes Theme darf nicht mehr gerendert werden.
|
|
->assertDontSee('gradient-hero');
|
|
})->with('static pages');
|
|
|
|
test('the faq page lists questions and links to support', function () {
|
|
/** @var TestCase $this */
|
|
$this->get('https://businessportal24.test/de/faq')
|
|
->assertSuccessful()
|
|
->assertSeeText('Wie veröffentliche ich meine erste Pressemitteilung?')
|
|
->assertSeeText('Frage nicht gefunden?')
|
|
// Kontakt läuft nach dem Rückbau der Kontakt-Seite über das
|
|
// Support-Postfach und die Kündigung über die eigene Seite.
|
|
->assertSee('mailto:', false)
|
|
->assertSee(route('kuendigung', ['edition' => 'de']), false);
|
|
});
|
|
|
|
test('the retired contact and about pages redirect to the edition home', function (string $path) {
|
|
/** @var TestCase $this */
|
|
$this->get('https://businessportal24.test/de/'.$path)
|
|
->assertStatus(301)
|
|
->assertRedirect('https://businessportal24.test/de');
|
|
})->with(['kontakt', 'ueber-uns']);
|
|
|
|
test('the imprint shows the real provider data instead of placeholders', function () {
|
|
/** @var TestCase $this */
|
|
$this->get('https://businessportal24.test/de/impressum')
|
|
->assertSuccessful()
|
|
->assertSeeText('adametz.media')
|
|
->assertSeeText('Kevin Adametz')
|
|
->assertSeeText('33739 Bielefeld')
|
|
->assertSeeText('DE298729654')
|
|
// Zentrale Rechts-E-Mail (config/legal.php) auf allen Domains.
|
|
->assertSeeText('info@pressekonto.com')
|
|
->assertDontSeeText('info@businessportal24.com')
|
|
// DDG statt TMG; keine erfundene GmbH/Musterstraße mehr.
|
|
->assertSeeText('§ 5 DDG')
|
|
->assertDontSeeText('Business Portal GmbH')
|
|
->assertDontSeeText('Musterstraße');
|
|
});
|
|
|
|
test('the terms render the b2b version with cancellation and archive rules', function () {
|
|
/** @var TestCase $this */
|
|
$this->get('https://pressekonto.test/de/agb')
|
|
->assertSuccessful()
|
|
->assertSeeText('Kein Widerrufsrecht (B2B)')
|
|
->assertSeeText('richtet sich ausschließlich an Unternehmer')
|
|
->assertSeeText('Depublikation, Änderungen, Meldeverfahren')
|
|
// Alte Platzhalter-AGB (30-Tage-Frist, Business Portal GmbH) sind weg.
|
|
->assertDontSeeText('Frist von 30')
|
|
->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
|
|
// erscheinen ohne Textänderung, deaktivierte verschwinden.
|
|
$this->seed(RejectionCategorySeeder::class);
|
|
RejectionCategory::query()->where('code', 'K6')->update(['active' => false]);
|
|
RejectionCategory::factory()->create([
|
|
'code' => 'K7',
|
|
'public_label' => 'Testkategorie aus der Datenbank',
|
|
'sort_order' => 70,
|
|
]);
|
|
|
|
$this->get('https://presseecho.test/de/richtlinien')
|
|
->assertSuccessful()
|
|
->assertSeeText('So funktioniert die Prüfung')
|
|
->assertSeeText('Rechtswidrige Inhalte')
|
|
->assertSeeText('Testkategorie aus der Datenbank')
|
|
->assertSee('id="K1"', false)
|
|
->assertSee('id="K7"', false)
|
|
// Deaktivierte Kategorien werden nicht mehr gerendert.
|
|
->assertDontSeeText('Kein Pressecharakter / Spam');
|
|
});
|
|
|
|
test('the reporting page separates free legal paths from the paid takedown service', function () {
|
|
/** @var TestCase $this */
|
|
$this->get('https://businessportal24.test/de/melden')
|
|
->assertSuccessful()
|
|
->assertSeeText('Rechtswidrige Inhalte oder Rechteverletzungen melden')
|
|
->assertSeeText('Eigene personenbezogene Daten entfernen lassen')
|
|
->assertSeeText('Freiwillige Entfernung rechtmäßiger Inhalte')
|
|
->assertSeeText('Ausübung gesetzlicher Rechte')
|
|
// Depublikations-Preis (O6, 06.07.: 35 € netto) im Doppelausweis.
|
|
->assertSeeText('35,00 € zzgl. USt.')
|
|
->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 () {
|
|
/** @var TestCase $this */
|
|
config()->set('billing.depublication_price_cents', null);
|
|
|
|
$this->get('https://businessportal24.test/de/melden')
|
|
->assertSuccessful()
|
|
->assertSeeText('Der Preis wird Ihnen vor Beauftragung angezeigt.')
|
|
->assertDontSeeText('zzgl. USt.');
|
|
});
|
|
|
|
test('the privacy policy renders the real v03 content with host-specific blocks', function () {
|
|
/** @var TestCase $this */
|
|
// Spoke: Portal-Bausteine (Medienprivileg, Änderungslinks), kein Stripe-Block.
|
|
$this->get('https://presseecho.test/de/datenschutz')
|
|
->assertSuccessful()
|
|
->assertSeeText('adametz.media')
|
|
->assertSeeText('info@pressekonto.com')
|
|
->assertSeeText('Hetzner Online GmbH')
|
|
->assertSeeText('Medienprivileg')
|
|
->assertSeeText('Änderungslinks für Pressekontakte')
|
|
// Roadmap 0.7: Ereignisprotokolle ohne Personenbezug, 395 Tage.
|
|
->assertSeeText('Eigene Nutzungsstatistiken ohne Personenbezug')
|
|
->assertSeeText('Feed abonniert hat, erfahren wir nicht.')
|
|
->assertSeeText('werden nach 395 Tagen gelöscht')
|
|
->assertDontSeeText('Zahlungsabwicklung mit Stripe')
|
|
// Alter Platzhalter (Google Analytics gibt es nicht) ist weg.
|
|
->assertDontSeeText('Google Analytics');
|
|
|
|
// Hub: Kundenkonto-/Stripe-Bausteine, keine Portal-Bausteine.
|
|
$this->get('https://pressekonto.test/de/datenschutz')
|
|
->assertSuccessful()
|
|
->assertSeeText('Kundenkonto und Registrierung auf dem Hub')
|
|
->assertSeeText('Eigene Nutzungsstatistiken ohne Personenbezug')
|
|
->assertSeeText('Zahlungsabwicklung mit Stripe')
|
|
->assertSeeText('gewerblichen oder selbständigen beruflichen Tätigkeit')
|
|
->assertDontSeeText('Medienprivileg');
|
|
});
|
|
|
|
test('the help center shows quick links and topics', function () {
|
|
/** @var TestCase $this */
|
|
$this->get('https://businessportal24.test/de/hilfe')
|
|
->assertSuccessful()
|
|
->assertSeeText('Hilfe-Themen')
|
|
->assertSee(route('faq'), false)
|
|
->assertSee(route('veroeffentlichen'), false);
|
|
});
|
|
|
|
dataset('static pages in english', [
|
|
'faq' => ['en/faq', 'Frequently asked questions'],
|
|
'hilfe' => ['en/hilfe', 'Help center'],
|
|
'gute-pressemitteilung' => ['en/gute-pressemitteilung', 'What makes a good press release'],
|
|
'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');
|
|
});
|
|
|
|
test('the good-release help page explains the check without selling anything', function () {
|
|
/** @var TestCase $this */
|
|
// Roadmap 1d.1: ohne kommerziellen Anteil, Rot nur als Kategorie,
|
|
// Dimensionen offen, Versuchszahl aus der Konfiguration.
|
|
config()->set('scoring.classification.max_automatic_attempts', 2);
|
|
|
|
$response = $this->get('https://businessportal24.test/de/gute-pressemitteilung')
|
|
->assertSuccessful()
|
|
->assertSeeText('bis zu 2 Mal')
|
|
->assertSeeText('Pressestil')
|
|
->assertSeeText('Pressebilder')
|
|
->assertSeeText('Partner')
|
|
->assertSee(route('richtlinien'), false);
|
|
|
|
// Kein kommerzieller Anteil im Seiteninhalt (die Shell-Navigation zählt nicht).
|
|
$body = Str::between($response->getContent(), 'class="pm-body', 'aria-labelledby="partner-heading"');
|
|
expect($body)->not->toContain('/preise')->not->toContain('Credits');
|
|
|
|
// Aus dem Hilfe-Center erreichbar; in der Sitemap steht sie beim
|
|
// führenden Host (Anhang 2, E10) — presseecho, nicht businessportal24.
|
|
$this->get('https://businessportal24.test/de/hilfe')->assertSee('/de/gute-pressemitteilung', false);
|
|
$this->get('https://presseecho.test/sitemap.xml')->assertSee('/de/gute-pressemitteilung', false);
|
|
$this->get('https://businessportal24.test/sitemap.xml')->assertDontSee('/de/gute-pressemitteilung', false);
|
|
});
|