clock = new SystemClock(); $this->objectStorage = Mockery::mock(ObjectStorage::class); $this->adapter = new ObjectStorageAdapter($this->objectStorage); }); it('puts asset content to storage', function () { $asset = AssetTestHelpers::createAsset($this->clock); $content = 'test-content'; $this->objectStorage->shouldReceive('put') ->once() ->with($asset->bucket->toString(), $asset->key->toString(), $content) ->andReturnNull(); $this->adapter->put($asset, $content); }); it('gets asset content from storage', function () { $asset = AssetTestHelpers::createAsset($this->clock); $content = 'test-content'; $this->objectStorage->shouldReceive('get') ->once() ->with($asset->bucket->toString(), $asset->key->toString()) ->andReturn($content); $result = $this->adapter->get($asset); expect($result)->toBe($content); }); it('checks if asset exists in storage', function () { $asset = AssetTestHelpers::createAsset($this->clock); $this->objectStorage->shouldReceive('exists') ->once() ->with($asset->bucket->toString(), $asset->key->toString()) ->andReturn(true); expect($this->adapter->exists($asset))->toBeTrue(); }); it('deletes asset from storage', function () { $asset = AssetTestHelpers::createAsset($this->clock); $this->objectStorage->shouldReceive('delete') ->once() ->with($asset->bucket->toString(), $asset->key->toString()) ->andReturnNull(); $this->adapter->delete($asset); }); it('gets URL from object storage', function () { $asset = AssetTestHelpers::createAsset($this->clock); $url = 'https://storage.example.com/media/orig/test.jpg'; $this->objectStorage->shouldReceive('url') ->once() ->with($asset->bucket->toString(), $asset->key->toString()) ->andReturn($url); $result = $this->adapter->getUrl($asset); expect($result)->toBe($url); }); it('falls back to CDN URL when object storage returns null', function () { $asset = AssetTestHelpers::createAsset($this->clock); $cdnBaseUrl = 'https://cdn.example.com'; $adapter = new ObjectStorageAdapter($this->objectStorage, $cdnBaseUrl); $this->objectStorage->shouldReceive('url') ->once() ->with($asset->bucket->toString(), $asset->key->toString()) ->andReturn(null); $result = $adapter->getUrl($asset); expect($result)->toContain($cdnBaseUrl); expect($result)->toContain($asset->bucket->toString()); expect($result)->toContain($asset->key->toString()); }); it('falls back to storage path when no CDN configured', function () { $asset = AssetTestHelpers::createAsset($this->clock); $this->objectStorage->shouldReceive('url') ->once() ->with($asset->bucket->toString(), $asset->key->toString()) ->andReturn(null); $result = $this->adapter->getUrl($asset); expect($result)->toContain($asset->bucket->toString()); expect($result)->toContain($asset->key->toString()); }); it('gets signed URL from object storage', function () { $asset = AssetTestHelpers::createAsset($this->clock); $signedUrl = 'https://storage.example.com/media/orig/test.jpg?signature=abc123'; $expiresIn = 3600; $this->objectStorage->shouldReceive('temporaryUrl') ->once() ->with( $asset->bucket->toString(), $asset->key->toString(), Mockery::type(\DateInterval::class) ) ->andReturn($signedUrl); $result = $this->adapter->getSignedUrl($asset, $expiresIn); expect($result)->toBe($signedUrl); }); });