436 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			436 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			PHP
		
	
	
|  | <?php | ||
|  | 
 | ||
|  | namespace spec\League\Flysystem\Cached; | ||
|  | 
 | ||
|  | use League\Flysystem\AdapterInterface; | ||
|  | use League\Flysystem\Cached\CacheInterface; | ||
|  | use League\Flysystem\Config; | ||
|  | use PhpSpec\ObjectBehavior; | ||
|  | 
 | ||
|  | class CachedAdapterSpec extends ObjectBehavior | ||
|  | { | ||
|  |     /** | ||
|  |      * @var AdapterInterface | ||
|  |      */ | ||
|  |     private $adapter; | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @var CacheInterface | ||
|  |      */ | ||
|  |     private $cache; | ||
|  | 
 | ||
|  |     public function let(AdapterInterface $adapter, CacheInterface $cache) | ||
|  |     { | ||
|  |         $this->adapter = $adapter; | ||
|  |         $this->cache = $cache; | ||
|  |         $this->cache->load()->shouldBeCalled(); | ||
|  |         $this->beConstructedWith($adapter, $cache); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_is_initializable() | ||
|  |     { | ||
|  |         $this->shouldHaveType('League\Flysystem\Cached\CachedAdapter'); | ||
|  |         $this->shouldHaveType('League\Flysystem\AdapterInterface'); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_forward_read_streams() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $response = ['path' => $path]; | ||
|  |         $this->adapter->readStream($path)->willReturn($response); | ||
|  |         $this->readStream($path)->shouldbe($response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_writes() | ||
|  |     { | ||
|  |         $type = 'file'; | ||
|  |         $path = 'path.txt'; | ||
|  |         $contents = 'contents'; | ||
|  |         $config = new Config(); | ||
|  |         $response = compact('path', 'contents', 'type'); | ||
|  |         $this->adapter->write($path, $contents, $config)->willReturn($response); | ||
|  |         $this->cache->updateObject($path, $response, true)->shouldBeCalled(); | ||
|  |         $this->write($path, $contents, $config)->shouldBe($response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_streamed_writes() | ||
|  |     { | ||
|  |         $type = 'file'; | ||
|  |         $path = 'path.txt'; | ||
|  |         $stream = tmpfile(); | ||
|  |         $config = new Config(); | ||
|  |         $response = compact('path', 'stream', 'type'); | ||
|  |         $this->adapter->writeStream($path, $stream, $config)->willReturn($response); | ||
|  |         $this->cache->updateObject($path, ['contents' => false] + $response, true)->shouldBeCalled(); | ||
|  |         $this->writeStream($path, $stream, $config)->shouldBe($response); | ||
|  |         fclose($stream); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_streamed_updates() | ||
|  |     { | ||
|  |         $type = 'file'; | ||
|  |         $path = 'path.txt'; | ||
|  |         $stream = tmpfile(); | ||
|  |         $config = new Config(); | ||
|  |         $response = compact('path', 'stream', 'type'); | ||
|  |         $this->adapter->updateStream($path, $stream, $config)->willReturn($response); | ||
|  |         $this->cache->updateObject($path, ['contents' => false] + $response, true)->shouldBeCalled(); | ||
|  |         $this->updateStream($path, $stream, $config)->shouldBe($response); | ||
|  |         fclose($stream); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_writes() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $contents = 'contents'; | ||
|  |         $config = new Config(); | ||
|  |         $this->adapter->write($path, $contents, $config)->willReturn(false); | ||
|  |         $this->write($path, $contents, $config)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_streamed_writes() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $contents = tmpfile(); | ||
|  |         $config = new Config(); | ||
|  |         $this->adapter->writeStream($path, $contents, $config)->willReturn(false); | ||
|  |         $this->writeStream($path, $contents, $config)->shouldBe(false); | ||
|  |         fclose($contents); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_updated() | ||
|  |     { | ||
|  |         $type = 'file'; | ||
|  |         $path = 'path.txt'; | ||
|  |         $contents = 'contents'; | ||
|  |         $config = new Config(); | ||
|  |         $response = compact('path', 'contents', 'type'); | ||
|  |         $this->adapter->update($path, $contents, $config)->willReturn($response); | ||
|  |         $this->cache->updateObject($path, $response, true)->shouldBeCalled(); | ||
|  |         $this->update($path, $contents, $config)->shouldBe($response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_updates() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $contents = 'contents'; | ||
|  |         $config = new Config(); | ||
|  |         $this->adapter->update($path, $contents, $config)->willReturn(false); | ||
|  |         $this->update($path, $contents, $config)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_streamed_updates() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $contents = tmpfile(); | ||
|  |         $config = new Config(); | ||
|  |         $this->adapter->updateStream($path, $contents, $config)->willReturn(false); | ||
|  |         $this->updateStream($path, $contents, $config)->shouldBe(false); | ||
|  |         fclose($contents); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_renames() | ||
|  |     { | ||
|  |         $old = 'old.txt'; | ||
|  |         $new = 'new.txt'; | ||
|  |         $this->adapter->rename($old, $new)->willReturn(true); | ||
|  |         $this->cache->rename($old, $new)->shouldBeCalled(); | ||
|  |         $this->rename($old, $new)->shouldBe(true); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_rename_fails() | ||
|  |     { | ||
|  |         $old = 'old.txt'; | ||
|  |         $new = 'new.txt'; | ||
|  |         $this->adapter->rename($old, $new)->willReturn(false); | ||
|  |         $this->rename($old, $new)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_copies() | ||
|  |     { | ||
|  |         $old = 'old.txt'; | ||
|  |         $new = 'new.txt'; | ||
|  |         $this->adapter->copy($old, $new)->willReturn(true); | ||
|  |         $this->cache->copy($old, $new)->shouldBeCalled(); | ||
|  |         $this->copy($old, $new)->shouldBe(true); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_copy_fails() | ||
|  |     { | ||
|  |         $old = 'old.txt'; | ||
|  |         $new = 'new.txt'; | ||
|  |         $this->adapter->copy($old, $new)->willReturn(false); | ||
|  |         $this->copy($old, $new)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_deletes() | ||
|  |     { | ||
|  |         $delete = 'delete.txt'; | ||
|  |         $this->adapter->delete($delete)->willReturn(true); | ||
|  |         $this->cache->delete($delete)->shouldBeCalled(); | ||
|  |         $this->delete($delete)->shouldBe(true); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_delete_fails() | ||
|  |     { | ||
|  |         $delete = 'delete.txt'; | ||
|  |         $this->adapter->delete($delete)->willReturn(false); | ||
|  |         $this->delete($delete)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_dir_deletes() | ||
|  |     { | ||
|  |         $delete = 'delete'; | ||
|  |         $this->adapter->deleteDir($delete)->willReturn(true); | ||
|  |         $this->cache->deleteDir($delete)->shouldBeCalled(); | ||
|  |         $this->deleteDir($delete)->shouldBe(true); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_delete_dir_fails() | ||
|  |     { | ||
|  |         $delete = 'delete'; | ||
|  |         $this->adapter->deleteDir($delete)->willReturn(false); | ||
|  |         $this->deleteDir($delete)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_dir_creates() | ||
|  |     { | ||
|  |         $dirname = 'dirname'; | ||
|  |         $config = new Config(); | ||
|  |         $response = ['path' => $dirname, 'type' => 'dir']; | ||
|  |         $this->adapter->createDir($dirname, $config)->willReturn($response); | ||
|  |         $this->cache->updateObject($dirname, $response, true)->shouldBeCalled(); | ||
|  |         $this->createDir($dirname, $config)->shouldBe($response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_create_dir_fails() | ||
|  |     { | ||
|  |         $dirname = 'dirname'; | ||
|  |         $config = new Config(); | ||
|  |         $this->adapter->createDir($dirname, $config)->willReturn(false); | ||
|  |         $this->createDir($dirname, $config)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_set_visibility() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $visibility = AdapterInterface::VISIBILITY_PUBLIC; | ||
|  |         $this->adapter->setVisibility($path, $visibility)->willReturn(true); | ||
|  |         $this->cache->updateObject($path, ['path' => $path, 'visibility' => $visibility], true)->shouldBeCalled(); | ||
|  |         $this->setVisibility($path, $visibility)->shouldBe(true); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_set_visibility_fails() | ||
|  |     { | ||
|  |         $dirname = 'delete'; | ||
|  |         $visibility = AdapterInterface::VISIBILITY_PUBLIC; | ||
|  |         $this->adapter->setVisibility($dirname, $visibility)->willReturn(false); | ||
|  |         $this->setVisibility($dirname, $visibility)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_indicate_missing_files() | ||
|  |     { | ||
|  |         $this->cache->has($path = 'path.txt')->willReturn(false); | ||
|  |         $this->has($path)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_indicate_file_existance() | ||
|  |     { | ||
|  |         $this->cache->has($path = 'path.txt')->willReturn(true); | ||
|  |         $this->has($path)->shouldBe(true); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_missing_files() | ||
|  |     { | ||
|  |         $this->cache->has($path = 'path.txt')->willReturn(null); | ||
|  |         $this->adapter->has($path)->willReturn(false); | ||
|  |         $this->cache->storeMiss($path)->shouldBeCalled(); | ||
|  |         $this->has($path)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_delete_when_metadata_is_missing() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $this->cache->has($path)->willReturn(true); | ||
|  |         $this->cache->getSize($path)->willReturn(['path' => $path]); | ||
|  |         $this->adapter->getSize($path)->willReturn($response = ['path' => $path, 'size' => 1024]); | ||
|  |         $this->cache->updateObject($path, $response, true)->shouldBeCalled(); | ||
|  |         $this->getSize($path)->shouldBe($response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_has() | ||
|  |     { | ||
|  |         $this->cache->has($path = 'path.txt')->willReturn(null); | ||
|  |         $this->adapter->has($path)->willReturn(true); | ||
|  |         $this->cache->updateObject($path, compact('path'), true)->shouldBeCalled(); | ||
|  |         $this->has($path)->shouldBe(true); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_list_cached_contents() | ||
|  |     { | ||
|  |         $this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(true); | ||
|  |         $response = [['path' => 'path.txt']]; | ||
|  |         $this->cache->listContents($dirname, $recursive)->willReturn($response); | ||
|  |         $this->listContents($dirname, $recursive)->shouldBe($response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_list_contents() | ||
|  |     { | ||
|  |         $this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(false); | ||
|  |         $this->adapter->listContents($dirname, $recursive)->willReturn(false); | ||
|  |         $this->listContents($dirname, $recursive)->shouldBe(false); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_contents_listings() | ||
|  |     { | ||
|  |         $this->cache->isComplete($dirname = 'dirname', $recursive = true)->willReturn(false); | ||
|  |         $response = [['path' => 'path.txt']]; | ||
|  |         $this->adapter->listContents($dirname, $recursive)->willReturn($response); | ||
|  |         $this->cache->storeContents($dirname, $response, $recursive)->shouldBeCalled(); | ||
|  |         $this->listContents($dirname, $recursive)->shouldBe($response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_use_cached_visibility() | ||
|  |     { | ||
|  |         $this->make_it_use_getter_cache('getVisibility', 'path.txt', [ | ||
|  |             'path' => 'path.txt', | ||
|  |             'visibility' => AdapterInterface::VISIBILITY_PUBLIC, | ||
|  |         ]); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_get_visibility() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $response = ['visibility' => AdapterInterface::VISIBILITY_PUBLIC, 'path' => $path]; | ||
|  |         $this->make_it_cache_getter('getVisibility', $path, $response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_get_visibility() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $this->make_it_ignore_failed_getter('getVisibility', $path); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_use_cached_timestamp() | ||
|  |     { | ||
|  |         $this->make_it_use_getter_cache('getTimestamp', 'path.txt', [ | ||
|  |             'path' => 'path.txt', | ||
|  |             'timestamp' => 1234, | ||
|  |         ]); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_timestamps() | ||
|  |     { | ||
|  |         $this->make_it_cache_getter('getTimestamp', 'path.txt', [ | ||
|  |             'path' => 'path.txt', | ||
|  |             'timestamp' => 1234, | ||
|  |         ]); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_get_timestamps() | ||
|  |     { | ||
|  |         $this->make_it_ignore_failed_getter('getTimestamp', 'path.txt'); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_get_metadata() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $response = ['visibility' => AdapterInterface::VISIBILITY_PUBLIC, 'path' => $path]; | ||
|  |         $this->make_it_cache_getter('getMetadata', $path, $response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_use_cached_metadata() | ||
|  |     { | ||
|  |         $this->make_it_use_getter_cache('getMetadata', 'path.txt', [ | ||
|  |             'path' => 'path.txt', | ||
|  |             'timestamp' => 1234, | ||
|  |         ]); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_get_metadata() | ||
|  |     { | ||
|  |         $this->make_it_ignore_failed_getter('getMetadata', 'path.txt'); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_get_size() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $response = ['size' => 1234, 'path' => $path]; | ||
|  |         $this->make_it_cache_getter('getSize', $path, $response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_use_cached_size() | ||
|  |     { | ||
|  |         $this->make_it_use_getter_cache('getSize', 'path.txt', [ | ||
|  |             'path' => 'path.txt', | ||
|  |             'size' => 1234, | ||
|  |         ]); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_get_size() | ||
|  |     { | ||
|  |         $this->make_it_ignore_failed_getter('getSize', 'path.txt'); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_get_mimetype() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $response = ['mimetype' => 'text/plain', 'path' => $path]; | ||
|  |         $this->make_it_cache_getter('getMimetype', $path, $response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_use_cached_mimetype() | ||
|  |     { | ||
|  |         $this->make_it_use_getter_cache('getMimetype', 'path.txt', [ | ||
|  |             'path' => 'path.txt', | ||
|  |             'mimetype' => 'text/plain', | ||
|  |         ]); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_get_mimetype() | ||
|  |     { | ||
|  |         $this->make_it_ignore_failed_getter('getMimetype', 'path.txt'); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_cache_reads() | ||
|  |     { | ||
|  |         $path = 'path.txt'; | ||
|  |         $response = ['path' => $path, 'contents' => 'contents']; | ||
|  |         $this->make_it_cache_getter('read', $path, $response); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_use_cached_file_contents() | ||
|  |     { | ||
|  |         $this->make_it_use_getter_cache('read', 'path.txt', [ | ||
|  |             'path' => 'path.txt', | ||
|  |             'contents' => 'contents' | ||
|  |         ]); | ||
|  |     } | ||
|  | 
 | ||
|  |     public function it_should_ignore_failed_reads() | ||
|  |     { | ||
|  |         $this->make_it_ignore_failed_getter('read', 'path.txt'); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function make_it_use_getter_cache($method, $path, $response) | ||
|  |     { | ||
|  |         $this->cache->{$method}($path)->willReturn($response); | ||
|  |         $this->{$method}($path)->shouldBe($response); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function make_it_cache_getter($method, $path, $response) | ||
|  |     { | ||
|  |         $this->cache->{$method}($path)->willReturn(false); | ||
|  |         $this->adapter->{$method}($path)->willReturn($response); | ||
|  |         $this->cache->updateObject($path, $response, true)->shouldBeCalled(); | ||
|  |         $this->{$method}($path)->shouldBe($response); | ||
|  |     } | ||
|  | 
 | ||
|  |     protected function make_it_ignore_failed_getter($method, $path) | ||
|  |     { | ||
|  |         $this->cache->{$method}($path)->willReturn(false); | ||
|  |         $this->adapter->{$method}($path)->willReturn(false); | ||
|  |         $this->{$method}($path)->shouldBe(false); | ||
|  |     } | ||
|  | } |