pp-planer/tests/Feature/SongPrefixPostfixServiceTest.php
Thorsten Bus 42b8b5f428 fix(export): copyright/blank slides, bundle-relative media, probundle injection, song links
- populate COPYRIGHT (title/author/copyright/CCLI) + blank slides on every song; songHasContent ignores locked sections
- foreground info/moderation images now bundle-relative (fixes blank images)
- pre-added .probundle injection: Zip64-fix + verbatim .pro extraction (fixes empty bundle)
- nametag subtitle split (text + subtitle); smaller non-bold render
- skip songs with no content slides at export with German warning
- link service agenda songs to SongDB edit modal via #song-<id>
- allow CCLI import of metadata-only songs (no lyric sections)
- expose has_content_slides on service songs; show "Keine Inhaltsfolien"
2026-06-21 09:58:55 +02:00

109 lines
3.3 KiB
PHP

<?php
use App\Models\Setting;
use App\Models\Song;
use App\Models\SongSection;
use App\Models\SongSlide;
use App\Services\SongPrefixPostfixService;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('ensure populiert COPYRIGHT-Folie mit Attribution inkl. CCLI-Nummer', function (): void {
$song = Song::create([
'title' => 'Mein Lied',
'author' => 'Max Mustermann',
'copyright_text' => '© 2024 Verlag',
'ccli_id' => '1234567',
]);
app(SongPrefixPostfixService::class)->ensure($song);
$prefixLabelId = (int) Setting::get('song_prefix_label_id');
$prefixSection = SongSection::where('song_id', $song->id)
->where('label_id', $prefixLabelId)
->first();
expect($prefixSection)->not->toBeNull()
->and($prefixSection->locked)->toBeTrue();
$slides = $prefixSection->slides()->get();
expect($slides)->toHaveCount(1);
$expected = implode("\n", [
'Mein Lied',
'Max Mustermann',
'© 2024 Verlag',
'CCLI-Liednr. 1234567',
]);
expect($slides->first()->text_content)->toBe($expected);
});
test('ensure laesst leere Felder in der Attribution weg', function (): void {
$song = Song::create([
'title' => 'Nur Titel',
]);
app(SongPrefixPostfixService::class)->ensure($song);
$prefixLabelId = (int) Setting::get('song_prefix_label_id');
$slide = SongSection::where('song_id', $song->id)
->where('label_id', $prefixLabelId)
->first()
->slides()
->first();
expect($slide->text_content)->toBe('Nur Titel');
});
test('ensure erstellt eine leere BLANK-Folie in gesperrter Postfix-Sektion', function (): void {
$song = Song::create(['title' => 'Mein Lied', 'ccli_id' => '999']);
app(SongPrefixPostfixService::class)->ensure($song);
$postfixLabelId = (int) Setting::get('song_postfix_label_id');
$postfixSection = SongSection::where('song_id', $song->id)
->where('label_id', $postfixLabelId)
->first();
expect($postfixSection)->not->toBeNull()
->and($postfixSection->locked)->toBeTrue();
$slides = $postfixSection->slides()->get();
expect($slides)->toHaveCount(1)
->and($slides->first()->text_content)->toBe('');
});
test('default-Arrangement hat COPYRIGHT zuerst und BLANK zuletzt', function (): void {
$song = Song::create(['title' => 'Mein Lied', 'ccli_id' => '999']);
app(SongPrefixPostfixService::class)->ensure($song);
$prefixLabelId = (int) Setting::get('song_prefix_label_id');
$postfixLabelId = (int) Setting::get('song_postfix_label_id');
$arrangement = $song->arrangements()->where('name', 'normal')->first();
$ordered = $arrangement->arrangementSections()
->with('section')
->get()
->sortBy('order')
->values();
expect($ordered->first()->section->label_id)->toBe($prefixLabelId)
->and($ordered->last()->section->label_id)->toBe($postfixLabelId);
});
test('ensure ist idempotent und erzeugt keine doppelten Folien', function (): void {
$song = Song::create(['title' => 'Mein Lied', 'ccli_id' => '999']);
$service = app(SongPrefixPostfixService::class);
$service->ensure($song);
$service->ensure($song);
expect(SongSlide::count())->toBe(2);
});