1bd3970536f80877583f5c1ccb509beac9648870
[yaffs-website] / web / core / modules / views / tests / src / Unit / EntityViewsDataTest.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Tests\views\Unit\EntityViewsDataTest.
6  */
7
8 namespace Drupal\Tests\views\Unit;
9
10 use Drupal\Core\Config\Entity\ConfigEntityType;
11 use Drupal\Core\Entity\ContentEntityType;
12 use Drupal\Core\Entity\EntityTypeInterface;
13 use Drupal\Core\Entity\Sql\DefaultTableMapping;
14 use Drupal\Core\Field\BaseFieldDefinition;
15 use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
16 use Drupal\Core\Field\Plugin\Field\FieldType\IntegerItem;
17 use Drupal\Core\Field\Plugin\Field\FieldType\LanguageItem;
18 use Drupal\Core\Field\Plugin\Field\FieldType\StringItem;
19 use Drupal\Core\Field\Plugin\Field\FieldType\UriItem;
20 use Drupal\Core\Field\Plugin\Field\FieldType\UuidItem;
21 use Drupal\Core\State\StateInterface;
22 use Drupal\Core\TypedData\TypedDataManagerInterface;
23 use Drupal\text\Plugin\Field\FieldType\TextLongItem;
24 use Drupal\entity_test\Entity\EntityTest;
25 use Drupal\entity_test\Entity\EntityTestMul;
26 use Drupal\entity_test\Entity\EntityTestMulRev;
27 use Drupal\Tests\UnitTestCase;
28 use Drupal\views\EntityViewsData;
29 use Prophecy\Argument;
30 use Symfony\Component\DependencyInjection\ContainerBuilder;
31
32 /**
33  * @coversDefaultClass \Drupal\views\EntityViewsData
34  * @group Views
35  */
36 class EntityViewsDataTest extends UnitTestCase {
37
38   /**
39    * Entity info to use in this test.
40    *
41    * @var \Drupal\Core\Entity\EntityTypeInterface|\Drupal\Tests\views\Unit\TestEntityType
42    */
43   protected $baseEntityType;
44
45   /**
46    * The mocked entity storage.
47    *
48    * @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage|\PHPUnit_Framework_MockObject_MockObject
49    */
50   protected $entityStorage;
51
52   /**
53    * The mocked entity manager.
54    *
55    * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
56    */
57   protected $entityManager;
58
59   /**
60    * The mocked module handler.
61    *
62    * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
63    */
64   protected $moduleHandler;
65
66   /**
67    * The mocked translation manager.
68    *
69    * @var \Drupal\Core\StringTranslation\TranslationInterface|\PHPUnit_Framework_MockObject_MockObject
70    */
71   protected $translationManager;
72
73   /**
74    * The tested entity views controller.
75    *
76    * @var \Drupal\Tests\views\Unit\TestEntityViewsData
77    */
78   protected $viewsData;
79
80   /**
81    * {@inheritdoc}
82    */
83   protected function setUp() {
84     $this->entityStorage = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorage')
85       ->disableOriginalConstructor()
86       ->getMock();
87     $this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
88
89     $typed_data_manager = $this->getMock(TypedDataManagerInterface::class);
90     $typed_data_manager->expects($this->any())
91       ->method('createDataDefinition')
92       ->willReturn($this->getMock('Drupal\Core\TypedData\DataDefinitionInterface'));
93
94     $typed_data_manager->expects($this->any())
95       ->method('getDefinition')
96       ->will($this->returnValueMap([
97         'entity:user' => ['class' => '\Drupal\Core\TypedData\DataDefinitionInterface'],
98         'field_item:string_long' => ['class' => '\Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem'],
99       ]));
100
101     $this->baseEntityType = new TestEntityType([
102       'base_table' => 'entity_test',
103       'id' => 'entity_test',
104       'label' => 'Entity test',
105       'entity_keys' => [
106         'uuid' => 'uuid',
107         'id' => 'id',
108         'langcode' => 'langcode',
109         'bundle' => 'type',
110         'revision' => 'revision_id',
111       ],
112       'provider' => 'entity_test',
113       'list_cache_contexts' => ['entity_test_list_cache_context'],
114     ]);
115
116     $this->translationManager = $this->getStringTranslationStub();
117     $this->baseEntityType->setStringTranslation($this->translationManager);
118     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
119
120     $this->viewsData = new TestEntityViewsData($this->baseEntityType, $this->entityStorage, $this->entityManager, $this->moduleHandler, $this->translationManager);
121
122     $field_type_manager = $this->getMockBuilder('Drupal\Core\Field\FieldTypePluginManager')
123       ->disableOriginalConstructor()
124       ->getMock();
125     $field_type_manager->expects($this->any())
126       ->method('getDefaultStorageSettings')
127       ->willReturn([]);
128     $field_type_manager->expects($this->any())
129       ->method('getDefaultFieldSettings')
130       ->willReturn([]);
131
132     $state = $this->prophesize(StateInterface::class);
133     $state->get(Argument::any(), [])->willReturn([]);
134
135     $container = new ContainerBuilder();
136     $container->set('plugin.manager.field.field_type', $field_type_manager);
137     $container->set('entity.manager', $this->entityManager);
138     $container->set('typed_data_manager', $typed_data_manager);
139     $container->set('state', $state->reveal());
140     \Drupal::setContainer($container);
141   }
142
143   /**
144    * Helper method to setup base fields.
145    *
146    * @param \Drupal\Core\Field\BaseFieldDefinition[] $base_fields
147    *   The base fields which are adapted.
148    *
149    * @return \Drupal\Core\Field\BaseFieldDefinition[]
150    *   The setup base fields.
151    */
152   protected function setupBaseFields(array $base_fields) {
153     // Add a description field to the fields supplied by the EntityTest
154     // classes. This example comes from the taxonomy Term entity.
155     $base_fields['description'] = BaseFieldDefinition::create('text_long')
156       ->setLabel('Description')
157       ->setDescription('A description of the term.')
158       ->setTranslatable(TRUE)
159       ->setDisplayOptions('view', [
160           'label' => 'hidden',
161           'type' => 'text_default',
162           'weight' => 0,
163         ])
164       ->setDisplayConfigurable('view', TRUE)
165       ->setDisplayOptions('form', [
166           'type' => 'text_textfield',
167           'weight' => 0,
168         ])
169       ->setDisplayConfigurable('form', TRUE);
170
171     // Add a URL field; this example is from the Comment entity.
172     $base_fields['homepage'] = BaseFieldDefinition::create('uri')
173       ->setLabel('Homepage')
174       ->setDescription("The comment author's home page address.")
175       ->setTranslatable(TRUE)
176       ->setSetting('max_length', 255);
177
178     // A base field with cardinality > 1
179     $base_fields['string']  = BaseFieldDefinition::create('string')
180       ->setLabel('Strong')
181       ->setTranslatable(TRUE)
182       ->setCardinality(2);
183
184     foreach ($base_fields as $name => $base_field) {
185       $base_field->setName($name);
186     }
187     return $base_fields;
188   }
189
190   /**
191    * Tests base tables.
192    */
193   public function testBaseTables() {
194     $data = $this->viewsData->getViewsData();
195
196     $this->assertEquals('entity_test', $data['entity_test']['table']['entity type']);
197     $this->assertEquals(FALSE, $data['entity_test']['table']['entity revision']);
198     $this->assertEquals('Entity test', $data['entity_test']['table']['group']);
199     $this->assertEquals('entity_test', $data['entity_test']['table']['provider']);
200
201     $this->assertEquals('id', $data['entity_test']['table']['base']['field']);
202     $this->assertEquals(['entity_test_list_cache_context'], $data['entity_test']['table']['base']['cache_contexts']);
203     $this->assertEquals('Entity test', $data['entity_test']['table']['base']['title']);
204
205     $this->assertFalse(isset($data['entity_test']['table']['defaults']));
206
207     $this->assertFalse(isset($data['entity_test_mul_property_data']));
208     $this->assertFalse(isset($data['revision_table']));
209     $this->assertFalse(isset($data['revision_data_table']));
210   }
211
212   /**
213    * Tests data_table support.
214    */
215   public function testDataTable() {
216     $entity_type = $this->baseEntityType
217       ->set('data_table', 'entity_test_mul_property_data')
218       ->set('id', 'entity_test_mul')
219       ->set('translatable', TRUE)
220       ->setKey('label', 'label');
221
222     $this->viewsData->setEntityType($entity_type);
223
224     // Tests the join definition between the base and the data table.
225     $data = $this->viewsData->getViewsData();
226     $base_views_data = $data['entity_test'];
227
228     // Ensure that the base table is set to the data table.
229     $this->assertEquals('id', $data['entity_test_mul_property_data']['table']['base']['field']);
230     $this->assertEquals('Entity test', $data['entity_test_mul_property_data']['table']['base']['title']);
231     $this->assertFalse(isset($data['entity_test']['table']['base']));
232
233     $this->assertEquals('entity_test_mul', $data['entity_test_mul_property_data']['table']['entity type']);
234     $this->assertEquals(FALSE, $data['entity_test_mul_property_data']['table']['entity revision']);
235     $this->assertEquals('Entity test', $data['entity_test_mul_property_data']['table']['group']);
236     $this->assertEquals('entity_test', $data['entity_test']['table']['provider']);
237     $this->assertEquals(['field' => 'label', 'table' => 'entity_test_mul_property_data'], $data['entity_test_mul_property_data']['table']['base']['defaults']);
238
239     // Ensure the join information is set up properly.
240     $this->assertCount(1, $base_views_data['table']['join']);
241     $this->assertEquals(['entity_test_mul_property_data' => ['left_field' => 'id', 'field' => 'id', 'type' => 'INNER']], $base_views_data['table']['join']);
242     $this->assertFalse(isset($data['revision_table']));
243     $this->assertFalse(isset($data['revision_data_table']));
244   }
245
246   /**
247    * Tests revision table without data table support.
248    */
249   public function testRevisionTableWithoutDataTable() {
250     $entity_type = $this->baseEntityType
251       ->set('revision_table', 'entity_test_mulrev_revision')
252       ->set('revision_data_table', NULL)
253       ->set('id', 'entity_test_mulrev')
254       ->setKey('revision', 'revision_id');
255     $this->viewsData->setEntityType($entity_type);
256
257     $data = $this->viewsData->getViewsData();
258
259     $this->assertEquals('Entity test revisions', $data['entity_test_mulrev_revision']['table']['base']['title']);
260     $this->assertEquals('revision_id', $data['entity_test_mulrev_revision']['table']['base']['field']);
261
262     $this->assertEquals(FALSE, $data['entity_test']['table']['entity revision']);
263     $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_revision']['table']['entity type']);
264     $this->assertEquals(TRUE, $data['entity_test_mulrev_revision']['table']['entity revision']);
265     $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_revision']['table']['entity type']);
266     $this->assertEquals(TRUE, $data['entity_test_mulrev_revision']['table']['entity revision']);
267
268     $this->assertEquals('Entity test revision', $data['entity_test_mulrev_revision']['table']['group']);
269     $this->assertEquals('entity_test', $data['entity_test']['table']['provider']);
270
271     // Ensure the join information is set up properly.
272     // Tests the join definition between the base and the revision table.
273     $revision_data = $data['entity_test_mulrev_revision'];
274     $this->assertCount(1, $revision_data['table']['join']);
275     $this->assertEquals(['entity_test' => ['left_field' => 'revision_id', 'field' => 'revision_id', 'type' => 'INNER']], $revision_data['table']['join']);
276     $this->assertFalse(isset($data['data_table']));
277   }
278
279   /**
280    * Tests revision table with data table support.
281    */
282   public function testRevisionTableWithRevisionDataTableAndDataTable() {
283     $entity_type = $this->baseEntityType
284       ->set('data_table', 'entity_test_mul_property_data')
285       ->set('revision_table', 'entity_test_mulrev_revision')
286       ->set('revision_data_table', 'entity_test_mulrev_property_revision')
287       ->set('id', 'entity_test_mulrev')
288       ->set('translatable', TRUE)
289       ->setKey('revision', 'revision_id');
290     $this->viewsData->setEntityType($entity_type);
291
292     $data = $this->viewsData->getViewsData();
293
294     $this->assertEquals('Entity test revisions', $data['entity_test_mulrev_property_revision']['table']['base']['title']);
295     $this->assertEquals('revision_id', $data['entity_test_mulrev_property_revision']['table']['base']['field']);
296     $this->assertFalse(isset($data['entity_test_mulrev_revision']['table']['base']));
297
298     $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_property_revision']['table']['entity type']);
299     $this->assertEquals('Entity test revision', $data['entity_test_mulrev_revision']['table']['group']);
300     $this->assertEquals('entity_test', $data['entity_test']['table']['provider']);
301
302     // Ensure the join information is set up properly.
303     // Tests the join definition between the base and the revision table.
304     $revision_field_data = $data['entity_test_mulrev_property_revision'];
305     $this->assertCount(1, $revision_field_data['table']['join']);
306     $this->assertEquals([
307       'entity_test_mul_property_data' => [
308         'left_field' => 'revision_id',
309         'field' => 'revision_id',
310         'type' => 'INNER',
311       ],
312     ], $revision_field_data['table']['join']);
313
314     $revision_base_data = $data['entity_test_mulrev_revision'];
315     $this->assertCount(1, $revision_base_data['table']['join']);
316     $this->assertEquals([
317       'entity_test_mulrev_property_revision' => [
318         'left_field' => 'revision_id',
319         'field' => 'revision_id',
320         'type' => 'INNER',
321       ],
322     ], $revision_base_data['table']['join']);
323
324     $this->assertFalse(isset($data['data_table']));
325   }
326
327   /**
328    * Tests revision table with data table support.
329    */
330   public function testRevisionTableWithRevisionDataTable() {
331     $entity_type = $this->baseEntityType
332       ->set('revision_table', 'entity_test_mulrev_revision')
333       ->set('revision_data_table', 'entity_test_mulrev_property_revision')
334       ->set('id', 'entity_test_mulrev')
335       ->set('translatable', TRUE)
336       ->setKey('revision', 'revision_id');
337     $this->viewsData->setEntityType($entity_type);
338
339     $data = $this->viewsData->getViewsData();
340
341     $this->assertEquals('Entity test revisions', $data['entity_test_mulrev_property_revision']['table']['base']['title']);
342     $this->assertEquals('revision_id', $data['entity_test_mulrev_property_revision']['table']['base']['field']);
343     $this->assertFalse(isset($data['entity_test_mulrev_revision']['table']['base']));
344
345     $this->assertEquals('entity_test_mulrev', $data['entity_test_mulrev_property_revision']['table']['entity type']);
346     $this->assertEquals('Entity test revision', $data['entity_test_mulrev_revision']['table']['group']);
347     $this->assertEquals('entity_test', $data['entity_test']['table']['provider']);
348
349     // Ensure the join information is set up properly.
350     // Tests the join definition between the base and the revision table.
351     $revision_field_data = $data['entity_test_mulrev_property_revision'];
352     $this->assertCount(1, $revision_field_data['table']['join']);
353     $this->assertEquals([
354       'entity_test_mulrev_field_data' => [
355         'left_field' => 'revision_id',
356         'field' => 'revision_id',
357         'type' => 'INNER',
358       ],
359     ], $revision_field_data['table']['join']);
360
361     $revision_base_data = $data['entity_test_mulrev_revision'];
362     $this->assertCount(1, $revision_base_data['table']['join']);
363     $this->assertEquals([
364       'entity_test_mulrev_property_revision' => [
365         'left_field' => 'revision_id',
366         'field' => 'revision_id',
367         'type' => 'INNER',
368       ],
369     ], $revision_base_data['table']['join']);
370     $this->assertFalse(isset($data['data_table']));
371   }
372
373   /**
374    * Helper method to mock all store definitions.
375    */
376   protected function setupFieldStorageDefinition() {
377     $id_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
378     $id_field_storage_definition->expects($this->any())
379       ->method('getSchema')
380       ->willReturn(IntegerItem::schema($id_field_storage_definition));
381     $uuid_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
382     $uuid_field_storage_definition->expects($this->any())
383       ->method('getSchema')
384       ->willReturn(UuidItem::schema($uuid_field_storage_definition));
385     $type_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
386     $type_field_storage_definition->expects($this->any())
387       ->method('getSchema')
388       ->willReturn(StringItem::schema($type_field_storage_definition));
389     $langcode_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
390     $langcode_field_storage_definition->expects($this->any())
391       ->method('getSchema')
392       ->willReturn(LanguageItem::schema($langcode_field_storage_definition));
393     $name_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
394     $name_field_storage_definition->expects($this->any())
395       ->method('getSchema')
396       ->willReturn(StringItem::schema($name_field_storage_definition));
397     $description_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
398     $description_field_storage_definition->expects($this->any())
399       ->method('getSchema')
400       ->willReturn(TextLongItem::schema($description_field_storage_definition));
401     $homepage_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
402     $homepage_field_storage_definition->expects($this->any())
403       ->method('getSchema')
404       ->willReturn(UriItem::schema($homepage_field_storage_definition));
405     $string_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
406     $string_field_storage_definition->expects($this->any())
407       ->method('getSchema')
408       ->willReturn(StringItem::schema($string_field_storage_definition));
409
410     // Setup the user_id entity reference field.
411     $this->entityManager->expects($this->any())
412       ->method('getDefinition')
413       ->willReturnMap([
414           ['user', TRUE, static::userEntityInfo()],
415         ]
416       );
417     $user_id_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
418     $user_id_field_storage_definition->expects($this->any())
419       ->method('getSetting')
420       ->with('target_type')
421       ->willReturn('user');
422     $user_id_field_storage_definition->expects($this->any())
423       ->method('getSettings')
424       ->willReturn(['target_type' => 'user']);
425     $user_id_field_storage_definition->expects($this->any())
426       ->method('getSchema')
427       ->willReturn(EntityReferenceItem::schema($user_id_field_storage_definition));
428
429     $revision_id_field_storage_definition = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
430     $revision_id_field_storage_definition->expects($this->any())
431       ->method('getSchema')
432       ->willReturn(IntegerItem::schema($revision_id_field_storage_definition));
433
434     $this->entityManager->expects($this->any())
435       ->method('getFieldStorageDefinitions')
436       ->willReturn([
437         'id' => $id_field_storage_definition,
438         'uuid' => $uuid_field_storage_definition,
439         'type' => $type_field_storage_definition,
440         'langcode' => $langcode_field_storage_definition,
441         'name' => $name_field_storage_definition,
442         'description' => $description_field_storage_definition,
443         'homepage' => $homepage_field_storage_definition,
444         'string' => $string_field_storage_definition,
445         'user_id' => $user_id_field_storage_definition,
446         'revision_id' => $revision_id_field_storage_definition,
447       ]);
448   }
449
450   /**
451    * Tests fields on the base table.
452    */
453   public function testBaseTableFields() {
454     $base_field_definitions = $this->setupBaseFields(EntityTest::baseFieldDefinitions($this->baseEntityType));
455     $user_base_field_definitions = [
456       'uid' => BaseFieldDefinition::create('integer')
457         ->setLabel('ID')
458         ->setDescription('The ID of the user entity.')
459         ->setReadOnly(TRUE)
460         ->setSetting('unsigned', TRUE)
461     ];
462     $this->entityManager->expects($this->any())
463       ->method('getBaseFieldDefinitions')
464       ->will($this->returnValueMap([
465         ['user', $user_base_field_definitions],
466         ['entity_test', $base_field_definitions],
467       ]));
468     // Setup the table mapping.
469     $table_mapping = $this->getMockBuilder(DefaultTableMapping::class)
470       ->disableOriginalConstructor()
471       ->getMock();
472     $table_mapping->expects($this->any())
473       ->method('getTableNames')
474       ->willReturn(['entity_test', 'entity_test__string']);
475     $table_mapping->expects($this->any())
476       ->method('getColumnNames')
477       ->willReturnMap([
478         ['id', ['value' => 'id']],
479         ['uuid', ['value' => 'uuid']],
480         ['type', ['value' => 'type']],
481         ['langcode', ['value' => 'langcode']],
482         ['name', ['value' => 'name']],
483         ['description', ['value' => 'description__value', 'format' => 'description__format']],
484         ['homepage', ['value' => 'homepage']],
485         ['user_id', ['target_id' => 'user_id']],
486         ['string', ['value' => 'string_value']],
487       ]);
488     $table_mapping->expects($this->any())
489       ->method('getFieldNames')
490       ->willReturnMap([
491         ['entity_test', ['id', 'uuid', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']],
492         ['entity_test__string', ['string']],
493       ]);
494     $table_mapping->expects($this->any())
495       ->method('requiresDedicatedTableStorage')
496       ->willReturnCallback(function (BaseFieldDefinition $base_field) {
497         return $base_field->getName() === 'string';
498       });
499     $table_mapping->expects($this->any())
500       ->method('getDedicatedDataTableName')
501       ->willReturnCallback(function (BaseFieldDefinition $base_field) {
502         if ($base_field->getName() === 'string') {
503           return 'entity_test__string';
504         }
505       });
506
507     $this->entityStorage->expects($this->once())
508       ->method('getTableMapping')
509       ->willReturn($table_mapping);
510
511     $this->setupFieldStorageDefinition();
512
513     $data = $this->viewsData->getViewsData();
514
515     $this->assertNumericField($data['entity_test']['id']);
516     $this->assertField($data['entity_test']['id'], 'id');
517     $this->assertUuidField($data['entity_test']['uuid']);
518     $this->assertField($data['entity_test']['uuid'], 'uuid');
519     $this->assertStringField($data['entity_test']['type']);
520     $this->assertEquals('type', $data['entity_test']['type']['entity field']);
521
522     $this->assertLanguageField($data['entity_test']['langcode']);
523     $this->assertField($data['entity_test']['langcode'], 'langcode');
524     $this->assertEquals('Original language', $data['entity_test']['langcode']['title']);
525
526     $this->assertStringField($data['entity_test']['name']);
527     $this->assertField($data['entity_test']['name'], 'name');
528
529     $this->assertLongTextField($data['entity_test'], 'description');
530     $this->assertField($data['entity_test']['description__value'], 'description');
531     $this->assertField($data['entity_test']['description__format'], 'description');
532
533     $this->assertUriField($data['entity_test']['homepage']);
534     $this->assertField($data['entity_test']['homepage'], 'homepage');
535
536     $this->assertEntityReferenceField($data['entity_test']['user_id']);
537     $this->assertField($data['entity_test']['user_id'], 'user_id');
538
539     $relationship = $data['entity_test']['user_id']['relationship'];
540     $this->assertEquals('users_field_data', $relationship['base']);
541     $this->assertEquals('uid', $relationship['base field']);
542
543     // The string field name should be used as the 'entity field' but the actual
544     // field should reflect what the column mapping is using for multi-value
545     // base fields NOT just the field name. The actual column name returned from
546     // mappings in the test mocks is 'value'.
547     $this->assertStringField($data['entity_test__string']['string_value']);
548     $this->assertField($data['entity_test__string']['string_value'], 'string');
549     $this->assertEquals([
550       'left_field' => 'id',
551       'field' => 'entity_id',
552       'extra' => [[
553           'field' => 'deleted',
554           'value' => 0,
555           'numeric' => TRUE,
556         ],
557       ],
558     ], $data['entity_test__string']['table']['join']['entity_test']);
559   }
560
561   /**
562    * Tests fields on the data table.
563    */
564   public function testDataTableFields() {
565     $entity_type = $this->baseEntityType
566       ->set('data_table', 'entity_test_mul_property_data')
567       ->set('base_table', 'entity_test_mul')
568       ->set('id', 'entity_test_mul')
569       ->setKey('bundle', 'type');
570     $base_field_definitions = $this->setupBaseFields(EntityTestMul::baseFieldDefinitions($this->baseEntityType));
571     $base_field_definitions['type'] = BaseFieldDefinition::create('entity_reference')
572       ->setLabel('entity test type')
573       ->setSetting('target_type', 'entity_test_bundle')
574       ->setTranslatable(TRUE);
575     $base_field_definitions = $this->setupBaseFields($base_field_definitions);
576     $user_base_field_definitions = [
577       'uid' => BaseFieldDefinition::create('integer')
578         ->setLabel('ID')
579         ->setDescription('The ID of the user entity.')
580         ->setReadOnly(TRUE)
581         ->setSetting('unsigned', TRUE)
582     ];
583     $entity_test_type = new ConfigEntityType(['id' => 'entity_test_bundle']);
584
585     $this->entityManager->expects($this->any())
586       ->method('getBaseFieldDefinitions')
587       ->will($this->returnValueMap([
588         ['user', $user_base_field_definitions],
589         ['entity_test_mul', $base_field_definitions],
590       ]));
591
592     $this->viewsData->setEntityType($entity_type);
593
594     // Setup the table mapping.
595     $table_mapping = $this->getMockBuilder(DefaultTableMapping::class)
596       ->disableOriginalConstructor()
597       ->getMock();
598     $table_mapping->expects($this->any())
599       ->method('getTableNames')
600       ->willReturn(['entity_test_mul', 'entity_test_mul_property_data', 'entity_test_mul__string']);
601     $table_mapping->expects($this->any())
602       ->method('getColumnNames')
603       ->willReturnMap([
604         ['id', ['value' => 'id']],
605         ['uuid', ['value' => 'uuid']],
606         ['type', ['value' => 'type']],
607         ['langcode', ['value' => 'langcode']],
608         ['name', ['value' => 'name']],
609         ['description', ['value' => 'description__value', 'format' => 'description__format']],
610         ['homepage', ['value' => 'homepage']],
611         ['user_id', ['target_id' => 'user_id']],
612         ['string', ['value' => 'string_value']],
613       ]);
614     $table_mapping->expects($this->any())
615       ->method('getFieldNames')
616       ->willReturnMap([
617         ['entity_test_mul', ['uuid']],
618         ['entity_test_mul_property_data', ['id', 'type', 'langcode', 'name', 'description', 'homepage', 'user_id']],
619         ['entity_test_mul__string', ['string']],
620       ]);
621
622     $table_mapping->expects($this->any())
623       ->method('getFieldTableName')
624       ->willReturnCallback(function ($field) {
625         if ($field == 'uuid') {
626           return 'entity_test_mul';
627         }
628         return 'entity_test_mul_property_data';
629       });
630     $table_mapping->expects($this->any())
631       ->method('requiresDedicatedTableStorage')
632       ->willReturnCallback(function (BaseFieldDefinition $base_field) {
633         return $base_field->getName() === 'string';
634       });
635     $table_mapping->expects($this->any())
636       ->method('getDedicatedDataTableName')
637       ->willReturnCallback(function (BaseFieldDefinition $base_field) {
638         if ($base_field->getName() === 'string') {
639           return 'entity_test_mul__string';
640         }
641       });
642
643     $this->entityStorage->expects($this->once())
644       ->method('getTableMapping')
645       ->willReturn($table_mapping);
646
647     $this->setupFieldStorageDefinition();
648
649     $user_entity_type = static::userEntityInfo();
650     $this->entityManager->expects($this->any())
651       ->method('getDefinition')
652       ->will($this->returnValueMap([
653         ['user', TRUE, $user_entity_type],
654         ['entity_test_bundle', TRUE, $entity_test_type],
655       ]));
656
657     $data = $this->viewsData->getViewsData();
658
659     // Check the base fields.
660     $this->assertFalse(isset($data['entity_test_mul']['id']));
661     $this->assertFalse(isset($data['entity_test_mul']['type']));
662     $this->assertUuidField($data['entity_test_mul']['uuid']);
663     $this->assertField($data['entity_test_mul']['uuid'], 'uuid');
664
665     $this->assertFalse(isset($data['entity_test_mul']['type']['relationship']));
666
667     // Also ensure that field_data only fields don't appear on the base table.
668     $this->assertFalse(isset($data['entity_test_mul']['name']));
669     $this->assertFalse(isset($data['entity_test_mul']['description']));
670     $this->assertFalse(isset($data['entity_test_mul']['description__value']));
671     $this->assertFalse(isset($data['entity_test_mul']['description__format']));
672     $this->assertFalse(isset($data['entity_test_mul']['user_id']));
673     $this->assertFalse(isset($data['entity_test_mul']['homepage']));
674
675     // Check the data fields.
676     $this->assertNumericField($data['entity_test_mul_property_data']['id']);
677     $this->assertField($data['entity_test_mul_property_data']['id'], 'id');
678
679     $this->assertBundleField($data['entity_test_mul_property_data']['type']);
680     $this->assertField($data['entity_test_mul_property_data']['type'], 'type');
681
682     $this->assertLanguageField($data['entity_test_mul_property_data']['langcode']);
683     $this->assertField($data['entity_test_mul_property_data']['langcode'], 'langcode');
684     $this->assertEquals('Translation language', $data['entity_test_mul_property_data']['langcode']['title']);
685
686     $this->assertStringField($data['entity_test_mul_property_data']['name']);
687     $this->assertField($data['entity_test_mul_property_data']['name'], 'name');
688
689     $this->assertLongTextField($data['entity_test_mul_property_data'], 'description');
690     $this->assertField($data['entity_test_mul_property_data']['description__value'], 'description');
691     $this->assertField($data['entity_test_mul_property_data']['description__format'], 'description');
692
693     $this->assertUriField($data['entity_test_mul_property_data']['homepage']);
694     $this->assertField($data['entity_test_mul_property_data']['homepage'], 'homepage');
695
696     $this->assertEntityReferenceField($data['entity_test_mul_property_data']['user_id']);
697     $this->assertField($data['entity_test_mul_property_data']['user_id'], 'user_id');
698     $relationship = $data['entity_test_mul_property_data']['user_id']['relationship'];
699     $this->assertEquals('users_field_data', $relationship['base']);
700     $this->assertEquals('uid', $relationship['base field']);
701
702     $this->assertStringField($data['entity_test_mul__string']['string_value']);
703     $this->assertField($data['entity_test_mul__string']['string_value'], 'string');
704     $this->assertEquals([
705       'left_field' => 'id',
706       'field' => 'entity_id',
707       'extra' => [[
708           'field' => 'deleted',
709           'value' => 0,
710           'numeric' => TRUE,
711         ],
712       ],
713     ], $data['entity_test_mul__string']['table']['join']['entity_test_mul']);
714   }
715
716   /**
717    * Tests fields on the revision table.
718    */
719   public function testRevisionTableFields() {
720     $entity_type = $this->baseEntityType
721       ->set('base_table', 'entity_test_mulrev')
722       ->set('revision_table', 'entity_test_mulrev_revision')
723       ->set('data_table', 'entity_test_mulrev_property_data')
724       ->set('revision_data_table', 'entity_test_mulrev_property_revision')
725       ->set('id', 'entity_test_mulrev')
726       ->set('translatable', TRUE);
727     $base_field_definitions = $this->setupBaseFields(EntityTestMulRev::baseFieldDefinitions($this->baseEntityType));
728     $user_base_field_definitions = [
729       'uid' => BaseFieldDefinition::create('integer')
730         ->setLabel('ID')
731         ->setDescription('The ID of the user entity.')
732         ->setReadOnly(TRUE)
733         ->setSetting('unsigned', TRUE)
734     ];
735     $this->entityManager->expects($this->any())
736       ->method('getBaseFieldDefinitions')
737       ->will($this->returnValueMap([
738         ['user', $user_base_field_definitions],
739         ['entity_test_mulrev', $base_field_definitions],
740       ]));
741
742     $this->viewsData->setEntityType($entity_type);
743
744     // Setup the table mapping.
745     $table_mapping = $this->getMockBuilder(DefaultTableMapping::class)
746       ->disableOriginalConstructor()
747       ->getMock();
748     $table_mapping->expects($this->any())
749       ->method('getTableNames')
750       ->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']);
751     $table_mapping->expects($this->any())
752       ->method('getColumnNames')
753       ->willReturnMap([
754         ['id', ['value' => 'id']],
755         ['uuid', ['value' => 'uuid']],
756         ['type', ['value' => 'type']],
757         ['langcode', ['value' => 'langcode']],
758         ['name', ['value' => 'name']],
759         ['description', ['value' => 'description__value', 'format' => 'description__format']],
760         ['homepage', ['value' => 'homepage']],
761         ['user_id', ['target_id' => 'user_id']],
762         ['revision_id', ['value' => 'revision_id']],
763         ['string', ['value' => 'string_value']],
764       ]);
765     $table_mapping->expects($this->any())
766       ->method('getFieldNames')
767       ->willReturnMap([
768         ['entity_test_mulrev', ['id', 'revision_id', 'uuid', 'type']],
769         ['entity_test_mulrev_revision', ['id', 'revision_id', 'langcode']],
770         ['entity_test_mulrev_property_data', ['id', 'revision_id', 'langcode', 'name', 'description', 'homepage', 'user_id']],
771         ['entity_test_mulrev_property_revision', ['id', 'revision_id', 'langcode', 'name', 'description', 'homepage', 'user_id']],
772         ['entity_test_mulrev__string', ['string']],
773         ['entity_test_mulrev_revision__string', ['string']],
774       ]);
775     $table_mapping->expects($this->any())
776       ->method('requiresDedicatedTableStorage')
777       ->willReturnCallback(function (BaseFieldDefinition $base_field) {
778         return $base_field->getName() === 'string';
779       });
780     $table_mapping->expects($this->any())
781       ->method('getDedicatedDataTableName')
782       ->willReturnCallback(function (BaseFieldDefinition $base_field) {
783         if ($base_field->getName() === 'string') {
784           return 'entity_test_mulrev__string';
785         }
786       });
787
788     $table_mapping->expects($this->any())
789       ->method('getDedicatedRevisionTableName')
790       ->willReturnCallback(function (BaseFieldDefinition $base_field) {
791         if ($base_field->getName() === 'string') {
792           return 'entity_test_mulrev_revision__string';
793         }
794       });
795
796     $table_mapping->expects($this->any())
797       ->method('getFieldTableName')
798       ->willReturnCallback(function ($field) {
799         if ($field == 'uuid') {
800           return 'entity_test_mulrev';
801         }
802         return 'entity_test_mulrev_property_data';
803       });
804
805     $this->entityStorage->expects($this->once())
806       ->method('getTableMapping')
807       ->willReturn($table_mapping);
808
809     $this->setupFieldStorageDefinition();
810
811     $data = $this->viewsData->getViewsData();
812
813     // Check the base fields.
814     $this->assertFalse(isset($data['entity_test_mulrev']['id']));
815     $this->assertFalse(isset($data['entity_test_mulrev']['type']));
816     $this->assertFalse(isset($data['entity_test_mulrev']['revision_id']));
817     $this->assertUuidField($data['entity_test_mulrev']['uuid']);
818     $this->assertField($data['entity_test_mulrev']['uuid'], 'uuid');
819
820     // Also ensure that field_data only fields don't appear on the base table.
821     $this->assertFalse(isset($data['entity_test_mulrev']['name']));
822     $this->assertFalse(isset($data['entity_test_mul']['description']));
823     $this->assertFalse(isset($data['entity_test_mul']['description__value']));
824     $this->assertFalse(isset($data['entity_test_mul']['description__format']));
825     $this->assertFalse(isset($data['entity_test_mul']['homepage']));
826     $this->assertFalse(isset($data['entity_test_mulrev']['langcode']));
827     $this->assertFalse(isset($data['entity_test_mulrev']['user_id']));
828
829     // Check the revision fields. The revision ID should only appear in the data
830     // table.
831     $this->assertFalse(isset($data['entity_test_mulrev_revision']['revision_id']));
832
833     // Also ensure that field_data only fields don't appear on the revision table.
834     $this->assertFalse(isset($data['entity_test_mulrev_revision']['id']));
835     $this->assertFalse(isset($data['entity_test_mulrev_revision']['name']));
836     $this->assertFalse(isset($data['entity_test_mulrev_revision']['description']));
837     $this->assertFalse(isset($data['entity_test_mulrev_revision']['description__value']));
838     $this->assertFalse(isset($data['entity_test_mulrev_revision']['description__format']));
839     $this->assertFalse(isset($data['entity_test_mulrev_revision']['homepage']));
840     $this->assertFalse(isset($data['entity_test_mulrev_revision']['user_id']));
841
842     // Check the data fields.
843     $this->assertNumericField($data['entity_test_mulrev_property_data']['id']);
844     $this->assertField($data['entity_test_mulrev_property_data']['id'], 'id');
845     $this->assertNumericField($data['entity_test_mulrev_property_data']['revision_id']);
846     $this->assertField($data['entity_test_mulrev_property_data']['revision_id'], 'revision_id');
847     $this->assertLanguageField($data['entity_test_mulrev_property_data']['langcode']);
848     $this->assertField($data['entity_test_mulrev_property_data']['langcode'], 'langcode');
849     $this->assertStringField($data['entity_test_mulrev_property_data']['name']);
850     $this->assertField($data['entity_test_mulrev_property_data']['name'], 'name');
851
852     $this->assertLongTextField($data['entity_test_mulrev_property_data'], 'description');
853     $this->assertField($data['entity_test_mulrev_property_data']['description__value'], 'description');
854     $this->assertField($data['entity_test_mulrev_property_data']['description__format'], 'description');
855     $this->assertUriField($data['entity_test_mulrev_property_data']['homepage']);
856     $this->assertField($data['entity_test_mulrev_property_data']['homepage'], 'homepage');
857
858     $this->assertEntityReferenceField($data['entity_test_mulrev_property_data']['user_id']);
859     $this->assertField($data['entity_test_mulrev_property_data']['user_id'], 'user_id');
860     $relationship = $data['entity_test_mulrev_property_data']['user_id']['relationship'];
861     $this->assertEquals('users_field_data', $relationship['base']);
862     $this->assertEquals('uid', $relationship['base field']);
863
864     // Check the property data fields.
865     $this->assertNumericField($data['entity_test_mulrev_property_revision']['id']);
866     $this->assertField($data['entity_test_mulrev_property_revision']['id'], 'id');
867
868     $this->assertLanguageField($data['entity_test_mulrev_property_revision']['langcode']);
869     $this->assertField($data['entity_test_mulrev_property_revision']['langcode'], 'langcode');
870     $this->assertEquals('Translation language', $data['entity_test_mulrev_property_revision']['langcode']['title']);
871
872     $this->assertStringField($data['entity_test_mulrev_property_revision']['name']);
873     $this->assertField($data['entity_test_mulrev_property_revision']['name'], 'name');
874
875     $this->assertLongTextField($data['entity_test_mulrev_property_revision'], 'description');
876     $this->assertField($data['entity_test_mulrev_property_revision']['description__value'], 'description');
877     $this->assertField($data['entity_test_mulrev_property_revision']['description__format'], 'description');
878
879     $this->assertUriField($data['entity_test_mulrev_property_revision']['homepage']);
880     $this->assertField($data['entity_test_mulrev_property_revision']['homepage'], 'homepage');
881
882     $this->assertEntityReferenceField($data['entity_test_mulrev_property_revision']['user_id']);
883     $this->assertField($data['entity_test_mulrev_property_revision']['user_id'], 'user_id');
884     $relationship = $data['entity_test_mulrev_property_revision']['user_id']['relationship'];
885     $this->assertEquals('users_field_data', $relationship['base']);
886     $this->assertEquals('uid', $relationship['base field']);
887
888     $this->assertStringField($data['entity_test_mulrev__string']['string_value']);
889     $this->assertField($data['entity_test_mulrev__string']['string_value'], 'string');
890     $this->assertEquals([
891       'left_field' => 'id',
892       'field' => 'entity_id',
893       'extra' => [[
894           'field' => 'deleted',
895           'value' => 0,
896           'numeric' => TRUE,
897         ],
898       ],
899     ], $data['entity_test_mulrev__string']['table']['join']['entity_test_mulrev_property_data']);
900
901     $this->assertStringField($data['entity_test_mulrev_revision__string']['string_value']);
902     $this->assertField($data['entity_test_mulrev_revision__string']['string_value'], 'string');
903     $this->assertEquals([
904       'left_field' => 'revision_id',
905       'field' => 'entity_id',
906       'extra' => [[
907           'field' => 'deleted',
908           'value' => 0,
909           'numeric' => TRUE,
910         ],
911       ],
912     ], $data['entity_test_mulrev_revision__string']['table']['join']['entity_test_mulrev_property_revision']);
913   }
914
915   /**
916    * Tests generic stuff per field.
917    *
918    * @param array $data
919    *   The views data to check.
920    * @param string $field_name
921    *   The entity field name.
922    */
923   protected function assertField($data, $field_name) {
924     $this->assertEquals($field_name, $data['entity field']);
925   }
926
927   /**
928    * Tests add link types.
929    */
930   public function testEntityLinks() {
931     $this->baseEntityType->setLinkTemplate('canonical', '/entity_test/{entity_test}');
932     $this->baseEntityType->setLinkTemplate('edit-form', '/entity_test/{entity_test}/edit');
933     $this->baseEntityType->setLinkTemplate('delete-form', '/entity_test/{entity_test}/delete');
934
935     $data = $this->viewsData->getViewsData();
936     $this->assertEquals('entity_link', $data['entity_test']['view_entity_test']['field']['id']);
937     $this->assertEquals('entity_link_edit', $data['entity_test']['edit_entity_test']['field']['id']);
938     $this->assertEquals('entity_link_delete', $data['entity_test']['delete_entity_test']['field']['id']);
939   }
940
941   /**
942    * Tests additional edit links.
943    */
944   public function testEntityLinksJustEditForm() {
945     $this->baseEntityType->setLinkTemplate('edit-form', '/entity_test/{entity_test}/edit');
946
947     $data = $this->viewsData->getViewsData();
948     $this->assertFalse(isset($data['entity_test']['view_entity_test']));
949     $this->assertFalse(isset($data['entity_test']['delete_entity_test']));
950
951     $this->assertEquals('entity_link_edit', $data['entity_test']['edit_entity_test']['field']['id']);
952   }
953
954   /**
955    * @covers ::getViewsData
956    */
957   public function testGetViewsDataWithoutEntityOperations() {
958     // Make sure there is no list builder. The API does not document is
959     // supports resetting entity handlers, so this might break in the future.
960     $this->baseEntityType->setListBuilderClass(NULL);
961     $data = $this->viewsData->getViewsData();
962     $this->assertArrayNotHasKey('operations', $data[$this->baseEntityType->getBaseTable()]);
963   }
964
965   /**
966    * @covers ::getViewsData
967    */
968   public function testGetViewsDataWithEntityOperations() {
969     $this->baseEntityType->setListBuilderClass('\Drupal\Core\Entity\EntityListBuilder');
970     $data = $this->viewsData->getViewsData();
971     $this->assertSame('entity_operations', $data[$this->baseEntityType->getBaseTable()]['operations']['field']['id']);
972   }
973
974   /**
975    * Tests views data for a string field.
976    *
977    * @param $data
978    *   The views data to check.
979    */
980   protected function assertStringField($data) {
981     $this->assertEquals('field', $data['field']['id']);
982     $this->assertEquals('string', $data['filter']['id']);
983     $this->assertEquals('string', $data['argument']['id']);
984     $this->assertEquals('standard', $data['sort']['id']);
985   }
986
987   /**
988    * Tests views data for a URI field.
989    *
990    * @param $data
991    *   The views data to check.
992    */
993   protected function assertUriField($data) {
994     $this->assertEquals('field', $data['field']['id']);
995     $this->assertEquals('string', $data['field']['default_formatter']);
996     $this->assertEquals('string', $data['filter']['id']);
997     $this->assertEquals('string', $data['argument']['id']);
998     $this->assertEquals('standard', $data['sort']['id']);
999   }
1000
1001   /**
1002    * Tests views data for a long text field.
1003    *
1004    * @param $data
1005    *   The views data for the table this field is in.
1006    * @param $field_name
1007    *   The name of the field being checked.
1008    */
1009   protected function assertLongTextField($data, $field_name) {
1010     $value_field = $data[$field_name . '__value'];
1011     $this->assertEquals('field', $value_field['field']['id']);
1012     $this->assertEquals($field_name . '__format', $value_field['field']['format']);
1013     $this->assertEquals('string', $value_field['filter']['id']);
1014     $this->assertEquals('string', $value_field['argument']['id']);
1015     $this->assertEquals('standard', $value_field['sort']['id']);
1016
1017     $this->assertStringField($data[$field_name . '__format']);
1018   }
1019
1020   /**
1021    * Tests views data for a UUID field.
1022    *
1023    * @param array $data
1024    *   The views data to check.
1025    */
1026   protected function assertUuidField($data) {
1027     // @todo Can we provide additional support for UUIDs in views?
1028     $this->assertEquals('field', $data['field']['id']);
1029     $this->assertFalse($data['field']['click sortable']);
1030     $this->assertEquals('string', $data['filter']['id']);
1031     $this->assertEquals('string', $data['argument']['id']);
1032     $this->assertEquals('standard', $data['sort']['id']);
1033   }
1034
1035   /**
1036    * Tests views data for a numeric field.
1037    *
1038    * @param array $data
1039    *   The views data to check.
1040    */
1041   protected function assertNumericField($data) {
1042     $this->assertEquals('field', $data['field']['id']);
1043     $this->assertEquals('numeric', $data['filter']['id']);
1044     $this->assertEquals('numeric', $data['argument']['id']);
1045     $this->assertEquals('standard', $data['sort']['id']);
1046   }
1047
1048   /**
1049    * Tests views data for a language field.
1050    *
1051    * @param array $data
1052    *   The views data to check.
1053    */
1054   protected function assertLanguageField($data) {
1055     $this->assertEquals('field', $data['field']['id']);
1056     $this->assertEquals('language', $data['filter']['id']);
1057     $this->assertEquals('language', $data['argument']['id']);
1058     $this->assertEquals('standard', $data['sort']['id']);
1059   }
1060
1061   /**
1062    * Tests views data for a entity reference field.
1063    */
1064   protected function assertEntityReferenceField($data) {
1065     $this->assertEquals('field', $data['field']['id']);
1066     $this->assertEquals('numeric', $data['filter']['id']);
1067     $this->assertEquals('numeric', $data['argument']['id']);
1068     $this->assertEquals('standard', $data['sort']['id']);
1069   }
1070
1071   /**
1072    * Tests views data for a bundle field.
1073    */
1074   protected function assertBundleField($data) {
1075     $this->assertEquals('field', $data['field']['id']);
1076     $this->assertEquals('bundle', $data['filter']['id']);
1077     $this->assertEquals('string', $data['argument']['id']);
1078     $this->assertEquals('standard', $data['sort']['id']);
1079   }
1080
1081   /**
1082    * Returns entity info for the user entity.
1083    *
1084    * @return array
1085    */
1086   protected static function userEntityInfo() {
1087     return new ContentEntityType([
1088       'id' => 'user',
1089       'class' => 'Drupal\user\Entity\User',
1090       'label' => 'User',
1091       'base_table' => 'users',
1092       'data_table' => 'users_field_data',
1093       'entity_keys' => [
1094         'id' => 'uid',
1095         'uuid' => 'uuid',
1096       ],
1097     ]);
1098   }
1099
1100 }
1101
1102 class TestEntityViewsData extends EntityViewsData {
1103
1104   public function setEntityType(EntityTypeInterface $entity_type) {
1105     $this->entityType = $entity_type;
1106   }
1107
1108 }
1109
1110 class TestEntityType extends ContentEntityType {
1111
1112   /**
1113    * Sets a specific entity key.
1114    *
1115    * @param string $key
1116    *   The name of the entity key.
1117    * @param string $value
1118    *   The new value of the key.
1119    *
1120    * @return $this
1121    */
1122   public function setKey($key, $value) {
1123     $this->entity_keys[$key] = $value;
1124     return $this;
1125   }
1126
1127 }
1128
1129 namespace Drupal\entity_test\Entity;
1130
1131 if (!function_exists('t')) {
1132   function t($string, array $args = []) {
1133     return strtr($string, $args);
1134   }
1135 }
1136
1137
1138 namespace Drupal\Core\Entity;
1139
1140 if (!function_exists('t')) {
1141   function t($string, array $args = []) {
1142     return strtr($string, $args);
1143   }
1144 }