625ee190edb95a8993eda4b2e1013937586f2b96
[yaffs-website] / web / core / modules / system / tests / src / Functional / Entity / Update / SqlContentEntityStorageSchemaConverterTest.php
1 <?php
2
3 namespace Drupal\Tests\system\Functional\Entity\Update;
4
5 use Drupal\Core\Entity\Sql\TemporaryTableMapping;
6 use Drupal\FunctionalTests\Update\UpdatePathTestBase;
7 use Drupal\system\Tests\Entity\EntityDefinitionTestTrait;
8
9 /**
10  * Tests updating an entity type with existing data to be revisionable.
11  *
12  * @group Entity
13  * @group Update
14  */
15 class SqlContentEntityStorageSchemaConverterTest extends UpdatePathTestBase {
16
17   use EntityDefinitionTestTrait;
18
19   /**
20    * The entity manager service.
21    *
22    * @var \Drupal\Core\Entity\EntityManagerInterface
23    */
24   protected $entityManager;
25
26   /**
27    * The entity definition update manager.
28    *
29    * @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface
30    */
31   protected $entityDefinitionUpdateManager;
32
33   /**
34    * The last installed schema repository service.
35    *
36    * @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface
37    */
38   protected $lastInstalledSchemaRepository;
39
40   /**
41    * The key-value collection for tracking installed storage schema.
42    *
43    * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
44    */
45   protected $installedStorageSchema;
46
47   /**
48    * The state service.
49    *
50    * @var \Drupal\Core\State\StateInterface
51    */
52   protected $state;
53
54   /**
55    * {@inheritdoc}
56    */
57   protected function setUp() {
58     parent::setUp();
59
60     $this->entityManager = \Drupal::entityManager();
61     $this->entityDefinitionUpdateManager = \Drupal::entityDefinitionUpdateManager();
62     $this->lastInstalledSchemaRepository = \Drupal::service('entity.last_installed_schema.repository');
63     $this->installedStorageSchema = \Drupal::keyValue('entity.storage_schema.sql');
64     $this->state = \Drupal::state();
65   }
66
67   /**
68    * {@inheritdoc}
69    */
70   protected function setDatabaseDumpFiles() {
71     $this->databaseDumpFiles = [
72       __DIR__ . '/../../../../fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz',
73       __DIR__ . '/../../../../fixtures/update/drupal-8.entity-test-schema-converter-enabled.php',
74     ];
75   }
76
77   /**
78    * Tests the conversion of an entity type to revisionable.
79    */
80   public function testMakeRevisionable() {
81     // Check that entity type is not revisionable prior to running the update
82     // process.
83     $entity_test_update = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update');
84     $this->assertFalse($entity_test_update->isRevisionable());
85
86     // Make the entity type revisionable and translatable and run the updates.
87     $this->updateEntityTypeToRevisionableAndTranslatable();
88
89     $this->runUpdates();
90
91     /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_test_update */
92     $entity_test_update = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update');
93     $this->assertTrue($entity_test_update->isRevisionable());
94
95     $field_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update');
96     $this->assertTrue(isset($field_storage_definitions['revision_translation_affected']));
97
98     /** @var \Drupal\Core\Entity\Sql\SqlEntityStorageInterface $storage */
99     $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
100     $this->assertEqual(count($storage->loadMultiple()), 102, 'All test entities were found.');
101
102     // Check that each field value was copied correctly to the revision tables.
103     for ($i = 1; $i <= 102; $i++) {
104       /** @var \Drupal\Core\Entity\ContentEntityInterface $revision */
105       $revision = $storage->loadRevision($i);
106
107       $this->assertEqual($i, $revision->id());
108       $this->assertEqual($i, $revision->getRevisionId());
109
110       // Check that the correct initial value was provided for the
111       // 'revision_translation_affected' field.
112       $this->assertTrue($revision->revision_translation_affected->value);
113
114       $this->assertEqual($i . ' - test single property', $revision->test_single_property->value);
115
116       $this->assertEqual($i . ' - test multiple properties - value1', $revision->test_multiple_properties->value1);
117       $this->assertEqual($i . ' - test multiple properties - value2', $revision->test_multiple_properties->value2);
118
119       $this->assertEqual($i . ' - test single property multiple values 0', $revision->test_single_property_multiple_values->value);
120       $this->assertEqual($i . ' - test single property multiple values 1', $revision->test_single_property_multiple_values[1]->value);
121
122       $this->assertEqual($i . ' - test multiple properties multiple values - value1 0', $revision->test_multiple_properties_multiple_values[0]->value1);
123       $this->assertEqual($i . ' - test multiple properties multiple values - value2 0', $revision->test_multiple_properties_multiple_values[0]->value2);
124       $this->assertEqual($i . ' - test multiple properties multiple values - value1 1', $revision->test_multiple_properties_multiple_values[1]->value1);
125       $this->assertEqual($i . ' - test multiple properties multiple values - value2 1', $revision->test_multiple_properties_multiple_values[1]->value2);
126
127       $this->assertEqual($i . ' - field test configurable field - value1 0', $revision->field_test_configurable_field[0]->value1);
128       $this->assertEqual($i . ' - field test configurable field - value2 0', $revision->field_test_configurable_field[0]->value2);
129       $this->assertEqual($i . ' - field test configurable field - value1 1', $revision->field_test_configurable_field[1]->value1);
130       $this->assertEqual($i . ' - field test configurable field - value2 1', $revision->field_test_configurable_field[1]->value2);
131
132       $this->assertEqual($i . ' - test entity base field info', $revision->test_entity_base_field_info->value);
133
134       // Do the same checks for translated field values.
135       $translation = $revision->getTranslation('ro');
136
137       $this->assertEqual($i . ' - test single property - ro', $translation->test_single_property->value);
138
139       $this->assertEqual($i . ' - test multiple properties - value1 - ro', $translation->test_multiple_properties->value1);
140       $this->assertEqual($i . ' - test multiple properties - value2 - ro', $translation->test_multiple_properties->value2);
141
142       $this->assertEqual($i . ' - test single property multiple values 0 - ro', $translation->test_single_property_multiple_values[0]->value);
143       $this->assertEqual($i . ' - test single property multiple values 1 - ro', $translation->test_single_property_multiple_values[1]->value);
144
145       $this->assertEqual($i . ' - test multiple properties multiple values - value1 0 - ro', $translation->test_multiple_properties_multiple_values[0]->value1);
146       $this->assertEqual($i . ' - test multiple properties multiple values - value2 0 - ro', $translation->test_multiple_properties_multiple_values[0]->value2);
147       $this->assertEqual($i . ' - test multiple properties multiple values - value1 1 - ro', $translation->test_multiple_properties_multiple_values[1]->value1);
148       $this->assertEqual($i . ' - test multiple properties multiple values - value2 1 - ro', $translation->test_multiple_properties_multiple_values[1]->value2);
149
150       $this->assertEqual($i . ' - field test configurable field - value1 0 - ro', $translation->field_test_configurable_field[0]->value1);
151       $this->assertEqual($i . ' - field test configurable field - value2 0 - ro', $translation->field_test_configurable_field[0]->value2);
152       $this->assertEqual($i . ' - field test configurable field - value1 1 - ro', $translation->field_test_configurable_field[1]->value1);
153       $this->assertEqual($i . ' - field test configurable field - value2 1 - ro', $translation->field_test_configurable_field[1]->value2);
154
155       $this->assertEqual($i . ' - test entity base field info - ro', $translation->test_entity_base_field_info->value);
156     }
157
158     // Check that temporary tables have been removed at the end of the process.
159     $schema = \Drupal::database()->schema();
160     foreach ($storage->getTableMapping()->getTableNames() as $table_name) {
161       $this->assertFalse($schema->tableExists(TemporaryTableMapping::getTempTableName($table_name)));
162     }
163
164     // Check that backup tables have been removed at the end of the process.
165     $schema = \Drupal::database()->schema();
166     foreach ($storage->getTableMapping()->getTableNames() as $table_name) {
167       $this->assertFalse($schema->tableExists(TemporaryTableMapping::getTempTableName($table_name, 'old_')));
168     }
169   }
170
171   /**
172    * Tests that a failed "make revisionable" update preserves the existing data.
173    */
174   public function testMakeRevisionableErrorHandling() {
175     $original_entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update');
176     $original_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update');
177
178     $original_entity_schema_data = $this->installedStorageSchema->get('entity_test_update.entity_schema_data', []);
179     foreach ($original_storage_definitions as $storage_definition) {
180       $original_field_schema_data[$storage_definition->getName()] = $this->installedStorageSchema->get('entity_test_update.field_schema_data.' . $storage_definition->getName(), []);
181     }
182
183     // Check that entity type is not revisionable prior to running the update
184     // process.
185     $this->assertFalse($original_entity_type->isRevisionable());
186
187     // Make the update throw an exception during the entity save process.
188     \Drupal::state()->set('entity_test_update.throw_exception', TRUE);
189
190     // Since the update process is interrupted by the exception thrown above,
191     // we can not do the full post update testing offered by UpdatePathTestBase.
192     $this->checkFailedUpdates = FALSE;
193
194     // Make the entity type revisionable and run the updates.
195     $this->updateEntityTypeToRevisionableAndTranslatable();
196
197     $this->runUpdates();
198
199     // Check that the update failed.
200     $this->assertRaw('<strong>' . t('Failed:') . '</strong>');
201
202     // Check that the last installed entity type definition is kept as
203     // non-revisionable.
204     $new_entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update');
205     $this->assertFalse($new_entity_type->isRevisionable(), 'The entity type is kept unchanged.');
206
207     // Check that the last installed field storage definitions did not change by
208     // looking at the 'langcode' field, which is updated automatically.
209     $new_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update');
210     $langcode_key = $original_entity_type->getKey('langcode');
211     $this->assertEqual($original_storage_definitions[$langcode_key]->isRevisionable(), $new_storage_definitions[$langcode_key]->isRevisionable(), "The 'langcode' field is kept unchanged.");
212
213     /** @var \Drupal\Core\Entity\Sql\SqlEntityStorageInterface $storage */
214     $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
215
216     // Check that installed storage schema did not change.
217     $new_entity_schema_data = $this->installedStorageSchema->get('entity_test_update.entity_schema_data', []);
218     $this->assertEqual($original_entity_schema_data, $new_entity_schema_data);
219
220     foreach ($new_storage_definitions as $storage_definition) {
221       $new_field_schema_data[$storage_definition->getName()] = $this->installedStorageSchema->get('entity_test_update.field_schema_data.' . $storage_definition->getName(), []);
222     }
223     $this->assertEqual($original_field_schema_data, $new_field_schema_data);
224
225     // Check that temporary tables have been removed.
226     $schema = \Drupal::database()->schema();
227     foreach ($storage->getTableMapping()->getTableNames() as $table_name) {
228       $this->assertFalse($schema->tableExists(TemporaryTableMapping::getTempTableName($table_name)));
229     }
230
231     // Check that the original tables still exist and their data is intact.
232     $this->assertTrue($schema->tableExists('entity_test_update'));
233     $this->assertTrue($schema->tableExists('entity_test_update_data'));
234
235     $base_table_count = \Drupal::database()->select('entity_test_update')
236       ->countQuery()
237       ->execute()
238       ->fetchField();
239     $this->assertEqual($base_table_count, 102);
240
241     $data_table_count = \Drupal::database()->select('entity_test_update_data')
242       ->countQuery()
243       ->execute()
244       ->fetchField();
245     // There are two records for each entity, one for English and one for
246     // Romanian.
247     $this->assertEqual($data_table_count, 204);
248
249     $base_table_row = \Drupal::database()->select('entity_test_update')
250       ->fields('entity_test_update')
251       ->condition('id', 1, '=')
252       ->condition('langcode', 'en', '=')
253       ->execute()
254       ->fetchAllAssoc('id');
255     $this->assertEqual('843e9ac7-3351-4cc1-a202-2dbffffae21c', $base_table_row[1]->uuid);
256
257     $data_table_row = \Drupal::database()->select('entity_test_update_data')
258       ->fields('entity_test_update_data')
259       ->condition('id', 1, '=')
260       ->condition('langcode', 'en', '=')
261       ->execute()
262       ->fetchAllAssoc('id');
263     $this->assertEqual('1 - test single property', $data_table_row[1]->test_single_property);
264     $this->assertEqual('1 - test multiple properties - value1', $data_table_row[1]->test_multiple_properties__value1);
265     $this->assertEqual('1 - test multiple properties - value2', $data_table_row[1]->test_multiple_properties__value2);
266     $this->assertEqual('1 - test entity base field info', $data_table_row[1]->test_entity_base_field_info);
267   }
268
269 }