You are here

public function EntityDefinitionUpdateTest::testBundleFieldDeleteWithExistingData in Drupal 9

Same name and namespace in other branches
  1. 8 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 719

Class

EntityDefinitionUpdateTest
Tests EntityDefinitionUpdateManager functionality.

Namespace

Drupal\KernelTests\Core\Entity

Code

public function testBundleFieldDeleteWithExistingData() {

  /** @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.');
}