3 namespace Drupal\Tests\Core\Entity;
5 use Drupal\Component\Plugin\Exception\PluginNotFoundException;
6 use Drupal\Core\Cache\Cache;
7 use Drupal\Core\Cache\CacheBackendInterface;
8 use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
9 use Drupal\Core\Entity\EntityInterface;
10 use Drupal\Core\Entity\EntityTypeBundleInfo;
11 use Drupal\Core\Entity\EntityTypeInterface;
12 use Drupal\Core\Entity\EntityTypeManagerInterface;
13 use Drupal\Core\Extension\ModuleHandlerInterface;
14 use Drupal\Core\Language\Language;
15 use Drupal\Core\Language\LanguageManagerInterface;
16 use Drupal\Core\TypedData\TypedDataManagerInterface;
17 use Drupal\Tests\UnitTestCase;
18 use Prophecy\Argument;
19 use Symfony\Component\DependencyInjection\ContainerInterface;
22 * @coversDefaultClass \Drupal\Core\Entity\EntityTypeBundleInfo
25 class EntityTypeBundleInfoTest extends UnitTestCase {
30 * @var \Drupal\Core\Extension\ModuleHandlerInterface|\Prophecy\Prophecy\ProphecyInterface
32 protected $moduleHandler;
35 * The cache backend to use.
37 * @var \Drupal\Core\Cache\CacheBackendInterface|\Prophecy\Prophecy\ProphecyInterface
39 protected $cacheBackend;
42 * The cache tags invalidator.
44 * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\Prophecy\Prophecy\ProphecyInterface
46 protected $cacheTagsInvalidator;
49 * The typed data manager.
51 * @var \Drupal\Core\TypedData\TypedDataManagerInterface|\Prophecy\Prophecy\ProphecyInterface
53 protected $typedDataManager;
56 * The entity type manager.
58 * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\Prophecy\Prophecy\ProphecyInterface
60 protected $entityTypeManager;
63 * The language manager.
65 * @var \Drupal\Core\Language\LanguageManagerInterface
67 protected $languageManager;
70 * The entity type bundle info under test.
72 * @var \Drupal\Core\Entity\EntityTypeBundleInfo
74 protected $entityTypeBundleInfo;
79 protected function setUp() {
82 $this->moduleHandler = $this->prophesize(ModuleHandlerInterface::class);
83 $this->moduleHandler->getImplementations('entity_type_build')->willReturn([]);
84 $this->moduleHandler->alter('entity_type', Argument::type('array'))->willReturn(NULL);
86 $this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
88 $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
90 $this->cacheTagsInvalidator = $this->prophesize(CacheTagsInvalidatorInterface::class);
92 $language = new Language(['id' => 'en']);
93 $this->languageManager = $this->prophesize(LanguageManagerInterface::class);
94 $this->languageManager->getCurrentLanguage()->willReturn($language);
95 $this->languageManager->getLanguages()->willReturn(['en' => (object) ['id' => 'en']]);
97 $this->typedDataManager = $this->prophesize(TypedDataManagerInterface::class);
99 $this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
101 $container = $this->prophesize(ContainerInterface::class);
102 $container->get('cache_tags.invalidator')->willReturn($this->cacheTagsInvalidator->reveal());
103 //$container->get('typed_data_manager')->willReturn($this->typedDataManager->reveal());
104 \Drupal::setContainer($container->reveal());
106 $this->entityTypeBundleInfo = new EntityTypeBundleInfo($this->entityTypeManager->reveal(), $this->languageManager->reveal(), $this->moduleHandler->reveal(), $this->typedDataManager->reveal(), $this->cacheBackend->reveal());
110 * Sets up the entity type manager to be tested.
112 * @param \Drupal\Core\Entity\EntityTypeInterface[]|\Prophecy\Prophecy\ProphecyInterface[] $definitions
113 * (optional) An array of entity type definitions.
115 protected function setUpEntityTypeDefinitions($definitions = []) {
116 $class = $this->getMockClass(EntityInterface::class);
117 foreach ($definitions as $key => $entity_type) {
118 // \Drupal\Core\Entity\EntityTypeInterface::getLinkTemplates() is called
119 // by \Drupal\Core\Entity\EntityManager::processDefinition() so it must
121 $entity_type->getLinkTemplates()->willReturn([]);
123 // Give the entity type a legitimate class to return.
124 $entity_type->getClass()->willReturn($class);
126 $definitions[$key] = $entity_type->reveal();
129 $this->entityTypeManager->getDefinition(Argument::cetera())
130 ->will(function ($args) use ($definitions) {
131 $entity_type_id = $args[0];
132 $exception_on_invalid = $args[1];
133 if (isset($definitions[$entity_type_id])) {
134 return $definitions[$entity_type_id];
136 elseif (!$exception_on_invalid) {
139 else throw new PluginNotFoundException($entity_type_id);
141 $this->entityTypeManager->getDefinitions()->willReturn($definitions);
146 * Tests the clearCachedBundles() method.
148 * @covers ::clearCachedBundles
150 public function testClearCachedBundles() {
151 $this->setUpEntityTypeDefinitions();
153 $this->typedDataManager->clearCachedDefinitions()->shouldBeCalled();
155 $this->cacheTagsInvalidator->invalidateTags(['entity_bundles'])->shouldBeCalled();
157 $this->entityTypeBundleInfo->clearCachedBundles();
161 * Tests the getBundleInfo() method.
163 * @covers ::getBundleInfo
165 * @dataProvider providerTestGetBundleInfo
167 public function testGetBundleInfo($entity_type_id, $expected) {
168 $this->moduleHandler->invokeAll('entity_bundle_info')->willReturn([]);
169 $this->moduleHandler->alter('entity_bundle_info', Argument::type('array'))->willReturn(NULL);
171 $apple = $this->prophesize(EntityTypeInterface::class);
172 $apple->getLabel()->willReturn('Apple');
173 $apple->getBundleEntityType()->willReturn(NULL);
175 $banana = $this->prophesize(EntityTypeInterface::class);
176 $banana->getLabel()->willReturn('Banana');
177 $banana->getBundleEntityType()->willReturn(NULL);
179 $this->setUpEntityTypeDefinitions([
184 $bundle_info = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);
185 $this->assertSame($expected, $bundle_info);
189 * Provides test data for testGetBundleInfo().
194 public function providerTestGetBundleInfo() {
211 * Tests the getAllBundleInfo() method.
213 * @covers ::getAllBundleInfo
215 public function testGetAllBundleInfo() {
216 $this->moduleHandler->invokeAll('entity_bundle_info')->willReturn([]);
217 $this->moduleHandler->alter('entity_bundle_info', Argument::type('array'))->willReturn(NULL);
219 $apple = $this->prophesize(EntityTypeInterface::class);
220 $apple->getLabel()->willReturn('Apple');
221 $apple->getBundleEntityType()->willReturn(NULL);
223 $banana = $this->prophesize(EntityTypeInterface::class);
224 $banana->getLabel()->willReturn('Banana');
225 $banana->getBundleEntityType()->willReturn(NULL);
227 $this->setUpEntityTypeDefinitions([
232 $this->cacheBackend->get('entity_bundle_info:en')->willReturn(FALSE);
233 $this->cacheBackend->set('entity_bundle_info:en', Argument::any(), Cache::PERMANENT, ['entity_types', 'entity_bundles'])
235 $this->get('entity_bundle_info:en')
236 ->willReturn((object) ['data' => 'cached data'])
241 $this->cacheTagsInvalidator->invalidateTags(['entity_bundles'])->shouldBeCalled();
243 $this->typedDataManager->clearCachedDefinitions()->shouldBeCalled();
257 $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
258 $this->assertSame($expected, $bundle_info);
260 $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
261 $this->assertSame($expected, $bundle_info);
263 $this->entityTypeBundleInfo->clearCachedBundles();
265 $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
266 $this->assertSame('cached data', $bundle_info);
270 * @covers ::getAllBundleInfo
272 public function testGetAllBundleInfoWithEntityBundleInfo() {
273 // Ensure that EntityTypeBundleInfo::getAllBundleInfo() does not add
274 // additional bundles if hook_entity_bundle_info() defines some and the
275 // entity_type does not define a bundle entity type.
276 $this->moduleHandler->invokeAll('entity_bundle_info')->willReturn([
279 'label' => 'Fig banana',
283 $this->moduleHandler->alter('entity_bundle_info', Argument::type('array'))->willReturn(NULL);
285 $apple = $this->prophesize(EntityTypeInterface::class);
286 $apple->getLabel()->willReturn('Apple');
287 $apple->getBundleEntityType()->willReturn(NULL);
289 $banana = $this->prophesize(EntityTypeInterface::class);
290 $banana->getLabel()->willReturn('Banana');
291 $banana->getBundleEntityType()->willReturn(NULL);
293 $this->setUpEntityTypeDefinitions([
301 'label' => 'Fig banana',
310 $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
311 $this->assertSame($expected, $bundle_info);