create(); $service = Service::factory()->create(); $agendaItem = ServiceAgendaItem::factory()->create([ 'service_id' => $service->id, 'title' => 'Predigt', 'sort_order' => 1, 'service_song_id' => null, 'is_before_event' => false, ]); Storage::disk('public')->put('slides/predigt-1.jpg', 'fake-image-1'); Storage::disk('public')->put('slides/predigt-2.jpg', 'fake-image-2'); Slide::factory()->create([ 'service_id' => $service->id, 'service_agenda_item_id' => $agendaItem->id, 'type' => 'sermon', 'stored_filename' => 'slides/predigt-1.jpg', 'original_filename' => 'Predigt Folie 1.jpg', 'sort_order' => 0, ]); Slide::factory()->create([ 'service_id' => $service->id, 'service_agenda_item_id' => $agendaItem->id, 'type' => 'sermon', 'stored_filename' => 'slides/predigt-2.jpg', 'original_filename' => 'Predigt Folie 2.jpg', 'sort_order' => 1, ]); $response = $this->actingAs($user)->get( route('services.agenda-item.download', [ 'service' => $service, 'agendaItem' => $agendaItem, ]) ); $response->assertOk(); $response->assertHeader('content-type', 'application/zip'); $baseResponse = $response->baseResponse; $this->assertInstanceOf(BinaryFileResponse::class, $baseResponse); $copiedPath = sys_get_temp_dir().'/agenda-test-'.uniqid().'.probundle'; copy($baseResponse->getFile()->getPathname(), $copiedPath); $zip = new ZipArchive; $this->assertTrue($zip->open($copiedPath) === true); $this->assertSame(3, $zip->numFiles); $names = []; for ($i = 0; $i < $zip->numFiles; $i++) { $name = $zip->getNameIndex($i); if ($name !== false) { $names[] = $name; } } $proEntry = array_values(array_filter($names, fn (string $n) => str_ends_with($n, '.pro'))); $this->assertCount(1, $proEntry, '.probundle muss genau eine .pro Datei enthalten'); $this->assertContains('predigt-1.jpg', $names); $this->assertContains('predigt-2.jpg', $names); $this->assertSame('fake-image-1', $zip->getFromName('predigt-1.jpg')); $this->assertSame('fake-image-2', $zip->getFromName('predigt-2.jpg')); $zip->close(); @unlink($copiedPath); } public function test_song_agenda_item_liefert_probundle_mit_pro_daten(): void { $user = User::factory()->create(); $service = Service::factory()->create(); $song = Song::factory()->create(['title' => 'Amazing Grace']); $group = SongGroup::factory()->create(['song_id' => $song->id, 'name' => 'Verse 1', 'order' => 1]); SongSlide::factory()->create(['song_group_id' => $group->id, 'text_content' => 'Amazing grace how sweet the sound', 'order' => 1]); $serviceSong = ServiceSong::create([ 'service_id' => $service->id, 'song_id' => $song->id, 'song_arrangement_id' => null, 'use_translation' => false, 'order' => 1, 'cts_song_name' => 'Amazing Grace', 'cts_ccli_id' => '12345', ]); $agendaItem = ServiceAgendaItem::factory()->create([ 'service_id' => $service->id, 'title' => 'Amazing Grace', 'sort_order' => 1, 'service_song_id' => $serviceSong->id, 'is_before_event' => false, ]); $response = $this->actingAs($user)->get( route('services.agenda-item.download', [ 'service' => $service, 'agendaItem' => $agendaItem, ]) ); $response->assertOk(); $response->assertHeader('content-type', 'application/zip'); $baseResponse = $response->baseResponse; $this->assertInstanceOf(BinaryFileResponse::class, $baseResponse); $copiedPath = sys_get_temp_dir().'/agenda-song-test-'.uniqid().'.probundle'; copy($baseResponse->getFile()->getPathname(), $copiedPath); $zip = new ZipArchive; $this->assertTrue($zip->open($copiedPath) === true); $this->assertSame(1, $zip->numFiles); $this->assertTrue(str_ends_with($zip->getNameIndex(0), '.pro'), '.probundle muss eine .pro Datei enthalten'); $proContent = $zip->getFromName($zip->getNameIndex(0)); $this->assertNotFalse($proContent); $this->assertGreaterThan(0, strlen($proContent)); $zip->close(); @unlink($copiedPath); } public function test_agenda_item_von_anderem_service_liefert_404(): void { $user = User::factory()->create(); $service = Service::factory()->create(); $otherService = Service::factory()->create(); $agendaItem = ServiceAgendaItem::factory()->create([ 'service_id' => $otherService->id, 'title' => 'Fremd', 'sort_order' => 1, 'is_before_event' => false, ]); $response = $this->actingAs($user)->get( route('services.agenda-item.download', [ 'service' => $service, 'agendaItem' => $agendaItem, ]) ); $response->assertNotFound(); } public function test_agenda_item_ohne_slides_und_ohne_song_liefert_leeres_probundle(): void { $user = User::factory()->create(); $service = Service::factory()->create(); $agendaItem = ServiceAgendaItem::factory()->create([ 'service_id' => $service->id, 'title' => 'Leer', 'sort_order' => 1, 'service_song_id' => null, 'is_before_event' => false, ]); $response = $this->actingAs($user)->get( route('services.agenda-item.download', [ 'service' => $service, 'agendaItem' => $agendaItem, ]) ); $response->assertOk(); $baseResponse = $response->baseResponse; $this->assertInstanceOf(BinaryFileResponse::class, $baseResponse); $copiedPath = sys_get_temp_dir().'/agenda-empty-test-'.uniqid().'.probundle'; copy($baseResponse->getFile()->getPathname(), $copiedPath); $zip = new ZipArchive; $this->assertTrue($zip->open($copiedPath) === true); $this->assertSame(1, $zip->numFiles); $this->assertTrue(str_ends_with($zip->getNameIndex(0), '.pro'), 'Einziger Eintrag muss .pro Datei sein'); $zip->close(); @unlink($copiedPath); } public function test_erfordert_authentifizierung(): void { $service = Service::factory()->create(); $agendaItem = ServiceAgendaItem::factory()->create([ 'service_id' => $service->id, 'is_before_event' => false, ]); $response = $this->get( route('services.agenda-item.download', [ 'service' => $service, 'agendaItem' => $agendaItem, ]) ); $response->assertRedirect(route('login')); } }