testDir = '/tmp/test_images'; if (!is_dir($this->testDir)) { mkdir($this->testDir, 0755, true); } // Create test image file $this->testImagePath = $this->testDir . '/test.jpg'; file_put_contents($this->testImagePath, 'fake-image-content'); // Create Clock instance $clock = new SystemClock(); $this->testImage = new Image( ulid: Ulid::fromString($clock, '00MF9VW9R36NJN3VCFSTS2CK6R'), filename: 'test.jpg', originalFilename: 'original-test.jpg', mimeType: MimeType::fromString('image/jpeg'), fileSize: FileSize::fromBytes(strlen('fake-image-content')), width: 100, height: 200, hash: Hash::fromString('2f36ee4cde5b43e02c118f4b21e5a4904d0c13597b5c2f1127097b808080622d'), path: FilePath::create($this->testDir), altText: 'Test image' ); }); afterEach(function () { // Clean up test files if (file_exists($this->testImagePath)) { unlink($this->testImagePath); } if (is_dir($this->testDir)) { rmdir($this->testDir); } }); it('can create Image entity with Value Objects', function () { expect($this->testImage->filename)->toBe('test.jpg'); expect($this->testImage->originalFilename)->toBe('original-test.jpg'); expect($this->testImage->width)->toBe(100); expect($this->testImage->height)->toBe(200); expect($this->testImage->altText)->toBe('Test image'); }); it('can get full file path using FilePath join', function () { $fullPath = $this->testImage->path->join($this->testImage->filename); expect($fullPath->toString())->toBe($this->testDir . '/test.jpg'); }); it('can check if image file exists on filesystem', function () { $fullPath = $this->testImage->path->join($this->testImage->filename); expect(file_exists($fullPath->toString()))->toBeTrue(); }); it('returns correct MIME type', function () { expect($this->testImage->mimeType->value)->toBe('image/jpeg'); expect($this->testImage->mimeType->isImage())->toBeTrue(); }); it('can verify hash', function () { $testHash = Hash::fromString('2f36ee4cde5b43e02c118f4b21e5a4904d0c13597b5c2f1127097b808080622d'); expect($this->testImage->verifyHash($testHash))->toBeTrue(); $wrongHash = Hash::fromString('1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'); expect($this->testImage->verifyHash($wrongHash))->toBeFalse(); }); it('can get human readable file size', function () { $readableSize = $this->testImage->getHumanReadableFileSize(); expect($readableSize)->toBeString(); expect(strlen($readableSize))->toBeGreaterThan(0); }); it('can get image dimensions and aspect ratio', function () { $dimensions = $this->testImage->getDimensions(); expect($dimensions->width)->toBe(100); expect($dimensions->height)->toBe(200); $aspectRatio = $this->testImage->getAspectRatio(); expect($aspectRatio)->toBe(0.5); // 100/200 expect($this->testImage->isPortrait())->toBeTrue(); expect($this->testImage->isLandscape())->toBeFalse(); expect($this->testImage->isSquare())->toBeFalse(); }); it('can create immutable copy with updated filename', function () { $newImage = $this->testImage->withFilename('new-name.jpg'); expect($newImage->filename)->toBe('new-name.jpg'); expect($this->testImage->filename)->toBe('test.jpg'); // Original unchanged expect($newImage->ulid)->toEqual($this->testImage->ulid); // Other properties same }); it('can create immutable copy with updated alt text', function () { $newImage = $this->testImage->withAltText('Updated alt text'); expect($newImage->altText)->toBe('Updated alt text'); expect($this->testImage->altText)->toBe('Test image'); // Original unchanged }); it('can create immutable copy with updated path', function () { $newPath = FilePath::create('/new/path'); $newImage = $this->testImage->withPath($newPath); expect($newImage->path->toString())->toBe('/new/path'); expect($this->testImage->path->toString())->toBe($this->testDir); // Original unchanged });