presseportale/tests/Feature/Web/TransparencyPagesTest.php
Kevin Adametz 106edb1384 web: Transparenzseiten — was kostet, ohne Abo, loeschen/aendern (Roadmap 2.4)
Drei Seiten mit unterschiedlicher Suchintention, DE/EN, Hub + Spokes:
- /was-kostet-eine-pressemitteilung: kurze Antwort im ersten Bildschirm,
  vier Abrechnungsmodelle ohne Anbieternamen und fremde Preise, sechs
  Prueffragen fuer Folgekosten, "Was bei uns gilt" (sieben Zusagen mit
  Einloesung), Rechenbeispiel Einzelabrechnung gegen Starter-Monate mit
  Zeilen fuer beide Seiten.
- /pressemitteilung-veroeffentlichen-ohne-abo: Ablauf, enthalten / nicht
  enthalten, nichts verfaellt, wann sich ein Tarif lohnt.
- /pressemitteilung-loeschen-oder-aendern-lassen: fuenf Wege als
  Tabelle (Korrektur, Aenderung, DSGVO, Depublikation, DSA), Antragsweg
  ueber /melden/pm, Korrektur statt Loeschung, Absatz fuer Meldungen auf
  fremden Portalen ohne Zusagen ueber Dritte.

PricingTransparencyData liefert alle Zahlen aus config/billing, credits,
legal und dem Starter-Tarif; TransparencyPageController leitet die Marke
aus dem Host ab. Tabellen-Typografie fuer .pm-body. Verlinkt aus
Preisuebersicht, Hilfe-Center, Sitemaps und llms.txt.

Test TransparencyPagesTest (9) erzwingt u. a., dass im Rechenbeispiel
beide Modelle Zeilen gewinnen. Protokoll Teil 5, Roadmap 2.4 abgehakt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 12:00:28 +00:00

87 lines
4.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
use App\Models\Plan;
use App\Services\Web\PricingTransparencyData;
use Tests\TestCase;
/**
* Transparenzseiten (Roadmap 2.4): Zahlen aus der Konfiguration, kein
* Anbietername, Rechenbeispiel mit gemischtem Ausgang.
*/
beforeEach(function (): void {
config()->set('billing.single_pm_price_cents', 1900);
config()->set('billing.change_price_cents', 1000);
config()->set('billing.depublication_price_cents', 3500);
config()->set('billing.vat_rate', 0.19);
config()->set('credits.extra_pm.starter', 15);
Plan::factory()->create(['slug' => 'starter', 'name' => 'Starter', 'monthly_price_cents' => 2900, 'yearly_price_cents' => 29000, 'press_release_quota' => 3, 'is_active' => true]);
});
test('the worked example lets pay-per-release win in some rows and the plan in others', function () {
$data = app(PricingTransparencyData::class)->build();
expect($data['singleNet'])->toBe('19')
->and($data['singleGross'])->toBe('22,61')
->and($data['starterMonthlyNet'])->toBe('29')
->and(collect($data['examples'])->pluck('cheaper')->unique()->sort()->values()->all())->toBe(['single', 'starter']);
});
test('the cost page shows the short answer with the configured price and no competitor names', function () {
/** @var TestCase $this */
$response = $this->get('https://presseecho.test/de/was-kostet-eine-pressemitteilung')->assertSuccessful();
$response
->assertSee('Was kostet eine Pressemitteilung?')
->assertSee('<strong>19 € netto</strong> (22,61 € inkl. 19 % USt.)', false)
->assertSee('Woran man Folgekosten erkennt')
->assertSee('Rechenbeispiel')
->assertSee('228&nbsp;€', false)
->assertSee('10 € netto')
->assertSee('35 € netto')
->assertSee('/de/pressemitteilung-loeschen-oder-aendern-lassen', false)
->assertSee('<title>Was kostet eine Pressemitteilung? Preis, Modelle, Rechenbeispiel – presseecho</title>', false);
// Kein Anbietername, keine fremden Preise (Briefing 17.09.2026).
$this->assertStringNotContainsStringIgnoringCase('presseportal.de', (string) $response->getContent());
$this->assertStringNotContainsStringIgnoringCase('openpr', (string) $response->getContent());
});
test('the no-subscription page and the change page render on every host in both editions', function (string $url) {
/** @var TestCase $this */
$this->get($url)->assertSuccessful();
})->with([
'https://businessportal24.test/de/pressemitteilung-veroeffentlichen-ohne-abo',
'https://businessportal24.test/en/pressemitteilung-veroeffentlichen-ohne-abo',
'https://pressekonto.test/de/pressemitteilung-loeschen-oder-aendern-lassen',
'https://presseecho.test/en/pressemitteilung-loeschen-oder-aendern-lassen',
'https://pressekonto.test/en/was-kostet-eine-pressemitteilung',
]);
test('the change page names the five ways with their prices and points to the self-service entry', function () {
/** @var TestCase $this */
$this->get('https://businessportal24.test/de/pressemitteilung-loeschen-oder-aendern-lassen')
->assertSuccessful()
->assertSee('Die fünf Wege')
->assertSee('kostenlos')
->assertSee('10 € netto')
->assertSee('35 € netto')
->assertSee('/de/melden/pm', false)
->assertSee('Die Meldung steht auf einem anderen Portal?');
});
test('the pages are linked from the pricing page, the help centre and the sitemap', function () {
/** @var TestCase $this */
$this->get('https://presseecho.test/de/preise')->assertSuccessful()
->assertSee('/de/was-kostet-eine-pressemitteilung', false);
$this->get('https://presseecho.test/de/hilfe')->assertSuccessful()
->assertSee('/de/pressemitteilung-loeschen-oder-aendern-lassen', false)
->assertSee('/de/pressemitteilung-veroeffentlichen-ohne-abo', false);
$this->get('https://presseecho.test/sitemap.xml')->assertSuccessful()
->assertSee('<loc>https://presseecho.test/de/was-kostet-eine-pressemitteilung</loc>', false);
$this->get('https://pressekonto.test/sitemap.xml')->assertSuccessful()
->assertSee('<loc>https://pressekonto.test/de/pressemitteilung-loeschen-oder-aendern-lassen</loc>', false);
});