From 31ac0cc8b71bc3eb53f94fc310697173d6e57e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3js?= Date: Thu, 1 Feb 2018 11:39:51 +0100 Subject: [PATCH] EZP-28747: HTTP Cache purge when UserService\{CreateUser,CreateUserGroup,UpdateUser,UpdateUserGroup}Signal is emited. --- src/Resources/config/slot.yml | 26 ++++++++++- src/SignalSlot/AbstractContentSlot.php | 2 +- src/SignalSlot/AbstractPublishSlot.php | 64 ++++++++++++++++++++++++++ src/SignalSlot/CreateUserGroupSlot.php | 27 +++++++++++ src/SignalSlot/CreateUserSlot.php | 27 +++++++++++ src/SignalSlot/PublishVersionSlot.php | 48 +++----------------- src/SignalSlot/UpdateUserGroupSlot.php | 27 +++++++++++ src/SignalSlot/UpdateUserSlot.php | 13 +++--- tests/SignalSlot/AbstractPublishSlotTest.php | 67 ++++++++++++++++++++++++++++ tests/SignalSlot/CreateUserGroupSlotTest.php | 32 +++++++++++++ tests/SignalSlot/CreateUserSlotTest.php | 32 +++++++++++++ tests/SignalSlot/PublishVersionSlotTest.php | 57 ++--------------------- tests/SignalSlot/UpdateUserGroupSlotTest.php | 32 +++++++++++++ tests/SignalSlot/UpdateUserSlotTest.php | 12 ++--- 14 files changed, 351 insertions(+), 115 deletions(-) create mode 100644 src/SignalSlot/AbstractPublishSlot.php create mode 100644 src/SignalSlot/CreateUserGroupSlot.php create mode 100644 src/SignalSlot/CreateUserSlot.php create mode 100644 src/SignalSlot/UpdateUserGroupSlot.php create mode 100644 tests/SignalSlot/AbstractPublishSlotTest.php create mode 100644 tests/SignalSlot/CreateUserGroupSlotTest.php create mode 100644 tests/SignalSlot/CreateUserSlotTest.php create mode 100644 tests/SignalSlot/UpdateUserGroupSlotTest.php diff --git a/src/Resources/config/slot.yml b/src/Resources/config/slot.yml index 76fc627..d5b78c1 100644 --- a/src/Resources/config/slot.yml +++ b/src/Resources/config/slot.yml @@ -4,6 +4,10 @@ services: abstract: true arguments: ["@ezplatform.http_cache.purge_client"] + ezplatform.http_cache.signalslot.abstract_publish: + abstract: true + arguments: ["@ezplatform.http_cache.purge_client", "@ezpublish.spi.persistence.cache.locationHandler"] + ezplatform.http_cache.signalslot.assign_section: class: EzSystems\PlatformHttpCacheBundle\SignalSlot\AssignSectionSlot parent: ezplatform.http_cache.signalslot.abstract_content @@ -60,7 +64,7 @@ services: ezplatform.http_cache.signalslot.publish_version: class: EzSystems\PlatformHttpCacheBundle\SignalSlot\PublishVersionSlot - arguments: ["@ezplatform.http_cache.purge_client", "@ezpublish.spi.persistence.cache.locationHandler"] + parent: ezplatform.http_cache.signalslot.abstract_publish tags: - { name: ezpublish.api.slot, signal: ContentService\PublishVersionSignal } @@ -88,12 +92,30 @@ services: tags: - { name: ezpublish.api.slot, signal: LocationService\UpdateLocationSignal } + ezplatform.http_cache.signalslot.create_user: + class: EzSystems\PlatformHttpCacheBundle\SignalSlot\CreateUserSlot + parent: ezplatform.http_cache.signalslot.abstract_publish + tags: + - { name: ezpublish.api.slot, signal: UserService\CreateUserSignal } + ezplatform.http_cache.signalslot.update_user: class: EzSystems\PlatformHttpCacheBundle\SignalSlot\UpdateUserSlot - parent: ezplatform.http_cache.signalslot.abstract_content + parent: ezplatform.http_cache.signalslot.abstract_publish tags: - { name: ezpublish.api.slot, signal: UserService\UpdateUserSignal } + ezplatform.http_cache.signalslot.create_user_group: + class: EzSystems\PlatformHttpCacheBundle\SignalSlot\CreateUserGroupSlot + parent: ezplatform.http_cache.signalslot.abstract_publish + tags: + - { name: ezpublish.api.slot, signal: UserService\CreateUserGroupSignal } + + ezplatform.http_cache.signalslot.update_user_group: + class: EzSystems\PlatformHttpCacheBundle\SignalSlot\UpdateUserGroupSlot + parent: ezplatform.http_cache.signalslot.abstract_publish + tags: + - { name: ezpublish.api.slot, signal: UserService\UpdateUserGroupSignal } + ezplatform.http_cache.signalslot.assign_user_to_user_group: class: EzSystems\PlatformHttpCacheBundle\SignalSlot\AssignUserToUserGroupSlot parent: ezplatform.http_cache.signalslot.abstract_content diff --git a/src/SignalSlot/AbstractContentSlot.php b/src/SignalSlot/AbstractContentSlot.php index 44afa99..a39c048 100644 --- a/src/SignalSlot/AbstractContentSlot.php +++ b/src/SignalSlot/AbstractContentSlot.php @@ -44,7 +44,7 @@ protected function generateTags(Signal $signal) $tags = []; if (isset($signal->contentId)) { - // self in all forms (also withouth locations) + // self in all forms (also without locations) $tags[] = 'content-' . $signal->contentId; // reverse relations $tags[] = 'relation-' . $signal->contentId; diff --git a/src/SignalSlot/AbstractPublishSlot.php b/src/SignalSlot/AbstractPublishSlot.php new file mode 100644 index 0000000..d9da451 --- /dev/null +++ b/src/SignalSlot/AbstractPublishSlot.php @@ -0,0 +1,64 @@ +locationHandler = $spiLocationHandler; + } + + /** + * Extracts content id from signal. + * + * @param Signal $signal + * @return mixed + */ + abstract protected function getContentId(Signal $signal); + + protected function generateTags(Signal $signal) + { + $contentId = $this->getContentId($signal); + + $tags = [ + // self in all forms (also without locations) + 'content-' . $contentId, + // reverse relations + 'relation-' . $contentId, + ]; + + foreach ($this->locationHandler->loadLocationsByContent($contentId) as $location) { + // self + $tags[] = 'location-' . $location->id; + // children + $tags[] = 'parent-' . $location->id; + // parent + $tags[] = 'location-' . $location->parentId; + // siblings + $tags[] = 'parent-' . $location->parentId; + } + + return $tags; + } +} diff --git a/src/SignalSlot/CreateUserGroupSlot.php b/src/SignalSlot/CreateUserGroupSlot.php new file mode 100644 index 0000000..5346749 --- /dev/null +++ b/src/SignalSlot/CreateUserGroupSlot.php @@ -0,0 +1,27 @@ +userGroupId; + } +} diff --git a/src/SignalSlot/CreateUserSlot.php b/src/SignalSlot/CreateUserSlot.php new file mode 100644 index 0000000..9d79997 --- /dev/null +++ b/src/SignalSlot/CreateUserSlot.php @@ -0,0 +1,27 @@ +userId; + } +} diff --git a/src/SignalSlot/PublishVersionSlot.php b/src/SignalSlot/PublishVersionSlot.php index c3b632b..e2df4f5 100644 --- a/src/SignalSlot/PublishVersionSlot.php +++ b/src/SignalSlot/PublishVersionSlot.php @@ -8,58 +8,20 @@ */ namespace EzSystems\PlatformHttpCacheBundle\SignalSlot; -use EzSystems\PlatformHttpCacheBundle\PurgeClient\PurgeClientInterface; use eZ\Publish\Core\SignalSlot\Signal; -use eZ\Publish\SPI\Persistence\Content\Location\Handler; /** * A slot handling PublishVersionSignal. */ -class PublishVersionSlot extends AbstractContentSlot +class PublishVersionSlot extends AbstractPublishSlot { - /** - * @var \eZ\Publish\SPI\Persistence\Content\Location\Handler - */ - private $locationHandler; - - /** - * @param \EzSystems\PlatformHttpCacheBundle\PurgeClient\PurgeClientInterface $purgeClient - * @param \eZ\Publish\SPI\Persistence\Content\Location\Handler $spiLocationHandler - */ - public function __construct(PurgeClientInterface $purgeClient, Handler $spiLocationHandler) - { - parent::__construct($purgeClient); - $this->locationHandler = $spiLocationHandler; - } - - /** - * Default provides tags to clear content, relation, location, parent and sibling cache. - * - * Overload for tree operations where you also need to clear whole path. - * - * @param \eZ\Publish\Core\SignalSlot\Signal\ContentService\PublishVersionSignal $signal - * - * @return array - */ - protected function generateTags(Signal $signal) + protected function supports(Signal $signal) { - $tags = parent::generateTags($signal); - foreach ($this->locationHandler->loadLocationsByContent($signal->contentId) as $location) { - // self - $tags[] = 'location-' . $location->id; - // children - $tags[] = 'parent-' . $location->id; - // parent - $tags[] = 'location-' . $location->parentId; - // siblings - $tags[] = 'parent-' . $location->parentId; - } - - return $tags; + return $signal instanceof Signal\ContentService\PublishVersionSignal; } - protected function supports(Signal $signal) + protected function getContentId(Signal $signal) { - return $signal instanceof Signal\ContentService\PublishVersionSignal; + return $signal->contentId; } } diff --git a/src/SignalSlot/UpdateUserGroupSlot.php b/src/SignalSlot/UpdateUserGroupSlot.php new file mode 100644 index 0000000..f9e7d7d --- /dev/null +++ b/src/SignalSlot/UpdateUserGroupSlot.php @@ -0,0 +1,27 @@ +userGroupId; + } +} diff --git a/src/SignalSlot/UpdateUserSlot.php b/src/SignalSlot/UpdateUserSlot.php index 5229311..a9d72e1 100644 --- a/src/SignalSlot/UpdateUserSlot.php +++ b/src/SignalSlot/UpdateUserSlot.php @@ -13,18 +13,15 @@ /** * A slot handling UpdateUserSignal. */ -class UpdateUserSlot extends AbstractContentSlot +class UpdateUserSlot extends AbstractPublishSlot { - /** - * @param \eZ\Publish\Core\SignalSlot\Signal\UserService\UpdateUserSignal $signal - */ - protected function generateTags(Signal $signal) + protected function supports(Signal $signal) { - return ['content-' . $signal->userId]; + return $signal instanceof Signal\UserService\UpdateUserSignal; } - protected function supports(Signal $signal) + protected function getContentId(Signal $signal) { - return $signal instanceof Signal\UserService\UpdateUserSignal; + return $signal->userId; } } diff --git a/tests/SignalSlot/AbstractPublishSlotTest.php b/tests/SignalSlot/AbstractPublishSlotTest.php new file mode 100644 index 0000000..9fedf97 --- /dev/null +++ b/tests/SignalSlot/AbstractPublishSlotTest.php @@ -0,0 +1,67 @@ +getSlotClass(); + if ($this->spiLocationHandlerMock === null) { + $this->spiLocationHandlerMock = $this->createMock(Handler::class); + } + + return new $class($this->purgeClientMock, $this->spiLocationHandlerMock); + } + + /** + * @dataProvider getUnreceivedSignals + */ + public function testDoesNotReceiveOtherSignals($signal) + { + $this->purgeClientMock->expects($this->never())->method('purge'); + $this->purgeClientMock->expects($this->never())->method('purgeAll'); + + $this->spiLocationHandlerMock->expects($this->never())->method('loadLocationsByContent'); + + $this->slot->receive($signal); + } + + /** + * @dataProvider getReceivedSignals + */ + public function testReceivePurgesCacheForTags($signal) + { + $this->spiLocationHandlerMock + ->expects($this->once()) + ->method('loadLocationsByContent') + ->with($this->contentId) + ->willReturn( + [ + new Location([ + 'id' => $this->locationId, + 'parentId' => $this->parentLocationId, + ]), + ] + ); + + $this->purgeClientMock->expects($this->once())->method('purge')->with($this->generateTags()); + $this->purgeClientMock->expects($this->never())->method('purgeAll'); + parent::receive($signal); + } +} diff --git a/tests/SignalSlot/CreateUserGroupSlotTest.php b/tests/SignalSlot/CreateUserGroupSlotTest.php new file mode 100644 index 0000000..24833b5 --- /dev/null +++ b/tests/SignalSlot/CreateUserGroupSlotTest.php @@ -0,0 +1,32 @@ + $this->contentId, + ]); + } + + public function getReceivedSignalClasses() + { + return [CreateUserGroupSignal::class]; + } + + public function getSlotClass() + { + return CreateUserGroupSlot::class; + } +} diff --git a/tests/SignalSlot/CreateUserSlotTest.php b/tests/SignalSlot/CreateUserSlotTest.php new file mode 100644 index 0000000..8092421 --- /dev/null +++ b/tests/SignalSlot/CreateUserSlotTest.php @@ -0,0 +1,32 @@ + $this->contentId, + ]); + } + + public function getReceivedSignalClasses() + { + return [CreateUserSignal::class]; + } + + public function getSlotClass() + { + return CreateUserSlot::class; + } +} diff --git a/tests/SignalSlot/PublishVersionSlotTest.php b/tests/SignalSlot/PublishVersionSlotTest.php index ee803b7..68f4b93 100644 --- a/tests/SignalSlot/PublishVersionSlotTest.php +++ b/tests/SignalSlot/PublishVersionSlotTest.php @@ -9,17 +9,9 @@ namespace EzSystems\PlatformHttpCacheBundle\Tests\SignalSlot; use eZ\Publish\Core\SignalSlot\Signal\ContentService\PublishVersionSignal; -use eZ\Publish\SPI\Persistence\Content\Location; -use eZ\Publish\SPI\Persistence\Content\Location\Handler; -class PublishVersionSlotTest extends AbstractContentSlotTest +class PublishVersionSlotTest extends AbstractPublishSlotTest { - protected $locationId = 45; - protected $parentLocationId = 32; - - /** @var \eZ\Publish\SPI\Persistence\Content\Location\Handler|\PHPUnit_Framework_MockObject_MockObject */ - protected $spiLocationHandlerMock; - public function getSlotClass() { return 'EzSystems\PlatformHttpCacheBundle\SignalSlot\PublishVersionSlot'; @@ -27,54 +19,13 @@ public function getSlotClass() public function createSignal() { - return new PublishVersionSignal(['contentId' => $this->contentId]); + return new PublishVersionSignal([ + 'contentId' => $this->contentId, + ]); } public function getReceivedSignalClasses() { return ['eZ\Publish\Core\SignalSlot\Signal\ContentService\PublishVersionSignal']; } - - protected function createSlot() - { - $class = $this->getSlotClass(); - if ($this->spiLocationHandlerMock === null) { - $this->spiLocationHandlerMock = $this->createMock(Handler::class); - } - - return new $class($this->purgeClientMock, $this->spiLocationHandlerMock); - } - - /** - * @dataProvider getUnreceivedSignals - */ - public function testDoesNotReceiveOtherSignals($signal) - { - $this->purgeClientMock->expects($this->never())->method('purge'); - $this->purgeClientMock->expects($this->never())->method('purgeAll'); - - $this->spiLocationHandlerMock->expects($this->never())->method('loadLocationsByContent'); - - $this->slot->receive($signal); - } - - /** - * @dataProvider getReceivedSignals - */ - public function testReceivePurgesCacheForTags($signal) - { - $this->spiLocationHandlerMock - ->expects($this->once()) - ->method('loadLocationsByContent') - ->with($this->contentId) - ->willReturn( - [ - new Location(['id' => $this->locationId, 'parentId' => $this->parentLocationId]), - ] - ); - - $this->purgeClientMock->expects($this->once())->method('purge')->with($this->generateTags()); - $this->purgeClientMock->expects($this->never())->method('purgeAll'); - parent::receive($signal); - } } diff --git a/tests/SignalSlot/UpdateUserGroupSlotTest.php b/tests/SignalSlot/UpdateUserGroupSlotTest.php new file mode 100644 index 0000000..d1a60d7 --- /dev/null +++ b/tests/SignalSlot/UpdateUserGroupSlotTest.php @@ -0,0 +1,32 @@ + $this->contentId, + ]); + } + + public function getSlotClass() + { + return UpdateUserGroupSlot::class; + } + + public function getReceivedSignalClasses() + { + return [UpdateUserGroupSignal::class]; + } +} diff --git a/tests/SignalSlot/UpdateUserSlotTest.php b/tests/SignalSlot/UpdateUserSlotTest.php index 11cd607..d77c5c8 100644 --- a/tests/SignalSlot/UpdateUserSlotTest.php +++ b/tests/SignalSlot/UpdateUserSlotTest.php @@ -9,26 +9,22 @@ namespace EzSystems\PlatformHttpCacheBundle\Tests\SignalSlot; use eZ\Publish\Core\SignalSlot\Signal\UserService\UpdateUserSignal; +use EzSystems\PlatformHttpCacheBundle\SignalSlot\UpdateUserSlot; -class UpdateUserSlotTest extends AbstractContentSlotTest +class UpdateUserSlotTest extends AbstractPublishSlotTest { public function createSignal() { return new UpdateUserSignal(['userId' => $this->contentId]); } - public function generateTags() - { - return ['content-' . $this->contentId]; - } - public function getSlotClass() { - return 'EzSystems\PlatformHttpCacheBundle\SignalSlot\UpdateUserSlot'; + return UpdateUserSlot::class; } public function getReceivedSignalClasses() { - return ['eZ\Publish\Core\SignalSlot\Signal\UserService\UpdateUserSignal']; + return [UpdateUserSignal::class]; } }