diff --git a/core/modules/views/tests/src/Kernel/Entity/EntityViewsDataTest.php b/core/modules/views/tests/src/Kernel/Entity/EntityViewsDataTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6bab4cfdbdec1756c16a56aa2bf30df6f42f098a --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Entity/EntityViewsDataTest.php @@ -0,0 +1,821 @@ +<?php + +namespace Drupal\Tests\views\Kernel\Entity; + +use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Config\Entity\ConfigEntityBase; +use Drupal\Core\Config\Entity\ConfigEntityType; +use Drupal\Core\Entity\ContentEntityBase; +use Drupal\Core\Entity\ContentEntityType; +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\KernelTests\KernelTestBase; +use Drupal\views\EntityViewsData; + +/** + * Tests entity views data. + * + * @coversDefaultClass \Drupal\views\EntityViewsData + * @group views + */ +class EntityViewsDataTest extends KernelTestBase { + + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * The base entity type definition, which some tests modify. + * + * Uses a custom class which allows changing entity keys. + * + * @var \Drupal\Tests\views\Kernel\Entity\TestEntityType + */ + protected $baseEntityType; + + /** + * The common base fields for test entity types. + * + * @var \Drupal\Core\Field\BaseFieldDefinition[] + */ + protected $commonBaseFields; + + /** + * Modules to enable. + * + * @var array + */ + protected static $modules = [ + 'user', + 'system', + 'field', + 'text', + 'filter', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $this->entityTypeManager = $this->container->get('entity_type.manager'); + + // A common entity type definition. Tests may change this prior to passing + // it to setUpEntityType(). + $this->baseEntityType = new TestEntityType([ + // A normal entity type would have its class picked up during discovery, + // but as we're mocking this without an annotation we have to specify it. + 'class' => ViewsTestEntity::class, + 'base_table' => 'entity_test', + 'id' => 'entity_test', + 'label' => 'Entity test', + 'entity_keys' => [ + 'uuid' => 'uuid', + 'id' => 'id', + 'langcode' => 'langcode', + 'bundle' => 'type', + 'revision' => 'revision_id', + ], + 'handlers' => [ + 'views_data' => EntityViewsData::class, + ], + 'provider' => 'entity_test', + 'list_cache_contexts' => ['entity_test_list_cache_context'], + ]); + + // Base fields for the test entity types. + $this->commonBaseFields['name'] = BaseFieldDefinition::create('string') + ->setLabel(t('Name')) + ->setDescription(t('The name of the test entity.')) + ->setTranslatable(TRUE) + ->setSetting('max_length', 32); + + $this->commonBaseFields['created'] = BaseFieldDefinition::create('created') + ->setLabel(t('Authored on')) + ->setDescription(t('Time the entity was created')) + ->setTranslatable(TRUE); + + $this->commonBaseFields['user_id'] = BaseFieldDefinition::create('entity_reference') + ->setLabel(t('User ID')) + ->setDescription(t('The ID of the associated user.')) + ->setSetting('target_type', 'user') + ->setSetting('handler', 'default') + // Default EntityTest entities to have the root user as the owner, to + // simplify testing. + ->setDefaultValue([0 => ['target_id' => 1]]) + ->setTranslatable(TRUE); + + // Add a description field. This example comes from the taxonomy Term + // entity. + $this->commonBaseFields['description'] = BaseFieldDefinition::create('text_long') + ->setLabel('Description') + ->setDescription('A description of the term.') + ->setTranslatable(TRUE); + + // Add a URL field; this example is from the Comment entity. + $this->commonBaseFields['homepage'] = BaseFieldDefinition::create('uri') + ->setLabel('Homepage') + ->setDescription("The comment author's home page address.") + ->setTranslatable(TRUE) + ->setSetting('max_length', 255); + + // A base field with cardinality > 1 + $this->commonBaseFields['string'] = BaseFieldDefinition::create('string') + ->setLabel('Strong') + ->setTranslatable(TRUE) + ->setCardinality(2); + + // Set up the basic 'entity_test' entity type. This is used by several + // tests; others customize it and the base fields. + $this->setUpEntityType($this->baseEntityType, $this->commonBaseFields); + } + + /** + * Mocks an entity type and its base fields. + * + * This works by: + * - inserting the entity type definition into the entity type manager's cache + * - setting the base fields on the ViewsTestEntity class as a static property + * for its baseFieldsDefinitions() method to use. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $definition + * An entity type definition to add to the entity type manager. + * @param \Drupal\Core\Field\BaseFieldDefinition[] $base_fields + * An array of base field definitions + */ + protected function setUpEntityType(EntityTypeInterface $definition, array $base_fields = []) { + // Replace the cache backend in the entity type manager so it returns + // our test entity type in addition to the existing ones. + $definitions = $this->entityTypeManager->getDefinitions(); + $definitions[$definition->id()] = $definition; + + $cache_backend = $this->prophesize(CacheBackendInterface::class); + $cache_data = new \StdClass(); + $cache_data->data = $definitions; + $cache_backend->get('entity_type')->willReturn($cache_data); + $this->entityTypeManager->setCacheBackend($cache_backend->reveal(), 'entity_type', ['entity_types']); + $this->entityTypeManager->clearCachedDefinitions(); + + if ($base_fields) { + ViewsTestEntity::setMockedBaseFieldDefinitions($definition->id(), $base_fields); + } + } + + /** + * Tests base tables. + */ + public function testBaseTables() { + $data = $this->entityTypeManager->getHandler('entity_test', 'views_data')->getViewsData(); + + $this->assertEquals('entity_test', $data['entity_test']['table']['entity type']); + $this->assertEquals(FALSE, $data['entity_test']['table']['entity revision']); + $this->assertEquals('Entity test', $data['entity_test']['table']['group']); + $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); + + $this->assertEquals('id', $data['entity_test']['table']['base']['field']); + $this->assertEquals(['entity_test_list_cache_context'], $data['entity_test']['table']['base']['cache_contexts']); + $this->assertEquals('Entity test', $data['entity_test']['table']['base']['title']); + + // TODO: change these to assertArrayNotHasKey(). + $this->assertFalse(isset($data['entity_test']['table']['defaults'])); + + $this->assertFalse(isset($data['entity_test_mul_property_data'])); + $this->assertFalse(isset($data['revision_table'])); + $this->assertFalse(isset($data['revision_data_table'])); + } + + /** + * Tests data_table support. + */ + public function testDataTable() { + $entity_type = $this->baseEntityType + ->set('data_table', 'entity_test_mul_property_data') + ->set('id', 'entity_test_mul') + ->set('translatable', TRUE) + ->setKey('label', 'label'); + + $this->setUpEntityType($entity_type); + + // Tests the join definition between the base and the data table. + $data = $this->entityTypeManager->getHandler('entity_test_mul', 'views_data')->getViewsData(); + // TODO: change the base table in the entity type definition to match the + // changed entity ID. + $base_views_data = $data['entity_test']; + + // Ensure that the base table is set to the data table. + $this->assertEquals('id', $data['entity_test_mul_property_data']['table']['base']['field']); + $this->assertEquals('Entity test', $data['entity_test_mul_property_data']['table']['base']['title']); + $this->assertFalse(isset($data['entity_test']['table']['base'])); + + $this->assertEquals('entity_test_mul', $data['entity_test_mul_property_data']['table']['entity type']); + $this->assertEquals(FALSE, $data['entity_test_mul_property_data']['table']['entity revision']); + $this->assertEquals('Entity test', $data['entity_test_mul_property_data']['table']['group']); + $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); + $this->assertEquals(['field' => 'label', 'table' => 'entity_test_mul_property_data'], $data['entity_test_mul_property_data']['table']['base']['defaults']); + + // Ensure the join information is set up properly. + $this->assertCount(1, $base_views_data['table']['join']); + $this->assertEquals(['entity_test_mul_property_data' => ['left_field' => 'id', 'field' => 'id', 'type' => 'INNER']], $base_views_data['table']['join']); + $this->assertFalse(isset($data['revision_table'])); + $this->assertFalse(isset($data['revision_data_table'])); + } + + /** + * Tests revision table without data table support. + */ + public function testRevisionTableWithoutDataTable() { + $entity_type = $this->baseEntityType + ->set('revision_table', 'entity_test_mulrev_revision') + ->set('revision_data_table', NULL) + ->set('id', 'entity_test_mulrev') + ->setKey('revision', 'revision_id'); + + $this->setUpEntityType($entity_type); + + $data = $this->entityTypeManager->getHandler('entity_test_mulrev', 'views_data')->getViewsData(); + + $this->assertEquals('Entity test revisions', $data['entity_test_mulrev_revision']['table']['base']['title']); + $this->assertEquals('revision_id', $data['entity_test_mulrev_revision']['table']['base']['field']); + + $this->assertEquals(FALSE, $data['entity_test']['table']['entity revision']); + $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_revision']['table']['entity type']); + $this->assertEquals(TRUE, $data['entity_test_mulrev_revision']['table']['entity revision']); + $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_revision']['table']['entity type']); + $this->assertEquals(TRUE, $data['entity_test_mulrev_revision']['table']['entity revision']); + + $this->assertEquals('Entity test revision', $data['entity_test_mulrev_revision']['table']['group']); + $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); + + // Ensure the join information is set up properly. + // Tests the join definition between the base and the revision table. + $revision_data = $data['entity_test_mulrev_revision']; + $this->assertCount(1, $revision_data['table']['join']); + $this->assertEquals(['entity_test' => ['left_field' => 'revision_id', 'field' => 'revision_id', 'type' => 'INNER']], $revision_data['table']['join']); + $this->assertFalse(isset($data['data_table'])); + } + + /** + * Tests revision table with data table support. + */ + public function testRevisionTableWithRevisionDataTableAndDataTable() { + $entity_type = $this->baseEntityType + ->set('data_table', 'entity_test_mul_property_data') + ->set('revision_table', 'entity_test_mulrev_revision') + ->set('revision_data_table', 'entity_test_mulrev_property_revision') + ->set('id', 'entity_test_mulrev') + ->set('translatable', TRUE) + ->setKey('revision', 'revision_id'); + $this->setUpEntityType($entity_type); + + $data = $this->entityTypeManager->getHandler('entity_test_mulrev', 'views_data')->getViewsData(); + + $this->assertEquals('Entity test revisions', $data['entity_test_mulrev_property_revision']['table']['base']['title']); + $this->assertEquals('revision_id', $data['entity_test_mulrev_property_revision']['table']['base']['field']); + $this->assertFalse(isset($data['entity_test_mulrev_revision']['table']['base'])); + + $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_property_revision']['table']['entity type']); + $this->assertEquals('Entity test revision', $data['entity_test_mulrev_revision']['table']['group']); + $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); + + // Ensure the join information is set up properly. + // Tests the join definition between the base and the revision table. + $revision_field_data = $data['entity_test_mulrev_property_revision']; + $this->assertCount(1, $revision_field_data['table']['join']); + $this->assertEquals([ + 'entity_test_mul_property_data' => [ + 'left_field' => 'revision_id', + 'field' => 'revision_id', + 'type' => 'INNER', + ], + ], $revision_field_data['table']['join']); + + $revision_base_data = $data['entity_test_mulrev_revision']; + $this->assertCount(1, $revision_base_data['table']['join']); + $this->assertEquals([ + 'entity_test_mulrev_property_revision' => [ + 'left_field' => 'revision_id', + 'field' => 'revision_id', + 'type' => 'INNER', + ], + ], $revision_base_data['table']['join']); + + $this->assertFalse(isset($data['data_table'])); + } + + /** + * Tests revision table with data table support. + */ + public function testRevisionTableWithRevisionDataTable() { + $entity_type = $this->baseEntityType + ->set('revision_table', 'entity_test_mulrev_revision') + ->set('revision_data_table', 'entity_test_mulrev_property_revision') + ->set('id', 'entity_test_mulrev') + ->set('translatable', TRUE) + ->setKey('revision', 'revision_id'); + $this->setUpEntityType($entity_type); + + $data = $this->entityTypeManager->getHandler('entity_test_mulrev', 'views_data')->getViewsData(); + + $this->assertEquals('Entity test revisions', $data['entity_test_mulrev_property_revision']['table']['base']['title']); + $this->assertEquals('revision_id', $data['entity_test_mulrev_property_revision']['table']['base']['field']); + $this->assertFalse(isset($data['entity_test_mulrev_revision']['table']['base'])); + + $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_property_revision']['table']['entity type']); + $this->assertEquals('Entity test revision', $data['entity_test_mulrev_revision']['table']['group']); + $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); + + // Ensure the join information is set up properly. + // Tests the join definition between the base and the revision table. + $revision_field_data = $data['entity_test_mulrev_property_revision']; + $this->assertCount(1, $revision_field_data['table']['join']); + $this->assertEquals([ + 'entity_test_mulrev_field_data' => [ + 'left_field' => 'revision_id', + 'field' => 'revision_id', + 'type' => 'INNER', + ], + ], $revision_field_data['table']['join']); + + $revision_base_data = $data['entity_test_mulrev_revision']; + $this->assertCount(1, $revision_base_data['table']['join']); + $this->assertEquals([ + 'entity_test_mulrev_property_revision' => [ + 'left_field' => 'revision_id', + 'field' => 'revision_id', + 'type' => 'INNER', + ], + ], $revision_base_data['table']['join']); + $this->assertFalse(isset($data['data_table'])); + } + + /** + * Tests fields on the base table. + */ + public function testBaseTableFields() { + $data = $this->entityTypeManager->getHandler('entity_test', 'views_data')->getViewsData(); + + $this->assertNumericField($data['entity_test']['id']); + $this->assertViewsDataField($data['entity_test']['id'], 'id'); + $this->assertUuidField($data['entity_test']['uuid']); + $this->assertViewsDataField($data['entity_test']['uuid'], 'uuid'); + $this->assertStringField($data['entity_test']['type']); + $this->assertEquals('type', $data['entity_test']['type']['entity field']); + + $this->assertLanguageField($data['entity_test']['langcode']); + $this->assertViewsDataField($data['entity_test']['langcode'], 'langcode'); + $this->assertEquals('Original language', $data['entity_test']['langcode']['title']); + + $this->assertStringField($data['entity_test']['name']); + $this->assertViewsDataField($data['entity_test']['name'], 'name'); + + $this->assertLongTextField($data['entity_test'], 'description'); + $this->assertViewsDataField($data['entity_test']['description__value'], 'description'); + $this->assertViewsDataField($data['entity_test']['description__format'], 'description'); + + $this->assertUriField($data['entity_test']['homepage']); + $this->assertViewsDataField($data['entity_test']['homepage'], 'homepage'); + + $this->assertEntityReferenceField($data['entity_test']['user_id']); + $this->assertViewsDataField($data['entity_test']['user_id'], 'user_id'); + + $relationship = $data['entity_test']['user_id']['relationship']; + $this->assertEquals('users_field_data', $relationship['base']); + $this->assertEquals('uid', $relationship['base field']); + + // The string field name should be used as the 'entity field' but the actual + // field should reflect what the column mapping is using for multi-value + // base fields NOT just the field name. The actual column name returned from + // mappings in the test mocks is 'value'. + $this->assertStringField($data['entity_test__string']['string_value']); + $this->assertViewsDataField($data['entity_test__string']['string_value'], 'string'); + $this->assertEquals([ + 'left_field' => 'id', + 'field' => 'entity_id', + 'extra' => [[ + 'field' => 'deleted', + 'value' => 0, + 'numeric' => TRUE, + ], + ], + ], $data['entity_test__string']['table']['join']['entity_test']); + } + + /** + * Tests fields on the data table. + */ + public function testDataTableFields() { + $entity_test_type = new ConfigEntityType([ + 'class' => ConfigEntityBase::class, + 'id' => 'entity_test_bundle', + 'entity_keys' => [ + 'id' => 'type', + 'label' => 'name', + ], + ]); + $this->setUpEntityType($entity_test_type); + + $entity_type = $this->baseEntityType + ->set('data_table', 'entity_test_mul_property_data') + ->set('base_table', 'entity_test_mul') + ->set('translatable', TRUE) + ->set('id', 'entity_test_mul') + ->set('bundle_entity_type', 'entity_test_bundle') + ->setKey('bundle', 'type'); + + $base_field_definitions = $this->commonBaseFields; + $base_field_definitions['type'] = BaseFieldDefinition::create('entity_reference') + ->setLabel('entity test type') + ->setSetting('target_type', 'entity_test_bundle'); + + $this->setUpEntityType($entity_type, $base_field_definitions); + + $data = $this->entityTypeManager->getHandler('entity_test_mul', 'views_data')->getViewsData(); + + // Check the base fields. + $this->assertFalse(isset($data['entity_test_mul']['id'])); + $this->assertFalse(isset($data['entity_test_mul']['type'])); + $this->assertUuidField($data['entity_test_mul']['uuid']); + $this->assertViewsDataField($data['entity_test_mul']['uuid'], 'uuid'); + + $this->assertFalse(isset($data['entity_test_mul']['type']['relationship'])); + + // Also ensure that field_data only fields don't appear on the base table. + $this->assertFalse(isset($data['entity_test_mul']['name'])); + $this->assertFalse(isset($data['entity_test_mul']['description'])); + $this->assertFalse(isset($data['entity_test_mul']['description__value'])); + $this->assertFalse(isset($data['entity_test_mul']['description__format'])); + $this->assertFalse(isset($data['entity_test_mul']['user_id'])); + $this->assertFalse(isset($data['entity_test_mul']['homepage'])); + + // Check the data fields. + $this->assertNumericField($data['entity_test_mul_property_data']['id']); + $this->assertViewsDataField($data['entity_test_mul_property_data']['id'], 'id'); + + $this->assertBundleField($data['entity_test_mul_property_data']['type']); + $this->assertViewsDataField($data['entity_test_mul_property_data']['type'], 'type'); + + $this->assertLanguageField($data['entity_test_mul_property_data']['langcode']); + $this->assertViewsDataField($data['entity_test_mul_property_data']['langcode'], 'langcode'); + $this->assertEquals('Translation language', $data['entity_test_mul_property_data']['langcode']['title']); + + $this->assertStringField($data['entity_test_mul_property_data']['name']); + $this->assertViewsDataField($data['entity_test_mul_property_data']['name'], 'name'); + + $this->assertLongTextField($data['entity_test_mul_property_data'], 'description'); + $this->assertViewsDataField($data['entity_test_mul_property_data']['description__value'], 'description'); + $this->assertViewsDataField($data['entity_test_mul_property_data']['description__format'], 'description'); + + $this->assertUriField($data['entity_test_mul_property_data']['homepage']); + $this->assertViewsDataField($data['entity_test_mul_property_data']['homepage'], 'homepage'); + + $this->assertEntityReferenceField($data['entity_test_mul_property_data']['user_id']); + $this->assertViewsDataField($data['entity_test_mul_property_data']['user_id'], 'user_id'); + $relationship = $data['entity_test_mul_property_data']['user_id']['relationship']; + $this->assertEquals('users_field_data', $relationship['base']); + $this->assertEquals('uid', $relationship['base field']); + + $this->assertStringField($data['entity_test_mul__string']['string_value']); + $this->assertViewsDataField($data['entity_test_mul__string']['string_value'], 'string'); + $this->assertEquals([ + 'left_field' => 'id', + 'field' => 'entity_id', + 'extra' => [[ + 'field' => 'deleted', + 'value' => 0, + 'numeric' => TRUE, + ], + ], + ], $data['entity_test_mul__string']['table']['join']['entity_test_mul_property_data']); + } + + /** + * Tests fields on the revision table. + */ + public function testRevisionTableFields() { + $entity_type = $this->baseEntityType + ->set('id', 'entity_test_mulrev') + ->set('base_table', 'entity_test_mulrev') + ->set('revision_table', 'entity_test_mulrev_revision') + ->set('data_table', 'entity_test_mulrev_property_data') + ->set('revision_data_table', 'entity_test_mulrev_property_revision') + ->set('translatable', TRUE); + + $base_field_definitions = $this->commonBaseFields; + + $base_field_definitions['name']->setRevisionable(TRUE); + $base_field_definitions['description']->setRevisionable(TRUE); + $base_field_definitions['homepage']->setRevisionable(TRUE); + $base_field_definitions['user_id']->setRevisionable(TRUE); + + $base_field_definitions['non_rev_field'] = BaseFieldDefinition::create('string') + ->setLabel(t('Non Revisionable Field')) + ->setDescription(t('A non-revisionable test field.')) + ->setRevisionable(FALSE) + ->setTranslatable(TRUE) + ->setCardinality(1) + ->setReadOnly(TRUE); + + $base_field_definitions['non_mul_field'] = BaseFieldDefinition::create('string') + ->setLabel(t('Non translatable')) + ->setDescription(t('A non-translatable string field')) + ->setRevisionable(TRUE); + + $this->setUpEntityType($entity_type, $base_field_definitions); + + $data = $this->entityTypeManager->getHandler('entity_test_mulrev', 'views_data')->getViewsData(); + + // Check the base fields. + $this->assertFalse(isset($data['entity_test_mulrev']['id'])); + $this->assertFalse(isset($data['entity_test_mulrev']['type'])); + $this->assertFalse(isset($data['entity_test_mulrev']['revision_id'])); + $this->assertUuidField($data['entity_test_mulrev']['uuid']); + $this->assertViewsDataField($data['entity_test_mulrev']['uuid'], 'uuid'); + + // Also ensure that field_data only fields don't appear on the base table. + $this->assertFalse(isset($data['entity_test_mulrev']['name'])); + $this->assertFalse(isset($data['entity_test_mul']['description'])); + $this->assertFalse(isset($data['entity_test_mul']['description__value'])); + $this->assertFalse(isset($data['entity_test_mul']['description__format'])); + $this->assertFalse(isset($data['entity_test_mul']['homepage'])); + // $this->assertFalse(isset($data['entity_test_mulrev']['langcode'])); + $this->assertFalse(isset($data['entity_test_mulrev']['user_id'])); + + // Check the revision fields. The revision ID should only appear in the data + // table. + $this->assertFalse(isset($data['entity_test_mulrev_revision']['revision_id'])); + + // Also ensure that field_data only fields don't appear on the revision table. + $this->assertFalse(isset($data['entity_test_mulrev_revision']['id'])); + $this->assertFalse(isset($data['entity_test_mulrev_revision']['name'])); + $this->assertFalse(isset($data['entity_test_mulrev_revision']['description'])); + $this->assertFalse(isset($data['entity_test_mulrev_revision']['description__value'])); + $this->assertFalse(isset($data['entity_test_mulrev_revision']['description__format'])); + $this->assertFalse(isset($data['entity_test_mulrev_revision']['homepage'])); + $this->assertFalse(isset($data['entity_test_mulrev_revision']['user_id'])); + + // Check the data fields. + $this->assertNumericField($data['entity_test_mulrev_property_data']['id']); + $this->assertViewsDataField($data['entity_test_mulrev_property_data']['id'], 'id'); + $this->assertNumericField($data['entity_test_mulrev_property_data']['revision_id']); + $this->assertViewsDataField($data['entity_test_mulrev_property_data']['revision_id'], 'revision_id'); + $this->assertLanguageField($data['entity_test_mulrev_property_data']['langcode']); + $this->assertViewsDataField($data['entity_test_mulrev_property_data']['langcode'], 'langcode'); + $this->assertStringField($data['entity_test_mulrev_property_data']['name']); + $this->assertViewsDataField($data['entity_test_mulrev_property_data']['name'], 'name'); + + $this->assertLongTextField($data['entity_test_mulrev_property_data'], 'description'); + $this->assertViewsDataField($data['entity_test_mulrev_property_data']['description__value'], 'description'); + $this->assertViewsDataField($data['entity_test_mulrev_property_data']['description__format'], 'description'); + $this->assertUriField($data['entity_test_mulrev_property_data']['homepage']); + $this->assertViewsDataField($data['entity_test_mulrev_property_data']['homepage'], 'homepage'); + + $this->assertEntityReferenceField($data['entity_test_mulrev_property_data']['user_id']); + $this->assertViewsDataField($data['entity_test_mulrev_property_data']['user_id'], 'user_id'); + $relationship = $data['entity_test_mulrev_property_data']['user_id']['relationship']; + $this->assertEquals('users_field_data', $relationship['base']); + $this->assertEquals('uid', $relationship['base field']); + + // Check the property data fields. + $this->assertNumericField($data['entity_test_mulrev_property_revision']['id']); + $this->assertViewsDataField($data['entity_test_mulrev_property_revision']['id'], 'id'); + + $this->assertLanguageField($data['entity_test_mulrev_property_revision']['langcode']); + $this->assertViewsDataField($data['entity_test_mulrev_property_revision']['langcode'], 'langcode'); + $this->assertEquals('Translation language', $data['entity_test_mulrev_property_revision']['langcode']['title']); + + $this->assertStringField($data['entity_test_mulrev_property_revision']['name']); + $this->assertViewsDataField($data['entity_test_mulrev_property_revision']['name'], 'name'); + + $this->assertLongTextField($data['entity_test_mulrev_property_revision'], 'description'); + $this->assertViewsDataField($data['entity_test_mulrev_property_revision']['description__value'], 'description'); + $this->assertViewsDataField($data['entity_test_mulrev_property_revision']['description__format'], 'description'); + + $this->assertUriField($data['entity_test_mulrev_property_revision']['homepage']); + $this->assertViewsDataField($data['entity_test_mulrev_property_revision']['homepage'], 'homepage'); + + $this->assertEntityReferenceField($data['entity_test_mulrev_property_revision']['user_id']); + $this->assertViewsDataField($data['entity_test_mulrev_property_revision']['user_id'], 'user_id'); + $relationship = $data['entity_test_mulrev_property_revision']['user_id']['relationship']; + $this->assertEquals('users_field_data', $relationship['base']); + $this->assertEquals('uid', $relationship['base field']); + + $this->assertStringField($data['entity_test_mulrev__string']['string_value']); + $this->assertViewsDataField($data['entity_test_mulrev__string']['string_value'], 'string'); + $this->assertEquals([ + 'left_field' => 'id', + 'field' => 'entity_id', + 'extra' => [[ + 'field' => 'deleted', + 'value' => 0, + 'numeric' => TRUE, + ], + ], + ], $data['entity_test_mulrev__string']['table']['join']['entity_test_mulrev_property_data']); + + $this->assertStringField($data['entity_test_mulrev_revision__string']['string_value']); + $this->assertViewsDataField($data['entity_test_mulrev_revision__string']['string_value'], 'string'); + $this->assertEquals([ + 'left_field' => 'revision_id', + 'field' => 'entity_id', + 'extra' => [[ + 'field' => 'deleted', + 'value' => 0, + 'numeric' => TRUE, + ], + ], + ], $data['entity_test_mulrev_revision__string']['table']['join']['entity_test_mulrev_property_revision']); + } + + /** + * Tests generic stuff per field. + * + * @param array $data + * The views data to check. + * @param string $field_name + * The entity field name. + */ + protected function assertViewsDataField($data, $field_name) { + $this->assertEquals($field_name, $data['entity field']); + } + + /** + * Tests views data for a string field. + * + * @param $data + * The views data to check. + */ + protected function assertStringField($data) { + $this->assertEquals('field', $data['field']['id']); + $this->assertEquals('string', $data['filter']['id']); + $this->assertEquals('string', $data['argument']['id']); + $this->assertEquals('standard', $data['sort']['id']); + } + + /** + * Tests views data for a URI field. + * + * @param $data + * The views data to check. + */ + protected function assertUriField($data) { + $this->assertEquals('field', $data['field']['id']); + $this->assertEquals('string', $data['field']['default_formatter']); + $this->assertEquals('string', $data['filter']['id']); + $this->assertEquals('string', $data['argument']['id']); + $this->assertEquals('standard', $data['sort']['id']); + } + + /** + * Tests views data for a long text field. + * + * @param $data + * The views data for the table this field is in. + * @param $field_name + * The name of the field being checked. + */ + protected function assertLongTextField($data, $field_name) { + $value_field = $data[$field_name . '__value']; + $this->assertEquals('field', $value_field['field']['id']); + $this->assertEquals($field_name . '__format', $value_field['field']['format']); + $this->assertEquals('string', $value_field['filter']['id']); + $this->assertEquals('string', $value_field['argument']['id']); + $this->assertEquals('standard', $value_field['sort']['id']); + + $this->assertStringField($data[$field_name . '__format']); + } + + /** + * Tests views data for a UUID field. + * + * @param array $data + * The views data to check. + */ + protected function assertUuidField($data) { + // @todo Can we provide additional support for UUIDs in views? + $this->assertEquals('field', $data['field']['id']); + $this->assertFalse($data['field']['click sortable']); + $this->assertEquals('string', $data['filter']['id']); + $this->assertEquals('string', $data['argument']['id']); + $this->assertEquals('standard', $data['sort']['id']); + } + + /** + * Tests views data for a numeric field. + * + * @param array $data + * The views data to check. + */ + protected function assertNumericField($data) { + $this->assertEquals('field', $data['field']['id']); + $this->assertEquals('numeric', $data['filter']['id']); + $this->assertEquals('numeric', $data['argument']['id']); + $this->assertEquals('standard', $data['sort']['id']); + } + + /** + * Tests views data for a language field. + * + * @param array $data + * The views data to check. + */ + protected function assertLanguageField($data) { + $this->assertEquals('field', $data['field']['id']); + $this->assertEquals('language', $data['filter']['id']); + $this->assertEquals('language', $data['argument']['id']); + $this->assertEquals('standard', $data['sort']['id']); + } + + /** + * Tests views data for an entity reference field. + */ + protected function assertEntityReferenceField($data) { + $this->assertEquals('field', $data['field']['id']); + $this->assertEquals('numeric', $data['filter']['id']); + $this->assertEquals('numeric', $data['argument']['id']); + $this->assertEquals('standard', $data['sort']['id']); + } + + /** + * Tests views data for a bundle field. + */ + protected function assertBundleField($data) { + $this->assertEquals('field', $data['field']['id']); + $this->assertEquals('bundle', $data['filter']['id']); + $this->assertEquals('string', $data['argument']['id']); + $this->assertEquals('standard', $data['sort']['id']); + } + +} + +/** + * Entity type class which allows changing the entity keys. + */ +class TestEntityType extends ContentEntityType { + + /** + * Sets a specific entity key. + * + * @param string $key + * The name of the entity key. + * @param string $value + * The new value of the key. + * + * @return $this + */ + public function setKey($key, $value) { + $this->entity_keys[$key] = $value; + return $this; + } + +} + +/** + * Generic entity class for our test entity types. + * + * Allows mocked base field definitions. + */ +class ViewsTestEntity extends ContentEntityBase { + + /** + * The mocked base fields for test entity types. + * + * An array keyed by entity type ID, whose values are arrays of base field + * definitions. + * + * @var array + */ + protected static $mockedBaseFieldDefinitions = []; + + /** + * Sets up the mocked base field definitions. + * + * @param string $entity_type_id + * The entity type ID. + * @param array $definitions + * The array of base field definitions to mock. These are added to the + * defaults ones from the parent class. + */ + public static function setMockedBaseFieldDefinitions(string $entity_type_id, array $definitions) { + static::$mockedBaseFieldDefinitions[$entity_type_id] = $definitions; + } + + /** + * {@inheritdoc} + */ + public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { + $fields = parent::baseFieldDefinitions($entity_type); + + if (isset(static::$mockedBaseFieldDefinitions[$entity_type->id()])) { + $mocked_fields = static::$mockedBaseFieldDefinitions[$entity_type->id()]; + // Mocked fields take priority over ones from the base class. + $fields = $mocked_fields + $fields; + } + + return $fields; + } + +} diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php deleted file mode 100644 index 6e0621e40fde5b6d0b9b87e9c4343ce4360b0576..0000000000000000000000000000000000000000 --- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php +++ /dev/null @@ -1,1197 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\Tests\views\Unit\EntityViewsDataTest. - */ - -namespace Drupal\Tests\views\Unit; - -use Drupal\Core\Config\Entity\ConfigEntityType; -use Drupal\Core\Entity\ContentEntityType; -use Drupal\Core\Entity\EntityFieldManagerInterface; -use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Entity\Sql\DefaultTableMapping; -use Drupal\Core\Field\BaseFieldDefinition; -use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; -use Drupal\Core\Field\Plugin\Field\FieldType\IntegerItem; -use Drupal\Core\Field\Plugin\Field\FieldType\LanguageItem; -use Drupal\Core\Field\Plugin\Field\FieldType\StringItem; -use Drupal\Core\Field\Plugin\Field\FieldType\UriItem; -use Drupal\Core\Field\Plugin\Field\FieldType\UuidItem; -use Drupal\Core\State\StateInterface; -use Drupal\Core\TypedData\TypedDataManagerInterface; -use Drupal\text\Plugin\Field\FieldType\TextLongItem; -use Drupal\entity_test\Entity\EntityTest; -use Drupal\entity_test\Entity\EntityTestMul; -use Drupal\entity_test\Entity\EntityTestMulRev; -use Drupal\Tests\UnitTestCase; -use Drupal\views\EntityViewsData; -use Prophecy\Argument; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -/** - * @coversDefaultClass \Drupal\views\EntityViewsData - * @group Views - */ -class EntityViewsDataTest extends UnitTestCase { - - /** - * Entity info to use in this test. - * - * @var \Drupal\Core\Entity\EntityTypeInterface|\Drupal\Tests\views\Unit\TestEntityType - */ - protected $baseEntityType; - - /** - * The mocked entity storage. - * - * @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage|\PHPUnit\Framework\MockObject\MockObject - */ - protected $entityStorage; - - /** - * The mocked entity field manager. - * - * @var \Drupal\Core\Entity\EntityFieldManagerInterface|\PHPUnit\Framework\MockObject\MockObject - */ - protected $entityFieldManager; - - - /** - * The mocked entity type manager. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit\Framework\MockObject\MockObject - */ - protected $entityTypeManager; - - /** - * The mocked module handler. - * - * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit\Framework\MockObject\MockObject - */ - protected $moduleHandler; - - /** - * The mocked translation manager. - * - * @var \Drupal\Core\StringTranslation\TranslationInterface|\PHPUnit\Framework\MockObject\MockObject - */ - protected $translationManager; - - /** - * The tested entity views controller. - * - * @var \Drupal\Tests\views\Unit\TestEntityViewsData - */ - protected $viewsData; - - /** - * {@inheritdoc} - */ - protected function setUp(): void { - $this->entityStorage = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorage') - ->disableOriginalConstructor() - ->getMock(); - $this->entityTypeManager = $this->createMock(EntityTypeManagerInterface::class); - $this->entityFieldManager = $this->createMock(EntityFieldManagerInterface::class); - - $typed_data_manager = $this->createMock(TypedDataManagerInterface::class); - $typed_data_manager->expects($this->any()) - ->method('createDataDefinition') - ->willReturn($this->createMock('Drupal\Core\TypedData\DataDefinitionInterface')); - - $typed_data_manager->expects($this->any()) - ->method('getDefinition') - ->will($this->returnValueMap([ - 'entity:user' => ['class' => '\Drupal\Core\TypedData\DataDefinitionInterface'], - 'field_item:string_long' => ['class' => '\Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem'], - ])); - - $this->baseEntityType = new TestEntityType([ - 'base_table' => 'entity_test', - 'id' => 'entity_test', - 'label' => 'Entity test', - 'entity_keys' => [ - 'uuid' => 'uuid', - 'id' => 'id', - 'langcode' => 'langcode', - 'bundle' => 'type', - 'revision' => 'revision_id', - ], - 'provider' => 'entity_test', - 'list_cache_contexts' => ['entity_test_list_cache_context'], - ]); - - $this->translationManager = $this->getStringTranslationStub(); - $this->baseEntityType->setStringTranslation($this->translationManager); - $this->moduleHandler = $this->createMock('Drupal\Core\Extension\ModuleHandlerInterface'); - - $this->viewsData = new TestEntityViewsData($this->baseEntityType, $this->entityStorage, $this->entityTypeManager, $this->moduleHandler, $this->translationManager, $this->entityFieldManager); - - $field_type_manager = $this->getMockBuilder('Drupal\Core\Field\FieldTypePluginManager') - ->disableOriginalConstructor() - ->getMock(); - $field_type_manager->expects($this->any()) - ->method('getDefaultStorageSettings') - ->willReturn([]); - $field_type_manager->expects($this->any()) - ->method('getDefaultFieldSettings') - ->willReturn([]); - - $state = $this->prophesize(StateInterface::class); - $state->get(Argument::any(), [])->willReturn([]); - - $container = new ContainerBuilder(); - $container->set('plugin.manager.field.field_type', $field_type_manager); - $container->set('entity_type.manager', $this->entityTypeManager); - $container->set('entity_field.manager', $this->entityFieldManager); - $container->set('typed_data_manager', $typed_data_manager); - $container->set('state', $state->reveal()); - \Drupal::setContainer($container); - } - - /** - * Helper method to setup base fields. - * - * @param \Drupal\Core\Field\BaseFieldDefinition[] $base_fields - * The base fields which are adapted. - * - * @return \Drupal\Core\Field\BaseFieldDefinition[] - * The setup base fields. - */ - protected function setupBaseFields(array $base_fields) { - // Add a description field to the fields supplied by the EntityTest - // classes. This example comes from the taxonomy Term entity. - $base_fields['description'] = BaseFieldDefinition::create('text_long') - ->setLabel('Description') - ->setDescription('A description of the term.') - ->setTranslatable(TRUE) - ->setDisplayOptions('view', [ - 'label' => 'hidden', - 'type' => 'text_default', - 'weight' => 0, - ]) - ->setDisplayConfigurable('view', TRUE) - ->setDisplayOptions('form', [ - 'type' => 'text_textfield', - 'weight' => 0, - ]) - ->setDisplayConfigurable('form', TRUE); - - // Add a URL field; this example is from the Comment entity. - $base_fields['homepage'] = BaseFieldDefinition::create('uri') - ->setLabel('Homepage') - ->setDescription("The comment author's home page address.") - ->setTranslatable(TRUE) - ->setSetting('max_length', 255); - - // A base field with cardinality > 1 - $base_fields['string'] = BaseFieldDefinition::create('string') - ->setLabel('Strong') - ->setTranslatable(TRUE) - ->setCardinality(2); - - foreach ($base_fields as $name => $base_field) { - $base_field->setName($name); - } - return $base_fields; - } - - /** - * Tests base tables. - */ - public function testBaseTables() { - $data = $this->viewsData->getViewsData(); - - $this->assertEquals('entity_test', $data['entity_test']['table']['entity type']); - $this->assertEquals(FALSE, $data['entity_test']['table']['entity revision']); - $this->assertEquals('Entity test', $data['entity_test']['table']['group']); - $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); - - $this->assertEquals('id', $data['entity_test']['table']['base']['field']); - $this->assertEquals(['entity_test_list_cache_context'], $data['entity_test']['table']['base']['cache_contexts']); - $this->assertEquals('Entity test', $data['entity_test']['table']['base']['title']); - - $this->assertFalse(isset($data['entity_test']['table']['defaults'])); - - $this->assertFalse(isset($data['entity_test_mul_property_data'])); - $this->assertFalse(isset($data['revision_table'])); - $this->assertFalse(isset($data['revision_data_table'])); - } - - /** - * Tests data_table support. - */ - public function testDataTable() { - $entity_type = $this->baseEntityType - ->set('data_table', 'entity_test_mul_property_data') - ->set('id', 'entity_test_mul') - ->set('translatable', TRUE) - ->setKey('label', 'label'); - - $this->viewsData->setEntityType($entity_type); - - // Tests the join definition between the base and the data table. - $data = $this->viewsData->getViewsData(); - $base_views_data = $data['entity_test']; - - // Ensure that the base table is set to the data table. - $this->assertEquals('id', $data['entity_test_mul_property_data']['table']['base']['field']); - $this->assertEquals('Entity test', $data['entity_test_mul_property_data']['table']['base']['title']); - $this->assertFalse(isset($data['entity_test']['table']['base'])); - - $this->assertEquals('entity_test_mul', $data['entity_test_mul_property_data']['table']['entity type']); - $this->assertEquals(FALSE, $data['entity_test_mul_property_data']['table']['entity revision']); - $this->assertEquals('Entity test', $data['entity_test_mul_property_data']['table']['group']); - $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); - $this->assertEquals(['field' => 'label', 'table' => 'entity_test_mul_property_data'], $data['entity_test_mul_property_data']['table']['base']['defaults']); - - // Ensure the join information is set up properly. - $this->assertCount(1, $base_views_data['table']['join']); - $this->assertEquals(['entity_test_mul_property_data' => ['left_field' => 'id', 'field' => 'id', 'type' => 'INNER']], $base_views_data['table']['join']); - $this->assertFalse(isset($data['revision_table'])); - $this->assertFalse(isset($data['revision_data_table'])); - } - - /** - * Tests revision table without data table support. - */ - public function testRevisionTableWithoutDataTable() { - $entity_type = $this->baseEntityType - ->set('revision_table', 'entity_test_mulrev_revision') - ->set('revision_data_table', NULL) - ->set('id', 'entity_test_mulrev') - ->setKey('revision', 'revision_id'); - $this->viewsData->setEntityType($entity_type); - - $data = $this->viewsData->getViewsData(); - - $this->assertEquals('Entity test revisions', $data['entity_test_mulrev_revision']['table']['base']['title']); - $this->assertEquals('revision_id', $data['entity_test_mulrev_revision']['table']['base']['field']); - - $this->assertEquals(FALSE, $data['entity_test']['table']['entity revision']); - $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_revision']['table']['entity type']); - $this->assertEquals(TRUE, $data['entity_test_mulrev_revision']['table']['entity revision']); - $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_revision']['table']['entity type']); - $this->assertEquals(TRUE, $data['entity_test_mulrev_revision']['table']['entity revision']); - - $this->assertEquals('Entity test revision', $data['entity_test_mulrev_revision']['table']['group']); - $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); - - // Ensure the join information is set up properly. - // Tests the join definition between the base and the revision table. - $revision_data = $data['entity_test_mulrev_revision']; - $this->assertCount(1, $revision_data['table']['join']); - $this->assertEquals(['entity_test' => ['left_field' => 'revision_id', 'field' => 'revision_id', 'type' => 'INNER']], $revision_data['table']['join']); - $this->assertFalse(isset($data['data_table'])); - } - - /** - * Tests revision table with data table support. - */ - public function testRevisionTableWithRevisionDataTableAndDataTable() { - $entity_type = $this->baseEntityType - ->set('data_table', 'entity_test_mul_property_data') - ->set('revision_table', 'entity_test_mulrev_revision') - ->set('revision_data_table', 'entity_test_mulrev_property_revision') - ->set('id', 'entity_test_mulrev') - ->set('translatable', TRUE) - ->setKey('revision', 'revision_id'); - $this->viewsData->setEntityType($entity_type); - - $data = $this->viewsData->getViewsData(); - - $this->assertEquals('Entity test revisions', $data['entity_test_mulrev_property_revision']['table']['base']['title']); - $this->assertEquals('revision_id', $data['entity_test_mulrev_property_revision']['table']['base']['field']); - $this->assertFalse(isset($data['entity_test_mulrev_revision']['table']['base'])); - - $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_property_revision']['table']['entity type']); - $this->assertEquals('Entity test revision', $data['entity_test_mulrev_revision']['table']['group']); - $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); - - // Ensure the join information is set up properly. - // Tests the join definition between the base and the revision table. - $revision_field_data = $data['entity_test_mulrev_property_revision']; - $this->assertCount(1, $revision_field_data['table']['join']); - $this->assertEquals([ - 'entity_test_mul_property_data' => [ - 'left_field' => 'revision_id', - 'field' => 'revision_id', - 'type' => 'INNER', - ], - ], $revision_field_data['table']['join']); - - $revision_base_data = $data['entity_test_mulrev_revision']; - $this->assertCount(1, $revision_base_data['table']['join']); - $this->assertEquals([ - 'entity_test_mulrev_property_revision' => [ - 'left_field' => 'revision_id', - 'field' => 'revision_id', - 'type' => 'INNER', - ], - ], $revision_base_data['table']['join']); - - $this->assertFalse(isset($data['data_table'])); - } - - /** - * Tests revision table with data table support. - */ - public function testRevisionTableWithRevisionDataTable() { - $entity_type = $this->baseEntityType - ->set('revision_table', 'entity_test_mulrev_revision') - ->set('revision_data_table', 'entity_test_mulrev_property_revision') - ->set('id', 'entity_test_mulrev') - ->set('translatable', TRUE) - ->setKey('revision', 'revision_id'); - $this->viewsData->setEntityType($entity_type); - - $data = $this->viewsData->getViewsData(); - - $this->assertEquals('Entity test revisions', $data['entity_test_mulrev_property_revision']['table']['base']['title']); - $this->assertEquals('revision_id', $data['entity_test_mulrev_property_revision']['table']['base']['field']); - $this->assertFalse(isset($data['entity_test_mulrev_revision']['table']['base'])); - - $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_property_revision']['table']['entity type']); - $this->assertEquals('Entity test revision', $data['entity_test_mulrev_revision']['table']['group']); - $this->assertEquals('entity_test', $data['entity_test']['table']['provider']); - - // Ensure the join information is set up properly. - // Tests the join definition between the base and the revision table. - $revision_field_data = $data['entity_test_mulrev_property_revision']; - $this->assertCount(1, $revision_field_data['table']['join']); - $this->assertEquals([ - 'entity_test_mulrev_field_data' => [ - 'left_field' => 'revision_id', - 'field' => 'revision_id', - 'type' => 'INNER', - ], - ], $revision_field_data['table']['join']); - - $revision_base_data = $data['entity_test_mulrev_revision']; - $this->assertCount(1, $revision_base_data['table']['join']); - $this->assertEquals([ - 'entity_test_mulrev_property_revision' => [ - 'left_field' => 'revision_id', - 'field' => 'revision_id', - 'type' => 'INNER', - ], - ], $revision_base_data['table']['join']); - $this->assertFalse(isset($data['data_table'])); - } - - /** - * Helper method to mock all store definitions. - */ - protected function setupFieldStorageDefinition() { - $id_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $id_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(IntegerItem::schema($id_field_storage_definition)); - $uuid_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $uuid_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(UuidItem::schema($uuid_field_storage_definition)); - $type_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $type_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(StringItem::schema($type_field_storage_definition)); - $langcode_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $langcode_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(LanguageItem::schema($langcode_field_storage_definition)); - $name_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $name_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(StringItem::schema($name_field_storage_definition)); - $description_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $description_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(TextLongItem::schema($description_field_storage_definition)); - $homepage_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $homepage_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(UriItem::schema($homepage_field_storage_definition)); - $string_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $string_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(StringItem::schema($string_field_storage_definition)); - - // Setup the user_id entity reference field. - $this->entityTypeManager->expects($this->any()) - ->method('getDefinition') - ->willReturnMap([ - ['user', TRUE, static::userEntityInfo()], - ] - ); - $this->entityTypeManager->expects($this->any()) - ->method('getDefinition') - ->willReturnMap([ - ['user', TRUE, static::userEntityInfo()], - ] - ); - $user_id_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $user_id_field_storage_definition->expects($this->any()) - ->method('getSetting') - ->with('target_type') - ->willReturn('user'); - $user_id_field_storage_definition->expects($this->any()) - ->method('getSettings') - ->willReturn(['target_type' => 'user']); - $user_id_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(EntityReferenceItem::schema($user_id_field_storage_definition)); - - $revision_id_field_storage_definition = $this->createMock('Drupal\Core\Field\FieldStorageDefinitionInterface'); - $revision_id_field_storage_definition->expects($this->any()) - ->method('getSchema') - ->willReturn(IntegerItem::schema($revision_id_field_storage_definition)); - - $this->entityFieldManager->expects($this->any()) - ->method('getFieldStorageDefinitions') - ->willReturn([ - 'id' => $id_field_storage_definition, - 'uuid' => $uuid_field_storage_definition, - 'type' => $type_field_storage_definition, - 'langcode' => $langcode_field_storage_definition, - 'name' => $name_field_storage_definition, - 'description' => $description_field_storage_definition, - 'homepage' => $homepage_field_storage_definition, - 'string' => $string_field_storage_definition, - 'user_id' => $user_id_field_storage_definition, - 'revision_id' => $revision_id_field_storage_definition, - ]); - } - - /** - * Tests fields on the base table. - */ - public function testBaseTableFields() { - $base_field_definitions = $this->setupBaseFields(EntityTest::baseFieldDefinitions($this->baseEntityType)); - $user_base_field_definitions = [ - 'uid' => BaseFieldDefinition::create('integer') - ->setLabel('ID') - ->setDescription('The ID of the user entity.') - ->setReadOnly(TRUE) - ->setSetting('unsigned', TRUE), - ]; - $this->entityFieldManager->expects($this->any()) - ->method('getBaseFieldDefinitions') - ->will($this->returnValueMap([ - ['user', $user_base_field_definitions], - ['entity_test', $base_field_definitions], - ])); - $this->entityFieldManager->expects($this->any()) - ->method('getBaseFieldDefinitions') - ->will($this->returnValueMap([ - ['user', $user_base_field_definitions], - ['entity_test', $base_field_definitions], - ])); - // Setup the table mapping. - $table_mapping = $this->getMockBuilder(DefaultTableMapping::class) - ->disableOriginalConstructor() - ->getMock(); - $table_mapping->expects($this->any()) - ->method('getTableNames') - ->willReturn(['entity_test', 'entity_test__string']); - $table_mapping->expects($this->any()) - ->method('getColumnNames') - ->willReturnMap([ - ['id', ['value' => 'id']], - ['uuid', ['value' => 'uuid']], - ['type', ['value' => 'type']], - ['langcode', ['value' => 'langcode']], - ['name', ['value' => 'name']], - ['description', ['value' => 'description__value', 'format' => 'description__format']], - ['homepage', ['value' => 'homepage']], - ['user_id', ['target_id' => 'user_id']], - ['string', ['value' => 'string_value']], - ]); - $table_mapping->expects($this->any()) - ->method('getFieldNames') - ->willReturnMap([ - ['entity_test', ['id', 'uuid', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']], - ['entity_test__string', ['string']], - ]); - $table_mapping->expects($this->any()) - ->method('requiresDedicatedTableStorage') - ->willReturnCallback(function (BaseFieldDefinition $base_field) { - return $base_field->getName() === 'string'; - }); - $table_mapping->expects($this->any()) - ->method('getDedicatedDataTableName') - ->willReturnCallback(function (BaseFieldDefinition $base_field) { - if ($base_field->getName() === 'string') { - return 'entity_test__string'; - } - }); - - $this->entityStorage->expects($this->once()) - ->method('getTableMapping') - ->willReturn($table_mapping); - - $this->setupFieldStorageDefinition(); - - $data = $this->viewsData->getViewsData(); - - $this->assertNumericField($data['entity_test']['id']); - $this->assertField($data['entity_test']['id'], 'id'); - $this->assertUuidField($data['entity_test']['uuid']); - $this->assertField($data['entity_test']['uuid'], 'uuid'); - $this->assertStringField($data['entity_test']['type']); - $this->assertEquals('type', $data['entity_test']['type']['entity field']); - - $this->assertLanguageField($data['entity_test']['langcode']); - $this->assertField($data['entity_test']['langcode'], 'langcode'); - $this->assertEquals('Original language', $data['entity_test']['langcode']['title']); - - $this->assertStringField($data['entity_test']['name']); - $this->assertField($data['entity_test']['name'], 'name'); - - $this->assertLongTextField($data['entity_test'], 'description'); - $this->assertField($data['entity_test']['description__value'], 'description'); - $this->assertField($data['entity_test']['description__format'], 'description'); - - $this->assertUriField($data['entity_test']['homepage']); - $this->assertField($data['entity_test']['homepage'], 'homepage'); - - $this->assertEntityReferenceField($data['entity_test']['user_id']); - $this->assertField($data['entity_test']['user_id'], 'user_id'); - - $relationship = $data['entity_test']['user_id']['relationship']; - $this->assertEquals('users_field_data', $relationship['base']); - $this->assertEquals('uid', $relationship['base field']); - - // The string field name should be used as the 'entity field' but the actual - // field should reflect what the column mapping is using for multi-value - // base fields NOT just the field name. The actual column name returned from - // mappings in the test mocks is 'value'. - $this->assertStringField($data['entity_test__string']['string_value']); - $this->assertField($data['entity_test__string']['string_value'], 'string'); - $this->assertEquals([ - 'left_field' => 'id', - 'field' => 'entity_id', - 'extra' => [[ - 'field' => 'deleted', - 'value' => 0, - 'numeric' => TRUE, - ], - ], - ], $data['entity_test__string']['table']['join']['entity_test']); - } - - /** - * Tests fields on the data table. - */ - public function testDataTableFields() { - $entity_type = $this->baseEntityType - ->set('data_table', 'entity_test_mul_property_data') - ->set('base_table', 'entity_test_mul') - ->set('id', 'entity_test_mul') - ->setKey('bundle', 'type'); - $base_field_definitions = $this->setupBaseFields(EntityTestMul::baseFieldDefinitions($this->baseEntityType)); - $base_field_definitions['type'] = BaseFieldDefinition::create('entity_reference') - ->setLabel('entity test type') - ->setSetting('target_type', 'entity_test_bundle') - ->setTranslatable(TRUE); - $base_field_definitions = $this->setupBaseFields($base_field_definitions); - $user_base_field_definitions = [ - 'uid' => BaseFieldDefinition::create('integer') - ->setLabel('ID') - ->setDescription('The ID of the user entity.') - ->setReadOnly(TRUE) - ->setSetting('unsigned', TRUE), - ]; - $entity_test_type = new ConfigEntityType(['id' => 'entity_test_bundle']); - - $this->entityFieldManager->expects($this->any()) - ->method('getBaseFieldDefinitions') - ->will($this->returnValueMap([ - ['user', $user_base_field_definitions], - ['entity_test_mul', $base_field_definitions], - ])); - $this->entityFieldManager->expects($this->any()) - ->method('getBaseFieldDefinitions') - ->will($this->returnValueMap([ - ['user', $user_base_field_definitions], - ['entity_test_mul', $base_field_definitions], - ])); - - $this->viewsData->setEntityType($entity_type); - - // Setup the table mapping. - $table_mapping = $this->getMockBuilder(DefaultTableMapping::class) - ->disableOriginalConstructor() - ->getMock(); - $table_mapping->expects($this->any()) - ->method('getTableNames') - ->willReturn(['entity_test_mul', 'entity_test_mul_property_data', 'entity_test_mul__string']); - $table_mapping->expects($this->any()) - ->method('getColumnNames') - ->willReturnMap([ - ['id', ['value' => 'id']], - ['uuid', ['value' => 'uuid']], - ['type', ['value' => 'type']], - ['langcode', ['value' => 'langcode']], - ['name', ['value' => 'name']], - ['description', ['value' => 'description__value', 'format' => 'description__format']], - ['homepage', ['value' => 'homepage']], - ['user_id', ['target_id' => 'user_id']], - ['string', ['value' => 'string_value']], - ]); - $table_mapping->expects($this->any()) - ->method('getFieldNames') - ->willReturnMap([ - ['entity_test_mul', ['uuid']], - ['entity_test_mul_property_data', ['id', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']], - ['entity_test_mul__string', ['string']], - ]); - - $table_mapping->expects($this->any()) - ->method('getFieldTableName') - ->willReturnCallback(function ($field) { - if ($field == 'uuid') { - return 'entity_test_mul'; - } - return 'entity_test_mul_property_data'; - }); - $table_mapping->expects($this->any()) - ->method('requiresDedicatedTableStorage') - ->willReturnCallback(function (BaseFieldDefinition $base_field) { - return $base_field->getName() === 'string'; - }); - $table_mapping->expects($this->any()) - ->method('getDedicatedDataTableName') - ->willReturnCallback(function (BaseFieldDefinition $base_field) { - if ($base_field->getName() === 'string') { - return 'entity_test_mul__string'; - } - }); - - $this->entityStorage->expects($this->once()) - ->method('getTableMapping') - ->willReturn($table_mapping); - - $this->setupFieldStorageDefinition(); - - $user_entity_type = static::userEntityInfo(); - $this->entityTypeManager->expects($this->any()) - ->method('getDefinition') - ->will($this->returnValueMap([ - ['user', TRUE, $user_entity_type], - ['entity_test_bundle', TRUE, $entity_test_type], - ])); - - $data = $this->viewsData->getViewsData(); - - // Check the base fields. - $this->assertFalse(isset($data['entity_test_mul']['id'])); - $this->assertFalse(isset($data['entity_test_mul']['type'])); - $this->assertUuidField($data['entity_test_mul']['uuid']); - $this->assertField($data['entity_test_mul']['uuid'], 'uuid'); - - $this->assertFalse(isset($data['entity_test_mul']['type']['relationship'])); - - // Also ensure that field_data only fields don't appear on the base table. - $this->assertFalse(isset($data['entity_test_mul']['name'])); - $this->assertFalse(isset($data['entity_test_mul']['description'])); - $this->assertFalse(isset($data['entity_test_mul']['description__value'])); - $this->assertFalse(isset($data['entity_test_mul']['description__format'])); - $this->assertFalse(isset($data['entity_test_mul']['user_id'])); - $this->assertFalse(isset($data['entity_test_mul']['homepage'])); - - // Check the data fields. - $this->assertNumericField($data['entity_test_mul_property_data']['id']); - $this->assertField($data['entity_test_mul_property_data']['id'], 'id'); - - $this->assertBundleField($data['entity_test_mul_property_data']['type']); - $this->assertField($data['entity_test_mul_property_data']['type'], 'type'); - - $this->assertLanguageField($data['entity_test_mul_property_data']['langcode']); - $this->assertField($data['entity_test_mul_property_data']['langcode'], 'langcode'); - $this->assertEquals('Translation language', $data['entity_test_mul_property_data']['langcode']['title']); - - $this->assertStringField($data['entity_test_mul_property_data']['name']); - $this->assertField($data['entity_test_mul_property_data']['name'], 'name'); - - $this->assertLongTextField($data['entity_test_mul_property_data'], 'description'); - $this->assertField($data['entity_test_mul_property_data']['description__value'], 'description'); - $this->assertField($data['entity_test_mul_property_data']['description__format'], 'description'); - - $this->assertUriField($data['entity_test_mul_property_data']['homepage']); - $this->assertField($data['entity_test_mul_property_data']['homepage'], 'homepage'); - - $this->assertEntityReferenceField($data['entity_test_mul_property_data']['user_id']); - $this->assertField($data['entity_test_mul_property_data']['user_id'], 'user_id'); - $relationship = $data['entity_test_mul_property_data']['user_id']['relationship']; - $this->assertEquals('users_field_data', $relationship['base']); - $this->assertEquals('uid', $relationship['base field']); - - $this->assertStringField($data['entity_test_mul__string']['string_value']); - $this->assertField($data['entity_test_mul__string']['string_value'], 'string'); - $this->assertEquals([ - 'left_field' => 'id', - 'field' => 'entity_id', - 'extra' => [[ - 'field' => 'deleted', - 'value' => 0, - 'numeric' => TRUE, - ], - ], - ], $data['entity_test_mul__string']['table']['join']['entity_test_mul']); - } - - /** - * Tests fields on the revision table. - */ - public function testRevisionTableFields() { - $entity_type = $this->baseEntityType - ->set('base_table', 'entity_test_mulrev') - ->set('revision_table', 'entity_test_mulrev_revision') - ->set('data_table', 'entity_test_mulrev_property_data') - ->set('revision_data_table', 'entity_test_mulrev_property_revision') - ->set('id', 'entity_test_mulrev') - ->set('translatable', TRUE); - $base_field_definitions = $this->setupBaseFields(EntityTestMulRev::baseFieldDefinitions($this->baseEntityType)); - $user_base_field_definitions = [ - 'uid' => BaseFieldDefinition::create('integer') - ->setLabel('ID') - ->setDescription('The ID of the user entity.') - ->setReadOnly(TRUE) - ->setSetting('unsigned', TRUE), - ]; - $this->entityFieldManager->expects($this->any()) - ->method('getBaseFieldDefinitions') - ->will($this->returnValueMap([ - ['user', $user_base_field_definitions], - ['entity_test_mulrev', $base_field_definitions], - ])); - $this->entityFieldManager->expects($this->any()) - ->method('getBaseFieldDefinitions') - ->will($this->returnValueMap([ - ['user', $user_base_field_definitions], - ['entity_test_mulrev', $base_field_definitions], - ])); - - $this->viewsData->setEntityType($entity_type); - - // Setup the table mapping. - $table_mapping = $this->getMockBuilder(DefaultTableMapping::class) - ->disableOriginalConstructor() - ->getMock(); - $table_mapping->expects($this->any()) - ->method('getTableNames') - ->willReturn(['entity_test_mulrev', 'entity_test_mulrev_revision', 'entity_test_mulrev_property_data', 'entity_test_mulrev_property_revision', 'entity_test_mulrev__string', 'entity_test_mulrev_revision__string']); - $table_mapping->expects($this->any()) - ->method('getColumnNames') - ->willReturnMap([ - ['id', ['value' => 'id']], - ['uuid', ['value' => 'uuid']], - ['type', ['value' => 'type']], - ['langcode', ['value' => 'langcode']], - ['name', ['value' => 'name']], - ['description', ['value' => 'description__value', 'format' => 'description__format']], - ['homepage', ['value' => 'homepage']], - ['user_id', ['target_id' => 'user_id']], - ['revision_id', ['value' => 'revision_id']], - ['string', ['value' => 'string_value']], - ]); - $table_mapping->expects($this->any()) - ->method('getFieldNames') - ->willReturnMap([ - ['entity_test_mulrev', ['id', 'revision_id', 'uuid', 'type']], - ['entity_test_mulrev_revision', ['id', 'revision_id', 'langcode']], - ['entity_test_mulrev_property_data', ['id', 'revision_id', 'langcode', 'name', 'description', 'homepage', 'user_id']], - ['entity_test_mulrev_property_revision', ['id', 'revision_id', 'langcode', 'name', 'description', 'homepage', 'user_id']], - ['entity_test_mulrev__string', ['string']], - ['entity_test_mulrev_revision__string', ['string']], - ]); - $table_mapping->expects($this->any()) - ->method('requiresDedicatedTableStorage') - ->willReturnCallback(function (BaseFieldDefinition $base_field) { - return $base_field->getName() === 'string'; - }); - $table_mapping->expects($this->any()) - ->method('getDedicatedDataTableName') - ->willReturnCallback(function (BaseFieldDefinition $base_field) { - if ($base_field->getName() === 'string') { - return 'entity_test_mulrev__string'; - } - }); - - $table_mapping->expects($this->any()) - ->method('getDedicatedRevisionTableName') - ->willReturnCallback(function (BaseFieldDefinition $base_field) { - if ($base_field->getName() === 'string') { - return 'entity_test_mulrev_revision__string'; - } - }); - - $table_mapping->expects($this->any()) - ->method('getFieldTableName') - ->willReturnCallback(function ($field) { - if ($field == 'uuid') { - return 'entity_test_mulrev'; - } - return 'entity_test_mulrev_property_data'; - }); - - $this->entityStorage->expects($this->once()) - ->method('getTableMapping') - ->willReturn($table_mapping); - - $this->setupFieldStorageDefinition(); - - $data = $this->viewsData->getViewsData(); - - // Check the base fields. - $this->assertFalse(isset($data['entity_test_mulrev']['id'])); - $this->assertFalse(isset($data['entity_test_mulrev']['type'])); - $this->assertFalse(isset($data['entity_test_mulrev']['revision_id'])); - $this->assertUuidField($data['entity_test_mulrev']['uuid']); - $this->assertField($data['entity_test_mulrev']['uuid'], 'uuid'); - - // Also ensure that field_data only fields don't appear on the base table. - $this->assertFalse(isset($data['entity_test_mulrev']['name'])); - $this->assertFalse(isset($data['entity_test_mul']['description'])); - $this->assertFalse(isset($data['entity_test_mul']['description__value'])); - $this->assertFalse(isset($data['entity_test_mul']['description__format'])); - $this->assertFalse(isset($data['entity_test_mul']['homepage'])); - $this->assertFalse(isset($data['entity_test_mulrev']['langcode'])); - $this->assertFalse(isset($data['entity_test_mulrev']['user_id'])); - - // Check the revision fields. The revision ID should only appear in the data - // table. - $this->assertFalse(isset($data['entity_test_mulrev_revision']['revision_id'])); - - // Also ensure that field_data only fields don't appear on the revision table. - $this->assertFalse(isset($data['entity_test_mulrev_revision']['id'])); - $this->assertFalse(isset($data['entity_test_mulrev_revision']['name'])); - $this->assertFalse(isset($data['entity_test_mulrev_revision']['description'])); - $this->assertFalse(isset($data['entity_test_mulrev_revision']['description__value'])); - $this->assertFalse(isset($data['entity_test_mulrev_revision']['description__format'])); - $this->assertFalse(isset($data['entity_test_mulrev_revision']['homepage'])); - $this->assertFalse(isset($data['entity_test_mulrev_revision']['user_id'])); - - // Check the data fields. - $this->assertNumericField($data['entity_test_mulrev_property_data']['id']); - $this->assertField($data['entity_test_mulrev_property_data']['id'], 'id'); - $this->assertNumericField($data['entity_test_mulrev_property_data']['revision_id']); - $this->assertField($data['entity_test_mulrev_property_data']['revision_id'], 'revision_id'); - $this->assertLanguageField($data['entity_test_mulrev_property_data']['langcode']); - $this->assertField($data['entity_test_mulrev_property_data']['langcode'], 'langcode'); - $this->assertStringField($data['entity_test_mulrev_property_data']['name']); - $this->assertField($data['entity_test_mulrev_property_data']['name'], 'name'); - - $this->assertLongTextField($data['entity_test_mulrev_property_data'], 'description'); - $this->assertField($data['entity_test_mulrev_property_data']['description__value'], 'description'); - $this->assertField($data['entity_test_mulrev_property_data']['description__format'], 'description'); - $this->assertUriField($data['entity_test_mulrev_property_data']['homepage']); - $this->assertField($data['entity_test_mulrev_property_data']['homepage'], 'homepage'); - - $this->assertEntityReferenceField($data['entity_test_mulrev_property_data']['user_id']); - $this->assertField($data['entity_test_mulrev_property_data']['user_id'], 'user_id'); - $relationship = $data['entity_test_mulrev_property_data']['user_id']['relationship']; - $this->assertEquals('users_field_data', $relationship['base']); - $this->assertEquals('uid', $relationship['base field']); - - // Check the property data fields. - $this->assertNumericField($data['entity_test_mulrev_property_revision']['id']); - $this->assertField($data['entity_test_mulrev_property_revision']['id'], 'id'); - - $this->assertLanguageField($data['entity_test_mulrev_property_revision']['langcode']); - $this->assertField($data['entity_test_mulrev_property_revision']['langcode'], 'langcode'); - $this->assertEquals('Translation language', $data['entity_test_mulrev_property_revision']['langcode']['title']); - - $this->assertStringField($data['entity_test_mulrev_property_revision']['name']); - $this->assertField($data['entity_test_mulrev_property_revision']['name'], 'name'); - - $this->assertLongTextField($data['entity_test_mulrev_property_revision'], 'description'); - $this->assertField($data['entity_test_mulrev_property_revision']['description__value'], 'description'); - $this->assertField($data['entity_test_mulrev_property_revision']['description__format'], 'description'); - - $this->assertUriField($data['entity_test_mulrev_property_revision']['homepage']); - $this->assertField($data['entity_test_mulrev_property_revision']['homepage'], 'homepage'); - - $this->assertEntityReferenceField($data['entity_test_mulrev_property_revision']['user_id']); - $this->assertField($data['entity_test_mulrev_property_revision']['user_id'], 'user_id'); - $relationship = $data['entity_test_mulrev_property_revision']['user_id']['relationship']; - $this->assertEquals('users_field_data', $relationship['base']); - $this->assertEquals('uid', $relationship['base field']); - - $this->assertStringField($data['entity_test_mulrev__string']['string_value']); - $this->assertField($data['entity_test_mulrev__string']['string_value'], 'string'); - $this->assertEquals([ - 'left_field' => 'id', - 'field' => 'entity_id', - 'extra' => [[ - 'field' => 'deleted', - 'value' => 0, - 'numeric' => TRUE, - ], - ], - ], $data['entity_test_mulrev__string']['table']['join']['entity_test_mulrev_property_data']); - - $this->assertStringField($data['entity_test_mulrev_revision__string']['string_value']); - $this->assertField($data['entity_test_mulrev_revision__string']['string_value'], 'string'); - $this->assertEquals([ - 'left_field' => 'revision_id', - 'field' => 'entity_id', - 'extra' => [[ - 'field' => 'deleted', - 'value' => 0, - 'numeric' => TRUE, - ], - ], - ], $data['entity_test_mulrev_revision__string']['table']['join']['entity_test_mulrev_property_revision']); - } - - /** - * Tests generic stuff per field. - * - * @param array $data - * The views data to check. - * @param string $field_name - * The entity field name. - */ - protected function assertField($data, $field_name) { - $this->assertEquals($field_name, $data['entity field']); - } - - /** - * Tests add link types. - */ - public function testEntityLinks() { - $this->baseEntityType->setLinkTemplate('canonical', '/entity_test/{entity_test}'); - $this->baseEntityType->setLinkTemplate('edit-form', '/entity_test/{entity_test}/edit'); - $this->baseEntityType->setLinkTemplate('delete-form', '/entity_test/{entity_test}/delete'); - - $data = $this->viewsData->getViewsData(); - foreach (['entity_test', 'entity_test_revision'] as $table_name) { - $this->assertEquals('entity_link', $data[$table_name]['view_entity_test']['field']['id']); - $this->assertEquals('entity_link_edit', $data[$table_name]['edit_entity_test']['field']['id']); - $this->assertEquals('entity_link_delete', $data[$table_name]['delete_entity_test']['field']['id']); - } - } - - /** - * Tests additional edit links. - */ - public function testEntityLinksJustEditForm() { - $this->baseEntityType->setLinkTemplate('edit-form', '/entity_test/{entity_test}/edit'); - - $data = $this->viewsData->getViewsData(); - - foreach (['entity_test', 'entity_test_revision'] as $table_name) { - $this->assertFalse(isset($data[$table_name]['view_entity_test'])); - $this->assertFalse(isset($data[$table_name]['delete_entity_test'])); - - $this->assertEquals('entity_link_edit', $data[$table_name]['edit_entity_test']['field']['id']); - } - } - - /** - * @covers ::getViewsData - */ - public function testGetViewsDataWithoutEntityOperations() { - // Make sure there is no list builder. The API does not document is - // supports resetting entity handlers, so this might break in the future. - $this->baseEntityType->setListBuilderClass(NULL); - $data = $this->viewsData->getViewsData(); - $this->assertArrayNotHasKey('operations', $data[$this->baseEntityType->getBaseTable()]); - } - - /** - * @covers ::getViewsData - */ - public function testGetViewsDataWithEntityOperations() { - $this->baseEntityType->setListBuilderClass('\Drupal\Core\Entity\EntityListBuilder'); - $data = $this->viewsData->getViewsData(); - - $tables = ['entity_test', 'entity_test_revision']; - $this->assertSame($tables, array_keys($data)); - foreach ($tables as $table_name) { - $this->assertSame('entity_operations', $data[$table_name]['operations']['field']['id']); - } - } - - /** - * @covers ::getViewsData - */ - public function testGetViewsDataWithNonRevisionableEntityOperations() { - $this->baseEntityType->setListBuilderClass('\Drupal\Core\Entity\EntityListBuilder'); - - $entity_type_without_revisions = $this->baseEntityType; - $views_data = $this->viewsData; - - $entity_type_keys = $entity_type_without_revisions->getKeys(); - unset($entity_type_keys['revision']); - - $entity_type_without_revisions->set('entity_keys', $entity_type_keys); - $views_data->setEntityType($entity_type_without_revisions); - - $data = $views_data->getViewsData(); - - $tables = ['entity_test']; - $this->assertSame($tables, array_keys($data)); - foreach ($tables as $table_name) { - $this->assertSame('entity_operations', $data[$table_name]['operations']['field']['id']); - } - } - - /** - * Tests views data for a string field. - * - * @param $data - * The views data to check. - */ - protected function assertStringField($data) { - $this->assertEquals('field', $data['field']['id']); - $this->assertEquals('string', $data['filter']['id']); - $this->assertEquals('string', $data['argument']['id']); - $this->assertEquals('standard', $data['sort']['id']); - } - - /** - * Tests views data for a URI field. - * - * @param $data - * The views data to check. - */ - protected function assertUriField($data) { - $this->assertEquals('field', $data['field']['id']); - $this->assertEquals('string', $data['field']['default_formatter']); - $this->assertEquals('string', $data['filter']['id']); - $this->assertEquals('string', $data['argument']['id']); - $this->assertEquals('standard', $data['sort']['id']); - } - - /** - * Tests views data for a long text field. - * - * @param $data - * The views data for the table this field is in. - * @param $field_name - * The name of the field being checked. - */ - protected function assertLongTextField($data, $field_name) { - $value_field = $data[$field_name . '__value']; - $this->assertEquals('field', $value_field['field']['id']); - $this->assertEquals($field_name . '__format', $value_field['field']['format']); - $this->assertEquals('string', $value_field['filter']['id']); - $this->assertEquals('string', $value_field['argument']['id']); - $this->assertEquals('standard', $value_field['sort']['id']); - - $this->assertStringField($data[$field_name . '__format']); - } - - /** - * Tests views data for a UUID field. - * - * @param array $data - * The views data to check. - */ - protected function assertUuidField($data) { - // @todo Can we provide additional support for UUIDs in views? - $this->assertEquals('field', $data['field']['id']); - $this->assertFalse($data['field']['click sortable']); - $this->assertEquals('string', $data['filter']['id']); - $this->assertEquals('string', $data['argument']['id']); - $this->assertEquals('standard', $data['sort']['id']); - } - - /** - * Tests views data for a numeric field. - * - * @param array $data - * The views data to check. - */ - protected function assertNumericField($data) { - $this->assertEquals('field', $data['field']['id']); - $this->assertEquals('numeric', $data['filter']['id']); - $this->assertEquals('numeric', $data['argument']['id']); - $this->assertEquals('standard', $data['sort']['id']); - } - - /** - * Tests views data for a language field. - * - * @param array $data - * The views data to check. - */ - protected function assertLanguageField($data) { - $this->assertEquals('field', $data['field']['id']); - $this->assertEquals('language', $data['filter']['id']); - $this->assertEquals('language', $data['argument']['id']); - $this->assertEquals('standard', $data['sort']['id']); - } - - /** - * Tests views data for an entity reference field. - */ - protected function assertEntityReferenceField($data) { - $this->assertEquals('field', $data['field']['id']); - $this->assertEquals('numeric', $data['filter']['id']); - $this->assertEquals('numeric', $data['argument']['id']); - $this->assertEquals('standard', $data['sort']['id']); - } - - /** - * Tests views data for a bundle field. - */ - protected function assertBundleField($data) { - $this->assertEquals('field', $data['field']['id']); - $this->assertEquals('bundle', $data['filter']['id']); - $this->assertEquals('string', $data['argument']['id']); - $this->assertEquals('standard', $data['sort']['id']); - } - - /** - * Returns entity info for the user entity. - * - * @return array - */ - protected static function userEntityInfo() { - return new ContentEntityType([ - 'id' => 'user', - 'class' => 'Drupal\user\Entity\User', - 'label' => 'User', - 'base_table' => 'users', - 'data_table' => 'users_field_data', - 'entity_keys' => [ - 'id' => 'uid', - 'uuid' => 'uuid', - ], - ]); - } - -} - -class TestEntityViewsData extends EntityViewsData { - - public function setEntityType(EntityTypeInterface $entity_type) { - $this->entityType = $entity_type; - } - -} - -class TestEntityType extends ContentEntityType { - - /** - * Sets a specific entity key. - * - * @param string $key - * The name of the entity key. - * @param string $value - * The new value of the key. - * - * @return $this - */ - public function setKey($key, $value) { - $this->entity_keys[$key] = $value; - return $this; - } - -}