diff --git a/CHANGELOG.md b/CHANGELOG.md index a8d9a3255..b40d27aa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,9 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed +- [#147](https://github.com/zendframework/zend-cache/pull/147) fixes the Redis extension by ensuring it casts the results of `exists()` to a + boolean when testing if the storage contains an item. + - [#146](https://github.com/zendframework/zend-cache/pull/146) fixes several methods to change `@return` annotations to `@throws` where applicable. - [#134](https://github.com/zendframework/zend-cache/pull/134) adds a missing import statement for `Traversable` within the `AdapterOptions` class. diff --git a/src/Storage/Adapter/Redis.php b/src/Storage/Adapter/Redis.php index 16a12b319..0ab118d84 100644 --- a/src/Storage/Adapter/Redis.php +++ b/src/Storage/Adapter/Redis.php @@ -206,7 +206,7 @@ protected function internalHasItem(& $normalizedKey) { $redis = $this->getRedisResource(); try { - return $redis->exists($this->namespacePrefix . $normalizedKey); + return (bool) $redis->exists($this->namespacePrefix . $normalizedKey); } catch (RedisResourceException $e) { throw new Exception\RuntimeException($redis->getLastError(), $e->getCode(), $e); } diff --git a/test/Storage/Adapter/RedisTest.php b/test/Storage/Adapter/RedisTest.php index d93279aee..14bb9ff3e 100644 --- a/test/Storage/Adapter/RedisTest.php +++ b/test/Storage/Adapter/RedisTest.php @@ -9,8 +9,12 @@ namespace ZendTest\Cache\Storage\Adapter; +use PHPUnit_Framework_MockObject_MockObject; use Zend\Cache; use Redis as RedisResource; +use Zend\Cache\Storage\Adapter\Redis; +use Zend\Cache\Storage\Adapter\RedisOptions; +use Zend\Cache\Storage\Adapter\RedisResourceManager; /** * @covers Zend\Cache\Storage\Adapter\Redis @@ -337,4 +341,48 @@ public function testTouchItem() $this->assertTrue($this->_storage->touchItem($key)); $this->assertEquals($ttl, ceil($this->_storage->getMetadata($key)['ttl'])); } + + public function testHasItemReturnsFalseIfRedisExistsReturnsZero() + { + $redis = $this->mockInitializedRedisResource(); + $redis->method('exists')->willReturn(0); + $adapter = $this->createAdapterFromResource($redis); + + $hasItem = $adapter->hasItem('does-not-exist'); + + $this->assertFalse($hasItem); + } + + public function testHasItemReturnsTrueIfRedisExistsReturnsNonZeroInt() + { + $redis = $this->mockInitializedRedisResource(); + $redis->method('exists')->willReturn(23); + $adapter = $this->createAdapterFromResource($redis); + + $hasItem = $adapter->hasItem('does-not-exist'); + + $this->assertTrue($hasItem); + } + + /** + * @return Redis + */ + private function createAdapterFromResource(RedisResource $redis) + { + $resourceManager = new RedisResourceManager(); + $resourceId = 'my-resource'; + $resourceManager->setResource($resourceId, $redis); + $options = new RedisOptions(['resource_manager' => $resourceManager, 'resource_id' => $resourceId]); + return new Redis($options); + } + + /** + * @return PHPUnit_Framework_MockObject_MockObject|RedisResource + */ + private function mockInitializedRedisResource() + { + $redis = $this->getMock(RedisResource::class); + $redis->socket = true; + return $redis; + } }