hash); $directory = $root.DIRECTORY_SEPARATOR.substr($hash, 0, 2).DIRECTORY_SEPARATOR.substr($hash, 2, 2); File::ensureDirectoryExists($directory); $path = $directory.DIRECTORY_SEPARATOR.$hash.'.png'; $file = UploadedFile::fake()->image($hash.'.png', 1800, 1200); file_put_contents($path, $file->get()); return $path; } function insertFeaturedArtworkRow(Artwork $artwork): void { DB::table('artwork_features')->insert([ 'artwork_id' => $artwork->id, 'featured_at' => now()->subHour(), 'expires_at' => null, 'priority' => 500, 'label' => null, 'note' => null, 'is_active' => true, 'force_hero' => true, 'created_by' => null, 'created_at' => now(), 'updated_at' => now(), 'deleted_at' => null, ]); } test('featured thumbnail command generates dedicated featured variants', function () { Storage::fake('s3'); $localRoot = storage_path('framework/testing/featured-originals-command'); $backupRoot = storage_path('framework/testing/featured-originals-command-backup'); File::deleteDirectory($localRoot); File::deleteDirectory($backupRoot); File::ensureDirectoryExists($localRoot); File::ensureDirectoryExists($backupRoot); config([ 'uploads.object_storage.disk' => 's3', 'uploads.local_originals_root' => $localRoot, 'uploads.readonly_backup_originals_root' => $backupRoot, 'cdn.files_url' => 'https://files.skinbase.org', ]); $owner = User::factory()->create(); $artwork = Artwork::factory()->create([ 'user_id' => $owner->id, 'title' => 'Featured Command Artwork', 'hash' => str_repeat('b', 64), 'file_ext' => 'png', 'thumb_ext' => 'webp', ]); insertFeaturedArtworkRow($artwork); makeFeaturedArtworkSource($artwork, $localRoot); $this->artisan('skinbase:featured-thumbnails:generate', [ '--artwork' => [(string) $artwork->id], ])->assertExitCode(0); $paths = app(ArtworkFeaturedImagePath::class); foreach ($paths->variantNames() as $variant) { Storage::disk('s3')->assertExists($paths->objectPath($artwork, $variant)); } }); test('featured thumbnail generation purges Cloudflare for generated featured variants', function () { Http::fake([ 'https://api.cloudflare.com/client/v4/zones/test-zone/purge_cache' => Http::response(['success' => true], 200), ]); Storage::fake('s3'); $localRoot = storage_path('framework/testing/featured-originals-command-purge'); $backupRoot = storage_path('framework/testing/featured-originals-command-purge-backup'); File::deleteDirectory($localRoot); File::deleteDirectory($backupRoot); File::ensureDirectoryExists($localRoot); File::ensureDirectoryExists($backupRoot); config([ 'uploads.object_storage.disk' => 's3', 'uploads.local_originals_root' => $localRoot, 'uploads.readonly_backup_originals_root' => $backupRoot, 'cdn.files_url' => 'https://files.skinbase.org', 'cdn.cloudflare.zone_id' => 'test-zone', 'cdn.cloudflare.api_token' => 'test-token', ]); $owner = User::factory()->create(); $artwork = Artwork::factory()->create([ 'user_id' => $owner->id, 'title' => 'Featured Command Artwork Purge', 'hash' => str_repeat('d', 64), 'file_ext' => 'png', 'thumb_ext' => 'webp', ]); insertFeaturedArtworkRow($artwork); makeFeaturedArtworkSource($artwork, $localRoot); $this->artisan('skinbase:featured-thumbnails:generate', [ '--artwork' => [(string) $artwork->id], ])->assertExitCode(0); $paths = app(ArtworkFeaturedImagePath::class); $expectedUrls = collect($paths->variantNames()) ->map(fn (string $variant): string => $paths->url($artwork, $variant)) ->all(); Http::assertSent(function ($request) use ($expectedUrls): bool { $data = $request->data(); return $request->url() === 'https://api.cloudflare.com/client/v4/zones/test-zone/purge_cache' && $request->method() === 'POST' && ($data['files'] ?? null) === $expectedUrls; }); }); test('featured thumbnail command can queue generation jobs', function () { Queue::fake(); $owner = User::factory()->create(); $artwork = Artwork::factory()->create([ 'user_id' => $owner->id, 'hash' => str_repeat('c', 64), 'file_ext' => 'png', 'thumb_ext' => 'webp', ]); insertFeaturedArtworkRow($artwork); $this->artisan('skinbase:featured-thumbnails:generate', [ '--artwork' => [(string) $artwork->id], '--queue' => true, ])->assertExitCode(0); Queue::assertPushed(GenerateFeaturedArtworkThumbnailsJob::class, 1); });