presseportale/tests/Feature/PressReleaseMediaPrivatizerTest.php
Kevin Adametz 6250b0bab4 media: PM-Medien privat ausliefern + Vorschau-Signatur (M4, M5, Fix#4/#5)
- Neue PM-Bilder/Anhänge liegen auf der privaten local-Disk; Auslieferung
  über kontrollierte Media-Routen mit gemeinsamer Zugriffslogik
  (AuthorizesPressReleaseMediaAccess). Öffentliche Medien werden aus den
  geladenen Modellen ermittelt (weniger Queries) und länger gecacht.
- Anonyme Token-Vorschau lädt Bilder über temporär signierte URLs (Fix#5).
- API-Resource baut Variant-URLs über die Media-Route statt /storage
  (Fix#4). Storage-Schicht prüft zusätzlich den serverseitigen MIME-Type (M5).
- press-releases:privatize-media migriert Bestandsmedien.

Deployment: einmalig `php artisan press-releases:privatize-media` ausführen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 13:48:06 +00:00

59 lines
2.2 KiB
PHP

<?php
use App\Models\PressRelease;
use App\Services\PressRelease\PressReleaseMediaPrivatizer;
use Illuminate\Support\Facades\Storage;
test('existing public press release media is moved to private storage', function () {
Storage::fake('public');
Storage::fake('local');
$pressRelease = PressRelease::factory()->create();
$image = $pressRelease->images()->create([
'disk' => 'public',
'path' => "press-releases/{$pressRelease->id}/images/cover.jpg",
'variants' => [
'thumb' => "press-releases/{$pressRelease->id}/images/thumb.jpg",
],
]);
$attachment = $pressRelease->attachments()->create([
'disk' => 'public',
'path' => "press-releases/{$pressRelease->id}/attachments/factsheet.pdf",
'original_name' => 'factsheet.pdf',
'mime' => 'application/pdf',
'size' => 10,
]);
foreach ([$image->path, $image->variants['thumb'], $attachment->path] as $path) {
Storage::disk('public')->put($path, 'content');
}
$this->artisan('press-releases:privatize-media')
->expectsOutput('1 Bilder und 1 Anhänge wurden auf den privaten Datenträger migriert.')
->assertSuccessful();
foreach ([$image->path, $image->variants['thumb'], $attachment->path] as $path) {
Storage::disk('public')->assertMissing($path);
Storage::disk('local')->assertExists($path);
}
expect($image->fresh()->disk)->toBe('local')
->and($attachment->fresh()->disk)->toBe('local');
});
test('a missing source file never flips its database record to the private disk', function () {
Storage::fake('public');
Storage::fake('local');
$pressRelease = PressRelease::factory()->create();
$attachment = $pressRelease->attachments()->create([
'disk' => 'public',
'path' => "press-releases/{$pressRelease->id}/attachments/missing.pdf",
'original_name' => 'missing.pdf',
'mime' => 'application/pdf',
'size' => 10,
]);
expect(fn () => app(PressReleaseMediaPrivatizer::class)->privatizeAll())
->toThrow(RuntimeException::class, 'missing on both disks');
expect($attachment->fresh()->disk)->toBe('public');
});