Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Entity / TypedData / EntityAdapterUnitTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Entity\TypedData;
4
5 use Drupal\Core\DependencyInjection\ContainerBuilder;
6 use Drupal\Core\Entity\EntityFieldManagerInterface;
7 use Drupal\Core\Entity\EntityManager;
8 use Drupal\Core\Entity\EntityTypeManagerInterface;
9 use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
10 use Drupal\Core\Field\BaseFieldDefinition;
11 use Drupal\Core\Language\LanguageInterface;
12 use Drupal\Core\TypedData\Exception\MissingDataException;
13 use Drupal\Core\TypedData\TypedDataManagerInterface;
14 use Drupal\Tests\UnitTestCase;
15 use Drupal\Core\Language\Language;
16
17 /**
18  * @coversDefaultClass \Drupal\Core\Entity\Plugin\DataType\EntityAdapter
19  * @group Entity
20  * @group TypedData
21  */
22 class EntityAdapterUnitTest extends UnitTestCase {
23
24   /**
25    * The bundle used for testing.
26    *
27    * @var string
28    */
29   protected $bundle;
30
31   /**
32    * The content entity used for testing.
33    *
34    * @var \Drupal\Core\Entity\ContentEntityBase|\PHPUnit_Framework_MockObject_MockObject
35    */
36   protected $entity;
37
38   /**
39    * The config entity used for testing.
40    *
41    * @var \Drupal\Core\Entity\ConfigtEntityBase|\PHPUnit_Framework_MockObject_MockObject
42    */
43   protected $configEntity;
44
45   /**
46    * The content entity adapter under test.
47    *
48    * @var \Drupal\Core\Entity\Plugin\DataType\EntityAdapter
49    */
50   protected $entityAdapter;
51
52   /**
53    * The config entity adapter under test.
54    *
55    * @var \Drupal\Core\Entity\Plugin\DataType\EntityAdapter
56    */
57   protected $configEntityAdapter;
58
59   /**
60    * The entity type used for testing.
61    *
62    * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
63    */
64   protected $entityType;
65
66   /**
67    * The entity manager used for testing.
68    *
69    * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
70    */
71   protected $entityManager;
72
73   /**
74    * The entity type manager used for testing.
75    *
76    * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
77    */
78   protected $entityTypeManager;
79
80   /**
81    *
82    * @var \Drupal\Core\Entity\EntityFieldManagerInterface|\PHPUnit_Framework_MockObject_MockObject
83    */
84   protected $entityFieldManager;
85
86   /**
87    * The type ID of the entity under test.
88    *
89    * @var string
90    */
91   protected $entityTypeId;
92
93   /**
94    * The typed data manager used for testing.
95    *
96    * @var \Drupal\Core\TypedData\TypedDataManager|\PHPUnit_Framework_MockObject_MockObject
97    */
98   protected $typedDataManager;
99
100   /**
101    * The field item list returned by the typed data manager.
102    *
103    * @var \Drupal\Core\Field\FieldItemListInterface|\PHPUnit_Framework_MockObject_MockObject
104    */
105   protected $fieldItemList;
106
107   /**
108    * The field type manager used for testing.
109    *
110    * @var \Drupal\Core\Field\FieldTypePluginManager|\PHPUnit_Framework_MockObject_MockObject
111    */
112   protected $fieldTypePluginManager;
113
114   /**
115    * The language manager.
116    *
117    * @var \Drupal\Core\Language\LanguageManagerInterface|\PHPUnit_Framework_MockObject_MockObject
118    */
119   protected $languageManager;
120
121   /**
122    * The UUID generator used for testing.
123    *
124    * @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
125    */
126   protected $uuid;
127
128   /**
129    * The entity ID.
130    *
131    * @var int
132    */
133   protected $id;
134
135   /**
136    * Field definitions.
137    *
138    * @var \Drupal\Core\Field\BaseFieldDefinition[]
139    */
140   protected $fieldDefinitions;
141
142   /**
143    * {@inheritdoc}
144    */
145   protected function setUp() {
146     $this->id = 1;
147     $values = [
148       'id' => $this->id,
149       'uuid' => '3bb9ee60-bea5-4622-b89b-a63319d10b3a',
150       'defaultLangcode' => [LanguageInterface::LANGCODE_DEFAULT => 'en'],
151     ];
152     $this->entityTypeId = $this->randomMachineName();
153     $this->bundle = $this->randomMachineName();
154
155     $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
156     $this->entityType->expects($this->any())
157       ->method('getKeys')
158       ->will($this->returnValue([
159         'id' => 'id',
160         'uuid' => 'uuid',
161     ]));
162
163     $this->entityManager = new EntityManager();
164
165     $this->entityTypeManager = $this->getMock(EntityTypeManagerInterface::class);
166     $this->entityTypeManager->expects($this->any())
167       ->method('getDefinition')
168       ->with($this->entityTypeId)
169       ->will($this->returnValue($this->entityType));
170
171     $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
172
173     $this->typedDataManager = $this->getMock(TypedDataManagerInterface::class);
174     $this->typedDataManager->expects($this->any())
175       ->method('getDefinition')
176       ->with('entity')
177       ->will($this->returnValue(['class' => '\Drupal\Core\Entity\Plugin\DataType\EntityAdapter']));
178     $this->typedDataManager->expects($this->any())
179       ->method('getDefaultConstraints')
180       ->willReturn([]);
181
182     $validation_constraint_manager = $this->getMockBuilder('\Drupal\Core\Validation\ConstraintManager')
183       ->disableOriginalConstructor()
184       ->getMock();
185     $validation_constraint_manager->expects($this->any())
186       ->method('create')
187       ->willReturn([]);
188     $this->typedDataManager->expects($this->any())
189       ->method('getValidationConstraintManager')
190       ->willReturn($validation_constraint_manager);
191
192     $not_specified = new Language(['id' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'locked' => TRUE]);
193     $this->languageManager = $this->getMock('\Drupal\Core\Language\LanguageManagerInterface');
194     $this->languageManager->expects($this->any())
195       ->method('getLanguages')
196       ->will($this->returnValue([LanguageInterface::LANGCODE_NOT_SPECIFIED => $not_specified]));
197
198     $this->languageManager->expects($this->any())
199       ->method('getLanguage')
200       ->with(LanguageInterface::LANGCODE_NOT_SPECIFIED)
201       ->will($this->returnValue($not_specified));
202
203     $this->fieldTypePluginManager = $this->getMockBuilder('\Drupal\Core\Field\FieldTypePluginManager')
204       ->disableOriginalConstructor()
205       ->getMock();
206     $this->fieldTypePluginManager->expects($this->any())
207       ->method('getDefaultStorageSettings')
208       ->will($this->returnValue([]));
209     $this->fieldTypePluginManager->expects($this->any())
210       ->method('getDefaultFieldSettings')
211       ->will($this->returnValue([]));
212
213     $this->fieldItemList = $this->getMock('\Drupal\Core\Field\FieldItemListInterface');
214     $this->fieldTypePluginManager->expects($this->any())
215       ->method('createFieldItemList')
216       ->willReturn($this->fieldItemList);
217
218     $this->entityFieldManager = $this->getMockForAbstractClass(EntityFieldManagerInterface::class);
219
220     $container = new ContainerBuilder();
221     $container->set('entity.manager', $this->entityManager);
222     $container->set('entity_type.manager', $this->entityTypeManager);
223     $container->set('entity_field.manager', $this->entityFieldManager);
224     $container->set('uuid', $this->uuid);
225     $container->set('typed_data_manager', $this->typedDataManager);
226     $container->set('language_manager', $this->languageManager);
227     $container->set('plugin.manager.field.field_type', $this->fieldTypePluginManager);
228     // Inject the container into entity.manager so it can defer to
229     // entity_type.manager and other services.
230     $this->entityManager->setContainer($container);
231     \Drupal::setContainer($container);
232
233     $this->fieldDefinitions = [
234       'id' => BaseFieldDefinition::create('integer'),
235       'revision_id' => BaseFieldDefinition::create('integer'),
236     ];
237     $this->entityFieldManager->expects($this->any())
238       ->method('getFieldDefinitions')
239       ->with($this->entityTypeId, $this->bundle)
240       ->will($this->returnValue($this->fieldDefinitions));
241
242     $this->entity = $this->getMockForAbstractClass('\Drupal\Core\Entity\ContentEntityBase', [$values, $this->entityTypeId, $this->bundle]);
243
244     $this->entityAdapter = EntityAdapter::createFromEntity($this->entity);
245
246     $this->configEntity = $this->getMockForAbstractClass('\Drupal\Core\Config\Entity\ConfigEntityBase', [$values, $this->entityTypeId, $this->bundle]);
247
248     $this->configEntityAdapter = EntityAdapter::createFromEntity($this->configEntity);
249   }
250
251   /**
252    * @covers ::getConstraints
253    */
254   public function testGetConstraints() {
255     $this->assertInternalType('array', $this->entityAdapter->getConstraints());
256   }
257
258   /**
259    * @covers ::getName
260    */
261   public function testGetName() {
262     $this->assertNull($this->entityAdapter->getName());
263   }
264
265   /**
266    * @covers ::getRoot
267    */
268   public function testGetRoot() {
269     $this->assertSame(spl_object_hash($this->entityAdapter), spl_object_hash($this->entityAdapter->getRoot()));
270   }
271
272   /**
273    * @covers ::getPropertyPath
274    */
275   public function testGetPropertyPath() {
276     $this->assertSame('', $this->entityAdapter->getPropertyPath());
277   }
278
279   /**
280    * @covers ::getParent
281    */
282   public function testGetParent() {
283     $this->assertNull($this->entityAdapter->getParent());
284   }
285
286   /**
287    * @covers ::setContext
288    */
289   public function testSetContext() {
290     $name = $this->randomMachineName();
291     $parent = $this->getMock('\Drupal\Core\TypedData\TraversableTypedDataInterface');
292     // Our mocked entity->setContext() returns NULL, so assert that.
293     $this->assertNull($this->entityAdapter->setContext($name, $parent));
294     $this->assertEquals($name, $this->entityAdapter->getName());
295     $this->assertEquals($parent, $this->entityAdapter->getParent());
296   }
297
298   /**
299    * @covers ::getValue
300    */
301   public function testGetValue() {
302     $this->assertEquals($this->entity, $this->entityAdapter->getValue());
303   }
304
305   /**
306    * @covers ::setValue
307    */
308   public function testSetValue() {
309     $this->entityAdapter->setValue(NULL);
310     $this->assertNull($this->entityAdapter->getValue());
311   }
312
313   /**
314    * @covers ::get
315    */
316   public function testGet() {
317     $this->assertInstanceOf('\Drupal\Core\Field\FieldItemListInterface', $this->entityAdapter->get('id'));
318   }
319
320   /**
321    * @covers ::get
322    */
323   public function testGetInvalidField() {
324     $this->setExpectedException(\InvalidArgumentException::class);
325     $this->entityAdapter->get('invalid');
326   }
327
328   /**
329    * @covers ::get
330    */
331   public function testGetWithoutData() {
332     $this->entityAdapter->setValue(NULL);
333     $this->setExpectedException(MissingDataException::class);
334     $this->entityAdapter->get('id');
335   }
336
337   /**
338    * @covers ::set
339    */
340   public function testSet() {
341     $id_items = [['value' => $this->id + 1]];
342
343     $this->fieldItemList->expects($this->once())
344       ->method('setValue')
345       ->with($id_items);
346
347     $this->entityAdapter->set('id', $id_items);
348   }
349
350   /**
351    * @covers ::set
352    */
353   public function testSetWithoutData() {
354     $this->entityAdapter->setValue(NULL);
355     $id_items = [['value' => $this->id + 1]];
356     $this->setExpectedException(MissingDataException::class);
357     $this->entityAdapter->set('id', $id_items);
358   }
359
360   /**
361  * @covers ::getProperties
362  */
363   public function testGetProperties() {
364     $fields = $this->entityAdapter->getProperties();
365     $this->assertInstanceOf('Drupal\Core\Field\FieldItemListInterface', $fields['id']);
366     $this->assertInstanceOf('Drupal\Core\Field\FieldItemListInterface', $fields['revision_id']);
367   }
368
369   /**
370    * @covers ::toArray
371    */
372   public function testToArray() {
373     $array = $this->entityAdapter->toArray();
374     // Mock field objects return NULL values, so test keys only.
375     $this->assertArrayHasKey('id', $array);
376     $this->assertArrayHasKey('revision_id', $array);
377     $this->assertEquals(count($array), 2);
378   }
379
380   /**
381    * @covers ::toArray
382    */
383   public function testToArrayWithoutData() {
384     $this->entityAdapter->setValue(NULL);
385     $this->setExpectedException(MissingDataException::class);
386     $this->entityAdapter->toArray();
387   }
388
389   /**
390    * @covers ::isEmpty
391    */
392   public function testIsEmpty() {
393     $this->assertFalse($this->entityAdapter->isEmpty());
394     $this->entityAdapter->setValue(NULL);
395     $this->assertTrue($this->entityAdapter->isEmpty());
396   }
397
398   /**
399    * @covers ::onChange
400    */
401   public function testOnChange() {
402     $entity = $this->getMock('\Drupal\Core\Entity\ContentEntityInterface');
403     $entity->expects($this->once())
404       ->method('onChange')
405       ->with('foo')
406       ->willReturn(NULL);
407     $this->entityAdapter->setValue($entity);
408     $this->entityAdapter->onChange('foo');
409   }
410
411   /**
412    * @covers ::getDataDefinition
413    */
414   public function testGetDataDefinition() {
415     $definition = $this->entityAdapter->getDataDefinition();
416     $this->assertInstanceOf('\Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface', $definition);
417     $this->assertEquals($definition->getEntityTypeId(), $this->entityTypeId);
418     $this->assertEquals($definition->getBundles(), [$this->bundle]);
419   }
420
421   /**
422    * @covers ::getString
423    */
424   public function testGetString() {
425     $entity = $this->getMock('\Drupal\Core\Entity\ContentEntityInterface');
426     $entity->expects($this->once())
427       ->method('label')
428       ->willReturn('foo');
429     $this->entityAdapter->setValue($entity);
430     $this->assertEquals('foo', $this->entityAdapter->getString());
431     $this->entityAdapter->setValue(NULL);
432     $this->assertEquals('', $this->entityAdapter->getString());
433   }
434
435   /**
436    * @covers ::applyDefaultValue
437    */
438   public function testApplyDefaultValue() {
439     // For each field on the entity the mock method has to be invoked once.
440     $this->fieldItemList->expects($this->exactly(2))
441       ->method('applyDefaultValue');
442     $this->entityAdapter->applyDefaultValue();
443   }
444
445   /**
446    * @covers ::getIterator
447    */
448   public function testGetIterator() {
449     // Content entity test.
450     $iterator = $this->entityAdapter->getIterator();
451     $fields = iterator_to_array($iterator);
452     $this->assertArrayHasKey('id', $fields);
453     $this->assertArrayHasKey('revision_id', $fields);
454     $this->assertEquals(count($fields), 2);
455
456     $this->entityAdapter->setValue(NULL);
457     $this->assertEquals(new \ArrayIterator([]), $this->entityAdapter->getIterator());
458
459     // Config entity test.
460     $iterator = $this->configEntityAdapter->getIterator();
461     $this->configEntityAdapter->setValue(NULL);
462     $this->assertEquals(new \ArrayIterator([]), $this->entityAdapter->getIterator());
463   }
464
465 }