From 05afc99e126d4f2f784db7dc44028605ca619c00 Mon Sep 17 00:00:00 2001 From: Remon van de Kamp Date: Wed, 10 May 2017 22:23:13 +0200 Subject: [PATCH] Use FilterService in ResolveCacheProcessor --- Async/ResolveCacheProcessor.php | 36 +-- Resources/config/enqueue.xml | 3 +- Service/FilterService.php | 13 ++ Tests/Async/ResolveCacheProcessorTest.php | 271 +++++++++++++--------- 4 files changed, 184 insertions(+), 139 deletions(-) diff --git a/Async/ResolveCacheProcessor.php b/Async/ResolveCacheProcessor.php index edb7d467a..11121fd24 100644 --- a/Async/ResolveCacheProcessor.php +++ b/Async/ResolveCacheProcessor.php @@ -18,26 +18,20 @@ use Enqueue\Psr\PsrContext; use Enqueue\Psr\PsrMessage; use Enqueue\Psr\PsrProcessor; -use Liip\ImagineBundle\Imagine\Cache\CacheManager; -use Liip\ImagineBundle\Imagine\Data\DataManager; use Liip\ImagineBundle\Imagine\Filter\FilterManager; +use Liip\ImagineBundle\Service\FilterService; class ResolveCacheProcessor implements PsrProcessor, TopicSubscriberInterface, QueueSubscriberInterface { - /** - * @var CacheManager - */ - private $cacheManager; - /** * @var FilterManager */ private $filterManager; /** - * @var DataManager + * @var FilterService */ - private $dataManager; + private $filterService; /** * @var ProducerInterface @@ -45,20 +39,17 @@ class ResolveCacheProcessor implements PsrProcessor, TopicSubscriberInterface, Q private $producer; /** - * @param CacheManager $cacheManager * @param FilterManager $filterManager - * @param DataManager $dataManager + * @param FilterService $filterService * @param ProducerInterface $producer */ public function __construct( - CacheManager $cacheManager, FilterManager $filterManager, - DataManager $dataManager, + FilterService $filterService, ProducerInterface $producer ) { - $this->cacheManager = $cacheManager; $this->filterManager = $filterManager; - $this->dataManager = $dataManager; + $this->filterService = $filterService; $this->producer = $producer; } @@ -77,20 +68,13 @@ public function process(PsrMessage $psrMessage, PsrContext $psrContext) $path = $message->getPath(); $results = []; foreach ($filters as $filter) { - if ($this->cacheManager->isStored($path, $filter) && $message->isForce()) { - $this->cacheManager->remove($path, $filter); + if ($message->isForce()) { + $this->filterService->bustCache($path, $filter); } - if (false == $this->cacheManager->isStored($path, $filter)) { - $binary = $this->dataManager->find($filter, $path); - $this->cacheManager->store( - $this->filterManager->applyFilter($binary, $filter), - $path, - $filter - ); - } + $this->filterService->createFilteredImage($path, $filter); - $results[$filter] = $this->cacheManager->resolve($path, $filter); + $results[$filter] = $this->filterService->getUrlOfFilteredImage($path, $filter); } $this->producer->send(Topics::CACHE_RESOLVED, new CacheResolved($path, $results)); diff --git a/Resources/config/enqueue.xml b/Resources/config/enqueue.xml index fc5e04f0a..82c972b2f 100644 --- a/Resources/config/enqueue.xml +++ b/Resources/config/enqueue.xml @@ -5,9 +5,8 @@ - - + diff --git a/Service/FilterService.php b/Service/FilterService.php index 7b881a319..c2f309b5d 100644 --- a/Service/FilterService.php +++ b/Service/FilterService.php @@ -117,6 +117,19 @@ public function createFilteredImageWithRuntimeFilters($path, $filter, array $run ); } + /** + * @param string $path + * @param string $filter + */ + public function bustCache($path, $filter) + { + if (!$this->cacheManager->isStored($path, $filter)) { + return; + } + + $this->cacheManager->remove($path, $filter); + } + /** * @param string $path * @param string $filter diff --git a/Tests/Async/ResolveCacheProcessorTest.php b/Tests/Async/ResolveCacheProcessorTest.php index 5886132e2..70f530bd0 100644 --- a/Tests/Async/ResolveCacheProcessorTest.php +++ b/Tests/Async/ResolveCacheProcessorTest.php @@ -67,9 +67,8 @@ public function testShouldSubscribeToExpectedQueue() public function testCouldBeConstructedWithExpectedArguments() { new ResolveCacheProcessor( - $this->createCacheManagerMock(), $this->createFilterManagerMock(), - $this->createDataManagerMock(), + $this->createFilterServiceMock(), $this->createProducerMock() ); } @@ -77,9 +76,8 @@ public function testCouldBeConstructedWithExpectedArguments() public function testShouldRejectMessagesWithInvalidJsonBody() { $processor = new ResolveCacheProcessor( - $this->createCacheManagerMock(), $this->createFilterManagerMock(), - $this->createDataManagerMock(), + $this->createFilterServiceMock(), $this->createProducerMock() ); @@ -96,9 +94,8 @@ public function testShouldRejectMessagesWithInvalidJsonBody() public function testShouldRejectMessagesWithoutPass() { $processor = new ResolveCacheProcessor( - $this->createCacheManagerMock(), $this->createFilterManagerMock(), - $this->createDataManagerMock(), + $this->createFilterServiceMock(), $this->createProducerMock() ); @@ -112,71 +109,178 @@ public function testShouldRejectMessagesWithoutPass() $this->assertEquals('The message does not contain "path" but it is required.', $result->getReason()); } - public function testShouldResolveCacheIfNotStored() + public function testShouldCreateFilteredImage() { - $originalBinary = $this->createDummyBinary(); - $filteredBinary = $this->createDummyBinary(); + $filterName = 'fooFilter'; + $imagePath = 'theImagePath'; $filterManagerMock = $this->createFilterManagerMock(); $filterManagerMock ->expects($this->once()) ->method('getFilterConfiguration') ->willReturn(new FilterConfiguration(array( - 'fooFilter' => array('fooFilterConfig'), + $filterName => array('fooFilterConfig'), ))) ; + + $filterServiceMock = $this->createFilterServiceMock(); + $filterServiceMock + ->expects($this->once()) + ->method('createFilteredImage') + ->with($imagePath, $filterName); + + $processor = new ResolveCacheProcessor( + $filterManagerMock, + $filterServiceMock, + $this->createProducerMock() + ); + + $message = new NullMessage(); + $message->setBody(json_encode(['path' => $imagePath])); + + $result = $processor->process($message, new NullContext()); + + $this->assertEquals(Result::ACK, $result); + } + + public function testShouldCreateOneImagePerFilter() + { + $filterName1 = 'fooFilter'; + $filterName2 = 'barFilter'; + $imagePath = 'theImagePath'; + + $filterManagerMock = $this->createFilterManagerMock(); $filterManagerMock ->expects($this->once()) - ->method('applyFilter') - ->with($this->identicalTo($originalBinary), 'fooFilter') - ->willReturn($filteredBinary) + ->method('getFilterConfiguration') + ->willReturn(new FilterConfiguration(array( + $filterName1 => array('fooFilterConfig'), + $filterName2 => array('fooFilterConfig'), + ))) ; - $cacheManagerMock = $this->createCacheManagerMock(); - $cacheManagerMock - ->expects($this->atLeastOnce()) - ->method('isStored') - ->willReturn(false) - ; - $cacheManagerMock + $filterServiceMock = $this->createFilterServiceMock(); + $filterServiceMock + ->expects($this->exactly(2)) + ->method('createFilteredImage') + ->withConsecutive( + [$imagePath, $filterName1], + [$imagePath, $filterName2] + ); + + $processor = new ResolveCacheProcessor( + $filterManagerMock, + $filterServiceMock, + $this->createProducerMock() + ); + + $message = new NullMessage(); + $message->setBody(json_encode(['path' => $imagePath])); + + $result = $processor->process($message, new NullContext()); + + $this->assertEquals(Result::ACK, $result); + } + + public function testShouldOnlyCreateImageForRequestedFilter() + { + $relevantFilter = 'fooFilter'; + $imagePath = 'theImagePath'; + + $filterManagerMock = $this->createFilterManagerMock(); + $filterManagerMock + ->expects($this->never()) + ->method('getFilterConfiguration'); + + $filterServiceMock = $this->createFilterServiceMock(); + $filterServiceMock ->expects($this->once()) - ->method('store') - ->with( - $this->identicalTo($filteredBinary), - 'theImagePath', - 'fooFilter' - ) - ; - $cacheManagerMock + ->method('createFilteredImage') + ->with($imagePath, $relevantFilter); + + $processor = new ResolveCacheProcessor( + $filterManagerMock, + $filterServiceMock, + $this->createProducerMock() + ); + + $message = new NullMessage(); + $message->setBody(json_encode(['path' => $imagePath, 'filters' => [$relevantFilter]])); + + $result = $processor->process($message, new NullContext()); + + $this->assertEquals(Result::ACK, $result); + } + + public function testShouldCreateOneImagePerRequestedFilter() + { + $relevantFilter1 = 'fooFilter'; + $relevantFilter2 = 'fooFilter'; + $imagePath = 'theImagePath'; + + $filterManagerMock = $this->createFilterManagerMock(); + $filterManagerMock + ->expects($this->never()) + ->method('getFilterConfiguration'); + + $filterServiceMock = $this->createFilterServiceMock(); + $filterServiceMock + ->expects($this->exactly(2)) + ->method('createFilteredImage') + ->withConsecutive( + [$imagePath, $relevantFilter1], + [$imagePath, $relevantFilter2] + ); + + $processor = new ResolveCacheProcessor( + $filterManagerMock, + $filterServiceMock, + $this->createProducerMock() + ); + + $message = new NullMessage(); + $message->setBody(json_encode(['path' => $imagePath, 'filters' => [$relevantFilter1, $relevantFilter2]])); + + $result = $processor->process($message, new NullContext()); + + $this->assertEquals(Result::ACK, $result); + } + + public function testShouldBurstCacheWhenResolvingForced() + { + $filterName = 'fooFilter'; + $imagePath = 'theImagePath'; + + $filterManagerMock = $this->createFilterManagerMock(); + $filterManagerMock ->expects($this->once()) - ->method('resolve') - ->with('theImagePath', 'fooFilter') + ->method('getFilterConfiguration') + ->willReturn(new FilterConfiguration(array( + $filterName => array('fooFilterConfig'), + ))) ; - $dataManagerMock = $this->createDataManagerMock(); - $dataManagerMock + $filterServiceMock = $this->createFilterServiceMock(); + $filterServiceMock ->expects($this->once()) - ->method('find') - ->with('fooFilter', 'theImagePath') - ->willReturn($originalBinary) - ; + ->method('bustCache') + ->with($imagePath, $filterName); $processor = new ResolveCacheProcessor( - $cacheManagerMock, $filterManagerMock, - $dataManagerMock, + $filterServiceMock, $this->createProducerMock() ); $message = new NullMessage(); - $message->setBody('{"path": "theImagePath"}'); + $message->setBody(json_encode(['path' => $imagePath, 'force' => true])); $result = $processor->process($message, new NullContext()); $this->assertEquals(Result::ACK, $result); } - public function testShouldNotResolveCacheIfStoredAndNotForce() + public function testShouldNotBurstCacheWhenResolvingNotForced() { $filterManagerMock = $this->createFilterManagerMock(); $filterManagerMock @@ -186,43 +290,20 @@ public function testShouldNotResolveCacheIfStoredAndNotForce() 'fooFilter' => array('fooFilterConfig'), ))) ; - $filterManagerMock - ->expects($this->never()) - ->method('applyFilter') - ; - - $cacheManagerMock = $this->createCacheManagerMock(); - $cacheManagerMock - ->expects($this->atLeastOnce()) - ->method('isStored') - ->willReturn(true) - ; - $cacheManagerMock - ->expects($this->never()) - ->method('store') - ; - $cacheManagerMock - ->expects($this->once()) - ->method('resolve') - ->with('theImagePath', 'fooFilter') - ->willReturn('fooFilterUri') - ; - $dataManagerMock = $this->createDataManagerMock(); - $dataManagerMock + $filterServiceMock = $this->createFilterServiceMock(); + $filterServiceMock ->expects($this->never()) - ->method('find') - ; + ->method('bustCache'); $processor = new ResolveCacheProcessor( - $cacheManagerMock, $filterManagerMock, - $dataManagerMock, + $filterServiceMock, $this->createProducerMock() ); $message = new NullMessage(); - $message->setBody('{"path": "theImagePath"}'); + $message->setBody(json_encode(['path' => 'theImagePath'])); $result = $processor->process($message, new NullContext()); @@ -241,46 +322,23 @@ public function testShouldSendMessageOnSuccessResolve() 'bazFilter' => array('bazFilterConfig'), ))) ; - $filterManagerMock - ->expects($this->atLeastOnce()) - ->method('applyFilter') - ->willReturn($this->createDummyBinary()) - ; - $cacheManagerMock = $this->createCacheManagerMock(); - $cacheManagerMock - ->expects($this->atLeastOnce()) - ->method('isStored') - ->willReturn(false) - ; - $cacheManagerMock - ->expects($this->atLeastOnce()) - ->method('store') - ; - $cacheManagerMock - ->expects($this->atLeastOnce()) - ->method('resolve') - ->willReturnCallback(function ($path, $filter) { + $filterServiceMock = $this->createFilterServiceMock(); + $filterServiceMock + ->expects($this->exactly(3)) + ->method('getUrlOfFilteredImage') + ->willReturnCallback(function($path, $filter) { return $path.$filter.'Uri'; - }) - ; + }); - $dataManagerMock = $this->createDataManagerMock(); - $dataManagerMock - ->expects($this->atLeastOnce()) - ->method('find') - ->willReturn($this->createDummyBinary()) - ; - - $testCase = $this; $producerMock = $this->createProducerMock(); $producerMock ->expects($this->once()) ->method('send') ->with(Topics::CACHE_RESOLVED, $this->isInstanceOf('Liip\ImagineBundle\Async\CacheResolved')) - ->willReturnCallback(function ($topic, CacheResolved $message) use ($testCase) { - $testCase->assertEquals('theImagePath', $message->getPath()); - $testCase->assertEquals(array( + ->willReturnCallback(function ($topic, CacheResolved $message) { + $this->assertEquals('theImagePath', $message->getPath()); + $this->assertEquals(array( 'fooFilter' => 'theImagePathfooFilterUri', 'barFilter' => 'theImagePathbarFilterUri', 'bazFilter' => 'theImagePathbazFilterUri', @@ -288,14 +346,13 @@ public function testShouldSendMessageOnSuccessResolve() }); $processor = new ResolveCacheProcessor( - $cacheManagerMock, $filterManagerMock, - $dataManagerMock, + $filterServiceMock, $producerMock ); $message = new NullMessage(); - $message->setBody('{"path": "theImagePath"}'); + $message->setBody(json_encode(['path' => 'theImagePath'])); $result = $processor->process($message, new NullContext()); @@ -309,12 +366,4 @@ private function createProducerMock() { return $this->createMock(ProducerInterface::class); } - - /** - * @return Binary - */ - private function createDummyBinary() - { - return new Binary('theContent', 'image/png', 'png'); - } }