[BUGFIX] Add missing namespace parts
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Cache / CacheManagerTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Cache;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Prophecy\Argument;
18 use TYPO3\CMS\Core\Cache\CacheManager;
19 use TYPO3\CMS\Core\Cache\Exception\InvalidBackendException;
20 use TYPO3\CMS\Core\Cache\Exception\InvalidCacheException;
21 use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheGroupException;
22 use TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend;
23 use TYPO3\CMS\Core\Tests\Unit\Cache\Fixtures\BackendConfigurationOptionFixture;
24 use TYPO3\CMS\Core\Tests\Unit\Cache\Fixtures\BackendDefaultFixture;
25 use TYPO3\CMS\Core\Tests\Unit\Cache\Fixtures\BackendFixture;
26 use TYPO3\CMS\Core\Tests\Unit\Cache\Fixtures\BackendInitializeObjectFixture;
27 use TYPO3\CMS\Core\Tests\Unit\Cache\Fixtures\FrontendBackendInstanceFixture;
28 use TYPO3\CMS\Core\Tests\Unit\Cache\Fixtures\FrontendDefaultFixture;
29 use TYPO3\CMS\Core\Tests\Unit\Cache\Fixtures\FrontendFixture;
30 use TYPO3\CMS\Core\Tests\Unit\Cache\Fixtures\FrontendIdentifierFixture;
31 use TYPO3\CMS\Core\Tests\Unit\Cache\Fixtures\FrontendInitializeObjectFixture;
32
33 /**
34 * Testcase for the TYPO3\CMS\Core\Cache\CacheManager
35 *
36 * This file is a backport from FLOW3
37 */
38 class CacheManagerTest extends \TYPO3\Components\TestingFramework\Core\Unit\UnitTestCase
39 {
40 /**
41 * @test
42 */
43 public function managerThrowsExceptionOnCacheRegistrationWithAlreadyExistingIdentifier()
44 {
45 $this->expectException(\TYPO3\CMS\Core\Cache\Exception\DuplicateIdentifierException::class);
46 $this->expectExceptionCode(1203698223);
47
48 $manager = new CacheManager();
49 $cache1 = $this->getMockBuilder(AbstractFrontend::class)
50 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
51 ->disableOriginalConstructor()
52 ->getMock();
53 $cache1->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('test'));
54 $cache2 = $this->getMockBuilder(AbstractFrontend::class)
55 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
56 ->disableOriginalConstructor()
57 ->getMock();
58 $cache2->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('test'));
59 $manager->registerCache($cache1);
60 $manager->registerCache($cache2);
61 }
62
63 /**
64 * @test
65 */
66 public function managerReturnsThePreviouslyRegisteredCache()
67 {
68 $manager = new CacheManager();
69 $cache1 = $this->getMockBuilder(AbstractFrontend::class)
70 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
71 ->disableOriginalConstructor()
72 ->getMock();
73 $cache1->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('cache1'));
74 $cache2 = $this->getMockBuilder(AbstractFrontend::class)
75 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
76 ->disableOriginalConstructor()
77 ->getMock();
78 $cache2->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('cache2'));
79 $manager->registerCache($cache1);
80 $manager->registerCache($cache2);
81 $this->assertSame($cache2, $manager->getCache('cache2'), 'The cache returned by getCache() was not the same I registered.');
82 }
83
84 /**
85 * @test
86 */
87 public function getCacheThrowsExceptionForNonExistingIdentifier()
88 {
89 $this->expectException(\TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException::class);
90 $this->expectExceptionCode(1203699034);
91
92 $manager = new CacheManager();
93 $cache = $this->getMockBuilder(AbstractFrontend::class)
94 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
95 ->disableOriginalConstructor()
96 ->getMock();
97 $cache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('someidentifier'));
98 $manager->registerCache($cache);
99 $manager->getCache('someidentifier');
100 $manager->getCache('doesnotexist');
101 }
102
103 /**
104 * @test
105 */
106 public function hasCacheReturnsCorrectResult()
107 {
108 $manager = new CacheManager();
109 $cache1 = $this->getMockBuilder(AbstractFrontend::class)
110 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
111 ->disableOriginalConstructor()
112 ->getMock();
113 $cache1->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('cache1'));
114 $manager->registerCache($cache1);
115 $this->assertTrue($manager->hasCache('cache1'), 'hasCache() did not return TRUE.');
116 $this->assertFalse($manager->hasCache('cache2'), 'hasCache() did not return FALSE.');
117 }
118
119 /**
120 * @test
121 */
122 public function flushCachesByTagCallsTheFlushByTagMethodOfAllRegisteredCaches()
123 {
124 $manager = new CacheManager();
125 $cache1 = $this->getMockBuilder(AbstractFrontend::class)
126 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
127 ->disableOriginalConstructor()
128 ->getMock();
129 $cache1->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('cache1'));
130 $cache1->expects($this->once())->method('flushByTag')->with($this->equalTo('theTag'));
131 $manager->registerCache($cache1);
132 $cache2 = $this->getMockBuilder(AbstractFrontend::class)
133 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
134 ->disableOriginalConstructor()
135 ->getMock();
136 $cache2->expects($this->once())->method('flushByTag')->with($this->equalTo('theTag'));
137 $manager->registerCache($cache2);
138 $manager->flushCachesByTag('theTag');
139 }
140
141 /**
142 * @test
143 */
144 public function flushCachesByTagsCallsTheFlushByTagsMethodOfAllRegisteredCaches()
145 {
146 $manager = new CacheManager();
147 $cache1 = $this->getMockBuilder(AbstractFrontend::class)
148 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTags'])
149 ->disableOriginalConstructor()
150 ->getMock();
151 $cache1->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('cache1'));
152 $cache1->expects($this->once())->method('flushByTags')->with($this->equalTo(['theTag']));
153 $manager->registerCache($cache1);
154 $cache2 = $this->getMockBuilder(AbstractFrontend::class)
155 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTags'])
156 ->disableOriginalConstructor()
157 ->getMock();
158 $cache2->expects($this->once())->method('flushByTags')->with($this->equalTo(['theTag']));
159 $manager->registerCache($cache2);
160 $manager->flushCachesByTags(['theTag']);
161 }
162
163 /**
164 * @test
165 */
166 public function flushCachesCallsTheFlushMethodOfAllRegisteredCaches()
167 {
168 $manager = new CacheManager();
169 $cache1 = $this->getMockBuilder(AbstractFrontend::class)
170 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
171 ->disableOriginalConstructor()
172 ->getMock();
173 $cache1->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('cache1'));
174 $cache1->expects($this->once())->method('flush');
175 $manager->registerCache($cache1);
176 $cache2 = $this->getMockBuilder(AbstractFrontend::class)
177 ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag'])
178 ->disableOriginalConstructor()
179 ->getMock();
180 $cache2->expects($this->once())->method('flush');
181 $manager->registerCache($cache2);
182 $manager->flushCaches();
183 }
184
185 /**
186 * @test
187 */
188 public function flushCachesInGroupThrowsExceptionForNonExistingGroup()
189 {
190 $this->expectException(NoSuchCacheGroupException::class);
191 $this->expectExceptionCode(1390334120);
192
193 $manager = new CacheManager();
194 $manager->flushCachesInGroup('nonExistingGroup');
195 }
196
197 /**
198 * @test
199 */
200 public function flushCachesInGroupByTagThrowsExceptionForNonExistingGroup()
201 {
202 $this->expectException(NoSuchCacheGroupException::class);
203 $this->expectExceptionCode(1390334120);
204
205 $manager = new CacheManager();
206 $manager->flushCachesInGroup('nonExistingGroup');
207 }
208
209 /**
210 * @test
211 */
212 public function getCacheThrowsExceptionIfConfiguredFrontendDoesNotImplementFrontendInterface()
213 {
214 $manager = new CacheManager();
215 $cacheIdentifier = 'aCache';
216 $configuration = [
217 $cacheIdentifier => [
218 'frontend' => \stdClass::class,
219 'backend' => BackendFixture::class,
220 'options' => [],
221 ],
222 ];
223 $manager->setCacheConfigurations($configuration);
224 $this->expectException(InvalidCacheException::class);
225 $this->expectExceptionCode(1464550984);
226 $manager->getCache($cacheIdentifier);
227 }
228
229 /**
230 * @test
231 */
232 public function getCacheThrowsExceptionIfConfiguredBackendDoesNotImplementBackendInterface()
233 {
234 $manager = new CacheManager();
235 $cacheIdentifier = 'aCache';
236 $configuration = [
237 $cacheIdentifier => [
238 'frontend' => FrontendFixture::class,
239 'backend' => \stdClass::class,
240 'options' => [],
241 ],
242 ];
243 $manager->setCacheConfigurations($configuration);
244 $this->expectException(InvalidBackendException::class);
245 $this->expectExceptionCode(1464550977);
246 $manager->getCache($cacheIdentifier);
247 }
248
249 /**
250 * @test
251 */
252 public function getCacheCallsInitializeObjectOnFrontendInstance()
253 {
254 $manager = new CacheManager();
255 $cacheIdentifier = 'aCache';
256 $configuration = [
257 $cacheIdentifier => [
258 'backend' => BackendFixture::class,
259 'frontend' => FrontendInitializeObjectFixture::class,
260 'options' => [],
261 ],
262 ];
263 $manager->setCacheConfigurations($configuration);
264 // BackendInitializeObjectFixture throws exception if initializeObject() is called, so expect this
265 $this->expectException(\RuntimeException::class);
266 $this->expectExceptionCode(1464553495);
267 $manager->getCache($cacheIdentifier);
268 }
269
270 /**
271 * @test
272 */
273 public function getCacheCallsInitializeObjectOnBackendInstance()
274 {
275 $manager = new CacheManager();
276 $cacheIdentifier = 'aCache';
277 $configuration = [
278 $cacheIdentifier => [
279 'backend' => BackendInitializeObjectFixture::class,
280 'frontend' => FrontendFixture::class,
281 'options' => [],
282 ],
283 ];
284 $manager->setCacheConfigurations($configuration);
285 // BackendInitializeObjectFixture throws exception if initializeObject() is called, so expect this
286 $this->expectException(\RuntimeException::class);
287 $this->expectExceptionCode(1464552894);
288 $manager->getCache($cacheIdentifier);
289 }
290
291 /**
292 * @test
293 */
294 public function getCacheCreatesBackendWithGivenConfiguration()
295 {
296 $manager = new CacheManager();
297 $cacheIdentifier = 'aCache';
298 $configuration = [
299 $cacheIdentifier => [
300 'backend' => BackendConfigurationOptionFixture::class,
301 'frontend' => FrontendFixture::class,
302 'options' => [
303 'anOption' => 'anOptionValue',
304 ],
305 ],
306 ];
307 $manager->setCacheConfigurations($configuration);
308 // BackendInitializeObjectFixture throws exception if initializeObject() is called, so expect this
309 $this->expectException(\RuntimeException::class);
310 $this->expectExceptionCode(1464555007);
311 $manager->getCache($cacheIdentifier);
312 }
313
314 /**
315 * @test
316 */
317 public function getCacheCreatesCacheInstanceWithFallbackToDefaultFrontend()
318 {
319 /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\Components\TestingFramework\Core\AccessibleObjectInterface|CacheManager $manager */
320 $manager = $this->getAccessibleMock(CacheManager::class, ['dummy'], [], '', false);
321 $cacheIdentifier = $this->getUniqueId('Test');
322 $configuration = [
323 $cacheIdentifier => [
324 'backend' => BackendFixture::class,
325 'options' => []
326 ]
327 ];
328 $defaultCacheConfiguration = [
329 'frontend' => FrontendDefaultFixture::class,
330 'options' => [],
331 'groups' => [],
332 ];
333 $manager->_set('defaultCacheConfiguration', $defaultCacheConfiguration);
334 $manager->setCacheConfigurations($configuration);
335 $this->expectException(\RuntimeException::class);
336 $this->expectExceptionCode(1476109149);
337 $manager->getCache($cacheIdentifier);
338 }
339
340 /**
341 * @test
342 */
343 public function getCacheCreatesCacheInstanceWithFallbackToDefaultBackend()
344 {
345 /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\Components\TestingFramework\Core\AccessibleObjectInterface|CacheManager $manager */
346 $manager = $this->getAccessibleMock(CacheManager::class, ['dummy'], [], '', false);
347 $cacheIdentifier = $this->getUniqueId('Test');
348 $configuration = [
349 $cacheIdentifier => [
350 'frontend' => FrontendFixture::class,
351 'options' => []
352 ]
353 ];
354 $defaultCacheConfiguration = [
355 'backend' => BackendDefaultFixture::class,
356 'options' => [],
357 'groups' => [],
358 ];
359 $manager->_set('defaultCacheConfiguration', $defaultCacheConfiguration);
360 $manager->setCacheConfigurations($configuration);
361 $this->expectException(\RuntimeException::class);
362 $this->expectExceptionCode(1464556045);
363 $manager->getCache($cacheIdentifier);
364 }
365
366 /**
367 * @test
368 */
369 public function getCacheReturnsInstanceOfTheSpecifiedCacheFrontend()
370 {
371 $manager = new CacheManager();
372 $cacheIdentifier = 'aCache';
373 $configuration = [
374 $cacheIdentifier => [
375 'backend' => BackendFixture::class,
376 'frontend' => FrontendFixture::class,
377 'options' => [],
378 ],
379 ];
380 $manager->setCacheConfigurations($configuration);
381 $this->assertInstanceOf(FrontendFixture::class, $manager->getCache($cacheIdentifier));
382 }
383
384 /**
385 * @test
386 */
387 public function getCacheGivesIdentifierToCacheFrontend()
388 {
389 $manager = new CacheManager();
390 $cacheIdentifier = 'aCache';
391 $configuration = [
392 $cacheIdentifier => [
393 'backend' => BackendFixture::class,
394 'frontend' => FrontendIdentifierFixture::class,
395 'options' => [],
396 ],
397 ];
398 $manager->setCacheConfigurations($configuration);
399 $this->expectException(\RuntimeException::class);
400 $this->expectExceptionCode(1464555650);
401 $manager->getCache($cacheIdentifier);
402 }
403
404 /**
405 * @test
406 */
407 public function getCacheGivesBackendInstanceToCacheFrontend()
408 {
409 $manager = new CacheManager();
410 $cacheIdentifier = 'aCache';
411 $configuration = [
412 $cacheIdentifier => [
413 'backend' => BackendFixture::class,
414 'frontend' => FrontendBackendInstanceFixture::class,
415 'options' => [],
416 ],
417 ];
418 $manager->setCacheConfigurations($configuration);
419 $this->expectException(\RuntimeException::class);
420 $this->expectExceptionCode(1464557160);
421 $manager->getCache($cacheIdentifier);
422 }
423
424 /**
425 * @test
426 */
427 public function flushCachesInGroupByTagsWithEmptyTagsArrayDoesNotFlushCaches()
428 {
429 /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\Components\TestingFramework\Core\AccessibleObjectInterface|CacheManager $manager */
430 $manager = $this->getAccessibleMock(CacheManager::class, ['dummy'], [], '', false);
431 $cacheIdentifier = 'aTest';
432
433 $cacheGroups = [
434 'group1' => [$cacheIdentifier],
435 'group2' => [$cacheIdentifier],
436 ];
437 $manager->_set('cacheGroups', $cacheGroups);
438
439 $frontend = $this->prophesize(FrontendFixture::class);
440
441 $caches = [
442 $cacheIdentifier => $frontend->reveal()
443 ];
444 $manager->_set('caches', $caches);
445
446 $frontend->flushByTags(Argument::any())->shouldNotBeCalled();
447
448 $configuration = [
449 $cacheIdentifier => [
450 'frontend' => $frontend,
451 'backend' => BackendFixture::class,
452 'options' => [],
453 'groups' => ['group1', 'group2']
454 ],
455 ];
456 $manager->setCacheConfigurations($configuration);
457 $manager->flushCachesInGroupByTags('group2', []);
458 }
459
460 /**
461 * @test
462 */
463 public function flushCachesInGroupByTagsDeletesByTag()
464 {
465 /** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\Components\TestingFramework\Core\AccessibleObjectInterface|CacheManager $manager */
466 $manager = $this->getAccessibleMock(CacheManager::class, ['dummy'], [], '', false);
467 $cacheIdentifier = 'aTest';
468
469 $cacheGroups = [
470 'group1' => [$cacheIdentifier],
471 'group2' => [$cacheIdentifier],
472 ];
473 $manager->_set('cacheGroups', $cacheGroups);
474
475 $frontend = $this->prophesize(FrontendFixture::class);
476
477 $caches = [
478 $cacheIdentifier => $frontend->reveal()
479 ];
480 $manager->_set('caches', $caches);
481
482 $tags = ['tag1', 'tag2'];
483 $frontend->flushByTags($tags)->shouldBeCalled();
484
485 $configuration = [
486 $cacheIdentifier => [
487 'frontend' => $frontend,
488 'backend' => BackendFixture::class,
489 'options' => [],
490 'groups' => ['group1', 'group2']
491 ],
492 ];
493 $manager->setCacheConfigurations($configuration);
494 $manager->flushCachesInGroupByTags('group2', $tags);
495 }
496 }