'local-hot', 'name' => 'Local Hot', 'driver' => 'local', 'config' => ['monitor_path' => storage_path('app')], 'is_hot' => true, 'is_default' => true, 'is_active' => true, 'priority' => 100, ]); $event = Event::factory()->create(['status' => 'published']); $package = Package::factory()->create(['gallery_days' => 1]); EventPackage::create([ 'event_id' => $event->id, 'package_id' => $package->id, 'purchased_price' => 0, 'purchased_at' => now()->subDays(10), 'used_photos' => 0, 'used_guests' => 0, 'gallery_expires_at' => now()->subDays(5), ]); EventMediaAsset::create([ 'event_id' => $event->id, 'media_storage_target_id' => $target->id, 'variant' => 'original', 'disk' => 'local-hot', 'path' => 'events/'.$event->id.'/photo.jpg', 'size_bytes' => 1024, 'status' => 'hot', ]); Queue::fake(); $this->artisan('storage:archive-pending') ->expectsOutput('Dispatched 1 archive job(s).') ->assertExitCode(0); Queue::assertPushed(ArchiveEventMediaAssets::class, fn ($job) => $job->eventId === $event->id); } public function test_skips_events_without_pending_assets(): void { $target = MediaStorageTarget::create([ 'key' => 'archive-only', 'name' => 'Archive Only', 'driver' => 'local', 'config' => ['monitor_path' => storage_path('app')], 'is_hot' => false, 'is_default' => false, 'is_active' => true, 'priority' => 50, ]); $event = Event::factory()->create(['status' => 'archived']); EventMediaAsset::create([ 'event_id' => $event->id, 'media_storage_target_id' => $target->id, 'variant' => 'original', 'disk' => 'archive-only', 'path' => 'events/'.$event->id.'/archived.jpg', 'size_bytes' => 1024, 'status' => 'archived', ]); Queue::fake(); $this->artisan('storage:archive-pending') ->expectsOutput('Dispatched 0 archive job(s).') ->assertExitCode(0); Queue::assertNothingPushed(); } public function test_skips_events_with_retention_override(): void { $target = MediaStorageTarget::create([ 'key' => 'local-hot', 'name' => 'Local Hot', 'driver' => 'local', 'config' => ['monitor_path' => storage_path('app')], 'is_hot' => true, 'is_default' => true, 'is_active' => true, 'priority' => 100, ]); $event = Event::factory()->create(['status' => 'published']); $package = Package::factory()->create(['gallery_days' => 1]); EventPackage::create([ 'event_id' => $event->id, 'package_id' => $package->id, 'purchased_price' => 0, 'purchased_at' => now()->subDays(10), 'used_photos' => 0, 'used_guests' => 0, 'gallery_expires_at' => now()->subDays(5), ]); EventMediaAsset::create([ 'event_id' => $event->id, 'media_storage_target_id' => $target->id, 'variant' => 'original', 'disk' => 'local-hot', 'path' => 'events/'.$event->id.'/photo.jpg', 'size_bytes' => 1024, 'status' => 'hot', ]); RetentionOverride::factory()->create([ 'scope' => RetentionOverrideScope::EVENT, 'tenant_id' => $event->tenant_id, 'event_id' => $event->id, ]); Queue::fake(); $this->artisan('storage:archive-pending') ->expectsOutput('Dispatched 0 archive job(s).') ->assertExitCode(0); Queue::assertNothingPushed(); } }