3 namespace Drupal\Tests\entity_reference_revisions\Kernel\Plugin\migrate\destination;
5 use Drupal\field\Entity\FieldConfig;
6 use Drupal\field\Entity\FieldStorageConfig;
7 use Drupal\KernelTests\KernelTestBase;
8 use Drupal\migrate\MigrateExecutable;
9 use Drupal\migrate\MigrateMessageInterface;
10 use Drupal\migrate\Plugin\Migration;
11 use Drupal\node\Entity\NodeType;
14 * Tests the migration destination plugin.
16 * @coversDefaultClass \Drupal\entity_reference_revisions\Plugin\migrate\destination\EntityReferenceRevisions
17 * @group entity_reference_revisions
19 class EntityReferenceRevisionsDestinationTest extends KernelTestBase implements MigrateMessageInterface {
22 * The migration plugin manager.
24 * @var \Drupal\migrate\Plugin\MigrationPluginManager
26 protected $migrationPluginManager;
31 public static $modules = [
33 'entity_reference_revisions',
34 'entity_composite_relationship_test',
43 protected function setUp() {
45 $this->installEntitySchema('entity_test_composite');
46 $this->installSchema('system', ['sequences']);
47 $this->installConfig($this->modules);
49 $this->migrationPluginManager = \Drupal::service('plugin.manager.migration');
53 * Tests get entity type id.
55 * @dataProvider getEntityTypeIdDataProvider
57 * @covers ::getEntityTypeId
59 public function testGetEntityTypeId(array $definition, $expected) {
60 /** @var \Drupal\migrate\Plugin\Migration $migration */
61 $migration = $this->migrationPluginManager->createStubMigration($definition);
62 /** @var \Drupal\entity_reference_revisions\Plugin\migrate\destination\EntityReferenceRevisions $destination */
63 $destination = $migration->getDestinationPlugin();
65 /** @var \Drupal\Core\Entity\EntityStorageBase $storage */
66 $storage = $this->readAttribute($destination, 'storage');
67 $actual = $this->readAttribute($storage, 'entityTypeId');
69 $this->assertEquals($expected, $actual);
73 * Provides multiple migration definitions for "getEntityTypeId" test.
75 public function getEntityTypeIdDataProvider() {
76 $data = $this->getEntityDataProvider();
78 foreach ($data as &$datum) {
79 $datum['expected'] = 'entity_test_composite';
88 * @dataProvider getEntityDataProvider
92 * @covers ::rollbackNonTranslation
94 public function testGetEntity(array $definition, array $expected) {
95 /** @var \Drupal\migrate\Plugin\Migration $migration */
96 $migration = $this->migrationPluginManager->createStubMigration($definition);
97 $migrationExecutable = (new MigrateExecutable($migration, $this));
98 /** @var \Drupal\Core\Entity\EntityStorageBase $storage */
99 $storage = $this->readAttribute($migration->getDestinationPlugin(), 'storage');
100 // Test inserting and updating by looping twice.
101 for ($i = 0; $i < 2; $i++) {
102 $migrationExecutable->import();
103 $migration->getIdMap()->prepareUpdate();
104 foreach ($expected as $data) {
105 $entity = $storage->loadRevision($data['revision_id']);
106 $this->assertEquals($data['label'], $entity->label());
107 $this->assertEquals($data['id'], $entity->id());
110 $migrationExecutable->rollback();
111 foreach ($expected as $data) {
112 $entity = $storage->loadRevision($data['id']);
113 $this->assertEmpty($entity);
118 * Provides multiple migration definitions for "getEntity" test.
120 public function getEntityDataProvider() {
125 'plugin' => 'embedded_data',
127 ['id' => 1, 'name' => 'content item 1a'],
128 ['id' => 1, 'name' => 'content item 1b'],
129 ['id' => 2, 'name' => 'content item 2'],
132 'id' => ['type' => 'integer'],
133 'name' => ['type' => 'text'],
140 'plugin' => 'entity_reference_revisions:entity_test_composite',
144 ['id' => 1, 'revision_id' => 1, 'label' => 'content item 1a'],
145 ['id' => 2, 'revision_id' => 2, 'label' => 'content item 1b'],
146 ['id' => 3, 'revision_id' => 3, 'label' => 'content item 2'],
152 'plugin' => 'embedded_data',
154 ['id' => 1, 'name' => 'content item 1a'],
155 ['id' => 1, 'name' => 'content item 1b'],
156 ['id' => 2, 'name' => 'content item 2'],
157 ['id' => 3, 'name' => 'content item 3'],
160 'id' => ['type' => 'integer'],
161 'name' => ['type' => 'text'],
169 'plugin' => 'entity_reference_revisions:entity_test_composite',
173 ['id' => 1, 'revision_id' => 1, 'label' => 'content item 1b'],
174 ['id' => 2, 'revision_id' => 2, 'label' => 'content item 2'],
175 ['id' => 3, 'revision_id' => 3, 'label' => 'content item 3'],
178 'with ids and new revisions' => [
181 'plugin' => 'embedded_data',
183 ['id' => 1, 'name' => 'content item 1a'],
184 ['id' => 1, 'name' => 'content item 1b'],
185 ['id' => 2, 'name' => 'content item 2'],
188 'id' => ['type' => 'integer'],
189 'name' => ['type' => 'text'],
197 'plugin' => 'entity_reference_revisions:entity_test_composite',
198 'new_revisions' => TRUE,
202 ['id' => 1, 'revision_id' => 1, 'label' => 'content item 1a'],
203 ['id' => 1, 'revision_id' => 2, 'label' => 'content item 1b'],
204 ['id' => 2, 'revision_id' => 3, 'label' => 'content item 2'],
207 'with ids and revisions' => [
210 'plugin' => 'embedded_data',
212 ['id' => 1, 'revision_id' => 1, 'name' => 'content item 1'],
213 ['id' => 2, 'revision_id' => 2, 'name' => 'content item 2'],
214 ['id' => 3, 'revision_id' => 3, 'name' => 'content item 3'],
217 'id' => ['type' => 'integer'],
218 'name' => ['type' => 'text'],
223 'revision_id' => 'revision_id',
227 'plugin' => 'entity_reference_revisions:entity_test_composite',
231 ['id' => 1, 'revision_id' => 1, 'label' => 'content item 1'],
232 ['id' => 2, 'revision_id' => 2, 'label' => 'content item 2'],
233 ['id' => 3, 'revision_id' => 3, 'label' => 'content item 3'],
240 * Tests multi-value and single-value destination field linkage.
242 * @dataProvider destinationFieldMappingDataProvider
244 public function testDestinationFieldMapping(array $data) {
245 $this->enableModules(['node', 'field']);
246 $this->installEntitySchema('node');
247 $this->installEntitySchema('user');
248 $this->installSchema('node', ['node_access']);
250 // Create new content type.
251 $values = ['type' => 'article', 'name' => 'Article'];
252 $node_type = NodeType::create($values);
255 // Add the field_err_single field to the node type.
256 $field_storage = FieldStorageConfig::create([
257 'field_name' => 'field_err_single',
258 'entity_type' => 'node',
259 'type' => 'entity_reference_revisions',
261 'target_type' => 'entity_test_composite',
265 $field_storage->save();
266 $field = FieldConfig::create([
267 'field_storage' => $field_storage,
268 'bundle' => 'article',
272 // Add the field_err_multiple field to the node type.
273 $field_storage = FieldStorageConfig::create([
274 'field_name' => 'field_err_multiple',
275 'entity_type' => 'node',
276 'type' => 'entity_reference_revisions',
278 'target_type' => 'entity_test_composite',
282 $field_storage->save();
283 $field = FieldConfig::create([
284 'field_storage' => $field_storage,
285 'bundle' => 'article',
291 foreach ($data as $datum) {
292 $definitions[$datum['definition']['id']] = $datum['definition'];
293 $instances[$datum['definition']['id']] = $this->migrationPluginManager->createStubMigration($datum['definition']);
296 // Reflection is easier than mocking. We need to use createInstance for
297 // purposes of registering the migration for the migration process plugin.
298 $reflector = new \ReflectionObject($this->migrationPluginManager);
299 $property = $reflector->getProperty('definitions');
300 $property->setAccessible(TRUE);
301 $property->setValue($this->migrationPluginManager, $definitions);
302 $this->container->set('plugin.manager.migration', $this->migrationPluginManager);
304 foreach ($data as $datum) {
305 $migration = $this->migrationPluginManager->createInstance($datum['definition']['id']);
306 $migrationExecutable = (new MigrateExecutable($migration, $this));
307 /** @var \Drupal\Core\Entity\EntityStorageBase $storage */
308 $storage = $this->readAttribute($migration->getDestinationPlugin(), 'storage');
309 $migrationExecutable->import();
310 foreach ($datum['expected'] as $expected) {
311 $entity = $storage->loadRevision($expected['id']);
312 $properties = array_diff_key($expected, array_flip(['id']));
313 foreach ($properties as $property => $value) {
314 if (is_array($value)) {
315 foreach ($value as $delta => $text) {
316 $this->assertNotEmpty($entity->{$property}[$delta]->entity, "Entity property $property with $delta is empty");
317 $this->assertEquals($text, $entity->{$property}[$delta]->entity->label());
321 $this->assertNotEmpty($entity, 'Entity with label ' . $expected[$property] . ' is empty');
322 $this->assertEquals($expected[$property], $entity->label());
330 * Provides multiple migration definitions for "getEntity" test.
332 public function destinationFieldMappingDataProvider() {
338 'id' => 'single_err',
339 'class' => Migration::class,
341 'plugin' => 'embedded_data',
345 'photo' => 'Photo1 here',
349 'photo' => 'Photo2 here',
353 'id' => ['type' => 'integer'],
360 'plugin' => 'entity_reference_revisions:entity_test_composite',
364 ['id' => 1, 'name' => 'Photo1 here'],
365 ['id' => 2, 'name' => 'Photo2 here'],
368 'multiple err author1' => [
370 'id' => 'multiple_err_author1',
371 'class' => Migration::class,
373 'plugin' => 'embedded_data',
377 'author' => 'Author 1',
381 'author' => 'Author 2',
385 'author' => ['type' => 'text'],
392 'plugin' => 'entity_reference_revisions:entity_test_composite',
396 ['id' => 3, 'name' => 'Author 1'],
397 ['id' => 4, 'name' => 'Author 2'],
400 'multiple err author 2' => [
402 'id' => 'multiple_err_author2',
403 'class' => Migration::class,
405 'plugin' => 'embedded_data',
409 'author' => 'Author 3',
413 'author' => 'Author 4',
417 'author' => ['type' => 'text'],
424 'plugin' => 'entity_reference_revisions:entity_test_composite',
428 ['id' => 5, 'name' => 'Author 3'],
429 ['id' => 6, 'name' => 'Author 4'],
432 'destination entity' => [
434 'id' => 'node_migration',
435 'class' => Migration::class,
437 'plugin' => 'embedded_data',
441 'title' => 'Article 1',
442 'photo' => 'Photo1 here',
443 'author' => ['Author 1', 'Author 3'],
447 'title' => 'Article 2',
448 'photo' => 'Photo2 here',
449 'author' => ['Author 2', 'Author 4'],
453 'id' => ['type' => 'integer'],
459 'plugin' => 'default_value',
460 'default_value' => 'article',
462 'field_err_single/target_id' => [
464 'plugin' => 'migration',
465 'migration' => ['single_err'],
470 'plugin' => 'extract',
476 'field_err_single/target_revision_id' => [
478 'plugin' => 'migration',
479 'migration' => ['single_err'],
484 'plugin' => 'extract',
490 'field_err_multiple' => [
492 'plugin' => 'migration',
494 'multiple_err_author1',
495 'multiple_err_author2',
498 'source' => 'author',
501 'plugin' => 'iterator',
504 'target_revision_id' => '1',
510 'plugin' => 'entity:node',
516 'title' => 'Article 1',
517 'field_err_single' => ['Photo1 here'],
518 'field_err_multiple' => ['Author 1', 'Author 3'],
522 'title' => 'Article 2',
523 'field_err_single' => ['Photo2 here'],
524 'field_err_multiple' => ['Author 2', 'Author 4'],
536 public function display($message, $type = 'status') {
537 $this->assertTrue($type == 'status', $message);