pp-planer/tests/Feature/ProBundleExportTest.php

142 lines
4.7 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Service;
use App\Models\Slide;
use App\Models\User;
use Illuminate\Foundation\Testing\Concerns\InteractsWithAuthentication;
use Illuminate\Foundation\Testing\Concerns\MakesHttpRequests;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Tests\TestCase;
use ZipArchive;
final class ProBundleExportTest extends TestCase
{
use InteractsWithAuthentication;
use MakesHttpRequests;
use RefreshDatabase;
public function test_probundle_enthaelt_data_und_bilder(): void
{
Storage::fake('public');
$user = User::factory()->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);
}
}