From 6d3b05c2081a8466c92d8d31941f394139807631 Mon Sep 17 00:00:00 2001 From: Lee Rowlands <lee.rowlands@previousnext.com.au> Date: Fri, 16 Aug 2019 17:56:19 +1000 Subject: [PATCH] Issue #3061610 by gabesullice, Wim Leers, tedbow, larowlan: Typed Data's EntityDeriver does not derive bundle-level data types when a bundle has the same name as its entity type (f.e. entity:comment:comment) --- .../Plugin/DataType/Deriver/EntityDeriver.php | 7 +- .../Core/Entity/EntityDeriverTest.php | 95 +++++++++++++++++++ .../Entity/EntityTypedDataDefinitionTest.php | 1 + 3 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 core/tests/Drupal/KernelTests/Core/Entity/EntityDeriverTest.php diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/EntityDeriver.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/EntityDeriver.php index 3b2a52cd793a..8320bb4558c1 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/EntityDeriver.php +++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/Deriver/EntityDeriver.php @@ -105,11 +105,12 @@ public function getDerivativeDefinitions($base_plugin_definition) { ] + $base_plugin_definition; // Incorporate the bundles as entity:$entity_type:$bundle, if any. - foreach ($this->bundleInfoService->getBundleInfo($entity_type_id) as $bundle => $bundle_info) { - if ($bundle !== $entity_type_id) { + $bundle_info = $this->bundleInfoService->getBundleInfo($entity_type_id); + if (count($bundle_info) > 1 || $entity_type->getKey('bundle')) { + foreach ($bundle_info as $bundle => $info) { $this->derivatives[$entity_type_id . ':' . $bundle] = [ 'class' => $class, - 'label' => $bundle_info['label'], + 'label' => $info['label'], 'constraints' => $this->derivatives[$entity_type_id]['constraints'], ] + $base_plugin_definition; } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDeriverTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDeriverTest.php new file mode 100644 index 000000000000..bbe8af0706b7 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDeriverTest.php @@ -0,0 +1,95 @@ +<?php + +namespace Drupal\KernelTests\Core\Entity; + +use Drupal\comment\Entity\CommentType; +use Drupal\Component\Plugin\Exception\PluginNotFoundException; +use Drupal\KernelTests\KernelTestBase; +use Drupal\node\Entity\NodeType; + +/** + * Tests EntityDeriver functionality. + * + * @coversDefaultClass \Drupal\Core\Entity\Plugin\DataType\Deriver\EntityDeriver + * + * @group Entity + */ +class EntityDeriverTest extends KernelTestBase { + + /** + * The typed data manager to use. + * + * @var \Drupal\Core\TypedData\TypedDataManagerInterface + */ + protected $typedDataManager; + + /** + * {@inheritdoc} + */ + public static $modules = [ + 'system', + 'field', + 'user', + 'node', + 'comment', + 'entity_test', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setup(); + + $this->installEntitySchema('comment'); + NodeType::create(['type' => 'article', 'name' => 'Article'])->save(); + CommentType::create([ + 'id' => 'comment', + 'name' => 'Default comment', + 'target_entity_type_id' => 'node', + ])->save(); + entity_test_create_bundle('foo', NULL, 'entity_test_no_bundle'); + entity_test_create_bundle('entity_test_no_bundle', NULL, 'entity_test_no_bundle'); + $this->typedDataManager = $this->container->get('typed_data_manager'); + } + + /** + * Tests that types are derived for entity types with and without bundles. + * + * @dataProvider derivativesProvider + */ + public function testDerivatives($data_type, $expect_exception) { + if ($expect_exception) { + $this->expectException(PluginNotFoundException::class); + } + $this->typedDataManager->createDataDefinition($data_type); + } + + /** + * Provides test data for ::testDerivatives(). + */ + public function derivativesProvider() { + return [ + 'unbundleable entity type with no bundle type' => ['entity:user', FALSE], + 'unbundleable entity type with bundle type' => ['entity:user:user', TRUE], + 'bundleable entity type with no bundle type' => ['entity:node', FALSE], + 'bundleable entity type with bundle type' => [ + 'entity:node:article', + FALSE, + ], + 'bundleable entity type with bundle type with matching name' => [ + 'entity:comment:comment', + FALSE, + ], + 'unbundleable entity type with entity_test_entity_bundle_info()-generated bundle type' => [ + 'entity:entity_test_no_bundle:foo', + FALSE, + ], + 'unbundleable entity type with entity_test_entity_bundle_info()-generated bundle type with matching name' => [ + 'entity:entity_test_no_bundle:entity_test_no_bundle', + FALSE, + ], + ]; + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php index b4d97bf910fd..dcfe664a6d5e 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php @@ -151,6 +151,7 @@ public function testEntityDefinitionIsInternal($internal, $expected) { $entity_type = $this->prophesize(EntityTypeInterface::class); $entity_type->entityClassImplements(ConfigEntityInterface::class)->willReturn(FALSE); + $entity_type->getKey('bundle')->willReturn(FALSE); $entity_type->getLabel()->willReturn($this->randomString()); $entity_type->getConstraints()->willReturn([]); $entity_type->isInternal()->willReturn($internal); -- GitLab