Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[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\KernelTests\KernelTestBase;
10 use Drupal\media\Entity\Media;
11 use Drupal\node\Entity\Node;
12 use Drupal\taxonomy\Entity\Term;
13 use Drupal\taxonomy\Entity\Vocabulary;
14 use Drupal\node\NodeInterface;
15 use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
16 use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
17 use Drupal\Tests\user\Traits\UserCreationTrait;
18 use Drupal\user\Entity\User;
19 use Drupal\comment\Entity\Comment;
20
21 /**
22  * Tests for the base handlers provided by Entity Reference.
23  *
24  * @group entity_reference
25  */
26 class EntityReferenceSelectionAccessTest extends KernelTestBase {
27
28   use CommentTestTrait;
29   use ContentTypeCreationTrait;
30   use MediaTypeCreationTrait;
31   use UserCreationTrait;
32
33   /**
34    * Modules to enable.
35    *
36    * @var array
37    */
38   public static $modules = ['comment', 'field', 'file', 'image', 'node', 'media', 'system', 'taxonomy', 'text', 'user'];
39
40   /**
41    * {@inheritdoc}
42    */
43   protected function setUp() {
44     parent::setUp();
45
46     $this->installSchema('system', 'sequences');
47     $this->installSchema('comment', ['comment_entity_statistics']);
48     $this->installSchema('file', ['file_usage']);
49
50     $this->installEntitySchema('comment');
51     $this->installEntitySchema('file');
52     $this->installEntitySchema('media');
53     $this->installEntitySchema('node');
54     $this->installEntitySchema('taxonomy_term');
55     $this->installEntitySchema('user');
56
57     $this->installConfig(['comment', 'field', 'media', 'node', 'taxonomy', 'user']);
58
59     // Create the anonymous and the admin users.
60     $anonymous_user = User::create([
61       'uid' => 0,
62       'name' => '',
63     ]);
64     $anonymous_user->save();
65     $admin_user = User::create([
66       'uid' => 1,
67       'name' => 'admin',
68       'status' => 1,
69     ]);
70     $admin_user->save();
71   }
72
73   /**
74    * Checks that a selection plugin returns the expected results.
75    *
76    * @param array $selection_options
77    *   An array of options as required by entity reference selection plugins.
78    * @param array $tests
79    *   An array of tests to run.
80    * @param string $handler_name
81    *   The name of the entity type selection handler being tested.
82    */
83   protected function assertReferenceable(array $selection_options, $tests, $handler_name) {
84     $handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($selection_options);
85
86     foreach ($tests as $test) {
87       foreach ($test['arguments'] as $arguments) {
88         $result = call_user_func_array([$handler, 'getReferenceableEntities'], $arguments);
89         $this->assertEqual($result, $test['result'], format_string('Valid result set returned by @handler.', ['@handler' => $handler_name]));
90
91         $result = call_user_func_array([$handler, 'countReferenceableEntities'], $arguments);
92         if (!empty($test['result'])) {
93           $bundle = key($test['result']);
94           $count = count($test['result'][$bundle]);
95         }
96         else {
97           $count = 0;
98         }
99
100         $this->assertEqual($result, $count, format_string('Valid count returned by @handler.', ['@handler' => $handler_name]));
101       }
102     }
103   }
104
105   /**
106    * Test the node-specific overrides of the entity handler.
107    */
108   public function testNodeHandler() {
109     $selection_options = [
110       'target_type' => 'node',
111       'handler' => 'default',
112       'target_bundles' => NULL,
113     ];
114
115     // Build a set of test data.
116     // Titles contain HTML-special characters to test escaping.
117     $node_values = [
118       'published1' => [
119         'type' => 'article',
120         'status' => NodeInterface::PUBLISHED,
121         'title' => 'Node published1 (<&>)',
122         'uid' => 1,
123       ],
124       'published2' => [
125         'type' => 'article',
126         'status' => NodeInterface::PUBLISHED,
127         'title' => 'Node published2 (<&>)',
128         'uid' => 1,
129       ],
130       'unpublished' => [
131         'type' => 'article',
132         'status' => NodeInterface::NOT_PUBLISHED,
133         'title' => 'Node unpublished (<&>)',
134         'uid' => 1,
135       ],
136     ];
137
138     $nodes = [];
139     $node_labels = [];
140     foreach ($node_values as $key => $values) {
141       $node = Node::create($values);
142       $node->save();
143       $nodes[$key] = $node;
144       $node_labels[$key] = Html::escape($node->label());
145     }
146
147     // Test as a non-admin.
148     $normal_user = $this->createUser(['access content']);
149     $this->setCurrentUser($normal_user);
150     $referenceable_tests = [
151       [
152         'arguments' => [
153           [NULL, 'CONTAINS'],
154         ],
155         'result' => [
156           'article' => [
157             $nodes['published1']->id() => $node_labels['published1'],
158             $nodes['published2']->id() => $node_labels['published2'],
159           ],
160         ],
161       ],
162       [
163         'arguments' => [
164           ['published1', 'CONTAINS'],
165           ['Published1', 'CONTAINS'],
166         ],
167         'result' => [
168           'article' => [
169             $nodes['published1']->id() => $node_labels['published1'],
170           ],
171         ],
172       ],
173       [
174         'arguments' => [
175           ['published2', 'CONTAINS'],
176           ['Published2', 'CONTAINS'],
177         ],
178         'result' => [
179           'article' => [
180             $nodes['published2']->id() => $node_labels['published2'],
181           ],
182         ],
183       ],
184       [
185         'arguments' => [
186           ['invalid node', 'CONTAINS'],
187         ],
188         'result' => [],
189       ],
190       [
191         'arguments' => [
192           ['Node unpublished', 'CONTAINS'],
193         ],
194         'result' => [],
195       ],
196     ];
197     $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler');
198
199     // Test as an admin.
200     $content_admin = $this->createUser(['access content', 'bypass node access']);
201     $this->setCurrentUser($content_admin);
202     $referenceable_tests = [
203       [
204         'arguments' => [
205           [NULL, 'CONTAINS'],
206         ],
207         'result' => [
208           'article' => [
209             $nodes['published1']->id() => $node_labels['published1'],
210             $nodes['published2']->id() => $node_labels['published2'],
211             $nodes['unpublished']->id() => $node_labels['unpublished'],
212           ],
213         ],
214       ],
215       [
216         'arguments' => [
217           ['Node unpublished', 'CONTAINS'],
218         ],
219         'result' => [
220           'article' => [
221             $nodes['unpublished']->id() => $node_labels['unpublished'],
222           ],
223         ],
224       ],
225     ];
226     $this->assertReferenceable($selection_options, $referenceable_tests, 'Node handler (admin)');
227   }
228
229   /**
230    * Test the user-specific overrides of the entity handler.
231    */
232   public function testUserHandler() {
233     $selection_options = [
234       'target_type' => 'user',
235       'handler' => 'default',
236       'target_bundles' => NULL,
237       'include_anonymous' => TRUE,
238     ];
239
240     // Build a set of test data.
241     $user_values = [
242       'anonymous' => User::load(0),
243       'admin' => User::load(1),
244       'non_admin' => [
245         'name' => 'non_admin <&>',
246         'mail' => 'non_admin@example.com',
247         'roles' => [],
248         'pass' => user_password(),
249         'status' => 1,
250       ],
251       'blocked' => [
252         'name' => 'blocked <&>',
253         'mail' => 'blocked@example.com',
254         'roles' => [],
255         'pass' => user_password(),
256         'status' => 0,
257       ],
258     ];
259
260     $user_values['anonymous']->name = $this->config('user.settings')->get('anonymous');
261     $users = [];
262
263     $user_labels = [];
264     foreach ($user_values as $key => $values) {
265       if (is_array($values)) {
266         $account = User::create($values);
267         $account->save();
268       }
269       else {
270         $account = $values;
271       }
272       $users[$key] = $account;
273       $user_labels[$key] = Html::escape($account->getUsername());
274     }
275
276     // Test as a non-admin.
277     $this->setCurrentUser($users['non_admin']);
278     $referenceable_tests = [
279       [
280         'arguments' => [
281           [NULL, 'CONTAINS'],
282         ],
283         'result' => [
284           'user' => [
285             $users['admin']->id() => $user_labels['admin'],
286             $users['non_admin']->id() => $user_labels['non_admin'],
287           ],
288         ],
289       ],
290       [
291         'arguments' => [
292           ['non_admin', 'CONTAINS'],
293           ['NON_ADMIN', 'CONTAINS'],
294         ],
295         'result' => [
296           'user' => [
297             $users['non_admin']->id() => $user_labels['non_admin'],
298           ],
299         ],
300       ],
301       [
302         'arguments' => [
303           ['invalid user', 'CONTAINS'],
304         ],
305         'result' => [],
306       ],
307       [
308         'arguments' => [
309           ['blocked', 'CONTAINS'],
310         ],
311         'result' => [],
312       ],
313     ];
314     $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler');
315
316     $this->setCurrentUser($users['admin']);
317     $referenceable_tests = [
318       [
319         'arguments' => [
320           [NULL, 'CONTAINS'],
321         ],
322         'result' => [
323           'user' => [
324             $users['anonymous']->id() => $user_labels['anonymous'],
325             $users['admin']->id() => $user_labels['admin'],
326             $users['non_admin']->id() => $user_labels['non_admin'],
327             $users['blocked']->id() => $user_labels['blocked'],
328           ],
329         ],
330       ],
331       [
332         'arguments' => [
333           ['blocked', 'CONTAINS'],
334         ],
335         'result' => [
336           'user' => [
337             $users['blocked']->id() => $user_labels['blocked'],
338           ],
339         ],
340       ],
341       [
342         'arguments' => [
343           ['Anonymous', 'CONTAINS'],
344           ['anonymous', 'CONTAINS'],
345         ],
346         'result' => [
347           'user' => [
348             $users['anonymous']->id() => $user_labels['anonymous'],
349           ],
350         ],
351       ],
352     ];
353     $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (admin)');
354
355     // Test the 'include_anonymous' option.
356     $selection_options['include_anonymous'] = FALSE;
357     $referenceable_tests = [
358       [
359         'arguments' => [
360           ['Anonymous', 'CONTAINS'],
361           ['anonymous', 'CONTAINS'],
362         ],
363         'result' => [],
364       ],
365     ];
366     $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)');
367
368     // Check that the Anonymous user is not included in the results when no
369     // label matching is done, for example when using the 'options_select'
370     // widget.
371     $referenceable_tests = [
372       [
373         'arguments' => [
374           [NULL],
375         ],
376         'result' => [
377           'user' => [
378             $users['admin']->id() => $user_labels['admin'],
379             $users['non_admin']->id() => $user_labels['non_admin'],
380             $users['blocked']->id() => $user_labels['blocked'],
381           ],
382         ],
383       ],
384     ];
385     $this->assertReferenceable($selection_options, $referenceable_tests, 'User handler (does not include anonymous)');
386   }
387
388   /**
389    * Test the comment-specific overrides of the entity handler.
390    */
391   public function testCommentHandler() {
392     $selection_options = [
393       'target_type' => 'comment',
394       'handler' => 'default',
395       'target_bundles' => NULL,
396     ];
397
398     // Build a set of test data.
399     $this->createContentType(['type' => 'article', 'name' => 'Article']);
400     $node_values = [
401       'published' => [
402         'type' => 'article',
403         'status' => 1,
404         'title' => 'Node published',
405         'uid' => 1,
406       ],
407       'unpublished' => [
408         'type' => 'article',
409         'status' => 0,
410         'title' => 'Node unpublished',
411         'uid' => 1,
412       ],
413     ];
414     $nodes = [];
415     foreach ($node_values as $key => $values) {
416       $node = Node::create($values);
417       $node->save();
418       $nodes[$key] = $node;
419     }
420
421     // Create comment field on article.
422     $this->addDefaultCommentField('node', 'article');
423
424     $comment_values = [
425       'published_published' => [
426         'entity_id' => $nodes['published']->id(),
427         'entity_type' => 'node',
428         'field_name' => 'comment',
429         'uid' => 1,
430         'cid' => NULL,
431         'pid' => 0,
432         'status' => CommentInterface::PUBLISHED,
433         'subject' => 'Comment Published <&>',
434         'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
435       ],
436       'published_unpublished' => [
437         'entity_id' => $nodes['published']->id(),
438         'entity_type' => 'node',
439         'field_name' => 'comment',
440         'uid' => 1,
441         'cid' => NULL,
442         'pid' => 0,
443         'status' => CommentInterface::NOT_PUBLISHED,
444         'subject' => 'Comment Unpublished <&>',
445         'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
446       ],
447       'unpublished_published' => [
448         'entity_id' => $nodes['unpublished']->id(),
449         'entity_type' => 'node',
450         'field_name' => 'comment',
451         'uid' => 1,
452         'cid' => NULL,
453         'pid' => 0,
454         'status' => CommentInterface::NOT_PUBLISHED,
455         'subject' => 'Comment Published on Unpublished node <&>',
456         'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
457       ],
458     ];
459
460     $comments = [];
461     $comment_labels = [];
462     foreach ($comment_values as $key => $values) {
463       $comment = Comment::create($values);
464       $comment->save();
465       $comments[$key] = $comment;
466       $comment_labels[$key] = Html::escape($comment->label());
467     }
468
469     // Test as a non-admin.
470     $normal_user = $this->createUser(['access content', 'access comments']);
471     $this->setCurrentUser($normal_user);
472     $referenceable_tests = [
473       [
474         'arguments' => [
475           [NULL, 'CONTAINS'],
476         ],
477         'result' => [
478           'comment' => [
479             $comments['published_published']->cid->value => $comment_labels['published_published'],
480           ],
481         ],
482       ],
483       [
484         'arguments' => [
485           ['Published', 'CONTAINS'],
486         ],
487         'result' => [
488           'comment' => [
489             $comments['published_published']->cid->value => $comment_labels['published_published'],
490           ],
491         ],
492       ],
493       [
494         'arguments' => [
495           ['invalid comment', 'CONTAINS'],
496         ],
497         'result' => [],
498       ],
499       [
500         'arguments' => [
501           ['Comment Unpublished', 'CONTAINS'],
502         ],
503         'result' => [],
504       ],
505     ];
506     $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler');
507
508     // Test as a comment admin.
509     $admin_user = $this->createUser(['access content', 'access comments', 'administer comments']);
510     $this->setCurrentUser($admin_user);
511     $referenceable_tests = [
512       [
513         'arguments' => [
514           [NULL, 'CONTAINS'],
515         ],
516         'result' => [
517           'comment' => [
518             $comments['published_published']->cid->value => $comment_labels['published_published'],
519             $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'],
520           ],
521         ],
522       ],
523     ];
524     $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment admin)');
525
526     // Test as a node and comment admin.
527     $admin_user = $this->createUser(['access content', 'access comments', 'administer comments', 'bypass node access']);
528     $this->setCurrentUser($admin_user);
529     $referenceable_tests = [
530       [
531         'arguments' => [
532           [NULL, 'CONTAINS'],
533         ],
534         'result' => [
535           'comment' => [
536             $comments['published_published']->cid->value => $comment_labels['published_published'],
537             $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'],
538             $comments['unpublished_published']->cid->value => $comment_labels['unpublished_published'],
539           ],
540         ],
541       ],
542     ];
543     $this->assertReferenceable($selection_options, $referenceable_tests, 'Comment handler (comment + node admin)');
544   }
545
546   /**
547    * Test the term-specific overrides of the selection handler.
548    */
549   public function testTermHandler() {
550     // Create a 'Tags' vocabulary.
551     Vocabulary::create([
552       'name' => 'Tags',
553       'description' => $this->randomMachineName(),
554       'vid' => 'tags',
555     ])->save();
556
557     $selection_options = [
558       'target_type' => 'taxonomy_term',
559       'handler' => 'default',
560       'target_bundles' => NULL,
561     ];
562
563     // Build a set of test data.
564     $term_values = [
565       'published1' => [
566         'vid' => 'tags',
567         'status' => 1,
568         'name' => 'Term published1',
569       ],
570       'published2' => [
571         'vid' => 'tags',
572         'status' => 1,
573         'name' => 'Term published2',
574       ],
575       'unpublished' => [
576         'vid' => 'tags',
577         'status' => 0,
578         'name' => 'Term unpublished',
579       ],
580       'published3' => [
581         'vid' => 'tags',
582         'status' => 1,
583         'name' => 'Term published3',
584         'parent' => 'unpublished',
585       ],
586       'published4' => [
587         'vid' => 'tags',
588         'status' => 1,
589         'name' => 'Term published4',
590         'parent' => 'published3',
591       ],
592     ];
593
594     $terms = [];
595     $term_labels = [];
596     foreach ($term_values as $key => $values) {
597       $term = Term::create($values);
598       if (isset($values['parent'])) {
599         $term->parent->entity = $terms[$values['parent']];
600       }
601       $term->save();
602       $terms[$key] = $term;
603       $term_labels[$key] = Html::escape($term->label());
604     }
605
606     // Test as a non-admin.
607     $normal_user = $this->createUser(['access content']);
608     $this->setCurrentUser($normal_user);
609     $referenceable_tests = [
610       [
611         'arguments' => [
612           [NULL, 'CONTAINS'],
613         ],
614         'result' => [
615           'tags' => [
616             $terms['published1']->id() => $term_labels['published1'],
617             $terms['published2']->id() => $term_labels['published2'],
618           ],
619         ],
620       ],
621       [
622         'arguments' => [
623           ['published1', 'CONTAINS'],
624           ['Published1', 'CONTAINS'],
625         ],
626         'result' => [
627           'tags' => [
628             $terms['published1']->id() => $term_labels['published1'],
629           ],
630         ],
631       ],
632       [
633         'arguments' => [
634           ['published2', 'CONTAINS'],
635           ['Published2', 'CONTAINS'],
636         ],
637         'result' => [
638           'tags' => [
639             $terms['published2']->id() => $term_labels['published2'],
640           ],
641         ],
642       ],
643       [
644         'arguments' => [
645           ['invalid term', 'CONTAINS'],
646         ],
647         'result' => [],
648       ],
649       [
650         'arguments' => [
651           ['Term unpublished', 'CONTAINS'],
652         ],
653         'result' => [],
654       ],
655     ];
656     $this->assertReferenceable($selection_options, $referenceable_tests, 'Term handler');
657
658     // Test as an admin.
659     $admin_user = $this->createUser(['access content', 'administer taxonomy']);
660     $this->setCurrentUser($admin_user);
661     $referenceable_tests = [
662       [
663         'arguments' => [
664           [NULL, 'CONTAINS'],
665         ],
666         'result' => [
667           'tags' => [
668             $terms['published1']->id() => $term_labels['published1'],
669             $terms['published2']->id() => $term_labels['published2'],
670             $terms['unpublished']->id() => $term_labels['unpublished'],
671             $terms['published3']->id() => '-' . $term_labels['published3'],
672             $terms['published4']->id() => '--' . $term_labels['published4'],
673           ],
674         ],
675       ],
676       [
677         'arguments' => [
678           ['Term unpublished', 'CONTAINS'],
679         ],
680         'result' => [
681           'tags' => [
682             $terms['unpublished']->id() => $term_labels['unpublished'],
683           ],
684         ],
685       ],
686     ];
687     $this->assertReferenceable($selection_options, $referenceable_tests, 'Term handler (admin)');
688   }
689
690   /**
691    * Tests the selection handler for the media entity type.
692    */
693   public function testMediaHandler() {
694     $selection_options = [
695       'target_type' => 'media',
696       'handler' => 'default',
697       'target_bundles' => NULL,
698     ];
699
700     // Build a set of test data.
701     $media_type = $this->createMediaType('file');
702     $media_values = [
703       'published' => [
704         'bundle' => $media_type->id(),
705         'status' => 1,
706         'name' => 'Media published',
707         'uid' => 1,
708       ],
709       'unpublished' => [
710         'bundle' => $media_type->id(),
711         'status' => 0,
712         'name' => 'Media unpublished',
713         'uid' => 1,
714       ],
715     ];
716
717     $media_entities = [];
718     $media_labels = [];
719     foreach ($media_values as $key => $values) {
720       $media = Media::create($values);
721       $media->save();
722       $media_entities[$key] = $media;
723       $media_labels[$key] = Html::escape($media->label());
724     }
725
726     // Test as a non-admin.
727     $normal_user = $this->createUser(['view media']);
728     $this->setCurrentUser($normal_user);
729     $referenceable_tests = [
730       [
731         'arguments' => [
732           [NULL, 'CONTAINS'],
733         ],
734         'result' => [
735           $media_type->id() => [
736             $media_entities['published']->id() => $media_labels['published'],
737           ],
738         ],
739       ],
740       [
741         'arguments' => [
742           ['Media unpublished', 'CONTAINS'],
743         ],
744         'result' => [],
745       ],
746     ];
747     $this->assertReferenceable($selection_options, $referenceable_tests, 'Media handler');
748
749     // Test as an admin.
750     $admin_user = $this->createUser(['view media', 'administer media']);
751     $this->setCurrentUser($admin_user);
752     $referenceable_tests = [
753       [
754         'arguments' => [
755           [NULL, 'CONTAINS'],
756         ],
757         'result' => [
758           $media_type->id() => [
759             $media_entities['published']->id() => $media_labels['published'],
760             $media_entities['unpublished']->id() => $media_labels['unpublished'],
761           ],
762         ],
763       ],
764       [
765         'arguments' => [
766           ['Media unpublished', 'CONTAINS'],
767         ],
768         'result' => [
769           $media_type->id() => [
770             $media_entities['unpublished']->id() => $media_labels['unpublished'],
771           ],
772         ],
773       ],
774     ];
775     $this->assertReferenceable($selection_options, $referenceable_tests, 'Media handler (admin)');
776   }
777
778 }