class NodeOperationAccessTest

Same name in other branches
  1. 10 core/modules/node/tests/src/Unit/NodeOperationAccessTest.php \Drupal\Tests\node\Unit\NodeOperationAccessTest
  2. 11.x core/modules/node/tests/src/Unit/NodeOperationAccessTest.php \Drupal\Tests\node\Unit\NodeOperationAccessTest

Tests node operations.

@coversDefaultClass \Drupal\node\NodeAccessControlHandler @group node

Hierarchy

Expanded class hierarchy of NodeOperationAccessTest

File

core/modules/node/tests/src/Unit/NodeOperationAccessTest.php, line 27

Namespace

Drupal\Tests\node\Unit
View source
class NodeOperationAccessTest extends UnitTestCase {
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        parent::setUp();
        // Cache utility calls container directly.
        $cacheContextsManager = $this->getMockBuilder(CacheContextsManager::class)
            ->disableOriginalConstructor()
            ->getMock();
        $cacheContextsManager->method('assertValidTokens')
            ->willReturn(TRUE);
        $container = new ContainerBuilder();
        $container->set('cache_contexts_manager', $cacheContextsManager);
        \Drupal::setContainer($container);
    }
    
    /**
     * Tests revision operations.
     *
     * @param string $operation
     *   A revision operation.
     * @param array $hasPermissionMap
     *   A map of permissions, to whether they should be granted.
     * @param bool|null $assertAccess
     *   Whether the access is allowed or denied.
     * @param bool|null $isDefaultRevision
     *   Whether the node should be default revision, or NULL if not to expect it
     *   to be called.
     *
     * @dataProvider providerTestRevisionOperations
     */
    public function testRevisionOperations($operation, array $hasPermissionMap, $assertAccess, $isDefaultRevision = NULL) {
        $account = $this->createMock(AccountInterface::class);
        $account->method('hasPermission')
            ->willReturnMap($hasPermissionMap);
        $entityType = $this->createMock(EntityTypeInterface::class);
        $grants = $this->createMock(NodeGrantDatabaseStorageInterface::class);
        $grants->expects($this->any())
            ->method('access')
            ->willReturn(AccessResult::neutral());
        $language = $this->createMock(LanguageInterface::class);
        $language->expects($this->any())
            ->method('getId')
            ->willReturn('de');
        $nid = 333;
        
        /** @var \Drupal\node\NodeInterface|\PHPUnit\Framework\MockObject\MockObject $node */
        $node = $this->createMock(NodeInterface::class);
        $node->expects($this->any())
            ->method('language')
            ->willReturn($language);
        $node->expects($this->any())
            ->method('id')
            ->willReturn($nid);
        $node->expects($this->any())
            ->method('getCacheContexts')
            ->willReturn([]);
        $node->expects($this->any())
            ->method('getCacheTags')
            ->willReturn([]);
        $node->expects($this->any())
            ->method('getCacheMaxAge')
            ->willReturn(-1);
        $node->expects($this->any())
            ->method('getEntityTypeId')
            ->willReturn('node');
        if (isset($isDefaultRevision)) {
            $node->expects($this->atLeastOnce())
                ->method('isDefaultRevision')
                ->willReturn($isDefaultRevision);
        }
        $nodeStorage = $this->createMock(NodeStorageInterface::class);
        $nodeStorage->expects($this->any())
            ->method('load')
            ->with($nid)
            ->willReturn($node);
        $entityTypeManager = $this->createMock(EntityTypeManagerInterface::class);
        $entityTypeManager->expects($this->any())
            ->method('getStorage')
            ->with('node')
            ->willReturn($nodeStorage);
        $moduleHandler = $this->createMock(ModuleHandlerInterface::class);
        $moduleHandler->expects($this->any())
            ->method('invokeAll')
            ->willReturn([]);
        $accessControl = new NodeAccessControlHandler($entityType, $grants, $entityTypeManager);
        $accessControl->setModuleHandler($moduleHandler);
        $nodeType = $this->createMock(RevisionableEntityBundleInterface::class);
        $typeProperty = new \stdClass();
        $typeProperty->entity = $nodeType;
        $node->type = $typeProperty;
        $access = $accessControl->access($node, $operation, $account, FALSE);
        $this->assertEquals($assertAccess, $access);
    }
    
    /**
     * Data provider for revisionOperationsProvider.
     *
     * @return array
     *   Data for testing.
     */
    public function providerTestRevisionOperations() {
        $data = [];
        // Tests 'bypass node access' never works on revision operations.
        $data['bypass, view all revisions'] = [
            'view all revisions',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'bypass node access',
                    TRUE,
                ],
            ],
            FALSE,
        ];
        $data['bypass, view revision'] = [
            'view revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'bypass node access',
                    TRUE,
                ],
            ],
            FALSE,
        ];
        $data['bypass, revert'] = [
            'revert revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'bypass node access',
                    TRUE,
                ],
            ],
            FALSE,
        ];
        $data['bypass, delete revision'] = [
            'delete revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'bypass node access',
                    TRUE,
                ],
            ],
            FALSE,
        ];
        $data['view all revisions'] = [
            'view all revisions',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'view all revisions',
                    TRUE,
                ],
            ],
            TRUE,
        ];
        $data['view all revisions with view access'] = [
            'view all revisions',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'view all revisions',
                    TRUE,
                ],
                // Bypass for 'view' operation.
[
                    'bypass node access',
                    TRUE,
                ],
            ],
            TRUE,
        ];
        $data['view revision, without view access'] = [
            'view revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'view all revisions',
                    TRUE,
                ],
            ],
            FALSE,
        ];
        $data['view revision, with view access'] = [
            'view revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'view all revisions',
                    TRUE,
                ],
                // Bypass for 'view' operation.
[
                    'bypass node access',
                    TRUE,
                ],
            ],
            TRUE,
        ];
        // Cannot revert if no update access.
        $data['revert, without update access, non default'] = [
            'revert revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'revert all revisions',
                    TRUE,
                ],
            ],
            FALSE,
            FALSE,
        ];
        // Can revert if has update access.
        $data['revert, with update access, non default'] = [
            'revert revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'revert all revisions',
                    TRUE,
                ],
                // Bypass for 'update' operation.
[
                    'bypass node access',
                    TRUE,
                ],
            ],
            TRUE,
            FALSE,
        ];
        // Can never revert default revision.
        $data['revert, with update access, default revision'] = [
            'revert revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'revert all revisions',
                    TRUE,
                ],
                // Bypass for 'update' operation.
[
                    'bypass node access',
                    TRUE,
                ],
            ],
            FALSE,
            TRUE,
        ];
        // Cannot delete non default revision if no delete access.
        $data['delete revision, without delete access, non default'] = [
            'delete revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'delete all revisions',
                    TRUE,
                ],
            ],
            FALSE,
            FALSE,
        ];
        // Can delete non default revision if delete access.
        $data['delete revision, with delete access, non default'] = [
            'delete revision',
            [
                [
                    'access content',
                    TRUE,
                ],
                [
                    'delete all revisions',
                    TRUE,
                ],
                // Bypass for 'delete' operation.
[
                    'bypass node access',
                    TRUE,
                ],
            ],
            TRUE,
            FALSE,
        ];
        return $data;
    }
    
    /**
     * Tests NodeAccessControlHandler deprecation.
     *
     * @group legacy
     */
    public function testNodeAccessControlHandlerDeprecation() {
        $entity_type = $this->prophesize(EntityTypeInterface::class);
        $entity_type->id()
            ->willReturn(mt_rand(1, 128));
        $node_grant_storage = $this->prophesize(NodeGrantDatabaseStorageInterface::class);
        $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
        $container = $this->prophesize(ContainerInterface::class);
        $container->get('entity_type.manager')
            ->willReturn($entity_type_manager->reveal());
        \Drupal::setContainer($container->reveal());
        $this->expectDeprecation('Calling Drupal\\node\\NodeAccessControlHandler::__construct() without the $entity_type_manager argument is deprecated in drupal:9.3.0 and will be required in drupal:10.0.0. See https://www.drupal.org/node/3214171');
        new NodeAccessControlHandler($entity_type->reveal(), $node_grant_storage->reveal());
    }

}

Members

Title Sort descending Deprecated Modifiers Object type Summary Overriden Title Overrides
NodeOperationAccessTest::providerTestRevisionOperations public function Data provider for revisionOperationsProvider.
NodeOperationAccessTest::setUp protected function Overrides UnitTestCase::setUp
NodeOperationAccessTest::testNodeAccessControlHandlerDeprecation public function Tests NodeAccessControlHandler deprecation.
NodeOperationAccessTest::testRevisionOperations public function Tests revision operations.
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.
UnitTestCase::$randomGenerator protected property The random generator.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::assertArrayEquals Deprecated protected function Asserts if two arrays are equal by sorting them first.
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getRandomGenerator protected function Gets the random generator for the utility methods.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::randomMachineName public function Generates a unique random string containing letters and numbers.
UnitTestCase::setUpBeforeClass public static function

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