Skip to content

Commit

Permalink
Merge pull request #1595 from laboro/fix/BAP-3788
Browse files Browse the repository at this point in the history
Fix/bap 3788
  • Loading branch information
yshyshkin committed Mar 31, 2014
2 parents 7858000 + f4b3472 commit e3129b2
Show file tree
Hide file tree
Showing 3 changed files with 295 additions and 1 deletion.
262 changes: 262 additions & 0 deletions src/Oro/Bundle/NavigationBundle/Tests/Unit/Twig/MenuExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Oro\Bundle\NavigationBundle\Tests\Unit\Twig;

use Knp\Menu\ItemInterface;
use Oro\Bundle\NavigationBundle\Twig\MenuExtension;

class MenuExtensionTest extends \PHPUnit_Framework_TestCase
Expand Down Expand Up @@ -151,6 +152,9 @@ public function testRenderMenuInstance()
$menuInstance->expects($this->once())
->method('getExtra')
->with('type');
$menuInstance->expects($this->any())
->method('getIterator')
->will($this->returnValue(new \ArrayIterator()));
$this->assertRender($menuInstance, $menuInstance, $options, $renderer);
}

Expand All @@ -163,6 +167,9 @@ public function testRenderMenuAsArray()
$menuInstance->expects($this->once())
->method('getExtra')
->with('type');
$menuInstance->expects($this->any())
->method('getIterator')
->will($this->returnValue(new \ArrayIterator()));
$this->assertRender($menu, $menuInstance, $options, $renderer);
}

Expand All @@ -180,6 +187,9 @@ public function testRenderMenuInstanceWithExtra($options)
->method('getExtra')
->with('type')
->will($this->returnValue('type'));
$menuInstance->expects($this->any())
->method('getIterator')
->will($this->returnValue(new \ArrayIterator()));

$runtimeOptions = array(
'template' => 'test_runtime.tpl'
Expand Down Expand Up @@ -215,6 +225,258 @@ public function typeOptionsDataProvider()
);
}

/**
* @dataProvider menuItemsDataProvider
* @param array $items
* @param array $expected
*/
public function testFilterUnallowedItems($items, $expected)
{
$menu = $this->getMockBuilder('Knp\Menu\ItemInterface')
->getMockForAbstractClass();

$menu->expects($this->atLeastOnce())
->method('getIterator')
->will($this->returnValue(new \ArrayIterator($items)));

$this->helper->expects($this->once())
->method('render')
->will(
$this->returnCallback(
function ($menu) use ($expected) {
$result = $this->collectResultItemsData($menu);
\PHPUnit_Framework_Assert::assertEquals($expected, $result);
}
)
);

$this->menuExtension->render($menu);
}

protected function collectResultItemsData($item)
{
$result = array();
/** @var ItemInterface $sub */
foreach ($item as $sub) {
$result[] = array(
'label' => $sub->getLabel(),
'uri' => $sub->getUri(),
'isAllowed' => $sub->getExtra('isAllowed'),
'children' => $this->collectResultItemsData($sub)
);
}

return $result;
}

/**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @return array
*/
public function menuItemsDataProvider()
{
return array(
array(
array(
$this->getMenuItem('item_1'),
$this->getMenuItem(
'item_2',
true,
array(
$this->getMenuItem('item_2_1'),
$this->getMenuItem(''),
)
),
$this->getMenuItem(
'item_3',
true,
array(
$this->getMenuItem('item_3_1', false),
$this->getMenuItem('item_3_2'),
)
),
$this->getMenuItem(
'item_4',
true,
array(
$this->getMenuItem('item_4_1', false),
$this->getMenuItem(''),
)
),
$this->getMenuItem(
'item_5',
true,
array(
$this->getMenuItem(
'item_5_1',
true,
array(
$this->getMenuItem('item_5_1_1', false),
)
)
),
'#'
),
$this->getMenuItem(
'item_6',
true,
array(
$this->getMenuItem('item_6_1', false),
$this->getMenuItem(''),
),
'/my-uri'
),
),
array(
array(
'label' => 'item_1',
'uri' => '',
'isAllowed' => true,
'children' => array()
),
array(
'label' => 'item_2',
'uri' => '',
'isAllowed' => true,
'children' => array(
array(
'label' => 'item_2_1',
'uri' => '',
'isAllowed' => true,
'children' => array()
),
array(
'label' => '',
'uri' => '',
'isAllowed' => true,
'children' => array()
),
)
),
array(
'label' => 'item_3',
'uri' => '',
'isAllowed' => true,
'children' => array(
array(
'label' => 'item_3_1',
'uri' => '',
'isAllowed' => false,
'children' => array()
),
array(
'label' => 'item_3_2',
'uri' => '',
'isAllowed' => true,
'children' => array()
),
)
),
array(
'label' => 'item_4',
'uri' => '',
'isAllowed' => false,
'children' => array(
array(
'label' => 'item_4_1',
'uri' => '',
'isAllowed' => false,
'children' => array()
),
array(
'label' => '',
'uri' => '',
'isAllowed' => true,
'children' => array()
),
)
),
array(
'label' => 'item_5',
'uri' => '#',
'isAllowed' => false,
'children' => array(
array(
'label' => 'item_5_1',
'uri' => '',
'isAllowed' => false,
'children' => array(
array(
'label' => 'item_5_1_1',
'uri' => '',
'isAllowed' => false,
'children' => array()
),
)
)
)
),
array(
'label' => 'item_6',
'uri' => '/my-uri',
'isAllowed' => true,
'children' => array(
array(
'label' => 'item_6_1',
'uri' => '',
'isAllowed' => false,
'children' => array()
),
array(
'label' => '',
'uri' => '',
'isAllowed' => true,
'children' => array()
),
)
),
)
)
);
}

protected function getMenuItem($label, $isAllowed = true, $children = array(), $uri = '')
{
$menu = $this->getMockBuilder('Knp\Menu\MenuItem')
->disableOriginalConstructor()
->setMethods(array('getLabel', 'getUri', 'hasChildren', 'getChildren', 'getIterator', 'count'))
->getMock();

$menu->expects($this->any())
->method('getLabel')
->will($this->returnValue($label));

$menu->expects($this->any())
->method('getUri')
->will($this->returnValue($uri));

$menu->setExtra('isAllowed', $isAllowed);

$childrenCount = count($children);
$hasChildren = $childrenCount > 0;
$menu->expects($this->any())
->method('hasChildren')
->will($this->returnValue($hasChildren));

$menu->expects($this->any())
->method('hasChildren')
->will($this->returnValue($hasChildren));

$menu->expects($this->any())
->method('getIterator')
->will($this->returnValue(new \ArrayIterator($children)));

$menu->expects($this->any())
->method('count')
->will($this->returnValue($childrenCount));

$menu->expects($this->any())
->method('getChildren')
->will($this->returnValue($children));

return $menu;
}

protected function assertRender($menu, $menuInstance, $options, $renderer)
{
$this->helper->expects($this->once())
Expand Down
32 changes: 32 additions & 0 deletions src/Oro/Bundle/NavigationBundle/Twig/MenuExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public function render($menu, array $options = array(), $renderer = null)
$menu = $this->getMenu($menu, $path, $options);
}

$menu = $this->filterUnallowedItems($menu);
$menuType = $menu->getExtra('type');
// rewrite config options with args
if (!empty($menuType) && !empty($this->menuConfiguration['templates'][$menuType])) {
Expand All @@ -112,6 +113,37 @@ public function render($menu, array $options = array(), $renderer = null)
return $this->helper->render($menu, $options, $renderer);
}

/**
* Get menu filtered by isAllowed children.
*
* @param ItemInterface|array $menu
* @return ItemInterface|array
*/
protected function filterUnallowedItems($menu)
{
/** @var ItemInterface $item */
foreach ($menu as $item) {
if ($item->hasChildren()) {
$filteredChildren = $this->filterUnallowedItems($item);
$invisibleChildrenCount = 0;
/** @var ItemInterface $child */
foreach ($filteredChildren as $child) {
if (!$child->getLabel() || !$child->getExtra('isAllowed')) {
$invisibleChildrenCount++;
}
}

if (count($filteredChildren) == $invisibleChildrenCount
&& (!$item->getUri() || $item->getUri() == '#')
) {
$item->setExtra('isAllowed', false);
}
}
}

return $menu;
}

/**
* Render breadcrumbs for menu
*
Expand Down
2 changes: 1 addition & 1 deletion src/Oro/Bundle/SecurityBundle/SecurityFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public function getClassMethodAnnotation($class, $method)
* @param mixed $object A domain object, object identity or object identity descriptor (id:type)
* (entity:Acme/DemoBundle/Entity/AcmeEntity, action:some_action)
*
*@return bool
* @return bool
*/
public function isGranted($attributes, $object = null)
{
Expand Down

0 comments on commit e3129b2

Please sign in to comment.