From 6a6caf2d6a10e93834339cd547741dfd6d4c340b Mon Sep 17 00:00:00 2001 From: Alexander Nezdoiminoga Date: Fri, 8 Jan 2016 16:03:11 +0200 Subject: [PATCH 1/2] BAP-9639: 500 error is occurred on Business Units - activity placeholder fixes - unit tests - template fixes (potential issue with hangouts button) --- .../Placeholder/PlaceholderFilter.php | 56 +++++-- .../Resources/config/services.yml | 1 + .../Placeholder/PlaceholderFilterTest.php | 145 +++++++++--------- .../Entity/BusinessUnit.php | 3 + 4 files changed, 126 insertions(+), 79 deletions(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Placeholder/PlaceholderFilter.php b/src/Oro/Bundle/ActivityListBundle/Placeholder/PlaceholderFilter.php index 7288b8ad675..c7b2931ecca 100644 --- a/src/Oro/Bundle/ActivityListBundle/Placeholder/PlaceholderFilter.php +++ b/src/Oro/Bundle/ActivityListBundle/Placeholder/PlaceholderFilter.php @@ -5,9 +5,11 @@ use Doctrine\Common\Persistence\ManagerRegistry; use Oro\Bundle\ActivityBundle\EntityConfig\ActivityScope; +use Oro\Bundle\ActivityBundle\Manager\ActivityManager; use Oro\Bundle\ActivityListBundle\Provider\ActivityListChainProvider; use Oro\Bundle\EntityBundle\ORM\DoctrineHelper; use Oro\Bundle\EntityConfigBundle\Provider\ConfigProvider; +use Oro\Bundle\EntityExtendBundle\Tools\ExtendHelper; use Oro\Bundle\UIBundle\Event\BeforeGroupingChainWidgetEvent; class PlaceholderFilter @@ -24,22 +26,28 @@ class PlaceholderFilter /** @var ConfigProvider */ protected $configProvider; + /** @var ActivityManager */ + protected $activityManager; + /** * @param ActivityListChainProvider $activityListChainProvider * @param ManagerRegistry $doctrine * @param DoctrineHelper $doctrineHelper * @param ConfigProvider $configProvider + * @param ActivityManager $activityManager */ public function __construct( ActivityListChainProvider $activityListChainProvider, ManagerRegistry $doctrine, DoctrineHelper $doctrineHelper, - ConfigProvider $configProvider + ConfigProvider $configProvider, + ActivityManager $activityManager ) { $this->activityListProvider = $activityListChainProvider; $this->doctrine = $doctrine; $this->doctrineHelper = $doctrineHelper; $this->configProvider = $configProvider; + $this->activityManager = $activityManager; } /** @@ -52,33 +60,60 @@ public function __construct( public function isApplicable($entity = null, $pageType = null) { if ($pageType === null || !is_object($entity) || !$this->doctrineHelper->isManageableEntity($entity) || - $this->doctrineHelper->isNewEntity($entity)) { + $this->doctrineHelper->isNewEntity($entity) + ) { + return false; + } + + $entityClass = $this->doctrineHelper->getEntityClass($entity); + if (!$this->configProvider->hasConfig($entityClass)) { + return false; + } + + $hasAppliedActivityAssociation = false; + $activityAssociations = $this->activityManager->getActivityAssociations($entityClass); + foreach ($activityAssociations as $activityAssociation) { + $isAssociationAccessible = ExtendHelper::isFieldAccessible( + $this->configProvider->getConfig( + $activityAssociation['className'], + $activityAssociation['associationName'] + ) + ); + if ($isAssociationAccessible) { + $hasAppliedActivityAssociation = true; + break; + } + } + + /** + * If at least one activity is accessible we can continue otherwise no. + */ + if (!$hasAppliedActivityAssociation) { return false; } $pageType = (int) $pageType; $id = $this->doctrineHelper->getSingleEntityIdentifier($entity); - $entityClass = $this->doctrineHelper->getEntityClass($entity); $activityListRepo = $this->doctrine->getRepository('OroActivityListBundle:ActivityList'); - return $this->isAllowedOnPage($entity, $pageType) && ( + return $this->isAllowedOnPage($entityClass, $pageType) && ( in_array($entityClass, $this->activityListProvider->getTargetEntityClasses()) || (bool)$activityListRepo->getRecordsCountForTargetClassAndId($entityClass, $id) ); } /** - * @param object $entity + * @param string $entityClass * @param int $pageType * @return bool */ - protected function isAllowedOnPage($entity, $pageType) + protected function isAllowedOnPage($entityClass, $pageType) { - if (!$this->configProvider->hasConfig($entity)) { + if (!$this->configProvider->hasConfig($entityClass)) { return false; } - $config = $this->configProvider->getConfig($entity); + $config = $this->configProvider->getConfig($entityClass); if (!$config->has(ActivityScope::SHOW_ON_PAGE)) { return false; } @@ -101,7 +136,10 @@ public function isAllowedButton(BeforeGroupingChainWidgetEvent $event) $entity = $event->getEntity(); $pageType = $event->getPageType(); - if ($pageType === null || !is_object($entity) || !$this->isAllowedOnPage($entity, $pageType)) { + if ($pageType === null + || !is_object($entity) + || !$this->isAllowedOnPage($this->doctrineHelper->getEntityClass($entity), $pageType) + ) { // Clear allowed widgets $event->setWidgets([]); } diff --git a/src/Oro/Bundle/ActivityListBundle/Resources/config/services.yml b/src/Oro/Bundle/ActivityListBundle/Resources/config/services.yml index dbd8e6e20c9..e6b445e63dc 100644 --- a/src/Oro/Bundle/ActivityListBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/ActivityListBundle/Resources/config/services.yml @@ -70,6 +70,7 @@ services: - @doctrine - @oro_entity.doctrine_helper - @oro_entity_config.provider.activity + - @oro_activity.manager tags: - { name: kernel.event_listener, event: oro.ui.grouping_chain_widget.before, method: isAllowedButton } diff --git a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Placeholder/PlaceholderFilterTest.php b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Placeholder/PlaceholderFilterTest.php index 0c89230968c..60db6fd0b71 100644 --- a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Placeholder/PlaceholderFilterTest.php +++ b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Placeholder/PlaceholderFilterTest.php @@ -11,8 +11,7 @@ use Oro\Bundle\ActivityListBundle\Tests\Unit\Placeholder\Fixture\TestNonManagedTarget; use Oro\Bundle\ActivityListBundle\Tests\Unit\Placeholder\Fixture\TestTarget; use Oro\Bundle\EntityBundle\ORM\DoctrineHelper; -use Oro\Bundle\EntityConfigBundle\Provider\ConfigProvider; -use Oro\Bundle\EntityConfigBundle\Exception\RuntimeException; +use Oro\Bundle\EntityConfigBundle\Tests\Unit\ConfigProviderMock; use Oro\Bundle\UIBundle\Event\BeforeGroupingChainWidgetEvent; class PlaceholderFilterTest extends \PHPUnit_Framework_TestCase @@ -20,13 +19,16 @@ class PlaceholderFilterTest extends \PHPUnit_Framework_TestCase /** @var \PHPUnit_Framework_MockObject_MockObject|ActivityListChainProvider */ protected $activityListProvider; + /** @var \PHPUnit_Framework_MockObject_MockObject|ActivityListChainProvider */ + protected $activityManager; + /** @var \PHPUnit_Framework_MockObject_MockObject|ManagerRegistry */ protected $doctrine; /** @var PlaceholderFilter */ protected $filter; - /** @var \PHPUnit_Framework_MockObject_MockObject|ConfigProvider */ + /** @var ConfigProviderMock */ protected $configProvider; /** @var array */ @@ -42,6 +44,11 @@ public function setUp() ->disableOriginalConstructor() ->getMock(); + $this->activityManager = $this + ->getMockBuilder('Oro\Bundle\ActivityBundle\Manager\ActivityManager') + ->disableOriginalConstructor() + ->getMock(); + $this->doctrine = $this ->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') ->disableOriginalConstructor() @@ -73,23 +80,40 @@ public function setUp() return !$entity instanceof TestNonManagedTarget; }); - $this->configureConfigProvider(); + $configManager = $this->getMockBuilder('Oro\Bundle\EntityConfigBundle\Config\ConfigManager') + ->disableOriginalConstructor() + ->getMock(); + $this->configProvider = new ConfigProviderMock($configManager, 'activity'); $this->filter = new PlaceholderFilter( $this->activityListProvider, $this->doctrine, $this->doctrineHelper, - $this->configProvider + $this->configProvider, + $this->activityManager ); } public function testIsApplicable() { $testTarget = new TestTarget(1); - $this->setConfigProviderEntitySupport( - $testTarget, - '\Oro\Bundle\ActivityBundle\EntityConfig\ActivityScope::VIEW_PAGE' + + $entityClass = get_class($testTarget); + $this->configProvider->addEntityConfig( + $entityClass, + [ActivityScope::SHOW_ON_PAGE => '\Oro\Bundle\ActivityBundle\EntityConfig\ActivityScope::VIEW_PAGE'] ); + $this->configProvider->addFieldConfig($entityClass, 'associationField'); + + $this->activityManager + ->expects($this->once()) + ->method('getActivityAssociations') + ->with($entityClass) + ->willReturn( + [ + ['className' => $entityClass, 'associationName' => 'associationField'] + ] + ); $this->assertTrue($this->filter->isApplicable($testTarget, ActivityScope::VIEW_PAGE)); $this->assertFalse($this->filter->isApplicable(null, ActivityScope::VIEW_PAGE)); @@ -105,15 +129,24 @@ public function testIsApplicableWithShowOnPageConfiguration() { $entity = new TestTarget(1); - $this->setConfigProviderEntitySupport( - $entity, - '\Oro\Bundle\ActivityBundle\EntityConfig\ActivityScope::UPDATE_PAGE' + $entityClass = get_class($entity); + $this->configProvider->addEntityConfig( + $entityClass, + [ActivityScope::SHOW_ON_PAGE => '\Oro\Bundle\ActivityBundle\EntityConfig\ActivityScope::UPDATE_PAGE'] ); + $this->configProvider->addFieldConfig($entityClass, 'associationField'); + $this->activityManager->expects($this->exactly(2)) + ->method('getActivityAssociations') + ->with($entityClass) + ->willReturn([ + ['className' => $entityClass, 'associationName' => 'associationField'] + ]); + $this->assertFalse($this->filter->isApplicable($entity, ActivityScope::VIEW_PAGE)); - $this->setConfigProviderEntitySupport( - $entity, - '\Oro\Bundle\ActivityBundle\EntityConfig\ActivityScope::VIEW_UPDATE_PAGES' + $this->configProvider->addEntityConfig( + $entityClass, + [ActivityScope::SHOW_ON_PAGE => '\Oro\Bundle\ActivityBundle\EntityConfig\ActivityScope::VIEW_UPDATE_PAGES'] ); $this->assertTrue($this->filter->isApplicable($entity, ActivityScope::VIEW_PAGE)); } @@ -133,10 +166,23 @@ public function testIsApplicableOnNonSupportedTarget() ->willReturn(true); $entity = new TestNonActiveTarget(123); - $this->setConfigProviderEntitySupport( - $entity, - '\Oro\Bundle\ActivityBundle\EntityConfig\ActivityScope::VIEW_PAGE' + + $entityClass = get_class($entity); + $this->configProvider->addEntityConfig( + $entityClass, + [ActivityScope::SHOW_ON_PAGE => '\Oro\Bundle\ActivityBundle\EntityConfig\ActivityScope::VIEW_PAGE'] ); + $this->configProvider->addFieldConfig($entityClass, 'associationField'); + + $this->activityManager + ->expects($this->once()) + ->method('getActivityAssociations') + ->with($entityClass) + ->willReturn( + [ + ['className' => $entityClass, 'associationName' => 'associationField'] + ] + ); $this->assertTrue($this->filter->isApplicable($entity, ActivityScope::VIEW_PAGE)); } @@ -147,13 +193,19 @@ public function testIsApplicableOnNonSupportedTarget() public function testIsAllowedButtonWithUnknownPageConstant() { $entity = new TestTarget(1); - $this->setConfigProviderEntitySupport($entity, 'UNKNOWN_ORO_CONSTANT'); + + $this->configProvider->addEntityConfig( + get_class($entity), + [ActivityScope::SHOW_ON_PAGE => 'UNKNOWN_ORO_CONSTANT'] + ); + $event = new BeforeGroupingChainWidgetEvent(ActivityScope::SHOW_ON_PAGE, [], $entity); $this->filter->isAllowedButton($event); } /** - * @dataProvider isAllowedButtonProvider + * @dataProvider isAllowedButtonProvider + * * @param int $pageType * @param array $widgets * @param object $entity @@ -163,7 +215,10 @@ public function testIsAllowedButtonWithUnknownPageConstant() public function testIsAllowedButton($pageType, $widgets, $entity, $configProviderSetting, $expected) { if ($configProviderSetting !== null) { - $this->setConfigProviderEntitySupport($entity, $configProviderSetting); + $this->configProvider->addEntityConfig( + get_class($entity), + [ActivityScope::SHOW_ON_PAGE => $configProviderSetting] + ); } $event = new BeforeGroupingChainWidgetEvent($pageType, $widgets, $entity); $this->filter->isAllowedButton($event); @@ -201,54 +256,4 @@ public function isAllowedButtonProvider() ], ]; } - - /** - * @param $entity - * @param $value - */ - protected function setConfigProviderEntitySupport($entity, $value) - { - $entityHash = spl_object_hash($entity); - $this->entities[$entityHash] = $value; - } - - protected function configureConfigProvider() - { - $this->configProvider = $this->getMockBuilder('Oro\Bundle\EntityConfigBundle\Provider\ConfigProvider') - ->disableOriginalConstructor() - ->getMock(); - - $this->configProvider->expects($this->any()) - ->method('hasConfig') - ->willReturnCallback(function ($entity) { - $entityHash = spl_object_hash($entity); - return array_key_exists($entityHash, $this->entities); - }); - - $this->configProvider->expects($this->any()) - ->method('getConfig') - ->willReturnCallback(function ($entity) { - $entityHash = spl_object_hash($entity); - - if (!array_key_exists($entityHash, $this->entities)) { - throw new RuntimeException(); - } - - $config = $this->getMockBuilder('Oro\Bundle\EntityConfigBundle\Config\ConfigInterface') - ->disableOriginalConstructor() - ->getMock(); - - $config->expects($this->any()) - ->method('get') - ->with($this->equalTo(ActivityScope::SHOW_ON_PAGE)) - ->willReturn($this->entities[$entityHash]); - - $config->expects($this->any()) - ->method('has') - ->with($this->equalTo(ActivityScope::SHOW_ON_PAGE)) - ->willReturn(array_key_exists($entityHash, $this->entities)); - - return $config; - }); - } } diff --git a/src/Oro/Bundle/OrganizationBundle/Entity/BusinessUnit.php b/src/Oro/Bundle/OrganizationBundle/Entity/BusinessUnit.php index 92b3f4fb622..f9d850d7e76 100644 --- a/src/Oro/Bundle/OrganizationBundle/Entity/BusinessUnit.php +++ b/src/Oro/Bundle/OrganizationBundle/Entity/BusinessUnit.php @@ -21,6 +21,9 @@ * @ORM\HasLifecycleCallbacks() * @Oro\Loggable * @Config( + * routeName="oro_business_unit_index", + * routeView="oro_business_unit_view", + * routeCreate="oro_business_unit_create", * defaultValues={ * "grouping"={ * "groups"={"dictionary"} From d4bc4470b33d66699926851cf42b7bd9d045d44d Mon Sep 17 00:00:00 2001 From: Vova Soroka Date: Mon, 11 Jan 2016 14:26:28 +0200 Subject: [PATCH 2/2] BAP-9639: 500 error is occurred on Business Units --- .../ActivityBundle/Manager/ActivityManager.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Oro/Bundle/ActivityBundle/Manager/ActivityManager.php b/src/Oro/Bundle/ActivityBundle/Manager/ActivityManager.php index 67582e9a7b3..e8d25624003 100644 --- a/src/Oro/Bundle/ActivityBundle/Manager/ActivityManager.php +++ b/src/Oro/Bundle/ActivityBundle/Manager/ActivityManager.php @@ -413,15 +413,14 @@ public function getActivityAssociations($entityClass) $config = $this->activityConfigProvider->getConfig($entityClass); $activityClassNames = $config->get('activities', false, []); foreach ($activityClassNames as $activityClassName) { - if (!$this->isActivityAssociationEnabled($entityClass, $activityClassName)) { + $associationName = ExtendHelper::buildAssociationName($entityClass, ActivityScope::ASSOCIATION_KIND); + if (!$this->isActivityAssociationEnabled($entityClass, $activityClassName, $associationName)) { continue; } $entityConfig = $this->entityConfigProvider->getConfig($activityClassName); $activityConfig = $this->activityConfigProvider->getConfig($activityClassName); - $associationName = ExtendHelper::buildAssociationName($entityClass, ActivityScope::ASSOCIATION_KIND); - $item = [ 'className' => $activityClassName, 'associationName' => $associationName, @@ -457,15 +456,14 @@ public function getActivityActions($entityClass) $activityClassNames = $this->activityConfigProvider->getConfig($entityClass)->get('activities'); foreach ($activityClassNames as $activityClassName) { - if (!$this->isActivityAssociationEnabled($entityClass, $activityClassName)) { + $associationName = ExtendHelper::buildAssociationName($entityClass, ActivityScope::ASSOCIATION_KIND); + if (!$this->isActivityAssociationEnabled($entityClass, $activityClassName, $associationName)) { continue; } $activityConfig = $this->activityConfigProvider->getConfig($activityClassName); $buttonWidget = $activityConfig->get('action_button_widget'); if (!empty($buttonWidget)) { - $associationName = ExtendHelper::buildAssociationName($entityClass, ActivityScope::ASSOCIATION_KIND); - $item = [ 'className' => $activityClassName, 'associationName' => $associationName, @@ -566,16 +564,17 @@ public function addFilterByTargetEntity( /** * @param string $entityClass * @param string $activityClassName + * @param string $activityAssociationName * * @return bool */ - protected function isActivityAssociationEnabled($entityClass, $activityClassName) + protected function isActivityAssociationEnabled($entityClass, $activityClassName, $activityAssociationName) { $extendConfig = $this->extendConfigProvider->getConfig($activityClassName); $relations = $extendConfig->get('relation', false, []); $relationKey = ExtendHelper::buildRelationKey( $activityClassName, - ExtendHelper::buildAssociationName($entityClass, ActivityScope::ASSOCIATION_KIND), + $activityAssociationName, RelationType::MANY_TO_MANY, $entityClass );