function EntityDefinitionUpdateTest::testBaseFieldDeleteWithExistingData
Same name in other branches
- 8.9.x core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php \Drupal\KernelTests\Core\Entity\EntityDefinitionUpdateTest::testBaseFieldDeleteWithExistingData()
Tests deleting a base field when it has existing data.
@dataProvider baseFieldDeleteWithExistingDataTestCases
File
-
core/
tests/ Drupal/ KernelTests/ Core/ Entity/ EntityDefinitionUpdateTest.php, line 519
Class
- EntityDefinitionUpdateTest
- Tests EntityDefinitionUpdateManager functionality.
Namespace
Drupal\KernelTests\Core\EntityCode
public function testBaseFieldDeleteWithExistingData($entity_type_id, $create_entity_revision, $base_field_revisionable, $create_entity_translation) {
// Enable an additional language.
ConfigurableLanguage::createFromLangcode('ro')->save();
/** @var \Drupal\Core\Entity\Sql\SqlEntityStorageInterface $storage */
$storage = $this->entityTypeManager
->getStorage($entity_type_id);
$schema_handler = $this->database
->schema();
// Create an entity without the base field, to ensure NULL values are not
// added to the dedicated table storage to be purged.
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity = $storage->create();
$entity->save();
// Add the base field and run the update.
$this->addBaseField('string', $entity_type_id, $base_field_revisionable, TRUE, $create_entity_translation);
$this->applyEntityUpdates();
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = $storage->getTableMapping();
$storage_definition = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledFieldStorageDefinitions($entity_type_id)['new_base_field'];
// Save an entity with the base field populated.
$entity = $storage->create([
'new_base_field' => 'foo',
]);
$entity->save();
if ($create_entity_translation) {
$translation = $entity->addTranslation('ro', [
'new_base_field' => 'foo-ro',
]);
$translation->save();
}
if ($create_entity_revision) {
$entity->setNewRevision(TRUE);
$entity->isDefaultRevision(FALSE);
$entity->new_base_field = 'bar';
$entity->save();
if ($create_entity_translation) {
$translation = $entity->getTranslation('ro');
$translation->new_base_field = 'bar-ro';
$translation->save();
}
}
// Remove the base field and apply updates.
$this->removeBaseField($entity_type_id);
$this->applyEntityUpdates();
// Check that the base field's column is deleted.
$this->assertFalse($schema_handler->fieldExists($entity_type_id, 'new_base_field'), 'Column deleted from shared table for new_base_field.');
// Check that a dedicated 'deleted' table was created for the deleted base
// field.
$dedicated_deleted_table_name = $table_mapping->getDedicatedDataTableName($storage_definition, TRUE);
$this->assertTrue($schema_handler->tableExists($dedicated_deleted_table_name), 'A dedicated table was created for the deleted new_base_field.');
$expected[] = [
'bundle' => $entity->bundle(),
'deleted' => '1',
'entity_id' => '2',
'revision_id' => '2',
'langcode' => 'en',
'delta' => '0',
'new_base_field_value' => 'foo',
];
if ($create_entity_translation) {
$expected[] = [
'bundle' => $entity->bundle(),
'deleted' => '1',
'entity_id' => '2',
'revision_id' => '2',
'langcode' => 'ro',
'delta' => '0',
'new_base_field_value' => 'foo-ro',
];
}
// Check that the deleted field's data is preserved in the dedicated
// 'deleted' table.
$result = $this->database
->select($dedicated_deleted_table_name, 't')
->fields('t')
->orderBy('revision_id', 'ASC')
->orderBy('langcode', 'ASC')
->execute()
->fetchAll(\PDO::FETCH_ASSOC);
$this->assertSameSize($expected, $result);
// Use assertEquals and not assertSame here to prevent that a different
// sequence of the columns in the table will affect the check.
$this->assertEquals($expected, $result);
if ($create_entity_revision) {
$dedicated_deleted_revision_table_name = $table_mapping->getDedicatedRevisionTableName($storage_definition, TRUE);
$this->assertTrue($schema_handler->tableExists($dedicated_deleted_revision_table_name), 'A dedicated revision table was created for the deleted new_base_field.');
if ($base_field_revisionable) {
$expected[] = [
'bundle' => $entity->bundle(),
'deleted' => '1',
'entity_id' => '2',
'revision_id' => '3',
'langcode' => 'en',
'delta' => '0',
'new_base_field_value' => 'bar',
];
if ($create_entity_translation) {
$expected[] = [
'bundle' => $entity->bundle(),
'deleted' => '1',
'entity_id' => '2',
'revision_id' => '3',
'langcode' => 'ro',
'delta' => '0',
'new_base_field_value' => 'bar-ro',
];
}
}
$result = $this->database
->select($dedicated_deleted_revision_table_name, 't')
->fields('t')
->orderBy('revision_id', 'ASC')
->orderBy('langcode', 'ASC')
->execute()
->fetchAll(\PDO::FETCH_ASSOC);
$this->assertSameSize($expected, $result);
// Use assertEquals and not assertSame here to prevent that a different
// sequence of the columns in the table will affect the check.
$this->assertEquals($expected, $result);
}
// Check that the field storage definition is marked for purging.
$deleted_storage_definitions = \Drupal::service('entity_field.deleted_fields_repository')->getFieldStorageDefinitions();
$this->assertArrayHasKey($storage_definition->getUniqueStorageIdentifier(), $deleted_storage_definitions, 'The base field is marked for purging.');
// Purge field data, and check that the storage definition has been
// completely removed once the data is purged.
field_purge_batch(10);
$deleted_storage_definitions = \Drupal::service('entity_field.deleted_fields_repository')->getFieldStorageDefinitions();
$this->assertEmpty($deleted_storage_definitions, 'The base field has been deleted.');
$this->assertFalse($schema_handler->tableExists($dedicated_deleted_table_name), 'A dedicated field table was deleted after new_base_field was purged.');
if (isset($dedicated_deleted_revision_table_name)) {
$this->assertFalse($schema_handler->tableExists($dedicated_deleted_revision_table_name), 'A dedicated field revision table was deleted after new_base_field was purged.');
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.