annotate core/modules/migrate/tests/src/Kernel/MigrateEntityContentBaseTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 1fec387a4317
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\migrate\Kernel;
Chris@0 4
Chris@14 5 use Drupal\entity_test\Entity\EntityTestMul;
Chris@0 6 use Drupal\KernelTests\KernelTestBase;
Chris@0 7 use Drupal\language\Entity\ConfigurableLanguage;
Chris@0 8 use Drupal\migrate\MigrateExecutable;
Chris@0 9 use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
Chris@0 10 use Drupal\migrate\Plugin\MigrateIdMapInterface;
Chris@0 11 use Drupal\migrate\Plugin\MigrationInterface;
Chris@0 12 use Drupal\migrate\Row;
Chris@0 13 use Drupal\migrate_entity_test\Entity\StringIdEntityTest;
Chris@0 14
Chris@0 15 /**
Chris@0 16 * Tests the EntityContentBase destination.
Chris@0 17 *
Chris@0 18 * @group migrate
Chris@0 19 */
Chris@0 20 class MigrateEntityContentBaseTest extends KernelTestBase {
Chris@0 21
Chris@0 22 /**
Chris@0 23 * Modules to enable.
Chris@0 24 *
Chris@0 25 * @var array
Chris@0 26 */
Chris@0 27 public static $modules = ['migrate', 'user', 'language', 'entity_test'];
Chris@0 28
Chris@0 29 /**
Chris@0 30 * The storage for entity_test_mul.
Chris@0 31 *
Chris@0 32 * @var \Drupal\Core\Entity\ContentEntityStorageInterface
Chris@0 33 */
Chris@0 34 protected $storage;
Chris@0 35
Chris@0 36 /**
Chris@0 37 * A content migrate destination.
Chris@0 38 *
Chris@0 39 * @var \Drupal\migrate\Plugin\MigrateDestinationInterface
Chris@0 40 */
Chris@0 41 protected $destination;
Chris@0 42
Chris@0 43 /**
Chris@0 44 * {@inheritdoc}
Chris@0 45 */
Chris@0 46 protected function setUp() {
Chris@0 47 parent::setUp();
Chris@14 48
Chris@14 49 // Enable two required fields with default values: a single-value field and
Chris@14 50 // a multi-value field.
Chris@14 51 \Drupal::state()->set('entity_test.required_default_field', TRUE);
Chris@14 52 \Drupal::state()->set('entity_test.required_multi_default_field', TRUE);
Chris@0 53 $this->installEntitySchema('entity_test_mul');
Chris@0 54
Chris@0 55 ConfigurableLanguage::createFromLangcode('en')->save();
Chris@0 56 ConfigurableLanguage::createFromLangcode('fr')->save();
Chris@0 57
Chris@0 58 $this->storage = $this->container->get('entity.manager')->getStorage('entity_test_mul');
Chris@0 59 }
Chris@0 60
Chris@0 61 /**
Chris@0 62 * Check the existing translations of an entity.
Chris@0 63 *
Chris@0 64 * @param int $id
Chris@0 65 * The entity ID.
Chris@0 66 * @param string $default
Chris@0 67 * The expected default translation language code.
Chris@0 68 * @param string[] $others
Chris@0 69 * The expected other translation language codes.
Chris@0 70 */
Chris@0 71 protected function assertTranslations($id, $default, $others = []) {
Chris@0 72 $entity = $this->storage->load($id);
Chris@0 73 $this->assertTrue($entity, "Entity exists");
Chris@0 74 $this->assertEquals($default, $entity->language()->getId(), "Entity default translation");
Chris@0 75 $translations = array_keys($entity->getTranslationLanguages(FALSE));
Chris@0 76 sort($others);
Chris@0 77 sort($translations);
Chris@0 78 $this->assertEquals($others, $translations, "Entity translations");
Chris@0 79 }
Chris@0 80
Chris@0 81 /**
Chris@0 82 * Create the destination plugin to test.
Chris@0 83 *
Chris@0 84 * @param array $configuration
Chris@0 85 * The plugin configuration.
Chris@0 86 */
Chris@0 87 protected function createDestination(array $configuration) {
Chris@0 88 $this->destination = new EntityContentBase(
Chris@0 89 $configuration,
Chris@0 90 'fake_plugin_id',
Chris@0 91 [],
Chris@0 92 $this->getMock(MigrationInterface::class),
Chris@0 93 $this->storage,
Chris@0 94 [],
Chris@0 95 $this->container->get('entity.manager'),
Chris@0 96 $this->container->get('plugin.manager.field.field_type')
Chris@0 97 );
Chris@0 98 }
Chris@0 99
Chris@0 100 /**
Chris@0 101 * Test importing and rolling back translated entities.
Chris@0 102 */
Chris@0 103 public function testTranslated() {
Chris@0 104 // Create a destination.
Chris@0 105 $this->createDestination(['translations' => TRUE]);
Chris@0 106
Chris@0 107 // Create some pre-existing entities.
Chris@0 108 $this->storage->create(['id' => 1, 'langcode' => 'en'])->save();
Chris@0 109 $this->storage->create(['id' => 2, 'langcode' => 'fr'])->save();
Chris@0 110 $translated = $this->storage->create(['id' => 3, 'langcode' => 'en']);
Chris@0 111 $translated->save();
Chris@0 112 $translated->addTranslation('fr')->save();
Chris@0 113
Chris@0 114 // Pre-assert that things are as expected.
Chris@0 115 $this->assertTranslations(1, 'en');
Chris@0 116 $this->assertTranslations(2, 'fr');
Chris@0 117 $this->assertTranslations(3, 'en', ['fr']);
Chris@0 118 $this->assertFalse($this->storage->load(4));
Chris@0 119
Chris@0 120 $destination_rows = [
Chris@0 121 // Existing default translation.
Chris@0 122 ['id' => 1, 'langcode' => 'en', 'action' => MigrateIdMapInterface::ROLLBACK_PRESERVE],
Chris@0 123 // New translation.
Chris@0 124 ['id' => 2, 'langcode' => 'en', 'action' => MigrateIdMapInterface::ROLLBACK_DELETE],
Chris@0 125 // Existing non-default translation.
Chris@0 126 ['id' => 3, 'langcode' => 'fr', 'action' => MigrateIdMapInterface::ROLLBACK_PRESERVE],
Chris@0 127 // Brand new row.
Chris@0 128 ['id' => 4, 'langcode' => 'fr', 'action' => MigrateIdMapInterface::ROLLBACK_DELETE],
Chris@0 129 ];
Chris@0 130 $rollback_actions = [];
Chris@0 131
Chris@0 132 // Import some rows.
Chris@0 133 foreach ($destination_rows as $idx => $destination_row) {
Chris@0 134 $row = new Row();
Chris@0 135 foreach ($destination_row as $key => $value) {
Chris@0 136 $row->setDestinationProperty($key, $value);
Chris@0 137 }
Chris@0 138 $this->destination->import($row);
Chris@0 139
Chris@0 140 // Check that the rollback action is correct, and save it.
Chris@0 141 $this->assertEquals($destination_row['action'], $this->destination->rollbackAction());
Chris@0 142 $rollback_actions[$idx] = $this->destination->rollbackAction();
Chris@0 143 }
Chris@0 144
Chris@0 145 $this->assertTranslations(1, 'en');
Chris@0 146 $this->assertTranslations(2, 'fr', ['en']);
Chris@0 147 $this->assertTranslations(3, 'en', ['fr']);
Chris@0 148 $this->assertTranslations(4, 'fr');
Chris@0 149
Chris@0 150 // Rollback the rows.
Chris@0 151 foreach ($destination_rows as $idx => $destination_row) {
Chris@0 152 if ($rollback_actions[$idx] == MigrateIdMapInterface::ROLLBACK_DELETE) {
Chris@0 153 $this->destination->rollback($destination_row);
Chris@0 154 }
Chris@0 155 }
Chris@0 156
Chris@0 157 // No change, update of existing translation.
Chris@0 158 $this->assertTranslations(1, 'en');
Chris@0 159 // Remove added translation.
Chris@0 160 $this->assertTranslations(2, 'fr');
Chris@0 161 // No change, update of existing translation.
Chris@0 162 $this->assertTranslations(3, 'en', ['fr']);
Chris@0 163 // No change, can't remove default translation.
Chris@0 164 $this->assertTranslations(4, 'fr');
Chris@0 165 }
Chris@0 166
Chris@0 167 /**
Chris@0 168 * Tests creation of ID columns table with definitions taken from entity type.
Chris@0 169 */
Chris@0 170 public function testEntityWithStringId() {
Chris@0 171 $this->enableModules(['migrate_entity_test']);
Chris@0 172 $this->installEntitySchema('migrate_string_id_entity_test');
Chris@0 173
Chris@0 174 $definition = [
Chris@0 175 'source' => [
Chris@0 176 'plugin' => 'embedded_data',
Chris@0 177 'data_rows' => [
Chris@0 178 ['id' => 123, 'version' => 'foo'],
Chris@0 179 // This integer needs an 'int' schema with 'big' size. If 'destid1'
Chris@0 180 // is not correctly taking the definition from the destination entity
Chris@0 181 // type, the import will fail with a SQL exception.
Chris@0 182 ['id' => 123456789012, 'version' => 'bar'],
Chris@0 183 ],
Chris@0 184 'ids' => [
Chris@0 185 'id' => ['type' => 'integer', 'size' => 'big'],
Chris@0 186 'version' => ['type' => 'string'],
Chris@0 187 ],
Chris@0 188 ],
Chris@0 189 'process' => [
Chris@0 190 'id' => 'id',
Chris@0 191 'version' => 'version',
Chris@0 192 ],
Chris@0 193 'destination' => [
Chris@0 194 'plugin' => 'entity:migrate_string_id_entity_test',
Chris@0 195 ],
Chris@0 196 ];
Chris@0 197
Chris@0 198 $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);
Chris@14 199 $executable = new MigrateExecutable($migration);
Chris@0 200 $result = $executable->import();
Chris@0 201 $this->assertEquals(MigrationInterface::RESULT_COMPLETED, $result);
Chris@0 202
Chris@0 203 /** @var \Drupal\migrate\Plugin\MigrateIdMapInterface $id_map_plugin */
Chris@0 204 $id_map_plugin = $migration->getIdMap();
Chris@0 205
Chris@0 206 // Check that the destination has been stored.
Chris@0 207 $map_row = $id_map_plugin->getRowBySource(['id' => 123, 'version' => 'foo']);
Chris@0 208 $this->assertEquals(123, $map_row['destid1']);
Chris@0 209 $map_row = $id_map_plugin->getRowBySource(['id' => 123456789012, 'version' => 'bar']);
Chris@0 210 $this->assertEquals(123456789012, $map_row['destid1']);
Chris@0 211 }
Chris@0 212
Chris@0 213 /**
Chris@0 214 * Tests empty destinations.
Chris@0 215 */
Chris@0 216 public function testEmptyDestinations() {
Chris@0 217 $this->enableModules(['migrate_entity_test']);
Chris@0 218 $this->installEntitySchema('migrate_string_id_entity_test');
Chris@0 219
Chris@0 220 $definition = [
Chris@0 221 'source' => [
Chris@0 222 'plugin' => 'embedded_data',
Chris@0 223 'data_rows' => [
Chris@0 224 ['id' => 123, 'version' => 'foo'],
Chris@0 225 // This integer needs an 'int' schema with 'big' size. If 'destid1'
Chris@0 226 // is not correctly taking the definition from the destination entity
Chris@0 227 // type, the import will fail with an SQL exception.
Chris@0 228 ['id' => 123456789012, 'version' => 'bar'],
Chris@0 229 ],
Chris@0 230 'ids' => [
Chris@0 231 'id' => ['type' => 'integer', 'size' => 'big'],
Chris@0 232 'version' => ['type' => 'string'],
Chris@0 233 ],
Chris@0 234 'constants' => ['null' => NULL],
Chris@0 235 ],
Chris@0 236 'process' => [
Chris@0 237 'id' => 'id',
Chris@0 238 'version' => 'version',
Chris@0 239 ],
Chris@0 240 'destination' => [
Chris@0 241 'plugin' => 'entity:migrate_string_id_entity_test',
Chris@0 242 ],
Chris@0 243 ];
Chris@0 244
Chris@0 245 $migration = \Drupal::service('plugin.manager.migration')
Chris@0 246 ->createStubMigration($definition);
Chris@14 247 $executable = new MigrateExecutable($migration);
Chris@0 248 $executable->import();
Chris@0 249
Chris@0 250 /** @var \Drupal\migrate_entity_test\Entity\StringIdEntityTest $entity */
Chris@0 251 $entity = StringIdEntityTest::load('123');
Chris@0 252 $this->assertSame('foo', $entity->version->value);
Chris@0 253 $entity = StringIdEntityTest::load('123456789012');
Chris@0 254 $this->assertSame('bar', $entity->version->value);
Chris@0 255
Chris@0 256 // Rerun the migration forcing the version to NULL.
Chris@0 257 $definition['process'] = [
Chris@0 258 'id' => 'id',
Chris@0 259 'version' => 'constants/null',
Chris@0 260 ];
Chris@0 261
Chris@0 262 $migration = \Drupal::service('plugin.manager.migration')
Chris@0 263 ->createStubMigration($definition);
Chris@14 264 $executable = new MigrateExecutable($migration);
Chris@0 265 $executable->import();
Chris@0 266
Chris@0 267 /** @var \Drupal\migrate_entity_test\Entity\StringIdEntityTest $entity */
Chris@0 268 $entity = StringIdEntityTest::load('123');
Chris@0 269 $this->assertNull($entity->version->value);
Chris@0 270 $entity = StringIdEntityTest::load('123456789012');
Chris@0 271 $this->assertNull($entity->version->value);
Chris@0 272 }
Chris@0 273
Chris@14 274 /**
Chris@14 275 * Tests stub rows.
Chris@14 276 */
Chris@14 277 public function testStubRows() {
Chris@14 278 // Create a destination.
Chris@14 279 $this->createDestination([]);
Chris@14 280
Chris@14 281 // Import a stub row.
Chris@14 282 $row = new Row([], [], TRUE);
Chris@14 283 $row->setDestinationProperty('type', 'test');
Chris@14 284 $ids = $this->destination->import($row);
Chris@14 285 $this->assertCount(1, $ids);
Chris@14 286
Chris@14 287 // Make sure the entity was saved.
Chris@14 288 $entity = EntityTestMul::load(reset($ids));
Chris@14 289 $this->assertInstanceOf(EntityTestMul::class, $entity);
Chris@14 290 // Make sure the default value was applied to the required fields.
Chris@14 291 $single_field_name = 'required_default_field';
Chris@14 292 $single_default_value = $entity->getFieldDefinition($single_field_name)->getDefaultValueLiteral();
Chris@14 293 $this->assertSame($single_default_value, $entity->get($single_field_name)->getValue());
Chris@14 294
Chris@14 295 $multi_field_name = 'required_multi_default_field';
Chris@14 296 $multi_default_value = $entity->getFieldDefinition($multi_field_name)->getDefaultValueLiteral();
Chris@14 297 $count = 3;
Chris@14 298 $this->assertCount($count, $multi_default_value);
Chris@14 299 for ($i = 0; $i < $count; ++$i) {
Chris@14 300 $this->assertSame($multi_default_value[$i], $entity->get($multi_field_name)->get($i)->getValue());
Chris@14 301 }
Chris@14 302 }
Chris@14 303
Chris@0 304 }