testDir = '/tmp/test_show_image'; if (!is_dir($this->testDir)) { mkdir($this->testDir, 0755, true); } $this->testImagePath = $this->testDir . '/test-show.jpg'; file_put_contents($this->testImagePath, 'fake-jpeg-content'); // Mock repositories $this->imageRepository = Mockery::mock(ImageRepository::class); $this->imageVariantRepository = Mockery::mock(ImageVariantRepository::class); $this->pathProvider = Mockery::mock(PathProvider::class); // Create controller $this->controller = new ShowImage( $this->pathProvider, $this->imageRepository, $this->imageVariantRepository ); // Test image entity $this->testImage = new Image( ulid: Ulid::generate(), filename: 'test-show.jpg', originalFilename: 'original.jpg', mimeType: MimeType::fromString('image/jpeg'), fileSize: FileSize::fromBytes(strlen('fake-jpeg-content')), width: 300, height: 400, hash: Hash::fromString('test-hash'), path: FilePath::create($this->testDir), altText: 'Test show image' ); }); afterEach(function () { if (file_exists($this->testImagePath)) { unlink($this->testImagePath); } if (is_dir($this->testDir)) { rmdir($this->testDir); } Mockery::close(); }); it('can serve existing image file', function () { // Arrange $filename = 'test-show.jpg'; $request = Mockery::mock(HttpRequest::class); $this->imageRepository ->shouldReceive('findByFilename') ->with($filename) ->andReturn($this->testImage); // Act $result = $this->controller->__invoke($filename, $request); // Assert expect($result)->toBeInstanceOf(FileResult::class); }); it('falls back to image variant repository when image not found', function () { // Arrange $filename = 'variant-image.jpg'; $request = Mockery::mock(HttpRequest::class); $this->imageRepository ->shouldReceive('findByFilename') ->with($filename) ->andReturn(null); $this->imageVariantRepository ->shouldReceive('findByFilename') ->with($filename) ->andReturn($this->testImage); // Act $result = $this->controller->__invoke($filename, $request); // Assert expect($result)->toBeInstanceOf(FileResult::class); }); it('throws exception when image not found in either repository', function () { // Arrange $filename = 'nonexistent.jpg'; $request = Mockery::mock(HttpRequest::class); $this->imageRepository ->shouldReceive('findByFilename') ->with($filename) ->andReturn(null); $this->imageVariantRepository ->shouldReceive('findByFilename') ->with($filename) ->andReturn(null); // Act & Assert expect(fn() => $this->controller->__invoke($filename, $request)) ->toThrow(FrameworkException::class, 'Image not found: nonexistent.jpg'); }); it('throws exception when image file does not exist on filesystem', function () { // Arrange $filename = 'missing-file.jpg'; $request = Mockery::mock(HttpRequest::class); $missingFileImage = new Image( ulid: Ulid::generate(), filename: 'missing-file.jpg', originalFilename: 'original.jpg', mimeType: MimeType::fromString('image/jpeg'), fileSize: FileSize::fromBytes(100), width: 300, height: 400, hash: Hash::fromString('test-hash'), path: FilePath::create('/nonexistent/path'), altText: 'Missing file' ); $this->imageRepository ->shouldReceive('findByFilename') ->with($filename) ->andReturn($missingFileImage); // Act & Assert expect(fn() => $this->controller->__invoke($filename, $request)) ->toThrow(FrameworkException::class, 'Image file not found on filesystem'); }); it('determines correct MIME type based on file extension', function () { // Test JPEG $jpegFilename = 'test.jpg'; $jpegImage = $this->testImage->withFilename($jpegFilename); $request = Mockery::mock(HttpRequest::class); $this->imageRepository ->shouldReceive('findByFilename') ->with($jpegFilename) ->andReturn($jpegImage); $result = $this->controller->__invoke($jpegFilename, $request); expect($result)->toBeInstanceOf(FileResult::class); }); it('handles different image file extensions', function () { $extensions = [ 'test.png' => 'image/png', 'test.gif' => 'image/gif', 'test.webp' => 'image/webp', 'test.avif' => 'image/avif', 'test.unknown' => 'image/jpeg' // fallback ]; foreach ($extensions as $filename => $expectedMime) { // Create test file for each extension $testPath = $this->testDir . '/' . $filename; file_put_contents($testPath, 'fake-content'); $testImage = $this->testImage->withFilename($filename); $request = Mockery::mock(HttpRequest::class); $this->imageRepository ->shouldReceive('findByFilename') ->with($filename) ->andReturn($testImage); $result = $this->controller->__invoke($filename, $request); expect($result)->toBeInstanceOf(FileResult::class); // Clean up unlink($testPath); } });