diff --git a/Resources/config/slots.yml b/Resources/config/slots.yml index dd5c2a0..a236c23 100644 --- a/Resources/config/slots.yml +++ b/Resources/config/slots.yml @@ -30,7 +30,7 @@ services: - "@ezpublish.api.persistence_handler" ez_recommendation.ez_slot.publish_version: - parent: ez_recommendation.ez_slot.base + parent: ez_recommendation.ez_slot.persistence_aware_base class: "%ez_recommendation.ez_slot.publish_version.class%" tags: - {name: ezpublish.api.slot, signal: ContentService\PublishVersionSignal} @@ -78,7 +78,7 @@ services: - {name: ezpublish.api.slot, signal: LocationService\MoveSubtreeSignal} ez_recommendation.ez_slot.trash: - parent: ez_recommendation.ez_slot.base + parent: ez_recommendation.ez_slot.persistence_aware_base class: "%ez_recommendation.ez_slot.trash.class%" tags: - {name: ezpublish.api.slot, signal: TrashService\TrashSignal} diff --git a/Tests/eZ/Publish/Slot/AbstractPersistenceAwareBaseTest.php b/Tests/eZ/Publish/Slot/AbstractPersistenceAwareBaseTest.php new file mode 100644 index 0000000..7e137e2 --- /dev/null +++ b/Tests/eZ/Publish/Slot/AbstractPersistenceAwareBaseTest.php @@ -0,0 +1,26 @@ +persistenceHandler = $this->getMock('\eZ\Publish\SPI\Persistence\Handler'); + + parent::setUp(); + } + + protected function createSlot() + { + $class = $this->getSlotClass(); + + return new $class($this->client, $this->persistenceHandler); + } +} diff --git a/Tests/eZ/Publish/Slot/AbstractSlotTest.php b/Tests/eZ/Publish/Slot/AbstractSlotTest.php new file mode 100644 index 0000000..92be140 --- /dev/null +++ b/Tests/eZ/Publish/Slot/AbstractSlotTest.php @@ -0,0 +1,228 @@ +client = $this->getMock('\EzSystems\RecommendationBundle\Client\RecommendationClient'); + $this->slot = $this->createSlot(); + } + + public function testReceiveSignal() + { + $this->client->expects($this->never())->method('updateContent'); + $this->client->expects($this->never())->method('deleteContent'); + $this->client->expects($this->never())->method('hideLocation'); + $this->client->expects($this->never())->method('unhideLocation'); + + $this->slot->receive($this->createSignal()); + } + + /** + * @dataProvider getUnreceivedSignals + */ + public function testDoesNotReceiveOtherSignals($signal) + { + $this->client->expects($this->never())->method('updateContent'); + $this->client->expects($this->never())->method('deleteContent'); + $this->client->expects($this->never())->method('hideLocation'); + $this->client->expects($this->never())->method('unhideLocation'); + + $this->slot->receive($signal); + } + + public function getReceivedSignals() + { + return [ + $this->createSignal(), + ]; + } + + public function getUnreceivedSignals() + { + $arguments = []; + + $signals = $this->getAllSignals(); + foreach ($signals as $signalClass) { + if (in_array($signalClass, $this->getReceivedSignalClasses())) { + continue; + } + $arguments[] = [new $signalClass()]; + } + + return $arguments; + } + + /** + * Asserts that recommendation service is notified about update of specified content objects. + * + * @param array $notifications + */ + protected function assertRecommendationServiceIsNotified(array $notifications) + { + $notifications = array_merge([ + 'deleteContent' => [], + 'updateContent' => [], + 'hideLocation' => [], + 'unhideLocation' => [], + ], $notifications); + + foreach ($notifications as $action => $contentIds) { + if (empty($contentIds)) { + $this->client->expects($this->never())->method($action); + } else { + $this->client + ->expects($this->exactly(count($contentIds))) + ->method($action) + ->willReturnCallback(function ($id) use ($contentIds) { + $this->assertContains($id, $contentIds); + }); + } + } + } + + /** + * Asserts that recommendation service is notified about delete of specified content objects. + * + * @param array $contentIds + */ + protected function assertContentIsDeleted(array $contentIds) + { + $this->client + ->expects($this->exactly(count($contentIds))) + ->method('deleteContent') + ->willReturnCallback(function ($id) use ($contentIds) { + $this->assertContains($id, $contentIds); + }); + } + + /** + * Asserts that recommendation service is notified about update of specified content objects. + * + * @param array $contentIds + */ + protected function assertContentIsUpdated(array $contentIds) + { + $this->client + ->expects($this->exactly(count($contentIds))) + ->method('updateContent') + ->willReturnCallback(function ($id) use ($contentIds) { + $this->assertContains($id, $contentIds); + }); + } + + protected function createSlot() + { + $class = $this->getSlotClass(); + + return new $class($this->client); + } + + abstract protected function createSignal(); + + abstract protected function getSlotClass(); + + abstract protected function getReceivedSignalClasses(); + + /** + * @return array + */ + private function getAllSignals() + { + return [ + 'eZ\Publish\Core\SignalSlot\Signal\URLAliasService\CreateUrlAliasSignal', + 'eZ\Publish\Core\SignalSlot\Signal\URLAliasService\RemoveAliasesSignal', + 'eZ\Publish\Core\SignalSlot\Signal\URLAliasService\CreateGlobalUrlAliasSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\CreateContentTypeSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\AddFieldDefinitionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\CopyContentTypeSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\DeleteContentTypeSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\UpdateContentTypeGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\DeleteContentTypeGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\UnassignContentTypeGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\PublishContentTypeDraftSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\AssignContentTypeGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\UpdateFieldDefinitionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\UpdateContentTypeDraftSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\RemoveFieldDefinitionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\CreateContentTypeDraftSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentTypeService\CreateContentTypeGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LanguageService\EnableLanguageSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LanguageService\UpdateLanguageNameSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LanguageService\CreateLanguageSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LanguageService\DisableLanguageSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LanguageService\DeleteLanguageSignal', + 'eZ\Publish\Core\SignalSlot\Signal\UserService\MoveUserGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\UserService\DeleteUserGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\UserService\CreateUserGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\UserService\UpdateUserGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\UserService\UnAssignUserFromUserGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\UserService\AssignUserToUserGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\UserService\DeleteUserSignal', + 'eZ\Publish\Core\SignalSlot\Signal\UserService\CreateUserSignal', + 'eZ\Publish\Core\SignalSlot\Signal\UserService\UpdateUserSignal', + 'eZ\Publish\Core\SignalSlot\Signal\SectionService\DeleteSectionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\SectionService\CreateSectionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\SectionService\UpdateSectionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\SectionService\AssignSectionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\AssignRoleToUserGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\UpdatePolicySignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\CreateRoleSignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\RemovePolicySignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\UnassignRoleFromUserSignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\AddPolicySignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\UnassignRoleFromUserGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\UpdateRoleSignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\AssignRoleToUserSignal', + 'eZ\Publish\Core\SignalSlot\Signal\RoleService\DeleteRoleSignal', + 'eZ\Publish\Core\SignalSlot\Signal\TrashService\TrashSignal', + 'eZ\Publish\Core\SignalSlot\Signal\TrashService\EmptyTrashSignal', + 'eZ\Publish\Core\SignalSlot\Signal\TrashService\RecoverSignal', + 'eZ\Publish\Core\SignalSlot\Signal\TrashService\DeleteTrashItemSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ObjectStateService\DeleteObjectStateSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ObjectStateService\CreateObjectStateSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ObjectStateService\DeleteObjectStateGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ObjectStateService\CreateObjectStateGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ObjectStateService\UpdateObjectStateSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ObjectStateService\UpdateObjectStateGroupSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ObjectStateService\SetContentStateSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ObjectStateService\SetPriorityOfObjectStateSignal', + 'eZ\Publish\Core\SignalSlot\Signal\URLWildcardService\TranslateSignal', + 'eZ\Publish\Core\SignalSlot\Signal\URLWildcardService\RemoveSignal', + 'eZ\Publish\Core\SignalSlot\Signal\URLWildcardService\CreateSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\UpdateContentSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\CreateContentDraftSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\AddRelationSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\CreateContentSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\DeleteContentSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\AddTranslationInfoSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\CopyContentSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\UpdateContentMetadataSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\TranslateVersionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\PublishVersionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\DeleteRelationSignal', + 'eZ\Publish\Core\SignalSlot\Signal\ContentService\DeleteVersionSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LocationService\UpdateLocationSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LocationService\HideLocationSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LocationService\SwapLocationSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LocationService\MoveSubtreeSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LocationService\UnhideLocationSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LocationService\CreateLocationSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LocationService\DeleteLocationSignal', + 'eZ\Publish\Core\SignalSlot\Signal\LocationService\CopySubtreeSignal', + ]; + } +} diff --git a/Tests/eZ/Publish/Slot/CopyContentTest.php b/Tests/eZ/Publish/Slot/CopyContentTest.php new file mode 100644 index 0000000..32b7a3d --- /dev/null +++ b/Tests/eZ/Publish/Slot/CopyContentTest.php @@ -0,0 +1,40 @@ +assertRecommendationServiceIsNotified([ + 'updateContent' => [self::DST_CONTENT_ID], + ]); + + $this->slot->receive($this->createSignal()); + } + + protected function createSignal() + { + return new CopyContentSignal([ + 'dstContentId' => self::DST_CONTENT_ID, + ]); + } + + protected function getSlotClass() + { + return 'EzSystems\RecommendationBundle\eZ\Publish\Slot\CopyContent'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\ContentService\CopyContentSignal']; + } +} diff --git a/Tests/eZ/Publish/Slot/CopySubtreeTest.php b/Tests/eZ/Publish/Slot/CopySubtreeTest.php new file mode 100644 index 0000000..e0ae178 --- /dev/null +++ b/Tests/eZ/Publish/Slot/CopySubtreeTest.php @@ -0,0 +1,57 @@ +createSignal(); + + $locationHandler = $this->getMock('\eZ\Publish\SPI\Persistence\Content\Location\Handler'); + $locationHandler + ->expects($this->once()) + ->method('loadSubtreeIds') + ->with($signal->targetNewSubtreeId) + ->willReturn($this->getTargetNewSubtreeId()); + + $this->persistenceHandler + ->expects($this->any()) + ->method('locationHandler') + ->willReturn($locationHandler); + + $this->assertRecommendationServiceIsNotified([ + 'updateContent' => $this->getTargetNewSubtreeId(), + ]); + + $this->slot->receive($this->createSignal()); + } + + protected function createSignal() + { + return new CopySubtreeSignal([ + 'targetNewSubtreeId' => 100, + ]); + } + + protected function getSlotClass() + { + return '\EzSystems\RecommendationBundle\eZ\Publish\Slot\CopySubtree'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\LocationService\CopySubtreeSignal']; + } + + private function getTargetNewSubtreeId() + { + return [2016, 2017, 2018]; + } +} diff --git a/Tests/eZ/Publish/Slot/CreateLocationTest.php b/Tests/eZ/Publish/Slot/CreateLocationTest.php new file mode 100644 index 0000000..577cb43 --- /dev/null +++ b/Tests/eZ/Publish/Slot/CreateLocationTest.php @@ -0,0 +1,42 @@ +createSignal(); + + $this->assertRecommendationServiceIsNotified([ + 'updateContent' => [self::CONTENT_ID], + ]); + + $this->slot->receive($signal); + } + + protected function createSignal() + { + return new CreateLocationSignal([ + 'contentId' => self::CONTENT_ID, + ]); + } + + protected function getSlotClass() + { + return '\EzSystems\RecommendationBundle\eZ\Publish\Slot\CreateLocation'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\LocationService\CreateLocationSignal']; + } +} diff --git a/Tests/eZ/Publish/Slot/DeleteContentTest.php b/Tests/eZ/Publish/Slot/DeleteContentTest.php new file mode 100644 index 0000000..9029033 --- /dev/null +++ b/Tests/eZ/Publish/Slot/DeleteContentTest.php @@ -0,0 +1,42 @@ +createSignal(); + + $this->assertRecommendationServiceIsNotified([ + 'deleteContent' => [self::CONTENT_ID], + ]); + + $this->slot->receive($signal); + } + + protected function createSignal() + { + return new DeleteContentSignal([ + 'contentId' => self::CONTENT_ID, + ]); + } + + protected function getSlotClass() + { + return 'EzSystems\RecommendationBundle\eZ\Publish\Slot\DeleteContent'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\ContentService\DeleteContentSignal']; + } +} diff --git a/Tests/eZ/Publish/Slot/DeleteLocationTest.php b/Tests/eZ/Publish/Slot/DeleteLocationTest.php new file mode 100644 index 0000000..d87bccb --- /dev/null +++ b/Tests/eZ/Publish/Slot/DeleteLocationTest.php @@ -0,0 +1,42 @@ +createSignal(); + + $this->assertRecommendationServiceIsNotified([ + 'deleteContent' => [self::CONTENT_ID], + ]); + + $this->slot->receive($signal); + } + + protected function createSignal() + { + return new DeleteLocationSignal([ + 'contentId' => self::CONTENT_ID, + ]); + } + + protected function getSlotClass() + { + return 'EzSystems\RecommendationBundle\eZ\Publish\Slot\DeleteLocation'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\LocationService\DeleteLocationSignal']; + } +} diff --git a/Tests/eZ/Publish/Slot/DeleteVersionTest.php b/Tests/eZ/Publish/Slot/DeleteVersionTest.php new file mode 100644 index 0000000..67eecb1 --- /dev/null +++ b/Tests/eZ/Publish/Slot/DeleteVersionTest.php @@ -0,0 +1,42 @@ +createSignal(); + + $this->assertRecommendationServiceIsNotified([ + 'updateContent' => [self::CONTENT_ID], + ]); + + $this->slot->receive($signal); + } + + protected function createSignal() + { + return new DeleteVersionSignal([ + 'contentId' => self::CONTENT_ID, + ]); + } + + protected function getSlotClass() + { + return 'EzSystems\RecommendationBundle\eZ\Publish\Slot\DeleteVersion'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\ContentService\DeleteVersionSignal']; + } +} diff --git a/Tests/eZ/Publish/Slot/HideLocationTest.php b/Tests/eZ/Publish/Slot/HideLocationTest.php new file mode 100644 index 0000000..c621c4f --- /dev/null +++ b/Tests/eZ/Publish/Slot/HideLocationTest.php @@ -0,0 +1,42 @@ +createSignal(); + + $this->assertRecommendationServiceIsNotified([ + 'hideLocation' => [self::LOCATION_ID], + ]); + + $this->slot->receive($signal); + } + + protected function createSignal() + { + return new HideLocationSignal([ + 'locationId' => self::LOCATION_ID, + ]); + } + + protected function getSlotClass() + { + return 'EzSystems\RecommendationBundle\eZ\Publish\Slot\HideLocation'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\LocationService\HideLocationSignal']; + } +} diff --git a/Tests/eZ/Publish/Slot/MoveSubtreeTest.php b/Tests/eZ/Publish/Slot/MoveSubtreeTest.php new file mode 100644 index 0000000..4462765 --- /dev/null +++ b/Tests/eZ/Publish/Slot/MoveSubtreeTest.php @@ -0,0 +1,59 @@ +createSignal(); + + $locationHandler = $this->getMock('\eZ\Publish\SPI\Persistence\Content\Location\Handler'); + $locationHandler + ->expects($this->once()) + ->method('loadSubtreeIds') + ->with($signal->locationId) + ->willReturn($this->getSubtreeIds()); + + $this->persistenceHandler + ->expects($this->any()) + ->method('locationHandler') + ->willReturn($locationHandler); + + $this->assertRecommendationServiceIsNotified([ + 'updateContent' => $this->getSubtreeIds(), + ]); + + $this->slot->receive($this->createSignal()); + } + + protected function createSignal() + { + return new MoveSubtreeSignal([ + 'locationId' => self::LOCATION_ID, + ]); + } + + protected function getSlotClass() + { + return '\EzSystems\RecommendationBundle\eZ\Publish\Slot\MoveSubtree'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\LocationService\MoveSubtreeSignal']; + } + + private function getSubtreeIds() + { + return [2016, 2017, 2018]; + } +} diff --git a/Tests/eZ/Publish/Slot/PublishVersionTest.php b/Tests/eZ/Publish/Slot/PublishVersionTest.php new file mode 100644 index 0000000..5df9f63 --- /dev/null +++ b/Tests/eZ/Publish/Slot/PublishVersionTest.php @@ -0,0 +1,63 @@ +getMock('\eZ\Publish\SPI\Persistence\Content\Handler'); + $contentHandler + ->expects($this->once()) + ->method('loadReverseRelations') + ->with(self::CONTENT_ID) + ->willReturn(array_map(function ($id) { + return new Relation([ + 'destinationContentId' => $id, + ]); + }, $this->getReverseRelationsIds())); + + $this->persistenceHandler + ->expects($this->once()) + ->method('contentHandler') + ->willReturn($contentHandler); + + $this->assertRecommendationServiceIsNotified([ + 'updateContent' => array_merge($this->getReverseRelationsIds(), [ + self::CONTENT_ID, + ]), + ]); + + $this->slot->receive($this->createSignal()); + } + + protected function createSignal() + { + return new PublishVersionSignal([ + 'contentId' => self::CONTENT_ID, + ]); + } + + protected function getSlotClass() + { + return 'EzSystems\RecommendationBundle\eZ\Publish\Slot\PublishVersion'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\ContentService\PublishVersionSignal']; + } + + private function getReverseRelationsIds() + { + return [101, 105, 107]; + } +} diff --git a/Tests/eZ/Publish/Slot/RecoverTest.php b/Tests/eZ/Publish/Slot/RecoverTest.php new file mode 100644 index 0000000..c2b0f0f --- /dev/null +++ b/Tests/eZ/Publish/Slot/RecoverTest.php @@ -0,0 +1,83 @@ +createSignal(); + + $locationHandler = $this->getMock('\eZ\Publish\SPI\Persistence\Content\Location\Handler'); + $locationHandler + ->expects($this->once()) + ->method('loadSubtreeIds') + ->with($signal->newLocationId) + ->willReturn($this->getSubtreeIds()); + + $contentHandler = $this->getMock('\eZ\Publish\SPI\Persistence\Content\Handler'); + $contentHandler + ->expects($this->once()) + ->method('loadReverseRelations') + ->with(self::CONTENT_ID) + ->willReturn(array_map(function ($id) { + return new Relation([ + 'destinationContentId' => $id, + ]); + }, $this->getReverseRelationsIds())); + + $this->persistenceHandler + ->expects($this->any()) + ->method('contentHandler') + ->willReturn($contentHandler); + + $this->persistenceHandler + ->expects($this->any()) + ->method('locationHandler') + ->willReturn($locationHandler); + + $this->assertRecommendationServiceIsNotified([ + 'updateContent' => array_merge($this->getReverseRelationsIds(), $this->getSubtreeIds()), + ]); + + $this->slot->receive($signal); + } + + protected function createSignal() + { + return new RecoverSignal([ + 'contentId' => self::CONTENT_ID, + 'newLocationId' => self::LOCATION_ID, + ]); + } + + protected function getSlotClass() + { + return 'EzSystems\RecommendationBundle\eZ\Publish\Slot\Recover'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\TrashService\RecoverSignal']; + } + + private function getSubtreeIds() + { + return [2016, 2017, 2018]; + } + + private function getReverseRelationsIds() + { + return [101, 105, 107]; + } +} diff --git a/Tests/eZ/Publish/Slot/SetContentStateTest.php b/Tests/eZ/Publish/Slot/SetContentStateTest.php new file mode 100644 index 0000000..c6c1949 --- /dev/null +++ b/Tests/eZ/Publish/Slot/SetContentStateTest.php @@ -0,0 +1,41 @@ +createSignal(); + + $this->assertRecommendationServiceIsNotified([ + 'updateContent' => [self::CONTENT_ID], + ]); + + $this->slot->receive($signal); + } + + protected function createSignal() + { + return new SetContentStateSignal([ + 'contentId' => self::CONTENT_ID, + ]); + } + + protected function getSlotClass() + { + return 'EzSystems\RecommendationBundle\eZ\Publish\Slot\SetContentState'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\ObjectStateService\SetContentStateSignal']; + } +} diff --git a/Tests/eZ/Publish/Slot/TrashTest.php b/Tests/eZ/Publish/Slot/TrashTest.php new file mode 100644 index 0000000..c0301a6 --- /dev/null +++ b/Tests/eZ/Publish/Slot/TrashTest.php @@ -0,0 +1,63 @@ +getMock('\eZ\Publish\SPI\Persistence\Content\Handler'); + $contentHandler + ->expects($this->once()) + ->method('loadReverseRelations') + ->with(self::CONTENT_ID) + ->willReturn(array_map(function ($id) { + return new Relation([ + 'destinationContentId' => $id, + ]); + }, $this->getReverseRelationsIds())); + + $this->persistenceHandler + ->expects($this->once()) + ->method('contentHandler') + ->willReturn($contentHandler); + + $this->assertRecommendationServiceIsNotified([ + 'deleteContent' => [self::CONTENT_ID], + 'updateContent' => $this->getReverseRelationsIds(), + ]); + + $this->slot->receive($this->createSignal()); + } + + protected function createSignal() + { + return new TrashSignal([ + 'contentId' => self::CONTENT_ID, + ]); + } + + protected function getSlotClass() + { + return 'EzSystems\RecommendationBundle\eZ\Publish\Slot\Trash'; + } + + protected function getReceivedSignalClasses() + { + return ['eZ\Publish\Core\SignalSlot\Signal\TrashService\TrashSignal']; + } + + private function getReverseRelationsIds() + { + return [101, 105, 107]; + } +} diff --git a/composer.json b/composer.json index 07afdfc..8cc25c2 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "ezsystems/ezpublish-kernel": "~5.1 || ^6.7", + "ezsystems/ezpublish-kernel": "^5.4.12 || ~6.0.1.7 || ^6.7 || ^7.0", "guzzlehttp/guzzle": "~5.0|~6.0", "components/handlebars.js": "~3.0.0", "symfony/symfony": "^2.7.7 || ^3.3" diff --git a/eZ/Publish/Slot/PublishVersion.php b/eZ/Publish/Slot/PublishVersion.php index dca4813..bb6b71e 100644 --- a/eZ/Publish/Slot/PublishVersion.php +++ b/eZ/Publish/Slot/PublishVersion.php @@ -10,7 +10,7 @@ namespace EzSystems\RecommendationBundle\eZ\Publish\Slot; use eZ\Publish\Core\SignalSlot\Signal; -class PublishVersion extends Base +class PublishVersion extends PersistenceAwareBase { public function receive(Signal $signal) { @@ -18,6 +18,13 @@ class PublishVersion extends Base return; } + $relations = $this->persistenceHandler + ->contentHandler() + ->loadReverseRelations($signal->contentId); + $this->client->updateContent($signal->contentId); + foreach ($relations as $relation) { + $this->client->updateContent($relation->destinationContentId); + } } } diff --git a/eZ/Publish/Slot/Recover.php b/eZ/Publish/Slot/Recover.php index 3d0a10d..b69ee7a 100644 --- a/eZ/Publish/Slot/Recover.php +++ b/eZ/Publish/Slot/Recover.php @@ -18,9 +18,20 @@ class Recover extends PersistenceAwareBase return; } - $contentIdArray = $this->persistenceHandler->locationHandler()->loadSubtreeIds($signal->newLocationId); + $contentIdArray = $this->persistenceHandler + ->locationHandler() + ->loadSubtreeIds($signal->newLocationId); + + $relations = $this->persistenceHandler + ->contentHandler() + ->loadReverseRelations($signal->contentId); + foreach ($contentIdArray as $contentId) { $this->client->updateContent($contentId); } + + foreach ($relations as $relation) { + $this->client->updateContent($relation->destinationContentId); + } } } diff --git a/eZ/Publish/Slot/Trash.php b/eZ/Publish/Slot/Trash.php index c476196..58c297b 100644 --- a/eZ/Publish/Slot/Trash.php +++ b/eZ/Publish/Slot/Trash.php @@ -10,7 +10,7 @@ namespace EzSystems\RecommendationBundle\eZ\Publish\Slot; use eZ\Publish\Core\SignalSlot\Signal; -class Trash extends Base +class Trash extends PersistenceAwareBase { public function receive(Signal $signal) { @@ -19,5 +19,12 @@ class Trash extends Base } $this->client->deleteContent($signal->contentId); + + $relations = $this->persistenceHandler + ->contentHandler() + ->loadReverseRelations($signal->contentId); + foreach ($relations as $relation) { + $this->client->updateContent($relation->destinationContentId); + } } }