df33102811fc690309b0bfb88a184651d0214218
[yaffs-website] / web / core / modules / system / tests / src / Functional / Entity / EntityReferenceSelection / EntityReferenceSelectionAccessTest.php
1 <?php
2
3 namespace Drupal\Tests\system\Functional\Entity\EntityReferenceSelection;
4
5 use Drupal\comment\Tests\CommentTestTrait;
6 use Drupal\Component\Utility\Html;
7 use Drupal\Core\Language\LanguageInterface;
8 use Drupal\comment\CommentInterface;
9 use Drupal\node\Entity\Node;
10 use Drupal\Tests\BrowserTestBase;
11 use Drupal\node\NodeInterface;
12 use Drupal\user\Entity\User;
13 use Drupal\comment\Entity\Comment;
14
15 /**
16  * Tests for the base handlers provided by Entity Reference.
17  *
18  * @group entity_reference
19  */
20 class EntityReferenceSelectionAccessTest extends BrowserTestBase {
21
22   use CommentTestTrait;
23
24   /**
25    * Modules to enable.
26    *
27    * @var array
28    */
29   public static $modules = ['node', 'comment'];
30
31   protected function setUp() {
32     parent::setUp();
33
34     // Create an Article node type.
35     $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
36   }
37
38   /**
39    * Checks that a selection plugin returns the expected results.
40    *
41    * @param array $selection_options
42    *   An array of options as required by entity reference selection plugins.
43    * @param array $tests
44    *   An array of tests to run.
45    * @param string $handler_name
46    *   The name of the entity type selection handler being tested.
47    */
48   protected function assertReferenceable(array $selection_options, $tests, $handler_name) {
49     $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($selection_options);
50
51     foreach ($tests as $test) {
52       foreach ($test['arguments'] as $arguments) {
53         $result = call_user_func_array([$handler, 'getReferenceableEntities'], $arguments);
54         $this->assertEqual($result, $test['result'], format_string('Valid result set returned by @handler.', ['@handler' => $handler_name]));
55
56         $result = call_user_func_array([$handler, 'countReferenceableEntities'], $arguments);
57         if (!empty($test['result'])) {
58           $bundle = key($test['result']);
59           $count = count($test['result'][$bundle]);
60         }
61         else {
62           $count = 0;
63         }
64
65         $this->assertEqual($result, $count, format_string('Valid count returned by @handler.', ['@handler' => $handler_name]));
66       }
67     }
68   }
69
70   /**
71    * Test the node-specific overrides of the entity handler.
72    */
73   public function testNodeHandler() {
74     $selection_options = [
75       'target_type' => 'node',
76       'handler' => 'default',
77       'handler_settings' => [
78         'target_bundles' => NULL,
79       ],
80     ];
81
82     // Build a set of test data.
83     // Titles contain HTML-special characters to test escaping.
84     $node_values = [
85       'published1' => [
86         'type' => 'article',
87         'status' => NodeInterface::PUBLISHED,
88         'title' => 'Node published1 (<&>)',
89         'uid' => 1,
90       ],
91       'published2' => [
92         'type' => 'article',
93         'status' => NodeInterface::PUBLISHED,
94         'title' => 'Node published2 (<&>)',
95         'uid' => 1,
96       ],
97       'unpublished' => [
98         'type' => 'article',
99         'status' => NodeInterface::NOT_PUBLISHED,
100         'title' => 'Node unpublished (<&>)',
101         'uid' => 1,
102       ],
103     ];
104
105     $nodes = [];
106     $node_labels = [];
107     foreach ($node_values as $key => $values) {
108       $node = Node::create($values);
109       $node->save();
110       $nodes[$key] = $node;
111       $node_labels[$key] = Html::escape($node->label());
112     }
113
114     // Test as a non-admin.
115     $normal_user = $this->drupalCreateUser(['access content']);
116     \Drupal::currentUser()->setAccount($normal_user);
117     $referenceable_tests = [
118       [
119         'arguments' => [
120           [NULL, 'CONTAINS'],
121         ],
122         'result' => [
123           'article' => [
124             $nodes['published1']->id() => $node_labels['published1'],
125             $nodes['published2']->id() => $node_labels['published2'],
126           ],
127         ],
128       ],
129       [
130         'arguments' => [
131           ['published1', 'CONTAINS'],
132           ['Published1', 'CONTAINS'],
133         ],
134         'result' => [
135           'article' => [
136             $nodes['published1']->id() => $node_labels['published1'],
137           ],
138         ],
139       ],
140       [
141         'arguments' => [
142           ['published2', 'CONTAINS'],
143           ['Published2', 'CONTAINS'],
144         ],
145         'result' => [
146           'article' => [
147             $nodes['published2']->id() => $node_labels['published2'],
148           ],
149         ],
150       ],
151       [
152         'arguments' => [
153           ['invalid node', 'CONTAINS'],
154         ],
155         'result' => [],
156       ],
157       [
158         'arguments' => [
159           ['Node unpublished', 'CONTAINS'],
160         ],
161         'result' => [],
162       ],
163     ];
164     $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler');
165
166     // Test as an admin.
167     $admin_user = $this->drupalCreateUser(['access content', 'bypass node access']);
168     \Drupal::currentUser()->setAccount($admin_user);
169     $referenceable_tests = [
170       [
171         'arguments' => [
172           [NULL, 'CONTAINS'],
173         ],
174         'result' => [
175           'article' => [
176             $nodes['published1']->id() => $node_labels['published1'],
177             $nodes['published2']->id() => $node_labels['published2'],
178             $nodes['unpublished']->id() => $node_labels['unpublished'],
179           ],
180         ],
181       ],
182       [
183         'arguments' => [
184           ['Node unpublished', 'CONTAINS'],
185         ],
186         'result' => [
187           'article' => [
188             $nodes['unpublished']->id() => $node_labels['unpublished'],
189           ],
190         ],
191       ],
192     ];
193     $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler (admin)');
194   }
195
196   /**
197    * Test the user-specific overrides of the entity handler.
198    */
199   public function testUserHandler() {
200     $selection_options = [
201       'target_type' => 'user',
202       'handler' => 'default',
203       'handler_settings' => [
204         'target_bundles' => NULL,
205         'include_anonymous' => TRUE,
206       ],
207     ];
208
209     // Build a set of test data.
210     $user_values = [
211       'anonymous' => User::load(0),
212       'admin' => User::load(1),
213       'non_admin' => [
214         'name' => 'non_admin <&>',
215         'mail' => 'non_admin@example.com',
216         'roles' => [],
217         'pass' => user_password(),
218         'status' => 1,
219       ],
220       'blocked' => [
221         'name' => 'blocked <&>',
222         'mail' => 'blocked@example.com',
223         'roles' => [],
224         'pass' => user_password(),
225         'status' => 0,
226       ],
227     ];
228
229     $user_values['anonymous']->name = $this->config('user.settings')->get('anonymous');
230     $users = [];
231
232     $user_labels = [];
233     foreach ($user_values as $key => $values) {
234       if (is_array($values)) {
235         $account = User::create($values);
236         $account->save();
237       }
238       else {
239         $account = $values;
240       }
241       $users[$key] = $account;
242       $user_labels[$key] = Html::escape($account->getUsername());
243     }
244
245     // Test as a non-admin.
246     \Drupal::currentUser()->setAccount($users['non_admin']);
247     $referenceable_tests = [
248       [
249         'arguments' => [
250           [NULL, 'CONTAINS'],
251         ],
252         'result' => [
253           'user' => [
254             $users['admin']->id() => $user_labels['admin'],
255             $users['non_admin']->id() => $user_labels['non_admin'],
256           ],
257         ],
258       ],
259       [
260         'arguments' => [
261           ['non_admin', 'CONTAINS'],
262           ['NON_ADMIN', 'CONTAINS'],
263         ],
264         'result' => [
265           'user' => [
266             $users['non_admin']->id() => $user_labels['non_admin'],
267           ],
268         ],
269       ],
270       [
271         'arguments' => [
272           ['invalid user', 'CONTAINS'],
273         ],
274         'result' => [],
275       ],
276       [
277         'arguments' => [
278           ['blocked', 'CONTAINS'],
279         ],
280         'result' => [],
281       ],
282     ];
283     $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler');
284
285     \Drupal::currentUser()->setAccount($users['admin']);
286     $referenceable_tests = [
287       [
288         'arguments' => [
289           [NULL, 'CONTAINS'],
290         ],
291         'result' => [
292           'user' => [
293             $users['anonymous']->id() => $user_labels['anonymous'],
294             $users['admin']->id() => $user_labels['admin'],
295             $users['non_admin']->id() => $user_labels['non_admin'],
296             $users['blocked']->id() => $user_labels['blocked'],
297           ],
298         ],
299       ],
300       [
301         'arguments' => [
302           ['blocked', 'CONTAINS'],
303         ],
304         'result' => [
305           'user' => [
306             $users['blocked']->id() => $user_labels['blocked'],
307           ],
308         ],
309       ],
310       [
311         'arguments' => [
312           ['Anonymous', 'CONTAINS'],
313           ['anonymous', 'CONTAINS'],
314         ],
315         'result' => [
316           'user' => [
317             $users['anonymous']->id() => $user_labels['anonymous'],
318           ],
319         ],
320       ],
321     ];
322     $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (admin)');
323
324     // Test the 'include_anonymous' option.
325     $selection_options['handler_settings']['include_anonymous'] = FALSE;
326     $referenceable_tests = [
327       [
328         'arguments' => [
329           ['Anonymous', 'CONTAINS'],
330           ['anonymous', 'CONTAINS'],
331         ],
332         'result' => [],
333       ],
334     ];
335     $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)');
336
337     // Check that the Anonymous user is not included in the results when no
338     // label matching is done, for example when using the 'options_select'
339     // widget.
340     $referenceable_tests = [
341       [
342         'arguments' => [
343           [NULL],
344         ],
345         'result' => [
346           'user' => [
347             $users['admin']->id() => $user_labels['admin'],
348             $users['non_admin']->id() => $user_labels['non_admin'],
349             $users['blocked']->id() => $user_labels['blocked'],
350           ],
351         ],
352       ],
353     ];
354     $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)');
355   }
356
357   /**
358    * Test the comment-specific overrides of the entity handler.
359    */
360   public function testCommentHandler() {
361     $selection_options = [
362       'target_type' => 'comment',
363       'handler' => 'default',
364       'handler_settings' => [
365         'target_bundles' => NULL,
366       ],
367     ];
368
369     // Build a set of test data.
370     $node_values = [
371       'published' => [
372         'type' => 'article',
373         'status' => 1,
374         'title' => 'Node published',
375         'uid' => 1,
376       ],
377       'unpublished' => [
378         'type' => 'article',
379         'status' => 0,
380         'title' => 'Node unpublished',
381         'uid' => 1,
382       ],
383     ];
384     $nodes = [];
385     foreach ($node_values as $key => $values) {
386       $node = Node::create($values);
387       $node->save();
388       $nodes[$key] = $node;
389     }
390
391     // Create comment field on article.
392     $this->addDefaultCommentField('node', 'article');
393
394     $comment_values = [
395       'published_published' => [
396         'entity_id' => $nodes['published']->id(),
397         'entity_type' => 'node',
398         'field_name' => 'comment',
399         'uid' => 1,
400         'cid' => NULL,
401         'pid' => 0,
402         'status' => CommentInterface::PUBLISHED,
403         'subject' => 'Comment Published <&>',
404         'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
405       ],
406       'published_unpublished' => [
407         'entity_id' => $nodes['published']->id(),
408         'entity_type' => 'node',
409         'field_name' => 'comment',
410         'uid' => 1,
411         'cid' => NULL,
412         'pid' => 0,
413         'status' => CommentInterface::NOT_PUBLISHED,
414         'subject' => 'Comment Unpublished <&>',
415         'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
416       ],
417       'unpublished_published' => [
418         'entity_id' => $nodes['unpublished']->id(),
419         'entity_type' => 'node',
420         'field_name' => 'comment',
421         'uid' => 1,
422         'cid' => NULL,
423         'pid' => 0,
424         'status' => CommentInterface::NOT_PUBLISHED,
425         'subject' => 'Comment Published on Unpublished node <&>',
426         'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
427       ],
428     ];
429
430     $comments = [];
431     $comment_labels = [];
432     foreach ($comment_values as $key => $values) {
433       $comment = Comment::create($values);
434       $comment->save();
435       $comments[$key] = $comment;
436       $comment_labels[$key] = Html::escape($comment->label());
437     }
438
439     // Test as a non-admin.
440     $normal_user = $this->drupalCreateUser(['access content', 'access comments']);
441     \Drupal::currentUser()->setAccount($normal_user);
442     $referenceable_tests = [
443       [
444         'arguments' => [
445           [NULL, 'CONTAINS'],
446         ],
447         'result' => [
448           'comment' => [
449             $comments['published_published']->cid->value => $comment_labels['published_published'],
450           ],
451         ],
452       ],
453       [
454         'arguments' => [
455           ['Published', 'CONTAINS'],
456         ],
457         'result' => [
458           'comment' => [
459             $comments['published_published']->cid->value => $comment_labels['published_published'],
460           ],
461         ],
462       ],
463       [
464         'arguments' => [
465           ['invalid comment', 'CONTAINS'],
466         ],
467         'result' => [],
468       ],
469       [
470         'arguments' => [
471           ['Comment Unpublished', 'CONTAINS'],
472         ],
473         'result' => [],
474       ],
475     ];
476     $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler');
477
478     // Test as a comment admin.
479     $admin_user = $this->drupalCreateUser(['access content', 'access comments', 'administer comments']);
480     \Drupal::currentUser()->setAccount($admin_user);
481     $referenceable_tests = [
482       [
483         'arguments' => [
484           [NULL, 'CONTAINS'],
485         ],
486         'result' => [
487           'comment' => [
488             $comments['published_published']->cid->value => $comment_labels['published_published'],
489             $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'],
490           ],
491         ],
492       ],
493     ];
494     $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment admin)');
495
496     // Test as a node and comment admin.
497     $admin_user = $this->drupalCreateUser(['access content', 'access comments', 'administer comments', 'bypass node access']);
498     \Drupal::currentUser()->setAccount($admin_user);
499     $referenceable_tests = [
500       [
501         'arguments' => [
502           [NULL, 'CONTAINS'],
503         ],
504         'result' => [
505           'comment' => [
506             $comments['published_published']->cid->value => $comment_labels['published_published'],
507             $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'],
508             $comments['unpublished_published']->cid->value => $comment_labels['unpublished_published'],
509           ],
510         ],
511       ],
512     ];
513     $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment + node admin)');
514   }
515
516 }