3 namespace Drupal\Tests\migrate_plus\Kernel\Plugin\migrate\process;
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;
16 * Tests the migration plugin.
18 * @coversDefaultClass \Drupal\migrate_plus\Plugin\migrate\process\EntityGenerate
21 class EntityGenerateTest extends KernelTestBase implements MigrateMessageInterface {
23 use EntityReferenceTestTrait;
28 public static $modules = [
41 * The bundle used in this test.
45 protected $bundle = 'page';
48 * The name of the field used in this test.
52 protected $fieldName = 'field_entity_reference';
59 protected $vocabulary = 'fruit';
62 * The migration plugin manager.
64 * @var \Drupal\migrate\Plugin\MigrationPluginManager
66 protected $migrationPluginManager;
71 protected function setUp() {
73 // Create article content type.
75 'type' => $this->bundle,
78 $node_type = NodeType::create($values);
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);
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,
99 $this->createEntityReferenceField(
106 ['target_bundles' => [$this->vocabulary]],
107 FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED
110 $this->migrationPluginManager = \Drupal::service('plugin.manager.migration');
114 * Tests generating an entity.
116 * @dataProvider transformDataProvider
118 * @covers ::transform
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);
131 $this->createTestData($storageName, $values);
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();
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)) {
148 $this->assertEmpty($entity->{$property}->getValue(), "Expected value is 'unset' but field $property is set.");
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
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.");
162 $this->assertTrue($entity->{$property}->isEmpty(), "FOOBAR Expected value is empty but field $property is not empty.");
165 elseif ($entity->{$property}->getValue()) {
166 $this->assertEquals($expectedValue, $entity->{$property}[$valueID]->entity->$key->value);
169 $this->fail("Expected value: $expectedValue does not exist in $property.");
174 // If we get to this point, we're only checking a
175 // single field value.
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.");
183 $this->assertTrue($entity->{$property}->isEmpty(), "BINBAZ Expected value is empty but field $property is not empty.");
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);
192 $this->fail("Expected value: $expectedValue does not exist in $property.");
199 $this->assertNotEmpty($entity, 'Entity with label ' . $row[$property] . ' is empty');
200 $this->assertEquals($row[$property], $entity->label());
207 * Provides multiple migration definitions for "transform" test.
209 public function transformDataProvider() {
214 'plugin' => 'embedded_data',
218 'title' => 'content item 1',
223 'title' => 'content item 2',
228 'title' => 'content item 3',
233 'id' => ['type' => 'integer'],
239 'plugin' => 'default_value',
240 'default_value' => $this->bundle,
243 $this->fieldName => [
244 'plugin' => 'entity_generate',
249 'plugin' => 'entity:node',
255 'title' => 'content item 1',
256 $this->fieldName => [
263 'title' => 'content item 2',
264 $this->fieldName => [
271 'title' => 'content item 3',
272 $this->fieldName => [
281 'vid' => $this->vocabulary,
282 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
286 'no arguments_lookup_only' => [
289 'plugin' => 'embedded_data',
293 'title' => 'content item 1',
298 'title' => 'content item 2',
303 'title' => 'content item 3',
308 'id' => ['type' => 'integer'],
314 'plugin' => 'default_value',
315 'default_value' => $this->bundle,
318 $this->fieldName => [
319 'plugin' => 'entity_lookup',
324 'plugin' => 'entity:node',
330 'title' => 'content item 1',
331 $this->fieldName => [
338 'title' => 'content item 2',
339 $this->fieldName => [
346 'title' => 'content item 3',
347 $this->fieldName => [
356 'vid' => $this->vocabulary,
357 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
361 'provide values' => [
364 'plugin' => 'embedded_data',
368 'title' => 'content item 1',
373 'title' => 'content item 2',
378 'title' => 'content item 3',
383 'id' => ['type' => 'integer'],
389 'plugin' => 'default_value',
390 'default_value' => $this->bundle,
394 'plugin' => 'callback',
396 'callable' => 'strtoupper',
398 $this->fieldName => [
399 'plugin' => 'entity_generate',
402 'description' => '@term_upper',
407 'plugin' => 'entity:node',
413 'title' => 'content item 1',
414 $this->fieldName => [
417 'description' => 'APPLES',
422 'title' => 'content item 2',
423 $this->fieldName => [
426 'description' => 'BANANAS',
431 'title' => 'content item 3',
432 $this->fieldName => [
435 'description' => NULL,
442 'vid' => $this->vocabulary,
443 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
447 'lookup single existing term returns correct term' => [
450 'plugin' => 'embedded_data',
454 'title' => 'content item 1',
459 'id' => ['type' => 'integer'],
465 'plugin' => 'default_value',
466 'default_value' => $this->bundle,
469 $this->fieldName => [
470 'plugin' => 'entity_lookup',
475 'plugin' => 'entity:node',
481 'title' => 'content item 1',
482 $this->fieldName => [
491 'vid' => $this->vocabulary,
492 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
496 'lookup single missing term returns null value' => [
499 'plugin' => 'embedded_data',
503 'title' => 'content item 1',
508 'id' => ['type' => 'integer'],
514 'plugin' => 'default_value',
515 'default_value' => $this->bundle,
518 $this->fieldName => [
519 'plugin' => 'entity_lookup',
524 'plugin' => 'entity:node',
530 'title' => 'content item 1',
531 $this->fieldName => [],
537 'vid' => $this->vocabulary,
538 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
542 'lookup multiple existing terms returns correct terms' => [
545 'plugin' => 'embedded_data',
549 'title' => 'content item 1',
557 'id' => ['type' => 'integer'],
564 'plugin' => 'default_value',
565 'default_value' => $this->bundle,
567 $this->fieldName => [
568 'plugin' => 'entity_lookup',
573 'plugin' => 'entity:node',
579 'title' => 'content item 1',
580 $this->fieldName => [
596 'vid' => $this->vocabulary,
597 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
601 'vid' => $this->vocabulary,
602 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
607 'lookup multiple mixed terms returns correct terms' => [
610 'plugin' => 'embedded_data',
614 'title' => 'content item 1',
622 'id' => ['type' => 'integer'],
629 'plugin' => 'default_value',
630 'default_value' => $this->bundle,
632 $this->fieldName => [
633 'plugin' => 'entity_lookup',
638 'plugin' => 'entity:node',
644 'title' => 'content item 1',
645 $this->fieldName => [
657 'vid' => $this->vocabulary,
658 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
662 'vid' => $this->vocabulary,
663 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
668 'lookup with empty term value returns no terms' => [
671 'plugin' => 'embedded_data',
675 'title' => 'content item 1',
680 'id' => ['type' => 'integer'],
687 'plugin' => 'default_value',
688 'default_value' => $this->bundle,
690 $this->fieldName => [
691 'plugin' => 'entity_lookup',
696 'plugin' => 'entity:node',
702 'title' => 'content item 1',
703 $this->fieldName => [],
709 'vid' => $this->vocabulary,
710 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
714 'lookup config entity' => [
717 'plugin' => 'embedded_data',
722 'mail' => 'user1@user1.com',
723 'roles' => ['role_1'],
727 'id' => ['type' => 'integer'],
734 'plugin' => 'entity_lookup',
735 'entity_type' => 'user_role',
741 'plugin' => 'entity:user',
767 public function display($message, $type = 'status') {
768 $this->assertTrue($type == 'status', $message);
772 * Create pre-seed test data.
774 * @param string $storageName
775 * The storage manager to create.
776 * @param array $values
777 * The values to use when creating the entity.
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);