localizedCategoryName/cardImageUrl/teaserText/wordCount/readTimeMinutes/ compactPublishedLabel ersetzen die 5x kopierte @php-Logik der Kartenkomponenten; Lesezeit-Formel vereinheitlicht (ceil -> round in HomePageData-Spotlight). Tests: Web/PressReleaseCardHelpersTest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
63 lines
2.7 KiB
PHP
63 lines
2.7 KiB
PHP
<?php
|
|
|
|
use App\Enums\Portal;
|
|
use App\Models\Category;
|
|
use App\Models\PressRelease;
|
|
|
|
test('localizedCategoryName resolves the current locale with fallback to the first translation', function () {
|
|
$category = Category::factory()->create(['portal' => Portal::Businessportal24]);
|
|
$category->translations()->create(['locale' => 'de', 'name' => 'Energie & Klima', 'slug' => 'energie-klima']);
|
|
$category->translations()->create(['locale' => 'en', 'name' => 'Energy & Climate', 'slug' => 'energy-climate']);
|
|
|
|
$release = PressRelease::factory()->for($category)->create();
|
|
$release->load('category.translations');
|
|
|
|
app()->setLocale('de');
|
|
expect($release->localizedCategoryName())->toBe('Energie & Klima');
|
|
|
|
app()->setLocale('en');
|
|
expect($release->localizedCategoryName())->toBe('Energy & Climate');
|
|
|
|
// Fallback: Sprache ohne Übersetzung → erste vorhandene.
|
|
app()->setLocale('fr');
|
|
expect($release->localizedCategoryName())->toBe('Energie & Klima');
|
|
|
|
app()->setLocale('de');
|
|
});
|
|
|
|
test('teaserText strips tags, squishes whitespace and limits length', function () {
|
|
$release = PressRelease::factory()->create([
|
|
'text' => "<p>Erster Absatz.</p>\n<p>Zweiter Absatz mit <strong>Auszeichnung</strong>.</p>",
|
|
]);
|
|
|
|
expect($release->teaserText())->toBe('Erster Absatz. Zweiter Absatz mit Auszeichnung.')
|
|
->and($release->teaserText(13))->toBe('Erster Absatz...');
|
|
});
|
|
|
|
test('readTimeMinutes rounds at 200 words per minute with a minimum of one', function () {
|
|
$short = PressRelease::factory()->create(['text' => 'Nur wenige Worte.']);
|
|
$long = PressRelease::factory()->create(['text' => implode(' ', array_fill(0, 450, 'Wort'))]);
|
|
|
|
expect($short->wordCount())->toBe(3)
|
|
->and($short->readTimeMinutes())->toBe(1)
|
|
->and($long->readTimeMinutes())->toBe(2);
|
|
});
|
|
|
|
test('compactPublishedLabel formats today, yesterday and older dates', function () {
|
|
$today = PressRelease::factory()->create(['published_at' => now()->setTime(9, 30)]);
|
|
$yesterday = PressRelease::factory()->create(['published_at' => now()->subDay()]);
|
|
$older = PressRelease::factory()->create(['published_at' => now()->parse('2026-03-05 08:00')]);
|
|
$unpublished = PressRelease::factory()->create(['published_at' => null]);
|
|
|
|
expect($today->compactPublishedLabel())->toBe('09:30')
|
|
->and($yesterday->compactPublishedLabel())->toBe(__('web.shared.yesterday'))
|
|
->and($older->compactPublishedLabel())->toBe($older->published_at->isoFormat('D. MMM'))
|
|
->and($unpublished->compactPublishedLabel())->toBeNull();
|
|
});
|
|
|
|
test('cardImageUrl is null for releases without images', function () {
|
|
$release = PressRelease::factory()->create();
|
|
$release->load('images');
|
|
|
|
expect($release->cardImageUrl())->toBeNull();
|
|
});
|