prepareUploadContext(); Bus::fake(); $response = $this->postJson("/api/v1/events/{$token}/upload", [ 'photo' => UploadedFile::fake()->create('evil.svg', 10, 'image/svg+xml'), ]); $response->assertStatus(422); Bus::assertNothingDispatched(); } public function test_guest_upload_dispatches_security_scan_for_valid_image(): void { [$token] = $this->prepareUploadContext(); Bus::fake(); $response = $this->postJson("/api/v1/events/{$token}/upload", [ 'photo' => UploadedFile::fake()->image('photo.jpg', 800, 600), ]); $response->assertCreated() ->assertJsonPath('status', 'pending'); Bus::assertDispatched(ProcessPhotoSecurityScan::class); } /** * @return array{string} */ private function prepareUploadContext(): array { config(['filesystems.default' => 'public']); Storage::fake('public'); $tenant = Tenant::factory()->create(); $package = Package::factory()->endcustomer()->create([ 'max_photos' => 100, 'gallery_days' => 14, ]); $eventType = EventType::factory()->create(); $event = Event::factory()->create([ 'tenant_id' => $tenant->id, 'event_type_id' => $eventType->id, 'status' => 'published', 'photo_upload_enabled' => true, ]); MediaStorageTarget::create([ 'key' => 'public', 'name' => 'Public (test)', 'driver' => 'local', 'config' => [ 'root' => Storage::disk('public')->path(''), 'url' => 'http://localhost/storage', 'visibility' => 'public', ], 'is_hot' => true, 'is_default' => true, 'is_active' => true, 'priority' => 10, ]); EventPackage::create([ 'event_id' => $event->id, 'package_id' => $package->id, 'purchased_price' => $package->price, 'purchased_at' => now(), 'used_photos' => 0, 'gallery_expires_at' => now()->addDays($package->gallery_days ?? 30), ]); $token = app(EventJoinTokenService::class) ->createToken($event, ['label' => 'Test upload']) ->getAttribute('plain_token'); return [$token]; } }