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