annotate core/modules/node/tests/src/Functional/NodeRevisionPermissionsTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\node\Functional;
Chris@0 4
Chris@0 5 use Drupal\Tests\Traits\Core\GeneratePermutationsTrait;
Chris@0 6
Chris@0 7 /**
Chris@0 8 * Tests user permissions for node revisions.
Chris@0 9 *
Chris@0 10 * @group node
Chris@0 11 */
Chris@0 12 class NodeRevisionPermissionsTest extends NodeTestBase {
Chris@0 13
Chris@0 14 use GeneratePermutationsTrait;
Chris@0 15
Chris@0 16 /**
Chris@0 17 * The node revisions.
Chris@0 18 *
Chris@0 19 * @var array
Chris@0 20 */
Chris@0 21 protected $nodeRevisions = [];
Chris@0 22
Chris@0 23 /**
Chris@0 24 * The accounts.
Chris@0 25 *
Chris@0 26 * @var array
Chris@0 27 */
Chris@0 28 protected $accounts = [];
Chris@0 29
Chris@0 30 // Map revision permission names to node revision access ops.
Chris@0 31 protected $map = [
Chris@0 32 'view' => 'view all revisions',
Chris@0 33 'update' => 'revert all revisions',
Chris@0 34 'delete' => 'delete all revisions',
Chris@0 35 ];
Chris@0 36
Chris@0 37 // Map revision permission names to node type revision access ops.
Chris@0 38 protected $typeMap = [
Chris@0 39 'view' => 'view page revisions',
Chris@0 40 'update' => 'revert page revisions',
Chris@0 41 'delete' => 'delete page revisions',
Chris@0 42 ];
Chris@0 43
Chris@0 44 protected function setUp() {
Chris@0 45 parent::setUp();
Chris@0 46
Chris@0 47 $types = ['page', 'article'];
Chris@0 48
Chris@0 49 foreach ($types as $type) {
Chris@0 50 // Create a node with several revisions.
Chris@0 51 $nodes[$type] = $this->drupalCreateNode(['type' => $type]);
Chris@0 52 $this->nodeRevisions[$type][] = $nodes[$type];
Chris@0 53
Chris@0 54 for ($i = 0; $i < 3; $i++) {
Chris@0 55 // Create a revision for the same nid and settings with a random log.
Chris@0 56 $revision = clone $nodes[$type];
Chris@0 57 $revision->setNewRevision();
Chris@0 58 $revision->revision_log = $this->randomMachineName(32);
Chris@0 59 $revision->save();
Chris@0 60 $this->nodeRevisions[$type][] = $revision;
Chris@0 61 }
Chris@0 62 }
Chris@0 63 }
Chris@0 64
Chris@0 65 /**
Chris@0 66 * Tests general revision access permissions.
Chris@0 67 */
Chris@0 68 public function testNodeRevisionAccessAnyType() {
Chris@0 69 // Create three users, one with each revision permission.
Chris@0 70 foreach ($this->map as $op => $permission) {
Chris@0 71 // Create the user.
Chris@0 72 $account = $this->drupalCreateUser(
Chris@0 73 [
Chris@0 74 'access content',
Chris@0 75 'edit any page content',
Chris@0 76 'delete any page content',
Chris@0 77 $permission,
Chris@0 78 ]
Chris@0 79 );
Chris@0 80 $account->op = $op;
Chris@0 81 $this->accounts[] = $account;
Chris@0 82 }
Chris@0 83
Chris@0 84 // Create an admin account (returns TRUE for all revision permissions).
Chris@0 85 $admin_account = $this->drupalCreateUser(['access content', 'administer nodes']);
Chris@0 86 $admin_account->is_admin = TRUE;
Chris@0 87 $this->accounts['admin'] = $admin_account;
Chris@0 88 $accounts['admin'] = $admin_account;
Chris@0 89
Chris@0 90 // Create a normal account (returns FALSE for all revision permissions).
Chris@0 91 $normal_account = $this->drupalCreateUser();
Chris@0 92 $normal_account->op = FALSE;
Chris@0 93 $this->accounts[] = $normal_account;
Chris@0 94 $accounts[] = $normal_account;
Chris@0 95 $revision = $this->nodeRevisions['page'][1];
Chris@0 96
Chris@0 97 $parameters = [
Chris@0 98 'op' => array_keys($this->map),
Chris@0 99 'account' => $this->accounts,
Chris@0 100 ];
Chris@0 101
Chris@0 102 $permutations = $this->generatePermutations($parameters);
Chris@0 103
Chris@0 104 $node_revision_access = \Drupal::service('access_check.node.revision');
Chris@0 105 foreach ($permutations as $case) {
Chris@0 106 // Skip this test if there are no revisions for the node.
Chris@0 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'))) {
Chris@0 108 if (!empty($case['account']->is_admin) || $case['account']->hasPermission($this->map[$case['op']])) {
Chris@0 109 $this->assertTrue($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->map[$case['op']]} granted.");
Chris@0 110 }
Chris@0 111 else {
Chris@0 112 $this->assertFalse($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->map[$case['op']]} not granted.");
Chris@0 113 }
Chris@0 114 }
Chris@0 115 }
Chris@0 116
Chris@0 117 // Test that access is FALSE for a node administrator with an invalid $node
Chris@0 118 // or $op parameters.
Chris@0 119 $admin_account = $accounts['admin'];
Chris@0 120 $this->assertFalse($node_revision_access->checkAccess($revision, $admin_account, 'invalid-op'), 'NodeRevisionAccessCheck() returns FALSE with an invalid op.');
Chris@0 121 }
Chris@0 122
Chris@0 123 /**
Chris@0 124 * Tests revision access permissions for a specific content type.
Chris@0 125 */
Chris@0 126 public function testNodeRevisionAccessPerType() {
Chris@0 127 // Create three users, one with each revision permission.
Chris@0 128 foreach ($this->typeMap as $op => $permission) {
Chris@0 129 // Create the user.
Chris@0 130 $account = $this->drupalCreateUser(
Chris@0 131 [
Chris@0 132 'access content',
Chris@0 133 'edit any page content',
Chris@0 134 'delete any page content',
Chris@0 135 $permission,
Chris@0 136 ]
Chris@0 137 );
Chris@0 138 $account->op = $op;
Chris@0 139 $accounts[] = $account;
Chris@0 140 }
Chris@0 141
Chris@0 142 $parameters = [
Chris@0 143 'op' => array_keys($this->typeMap),
Chris@0 144 'account' => $accounts,
Chris@0 145 ];
Chris@0 146
Chris@0 147 // Test that the accounts have access to the corresponding page revision
Chris@0 148 // permissions.
Chris@0 149 $revision = $this->nodeRevisions['page'][1];
Chris@0 150
Chris@0 151 $permutations = $this->generatePermutations($parameters);
Chris@0 152 $node_revision_access = \Drupal::service('access_check.node.revision');
Chris@0 153 foreach ($permutations as $case) {
Chris@0 154 // Skip this test if there are no revisions for the node.
Chris@0 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'))) {
Chris@17 156 if (!empty($case['account']->is_admin) || $case['account']->hasPermission($this->typeMap[$case['op']])) {
Chris@0 157 $this->assertTrue($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} granted.");
Chris@0 158 }
Chris@0 159 else {
Chris@0 160 $this->assertFalse($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} not granted.");
Chris@0 161 }
Chris@0 162 }
Chris@0 163 }
Chris@0 164
Chris@0 165 // Test that the accounts have no access to the article revisions.
Chris@0 166 $revision = $this->nodeRevisions['article'][1];
Chris@0 167
Chris@0 168 foreach ($permutations as $case) {
Chris@0 169 $this->assertFalse($node_revision_access->checkAccess($revision, $case['account'], $case['op']), "{$this->typeMap[$case['op']]} did not grant revision permission for articles.");
Chris@0 170 }
Chris@0 171 }
Chris@0 172
Chris@0 173 }