diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php index 8dacfaa..1784558 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -617,7 +617,6 @@ protected function initializeTranslation($langcode) { // The label is the only entity key that can change based on the language, // so unset that in case it is currently set. unset($translation->entityKeys['label']); - $translation->typedData = NULL; return $translation; } diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/Entity.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/Entity.php index d4c7b69..1f9ffbf 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/DataType/Entity.php +++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/Entity.php @@ -140,7 +140,7 @@ public function isEmpty() { * {@inheritdoc} */ public function onChange($property_name) { - if (isset($this->entity)) { + if (isset($this->entity) && $this->entity instanceof ContentEntityInterface) { // Let the entity know of any changes. $this->entity->onChange($property_name); } diff --git a/core/lib/Drupal/Core/TypedData/Exception/MissingDataException.php b/core/lib/Drupal/Core/TypedData/Exception/MissingDataException.php index f2ef0e9..e937212 100644 --- a/core/lib/Drupal/Core/TypedData/Exception/MissingDataException.php +++ b/core/lib/Drupal/Core/TypedData/Exception/MissingDataException.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\Core\TypedData\MissingDataException. + * Contains \Drupal\Core\TypedData\Exception\MissingDataException. */ namespace Drupal\Core\TypedData\Exception; diff --git a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php index 91ff8fe..168f86e 100644 --- a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php @@ -334,51 +334,6 @@ public function testValidate() { $this->assertSame(1, count($this->entity->validate())); } -// /** -// * @covers ::getConstraints -// */ -// public function testGetConstraints() { -// $this->assertInternalType('array', $this->entity->getConstraints()); -// } - -// /** -// * @covers ::getName -// */ -// public function testGetName() { -// $this->assertNull($this->entity->getName()); -// } -// -// /** -// * @covers ::getRoot -// */ -// public function testGetRoot() { -// $this->assertSame(spl_object_hash($this->entity), spl_object_hash($this->entity->getRoot())); -// } -// -// /** -// * @covers ::getPropertyPath -// */ -// public function testGetPropertyPath() { -// $this->assertSame('', $this->entity->getPropertyPath()); -// } -// -// /** -// * @covers ::getParent -// */ -// public function testGetParent() { -// $this->assertNull($this->entity->getParent()); -// } -// -// /** -// * @covers ::setContext -// */ -// public function testSetContext() { -// $name = $this->randomMachineName(); -// $parent = $this->getMock('\Drupal\Core\TypedData\TypedDataInterface'); -// // Our mocked entity->setContext() returns NULL, so assert that. -// $this->assertNull($this->entity->setContext($name, $parent)); -// } - /** * @covers ::bundle */ diff --git a/core/tests/Drupal/Tests/Core/Entity/TypedData/TypedEntityUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/TypedData/TypedEntityUnitTest.php new file mode 100644 index 0000000..34a5528 --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Entity/TypedData/TypedEntityUnitTest.php @@ -0,0 +1,422 @@ +id = 1; + $values = array( + 'id' => $this->id, + 'uuid' => '3bb9ee60-bea5-4622-b89b-a63319d10b3a', + 'defaultLangcode' => array(LanguageInterface::LANGCODE_DEFAULT => 'en'), + ); + $this->entityTypeId = $this->randomMachineName(); + $this->bundle = $this->randomMachineName(); + + $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface'); + $this->entityType->expects($this->any()) + ->method('getKeys') + ->will($this->returnValue(array( + 'id' => 'id', + 'uuid' => 'uuid', + ))); + + $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface'); + $this->entityManager->expects($this->any()) + ->method('getDefinition') + ->with($this->entityTypeId) + ->will($this->returnValue($this->entityType)); + + $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface'); + + $this->typedDataManager = $this->getMockBuilder('\Drupal\Core\TypedData\TypedDataManager') + ->disableOriginalConstructor() + ->getMock(); + $this->typedDataManager->expects($this->any()) + ->method('getDefinition') + ->with('entity') + ->will($this->returnValue(['class' => '\Drupal\Core\Entity\Plugin\DataType\Entity'])); + $this->typedDataManager->expects($this->any()) + ->method('getDefaultConstraints') + ->willReturn([]); + + $validation_constraint_manager = $this->getMockBuilder('\Drupal\Core\Validation\ConstraintManager') + ->disableOriginalConstructor() + ->getMock(); + $validation_constraint_manager->expects($this->any()) + ->method('create') + ->willReturn([]); + $this->typedDataManager->expects($this->any()) + ->method('getValidationConstraintManager') + ->willReturn($validation_constraint_manager); + + $this->fieldItemList = $this->getMock('\Drupal\Core\Field\FieldItemListInterface'); + $this->typedDataManager->expects($this->any()) + ->method('getPropertyInstance') + ->willReturn($this->fieldItemList); + + $not_specified = new Language(array('id' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'locked' => TRUE)); + $this->languageManager = $this->getMock('\Drupal\Core\Language\LanguageManagerInterface'); + $this->languageManager->expects($this->any()) + ->method('getLanguages') + ->will($this->returnValue(array(LanguageInterface::LANGCODE_NOT_SPECIFIED => $not_specified))); + + $this->languageManager->expects($this->any()) + ->method('getLanguage') + ->with(LanguageInterface::LANGCODE_NOT_SPECIFIED) + ->will($this->returnValue($not_specified)); + + $this->fieldTypePluginManager = $this->getMockBuilder('\Drupal\Core\Field\FieldTypePluginManager') + ->disableOriginalConstructor() + ->getMock(); + $this->fieldTypePluginManager->expects($this->any()) + ->method('getDefaultStorageSettings') + ->will($this->returnValue(array())); + $this->fieldTypePluginManager->expects($this->any()) + ->method('getDefaultFieldSettings') + ->will($this->returnValue(array())); + + $container = new ContainerBuilder(); + $container->set('entity.manager', $this->entityManager); + $container->set('uuid', $this->uuid); + $container->set('typed_data_manager', $this->typedDataManager); + $container->set('language_manager', $this->languageManager); + $container->set('plugin.manager.field.field_type', $this->fieldTypePluginManager); + \Drupal::setContainer($container); + + $this->fieldDefinitions = array( + 'id' => BaseFieldDefinition::create('integer'), + 'revision_id' => BaseFieldDefinition::create('integer'), + ); + + $this->entityManager->expects($this->any()) + ->method('getFieldDefinitions') + ->with($this->entityTypeId, $this->bundle) + ->will($this->returnValue($this->fieldDefinitions)); + $this->entity = $this->getMockForAbstractClass('\Drupal\Core\Entity\ContentEntityBase', array($values, $this->entityTypeId, $this->bundle)); + + $this->typedEntity = Entity::createFromEntity($this->entity); + } + + /** + * @covers ::getConstraints + */ + public function testGetConstraints() { + $this->assertInternalType('array', $this->typedEntity->getConstraints()); + } + + /** + * @covers ::getName + */ + public function testGetName() { + $this->assertNull($this->typedEntity->getName()); + } + + /** + * @covers ::getRoot + */ + public function testGetRoot() { + $this->assertSame(spl_object_hash($this->typedEntity), spl_object_hash($this->typedEntity->getRoot())); + } + + /** + * @covers ::getPropertyPath + */ + public function testGetPropertyPath() { + $this->assertSame('', $this->typedEntity->getPropertyPath()); + } + + /** + * @covers ::getParent + */ + public function testGetParent() { + $this->assertNull($this->typedEntity->getParent()); + } + + /** + * @covers ::setContext + */ + public function testSetContext() { + $name = $this->randomMachineName(); + $parent = $this->getMock('\Drupal\Core\TypedData\TypedDataInterface'); + // Our mocked entity->setContext() returns NULL, so assert that. + $this->assertNull($this->typedEntity->setContext($name, $parent)); + $this->assertEquals($name, $this->typedEntity->getName()); + $this->assertEquals($parent, $this->typedEntity->getParent()); + } + + /** + * @covers ::getValue + */ + public function testGetValue() { + $this->assertEquals($this->entity, $this->typedEntity->getValue()); + } + + /** + * @covers ::setValue + */ + public function testSetValue() { + $this->typedEntity->setValue(NULL); + $this->assertNull($this->typedEntity->getValue()); + } + + /** + * @covers ::get + */ + public function testGet() { + $this->assertInstanceOf('\Drupal\Core\Field\FieldItemListInterface', $this->typedEntity->get('id')); + } + + /** + * @covers ::get + * @expectedException \InvalidArgumentException + */ + public function testGetInvalidField() { + $this->typedEntity->get('invalid'); + } + + /** + * @covers ::get + * @expectedException \Drupal\Core\TypedData\Exception\MissingDataException + */ + public function testGetWithoutData() { + $this->typedEntity->setValue(NULL); + $this->typedEntity->get('id'); + } + + /** + * @covers ::set + */ + public function testSet() { + $id_items = [ array('value' => $this->id + 1) ]; + + $this->fieldItemList->expects($this->once()) + ->method('setValue') + ->with($id_items); + + $this->typedEntity->set('id', $id_items); + } + + /** + * @covers ::set + * @expectedException \Drupal\Core\TypedData\Exception\MissingDataException + */ + public function testSetWithoutData() { + $this->typedEntity->setValue(NULL); + $id_items = [ array('value' => $this->id + 1) ]; + $this->typedEntity->set('id', $id_items); + } + + /** + * @covers ::getProperties + */ + public function testGetProperties() { + $fields = $this->typedEntity->getProperties(); + $this->assertInstanceOf('Drupal\Core\Field\FieldItemListInterface', $fields['id']); + $this->assertInstanceOf('Drupal\Core\Field\FieldItemListInterface', $fields['revision_id']); + } + + /** + * @covers ::toArray + */ + public function testToArray() { + $array = $this->typedEntity->toArray(); + // Mock field objects return NULL values, so test keys only. + $this->assertArrayHasKey('id', $array); + $this->assertArrayHasKey('revision_id', $array); + $this->assertEquals(count($array), 2); + } + + /** + * @covers ::toArray + * @expectedException \Drupal\Core\TypedData\Exception\MissingDataException + */ + public function testToArrayWithoutData() { + $this->typedEntity->setValue(NULL); + $this->typedEntity->toArray(); + } + + /** + * @covers ::isEmpty + */ + public function testIsEmpty() { + $this->assertFalse($this->typedEntity->isEmpty()); + $this->typedEntity->setValue(NULL); + $this->assertTrue($this->typedEntity->isEmpty()); + } + + /** + * @covers ::onChange + */ + public function testOnChange() { + $entity = $this->getMock('\Drupal\Core\Entity\ContentEntityInterface'); + $entity->expects($this->once()) + ->method('onChange') + ->with('foo') + ->willReturn(NULL); + $this->typedEntity->setValue($entity); + $this->typedEntity->onChange('foo'); + } + + /** + * @covers ::getDataDefinition + */ + public function testGetDataDefinition() { + $definition = $this->typedEntity->getDataDefinition(); + $this->assertInstanceOf('\Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface', $definition); + $this->assertEquals($definition->getEntityTypeId(), $this->entityTypeId); + $this->assertEquals($definition->getBundles(), [ $this->bundle ]); + } + + /** + * @covers ::getString + */ + public function testGetString() { + $entity = $this->getMock('\Drupal\Core\Entity\ContentEntityInterface'); + $entity->expects($this->once()) + ->method('label') + ->willReturn('foo'); + $this->typedEntity->setValue($entity); + $this->assertEquals('foo', $this->typedEntity->getString()); + $this->typedEntity->setValue(NULL); + $this->assertEquals('', $this->typedEntity->getString()); + } + + /** + * @covers ::applyDefaultValue + */ + public function testApplyDefaultValue() { + // For each field on the entity the mock method has to be invoked once. + $this->fieldItemList->expects($this->exactly(2)) + ->method('applyDefaultValue'); + $this->typedEntity->applyDefaultValue(); + } + + /** + * @covers ::getIterator + */ + public function testGetIterator() { + $iterator = $this->typedEntity->getIterator(); + $fields = iterator_to_array($iterator); + $this->assertArrayHasKey('id', $fields); + $this->assertArrayHasKey('revision_id', $fields); + $this->assertEquals(count($fields), 2); + + $this->typedEntity->setValue(NULL); + $this->assertEquals(new \ArrayIterator([]), $this->typedEntity->getIterator()); + } +}