More updates to stop using dev or alpha or beta versions.
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Entity / EntityTypeBundleInfoTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Entity;
4
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;
20
21 /**
22  * @coversDefaultClass \Drupal\Core\Entity\EntityTypeBundleInfo
23  * @group Entity
24  */
25 class EntityTypeBundleInfoTest extends UnitTestCase {
26
27   /**
28    * The module handler.
29    *
30    * @var \Drupal\Core\Extension\ModuleHandlerInterface|\Prophecy\Prophecy\ProphecyInterface
31    */
32   protected $moduleHandler;
33
34   /**
35    * The cache backend to use.
36    *
37    * @var \Drupal\Core\Cache\CacheBackendInterface|\Prophecy\Prophecy\ProphecyInterface
38    */
39   protected $cacheBackend;
40
41   /**
42    * The cache tags invalidator.
43    *
44    * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\Prophecy\Prophecy\ProphecyInterface
45    */
46   protected $cacheTagsInvalidator;
47
48   /**
49    * The typed data manager.
50    *
51    * @var \Drupal\Core\TypedData\TypedDataManagerInterface|\Prophecy\Prophecy\ProphecyInterface
52    */
53   protected $typedDataManager;
54
55   /**
56    * The entity type manager.
57    *
58    * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\Prophecy\Prophecy\ProphecyInterface
59    */
60   protected $entityTypeManager;
61
62   /**
63    * The language manager.
64    *
65    * @var \Drupal\Core\Language\LanguageManagerInterface
66    */
67   protected $languageManager;
68
69   /**
70    * The entity type bundle info under test.
71    *
72    * @var \Drupal\Core\Entity\EntityTypeBundleInfo
73    */
74   protected $entityTypeBundleInfo;
75
76   /**
77    * {@inheritdoc}
78    */
79   protected function setUp() {
80     parent::setUp();
81
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);
85
86     $this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
87
88     $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
89
90     $this->cacheTagsInvalidator = $this->prophesize(CacheTagsInvalidatorInterface::class);
91
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']]);
96
97     $this->typedDataManager = $this->prophesize(TypedDataManagerInterface::class);
98
99     $this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
100
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());
105
106     $this->entityTypeBundleInfo = new EntityTypeBundleInfo($this->entityTypeManager->reveal(), $this->languageManager->reveal(), $this->moduleHandler->reveal(), $this->typedDataManager->reveal(), $this->cacheBackend->reveal());
107   }
108
109   /**
110    * Sets up the entity type manager to be tested.
111    *
112    * @param \Drupal\Core\Entity\EntityTypeInterface[]|\Prophecy\Prophecy\ProphecyInterface[] $definitions
113    *   (optional) An array of entity type definitions.
114    */
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
120       // always be mocked.
121       $entity_type->getLinkTemplates()->willReturn([]);
122
123       // Give the entity type a legitimate class to return.
124       $entity_type->getClass()->willReturn($class);
125
126       $definitions[$key] = $entity_type->reveal();
127     }
128
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];
135         }
136         elseif (!$exception_on_invalid) {
137           return NULL;
138         }
139         else {
140           throw new PluginNotFoundException($entity_type_id);
141         }
142       });
143     $this->entityTypeManager->getDefinitions()->willReturn($definitions);
144
145   }
146
147   /**
148    * Tests the clearCachedBundles() method.
149    *
150    * @covers ::clearCachedBundles
151    */
152   public function testClearCachedBundles() {
153     $this->setUpEntityTypeDefinitions();
154
155     $this->typedDataManager->clearCachedDefinitions()->shouldBeCalled();
156
157     $this->cacheTagsInvalidator->invalidateTags(['entity_bundles'])->shouldBeCalled();
158
159     $this->entityTypeBundleInfo->clearCachedBundles();
160   }
161
162   /**
163    * Tests the getBundleInfo() method.
164    *
165    * @covers ::getBundleInfo
166    *
167    * @dataProvider providerTestGetBundleInfo
168    */
169   public function testGetBundleInfo($entity_type_id, $expected) {
170     $this->moduleHandler->invokeAll('entity_bundle_info')->willReturn([]);
171     $this->moduleHandler->alter('entity_bundle_info', Argument::type('array'))->willReturn(NULL);
172
173     $apple = $this->prophesize(EntityTypeInterface::class);
174     $apple->getLabel()->willReturn('Apple');
175     $apple->getBundleEntityType()->willReturn(NULL);
176
177     $banana = $this->prophesize(EntityTypeInterface::class);
178     $banana->getLabel()->willReturn('Banana');
179     $banana->getBundleEntityType()->willReturn(NULL);
180
181     $this->setUpEntityTypeDefinitions([
182       'apple' => $apple,
183       'banana' => $banana,
184     ]);
185
186     $bundle_info = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);
187     $this->assertSame($expected, $bundle_info);
188   }
189
190   /**
191    * Provides test data for testGetBundleInfo().
192    *
193    * @return array
194    *   Test data.
195    */
196   public function providerTestGetBundleInfo() {
197     return [
198       ['apple', [
199           'apple' => ['label' => 'Apple'],
200         ],
201       ],
202       ['banana', [
203           'banana' => ['label' => 'Banana'],
204         ],
205       ],
206       ['pear', []],
207     ];
208   }
209
210   /**
211    * Tests the getAllBundleInfo() method.
212    *
213    * @covers ::getAllBundleInfo
214    */
215   public function testGetAllBundleInfo() {
216     $this->moduleHandler->invokeAll('entity_bundle_info')->willReturn([]);
217     $this->moduleHandler->alter('entity_bundle_info', Argument::type('array'))->willReturn(NULL);
218
219     $apple = $this->prophesize(EntityTypeInterface::class);
220     $apple->getLabel()->willReturn('Apple');
221     $apple->getBundleEntityType()->willReturn(NULL);
222
223     $banana = $this->prophesize(EntityTypeInterface::class);
224     $banana->getLabel()->willReturn('Banana');
225     $banana->getBundleEntityType()->willReturn(NULL);
226
227     $this->setUpEntityTypeDefinitions([
228       'apple' => $apple,
229       'banana' => $banana,
230     ]);
231
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'])
234       ->will(function () {
235         $this->get('entity_bundle_info:en')
236           ->willReturn((object) ['data' => 'cached data'])
237           ->shouldBeCalled();
238       })
239       ->shouldBeCalled();
240
241     $this->cacheTagsInvalidator->invalidateTags(['entity_bundles'])->shouldBeCalled();
242
243     $this->typedDataManager->clearCachedDefinitions()->shouldBeCalled();
244
245     $expected = [
246       'apple' => [
247         'apple' => [
248           'label' => 'Apple',
249         ],
250       ],
251       'banana' => [
252         'banana' => [
253           'label' => 'Banana',
254         ],
255       ],
256     ];
257     $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
258     $this->assertSame($expected, $bundle_info);
259
260     $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
261     $this->assertSame($expected, $bundle_info);
262
263     $this->entityTypeBundleInfo->clearCachedBundles();
264
265     $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
266     $this->assertSame('cached data', $bundle_info);
267   }
268
269   /**
270    * @covers ::getAllBundleInfo
271    */
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([
277       'banana' => [
278         'fig' => [
279           'label' => 'Fig banana',
280         ],
281       ],
282     ]);
283     $this->moduleHandler->alter('entity_bundle_info', Argument::type('array'))->willReturn(NULL);
284
285     $apple = $this->prophesize(EntityTypeInterface::class);
286     $apple->getLabel()->willReturn('Apple');
287     $apple->getBundleEntityType()->willReturn(NULL);
288
289     $banana = $this->prophesize(EntityTypeInterface::class);
290     $banana->getLabel()->willReturn('Banana');
291     $banana->getBundleEntityType()->willReturn(NULL);
292
293     $this->setUpEntityTypeDefinitions([
294       'apple' => $apple,
295       'banana' => $banana,
296     ]);
297
298     $expected = [
299       'banana' => [
300         'fig' => [
301           'label' => 'Fig banana',
302         ],
303       ],
304       'apple' => [
305         'apple' => [
306           'label' => 'Apple',
307         ],
308       ],
309     ];
310     $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo();
311     $this->assertSame($expected, $bundle_info);
312   }
313
314 }