NodeQueryAlterTest.php

Same filename and directory in other branches
  1. 10 core/modules/node/tests/src/Functional/NodeQueryAlterTest.php
  2. 9 core/modules/node/tests/src/Functional/NodeQueryAlterTest.php
  3. 8.9.x core/modules/node/tests/src/Functional/NodeQueryAlterTest.php

Namespace

Drupal\Tests\node\Functional

File

core/modules/node/tests/src/Functional/NodeQueryAlterTest.php

View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\node\Functional;

use Drupal\Core\Database\Database;
use Drupal\user\Entity\User;
use PHPUnit\Framework\Attributes\Group;

/**
 * Tests that node access queries are properly altered by the node module.
 */
class NodeQueryAlterTest extends NodeTestBase {
  
  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'node_access_test',
  ];
  
  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';
  
  /**
   * User with permission to view content.
   *
   * @var \Drupal\user\Entity\User|false
   */
  protected $accessUser;
  
  /**
   * User without permission to view content.
   *
   * @var \Drupal\user\Entity\User|false
   */
  protected $noAccessUser;
  
  /**
   * User without permission to view content.
   *
   * @var \Drupal\user\Entity\User
   */
  protected User $noAccessUser2;
  
  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    node_access_rebuild();
    // Create some content.
    $this->drupalCreateNode();
    $this->drupalCreateNode();
    $this->drupalCreateNode();
    $this->drupalCreateNode();
    // Create user with simple node access permission. The 'node test view'
    // permission is implemented and granted by the node_access_test module.
    $this->accessUser = $this->drupalCreateUser([
      'access content overview',
      'access content',
      'node test view',
    ]);
    $this->noAccessUser = $this->drupalCreateUser([
      'access content overview',
      'access content',
    ]);
    $this->noAccessUser2 = $this->drupalCreateUser([
      'access content overview',
      'access content',
    ]);
  }
  
  /**
   * Tests 'node_access' query alter, for user with access.
   *
   * Verifies that a non-standard table alias can be used, and that a user with
   * node access can view the nodes.
   */
  public function testNodeQueryAlterLowLevelWithAccess() : void {
    // User with access should be able to view 4 nodes.
    try {
      $query = Database::getConnection()->select('node', 'n')
        ->fields('n');
      $query->addTag('node_access');
      $query->addMetaData('op', 'view');
      $query->addMetaData('account', $this->accessUser);
      $result = $query->execute()
        ->fetchAll();
      $this->assertCount(4, $result, 'User with access can see correct nodes');
    } catch (\Exception) {
      $this->fail('Altered query is malformed');
    }
  }
  
  /**
   * Tests 'node_access' query alter with revision-enabled nodes.
   */
  public function testNodeQueryAlterWithRevisions() : void {
    // Execute a query that only deals with the 'node_revision' table.
    try {
      $query = \Drupal::entityTypeManager()->getStorage('node')
        ->getQuery();
      $result = $query->accessCheck(TRUE)
        ->allRevisions()
        ->execute();
      $this->assertCount(4, $result, 'User with access can see correct nodes');
    } catch (\Exception) {
      $this->fail('Altered query is malformed');
    }
  }
  
  /**
   * Tests 'node_access' query alter, for user without access.
   *
   * Verifies that a non-standard table alias can be used, and that a user
   * without node access cannot view the nodes.
   */
  public function testNodeQueryAlterLowLevelNoAccess() : void {
    // User without access should be able to view 0 nodes.
    try {
      $query = Database::getConnection()->select('node', 'n')
        ->fields('n');
      $query->addTag('node_access');
      $query->addMetaData('op', 'view');
      $query->addMetaData('account', $this->noAccessUser);
      $result = $query->execute()
        ->fetchAll();
      $this->assertCount(0, $result, 'User with no access cannot see nodes');
    } catch (\Exception) {
      $this->fail('Altered query is malformed');
    }
  }
  
  /**
   * Tests 'node_access' query alter, for edit access.
   *
   * Verifies that a non-standard table alias can be used, and that a user with
   * view-only node access cannot edit the nodes.
   */
  public function testNodeQueryAlterLowLevelEditAccess() : void {
    // User with view-only access should not be able to edit nodes.
    try {
      $query = Database::getConnection()->select('node', 'n')
        ->fields('n');
      $query->addTag('node_access');
      $query->addMetaData('op', 'update');
      $query->addMetaData('account', $this->accessUser);
      $result = $query->execute()
        ->fetchAll();
      $this->assertCount(0, $result, 'User with view-only access cannot edit nodes');
    } catch (\Exception $e) {
      $this->fail($e->getMessage());
      $this->fail((string) $query);
      $this->fail('Altered query is malformed');
    }
  }
  
  /**
   * Tests 'node_access' query alter override.
   *
   * Checks that \Drupal\node\NodeGrantDatabaseStorage::checkAllGrants() is
   * called from node_query_node_access_alter(). We do this by checking that a
   * user who normally would not have view privileges is able to view the nodes
   * when we add a record to {node_access} paired with a corresponding privilege
   * in hook_node_grants().
   */
  public function testNodeQueryAlterOverride() : void {
    $record = [
      'nid' => 0,
      'gid' => 0,
      'realm' => 'node_access_all',
      'grant_view' => 1,
      'grant_update' => 0,
      'grant_delete' => 0,
    ];
    $connection = Database::getConnection();
    $connection->insert('node_access')
      ->fields($record)
      ->execute();
    // Test that the noAccessUser still doesn't have the 'view'
    // privilege after adding the node_access record.
    \Drupal::service('node.view_all_nodes_memory_cache')->deleteAll();
    $query = $connection->select('node', 'n')
      ->fields('n');
    $query->addTag('node_access');
    $query->addMetaData('op', 'view');
    $query->addMetaData('account', $this->noAccessUser);
    $result = $query->execute()
      ->fetchAll();
    $this->assertCount(0, $result, 'User view privileges are not overridden');
    // Have node_test_node_grants return a node_access_all privilege,
    // to grant the noAccessUser 'view' access.  To verify that
    // \Drupal\node\NodeGrantDatabaseStorage::checkAllGrants() is
    // properly checking the specified $account instead of the current user, we
    // will log in as noAccessUser2.
    $this->drupalLogin($this->noAccessUser2);
    \Drupal::state()->set('node_access_test.no_access_uid', $this->noAccessUser
      ->id());
    \Drupal::service('node.view_all_nodes_memory_cache')->deleteAll();
    $query = $connection->select('node', 'n')
      ->fields('n');
    $query->addTag('node_access');
    $query->addMetaData('op', 'view');
    $query->addMetaData('account', $this->noAccessUser);
    $result = $query->execute()
      ->fetchAll();
    $this->assertCount(4, $result, 'User view privileges are overridden');
    \Drupal::state()->delete('node_access_test.no_access_uid');
  }

}

Classes

Title Deprecated Summary
NodeQueryAlterTest Tests that node access queries are properly altered by the node module.

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