Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / migrate_plus / tests / src / Kernel / Plugin / migrate / process / EntityGenerateTest.php
1 <?php
2
3 namespace Drupal\Tests\migrate_plus\Kernel\Plugin\migrate\process;
4
5 use Drupal\Core\Config\Entity\ConfigEntityInterface;
6 use Drupal\Core\Field\FieldStorageDefinitionInterface;
7 use Drupal\Core\Language\LanguageInterface;
8 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
9 use Drupal\KernelTests\KernelTestBase;
10 use Drupal\migrate\MigrateExecutable;
11 use Drupal\migrate\MigrateMessageInterface;
12 use Drupal\node\Entity\NodeType;
13 use Drupal\taxonomy\Entity\Vocabulary;
14
15 /**
16  * Tests the migration plugin.
17  *
18  * @coversDefaultClass \Drupal\migrate_plus\Plugin\migrate\process\EntityGenerate
19  * @group migrate_plus
20  */
21 class EntityGenerateTest extends KernelTestBase implements MigrateMessageInterface {
22
23   use EntityReferenceTestTrait;
24
25   /**
26    * {@inheritdoc}
27    */
28   public static $modules = [
29     'migrate_plus',
30     'migrate',
31     'user',
32     'system',
33     'node',
34     'taxonomy',
35     'field',
36     'text',
37     'filter',
38   ];
39
40   /**
41    * The bundle used in this test.
42    *
43    * @var string
44    */
45   protected $bundle = 'page';
46
47   /**
48    * The name of the field used in this test.
49    *
50    * @var string
51    */
52   protected $fieldName = 'field_entity_reference';
53
54   /**
55    * The vocabulary id.
56    *
57    * @var string
58    */
59   protected $vocabulary = 'fruit';
60
61   /**
62    * The migration plugin manager.
63    *
64    * @var \Drupal\migrate\Plugin\MigrationPluginManager
65    */
66   protected $migrationPluginManager;
67
68   /**
69    * {@inheritdoc}
70    */
71   protected function setUp() {
72     parent::setUp();
73     // Create article content type.
74     $values = [
75       'type' => $this->bundle,
76       'name' => 'Page',
77     ];
78     $node_type = NodeType::create($values);
79     $node_type->save();
80
81     $this->installEntitySchema('node');
82     $this->installEntitySchema('taxonomy_term');
83     $this->installEntitySchema('taxonomy_vocabulary');
84     $this->installEntitySchema('user');
85     $this->installSchema('system', ['sequences']);
86     $this->installSchema('user', 'users_data');
87     $this->installConfig($this->modules);
88
89     // Create a vocabulary.
90     $vocabulary = Vocabulary::create([
91       'name' => $this->vocabulary,
92       'description' => $this->vocabulary,
93       'vid' => $this->vocabulary,
94       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
95     ]);
96     $vocabulary->save();
97
98     // Create a field.
99     $this->createEntityReferenceField(
100       'node',
101       $this->bundle,
102       $this->fieldName,
103       'Term reference',
104       'taxonomy_term',
105       'default',
106       ['target_bundles' => [$this->vocabulary]],
107       FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED
108     );
109
110     $this->migrationPluginManager = \Drupal::service('plugin.manager.migration');
111   }
112
113   /**
114    * Tests generating an entity.
115    *
116    * @dataProvider transformDataProvider
117    *
118    * @covers ::transform
119    */
120   public function testTransform(array $definition, array $expected, array $preSeed = []) {
121     // Pre seed some test data.
122     foreach ($preSeed as $storageName => $values) {
123       // If the first element of $values is a non-empty array, create multiple
124       // entities. Otherwise, create just one entity.
125       if (isset($values[0])) {
126         foreach ($values as $itemValues) {
127           $this->createTestData($storageName, $itemValues);
128         }
129       }
130       else {
131         $this->createTestData($storageName, $values);
132       }
133     }
134
135     /** @var \Drupal\migrate\Plugin\Migration $migration */
136     $migration = $this->migrationPluginManager->createStubMigration($definition);
137     /** @var EntityStorageBase $storage */
138     $storage = $this->readAttribute($migration->getDestinationPlugin(), 'storage');
139     $migrationExecutable = (new MigrateExecutable($migration, $this));
140     $migrationExecutable->import();
141
142     foreach ($expected as $row) {
143       $entity = $storage->load($row['id']);
144       $properties = array_diff_key($row, array_flip(['id']));
145       foreach ($properties as $property => $value) {
146         if (is_array($value)) {
147           if (empty($value)) {
148             $this->assertEmpty($entity->{$property}->getValue(), "Expected value is 'unset' but field $property is set.");
149           }
150           else {
151             // Check if we're testing multiple values in one field. If so, loop
152             // through them one-by-one and check that they're present in the
153             // $entity.
154             if (isset($value[0])) {
155               foreach ($value as $valueID => $valueToCheck) {
156                 foreach ($valueToCheck as $key => $expectedValue) {
157                   if (empty($expectedValue)) {
158                     if (!$entity->{$property}->isEmpty()) {
159                       $this->assertTrue($entity->{$property}[0]->entity->$key->isEmpty(), "Expected value is empty but field $property.$key is not empty.");
160                     }
161                     else {
162                       $this->assertTrue($entity->{$property}->isEmpty(), "FOOBAR Expected value is empty but field $property is not empty.");
163                     }
164                   }
165                   elseif ($entity->{$property}->getValue()) {
166                     $this->assertEquals($expectedValue, $entity->{$property}[$valueID]->entity->$key->value);
167                   }
168                   else {
169                     $this->fail("Expected value: $expectedValue does not exist in $property.");
170                   }
171                 }
172               }
173             }
174             // If we get to this point, we're only checking a
175             // single field value.
176             else {
177               foreach ($value as $key => $expectedValue) {
178                 if (empty($expectedValue)) {
179                   if (!$entity->{$property}->isEmpty()) {
180                     $this->assertTrue($entity->{$property}[0]->entity->$key->isEmpty(), "Expected value is empty but field $property.$key is not empty.");
181                   }
182                   else {
183                     $this->assertTrue($entity->{$property}->isEmpty(), "BINBAZ Expected value is empty but field $property is not empty.");
184                   }
185                 }
186                 elseif ($entity->{$property}->getValue()) {
187                   $referenced_entity = $entity->{$property}[0]->entity;
188                   $result_value = $referenced_entity instanceof ConfigEntityInterface ? $referenced_entity->get($key) : $referenced_entity->get($key)->value;
189                   $this->assertEquals($expectedValue, $result_value);
190                 }
191                 else {
192                   $this->fail("Expected value: $expectedValue does not exist in $property.");
193                 }
194               }
195             }
196           }
197         }
198         else {
199           $this->assertNotEmpty($entity, 'Entity with label ' . $row[$property] . ' is empty');
200           $this->assertEquals($row[$property], $entity->label());
201         }
202       }
203     }
204   }
205
206   /**
207    * Provides multiple migration definitions for "transform" test.
208    */
209   public function transformDataProvider() {
210     return [
211       'no arguments' => [
212         'definition' => [
213           'source' => [
214             'plugin' => 'embedded_data',
215             'data_rows' => [
216               [
217                 'id' => 1,
218                 'title' => 'content item 1',
219                 'term' => 'Apples',
220               ],
221               [
222                 'id' => 2,
223                 'title' => 'content item 2',
224                 'term' => 'Bananas',
225               ],
226               [
227                 'id' => 3,
228                 'title' => 'content item 3',
229                 'term' => 'Grapes',
230               ],
231             ],
232             'ids' => [
233               'id' => ['type' => 'integer'],
234             ],
235           ],
236           'process' => [
237             'id' => 'id',
238             'type' => [
239               'plugin' => 'default_value',
240               'default_value' => $this->bundle,
241             ],
242             'title' => 'title',
243             $this->fieldName => [
244               'plugin' => 'entity_generate',
245               'source' => 'term',
246             ],
247           ],
248           'destination' => [
249             'plugin' => 'entity:node',
250           ],
251         ],
252         'expected' => [
253           'row 1' => [
254             'id' => 1,
255             'title' => 'content item 1',
256             $this->fieldName => [
257               'tid' => 2,
258               'name' => 'Apples',
259             ],
260           ],
261           'row 2' => [
262             'id' => 2,
263             'title' => 'content item 2',
264             $this->fieldName => [
265               'tid' => 3,
266               'name' => 'Bananas',
267             ],
268           ],
269           'row 3' => [
270             'id' => 3,
271             'title' => 'content item 3',
272             $this->fieldName => [
273               'tid' => 1,
274               'name' => 'Grapes',
275             ],
276           ],
277         ],
278         'pre seed' => [
279           'taxonomy_term' => [
280             'name' => 'Grapes',
281             'vid' => $this->vocabulary,
282             'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
283           ],
284         ],
285       ],
286       'no arguments_lookup_only' => [
287         'definition' => [
288           'source' => [
289             'plugin' => 'embedded_data',
290             'data_rows' => [
291               [
292                 'id' => 1,
293                 'title' => 'content item 1',
294                 'term' => 'Apples',
295               ],
296               [
297                 'id' => 2,
298                 'title' => 'content item 2',
299                 'term' => 'Bananas',
300               ],
301               [
302                 'id' => 3,
303                 'title' => 'content item 3',
304                 'term' => 'Grapes',
305               ],
306             ],
307             'ids' => [
308               'id' => ['type' => 'integer'],
309             ],
310           ],
311           'process' => [
312             'id' => 'id',
313             'type' => [
314               'plugin' => 'default_value',
315               'default_value' => $this->bundle,
316             ],
317             'title' => 'title',
318             $this->fieldName => [
319               'plugin' => 'entity_lookup',
320               'source' => 'term',
321             ],
322           ],
323           'destination' => [
324             'plugin' => 'entity:node',
325           ],
326         ],
327         'expected' => [
328           'row 1' => [
329             'id' => 1,
330             'title' => 'content item 1',
331             $this->fieldName => [
332               'tid' => NULL,
333               'name' => NULL,
334             ],
335           ],
336           'row 2' => [
337             'id' => 2,
338             'title' => 'content item 2',
339             $this->fieldName => [
340               'tid' => NULL,
341               'name' => NULL,
342             ],
343           ],
344           'row 3' => [
345             'id' => 3,
346             'title' => 'content item 3',
347             $this->fieldName => [
348               'tid' => 1,
349               'name' => 'Grapes',
350             ],
351           ],
352         ],
353         'pre seed' => [
354           'taxonomy_term' => [
355             'name' => 'Grapes',
356             'vid' => $this->vocabulary,
357             'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
358           ],
359         ],
360       ],
361       'provide values' => [
362         'definition' => [
363           'source' => [
364             'plugin' => 'embedded_data',
365             'data_rows' => [
366               [
367                 'id' => 1,
368                 'title' => 'content item 1',
369                 'term' => 'Apples',
370               ],
371               [
372                 'id' => 2,
373                 'title' => 'content item 2',
374                 'term' => 'Bananas',
375               ],
376               [
377                 'id' => 3,
378                 'title' => 'content item 3',
379                 'term' => 'Grapes',
380               ],
381             ],
382             'ids' => [
383               'id' => ['type' => 'integer'],
384             ],
385           ],
386           'process' => [
387             'id' => 'id',
388             'type' => [
389               'plugin' => 'default_value',
390               'default_value' => $this->bundle,
391             ],
392             'title' => 'title',
393             'term_upper' => [
394               'plugin' => 'callback',
395               'source' => 'term',
396               'callable' => 'strtoupper',
397             ],
398             $this->fieldName => [
399               'plugin' => 'entity_generate',
400               'source' => 'term',
401               'values' => [
402                 'description' => '@term_upper',
403               ],
404             ],
405           ],
406           'destination' => [
407             'plugin' => 'entity:node',
408           ],
409         ],
410         'expected' => [
411           'row 1' => [
412             'id' => 1,
413             'title' => 'content item 1',
414             $this->fieldName => [
415               'tid' => 2,
416               'name' => 'Apples',
417               'description' => 'APPLES',
418             ],
419           ],
420           'row 2' => [
421             'id' => 2,
422             'title' => 'content item 2',
423             $this->fieldName => [
424               'tid' => 3,
425               'name' => 'Bananas',
426               'description' => 'BANANAS',
427             ],
428           ],
429           'row 3' => [
430             'id' => 3,
431             'title' => 'content item 3',
432             $this->fieldName => [
433               'tid' => 1,
434               'name' => 'Grapes',
435               'description' => NULL,
436             ],
437           ],
438         ],
439         'pre seed' => [
440           'taxonomy_term' => [
441             'name' => 'Grapes',
442             'vid' => $this->vocabulary,
443             'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
444           ],
445         ],
446       ],
447       'lookup single existing term returns correct term' => [
448         'definition' => [
449           'source' => [
450             'plugin' => 'embedded_data',
451             'data_rows' => [
452               [
453                 'id' => 1,
454                 'title' => 'content item 1',
455                 'term' => 'Grapes',
456               ],
457             ],
458             'ids' => [
459               'id' => ['type' => 'integer'],
460             ],
461           ],
462           'process' => [
463             'id' => 'id',
464             'type' => [
465               'plugin' => 'default_value',
466               'default_value' => $this->bundle,
467             ],
468             'title' => 'title',
469             $this->fieldName => [
470               'plugin' => 'entity_lookup',
471               'source' => 'term',
472             ],
473           ],
474           'destination' => [
475             'plugin' => 'entity:node',
476           ],
477         ],
478         'expected' => [
479           'row 1' => [
480             'id' => 1,
481             'title' => 'content item 1',
482             $this->fieldName => [
483               'tid' => 1,
484               'name' => 'Grapes',
485             ],
486           ],
487         ],
488         'pre seed' => [
489           'taxonomy_term' => [
490             'name' => 'Grapes',
491             'vid' => $this->vocabulary,
492             'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
493           ],
494         ],
495       ],
496       'lookup single missing term returns null value' => [
497         'definition' => [
498           'source' => [
499             'plugin' => 'embedded_data',
500             'data_rows' => [
501               [
502                 'id' => 1,
503                 'title' => 'content item 1',
504                 'term' => 'Apple',
505               ],
506             ],
507             'ids' => [
508               'id' => ['type' => 'integer'],
509             ],
510           ],
511           'process' => [
512             'id' => 'id',
513             'type' => [
514               'plugin' => 'default_value',
515               'default_value' => $this->bundle,
516             ],
517             'title' => 'title',
518             $this->fieldName => [
519               'plugin' => 'entity_lookup',
520               'source' => 'term',
521             ],
522           ],
523           'destination' => [
524             'plugin' => 'entity:node',
525           ],
526         ],
527         'expected' => [
528           'row 1' => [
529             'id' => 1,
530             'title' => 'content item 1',
531             $this->fieldName => [],
532           ],
533         ],
534         'pre seed' => [
535           'taxonomy_term' => [
536             'name' => 'Grapes',
537             'vid' => $this->vocabulary,
538             'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
539           ],
540         ],
541       ],
542       'lookup multiple existing terms returns correct terms' => [
543         'definition' => [
544           'source' => [
545             'plugin' => 'embedded_data',
546             'data_rows' => [
547               [
548                 'id' => 1,
549                 'title' => 'content item 1',
550                 'term' => [
551                   'Grapes',
552                   'Apples',
553                 ],
554               ],
555             ],
556             'ids' => [
557               'id' => ['type' => 'integer'],
558             ],
559           ],
560           'process' => [
561             'id' => 'id',
562             'title' => 'title',
563             'type' => [
564               'plugin' => 'default_value',
565               'default_value' => $this->bundle,
566             ],
567             $this->fieldName => [
568               'plugin' => 'entity_lookup',
569               'source' => 'term',
570             ],
571           ],
572           'destination' => [
573             'plugin' => 'entity:node',
574           ],
575         ],
576         'expected' => [
577           'row 1' => [
578             'id' => 1,
579             'title' => 'content item 1',
580             $this->fieldName => [
581               [
582                 'tid' => 1,
583                 'name' => 'Grapes',
584               ],
585               [
586                 'tid' => 2,
587                 'name' => 'Apples',
588               ],
589             ],
590           ],
591         ],
592         'pre seed' => [
593           'taxonomy_term' => [
594             [
595               'name' => 'Grapes',
596               'vid' => $this->vocabulary,
597               'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
598             ],
599             [
600               'name' => 'Apples',
601               'vid' => $this->vocabulary,
602               'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
603             ],
604           ],
605         ],
606       ],
607       'lookup multiple mixed terms returns correct terms' => [
608         'definition' => [
609           'source' => [
610             'plugin' => 'embedded_data',
611             'data_rows' => [
612               [
613                 'id' => 1,
614                 'title' => 'content item 1',
615                 'term' => [
616                   'Grapes',
617                   'Pears',
618                 ],
619               ],
620             ],
621             'ids' => [
622               'id' => ['type' => 'integer'],
623             ],
624           ],
625           'process' => [
626             'id' => 'id',
627             'title' => 'title',
628             'type' => [
629               'plugin' => 'default_value',
630               'default_value' => $this->bundle,
631             ],
632             $this->fieldName => [
633               'plugin' => 'entity_lookup',
634               'source' => 'term',
635             ],
636           ],
637           'destination' => [
638             'plugin' => 'entity:node',
639           ],
640         ],
641         'expected' => [
642           'row 1' => [
643             'id' => '1',
644             'title' => 'content item 1',
645             $this->fieldName => [
646               [
647                 'tid' => 1,
648                 'name' => 'Grapes',
649               ],
650             ],
651           ],
652         ],
653         'pre seed' => [
654           'taxonomy_term' => [
655             [
656               'name' => 'Grapes',
657               'vid' => $this->vocabulary,
658               'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
659             ],
660             [
661               'name' => 'Apples',
662               'vid' => $this->vocabulary,
663               'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
664             ],
665           ],
666         ],
667       ],
668       'lookup with empty term value returns no terms' => [
669         'definition' => [
670           'source' => [
671             'plugin' => 'embedded_data',
672             'data_rows' => [
673               [
674                 'id' => 1,
675                 'title' => 'content item 1',
676                 'term' => [],
677               ],
678             ],
679             'ids' => [
680               'id' => ['type' => 'integer'],
681             ],
682           ],
683           'process' => [
684             'id' => 'id',
685             'title' => 'title',
686             'type' => [
687               'plugin' => 'default_value',
688               'default_value' => $this->bundle,
689             ],
690             $this->fieldName => [
691               'plugin' => 'entity_lookup',
692               'source' => 'term',
693             ],
694           ],
695           'destination' => [
696             'plugin' => 'entity:node',
697           ],
698         ],
699         'expected' => [
700           'row 1' => [
701             'id' => 1,
702             'title' => 'content item 1',
703             $this->fieldName => [],
704           ],
705         ],
706         'pre seed' => [
707           'taxonomy_term' => [
708             'name' => 'Grapes',
709             'vid' => $this->vocabulary,
710             'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
711           ],
712         ],
713       ],
714       'lookup config entity' => [
715         'definition' => [
716           'source' => [
717             'plugin' => 'embedded_data',
718             'data_rows' => [
719               [
720                 'id' => 1,
721                 'name' => 'user 1',
722                 'mail' => 'user1@user1.com',
723                 'roles' => ['role_1'],
724               ],
725             ],
726             'ids' => [
727               'id' => ['type' => 'integer'],
728             ],
729           ],
730           'process' => [
731             'id' => 'id',
732             'name' => 'name',
733             'roles' => [
734               'plugin' => 'entity_lookup',
735               'entity_type' => 'user_role',
736               'value_key' => 'id',
737               'source' => 'roles',
738             ],
739           ],
740           'destination' => [
741             'plugin' => 'entity:user',
742           ],
743         ],
744         'expected' => [
745           'row 1' => [
746             'id' => 1,
747             'name' => 'user 1',
748             'roles' => [
749               'id' => 'role_1',
750               'label' => 'Role 1',
751             ],
752           ],
753         ],
754         'pre seed' => [
755           'user_role' => [
756             'id' => 'role_1',
757             'label' => 'Role 1',
758           ],
759         ],
760       ],
761     ];
762   }
763
764   /**
765    * {@inheritdoc}
766    */
767   public function display($message, $type = 'status') {
768     $this->assertTrue($type == 'status', $message);
769   }
770
771   /**
772    * Create pre-seed test data.
773    *
774    * @param string $storageName
775    *   The storage manager to create.
776    * @param array $values
777    *   The values to use when creating the entity.
778    */
779   private function createTestData($storageName, array $values) {
780     /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
781     $storage = $this->container
782       ->get('entity_type.manager')
783       ->getStorage($storageName);
784     $entity = $storage->create($values);
785     $entity->save();
786   }
787
788 }