Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Tests\migrate\Kernel;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\KernelTests\KernelTestBase;
|
Chris@0
|
6 use Drupal\language\Entity\ConfigurableLanguage;
|
Chris@0
|
7 use Drupal\migrate\MigrateExecutable;
|
Chris@0
|
8 use Drupal\migrate\MigrateMessage;
|
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@0
|
48 $this->installEntitySchema('entity_test_mul');
|
Chris@0
|
49
|
Chris@0
|
50 ConfigurableLanguage::createFromLangcode('en')->save();
|
Chris@0
|
51 ConfigurableLanguage::createFromLangcode('fr')->save();
|
Chris@0
|
52
|
Chris@0
|
53 $this->storage = $this->container->get('entity.manager')->getStorage('entity_test_mul');
|
Chris@0
|
54 }
|
Chris@0
|
55
|
Chris@0
|
56 /**
|
Chris@0
|
57 * Check the existing translations of an entity.
|
Chris@0
|
58 *
|
Chris@0
|
59 * @param int $id
|
Chris@0
|
60 * The entity ID.
|
Chris@0
|
61 * @param string $default
|
Chris@0
|
62 * The expected default translation language code.
|
Chris@0
|
63 * @param string[] $others
|
Chris@0
|
64 * The expected other translation language codes.
|
Chris@0
|
65 */
|
Chris@0
|
66 protected function assertTranslations($id, $default, $others = []) {
|
Chris@0
|
67 $entity = $this->storage->load($id);
|
Chris@0
|
68 $this->assertTrue($entity, "Entity exists");
|
Chris@0
|
69 $this->assertEquals($default, $entity->language()->getId(), "Entity default translation");
|
Chris@0
|
70 $translations = array_keys($entity->getTranslationLanguages(FALSE));
|
Chris@0
|
71 sort($others);
|
Chris@0
|
72 sort($translations);
|
Chris@0
|
73 $this->assertEquals($others, $translations, "Entity translations");
|
Chris@0
|
74 }
|
Chris@0
|
75
|
Chris@0
|
76 /**
|
Chris@0
|
77 * Create the destination plugin to test.
|
Chris@0
|
78 *
|
Chris@0
|
79 * @param array $configuration
|
Chris@0
|
80 * The plugin configuration.
|
Chris@0
|
81 */
|
Chris@0
|
82 protected function createDestination(array $configuration) {
|
Chris@0
|
83 $this->destination = new EntityContentBase(
|
Chris@0
|
84 $configuration,
|
Chris@0
|
85 'fake_plugin_id',
|
Chris@0
|
86 [],
|
Chris@0
|
87 $this->getMock(MigrationInterface::class),
|
Chris@0
|
88 $this->storage,
|
Chris@0
|
89 [],
|
Chris@0
|
90 $this->container->get('entity.manager'),
|
Chris@0
|
91 $this->container->get('plugin.manager.field.field_type')
|
Chris@0
|
92 );
|
Chris@0
|
93 }
|
Chris@0
|
94
|
Chris@0
|
95 /**
|
Chris@0
|
96 * Test importing and rolling back translated entities.
|
Chris@0
|
97 */
|
Chris@0
|
98 public function testTranslated() {
|
Chris@0
|
99 // Create a destination.
|
Chris@0
|
100 $this->createDestination(['translations' => TRUE]);
|
Chris@0
|
101
|
Chris@0
|
102 // Create some pre-existing entities.
|
Chris@0
|
103 $this->storage->create(['id' => 1, 'langcode' => 'en'])->save();
|
Chris@0
|
104 $this->storage->create(['id' => 2, 'langcode' => 'fr'])->save();
|
Chris@0
|
105 $translated = $this->storage->create(['id' => 3, 'langcode' => 'en']);
|
Chris@0
|
106 $translated->save();
|
Chris@0
|
107 $translated->addTranslation('fr')->save();
|
Chris@0
|
108
|
Chris@0
|
109 // Pre-assert that things are as expected.
|
Chris@0
|
110 $this->assertTranslations(1, 'en');
|
Chris@0
|
111 $this->assertTranslations(2, 'fr');
|
Chris@0
|
112 $this->assertTranslations(3, 'en', ['fr']);
|
Chris@0
|
113 $this->assertFalse($this->storage->load(4));
|
Chris@0
|
114
|
Chris@0
|
115 $destination_rows = [
|
Chris@0
|
116 // Existing default translation.
|
Chris@0
|
117 ['id' => 1, 'langcode' => 'en', 'action' => MigrateIdMapInterface::ROLLBACK_PRESERVE],
|
Chris@0
|
118 // New translation.
|
Chris@0
|
119 ['id' => 2, 'langcode' => 'en', 'action' => MigrateIdMapInterface::ROLLBACK_DELETE],
|
Chris@0
|
120 // Existing non-default translation.
|
Chris@0
|
121 ['id' => 3, 'langcode' => 'fr', 'action' => MigrateIdMapInterface::ROLLBACK_PRESERVE],
|
Chris@0
|
122 // Brand new row.
|
Chris@0
|
123 ['id' => 4, 'langcode' => 'fr', 'action' => MigrateIdMapInterface::ROLLBACK_DELETE],
|
Chris@0
|
124 ];
|
Chris@0
|
125 $rollback_actions = [];
|
Chris@0
|
126
|
Chris@0
|
127 // Import some rows.
|
Chris@0
|
128 foreach ($destination_rows as $idx => $destination_row) {
|
Chris@0
|
129 $row = new Row();
|
Chris@0
|
130 foreach ($destination_row as $key => $value) {
|
Chris@0
|
131 $row->setDestinationProperty($key, $value);
|
Chris@0
|
132 }
|
Chris@0
|
133 $this->destination->import($row);
|
Chris@0
|
134
|
Chris@0
|
135 // Check that the rollback action is correct, and save it.
|
Chris@0
|
136 $this->assertEquals($destination_row['action'], $this->destination->rollbackAction());
|
Chris@0
|
137 $rollback_actions[$idx] = $this->destination->rollbackAction();
|
Chris@0
|
138 }
|
Chris@0
|
139
|
Chris@0
|
140 $this->assertTranslations(1, 'en');
|
Chris@0
|
141 $this->assertTranslations(2, 'fr', ['en']);
|
Chris@0
|
142 $this->assertTranslations(3, 'en', ['fr']);
|
Chris@0
|
143 $this->assertTranslations(4, 'fr');
|
Chris@0
|
144
|
Chris@0
|
145 // Rollback the rows.
|
Chris@0
|
146 foreach ($destination_rows as $idx => $destination_row) {
|
Chris@0
|
147 if ($rollback_actions[$idx] == MigrateIdMapInterface::ROLLBACK_DELETE) {
|
Chris@0
|
148 $this->destination->rollback($destination_row);
|
Chris@0
|
149 }
|
Chris@0
|
150 }
|
Chris@0
|
151
|
Chris@0
|
152 // No change, update of existing translation.
|
Chris@0
|
153 $this->assertTranslations(1, 'en');
|
Chris@0
|
154 // Remove added translation.
|
Chris@0
|
155 $this->assertTranslations(2, 'fr');
|
Chris@0
|
156 // No change, update of existing translation.
|
Chris@0
|
157 $this->assertTranslations(3, 'en', ['fr']);
|
Chris@0
|
158 // No change, can't remove default translation.
|
Chris@0
|
159 $this->assertTranslations(4, 'fr');
|
Chris@0
|
160 }
|
Chris@0
|
161
|
Chris@0
|
162 /**
|
Chris@0
|
163 * Tests creation of ID columns table with definitions taken from entity type.
|
Chris@0
|
164 */
|
Chris@0
|
165 public function testEntityWithStringId() {
|
Chris@0
|
166 $this->enableModules(['migrate_entity_test']);
|
Chris@0
|
167 $this->installEntitySchema('migrate_string_id_entity_test');
|
Chris@0
|
168
|
Chris@0
|
169 $definition = [
|
Chris@0
|
170 'source' => [
|
Chris@0
|
171 'plugin' => 'embedded_data',
|
Chris@0
|
172 'data_rows' => [
|
Chris@0
|
173 ['id' => 123, 'version' => 'foo'],
|
Chris@0
|
174 // This integer needs an 'int' schema with 'big' size. If 'destid1'
|
Chris@0
|
175 // is not correctly taking the definition from the destination entity
|
Chris@0
|
176 // type, the import will fail with a SQL exception.
|
Chris@0
|
177 ['id' => 123456789012, 'version' => 'bar'],
|
Chris@0
|
178 ],
|
Chris@0
|
179 'ids' => [
|
Chris@0
|
180 'id' => ['type' => 'integer', 'size' => 'big'],
|
Chris@0
|
181 'version' => ['type' => 'string'],
|
Chris@0
|
182 ],
|
Chris@0
|
183 ],
|
Chris@0
|
184 'process' => [
|
Chris@0
|
185 'id' => 'id',
|
Chris@0
|
186 'version' => 'version',
|
Chris@0
|
187 ],
|
Chris@0
|
188 'destination' => [
|
Chris@0
|
189 'plugin' => 'entity:migrate_string_id_entity_test',
|
Chris@0
|
190 ],
|
Chris@0
|
191 ];
|
Chris@0
|
192
|
Chris@0
|
193 $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);
|
Chris@0
|
194 $executable = new MigrateExecutable($migration, new MigrateMessage());
|
Chris@0
|
195 $result = $executable->import();
|
Chris@0
|
196 $this->assertEquals(MigrationInterface::RESULT_COMPLETED, $result);
|
Chris@0
|
197
|
Chris@0
|
198 /** @var \Drupal\migrate\Plugin\MigrateIdMapInterface $id_map_plugin */
|
Chris@0
|
199 $id_map_plugin = $migration->getIdMap();
|
Chris@0
|
200
|
Chris@0
|
201 // Check that the destination has been stored.
|
Chris@0
|
202 $map_row = $id_map_plugin->getRowBySource(['id' => 123, 'version' => 'foo']);
|
Chris@0
|
203 $this->assertEquals(123, $map_row['destid1']);
|
Chris@0
|
204 $map_row = $id_map_plugin->getRowBySource(['id' => 123456789012, 'version' => 'bar']);
|
Chris@0
|
205 $this->assertEquals(123456789012, $map_row['destid1']);
|
Chris@0
|
206 }
|
Chris@0
|
207
|
Chris@0
|
208 /**
|
Chris@0
|
209 * Tests empty destinations.
|
Chris@0
|
210 */
|
Chris@0
|
211 public function testEmptyDestinations() {
|
Chris@0
|
212 $this->enableModules(['migrate_entity_test']);
|
Chris@0
|
213 $this->installEntitySchema('migrate_string_id_entity_test');
|
Chris@0
|
214
|
Chris@0
|
215 $definition = [
|
Chris@0
|
216 'source' => [
|
Chris@0
|
217 'plugin' => 'embedded_data',
|
Chris@0
|
218 'data_rows' => [
|
Chris@0
|
219 ['id' => 123, 'version' => 'foo'],
|
Chris@0
|
220 // This integer needs an 'int' schema with 'big' size. If 'destid1'
|
Chris@0
|
221 // is not correctly taking the definition from the destination entity
|
Chris@0
|
222 // type, the import will fail with an SQL exception.
|
Chris@0
|
223 ['id' => 123456789012, 'version' => 'bar'],
|
Chris@0
|
224 ],
|
Chris@0
|
225 'ids' => [
|
Chris@0
|
226 'id' => ['type' => 'integer', 'size' => 'big'],
|
Chris@0
|
227 'version' => ['type' => 'string'],
|
Chris@0
|
228 ],
|
Chris@0
|
229 'constants' => ['null' => NULL],
|
Chris@0
|
230 ],
|
Chris@0
|
231 'process' => [
|
Chris@0
|
232 'id' => 'id',
|
Chris@0
|
233 'version' => 'version',
|
Chris@0
|
234 ],
|
Chris@0
|
235 'destination' => [
|
Chris@0
|
236 'plugin' => 'entity:migrate_string_id_entity_test',
|
Chris@0
|
237 ],
|
Chris@0
|
238 ];
|
Chris@0
|
239
|
Chris@0
|
240 $migration = \Drupal::service('plugin.manager.migration')
|
Chris@0
|
241 ->createStubMigration($definition);
|
Chris@0
|
242 $executable = new MigrateExecutable($migration, new MigrateMessage());
|
Chris@0
|
243 $executable->import();
|
Chris@0
|
244
|
Chris@0
|
245 /** @var \Drupal\migrate_entity_test\Entity\StringIdEntityTest $entity */
|
Chris@0
|
246 $entity = StringIdEntityTest::load('123');
|
Chris@0
|
247 $this->assertSame('foo', $entity->version->value);
|
Chris@0
|
248 $entity = StringIdEntityTest::load('123456789012');
|
Chris@0
|
249 $this->assertSame('bar', $entity->version->value);
|
Chris@0
|
250
|
Chris@0
|
251 // Rerun the migration forcing the version to NULL.
|
Chris@0
|
252 $definition['process'] = [
|
Chris@0
|
253 'id' => 'id',
|
Chris@0
|
254 'version' => 'constants/null',
|
Chris@0
|
255 ];
|
Chris@0
|
256
|
Chris@0
|
257 $migration = \Drupal::service('plugin.manager.migration')
|
Chris@0
|
258 ->createStubMigration($definition);
|
Chris@0
|
259 $executable = new MigrateExecutable($migration, new MigrateMessage());
|
Chris@0
|
260 $executable->import();
|
Chris@0
|
261
|
Chris@0
|
262 /** @var \Drupal\migrate_entity_test\Entity\StringIdEntityTest $entity */
|
Chris@0
|
263 $entity = StringIdEntityTest::load('123');
|
Chris@0
|
264 $this->assertNull($entity->version->value);
|
Chris@0
|
265 $entity = StringIdEntityTest::load('123456789012');
|
Chris@0
|
266 $this->assertNull($entity->version->value);
|
Chris@0
|
267 }
|
Chris@0
|
268
|
Chris@0
|
269 }
|