function EntitySchemaTest::testPrimaryKeyUpdate

Same name and namespace in other branches
  1. 9 core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php \Drupal\KernelTests\Core\Entity\EntitySchemaTest::testPrimaryKeyUpdate()
  2. 10 core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php \Drupal\KernelTests\Core\Entity\EntitySchemaTest::testPrimaryKeyUpdate()
  3. 11.x core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php \Drupal\KernelTests\Core\Entity\EntitySchemaTest::testPrimaryKeyUpdate()

Tests deleting and creating a field that is part of a primary key.

@dataProvider providerTestPrimaryKeyUpdate

Parameters

string $entity_type_id: The ID of the entity type whose schema is being tested.

string $field_name: The name of the field that is being re-installed.

File

core/tests/Drupal/KernelTests/Core/Entity/EntitySchemaTest.php, line 132

Class

EntitySchemaTest
Tests the default entity storage schema handler.

Namespace

Drupal\KernelTests\Core\Entity

Code

public function testPrimaryKeyUpdate($entity_type_id, $field_name) {
    // EntityKernelTestBase::setUp() already installs the schema for the
    // 'entity_test' entity type.
    if ($entity_type_id !== 'entity_test') {
        $this->installEntitySchema($entity_type_id);
    }
    
    /* @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface $update_manager */
    $update_manager = $this->container
        ->get('entity.definition_update_manager');
    $entity_type = $update_manager->getEntityType($entity_type_id);
    
    /* @see \Drupal\Core\Entity\ContentEntityBase::baseFieldDefinitions() */
    switch ($field_name) {
        case 'id':
            $field = BaseFieldDefinition::create('integer')->setLabel('ID')
                ->setReadOnly(TRUE)
                ->setSetting('unsigned', TRUE);
            break;
        case 'revision_id':
            $field = BaseFieldDefinition::create('integer')->setLabel('Revision ID')
                ->setReadOnly(TRUE)
                ->setSetting('unsigned', TRUE);
            break;
        case 'langcode':
            $field = BaseFieldDefinition::create('language')->setLabel('Language');
            if ($entity_type->isRevisionable()) {
                $field->setRevisionable(TRUE);
            }
            if ($entity_type->isTranslatable()) {
                $field->setTranslatable(TRUE);
            }
            break;
    }
    $field->setName($field_name)
        ->setTargetEntityTypeId($entity_type_id)
        ->setProvider($entity_type->getProvider());
    // Build up a map of expected primary keys depending on the entity type
    // configuration.
    $id_key = $entity_type->getKey('id');
    $revision_key = $entity_type->getKey('revision');
    $langcode_key = $entity_type->getKey('langcode');
    $expected = [];
    $expected[$entity_type->getBaseTable()] = [
        $id_key,
    ];
    if ($entity_type->isRevisionable()) {
        $expected[$entity_type->getRevisionTable()] = [
            $revision_key,
        ];
    }
    if ($entity_type->isTranslatable()) {
        $expected[$entity_type->getDataTable()] = [
            $id_key,
            $langcode_key,
        ];
    }
    if ($entity_type->isRevisionable() && $entity_type->isTranslatable()) {
        $expected[$entity_type->getRevisionDataTable()] = [
            $revision_key,
            $langcode_key,
        ];
    }
    // First, test explicitly deleting and re-installing a field. Make sure that
    // all primary keys are there to start with.
    $this->assertSame($expected, $this->findPrimaryKeys($entity_type));
    // Then uninstall the field and make sure all primary keys that the field
    // was part of have been updated. Since this is not a valid state of the
    // entity type (for example a revisionable entity type without a revision ID
    // field or a translatable entity type without a language code field) the
    // actual primary keys at this point are irrelevant.
    $update_manager->uninstallFieldStorageDefinition($field);
    $this->assertNotEquals($expected, $this->findPrimaryKeys($entity_type));
    // Finally, reinstall the field and make sure the primary keys have been
    // recreated.
    $update_manager->installFieldStorageDefinition($field->getName(), $entity_type_id, $field->getProvider(), $field);
    $this->assertSame($expected, $this->findPrimaryKeys($entity_type));
    // Now test updating a field without data. This will end up deleting
    // and re-creating the field, similar to the code above.
    $update_manager->updateFieldStorageDefinition($field);
    $this->assertSame($expected, $this->findPrimaryKeys($entity_type));
    // Now test updating a field with data.
    
    /* @var \Drupal\Core\Entity\FieldableEntityStorageInterface $storage */
    $storage = $this->entityTypeManager
        ->getStorage($entity_type_id);
    // The schema of ID fields is incorrectly recreated as 'int' instead of
    // 'serial', so we manually have to specify an ID.
    // @todo Remove this in https://www.drupal.org/project/drupal/issues/2928906
    $storage->create([
        'id' => 1,
        'revision_id' => 1,
    ])
        ->save();
    $this->assertTrue($storage->countFieldData($field, TRUE));
    $update_manager->updateFieldStorageDefinition($field);
    $this->assertSame($expected, $this->findPrimaryKeys($entity_type));
    $this->assertTrue($storage->countFieldData($field, TRUE));
}

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