[!!!][TASK] Replace ClassInfo with ClassSchema
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Mvc / Controller / ActionControllerTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Mvc\Controller;
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 TYPO3\CMS\Core\Page\PageRenderer;
18 use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
19 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
20 use TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException;
21 use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchActionException;
22 use TYPO3\CMS\Extbase\Mvc\RequestInterface;
23 use TYPO3\CMS\Extbase\Object\ObjectManager;
24 use TYPO3Fluid\Fluid\View\AbstractTemplateView;
25 use TYPO3Fluid\Fluid\View\TemplateView;
26
27 /**
28 * Test case
29 */
30 class ActionControllerTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
31 {
32 /**
33 * @var \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface
34 */
35 protected $actionController;
36
37 /**
38 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
39 */
40 protected $mockObjectManager;
41
42 /**
43 * @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder
44 */
45 protected $mockUriBuilder;
46
47 /**
48 * @var \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService
49 */
50 protected $mockMvcPropertyMappingConfigurationService;
51
52 protected function setUp()
53 {
54 $this->actionController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class);
55 }
56
57 /**
58 * @test
59 */
60 public function processRequestSticksToSpecifiedSequence()
61 {
62 $mockRequest = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Web\Request::class);
63 $mockRequest->expects($this->once())->method('setDispatched')->with(true);
64 $mockUriBuilder = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class);
65 $mockUriBuilder->expects($this->once())->method('setRequest')->with($mockRequest);
66 $mockObjectManager = $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class);
67 $mockObjectManager->expects($this->once())->method('get')->with(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class)->will($this->returnValue($mockUriBuilder));
68 $mockResponse = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Web\Response::class);
69 $configurationService = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService::class);
70 /** @var \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface */
71 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, [
72 'initializeFooAction',
73 'initializeAction',
74 'resolveActionMethodName',
75 'initializeActionMethodArguments',
76 'initializeActionMethodValidators',
77 'mapRequestArgumentsToControllerArguments',
78 'buildControllerContext',
79 'resolveView',
80 'initializeView',
81 'callActionMethod',
82 'checkRequestHash'
83 ], [], '', false);
84 $mockController->_set('objectManager', $mockObjectManager);
85
86 $mockController->expects($this->at(0))->method('resolveActionMethodName')->will($this->returnValue('fooAction'));
87 $mockController->expects($this->at(1))->method('initializeActionMethodArguments');
88 $mockController->expects($this->at(2))->method('initializeActionMethodValidators');
89 $mockController->expects($this->at(3))->method('initializeAction');
90 $mockController->expects($this->at(4))->method('initializeFooAction');
91 $mockController->expects($this->at(5))->method('mapRequestArgumentsToControllerArguments');
92 $mockController->expects($this->at(6))->method('checkRequestHash');
93 $mockController->expects($this->at(7))->method('buildControllerContext');
94 $mockController->expects($this->at(8))->method('resolveView');
95
96 $mockController->_set('mvcPropertyMappingConfigurationService', $configurationService);
97 $mockController->_set('arguments', new \TYPO3\CMS\Extbase\Mvc\Controller\Arguments());
98
99 $mockController->processRequest($mockRequest, $mockResponse);
100 $this->assertSame($mockRequest, $mockController->_get('request'));
101 $this->assertSame($mockResponse, $mockController->_get('response'));
102 }
103
104 /**
105 * @test
106 */
107 public function resolveViewUsesFluidTemplateViewIfTemplateIsAvailable()
108 {
109 $mockControllerContext = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext::class);
110 $mockFluidTemplateView = $this->createMock(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface::class);
111 $mockFluidTemplateView->expects($this->once())->method('setControllerContext')->with($mockControllerContext);
112 $mockFluidTemplateView->expects($this->once())->method('canRender')->with($mockControllerContext)->will($this->returnValue(true));
113 $mockObjectManager = $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class);
114 $mockObjectManager->expects($this->at(0))->method('get')->with(\TYPO3\CMS\Fluid\View\TemplateView::class)->will($this->returnValue($mockFluidTemplateView));
115 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['buildControllerContext', 'resolveViewObjectName', 'setViewConfiguration'], [], '', false);
116 $mockController->expects($this->once())->method('resolveViewObjectName')->will($this->returnValue(false));
117 $mockController->_set('objectManager', $mockObjectManager);
118 $mockController->_set('controllerContext', $mockControllerContext);
119 $this->assertSame($mockFluidTemplateView, $mockController->_call('resolveView'));
120 }
121
122 /**
123 * @test
124 */
125 public function resolveViewObjectNameUsesViewObjectNamePatternToResolveViewObjectName()
126 {
127 $mockRequest = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class);
128 $mockRequest->expects($this->once())->method('getControllerVendorName')->will($this->returnValue('MyVendor'));
129 $mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('MyPackage'));
130 $mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('MyController'));
131 $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('MyAction'));
132 $mockRequest->expects($this->atLeastOnce())->method('getFormat')->will($this->returnValue('MyFormat'));
133 $mockObjectManager = $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class);
134 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['dummy'], [], '', false);
135 $mockController->_set('request', $mockRequest);
136 $mockController->_set('objectManager', $mockObjectManager);
137 $mockController->_set('namespacesViewObjectNamePattern', 'RandomViewObject@vendor\@extension\View\@controller\@action@format');
138 $mockController->_call('resolveViewObjectName');
139 }
140
141 /**
142 * @test
143 */
144 public function resolveViewObjectNameUsesNamespacedViewObjectNamePatternForExtensionsWithVendor()
145 {
146 eval('namespace MyVendor\MyPackage\View\MyController; class MyActionMyFormat {}');
147
148 $mockRequest = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class);
149 $mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('MyPackage'));
150 $mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('MyController'));
151 $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('MyAction'));
152 $mockRequest->expects($this->once())->method('getControllerVendorName')->will($this->returnValue('MyVendor'));
153 $mockRequest->expects($this->atLeastOnce())->method('getFormat')->will($this->returnValue('MyFormat'));
154 $mockObjectManager = $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class);
155 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['dummy'], [], '', false);
156 $mockController->_set('request', $mockRequest);
157 $mockController->_set('objectManager', $mockObjectManager);
158
159 $this->assertEquals(
160 'MyVendor\MyPackage\View\MyController\MyActionMyFormat',
161 $mockController->_call('resolveViewObjectName')
162 );
163 }
164
165 /**
166 * @test
167 */
168 public function resolveActionMethodNameReturnsTheCurrentActionMethodNameFromTheRequest()
169 {
170 $mockRequest = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class);
171 $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('fooBar'));
172 /** @var \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface */
173 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['fooBarAction'], [], '', false);
174 $mockController->_set('request', $mockRequest);
175 $this->assertEquals('fooBarAction', $mockController->_call('resolveActionMethodName'));
176 }
177
178 /**
179 * @test
180 */
181 public function resolveActionMethodNameThrowsAnExceptionIfTheActionDefinedInTheRequestDoesNotExist()
182 {
183 $this->expectException(NoSuchActionException::class);
184 $this->expectExceptionCode(1186669086);
185 $mockRequest = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class);
186 $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('fooBar'));
187 /** @var \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface */
188 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['otherBarAction'], [], '', false);
189 $mockController->_set('request', $mockRequest);
190 $mockController->_call('resolveActionMethodName');
191 }
192
193 /**
194 * @test
195 */
196 public function initializeActionMethodArgumentsRegistersArgumentsFoundInTheSignatureOfTheCurrentActionMethod()
197 {
198 $mockRequest = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class);
199 $mockArguments = $this->getMockBuilder(\TYPO3\CMS\Extbase\Mvc\Controller\Arguments::class)
200 ->setMethods(['addNewArgument', 'removeAll'])
201 ->getMock();
202 $mockArguments->expects($this->at(0))->method('addNewArgument')->with('stringArgument', 'string', true);
203 $mockArguments->expects($this->at(1))->method('addNewArgument')->with('integerArgument', 'integer', true);
204 $mockArguments->expects($this->at(2))->method('addNewArgument')->with('objectArgument', 'F3_Foo_Bar', true);
205 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['fooAction', 'evaluateDontValidateAnnotations'], [], '', false);
206 $methodParameters = [
207 'stringArgument' => [
208 'position' => 0,
209 'byReference' => false,
210 'array' => false,
211 'optional' => false,
212 'allowsNull' => false,
213 'type' => 'string'
214 ],
215 'integerArgument' => [
216 'position' => 1,
217 'byReference' => false,
218 'array' => false,
219 'optional' => false,
220 'allowsNull' => false,
221 'type' => 'integer'
222 ],
223 'objectArgument' => [
224 'position' => 2,
225 'byReference' => false,
226 'array' => false,
227 'optional' => false,
228 'allowsNull' => false,
229 'type' => 'F3_Foo_Bar'
230 ]
231 ];
232 $mockReflectionService = $this->createMock(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class);
233 $mockReflectionService->expects($this->once())->method('getMethodParameters')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodParameters));
234 $mockController->_set('reflectionService', $mockReflectionService);
235 $mockController->_set('request', $mockRequest);
236 $mockController->_set('arguments', $mockArguments);
237 $mockController->_set('actionMethodName', 'fooAction');
238 $mockController->_call('initializeActionMethodArguments');
239 }
240
241 /**
242 * @test
243 */
244 public function initializeActionMethodArgumentsRegistersOptionalArgumentsAsSuch()
245 {
246 $mockRequest = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class);
247 $mockArguments = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Controller\Arguments::class);
248 $mockArguments->expects($this->at(0))->method('addNewArgument')->with('arg1', 'string', true);
249 $mockArguments->expects($this->at(1))->method('addNewArgument')->with('arg2', 'array', false, [21]);
250 $mockArguments->expects($this->at(2))->method('addNewArgument')->with('arg3', 'string', false, 42);
251 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['fooAction', 'evaluateDontValidateAnnotations'], [], '', false);
252 $methodParameters = [
253 'arg1' => [
254 'position' => 0,
255 'byReference' => false,
256 'array' => false,
257 'optional' => false,
258 'allowsNull' => false,
259 'type' => 'string',
260 'hasDefaultValue' => false
261 ],
262 'arg2' => [
263 'position' => 1,
264 'byReference' => false,
265 'array' => true,
266 'optional' => true,
267 'defaultValue' => [21],
268 'allowsNull' => false,
269 'hasDefaultValue' => true
270 ],
271 'arg3' => [
272 'position' => 2,
273 'byReference' => false,
274 'array' => false,
275 'optional' => true,
276 'defaultValue' => 42,
277 'allowsNull' => false,
278 'type' => 'string',
279 'hasDefaultValue' => true
280 ]
281 ];
282 $mockReflectionService = $this->createMock(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class);
283 $mockReflectionService->expects($this->once())->method('getMethodParameters')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodParameters));
284 $mockController->_set('reflectionService', $mockReflectionService);
285 $mockController->_set('request', $mockRequest);
286 $mockController->_set('arguments', $mockArguments);
287 $mockController->_set('actionMethodName', 'fooAction');
288 $mockController->_call('initializeActionMethodArguments');
289 }
290
291 /**
292 * @test
293 */
294 public function initializeActionMethodArgumentsThrowsExceptionIfDataTypeWasNotSpecified()
295 {
296 $this->expectException(InvalidArgumentTypeException::class);
297 $this->expectExceptionCode(1253175643);
298 $mockRequest = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class);
299 $mockArguments = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Controller\Arguments::class);
300 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['fooAction'], [], '', false);
301 $methodParameters = [
302 'arg1' => [
303 'position' => 0,
304 'byReference' => false,
305 'array' => false,
306 'optional' => false,
307 'allowsNull' => false
308 ]
309 ];
310 $mockReflectionService = $this->createMock(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class);
311 $mockReflectionService->expects($this->once())->method('getMethodParameters')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodParameters));
312 $mockController->_set('reflectionService', $mockReflectionService);
313 $mockController->_set('request', $mockRequest);
314 $mockController->_set('arguments', $mockArguments);
315 $mockController->_set('actionMethodName', 'fooAction');
316 $mockController->_call('initializeActionMethodArguments');
317 }
318
319 /**
320 * @test
321 * @dataProvider templateRootPathDataProvider
322 * @param array $configuration
323 * @param array $expected
324 */
325 public function setViewConfigurationResolvesTemplateRootPathsForTemplateRootPath($configuration, $expected)
326 {
327 /** @var ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface $mockController */
328 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['dummy'], [], '', false);
329 /** @var ConfigurationManagerInterface|\PHPUnit_Framework_MockObject_MockObject $mockConfigurationManager */
330 $mockConfigurationManager = $this->createMock(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::class);
331 $mockConfigurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($configuration));
332 $mockController->injectConfigurationManager($mockConfigurationManager);
333 $mockController->_set('request', $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class), ['getControllerExtensionKey']);
334 $view = $this->getMockBuilder(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface::class)
335 ->setMethods(['setControllerContext', 'assign', 'assignMultiple', 'canRender', 'render', 'initializeView', 'setTemplateRootPaths'])
336 ->getMock();
337 $view->expects($this->once())->method('setTemplateRootPaths')->with($expected);
338 $mockController->_call('setViewConfiguration', $view);
339 }
340
341 /**
342 * @return array
343 */
344 public function templateRootPathDataProvider()
345 {
346 return [
347 'text keys' => [
348 [
349 'view' => [
350 'templateRootPaths' => [
351 'default' => 'some path',
352 'extended' => 'some other path'
353 ]
354 ]
355 ],
356 [
357 'extended' => 'some other path',
358 'default' => 'some path'
359 ]
360 ],
361 'numerical keys' => [
362 [
363 'view' => [
364 'templateRootPaths' => [
365 '10' => 'some path',
366 '20' => 'some other path',
367 '15' => 'intermediate specific path'
368 ]
369 ]
370 ],
371 [
372 '20' => 'some other path',
373 '15' => 'intermediate specific path',
374 '10' => 'some path'
375 ]
376 ],
377 'mixed keys' => [
378 [
379 'view' => [
380 'templateRootPaths' => [
381 '10' => 'some path',
382 'very_specific' => 'some other path',
383 '15' => 'intermediate specific path'
384 ]
385 ]
386 ],
387 [
388 '15' => 'intermediate specific path',
389 'very_specific' => 'some other path',
390 '10' => 'some path'
391 ]
392 ],
393 ];
394 }
395
396 /**
397 * @test
398 * @dataProvider layoutRootPathDataProvider
399 *
400 * @param array $configuration
401 * @param array $expected
402 */
403 public function setViewConfigurationResolvesLayoutRootPathsForLayoutRootPath($configuration, $expected)
404 {
405 /** @var ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface $mockController */
406 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['dummy'], [], '', false);
407 /** @var ConfigurationManagerInterface|\PHPUnit_Framework_MockObject_MockObject $mockConfigurationManager */
408 $mockConfigurationManager = $this->createMock(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::class);
409 $mockConfigurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($configuration));
410 $mockController->injectConfigurationManager($mockConfigurationManager);
411 $mockController->_set('request', $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class), ['getControllerExtensionKey']);
412 $view = $this->getMockBuilder(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface::class)
413 ->setMethods(['setControllerContext', 'assign', 'assignMultiple', 'canRender', 'render', 'initializeView', 'setlayoutRootPaths'])
414 ->getMock();
415 $view->expects($this->once())->method('setlayoutRootPaths')->with($expected);
416 $mockController->_call('setViewConfiguration', $view);
417 }
418
419 /**
420 * @return array
421 */
422 public function layoutRootPathDataProvider()
423 {
424 return [
425 'text keys' => [
426 [
427 'view' => [
428 'layoutRootPaths' => [
429 'default' => 'some path',
430 'extended' => 'some other path'
431 ]
432 ]
433 ],
434 [
435 'extended' => 'some other path',
436 'default' => 'some path'
437 ]
438 ],
439 'numerical keys' => [
440 [
441 'view' => [
442 'layoutRootPaths' => [
443 '10' => 'some path',
444 '20' => 'some other path',
445 '15' => 'intermediate specific path'
446 ]
447 ]
448 ],
449 [
450 '20' => 'some other path',
451 '15' => 'intermediate specific path',
452 '10' => 'some path'
453 ]
454 ],
455 'mixed keys' => [
456 [
457 'view' => [
458 'layoutRootPaths' => [
459 '10' => 'some path',
460 'very_specific' => 'some other path',
461 '15' => 'intermediate specific path'
462 ]
463 ]
464 ],
465 [
466 '15' => 'intermediate specific path',
467 'very_specific' => 'some other path',
468 '10' => 'some path'
469 ]
470 ],
471 ];
472 }
473
474 /**
475 * @test
476 * @dataProvider partialRootPathDataProvider
477 *
478 * @param array $configuration
479 * @param array $expected
480 */
481 public function setViewConfigurationResolvesPartialRootPathsForPartialRootPath($configuration, $expected)
482 {
483 /** @var ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface $mockController */
484 $mockController = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController::class, ['dummy'], [], '', false);
485 /** @var ConfigurationManagerInterface|\PHPUnit_Framework_MockObject_MockObject $mockConfigurationManager */
486 $mockConfigurationManager = $this->createMock(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::class);
487 $mockConfigurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($configuration));
488 $mockController->injectConfigurationManager($mockConfigurationManager);
489 $mockController->_set('request', $this->createMock(\TYPO3\CMS\Extbase\Mvc\Request::class), ['getControllerExtensionKey']);
490 $view = $this->getMockBuilder(\TYPO3\CMS\Extbase\Mvc\View\ViewInterface::class)
491 ->setMethods(['setControllerContext', 'assign', 'assignMultiple', 'canRender', 'render', 'initializeView', 'setpartialRootPaths'])
492 ->getMock();
493 $view->expects($this->once())->method('setpartialRootPaths')->with($expected);
494 $mockController->_call('setViewConfiguration', $view);
495 }
496
497 /**
498 * @return array
499 */
500 public function partialRootPathDataProvider()
501 {
502 return [
503 'text keys' => [
504 [
505 'view' => [
506 'partialRootPaths' => [
507 'default' => 'some path',
508 'extended' => 'some other path'
509 ]
510 ]
511 ],
512 [
513 'extended' => 'some other path',
514 'default' => 'some path'
515 ]
516 ],
517 'numerical keys' => [
518 [
519 'view' => [
520 'partialRootPaths' => [
521 '10' => 'some path',
522 '20' => 'some other path',
523 '15' => 'intermediate specific path'
524 ]
525 ]
526 ],
527 [
528 '20' => 'some other path',
529 '15' => 'intermediate specific path',
530 '10' => 'some path'
531 ]
532 ],
533 'mixed keys' => [
534 [
535 'view' => [
536 'partialRootPaths' => [
537 '10' => 'some path',
538 'very_specific' => 'some other path',
539 '15' => 'intermediate specific path'
540 ]
541 ]
542 ],
543 [
544 '15' => 'intermediate specific path',
545 'very_specific' => 'some other path',
546 '10' => 'some path'
547 ]
548 ],
549 ];
550 }
551
552 /**
553 * @param TemplateView $viewMock
554 * @param string|null $expectedHeader
555 * @param string|null $expectedFooter
556 * @test
557 * @dataProvider headerAssetDataProvider
558 */
559 public function rendersAndAssignsAssetsFromViewIntoPageRenderer($viewMock, $expectedHeader, $expectedFooter)
560 {
561 $this->mockObjectManager = $this->getMockBuilder(ObjectManager::class)->setMethods(['get'])->getMock();
562 $pageRendererMock = $this->getMockBuilder(PageRenderer::class)->setMethods(['addHeaderData', 'addFooterData'])->getMock();
563 if (!$viewMock instanceof TemplateView) {
564 $this->mockObjectManager->expects($this->never())->method('get');
565 } else {
566 $this->mockObjectManager->expects($this->any())->method('get')->with(PageRenderer::class)->willReturn($pageRendererMock);
567 }
568 if (!empty(trim($expectedHeader))) {
569 $pageRendererMock->expects($this->once())->method('addHeaderData')->with($expectedHeader);
570 } else {
571 $pageRendererMock->expects($this->never())->method('addHeaderData');
572 }
573 if (!empty(trim($expectedFooter))) {
574 $pageRendererMock->expects($this->once())->method('addFooterData')->with($expectedFooter);
575 } else {
576 $pageRendererMock->expects($this->never())->method('addFooterData');
577 }
578 $requestMock = $this->getMockBuilder(RequestInterface::class)->getMockForAbstractClass();
579 $subject = new ActionController();
580 $viewProperty = new \ReflectionProperty($subject, 'view');
581 $viewProperty->setAccessible(true);
582 $viewProperty->setValue($subject, $viewMock);
583 $objectManagerProperty = new \ReflectionProperty($subject, 'objectManager');
584 $objectManagerProperty->setAccessible(true);
585 $objectManagerProperty->setValue($subject, $this->mockObjectManager);
586
587 $method = new \ReflectionMethod($subject, 'renderAssetsForRequest');
588 $method->setAccessible(true);
589 $method->invokeArgs($subject, [$requestMock]);
590 }
591
592 /**
593 * @return array
594 */
595 public function headerAssetDataProvider()
596 {
597 $viewWithHeaderData = $this->getMockBuilder(TemplateView::class)->setMethods(['renderSection'])->disableOriginalConstructor()->getMock();
598 $viewWithHeaderData->expects($this->at(0))->method('renderSection')->with('HeaderAssets', $this->anything(), true)->willReturn('custom-header-data');
599 $viewWithHeaderData->expects($this->at(1))->method('renderSection')->with('FooterAssets', $this->anything(), true)->willReturn(null);
600 $viewWithFooterData = $this->getMockBuilder(TemplateView::class)->setMethods(['renderSection'])->disableOriginalConstructor()->getMock();
601 $viewWithFooterData->expects($this->at(0))->method('renderSection')->with('HeaderAssets', $this->anything(), true)->willReturn(null);
602 $viewWithFooterData->expects($this->at(1))->method('renderSection')->with('FooterAssets', $this->anything(), true)->willReturn('custom-footer-data');
603 $viewWithBothData = $this->getMockBuilder(TemplateView::class)->setMethods(['renderSection'])->disableOriginalConstructor()->getMock();
604 $viewWithBothData->expects($this->at(0))->method('renderSection')->with('HeaderAssets', $this->anything(), true)->willReturn('custom-header-data');
605 $viewWithBothData->expects($this->at(1))->method('renderSection')->with('FooterAssets', $this->anything(), true)->willReturn('custom-footer-data');
606 $invalidView = $this->getMockBuilder(AbstractTemplateView::class)->disableOriginalConstructor()->getMockForAbstractClass();
607 return [
608 [$viewWithHeaderData, 'custom-header-data', null],
609 [$viewWithFooterData, null, 'custom-footer-data'],
610 [$viewWithBothData, 'custom-header-data', 'custom-footer-data'],
611 [$invalidView, null, null]
612 ];
613 }
614 }