create(); $service = Service::factory()->create(); $filenames = [ 'info-1.jpg', 'info-2.jpg', 'info-3.jpg', ]; foreach ($filenames as $index => $filename) { Storage::disk('public')->put('slides/'.$filename, 'fake-image-content-'.$index); Slide::factory()->create([ 'service_id' => $service->id, 'type' => 'information', 'stored_filename' => $filename, 'original_filename' => 'Original '.$filename, 'sort_order' => $index, ]); } $response = $this->actingAs($user)->get(route('services.download-bundle', [ 'service' => $service, 'blockType' => 'information', ])); $response->assertOk(); $response->assertHeader('content-type', 'application/zip'); $baseResponse = $response->baseResponse; if (! $baseResponse instanceof BinaryFileResponse) { $this->fail('Es wurde keine Dateiantwort zurückgegeben.'); } $copiedPath = sys_get_temp_dir().'/probundle-test-'.uniqid().'.probundle'; copy($baseResponse->getFile()->getPathname(), $copiedPath); $zip = new ZipArchive; $openResult = $zip->open($copiedPath); $this->assertTrue($openResult === true); $this->assertSame(4, $zip->numFiles); $names = []; for ($i = 0; $i < $zip->numFiles; $i++) { $name = $zip->getNameIndex($i); if ($name !== false) { $names[] = $name; } } $this->assertContains('data', $names, '.probundle muss einen data-Eintrag (Protobuf) enthalten'); $this->assertContains('info-1.jpg', $names); $this->assertContains('info-2.jpg', $names); $this->assertContains('info-3.jpg', $names); // Verify media files contain actual content, not file paths foreach ($filenames as $index => $filename) { $content = $zip->getFromName($filename); $this->assertSame('fake-image-content-'.$index, $content, "Bildinhalt von {$filename} muss korrekt sein"); } // Verify data entry is non-empty protobuf (not a file path) $dataContent = $zip->getFromName('data'); $this->assertNotFalse($dataContent, 'data-Eintrag muss existieren'); $this->assertGreaterThan(0, strlen($dataContent), 'data-Eintrag darf nicht leer sein'); $this->assertFalse(str_starts_with($dataContent, '/'), 'data-Eintrag darf kein Dateipfad sein'); $zip->close(); @unlink($copiedPath); } public function test_ungueltiger_block_type_liefert_422(): void { $user = User::factory()->create(); $service = Service::factory()->create(); $response = $this->actingAs($user)->getJson(route('services.download-bundle', [ 'service' => $service, 'blockType' => 'ungueltig', ])); $response->assertStatus(422); } public function test_probundle_ohne_slides_enthaelt_nur_data(): void { $user = User::factory()->create(); $service = Service::factory()->create(); $response = $this->actingAs($user)->get(route('services.download-bundle', [ 'service' => $service, 'blockType' => 'sermon', ])); $response->assertOk(); $baseResponse = $response->baseResponse; if (! $baseResponse instanceof BinaryFileResponse) { $this->fail('Es wurde keine Dateiantwort zurückgegeben.'); } $copiedPath = sys_get_temp_dir().'/probundle-empty-test-'.uniqid().'.probundle'; copy($baseResponse->getFile()->getPathname(), $copiedPath); $zip = new ZipArchive; $openResult = $zip->open($copiedPath); $this->assertTrue($openResult === true); $this->assertSame(1, $zip->numFiles); $this->assertSame('data', $zip->getNameIndex(0)); $zip->close(); @unlink($copiedPath); } }