function DefaultMenuLinkTreeManipulatorsTest::testCheckNodeAccess

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

Tests the optimized node access checking.

@covers ::checkNodeAccess @covers ::collectNodeLinks @covers ::checkAccess

File

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

Class

DefaultMenuLinkTreeManipulatorsTest
Tests the default menu link tree manipulators.

Namespace

Drupal\Tests\Core\Menu

Code

public function testCheckNodeAccess() : void {
    $links = [
        1 => MenuLinkMock::create([
            'id' => 'node.1',
            'route_name' => 'entity.node.canonical',
            'title' => 'foo',
            'parent' => '',
            'route_parameters' => [
                'node' => 1,
            ],
        ]),
        2 => MenuLinkMock::create([
            'id' => 'node.2',
            'route_name' => 'entity.node.canonical',
            'title' => 'bar',
            'parent' => '',
            'route_parameters' => [
                'node' => 2,
            ],
        ]),
        3 => MenuLinkMock::create([
            'id' => 'node.3',
            'route_name' => 'entity.node.canonical',
            'title' => 'baz',
            'parent' => 'node.2',
            'route_parameters' => [
                'node' => 3,
            ],
        ]),
        4 => MenuLinkMock::create([
            'id' => 'node.4',
            'route_name' => 'entity.node.canonical',
            'title' => 'qux',
            'parent' => 'node.3',
            'route_parameters' => [
                'node' => 4,
            ],
        ]),
        5 => MenuLinkMock::create([
            'id' => 'test.1',
            'route_name' => 'test_route',
            'title' => 'qux',
            'parent' => '',
        ]),
        6 => MenuLinkMock::create([
            'id' => 'test.2',
            'route_name' => 'test_route',
            'title' => 'qux',
            'parent' => 'test.1',
        ]),
    ];
    $tree = [];
    $tree[1] = new MenuLinkTreeElement($links[1], FALSE, 1, FALSE, []);
    $tree[2] = new MenuLinkTreeElement($links[2], TRUE, 1, FALSE, [
        3 => new MenuLinkTreeElement($links[3], TRUE, 2, FALSE, [
            4 => new MenuLinkTreeElement($links[4], FALSE, 3, FALSE, []),
        ]),
    ]);
    $tree[5] = new MenuLinkTreeElement($links[5], TRUE, 1, FALSE, [
        6 => new MenuLinkTreeElement($links[6], FALSE, 2, FALSE, []),
    ]);
    $query = $this->prophesize('Drupal\\Core\\Entity\\Query\\QueryInterface');
    $query->accessCheck(TRUE)
        ->shouldBeCalled();
    $query->condition('nid', [
        1,
        2,
        3,
        4,
    ], 'IN')
        ->shouldBeCalled();
    $query->condition('status', NodeInterface::PUBLISHED)
        ->shouldBeCalled();
    $query->execute()
        ->willReturn([
        1,
        2,
        4,
    ]);
    $storage = $this->createMock(EntityStorageInterface::class);
    $storage->expects($this->once())
        ->method('getQuery')
        ->willReturn($query->reveal());
    $this->entityTypeManager
        ->expects($this->once())
        ->method('getStorage')
        ->with('node')
        ->willReturn($storage);
    $this->cacheContextManager
        ->assertValidTokens([
        'user.permissions',
    ])
        ->shouldBeCalled()
        ->willReturn(TRUE);
    $this->cacheContextManager
        ->assertValidTokens([
        'user.permissions',
        'user.node_grants:view',
    ])
        ->shouldBeCalled()
        ->willReturn(TRUE);
    $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->exactly(2))
        ->method('checkNamedRoute')
        ->with('test_route', [], $this->currentUser, TRUE)
        ->willReturnOnConsecutiveCalls(AccessResult::allowed(), 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(), $tree[5]->access);
    $this->assertEquals(AccessResult::neutral(), $tree[5]->subtree[6]->access);
}

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