annotate core/modules/node/tests/src/Kernel/NodeAccessTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\node\Kernel;
Chris@0 4
Chris@0 5 use Drupal\Component\Render\FormattableMarkup;
Chris@0 6 use Drupal\Core\Session\AccountInterface;
Chris@0 7 use Drupal\KernelTests\KernelTestBase;
Chris@0 8 use Drupal\node\NodeInterface;
Chris@18 9 use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
Chris@18 10 use Drupal\Tests\node\Traits\NodeCreationTrait;
Chris@18 11 use Drupal\Tests\user\Traits\UserCreationTrait;
Chris@0 12 use Drupal\user\RoleInterface;
Chris@0 13
Chris@0 14 /**
Chris@0 15 * Tests basic node_access functionality.
Chris@0 16 *
Chris@0 17 * @group node
Chris@0 18 */
Chris@0 19 class NodeAccessTest extends KernelTestBase {
Chris@0 20
Chris@0 21 use NodeCreationTrait {
Chris@0 22 getNodeByTitle as drupalGetNodeByTitle;
Chris@0 23 createNode as drupalCreateNode;
Chris@0 24 }
Chris@0 25 use UserCreationTrait {
Chris@0 26 createUser as drupalCreateUser;
Chris@0 27 createRole as drupalCreateRole;
Chris@0 28 createAdminRole as drupalCreateAdminRole;
Chris@0 29 }
Chris@0 30 use ContentTypeCreationTrait {
Chris@0 31 createContentType as drupalCreateContentType;
Chris@0 32 }
Chris@0 33
Chris@0 34 /**
Chris@0 35 * {@inheritdoc}
Chris@0 36 */
Chris@0 37 public static $modules = [
Chris@0 38 'node',
Chris@0 39 'datetime',
Chris@0 40 'user',
Chris@0 41 'system',
Chris@0 42 'filter',
Chris@0 43 'field',
Chris@0 44 'text',
Chris@0 45 ];
Chris@0 46
Chris@0 47 /**
Chris@0 48 * Access handler.
Chris@0 49 *
Chris@0 50 * @var \Drupal\Core\Entity\EntityAccessControlHandlerInterface
Chris@0 51 */
Chris@0 52 protected $accessHandler;
Chris@0 53
Chris@0 54 /**
Chris@0 55 * {@inheritdoc}
Chris@0 56 */
Chris@0 57 protected function setUp() {
Chris@0 58 parent::setUp();
Chris@0 59 $this->installSchema('system', 'sequences');
Chris@0 60 $this->installSchema('node', 'node_access');
Chris@0 61 $this->installEntitySchema('user');
Chris@0 62 $this->installEntitySchema('node');
Chris@0 63 $this->installConfig('filter');
Chris@0 64 $this->installConfig('node');
Chris@0 65 $this->accessHandler = $this->container->get('entity_type.manager')
Chris@0 66 ->getAccessControlHandler('node');
Chris@0 67 // Clear permissions for authenticated users.
Chris@0 68 $this->config('user.role.' . RoleInterface::AUTHENTICATED_ID)
Chris@0 69 ->set('permissions', [])
Chris@0 70 ->save();
Chris@0 71
Chris@0 72 // Create user 1 who has special permissions.
Chris@0 73 $this->drupalCreateUser();
Chris@0 74
Chris@0 75 // Create a node type.
Chris@0 76 $this->drupalCreateContentType([
Chris@0 77 'type' => 'page',
Chris@0 78 'name' => 'Basic page',
Chris@0 79 'display_submitted' => FALSE,
Chris@0 80 ]);
Chris@0 81 }
Chris@0 82
Chris@0 83 /**
Chris@0 84 * Runs basic tests for node_access function.
Chris@0 85 */
Chris@0 86 public function testNodeAccess() {
Chris@0 87 // Ensures user without 'access content' permission can do nothing.
Chris@0 88 $web_user1 = $this->drupalCreateUser([
Chris@0 89 'create page content',
Chris@0 90 'edit any page content',
Chris@0 91 'delete any page content',
Chris@0 92 ]);
Chris@0 93 $node1 = $this->drupalCreateNode(['type' => 'page']);
Chris@0 94 $this->assertNodeCreateAccess($node1->bundle(), FALSE, $web_user1);
Chris@0 95 $this->assertNodeAccess([
Chris@0 96 'view' => FALSE,
Chris@0 97 'update' => FALSE,
Chris@0 98 'delete' => FALSE,
Chris@0 99 ], $node1, $web_user1);
Chris@0 100
Chris@0 101 // Ensures user with 'bypass node access' permission can do everything.
Chris@0 102 $web_user2 = $this->drupalCreateUser(['bypass node access']);
Chris@0 103 $node2 = $this->drupalCreateNode(['type' => 'page']);
Chris@0 104 $this->assertNodeCreateAccess($node2->bundle(), TRUE, $web_user2);
Chris@0 105 $this->assertNodeAccess([
Chris@0 106 'view' => TRUE,
Chris@0 107 'update' => TRUE,
Chris@0 108 'delete' => TRUE,
Chris@0 109 ], $node2, $web_user2);
Chris@0 110
Chris@0 111 // User cannot 'view own unpublished content'.
Chris@0 112 $web_user3 = $this->drupalCreateUser(['access content']);
Chris@0 113 $node3 = $this->drupalCreateNode([
Chris@0 114 'status' => 0,
Chris@0 115 'uid' => $web_user3->id(),
Chris@0 116 ]);
Chris@0 117 $this->assertNodeAccess(['view' => FALSE], $node3, $web_user3);
Chris@0 118
Chris@0 119 // User cannot create content without permission.
Chris@0 120 $this->assertNodeCreateAccess($node3->bundle(), FALSE, $web_user3);
Chris@0 121
Chris@0 122 // User can 'view own unpublished content', but another user cannot.
Chris@0 123 $web_user4 = $this->drupalCreateUser([
Chris@0 124 'access content',
Chris@0 125 'view own unpublished content',
Chris@0 126 ]);
Chris@0 127 $web_user5 = $this->drupalCreateUser([
Chris@0 128 'access content',
Chris@0 129 'view own unpublished content',
Chris@0 130 ]);
Chris@0 131 $node4 = $this->drupalCreateNode([
Chris@0 132 'status' => 0,
Chris@0 133 'uid' => $web_user4->id(),
Chris@0 134 ]);
Chris@0 135 $this->assertNodeAccess([
Chris@0 136 'view' => TRUE,
Chris@0 137 'update' => FALSE,
Chris@0 138 ], $node4, $web_user4);
Chris@0 139 $this->assertNodeAccess(['view' => FALSE], $node4, $web_user5);
Chris@0 140
Chris@0 141 // Tests the default access provided for a published node.
Chris@0 142 $node5 = $this->drupalCreateNode();
Chris@0 143 $this->assertNodeAccess([
Chris@0 144 'view' => TRUE,
Chris@0 145 'update' => FALSE,
Chris@0 146 'delete' => FALSE,
Chris@0 147 ], $node5, $web_user3);
Chris@0 148
Chris@0 149 // Tests the "edit any BUNDLE" and "delete any BUNDLE" permissions.
Chris@0 150 $web_user6 = $this->drupalCreateUser([
Chris@0 151 'access content',
Chris@0 152 'edit any page content',
Chris@0 153 'delete any page content',
Chris@0 154 ]);
Chris@0 155 $node6 = $this->drupalCreateNode(['type' => 'page']);
Chris@0 156 $this->assertNodeAccess([
Chris@0 157 'view' => TRUE,
Chris@0 158 'update' => TRUE,
Chris@0 159 'delete' => TRUE,
Chris@0 160 ], $node6, $web_user6);
Chris@0 161
Chris@0 162 // Tests the "edit own BUNDLE" and "delete own BUNDLE" permission.
Chris@0 163 $web_user7 = $this->drupalCreateUser([
Chris@0 164 'access content',
Chris@0 165 'edit own page content',
Chris@0 166 'delete own page content',
Chris@0 167 ]);
Chris@0 168 // User should not be able to edit or delete nodes they do not own.
Chris@0 169 $this->assertNodeAccess([
Chris@0 170 'view' => TRUE,
Chris@0 171 'update' => FALSE,
Chris@0 172 'delete' => FALSE,
Chris@0 173 ], $node6, $web_user7);
Chris@0 174
Chris@0 175 // User should be able to edit or delete nodes they own.
Chris@0 176 $node7 = $this->drupalCreateNode([
Chris@0 177 'type' => 'page',
Chris@0 178 'uid' => $web_user7->id(),
Chris@0 179 ]);
Chris@0 180 $this->assertNodeAccess([
Chris@0 181 'view' => TRUE,
Chris@0 182 'update' => TRUE,
Chris@0 183 'delete' => TRUE,
Chris@0 184 ], $node7, $web_user7);
Chris@0 185 }
Chris@0 186
Chris@0 187 /**
Chris@0 188 * Test operations not supported by node grants.
Chris@0 189 */
Chris@0 190 public function testUnsupportedOperation() {
Chris@0 191 $this->enableModules(['node_access_test_empty']);
Chris@0 192 $web_user = $this->drupalCreateUser(['access content']);
Chris@0 193 $node = $this->drupalCreateNode();
Chris@0 194 $this->assertNodeAccess(['random_operation' => FALSE], $node, $web_user);
Chris@0 195 }
Chris@0 196
Chris@0 197 /**
Chris@0 198 * Asserts that node access correctly grants or denies access.
Chris@0 199 *
Chris@0 200 * @param array $ops
Chris@0 201 * An associative array of the expected node access grants for the node
Chris@0 202 * and account, with each key as the name of an operation (e.g. 'view',
Chris@0 203 * 'delete') and each value a Boolean indicating whether access to that
Chris@0 204 * operation should be granted.
Chris@0 205 * @param \Drupal\node\NodeInterface $node
Chris@0 206 * The node object to check.
Chris@0 207 * @param \Drupal\Core\Session\AccountInterface $account
Chris@0 208 * The user account for which to check access.
Chris@0 209 */
Chris@0 210 public function assertNodeAccess(array $ops, NodeInterface $node, AccountInterface $account) {
Chris@0 211 foreach ($ops as $op => $result) {
Chris@0 212 $this->assertEquals($result, $this->accessHandler->access($node, $op, $account), $this->nodeAccessAssertMessage($op, $result, $node->language()
Chris@0 213 ->getId()));
Chris@0 214 }
Chris@0 215 }
Chris@0 216
Chris@0 217 /**
Chris@0 218 * Asserts that node create access correctly grants or denies access.
Chris@0 219 *
Chris@0 220 * @param string $bundle
Chris@0 221 * The node bundle to check access to.
Chris@0 222 * @param bool $result
Chris@0 223 * Whether access should be granted or not.
Chris@0 224 * @param \Drupal\Core\Session\AccountInterface $account
Chris@0 225 * The user account for which to check access.
Chris@0 226 * @param string|null $langcode
Chris@0 227 * (optional) The language code indicating which translation of the node
Chris@0 228 * to check. If NULL, the untranslated (fallback) access is checked.
Chris@0 229 */
Chris@0 230 public function assertNodeCreateAccess($bundle, $result, AccountInterface $account, $langcode = NULL) {
Chris@0 231 $this->assertEquals($result, $this->accessHandler->createAccess($bundle, $account, [
Chris@0 232 'langcode' => $langcode,
Chris@0 233 ]), $this->nodeAccessAssertMessage('create', $result, $langcode));
Chris@0 234 }
Chris@0 235
Chris@0 236 /**
Chris@0 237 * Constructs an assert message to display which node access was tested.
Chris@0 238 *
Chris@0 239 * @param string $operation
Chris@0 240 * The operation to check access for.
Chris@0 241 * @param bool $result
Chris@0 242 * Whether access should be granted or not.
Chris@0 243 * @param string|null $langcode
Chris@0 244 * (optional) The language code indicating which translation of the node
Chris@0 245 * to check. If NULL, the untranslated (fallback) access is checked.
Chris@0 246 *
Chris@0 247 * @return string
Chris@0 248 * An assert message string which contains information in plain English
Chris@0 249 * about the node access permission test that was performed.
Chris@0 250 */
Chris@0 251 public function nodeAccessAssertMessage($operation, $result, $langcode = NULL) {
Chris@0 252 return new FormattableMarkup(
Chris@0 253 'Node access returns @result with operation %op, language code %langcode.',
Chris@0 254 [
Chris@0 255 '@result' => $result ? 'true' : 'false',
Chris@0 256 '%op' => $operation,
Chris@0 257 '%langcode' => !empty($langcode) ? $langcode : 'empty',
Chris@0 258 ]
Chris@0 259 );
Chris@0 260 }
Chris@0 261
Chris@0 262 }