3 namespace Drupal\Tests\node\Functional;
5 use Drupal\Tests\Traits\Core\GeneratePermutationsTrait;
8 * Tests user permissions for node revisions.
12 class NodeRevisionPermissionsTest extends NodeTestBase {
14 use GeneratePermutationsTrait;
21 protected $nodeRevisions = [];
28 protected $accounts = [];
30 // Map revision permission names to node revision access ops.
32 'view' => 'view all revisions',
33 'update' => 'revert all revisions',
34 'delete' => 'delete all revisions',
37 // Map revision permission names to node type revision access ops.
38 protected $typeMap = [
39 'view' => 'view page revisions',
40 'update' => 'revert page revisions',
41 'delete' => 'delete page revisions',
44 protected function setUp() {
47 $types = ['page', 'article'];
49 foreach ($types as $type) {
50 // Create a node with several revisions.
51 $nodes[$type] = $this->drupalCreateNode(['type' => $type]);
52 $this->nodeRevisions[$type][] = $nodes[$type];
54 for ($i = 0; $i < 3; $i++) {
55 // Create a revision for the same nid and settings with a random log.
56 $revision = clone $nodes[$type];
57 $revision->setNewRevision();
58 $revision->revision_log = $this->randomMachineName(32);
60 $this->nodeRevisions[$type][] = $revision;
66 * Tests general revision access permissions.
68 public function testNodeRevisionAccessAnyType() {
69 // Create three users, one with each revision permission.
70 foreach ($this->map as $op => $permission) {
72 $account = $this->drupalCreateUser(
75 'edit any page content',
76 'delete any page content',
81 $this->accounts[] = $account;
84 // Create an admin account (returns TRUE for all revision permissions).
85 $admin_account = $this->drupalCreateUser(['access content', 'administer nodes']);
86 $admin_account->is_admin = TRUE;
87 $this->accounts['admin'] = $admin_account;
88 $accounts['admin'] = $admin_account;
90 // Create a normal account (returns FALSE for all revision permissions).
91 $normal_account = $this->drupalCreateUser();
92 $normal_account->op = FALSE;
93 $this->accounts[] = $normal_account;
94 $accounts[] = $normal_account;
95 $revision = $this->nodeRevisions['page'][1];
98 'op' => array_keys($this->map),
99 'account' => $this->accounts,
102 $permutations = $this->generatePermutations($parameters);
104 $node_revision_access = \Drupal::service('access_check.node.revision');
105 foreach ($permutations as $case) {
106 // Skip this test if there are no revisions for the node.
107 if (!($revision->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid', [':nid' => $revision->id()])->fetchField() == 1 || $case['op'] == 'update' || $case['op'] == 'delete'))) {
108 if (!empty($case['account']->is_admin) || $case['account']->hasPermission($this->map[$case['op']])) {
109 $this->assertTrue($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->map[$case['op']]} granted.");
112 $this->assertFalse($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->map[$case['op']]} not granted.");
117 // Test that access is FALSE for a node administrator with an invalid $node
118 // or $op parameters.
119 $admin_account = $accounts['admin'];
120 $this->assertFalse($node_revision_access->checkAccess($revision, $admin_account, 'invalid-op'), 'NodeRevisionAccessCheck() returns FALSE with an invalid op.');
124 * Tests revision access permissions for a specific content type.
126 public function testNodeRevisionAccessPerType() {
127 // Create three users, one with each revision permission.
128 foreach ($this->typeMap as $op => $permission) {
130 $account = $this->drupalCreateUser(
133 'edit any page content',
134 'delete any page content',
139 $accounts[] = $account;
143 'op' => array_keys($this->typeMap),
144 'account' => $accounts,
147 // Test that the accounts have access to the corresponding page revision
149 $revision = $this->nodeRevisions['page'][1];
151 $permutations = $this->generatePermutations($parameters);
152 $node_revision_access = \Drupal::service('access_check.node.revision');
153 foreach ($permutations as $case) {
154 // Skip this test if there are no revisions for the node.
155 if (!($revision->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_field_revision} WHERE nid = :nid', [':nid' => $revision->id()])->fetchField() == 1 || $case['op'] == 'update' || $case['op'] == 'delete'))) {
156 if (!empty($case['account']->is_admin) || $case['account']->hasPermission($this->typeMap[$case['op']], $case['account'])) {
157 $this->assertTrue($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} granted.");
160 $this->assertFalse($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} not granted.");
165 // Test that the accounts have no access to the article revisions.
166 $revision = $this->nodeRevisions['article'][1];
168 foreach ($permutations as $case) {
169 $this->assertFalse($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} did not grant revision permission for articles.");