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