/**
  * Tests the checkAccess() tree manipulator.
  *
  * @covers ::checkAccess
  */
 public function testCheckAccess()
 {
     // Those menu links that are non-external will have their access checks
     // performed. 8 routes, but 1 is external, 2 already have their 'access'
     // property set, and 1 is a child if an inaccessible menu link, so only 4
     // calls will be made.
     $this->accessManager->expects($this->exactly(4))->method('checkNamedRoute')->will($this->returnValueMap(array(array('example1', array(), $this->currentUser, NULL, FALSE), array('example2', array('foo' => 'bar'), $this->currentUser, NULL, TRUE), array('example3', array('baz' => 'qux'), $this->currentUser, NULL, FALSE), array('example5', array(), $this->currentUser, NULL, TRUE))));
     $this->mockTree();
     $this->originalTree[5]->subtree[7]->access = TRUE;
     $this->originalTree[8]->access = FALSE;
     $tree = $this->defaultMenuTreeManipulators->checkAccess($this->originalTree);
     // Menu link 1: route without parameters, access forbidden, hence removed.
     $this->assertFalse(array_key_exists(1, $tree));
     // Menu link 2: route with parameters, access granted.
     $element = $tree[2];
     $this->assertTrue($element->access);
     // Menu link 3: route with parameters, access forbidden, hence removed,
     // including its children.
     $this->assertFalse(array_key_exists(3, $tree[2]->subtree));
     // Menu link 4: child of menu link 3, which already is removed.
     $this->assertSame(array(), $tree[2]->subtree);
     // Menu link 5: no route name, treated as external, hence access granted.
     $element = $tree[5];
     $this->assertTrue($element->access);
     // Menu link 6: external URL, hence access granted.
     $element = $tree[6];
     $this->assertTrue($element->access);
     // Menu link 7: 'access' already set.
     $element = $tree[5]->subtree[7];
     $this->assertTrue($element->access);
     // Menu link 8: 'access' already set, to FALSE, hence removed.
     $this->assertFalse(array_key_exists(8, $tree));
 }
 /**
  * Tests the optimized node access checking.
  *
  * @covers ::checkNodeAccess
  * @covers ::collectNodeLinks
  * @covers ::checkAccess
  */
 public function testCheckNodeAccess()
 {
     $links = array(1 => MenuLinkMock::create(array('id' => 'node.1', 'route_name' => 'entity.node.canonical', 'title' => 'foo', 'parent' => '', 'route_parameters' => array('node' => 1))), 2 => MenuLinkMock::create(array('id' => 'node.2', 'route_name' => 'entity.node.canonical', 'title' => 'bar', 'parent' => '', 'route_parameters' => array('node' => 2))), 3 => MenuLinkMock::create(array('id' => 'node.3', 'route_name' => 'entity.node.canonical', 'title' => 'baz', 'parent' => 'node.2', 'route_parameters' => array('node' => 3))), 4 => MenuLinkMock::create(array('id' => 'node.4', 'route_name' => 'entity.node.canonical', 'title' => 'qux', 'parent' => 'node.3', 'route_parameters' => array('node' => 4))), 5 => MenuLinkMock::create(array('id' => 'test.1', 'route_name' => 'test_route', 'title' => 'qux', 'parent' => '')), 6 => MenuLinkMock::create(array('id' => 'test.2', 'route_name' => 'test_route', 'title' => 'qux', 'parent' => 'test.1')));
     $tree = array();
     $tree[1] = new MenuLinkTreeElement($links[1], FALSE, 1, FALSE, array());
     $tree[2] = new MenuLinkTreeElement($links[2], TRUE, 1, FALSE, array(3 => new MenuLinkTreeElement($links[3], TRUE, 2, FALSE, array(4 => new MenuLinkTreeElement($links[4], FALSE, 3, FALSE, array())))));
     $tree[5] = new MenuLinkTreeElement($links[5], TRUE, 1, FALSE, array(6 => new MenuLinkTreeElement($links[6], FALSE, 2, FALSE, array())));
     $query = $this->getMock('Drupal\\Core\\Entity\\Query\\QueryInterface');
     $query->expects($this->at(0))->method('condition')->with('nid', array(1, 2, 3, 4));
     $query->expects($this->at(1))->method('condition')->with('status', NODE_PUBLISHED);
     $query->expects($this->once())->method('execute')->willReturn(array(1, 2, 4));
     $this->queryFactory->expects($this->once())->method('get')->with('node')->willReturn($query);
     $node_access_result = AccessResult::allowed()->cachePerPermissions()->addCacheContexts(['user.node_grants:view']);
     $tree = $this->defaultMenuTreeManipulators->checkNodeAccess($tree);
     $this->assertEquals($node_access_result, $tree[1]->access);
     $this->assertEquals($node_access_result, $tree[2]->access);
     // Ensure that access denied is set.
     $this->assertEquals(AccessResult::neutral(), $tree[2]->subtree[3]->access);
     $this->assertEquals($node_access_result, $tree[2]->subtree[3]->subtree[4]->access);
     // Ensure that other routes than entity.node.canonical are set as well.
     $this->assertNull($tree[5]->access);
     $this->assertNull($tree[5]->subtree[6]->access);
     // On top of the node access checking now run the ordinary route based
     // access checkers.
     // Ensure that the access manager is just called for the non-node routes.
     $this->accessManager->expects($this->at(0))->method('checkNamedRoute')->with('test_route', [], $this->currentUser, TRUE)->willReturn(AccessResult::allowed());
     $this->accessManager->expects($this->at(1))->method('checkNamedRoute')->with('test_route', [], $this->currentUser, TRUE)->willReturn(AccessResult::neutral());
     $tree = $this->defaultMenuTreeManipulators->checkAccess($tree);
     $this->assertEquals($node_access_result, $tree[1]->access);
     $this->assertEquals($node_access_result, $tree[2]->access);
     $this->assertEquals(AccessResult::neutral(), $tree[2]->subtree[3]->access);
     $this->assertEquals(AccessResult::allowed()->cachePerPermissions(), $tree[5]->access);
     $this->assertEquals(AccessResult::neutral()->cachePerPermissions(), $tree[5]->subtree[6]->access);
 }