'array']); Cache::store('array')->flush(); } public function test_generates_named_variants_and_removes_them_with_original(): void { Storage::fake('public'); $manager = new ImageManager(new Driver); $original = $manager->create(2000, 1200)->toJpeg(quality: 90); $path = 'content/abc123.jpg'; Storage::disk('public')->put($path, (string) $original); ResponsiveImage::generate($path, 'public'); Storage::disk('public')->assertExists('content/abc123-480.jpg'); Storage::disk('public')->assertExists('content/abc123-960.jpg'); Storage::disk('public')->assertExists('content/abc123-1440.jpg'); $variant480 = (new ImageManager(new Driver))->read(Storage::disk('public')->path('content/abc123-480.jpg')); $this->assertSame(480, $variant480->width()); ResponsiveImage::delete($path, 'public'); Storage::disk('public')->assertMissing($path); Storage::disk('public')->assertMissing('content/abc123-480.jpg'); Storage::disk('public')->assertMissing('content/abc123-960.jpg'); Storage::disk('public')->assertMissing('content/abc123-1440.jpg'); } public function test_replace_deletes_previous_variants_and_generates_for_new_original(): void { Storage::fake('public'); $manager = new ImageManager(new Driver); Storage::disk('public')->put('content/old.jpg', (string) $manager->create(1600, 900)->toJpeg()); ResponsiveImage::generate('content/old.jpg', 'public'); Storage::disk('public')->put('content/new.jpg', (string) $manager->create(1800, 1000)->toJpeg()); ResponsiveImage::replace('content/old.jpg', 'content/new.jpg', 'public'); Storage::disk('public')->assertMissing('content/old.jpg'); Storage::disk('public')->assertMissing('content/old-480.jpg'); Storage::disk('public')->assertExists('content/new.jpg'); Storage::disk('public')->assertExists('content/new-480.jpg'); Storage::disk('public')->assertExists('content/new-960.jpg'); Storage::disk('public')->assertExists('content/new-1440.jpg'); } public function test_generates_a_webp_sibling_for_every_variant(): void { Storage::fake('public'); $manager = new ImageManager(new Driver); $path = 'content/photo.jpg'; Storage::disk('public')->put($path, (string) $manager->create(2000, 1200)->toJpeg(quality: 90)); ResponsiveImage::generate($path, 'public'); foreach (ResponsiveImage::WIDTHS as $width) { Storage::disk('public')->assertExists("content/photo-{$width}.jpg.webp"); } $this->assertSame( ResponsiveImage::WIDTHS, array_column(ResponsiveImage::availableWebpVariants($path, 'public'), 'width'), ); // The original format stays available so a browser that cannot decode // webp still has something to fall back to through the . foreach (ResponsiveImage::WIDTHS as $width) { Storage::disk('public')->assertExists("content/photo-{$width}.jpg"); } ResponsiveImage::delete($path, 'public'); foreach (ResponsiveImage::WIDTHS as $width) { Storage::disk('public')->assertMissing("content/photo-{$width}.jpg.webp"); } } public function test_webp_originals_do_not_get_a_duplicate_webp_sibling(): void { Storage::fake('public'); $manager = new ImageManager(new Driver); $path = 'content/already.webp'; Storage::disk('public')->put($path, (string) $manager->create(1600, 900)->toWebp()); ResponsiveImage::generate($path, 'public'); Storage::disk('public')->assertExists('content/already-480.webp'); Storage::disk('public')->assertMissing('content/already-480.webp.webp'); $this->assertSame([], ResponsiveImage::availableWebpVariants($path, 'public')); } public function test_metadata_is_cached_after_the_first_storage_read(): void { Storage::fake('public'); $manager = new ImageManager(new Driver); $path = 'content/cached.jpg'; Storage::disk('public')->put($path, (string) $manager->create(1600, 900)->toJpeg()); ResponsiveImage::generate($path, 'public'); $metadata = ResponsiveImage::metadata($path, 'public'); $this->assertSame(['width' => 1600, 'height' => 900], [ 'width' => $metadata['width'], 'height' => $metadata['height'], ]); $this->assertSame(ResponsiveImage::WIDTHS, array_column($metadata['variants'], 'width')); $this->assertSame(ResponsiveImage::WIDTHS, array_column($metadata['webp_variants'], 'width')); Storage::disk('public')->delete(array_merge( [$path], array_map(fn (int $width): string => ResponsiveImage::variantPath($path, $width), ResponsiveImage::WIDTHS), array_map(fn (int $width): string => ResponsiveImage::webpVariantPath($path, $width), ResponsiveImage::WIDTHS), )); $this->assertSame($metadata, ResponsiveImage::metadata($path, 'public')); } public function test_generation_populates_metadata_and_deletion_invalidates_it(): void { Storage::fake('public'); $manager = new ImageManager(new Driver); $path = 'content/generated.jpg'; Storage::disk('public')->put($path, (string) $manager->create(1400, 800)->toJpeg()); ResponsiveImage::generate($path, 'public'); $this->assertSame(['width' => 1400, 'height' => 800], ResponsiveImage::dimensions($path, 'public')); $this->assertSame(ResponsiveImage::WIDTHS, array_column(ResponsiveImage::availableVariants($path, 'public'), 'width')); ResponsiveImage::delete($path, 'public'); $this->assertNull(ResponsiveImage::metadata($path, 'public')); } public function test_replacement_invalidates_old_metadata_and_populates_new_metadata(): void { Storage::fake('public'); $manager = new ImageManager(new Driver); Storage::disk('public')->put('content/old-metadata.jpg', (string) $manager->create(1600, 900)->toJpeg()); ResponsiveImage::generate('content/old-metadata.jpg', 'public'); ResponsiveImage::metadata('content/old-metadata.jpg', 'public'); Storage::disk('public')->put('content/new-metadata.jpg', (string) $manager->create(1200, 675)->toJpeg()); ResponsiveImage::replace('content/old-metadata.jpg', 'content/new-metadata.jpg', 'public'); $this->assertNull(ResponsiveImage::metadata('content/old-metadata.jpg', 'public')); $this->assertSame(['width' => 1200, 'height' => 675], ResponsiveImage::dimensions('content/new-metadata.jpg', 'public')); } public function test_metadata_falls_back_safely_when_the_cache_is_unavailable(): void { Cache::shouldReceive('get') ->once() ->andThrow(new RuntimeException('Cache unavailable')); $this->assertNull(ResponsiveImage::metadata('content/unavailable.jpg', 'public')); } }