function EntityDefinitionUpdateTest::testBundleFieldDeleteWithExistingData

Same name and namespace in other branches
  1. 9 core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php \Drupal\KernelTests\Core\Entity\EntityDefinitionUpdateTest::testBundleFieldDeleteWithExistingData()
  2. 8.9.x core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php \Drupal\KernelTests\Core\Entity\EntityDefinitionUpdateTest::testBundleFieldDeleteWithExistingData()

Tests deleting a bundle field when it has existing data.

File

core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php, line 517

Class

EntityDefinitionUpdateTest
Tests EntityDefinitionUpdateManager functionality.

Namespace

Drupal\KernelTests\Core\Entity

Code

public function testBundleFieldDeleteWithExistingData() : void {
  /** @var \Drupal\Core\Entity\Sql\SqlEntityStorageInterface $storage */
  $storage = $this->entityTypeManager
    ->getStorage('entity_test_update');
  $schema_handler = $this->database
    ->schema();
  // Add the bundle field and run the update.
  $this->addBundleField();
  $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_test_update')['new_bundle_field'];
  // Check that the bundle field has a dedicated table.
  $dedicated_table_name = $table_mapping->getDedicatedDataTableName($storage_definition);
  $this->assertTrue($schema_handler->tableExists($dedicated_table_name), 'The bundle field uses a dedicated table.');
  // Save an entity with the bundle field populated.
  entity_test_create_bundle('custom');
  $entity = $storage->create([
    'type' => 'test_bundle',
    'new_bundle_field' => 'foo',
  ]);
  $entity->save();
  // Remove the bundle field and apply updates.
  $this->removeBundleField();
  $this->applyEntityUpdates();
  // Check that the table of the bundle field has been renamed to use a
  // 'deleted' table name.
  $this->assertFalse($schema_handler->tableExists($dedicated_table_name), 'The dedicated table of the bundle field no longer exists.');
  $dedicated_deleted_table_name = $table_mapping->getDedicatedDataTableName($storage_definition, TRUE);
  $this->assertTrue($schema_handler->tableExists($dedicated_deleted_table_name), 'The dedicated table of the bundle fields has been renamed to use the "deleted" name.');
  // 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')
    ->execute()
    ->fetchAll();
  $this->assertCount(1, $result);
  $expected = [
    'bundle' => $entity->bundle(),
    'deleted' => '1',
    'entity_id' => $entity->id(),
    'revision_id' => $entity->id(),
    'langcode' => $entity->language()
      ->getId(),
    'delta' => '0',
    'new_bundle_field_value' => $entity->new_bundle_field->value,
  ];
  // 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, (array) $result[0]);
  // Check that the field definition is marked for purging.
  $deleted_field_definitions = \Drupal::service('entity_field.deleted_fields_repository')->getFieldDefinitions();
  $this->assertArrayHasKey($storage_definition->getUniqueIdentifier(), $deleted_field_definitions, 'The bundle field is marked for purging.');
  // 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 bundle field storage 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_field_definitions = \Drupal::service('entity_field.deleted_fields_repository')->getFieldDefinitions();
  $this->assertEmpty($deleted_field_definitions, 'The bundle field has been deleted.');
  $deleted_storage_definitions = \Drupal::service('entity_field.deleted_fields_repository')->getFieldStorageDefinitions();
  $this->assertEmpty($deleted_storage_definitions, 'The bundle field storage has been deleted.');
  $this->assertFalse($schema_handler->tableExists($dedicated_deleted_table_name), 'The dedicated table of the bundle field has been removed.');
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.