function DefaultMenuLinkTreeManipulatorsTest::testCheckAccess

Same name in other branches
  1. 8.9.x core/tests/Drupal/Tests/Core/Menu/DefaultMenuLinkTreeManipulatorsTest.php \Drupal\Tests\Core\Menu\DefaultMenuLinkTreeManipulatorsTest::testCheckAccess()
  2. 10 core/tests/Drupal/Tests/Core/Menu/DefaultMenuLinkTreeManipulatorsTest.php \Drupal\Tests\Core\Menu\DefaultMenuLinkTreeManipulatorsTest::testCheckAccess()
  3. 11.x core/tests/Drupal/Tests/Core/Menu/DefaultMenuLinkTreeManipulatorsTest.php \Drupal\Tests\Core\Menu\DefaultMenuLinkTreeManipulatorsTest::testCheckAccess()

Tests the checkAccess() tree manipulator.

@covers ::checkAccess @covers ::menuLinkCheckAccess

File

core/tests/Drupal/Tests/Core/Menu/DefaultMenuLinkTreeManipulatorsTest.php, line 165

Class

DefaultMenuLinkTreeManipulatorsTest
Tests the default menu link tree manipulators.

Namespace

Drupal\Tests\Core\Menu

Code

public function testCheckAccess() {
    // Those menu links that are non-external will have their access checks
    // performed. 9 routes, but 1 is external, 2 already have their 'access'
    // property set, and 1 is a child if an inaccessible menu link, so only 5
    // calls will be made.
    $this->cacheContextManager
        ->assertValidTokens([
        'user.permissions',
    ])
        ->shouldBeCalled()
        ->willReturn(TRUE);
    $this->accessManager
        ->expects($this->exactly(5))
        ->method('checkNamedRoute')
        ->willReturnMap([
        [
            'example1',
            [],
            $this->currentUser,
            TRUE,
            AccessResult::forbidden(),
        ],
        [
            'example2',
            [
                'foo' => 'bar',
            ],
            $this->currentUser,
            TRUE,
            AccessResult::allowed()->cachePerPermissions(),
        ],
        [
            'example3',
            [
                'baz' => 'qux',
            ],
            $this->currentUser,
            TRUE,
            AccessResult::neutral(),
        ],
        [
            'example5',
            [],
            $this->currentUser,
            TRUE,
            AccessResult::allowed(),
        ],
        [
            'user.logout',
            [],
            $this->currentUser,
            TRUE,
            AccessResult::allowed(),
        ],
    ]);
    $this->mockTree();
    $this->originalTree[5]->subtree[7]->access = AccessResult::neutral();
    $this->cacheContextManager
        ->assertValidTokens([
        'user',
    ])
        ->shouldBeCalled()
        ->willReturn(TRUE);
    $this->originalTree[8]->access = AccessResult::allowed()->cachePerUser();
    // Since \Drupal\Core\Menu\DefaultMenuLinkTreeManipulators::checkAccess()
    // allows access to any link if the user has the 'link to any page'
    // permission, *every* single access result is varied by permissions.
    $tree = $this->defaultMenuTreeManipulators
        ->checkAccess($this->originalTree);
    // Menu link 1: route without parameters, access forbidden, but at level 0,
    // hence kept.
    $element = $tree[1];
    $this->assertEquals(AccessResult::forbidden()->cachePerPermissions(), $element->access);
    $this->assertInstanceOf('\\Drupal\\Core\\Menu\\InaccessibleMenuLink', $element->link);
    // Menu link 2: route with parameters, access granted.
    $element = $tree[2];
    $this->assertEquals(AccessResult::allowed()->cachePerPermissions(), $element->access);
    $this->assertNotInstanceOf('\\Drupal\\Core\\Menu\\InaccessibleMenuLink', $element->link);
    // Menu link 3: route with parameters, AccessResult::neutral(), top-level
    // inaccessible link, hence kept for its cacheability metadata.
    // Note that the permissions cache context is added automatically, because
    // we always check the "link to any page" permission.
    $element = $tree[2]->subtree[3];
    $this->assertEquals(AccessResult::neutral()->cachePerPermissions(), $element->access);
    $this->assertInstanceOf('\\Drupal\\Core\\Menu\\InaccessibleMenuLink', $element->link);
    // Menu link 4: child of menu link 3, which was AccessResult::neutral(),
    // hence menu link 3's subtree is removed, of which this menu link is one.
    $this->assertArrayNotHasKey(4, $tree[2]->subtree[3]->subtree);
    // Menu link 5: no route name, treated as external, hence access granted.
    $element = $tree[5];
    $this->assertEquals(AccessResult::allowed()->cachePerPermissions(), $element->access);
    $this->assertNotInstanceOf('\\Drupal\\Core\\Menu\\InaccessibleMenuLink', $element->link);
    // Menu link 6: external URL, hence access granted.
    $element = $tree[6];
    $this->assertEquals(AccessResult::allowed()->cachePerPermissions(), $element->access);
    $this->assertNotInstanceOf('\\Drupal\\Core\\Menu\\InaccessibleMenuLink', $element->link);
    // Menu link 7: 'access' already set: AccessResult::neutral(), top-level
    // inaccessible link, hence kept for its cacheability metadata.
    // Note that unlike for menu link 3, the permission cache context is absent,
    // because ::checkAccess() doesn't perform access checking when 'access' is
    // already set.
    $element = $tree[5]->subtree[7];
    $this->assertEquals(AccessResult::neutral(), $element->access);
    $this->assertInstanceOf('\\Drupal\\Core\\Menu\\InaccessibleMenuLink', $element->link);
    // Menu link 8: 'access' already set, note that 'per permissions' caching
    // is not added.
    $element = $tree[8];
    $this->assertEquals(AccessResult::allowed()->cachePerUser(), $element->access);
    $this->assertNotInstanceOf('\\Drupal\\Core\\Menu\\InaccessibleMenuLink', $element->link);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.