View source
<?php
namespace Drupal\Tests\Core\Entity\Sql;
use Drupal\Core\Entity\ContentEntityType;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\Sql\DefaultTableMapping;
use Drupal\Tests\UnitTestCase;
class SqlContentEntityStorageSchemaTest extends UnitTestCase {
protected $dbSchemaHandler;
protected $entityManager;
protected $entityType;
protected $storage;
protected $storageDefinitions;
protected $storageSchema;
protected function setUp() {
$this->entityManager = $this
->getMock('Drupal\\Core\\Entity\\EntityManagerInterface');
$this->storage = $this
->getMockBuilder('Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage')
->disableOriginalConstructor()
->getMock();
$this->storage
->expects($this
->any())
->method('getBaseTable')
->will($this
->returnValue('entity_test'));
$this
->setUpStorageDefinition('id', array(
'columns' => array(
'value' => array(
'type' => 'int',
),
),
));
}
public function testGetSchemaBase() {
$this->entityType = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array(
'id' => 'id',
),
));
$this
->setUpStorageDefinition('name', array(
'columns' => array(
'value' => array(
'type' => 'varchar',
'length' => 255,
),
),
));
$this
->setUpStorageDefinition('description', array(
'columns' => array(
'value' => array(
'type' => 'text',
),
'format' => array(
'type' => 'varchar',
),
),
));
$this
->setUpStorageDefinition('uuid', array(
'columns' => array(
'value' => array(
'type' => 'varchar',
'length' => 128,
),
),
'unique keys' => array(
'value' => array(
'value',
),
),
));
$this
->setUpStorageDefinition('hash', array(
'columns' => array(
'value' => array(
'type' => 'varchar',
'length' => 20,
),
),
'unique keys' => array(
'value' => array(
array(
'value',
10,
),
),
),
));
$this
->setUpStorageDefinition('email', array(
'columns' => array(
'username' => array(
'type' => 'varchar',
),
'hostname' => array(
'type' => 'varchar',
),
'domain' => array(
'type' => 'varchar',
),
),
'unique keys' => array(
'email' => array(
'username',
'hostname',
array(
'domain',
3,
),
),
),
));
$this
->setUpStorageDefinition('owner', array(
'columns' => array(
'target_id' => array(
'type' => 'int',
),
),
'indexes' => array(
'target_id' => array(
'target_id',
),
),
));
$this
->setUpStorageDefinition('translator', array(
'columns' => array(
'target_id' => array(
'type' => 'int',
),
),
'indexes' => array(
'target_id' => array(
array(
'target_id',
10,
),
),
),
));
$this
->setUpStorageDefinition('location', array(
'columns' => array(
'country' => array(
'type' => 'varchar',
),
'state' => array(
'type' => 'varchar',
),
'city' => array(
'type' => 'varchar',
),
),
'indexes' => array(
'country_state_city' => array(
'country',
'state',
array(
'city',
10,
),
),
),
));
$this
->setUpStorageDefinition('editor', array(
'columns' => array(
'target_id' => array(
'type' => 'int',
),
),
'foreign keys' => array(
'user_id' => array(
'table' => 'users',
'columns' => array(
'target_id' => 'uid',
),
),
),
));
$this
->setUpStorageDefinition('editor_revision', array(
'columns' => array(
'target_id' => array(
'type' => 'int',
),
'target_revision_id' => array(
'type' => 'int',
),
),
'foreign keys' => array(
'user_id' => array(
'table' => 'users',
'columns' => array(
'target_id' => 'uid',
),
),
),
));
$this
->setUpStorageDefinition('long_index_name', array(
'columns' => array(
'long_index_name' => array(
'type' => 'int',
),
),
'indexes' => array(
'long_index_name_really_long_long_name' => array(
array(
'long_index_name',
10,
),
),
),
));
$expected = array(
'entity_test' => array(
'description' => 'The base table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'serial',
'not null' => TRUE,
),
'name' => array(
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
),
'description__value' => array(
'type' => 'text',
'not null' => FALSE,
),
'description__format' => array(
'type' => 'varchar',
'not null' => FALSE,
),
'uuid' => array(
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'hash' => array(
'type' => 'varchar',
'length' => 20,
'not null' => FALSE,
),
'email__username' => array(
'type' => 'varchar',
'not null' => FALSE,
),
'email__hostname' => array(
'type' => 'varchar',
'not null' => FALSE,
),
'email__domain' => array(
'type' => 'varchar',
'not null' => FALSE,
),
'owner' => array(
'type' => 'int',
'not null' => FALSE,
),
'translator' => array(
'type' => 'int',
'not null' => FALSE,
),
'location__country' => array(
'type' => 'varchar',
'not null' => FALSE,
),
'location__state' => array(
'type' => 'varchar',
'not null' => FALSE,
),
'location__city' => array(
'type' => 'varchar',
'not null' => FALSE,
),
'editor' => array(
'type' => 'int',
'not null' => FALSE,
),
'editor_revision__target_id' => array(
'type' => 'int',
'not null' => FALSE,
),
'editor_revision__target_revision_id' => array(
'type' => 'int',
'not null' => FALSE,
),
'long_index_name' => array(
'type' => 'int',
'not null' => FALSE,
),
),
'primary key' => array(
'id',
),
'unique keys' => array(
'entity_test_field__uuid__value' => array(
'uuid',
),
'entity_test_field__hash__value' => array(
array(
'hash',
10,
),
),
'entity_test_field__email__email' => array(
'email__username',
'email__hostname',
array(
'email__domain',
3,
),
),
),
'indexes' => array(
'entity_test_field__owner__target_id' => array(
'owner',
),
'entity_test_field__translator__target_id' => array(
array(
'translator',
10,
),
),
'entity_test_field__location__country_state_city' => array(
'location__country',
'location__state',
array(
'location__city',
10,
),
),
'entity_test__b588603cb9' => array(
array(
'long_index_name',
10,
),
),
),
'foreign keys' => array(
'entity_test_field__editor__user_id' => array(
'table' => 'users',
'columns' => array(
'editor' => 'uid',
),
),
'entity_test_field__editor_revision__user_id' => array(
'table' => 'users',
'columns' => array(
'editor_revision__target_id' => 'uid',
),
),
),
),
);
$this
->setUpStorageSchema($expected);
$table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
$table_mapping
->setFieldNames('entity_test', array_keys($this->storageDefinitions));
$table_mapping
->setExtraColumns('entity_test', array(
'default_langcode',
));
$this->storage
->expects($this
->any())
->method('getTableMapping')
->will($this
->returnValue($table_mapping));
$this
->assertNull($this->storageSchema
->onEntityTypeCreate($this->entityType));
}
public function testGetSchemaRevisionable() {
$this->entityType = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array(
'id' => 'id',
'revision' => 'revision_id',
),
));
$this->storage
->expects($this
->exactly(2))
->method('getRevisionTable')
->will($this
->returnValue('entity_test_revision'));
$this
->setUpStorageDefinition('revision_id', array(
'columns' => array(
'value' => array(
'type' => 'int',
),
),
));
$expected = array(
'entity_test' => array(
'description' => 'The base table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'serial',
'not null' => TRUE,
),
'revision_id' => array(
'type' => 'int',
'not null' => FALSE,
),
),
'primary key' => array(
'id',
),
'unique keys' => array(
'entity_test__revision_id' => array(
'revision_id',
),
),
'indexes' => array(),
'foreign keys' => array(
'entity_test__revision' => array(
'table' => 'entity_test_revision',
'columns' => array(
'revision_id' => 'revision_id',
),
),
),
),
'entity_test_revision' => array(
'description' => 'The revision table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'int',
'not null' => TRUE,
),
'revision_id' => array(
'type' => 'serial',
'not null' => TRUE,
),
),
'primary key' => array(
'revision_id',
),
'unique keys' => array(),
'indexes' => array(
'entity_test__id' => array(
'id',
),
),
'foreign keys' => array(
'entity_test__revisioned' => array(
'table' => 'entity_test',
'columns' => array(
'id' => 'id',
),
),
),
),
);
$this
->setUpStorageSchema($expected);
$table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
$table_mapping
->setFieldNames('entity_test', array_keys($this->storageDefinitions));
$table_mapping
->setFieldNames('entity_test_revision', array_keys($this->storageDefinitions));
$this->storage
->expects($this
->any())
->method('getTableMapping')
->will($this
->returnValue($table_mapping));
$this->storageSchema
->onEntityTypeCreate($this->entityType);
}
public function testGetSchemaTranslatable() {
$this->entityType = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array(
'id' => 'id',
'langcode' => 'langcode',
),
));
$this->storage
->expects($this
->any())
->method('getDataTable')
->will($this
->returnValue('entity_test_field_data'));
$this
->setUpStorageDefinition('langcode', array(
'columns' => array(
'value' => array(
'type' => 'varchar',
),
),
));
$this
->setUpStorageDefinition('default_langcode', array(
'columns' => array(
'value' => array(
'type' => 'int',
'size' => 'tiny',
),
),
));
$expected = array(
'entity_test' => array(
'description' => 'The base table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'serial',
'not null' => TRUE,
),
'langcode' => array(
'type' => 'varchar',
'not null' => TRUE,
),
),
'primary key' => array(
'id',
),
'unique keys' => array(),
'indexes' => array(),
'foreign keys' => array(),
),
'entity_test_field_data' => array(
'description' => 'The data table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'int',
'not null' => TRUE,
),
'langcode' => array(
'type' => 'varchar',
'not null' => TRUE,
),
'default_langcode' => array(
'type' => 'int',
'size' => 'tiny',
'not null' => true,
),
),
'primary key' => array(
'id',
'langcode',
),
'unique keys' => array(),
'indexes' => array(
'entity_test__id__default_langcode__langcode' => array(
0 => 'id',
1 => 'default_langcode',
2 => 'langcode',
),
),
'foreign keys' => array(
'entity_test' => array(
'table' => 'entity_test',
'columns' => array(
'id' => 'id',
),
),
),
),
);
$this
->setUpStorageSchema($expected);
$table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
$non_data_fields = array_keys($this->storageDefinitions);
unset($non_data_fields[array_search('default_langcode', $non_data_fields)]);
$table_mapping
->setFieldNames('entity_test', $non_data_fields);
$table_mapping
->setFieldNames('entity_test_field_data', array_keys($this->storageDefinitions));
$this->storage
->expects($this
->any())
->method('getTableMapping')
->will($this
->returnValue($table_mapping));
$this
->assertNull($this->storageSchema
->onEntityTypeCreate($this->entityType));
}
public function testGetSchemaRevisionableTranslatable() {
$this->entityType = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array(
'id' => 'id',
'revision' => 'revision_id',
'langcode' => 'langcode',
),
));
$this->storage
->expects($this
->exactly(3))
->method('getRevisionTable')
->will($this
->returnValue('entity_test_revision'));
$this->storage
->expects($this
->once())
->method('getDataTable')
->will($this
->returnValue('entity_test_field_data'));
$this->storage
->expects($this
->once())
->method('getRevisionDataTable')
->will($this
->returnValue('entity_test_revision_field_data'));
$this
->setUpStorageDefinition('revision_id', array(
'columns' => array(
'value' => array(
'type' => 'int',
),
),
));
$this
->setUpStorageDefinition('langcode', array(
'columns' => array(
'value' => array(
'type' => 'varchar',
),
),
));
$this
->setUpStorageDefinition('default_langcode', array(
'columns' => array(
'value' => array(
'type' => 'int',
'size' => 'tiny',
),
),
));
$expected = array(
'entity_test' => array(
'description' => 'The base table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'serial',
'not null' => TRUE,
),
'revision_id' => array(
'type' => 'int',
'not null' => FALSE,
),
'langcode' => array(
'type' => 'varchar',
'not null' => TRUE,
),
),
'primary key' => array(
'id',
),
'unique keys' => array(
'entity_test__revision_id' => array(
'revision_id',
),
),
'indexes' => array(),
'foreign keys' => array(
'entity_test__revision' => array(
'table' => 'entity_test_revision',
'columns' => array(
'revision_id' => 'revision_id',
),
),
),
),
'entity_test_revision' => array(
'description' => 'The revision table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'int',
'not null' => TRUE,
),
'revision_id' => array(
'type' => 'serial',
'not null' => TRUE,
),
'langcode' => array(
'type' => 'varchar',
'not null' => TRUE,
),
),
'primary key' => array(
'revision_id',
),
'unique keys' => array(),
'indexes' => array(
'entity_test__id' => array(
'id',
),
),
'foreign keys' => array(
'entity_test__revisioned' => array(
'table' => 'entity_test',
'columns' => array(
'id' => 'id',
),
),
),
),
'entity_test_field_data' => array(
'description' => 'The data table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'int',
'not null' => TRUE,
),
'revision_id' => array(
'type' => 'int',
'not null' => TRUE,
),
'langcode' => array(
'type' => 'varchar',
'not null' => TRUE,
),
'default_langcode' => array(
'type' => 'int',
'size' => 'tiny',
'not null' => true,
),
),
'primary key' => array(
'id',
'langcode',
),
'unique keys' => array(),
'indexes' => array(
'entity_test__revision_id' => array(
'revision_id',
),
'entity_test__id__default_langcode__langcode' => array(
0 => 'id',
1 => 'default_langcode',
2 => 'langcode',
),
),
'foreign keys' => array(
'entity_test' => array(
'table' => 'entity_test',
'columns' => array(
'id' => 'id',
),
),
),
),
'entity_test_revision_field_data' => array(
'description' => 'The revision data table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'int',
'not null' => TRUE,
),
'revision_id' => array(
'type' => 'int',
'not null' => TRUE,
),
'langcode' => array(
'type' => 'varchar',
'not null' => TRUE,
),
'default_langcode' => array(
'type' => 'int',
'size' => 'tiny',
'not null' => true,
),
),
'primary key' => array(
'revision_id',
'langcode',
),
'unique keys' => array(),
'indexes' => array(
'entity_test__id__default_langcode__langcode' => array(
0 => 'id',
1 => 'default_langcode',
2 => 'langcode',
),
),
'foreign keys' => array(
'entity_test' => array(
'table' => 'entity_test',
'columns' => array(
'id' => 'id',
),
),
'entity_test__revision' => array(
'table' => 'entity_test_revision',
'columns' => array(
'revision_id' => 'revision_id',
),
),
),
),
);
$this
->setUpStorageSchema($expected);
$table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
$non_data_fields = array_keys($this->storageDefinitions);
unset($non_data_fields[array_search('default_langcode', $non_data_fields)]);
$table_mapping
->setFieldNames('entity_test', $non_data_fields);
$table_mapping
->setFieldNames('entity_test_revision', $non_data_fields);
$table_mapping
->setFieldNames('entity_test_field_data', array_keys($this->storageDefinitions));
$table_mapping
->setFieldNames('entity_test_revision_field_data', array_keys($this->storageDefinitions));
$this->storage
->expects($this
->any())
->method('getTableMapping')
->will($this
->returnValue($table_mapping));
$this->storageSchema
->onEntityTypeCreate($this->entityType);
}
public function testDedicatedTableSchema() {
$entity_type_id = 'entity_test';
$this->entityType = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array(
'id' => 'id',
),
));
$field_name = $this
->getRandomGenerator()
->name();
$this
->setUpStorageDefinition($field_name, array(
'columns' => array(
'shape' => array(
'type' => 'varchar',
'length' => 32,
'not null' => FALSE,
),
'color' => array(
'type' => 'varchar',
'length' => 32,
'not null' => FALSE,
),
),
'foreign keys' => array(
'color' => array(
'table' => 'color',
'columns' => array(
'color' => 'id',
),
),
),
'unique keys' => array(),
'indexes' => array(),
));
$field_storage = $this->storageDefinitions[$field_name];
$field_storage
->expects($this
->any())
->method('getType')
->will($this
->returnValue('shape'));
$field_storage
->expects($this
->any())
->method('getTargetEntityTypeId')
->will($this
->returnValue($entity_type_id));
$field_storage
->expects($this
->any())
->method('isMultiple')
->will($this
->returnValue(TRUE));
$this->storageDefinitions['id']
->expects($this
->any())
->method('getType')
->will($this
->returnValue('integer'));
$expected = array(
$entity_type_id . '__' . $field_name => array(
'description' => "Data storage for {$entity_type_id} field {$field_name}.",
'fields' => array(
'bundle' => array(
'type' => 'varchar_ascii',
'length' => 128,
'not null' => true,
'default' => '',
'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance',
),
'deleted' => array(
'type' => 'int',
'size' => 'tiny',
'not null' => true,
'default' => 0,
'description' => 'A boolean indicating whether this data item has been deleted',
),
'entity_id' => array(
'type' => 'int',
'unsigned' => true,
'not null' => true,
'description' => 'The entity id this data is attached to',
),
'revision_id' => array(
'type' => 'int',
'unsigned' => true,
'not null' => true,
'description' => 'The entity revision id this data is attached to, which for an unversioned entity type is the same as the entity id',
),
'langcode' => array(
'type' => 'varchar_ascii',
'length' => 32,
'not null' => true,
'default' => '',
'description' => 'The language code for this data item.',
),
'delta' => array(
'type' => 'int',
'unsigned' => true,
'not null' => true,
'description' => 'The sequence number for this data item, used for multi-value fields',
),
$field_name . '_shape' => array(
'type' => 'varchar',
'length' => 32,
'not null' => false,
),
$field_name . '_color' => array(
'type' => 'varchar',
'length' => 32,
'not null' => false,
),
),
'primary key' => array(
'entity_id',
'deleted',
'delta',
'langcode',
),
'indexes' => array(
'bundle' => array(
'bundle',
),
'revision_id' => array(
'revision_id',
),
),
'foreign keys' => array(
$field_name . '_color' => array(
'table' => 'color',
'columns' => array(
$field_name . '_color' => 'id',
),
),
),
),
);
$this
->setUpStorageSchema($expected);
$table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
$table_mapping
->setFieldNames($entity_type_id, array_keys($this->storageDefinitions));
$table_mapping
->setExtraColumns($entity_type_id, array(
'default_langcode',
));
$this->storage
->expects($this
->any())
->method('getTableMapping')
->will($this
->returnValue($table_mapping));
$this
->assertNull($this->storageSchema
->onFieldStorageDefinitionCreate($field_storage));
}
public function testDedicatedTableSchemaForEntityWithStringIdentifier() {
$entity_type_id = 'entity_test';
$this->entityType = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array(
'id' => 'id',
),
));
$field_name = $this
->getRandomGenerator()
->name();
$this
->setUpStorageDefinition($field_name, array(
'columns' => array(
'shape' => array(
'type' => 'varchar',
'length' => 32,
'not null' => FALSE,
),
'color' => array(
'type' => 'varchar',
'length' => 32,
'not null' => FALSE,
),
),
'foreign keys' => array(
'color' => array(
'table' => 'color',
'columns' => array(
'color' => 'id',
),
),
),
'unique keys' => array(),
'indexes' => array(),
));
$field_storage = $this->storageDefinitions[$field_name];
$field_storage
->expects($this
->any())
->method('getType')
->will($this
->returnValue('shape'));
$field_storage
->expects($this
->any())
->method('getTargetEntityTypeId')
->will($this
->returnValue($entity_type_id));
$field_storage
->expects($this
->any())
->method('isMultiple')
->will($this
->returnValue(TRUE));
$this->storageDefinitions['id']
->expects($this
->any())
->method('getType')
->will($this
->returnValue('string'));
$expected = array(
$entity_type_id . '__' . $field_name => array(
'description' => "Data storage for {$entity_type_id} field {$field_name}.",
'fields' => array(
'bundle' => array(
'type' => 'varchar_ascii',
'length' => 128,
'not null' => true,
'default' => '',
'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance',
),
'deleted' => array(
'type' => 'int',
'size' => 'tiny',
'not null' => true,
'default' => 0,
'description' => 'A boolean indicating whether this data item has been deleted',
),
'entity_id' => array(
'type' => 'varchar_ascii',
'length' => 128,
'not null' => true,
'description' => 'The entity id this data is attached to',
),
'revision_id' => array(
'type' => 'varchar_ascii',
'length' => 128,
'not null' => true,
'description' => 'The entity revision id this data is attached to, which for an unversioned entity type is the same as the entity id',
),
'langcode' => array(
'type' => 'varchar_ascii',
'length' => 32,
'not null' => true,
'default' => '',
'description' => 'The language code for this data item.',
),
'delta' => array(
'type' => 'int',
'unsigned' => true,
'not null' => true,
'description' => 'The sequence number for this data item, used for multi-value fields',
),
$field_name . '_shape' => array(
'type' => 'varchar',
'length' => 32,
'not null' => false,
),
$field_name . '_color' => array(
'type' => 'varchar',
'length' => 32,
'not null' => false,
),
),
'primary key' => array(
'entity_id',
'deleted',
'delta',
'langcode',
),
'indexes' => array(
'bundle' => array(
'bundle',
),
'revision_id' => array(
'revision_id',
),
),
'foreign keys' => array(
$field_name . '_color' => array(
'table' => 'color',
'columns' => array(
$field_name . '_color' => 'id',
),
),
),
),
);
$this
->setUpStorageSchema($expected);
$table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
$table_mapping
->setFieldNames($entity_type_id, array_keys($this->storageDefinitions));
$table_mapping
->setExtraColumns($entity_type_id, array(
'default_langcode',
));
$this->storage
->expects($this
->any())
->method('getTableMapping')
->will($this
->returnValue($table_mapping));
$this
->assertNull($this->storageSchema
->onFieldStorageDefinitionCreate($field_storage));
}
public function providerTestRequiresEntityDataMigration() {
$updated_entity_type_definition = $this
->getMock('\\Drupal\\Core\\Entity\\EntityTypeInterface');
$updated_entity_type_definition
->expects($this
->any())
->method('getStorageClass')
->willReturn('\\Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorageSchema');
$original_entity_type_definition = $this
->getMock('\\Drupal\\Core\\Entity\\EntityTypeInterface');
$original_entity_type_definition
->expects($this
->any())
->method('getStorageClass')
->willReturn('\\Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorageSchema');
$original_entity_type_definition_other_nonexisting = $this
->getMock('\\Drupal\\Core\\Entity\\EntityTypeInterface');
$original_entity_type_definition_other_nonexisting
->expects($this
->any())
->method('getStorageClass')
->willReturn('bar');
$original_entity_type_definition_other_existing = $this
->getMock('\\Drupal\\Core\\Entity\\EntityTypeInterface');
$original_entity_type_definition_other_existing
->expects($this
->any())
->method('getStorageClass')
->willReturn('\\Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorageSchema');
return [
[
$updated_entity_type_definition,
$original_entity_type_definition,
TRUE,
TRUE,
TRUE,
],
[
$updated_entity_type_definition,
$original_entity_type_definition,
FALSE,
TRUE,
FALSE,
],
[
$updated_entity_type_definition,
$original_entity_type_definition_other_nonexisting,
NULL,
TRUE,
TRUE,
],
[
$updated_entity_type_definition,
$original_entity_type_definition_other_existing,
TRUE,
TRUE,
TRUE,
],
[
$updated_entity_type_definition,
$original_entity_type_definition_other_existing,
FALSE,
TRUE,
FALSE,
],
[
$updated_entity_type_definition,
$original_entity_type_definition,
TRUE,
FALSE,
FALSE,
],
[
$updated_entity_type_definition,
$original_entity_type_definition_other_existing,
TRUE,
FALSE,
FALSE,
],
];
}
public function testRequiresEntityDataMigration($updated_entity_type_definition, $original_entity_type_definition, $original_storage_has_data, $shared_table_structure_changed, $migration_required) {
$this->entityType = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array(
'id' => 'id',
),
));
$original_storage = $this
->getMockBuilder('Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorage')
->disableOriginalConstructor()
->getMock();
$original_storage
->expects($this
->exactly(is_null($original_storage_has_data) || !$shared_table_structure_changed ? 0 : 1))
->method('hasData')
->willReturn($original_storage_has_data);
$this->storage
->expects($this
->never())
->method('hasData');
$connection = $this
->getMockBuilder('Drupal\\Core\\Database\\Connection')
->disableOriginalConstructor()
->getMock();
$this->entityManager
->expects($this
->any())
->method('createHandlerInstance')
->willReturn($original_storage);
$this->storageSchema = $this
->getMockBuilder('Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorageSchema')
->setConstructorArgs(array(
$this->entityManager,
$this->entityType,
$this->storage,
$connection,
))
->setMethods(array(
'installedStorageSchema',
'hasSharedTableStructureChange',
))
->getMock();
$this->storageSchema
->expects($this
->any())
->method('hasSharedTableStructureChange')
->with($updated_entity_type_definition, $original_entity_type_definition)
->willReturn($shared_table_structure_changed);
$this
->assertEquals($migration_required, $this->storageSchema
->requiresEntityDataMigration($updated_entity_type_definition, $original_entity_type_definition));
}
public function providerTestRequiresEntityStorageSchemaChanges() {
$cases = [];
$updated_entity_type_definition = $this
->getMock('\\Drupal\\Core\\Entity\\ContentEntityTypeInterface');
$original_entity_type_definition = $this
->getMock('\\Drupal\\Core\\Entity\\ContentEntityTypeInterface');
$updated_entity_type_definition
->expects($this
->any())
->method('id')
->willReturn('entity_test');
$updated_entity_type_definition
->expects($this
->any())
->method('getKey')
->willReturn('id');
$original_entity_type_definition
->expects($this
->any())
->method('id')
->willReturn('entity_test');
$original_entity_type_definition
->expects($this
->any())
->method('getKey')
->willReturn('id');
$updated = clone $updated_entity_type_definition;
$original = clone $original_entity_type_definition;
$updated
->expects($this
->never())
->method('getStorageClass');
$original
->expects($this
->never())
->method('getStorageClass');
$cases[] = [
$updated,
$original,
FALSE,
FALSE,
FALSE,
];
$cases[] = [
$updated,
$original,
TRUE,
TRUE,
FALSE,
];
$cases[] = [
$updated,
$original,
TRUE,
FALSE,
TRUE,
];
$updated = clone $updated_entity_type_definition;
$updated
->expects($this
->once())
->method('isTranslatable')
->willReturn(FALSE);
$original = clone $original_entity_type_definition;
$original
->expects($this
->once())
->method('isTranslatable')
->willReturn(TRUE);
$cases[] = [
$updated,
$original,
TRUE,
FALSE,
FALSE,
];
$updated = clone $updated_entity_type_definition;
$updated
->expects($this
->once())
->method('isRevisionable')
->willReturn(FALSE);
$original = clone $original_entity_type_definition;
$original
->expects($this
->once())
->method('isRevisionable')
->willReturn(TRUE);
$cases[] = [
$updated,
$original,
TRUE,
FALSE,
FALSE,
];
return $cases;
}
public function testRequiresEntityStorageSchemaChanges(ContentEntityTypeInterface $updated, ContentEntityTypeInterface $original, $requires_change, $change_schema, $change_shared_table) {
$this->entityType = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array(
'id' => 'id',
),
));
$this
->setUpStorageSchema();
$table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
$table_mapping
->setFieldNames('entity_test', array_keys($this->storageDefinitions));
$table_mapping
->setExtraColumns('entity_test', array(
'default_langcode',
));
$this->storage
->expects($this
->any())
->method('getTableMapping')
->will($this
->returnValue($table_mapping));
if ($change_schema) {
$this->storageSchema
->expects($this
->once())
->method('loadEntitySchemaData')
->willReturn(array());
}
else {
$expected = [
'entity_test' => [
'primary key' => [
'id',
],
],
];
$this->storageSchema
->expects($this
->any())
->method('loadEntitySchemaData')
->willReturn($expected);
}
if ($change_shared_table) {
$this->storageSchema
->expects($this
->once())
->method('hasSharedTableNameChanges')
->willReturn(TRUE);
}
$this
->assertEquals($requires_change, $this->storageSchema
->requiresEntityStorageSchemaChanges($updated, $original));
}
protected function setUpStorageSchema(array $expected = array()) {
$this->entityManager
->expects($this
->any())
->method('getDefinition')
->with($this->entityType
->id())
->will($this
->returnValue($this->entityType));
$this->entityManager
->expects($this
->any())
->method('getFieldStorageDefinitions')
->with($this->entityType
->id())
->will($this
->returnValue($this->storageDefinitions));
$this->dbSchemaHandler = $this
->getMockBuilder('Drupal\\Core\\Database\\Schema')
->disableOriginalConstructor()
->getMock();
if ($expected) {
$invocation_count = 0;
$expected_table_names = array_keys($expected);
$expected_table_schemas = array_values($expected);
$this->dbSchemaHandler
->expects($this
->any())
->method('createTable')
->with($this
->callback(function ($table_name) use (&$invocation_count, $expected_table_names) {
return $expected_table_names[$invocation_count] == $table_name;
}), $this
->callback(function ($table_schema) use (&$invocation_count, $expected_table_schemas) {
return $expected_table_schemas[$invocation_count] == $table_schema;
}))
->will($this
->returnCallback(function () use (&$invocation_count) {
$invocation_count++;
}));
}
$connection = $this
->getMockBuilder('Drupal\\Core\\Database\\Connection')
->disableOriginalConstructor()
->getMock();
$connection
->expects($this
->any())
->method('schema')
->will($this
->returnValue($this->dbSchemaHandler));
$key_value = $this
->getMock('Drupal\\Core\\KeyValueStore\\KeyValueStoreInterface');
$this->storageSchema = $this
->getMockBuilder('Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorageSchema')
->setConstructorArgs(array(
$this->entityManager,
$this->entityType,
$this->storage,
$connection,
))
->setMethods(array(
'installedStorageSchema',
'loadEntitySchemaData',
'hasSharedTableNameChanges',
'isTableEmpty',
))
->getMock();
$this->storageSchema
->expects($this
->any())
->method('installedStorageSchema')
->will($this
->returnValue($key_value));
$this->storageSchema
->expects($this
->any())
->method('isTableEmpty')
->willReturn(FALSE);
}
public function setUpStorageDefinition($field_name, array $schema) {
$this->storageDefinitions[$field_name] = $this
->getMock('Drupal\\Tests\\Core\\Field\\TestBaseFieldDefinitionInterface');
$this->storageDefinitions[$field_name]
->expects($this
->any())
->method('isBaseField')
->will($this
->returnValue(TRUE));
$this->storageDefinitions[$field_name]
->expects($this
->any())
->method('getName')
->will($this
->returnValue($field_name));
$this->storageDefinitions[$field_name]
->expects($this
->any())
->method('getSchema')
->will($this
->returnValue($schema));
$this->storageDefinitions[$field_name]
->expects($this
->any())
->method('getColumns')
->will($this
->returnValue($schema['columns']));
if (!empty($schema['columns'])) {
$property_definitions = array();
foreach ($schema['columns'] as $column => $info) {
$property_definitions[$column] = $this
->getMock('Drupal\\Core\\TypedData\\DataDefinitionInterface');
$property_definitions[$column]
->expects($this
->any())
->method('isRequired')
->will($this
->returnValue(!empty($info['not null'])));
}
$this->storageDefinitions[$field_name]
->expects($this
->any())
->method('getPropertyDefinitions')
->will($this
->returnValue($property_definitions));
}
}
public function testonEntityTypeUpdateWithNewIndex() {
$this->entityType = $original_entity_type = new ContentEntityType(array(
'id' => 'entity_test',
'entity_keys' => array(
'id' => 'id',
),
));
$this
->setUpStorageDefinition('long_index_name', array(
'columns' => array(
'long_index_name' => array(
'type' => 'int',
),
),
'indexes' => array(
'long_index_name_really_long_long_name' => array(
array(
'long_index_name',
10,
),
),
),
));
$expected = array(
'entity_test' => array(
'description' => 'The base table for entity_test entities.',
'fields' => array(
'id' => array(
'type' => 'serial',
'not null' => TRUE,
),
'long_index_name' => array(
'type' => 'int',
'not null' => FALSE,
),
),
'indexes' => array(
'entity_test__b588603cb9' => array(
array(
'long_index_name',
10,
),
),
),
),
);
$this
->setUpStorageSchema($expected);
$table_mapping = new DefaultTableMapping($this->entityType, $this->storageDefinitions);
$table_mapping
->setFieldNames('entity_test', array_keys($this->storageDefinitions));
$table_mapping
->setExtraColumns('entity_test', array(
'default_langcode',
));
$this->storage
->expects($this
->any())
->method('getTableMapping')
->will($this
->returnValue($table_mapping));
$this->storageSchema
->expects($this
->any())
->method('loadEntitySchemaData')
->willReturn([
'entity_test' => [
'indexes' => [
'entity_test__b588603cb9' => [
'longer_index_name',
],
'entity_test__removed_field' => [
'removed_field',
],
],
],
]);
$this->dbSchemaHandler
->expects($this
->at(0))
->method('dropIndex')
->with('entity_test', 'entity_test__b588603cb9');
$this->dbSchemaHandler
->expects($this
->at(1))
->method('dropIndex')
->with('entity_test', 'entity_test__removed_field');
$this->dbSchemaHandler
->expects($this
->atLeastOnce())
->method('fieldExists')
->willReturn(TRUE);
$this->dbSchemaHandler
->expects($this
->atLeastOnce())
->method('addIndex')
->with('entity_test', 'entity_test__b588603cb9', [
[
'long_index_name',
10,
],
], $this
->callback(function ($actual_value) use ($expected) {
$this
->assertEquals($expected['entity_test']['indexes'], $actual_value['indexes']);
$this
->assertEquals($expected['entity_test']['fields'], $actual_value['fields']);
return TRUE;
}));
$this
->assertNull($this->storageSchema
->onEntityTypeUpdate($this->entityType, $original_entity_type));
}
}