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