d00063d07de4cb5b9cf55a9436131459c9487993
[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 /**
18 * Test case
19 */
20 class ActionControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
21
22 /**
23 * @var \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
24 */
25 protected $actionController;
26
27 /**
28 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
29 */
30 protected $mockObjectManager;
31
32 /**
33 * @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder
34 */
35 protected $mockUriBuilder;
36
37 /**
38 * @var \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService
39 */
40 protected $mockMvcPropertyMappingConfigurationService;
41
42 public function setUp() {
43 $this->actionController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController');
44 }
45
46 /**
47 * @test
48 */
49 public function processRequestSticksToSpecifiedSequence() {
50 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Request', array(), array(), '', FALSE);
51 $mockRequest->expects($this->once())->method('setDispatched')->with(TRUE);
52 $mockUriBuilder = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Routing\\UriBuilder');
53 $mockUriBuilder->expects($this->once())->method('setRequest')->with($mockRequest);
54 $mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface');
55 $mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Routing\\UriBuilder')->will($this->returnValue($mockUriBuilder));
56 $mockResponse = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Response', array(), array(), '', FALSE);
57 $configurationService = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\MvcPropertyMappingConfigurationService');
58 /** @var \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
59 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array(
60 'initializeFooAction',
61 'initializeAction',
62 'resolveActionMethodName',
63 'initializeActionMethodArguments',
64 'initializeActionMethodValidators',
65 'mapRequestArgumentsToControllerArguments',
66 'buildControllerContext',
67 'resolveView',
68 'initializeView',
69 'callActionMethod',
70 'checkRequestHash'
71 ), array(), '', FALSE);
72 $mockController->_set('objectManager', $mockObjectManager);
73
74 $mockController->expects($this->at(0))->method('resolveActionMethodName')->will($this->returnValue('fooAction'));
75 $mockController->expects($this->at(1))->method('initializeActionMethodArguments');
76 $mockController->expects($this->at(2))->method('initializeActionMethodValidators');
77 $mockController->expects($this->at(3))->method('initializeAction');
78 $mockController->expects($this->at(4))->method('initializeFooAction');
79 $mockController->expects($this->at(5))->method('mapRequestArgumentsToControllerArguments');
80 $mockController->expects($this->at(6))->method('checkRequestHash');
81 $mockController->expects($this->at(7))->method('buildControllerContext');
82 $mockController->expects($this->at(8))->method('resolveView');
83
84 $mockController->_set('mvcPropertyMappingConfigurationService', $configurationService);
85 $mockController->_set('arguments', new \TYPO3\CMS\Extbase\Mvc\Controller\Arguments());
86
87 $mockController->processRequest($mockRequest, $mockResponse);
88 $this->assertSame($mockRequest, $mockController->_get('request'));
89 $this->assertSame($mockResponse, $mockController->_get('response'));
90 }
91
92 /**
93 * @test
94 * @author Robert Lemke <robert@typo3.org>
95 */
96 public function callActionMethodAppendsStringsReturnedByActionMethodToTheResponseObject() {
97 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
98 $mockResponse = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\ResponseInterface', array(), array(), '', FALSE);
99 $mockResponse->expects($this->once())->method('appendContent')->with('the returned string');
100 $mockArguments = new \ArrayObject();
101 $mockArgumentMappingResults = $this->getMock('TYPO3\\CMS\\Extbase\\Property\\MappingResults', array(), array(), '', FALSE);
102 $mockArgumentMappingResults->expects($this->once())->method('hasErrors')->will($this->returnValue(FALSE));
103 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooAction', 'initializeAction'), array(), '', FALSE);
104 $mockSignalSlotDispatcher = $this->getMock('TYPO3\\CMS\Extbase\\SignalSlot\\Dispatcher', array(), array(), '', FALSE);
105 $mockController->_set('signalSlotDispatcher', $mockSignalSlotDispatcher);
106 $this->enableDeprecatedPropertyMapperInController($mockController);
107 $mockController->expects($this->once())->method('fooAction')->will($this->returnValue('the returned string'));
108 $mockController->_set('request', $mockRequest);
109 $mockController->_set('response', $mockResponse);
110 $mockController->_set('arguments', $mockArguments);
111 $mockController->_set('actionMethodName', 'fooAction');
112 $mockController->_set('argumentsMappingResults', $mockArgumentMappingResults);
113 $mockController->_call('callActionMethod');
114 }
115
116 /**
117 * @test
118 * @author Robert Lemke <robert@typo3.org>
119 */
120 public function callActionMethodRendersTheViewAutomaticallyIfTheActionReturnedNullAndAViewExists() {
121 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
122 $mockResponse = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\ResponseInterface', array(), array(), '', FALSE);
123 $mockResponse->expects($this->once())->method('appendContent')->with('the view output');
124 $mockView = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\View\\ViewInterface');
125 $mockView->expects($this->once())->method('render')->will($this->returnValue('the view output'));
126 $mockArguments = new \ArrayObject();
127 $mockArgumentMappingResults = $this->getMock('TYPO3\\CMS\\Extbase\\Property\\MappingResults', array(), array(), '', FALSE);
128 $mockArgumentMappingResults->expects($this->once())->method('hasErrors')->will($this->returnValue(FALSE));
129 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooAction', 'initializeAction'), array(), '', FALSE);
130 $mockSignalSlotDispatcher = $this->getMock('TYPO3\\CMS\Extbase\\SignalSlot\\Dispatcher', array(), array(), '', FALSE);
131 $mockController->_set('signalSlotDispatcher', $mockSignalSlotDispatcher);
132 $this->enableDeprecatedPropertyMapperInController($mockController);
133 $mockController->expects($this->once())->method('fooAction');
134 $mockController->_set('request', $mockRequest);
135 $mockController->_set('response', $mockResponse);
136 $mockController->_set('arguments', $mockArguments);
137 $mockController->_set('actionMethodName', 'fooAction');
138 $mockController->_set('argumentsMappingResults', $mockArgumentMappingResults);
139 $mockController->_set('view', $mockView);
140 $mockController->_call('callActionMethod');
141 }
142
143 /**
144 * @test
145 * @author Robert Lemke <robert@typo3.org>
146 */
147 public function callActionMethodCallsTheErrorActionIfTheMappingResultsHaveErrors() {
148 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
149 $mockResponse = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\ResponseInterface', array(), array(), '', FALSE);
150 $mockResponse->expects($this->once())->method('appendContent')->with('the returned string');
151 $mockArguments = new \ArrayObject();
152 $mockArgumentMappingResults = $this->getMock('TYPO3\\CMS\\Extbase\\Property\\MappingResults', array(), array(), '', FALSE);
153 $mockArgumentMappingResults->expects($this->once())->method('hasErrors')->will($this->returnValue(TRUE));
154 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('barAction', 'initializeAction'), array(), '', FALSE);
155 $this->enableDeprecatedPropertyMapperInController($mockController);
156 $mockController->expects($this->once())->method('barAction')->will($this->returnValue('the returned string'));
157 $mockController->_set('request', $mockRequest);
158 $mockController->_set('response', $mockResponse);
159 $mockController->_set('arguments', $mockArguments);
160 $mockController->_set('actionMethodName', 'fooAction');
161 $mockController->_set('errorMethodName', 'barAction');
162 $mockController->_set('argumentsMappingResults', $mockArgumentMappingResults);
163 $mockController->_call('callActionMethod');
164 }
165
166 /**
167 * @test
168 * @author Sebastian Kurfürst <sebastian@typo3.org>
169 */
170 public function callActionMethodPassesDefaultValuesAsArguments() {
171 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
172 $mockResponse = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\ResponseInterface', array(), array(), '', FALSE);
173 $arguments = new \ArrayObject();
174 $optionalArgument = new \TYPO3\CMS\Extbase\Mvc\Controller\Argument('name1', 'Text');
175 $optionalArgument->setDefaultValue('Default value');
176 $arguments[] = $optionalArgument;
177 $mockArgumentMappingResults = $this->getMock('TYPO3\\CMS\\Extbase\\Property\\MappingResults', array(), array(), '', FALSE);
178 $mockArgumentMappingResults->expects($this->once())->method('hasErrors')->will($this->returnValue(FALSE));
179 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooAction', 'initializeAction'), array(), '', FALSE);
180 $mockSignalSlotDispatcher = $this->getMock('TYPO3\\CMS\Extbase\\SignalSlot\\Dispatcher', array(), array(), '', FALSE);
181 $mockController->_set('signalSlotDispatcher', $mockSignalSlotDispatcher);
182 $this->enableDeprecatedPropertyMapperInController($mockController);
183 $mockController->expects($this->once())->method('fooAction')->with('Default value');
184 $mockController->_set('request', $mockRequest);
185 $mockController->_set('response', $mockResponse);
186 $mockController->_set('arguments', $arguments);
187 $mockController->_set('actionMethodName', 'fooAction');
188 $mockController->_set('argumentsMappingResults', $mockArgumentMappingResults);
189 $mockController->_call('callActionMethod');
190 }
191
192 /**
193 * @test
194 * @author Karsten Dambekalns <karsten@typo3.org>
195 */
196 public function resolveViewUsesFluidTemplateViewIfTemplateIsAvailable() {
197 $mockSession = $this->getMock('Tx_Extbase_Session_SessionInterface');
198 $mockControllerContext = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ControllerContext', array(), array(), '', FALSE);
199 $mockFluidTemplateView = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\View\\ViewInterface');
200 $mockFluidTemplateView->expects($this->once())->method('setControllerContext')->with($mockControllerContext);
201 $mockFluidTemplateView->expects($this->once())->method('canRender')->with($mockControllerContext)->will($this->returnValue(TRUE));
202 $mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface', array(), array(), '', FALSE);
203 $mockObjectManager->expects($this->at(0))->method('get')->with('TYPO3\\CMS\\Fluid\\View\\TemplateView')->will($this->returnValue($mockFluidTemplateView));
204 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('buildControllerContext', 'resolveViewObjectName', 'setViewConfiguration'), array(), '', FALSE);
205 $mockController->expects($this->once())->method('resolveViewObjectName')->will($this->returnValue(FALSE));
206 $mockController->_set('session', $mockSession);
207 $mockController->_set('objectManager', $mockObjectManager);
208 $mockController->_set('controllerContext', $mockControllerContext);
209 $this->assertSame($mockFluidTemplateView, $mockController->_call('resolveView'));
210 }
211
212 /**
213 * @test
214 * @author Bastian Waidelich <bastian@typo3.org>
215 */
216 public function resolveViewObjectNameUsesViewObjectNamePatternToResolveViewObjectName() {
217 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
218 $mockRequest->expects($this->once())->method('getControllerVendorName')->will($this->returnValue('MyVendor'));
219 $mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('MyPackage'));
220 $mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('MyController'));
221 $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('MyAction'));
222 $mockRequest->expects($this->atLeastOnce())->method('getFormat')->will($this->returnValue('MyFormat'));
223 $mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface', array(), array(), '', FALSE);
224 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('dummy'), array(), '', FALSE);
225 $mockController->_set('request', $mockRequest);
226 $mockController->_set('objectManager', $mockObjectManager);
227 $mockController->_set('namespacesViewObjectNamePattern', 'RandomViewObject@vendor\@extension\View\@controller\@action@format');
228 $mockController->_call('resolveViewObjectName');
229 }
230
231 /**
232 * @test
233 */
234 public function resolveViewObjectNameUsesDeprecatedViewObjectNamePatternForExtensionsWithoutVendor() {
235 eval('class Tx_MyPackage_View_MyController_MyActionMyFormat {}');
236
237 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
238 $mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('MyPackage'));
239 $mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('MyController'));
240 $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('MyAction'));
241 $mockRequest->expects($this->once())->method('getControllerVendorName')->will($this->returnValue(NULL));
242 $mockRequest->expects($this->atLeastOnce())->method('getFormat')->will($this->returnValue('MyFormat'));
243 $mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface', array(), array(), '', FALSE);
244 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('dummy'), array(), '', FALSE);
245 $mockController->_set('request', $mockRequest);
246 $mockController->_set('objectManager', $mockObjectManager);
247
248 $this->assertEquals(
249 'Tx_MyPackage_View_MyController_MyActionMyFormat',
250 $mockController->_call('resolveViewObjectName')
251 );
252 }
253
254 /**
255 * @test
256 */
257 public function resolveViewObjectNameUsesNamespacedViewObjectNamePatternForExtensionsWithVendor() {
258 eval('namespace MyVendor\MyPackage\View\MyController; class MyActionMyFormat {}');
259
260 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
261 $mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('MyPackage'));
262 $mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('MyController'));
263 $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('MyAction'));
264 $mockRequest->expects($this->once())->method('getControllerVendorName')->will($this->returnValue('MyVendor'));
265 $mockRequest->expects($this->atLeastOnce())->method('getFormat')->will($this->returnValue('MyFormat'));
266 $mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface', array(), array(), '', FALSE);
267 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('dummy'), array(), '', FALSE);
268 $mockController->_set('request', $mockRequest);
269 $mockController->_set('objectManager', $mockObjectManager);
270
271 $this->assertEquals(
272 'MyVendor\MyPackage\View\MyController\MyActionMyFormat',
273 $mockController->_call('resolveViewObjectName')
274 );
275 }
276
277 /**
278 * @test
279 * @author Robert Lemke <robert@typo3.org>
280 */
281 public function resolveActionMethodNameReturnsTheCurrentActionMethodNameFromTheRequest() {
282 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
283 $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('fooBar'));
284 /** @var \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
285 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooBarAction'), array(), '', FALSE);
286 $mockController->_set('request', $mockRequest);
287 $this->assertEquals('fooBarAction', $mockController->_call('resolveActionMethodName'));
288 }
289
290 /**
291 * @test
292 * @expectedException \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchActionException
293 * @author Robert Lemke <robert@typo3.org>
294 */
295 public function resolveActionMethodNameThrowsAnExceptionIfTheActionDefinedInTheRequestDoesNotExist() {
296 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
297 $mockRequest->expects($this->once())->method('getControllerActionName')->will($this->returnValue('fooBar'));
298 /** @var \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
299 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('otherBarAction'), array(), '', FALSE);
300 $mockController->_set('request', $mockRequest);
301 $mockController->_call('resolveActionMethodName');
302 }
303
304 /**
305 * @test
306 * @author Robert Lemke <robert@typo3.org>
307 */
308 public function initializeActionMethodArgumentsRegistersArgumentsFoundInTheSignatureOfTheCurrentActionMethod() {
309 $this->markTestSkipped('Triggers "UnexpectedValueException: Serialized string cannot be empty", with phpunit since PHP in 5.4.29 and 5.5.13, needs investigation, see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/178');
310 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
311 $mockArguments = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Arguments', array('addNewArgument', 'removeAll'), array(), '', FALSE);
312 $mockArguments->expects($this->at(0))->method('addNewArgument')->with('stringArgument', 'string', TRUE);
313 $mockArguments->expects($this->at(1))->method('addNewArgument')->with('integerArgument', 'integer', TRUE);
314 $mockArguments->expects($this->at(2))->method('addNewArgument')->with('objectArgument', 'F3_Foo_Bar', TRUE);
315 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooAction', 'evaluateDontValidateAnnotations'), array(), '', FALSE);
316 $methodParameters = array(
317 'stringArgument' => array(
318 'position' => 0,
319 'byReference' => FALSE,
320 'array' => FALSE,
321 'optional' => FALSE,
322 'allowsNull' => FALSE,
323 'type' => 'string'
324 ),
325 'integerArgument' => array(
326 'position' => 1,
327 'byReference' => FALSE,
328 'array' => FALSE,
329 'optional' => FALSE,
330 'allowsNull' => FALSE,
331 'type' => 'integer'
332 ),
333 'objectArgument' => array(
334 'position' => 2,
335 'byReference' => FALSE,
336 'array' => FALSE,
337 'optional' => FALSE,
338 'allowsNull' => FALSE,
339 'type' => 'F3_Foo_Bar'
340 )
341 );
342 $mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService', array(), array(), '', FALSE);
343 $mockReflectionService->expects($this->once())->method('getMethodParameters')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodParameters));
344 $mockController->_set('reflectionService', $mockReflectionService);
345 $mockController->_set('request', $mockRequest);
346 $mockController->_set('arguments', $mockArguments);
347 $mockController->_set('actionMethodName', 'fooAction');
348 $mockController->_call('initializeActionMethodArguments');
349 }
350
351 /**
352 * @test
353 * @author Robert Lemke <robert@typo3.org>
354 */
355 public function initializeActionMethodArgumentsRegistersOptionalArgumentsAsSuch() {
356 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
357 $mockArguments = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Arguments', array(), array(), '', FALSE);
358 $mockArguments->expects($this->at(0))->method('addNewArgument')->with('arg1', 'string', TRUE);
359 $mockArguments->expects($this->at(1))->method('addNewArgument')->with('arg2', 'array', FALSE, array(21));
360 $mockArguments->expects($this->at(2))->method('addNewArgument')->with('arg3', 'string', FALSE, 42);
361 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooAction', 'evaluateDontValidateAnnotations'), array(), '', FALSE);
362 $methodParameters = array(
363 'arg1' => array(
364 'position' => 0,
365 'byReference' => FALSE,
366 'array' => FALSE,
367 'optional' => FALSE,
368 'allowsNull' => FALSE,
369 'type' => 'string'
370 ),
371 'arg2' => array(
372 'position' => 1,
373 'byReference' => FALSE,
374 'array' => TRUE,
375 'optional' => TRUE,
376 'defaultValue' => array(21),
377 'allowsNull' => FALSE
378 ),
379 'arg3' => array(
380 'position' => 2,
381 'byReference' => FALSE,
382 'array' => FALSE,
383 'optional' => TRUE,
384 'defaultValue' => 42,
385 'allowsNull' => FALSE,
386 'type' => 'string'
387 )
388 );
389 $mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService', array(), array(), '', FALSE);
390 $mockReflectionService->expects($this->once())->method('getMethodParameters')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodParameters));
391 $mockController->_set('reflectionService', $mockReflectionService);
392 $mockController->_set('request', $mockRequest);
393 $mockController->_set('arguments', $mockArguments);
394 $mockController->_set('actionMethodName', 'fooAction');
395 $mockController->_call('initializeActionMethodArguments');
396 }
397
398 /**
399 * @test
400 * @author Sebastian Kurfürst <sbastian@typo3.org>
401 * @expectedException \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException
402 */
403 public function initializeActionMethodArgumentsThrowsExceptionIfDataTypeWasNotSpecified() {
404 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
405 $mockArguments = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Arguments', array(), array(), '', FALSE);
406 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooAction'), array(), '', FALSE);
407 $methodParameters = array(
408 'arg1' => array(
409 'position' => 0,
410 'byReference' => FALSE,
411 'array' => FALSE,
412 'optional' => FALSE,
413 'allowsNull' => FALSE
414 )
415 );
416 $mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService', array(), array(), '', FALSE);
417 $mockReflectionService->expects($this->once())->method('getMethodParameters')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodParameters));
418 $mockController->_set('reflectionService', $mockReflectionService);
419 $mockController->_set('request', $mockRequest);
420 $mockController->_set('arguments', $mockArguments);
421 $mockController->_set('actionMethodName', 'fooAction');
422 $mockController->_call('initializeActionMethodArguments');
423 }
424
425 /**
426 * @test
427 * @author Sebastian Kurfürst <sbastian@typo3.org>
428 */
429 public function initializeActionMethodValidatorsCorrectlyRegistersValidatorsBasedOnDataType() {
430 $this->markTestSkipped('Triggers "UnexpectedValueException: Serialized string cannot be empty", with phpunit since PHP in 5.4.29 and 5.5.13, needs investigation, see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/178');
431 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooAction'), array(), '', FALSE);
432 $this->enableDeprecatedPropertyMapperInController($mockController);
433 $argument = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument', array('getName'), array(), '', FALSE);
434 $argument->expects($this->any())->method('getName')->will($this->returnValue('arg1'));
435 $arguments = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Arguments', array('dummy'), array(), '', FALSE);
436 $arguments->addArgument($argument);
437 $methodTagsValues = array();
438 $methodArgumentsValidatorConjunctions = array();
439 $methodArgumentsValidatorConjunctions['arg1'] = $this->getMock('TYPO3\\CMS\\Extbase\\Validation\\Validator\\ConjunctionValidator', array(), array(), '', FALSE);
440 $mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService', array(), array(), '', FALSE);
441 $mockReflectionService->expects($this->once())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
442 $mockValidatorResolver = $this->getMock('TYPO3\\CMS\\Extbase\\Validation\\ValidatorResolver', array(), array(), '', FALSE);
443 $mockValidatorResolver->expects($this->once())->method('buildMethodArgumentsValidatorConjunctions')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodArgumentsValidatorConjunctions));
444 $mockController->_set('reflectionService', $mockReflectionService);
445 $mockController->_set('validatorResolver', $mockValidatorResolver);
446 $mockController->_set('arguments', $arguments);
447 $mockController->_set('actionMethodName', 'fooAction');
448 $mockController->_call('initializeActionMethodValidators');
449 $this->assertEquals($methodArgumentsValidatorConjunctions['arg1'], $arguments['arg1']->getValidator());
450 }
451
452 /**
453 * @test
454 * @author Sebastian Kurfürst <sbastian@typo3.org>
455 */
456 public function initializeActionMethodValidatorsRegistersModelBasedValidators() {
457 $this->markTestSkipped('Triggers "UnexpectedValueException: Serialized string cannot be empty", with phpunit since PHP in 5.4.29 and 5.5.13, needs investigation, see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/178');
458 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooAction'), array(), '', FALSE);
459 $this->enableDeprecatedPropertyMapperInController($mockController);
460 $argument = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument', array('getName', 'getDataType'), array(), '', FALSE);
461 $argument->expects($this->any())->method('getName')->will($this->returnValue('arg1'));
462 $argument->expects($this->any())->method('getDataType')->will($this->returnValue('F3_Foo_Quux'));
463 $arguments = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Arguments', array('dummy'), array(), '', FALSE);
464 $arguments->addArgument($argument);
465 $methodTagsValues = array();
466 $quuxBaseValidatorConjunction = $this->getMock('TYPO3\\CMS\\Extbase\\Validation\\Validator\\ConjunctionValidator', array(), array(), '', FALSE);
467 $methodArgumentsValidatorConjunctions = array();
468 $methodArgumentsValidatorConjunctions['arg1'] = $this->getMock('TYPO3\\CMS\\Extbase\\Validation\\Validator\\ConjunctionValidator', array(), array(), '', FALSE);
469 $methodArgumentsValidatorConjunctions['arg1']->expects($this->once())->method('addValidator')->with($quuxBaseValidatorConjunction);
470 $mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService', array(), array(), '', FALSE);
471 $mockReflectionService->expects($this->once())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
472 $mockValidatorResolver = $this->getMock('TYPO3\\CMS\\Extbase\\Validation\\ValidatorResolver', array(), array(), '', FALSE);
473 $mockValidatorResolver->expects($this->once())->method('buildMethodArgumentsValidatorConjunctions')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodArgumentsValidatorConjunctions));
474 $mockValidatorResolver->expects($this->once())->method('getBaseValidatorConjunction')->with('F3_Foo_Quux')->will($this->returnValue($quuxBaseValidatorConjunction));
475 $mockController->_set('reflectionService', $mockReflectionService);
476 $mockController->_set('validatorResolver', $mockValidatorResolver);
477 $mockController->_set('arguments', $arguments);
478 $mockController->_set('actionMethodName', 'fooAction');
479 $mockController->_call('initializeActionMethodValidators');
480 $this->assertEquals($methodArgumentsValidatorConjunctions['arg1'], $arguments['arg1']->getValidator());
481 }
482
483 /**
484 * @test
485 * @author Sebastian Kurfürst <sbastian@typo3.org>
486 */
487 public function initializeActionMethodValidatorsDoesNotRegisterModelBasedValidatorsIfDontValidateAnnotationIsSet() {
488 $this->markTestSkipped('Triggers "UnexpectedValueException: Serialized string cannot be empty", with phpunit since PHP in 5.4.29 and 5.5.13, needs investigation, see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/178');
489 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('fooAction'), array(), '', FALSE);
490 $this->enableDeprecatedPropertyMapperInController($mockController);
491 $argument = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument', array('getName', 'getDataType'), array(), '', FALSE);
492 $argument->expects($this->any())->method('getName')->will($this->returnValue('arg1'));
493 $argument->expects($this->any())->method('getDataType')->will($this->returnValue('F3_Foo_Quux'));
494 $arguments = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Arguments', array('dummy'), array(), '', FALSE);
495 $arguments->addArgument($argument);
496 $methodTagsValues = array(
497 'dontvalidate' => array(
498 '$arg1'
499 )
500 );
501 $methodArgumentsValidatorConjunctions = array();
502 $methodArgumentsValidatorConjunctions['arg1'] = $this->getMock('TYPO3\\CMS\\Extbase\\Validation\\Validator\\ConjunctionValidator', array(), array(), '', FALSE);
503 $mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService', array(), array(), '', FALSE);
504 $mockReflectionService->expects($this->once())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
505 $mockValidatorResolver = $this->getMock('TYPO3\\CMS\\Extbase\\Validation\\ValidatorResolver', array(), array(), '', FALSE);
506 $mockValidatorResolver->expects($this->once())->method('buildMethodArgumentsValidatorConjunctions')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodArgumentsValidatorConjunctions));
507 $mockValidatorResolver->expects($this->any())->method('getBaseValidatorConjunction')->will($this->throwException(new \Exception('This should not be called because the dontvalidate annotation is set.')));
508 $mockController->_set('reflectionService', $mockReflectionService);
509 $mockController->_set('validatorResolver', $mockValidatorResolver);
510 $mockController->_set('arguments', $arguments);
511 $mockController->_set('actionMethodName', 'fooAction');
512 $mockController->_call('initializeActionMethodValidators');
513 $this->assertEquals($methodArgumentsValidatorConjunctions['arg1'], $arguments['arg1']->getValidator());
514 }
515
516 /**
517 * @test
518 * @author Christopher Hlubek <hlubek@networkteam.com>
519 */
520 public function defaultErrorActionSetsArgumentMappingResultsErrorsInRequest() {
521 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request', array(), array(), '', FALSE);
522 $mockError = $this->getMock('TYPO3\\CMS\\Extbase\\Error\\Error', array('getMessage'), array(), '', FALSE);
523 $mockArgumentsMappingResults = $this->getMock('TYPO3\\CMS\\Extbase\\Property\\MappingResults', array('getErrors', 'getWarnings'), array(), '', FALSE);
524 $mockArgumentsMappingResults->expects($this->atLeastOnce())->method('getErrors')->will($this->returnValue(array($mockError)));
525 $mockArgumentsMappingResults->expects($this->any())->method('getWarnings')->will($this->returnValue(array()));
526 /** @var $mockController \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
527 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('clearCacheOnError'), array(), '', FALSE);
528 $controllerContext = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ControllerContext', array('getFlashMessageQueue'));
529 $controllerContext->expects($this->any())->method('getFlashMessageQueue')->will($this->returnValue(new \TYPO3\CMS\Core\Messaging\FlashMessageQueue('foo')));
530 $this->enableDeprecatedPropertyMapperInController($mockController);
531 $mockController->_set('controllerContext', $controllerContext);
532 $mockController->_set('request', $mockRequest);
533 $mockController->_set('argumentsMappingResults', $mockArgumentsMappingResults);
534 $mockRequest->expects($this->once())->method('setErrors')->with(array($mockError));
535 $mockController->_call('errorAction');
536 }
537
538 /**
539 * Data Provider for checkRequestHashDoesNotThrowExceptionInNormalOperations
540 *
541 * @return array
542 */
543 public function checkRequestHashInNormalOperation() {
544 return array(
545 // HMAC is verified
546 array(TRUE),
547 // HMAC not verified, but objects are directly fetched from persistence layer
548 array(FALSE, FALSE, \TYPO3\CMS\Extbase\Mvc\Controller\Argument::ORIGIN_PERSISTENCE, \TYPO3\CMS\Extbase\Mvc\Controller\Argument::ORIGIN_PERSISTENCE),
549 // HMAC not verified, objects new and modified, but dontverifyrequesthash-annotation set
550 array(FALSE, TRUE, \TYPO3\CMS\Extbase\Mvc\Controller\Argument::ORIGIN_PERSISTENCE, \TYPO3\CMS\Extbase\Mvc\Controller\Argument::ORIGIN_PERSISTENCE_AND_MODIFIED, array('dontverifyrequesthash' => ''))
551 );
552 }
553
554 /**
555 * @test
556 * @author Sebastian Kurfürst <sebastian@typo3.org>
557 * @dataProvider checkRequestHashInNormalOperation
558 * @param boolean $hmacVerified
559 * @param boolean $reflectionServiceNeedsInitialization
560 * @param integer $argument1Origin
561 * @param integer $argument2Origin
562 * @param array $methodTagsValues
563 */
564 public function checkRequestHashDoesNotThrowExceptionInNormalOperations($hmacVerified, $reflectionServiceNeedsInitialization = FALSE, $argument1Origin = 3, $argument2Origin = 3, array $methodTagsValues = array()) {
565 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Request', array('isHmacVerified'), array(), '', FALSE);
566 $mockRequest->expects($this->once())->method('isHmacVerified')->will($this->returnValue($hmacVerified));
567 $argument1 = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument', array('getOrigin'), array(), '', FALSE);
568 $argument1->expects($this->any())->method('getOrigin')->will($this->returnValue($argument1Origin));
569 $argument2 = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument', array('getOrigin'), array(), '', FALSE);
570 $argument2->expects($this->any())->method('getOrigin')->will($this->returnValue($argument2Origin));
571 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('dummy'), array(), '', FALSE);
572 $this->enableDeprecatedPropertyMapperInController($mockController);
573 $mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService', array('getMethodTagsValues'), array(), '', FALSE);
574 if ($reflectionServiceNeedsInitialization) {
575 // Somehow this is needed, else I get "Mocked method does not exist."
576 $mockReflectionService->expects($this->any())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
577 }
578 $mockController->_set('arguments', array($argument1, $argument2));
579 $mockController->_set('request', $mockRequest);
580 $mockController->_set('actionMethodName', 'fooAction');
581 $mockController->_set('reflectionService', $mockReflectionService);
582 $mockController->_call('checkRequestHash');
583 }
584
585 /**
586 * @test
587 * @expectedException \TYPO3\CMS\Extbase\Mvc\Exception\InvalidOrNoRequestHashException
588 * @author Sebastian Kurfürst <sebastian@typo3.org>
589 */
590 public function checkRequestHashThrowsExceptionIfNeeded() {
591 $hmacVerified = FALSE;
592 $argument1Origin = \TYPO3\CMS\Extbase\Mvc\Controller\Argument::ORIGIN_PERSISTENCE_AND_MODIFIED;
593 $argument2Origin = \TYPO3\CMS\Extbase\Mvc\Controller\Argument::ORIGIN_PERSISTENCE;
594 $methodTagsValues = array();
595 $mockRequest = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Request', array('isHmacVerified'), array(), '', FALSE);
596 $mockRequest->expects($this->once())->method('isHmacVerified')->will($this->returnValue($hmacVerified));
597 $argument1 = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument', array('getOrigin'), array(), '', FALSE);
598 $argument1->expects($this->any())->method('getOrigin')->will($this->returnValue($argument1Origin));
599 $argument2 = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument', array('getOrigin'), array(), '', FALSE);
600 $argument2->expects($this->any())->method('getOrigin')->will($this->returnValue($argument2Origin));
601 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('dummy'), array(), '', FALSE);
602 $this->enableDeprecatedPropertyMapperInController($mockController);
603 $mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService', array('getMethodTagsValues'), array(), '', FALSE);
604 $mockReflectionService->expects($this->any())->method('getMethodTagsValues')->with(get_class($mockController), 'fooAction')->will($this->returnValue($methodTagsValues));
605 $mockController->_set('arguments', array($argument1, $argument2));
606 $mockController->_set('request', $mockRequest);
607 $mockController->_set('actionMethodName', 'fooAction');
608 $mockController->_set('reflectionService', $mockReflectionService);
609 $mockController->_call('checkRequestHash');
610 }
611
612 /**
613 * Helper which enables the deprecated property mapper in the ActionController class.
614 *
615 * @param \TYPO3\CMS\Extbase\Mvc\Controller\ActionController $actionController
616 */
617 protected function enableDeprecatedPropertyMapperInController(\TYPO3\CMS\Extbase\Mvc\Controller\ActionController $actionController) {
618 $mockConfigurationManager = $this->getMock('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
619 $mockConfigurationManager->expects($this->any())->method('isFeatureEnabled')->with('rewrittenPropertyMapper')->will($this->returnValue(FALSE));
620 $actionController->injectConfigurationManager($mockConfigurationManager);
621 }
622
623 /**
624 * @test
625 * @dataProvider templateRootPathDataProvider
626 * @param array $configuration
627 * @param array $expected
628 */
629 public function setViewConfigurationResolvesTemplateRootPathsForTemplateRootPath($configuration, $expected) {
630 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('dummy'), array(), '', FALSE);
631 $mockConfigurationManager = $this->getMock('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
632 $mockConfigurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($configuration));
633 $mockController->injectConfigurationManager($mockConfigurationManager);
634 $mockController->_set('request', $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request'), array('getControllerExtensionKey'));
635 $view = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\View\\ViewInterface', array('setControllerContext', 'assign', 'assignMultiple', 'canRender', 'render', 'initializeView', 'setTemplateRootPaths'));
636 $view->expects($this->once())->method('setTemplateRootPaths')->with($expected);
637 $mockController->_call('setViewConfiguration', $view);
638 }
639
640 /**
641 * @return array
642 */
643 public function templateRootPathDataProvider() {
644 return array(
645 'old behaviour only' => array(
646 array(
647 'view' => array(
648 'templateRootPath' => 'some path'
649 )
650 ),
651 array('some path')
652 ),
653 'new behaviour only with text keys' => array(
654 array(
655 'view' => array(
656 'templateRootPaths' => array(
657 'default' => 'some path',
658 'extended' => 'some other path'
659 )
660 )
661 ),
662 array(
663 'extended' => 'some other path',
664 'default' => 'some path'
665 )
666 ),
667 'new behaviour only with numerical keys' => array(
668 array(
669 'view' => array(
670 'templateRootPaths' => array(
671 '10' => 'some path',
672 '20' => 'some other path',
673 '15' => 'intermediate specific path'
674 )
675 )
676 ),
677 array(
678 '20' => 'some other path',
679 '15' => 'intermediate specific path',
680 '10' => 'some path'
681 )
682 ),
683 'new behaviour only with mixed keys' => array(
684 array(
685 'view' => array(
686 'templateRootPaths' => array(
687 '10' => 'some path',
688 'very_specific' => 'some other path',
689 '15' => 'intermediate specific path'
690 )
691 )
692 ),
693 array(
694 '15' => 'intermediate specific path',
695 'very_specific' => 'some other path',
696 '10' => 'some path'
697 )
698 ),
699 'old and new behaviour mixed with text keys' => array(
700 array(
701 'view' => array(
702 'templateRootPaths' => array(
703 'default' => 'some path',
704 'specific' => 'intermediate specific path',
705 'very_specific' => 'some other path'
706 ),
707 'templateRootPath' => 'old path'
708 )
709 ),
710 array(
711 'very_specific' => 'some other path',
712 'specific' => 'intermediate specific path',
713 'default' => 'some path',
714 '0' => 'old path'
715 )
716 ),
717 'old and new behaviour mixed with numerical keys' => array(
718 array(
719 'view' => array(
720 'templateRootPaths' => array(
721 '10' => 'some path',
722 '20' => 'intermediate specific path',
723 '30' => 'some other path'
724 ),
725 'templateRootPath' => 'old path'
726 )
727 ),
728 array(
729 '30' => 'some other path',
730 '20' => 'intermediate specific path',
731 '10' => 'some path',
732 '31' => 'old path'
733 )
734 ),
735 'old and new behaviour mixed with mixed keys' => array(
736 array(
737 'view' => array(
738 'templateRootPaths' => array(
739 '10' => 'some path',
740 'very_specific' => 'some other path',
741 '15' => 'intermediate specific path'
742 ),
743 'templateRootPath' => 'old path'
744 )
745 ),
746 array(
747 '15' => 'intermediate specific path',
748 'very_specific' => 'some other path',
749 '10' => 'some path',
750 '16' => 'old path'
751 )
752 )
753 );
754 }
755
756 /**
757 * @test
758 * @dataProvider layoutRootPathDataProvider
759 *
760 * @param array $configuration
761 * @param array $expected
762 */
763 public function setViewConfigurationResolvesLayoutRootPathsForLayoutRootPath($configuration, $expected) {
764 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('dummy'), array(), '', FALSE);
765 $mockConfigurationManager = $this->getMock('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
766 $mockConfigurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($configuration));
767 $mockController->injectConfigurationManager($mockConfigurationManager);
768 $mockController->_set('request', $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request'), array('getControllerExtensionKey'));
769 $view = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\View\\ViewInterface', array('setControllerContext', 'assign', 'assignMultiple', 'canRender', 'render', 'initializeView', 'setlayoutRootPaths'));
770 $view->expects($this->once())->method('setlayoutRootPaths')->with($expected);
771 $mockController->_call('setViewConfiguration', $view);
772 }
773
774 /**
775 * @return array
776 */
777 public function layoutRootPathDataProvider() {
778 return array(
779 'old behaviour only' => array(
780 array(
781 'view' => array(
782 'layoutRootPath' => 'some path'
783 )
784 ),
785 array('some path')
786 ),
787 'new behaviour only with text keys' => array(
788 array(
789 'view' => array(
790 'layoutRootPaths' => array(
791 'default' => 'some path',
792 'extended' => 'some other path'
793 )
794 )
795 ),
796 array(
797 'extended' => 'some other path',
798 'default' => 'some path'
799 )
800 ),
801 'new behaviour only with numerical keys' => array(
802 array(
803 'view' => array(
804 'layoutRootPaths' => array(
805 '10' => 'some path',
806 '20' => 'some other path',
807 '15' => 'intermediate specific path'
808 )
809 )
810 ),
811 array(
812 '20' => 'some other path',
813 '15' => 'intermediate specific path',
814 '10' => 'some path'
815 )
816 ),
817 'new behaviour only with mixed keys' => array(
818 array(
819 'view' => array(
820 'layoutRootPaths' => array(
821 '10' => 'some path',
822 'very_specific' => 'some other path',
823 '15' => 'intermediate specific path'
824 )
825 )
826 ),
827 array(
828 '15' => 'intermediate specific path',
829 'very_specific' => 'some other path',
830 '10' => 'some path'
831 )
832 ),
833 'old and new behaviour mixed with text keys' => array(
834 array(
835 'view' => array(
836 'layoutRootPaths' => array(
837 'default' => 'some path',
838 'specific' => 'intermediate specific path',
839 'very_specific' => 'some other path'
840 ),
841 'layoutRootPath' => 'old path'
842 )
843 ),
844 array(
845 'very_specific' => 'some other path',
846 'specific' => 'intermediate specific path',
847 'default' => 'some path',
848 '0' => 'old path'
849 )
850 ),
851 'old and new behaviour mixed with numerical keys' => array(
852 array(
853 'view' => array(
854 'layoutRootPaths' => array(
855 '10' => 'some path',
856 '20' => 'intermediate specific path',
857 '30' => 'some other path'
858 ),
859 'layoutRootPath' => 'old path'
860 )
861 ),
862 array(
863 '30' => 'some other path',
864 '20' => 'intermediate specific path',
865 '10' => 'some path',
866 '31' => 'old path'
867 )
868 ),
869 'old and new behaviour mixed with mixed keys' => array(
870 array(
871 'view' => array(
872 'layoutRootPaths' => array(
873 '10' => 'some path',
874 'very_specific' => 'some other path',
875 '15' => 'intermediate specific path'
876 ),
877 'layoutRootPath' => 'old path'
878 )
879 ),
880 array(
881 '15' => 'intermediate specific path',
882 'very_specific' => 'some other path',
883 '10' => 'some path',
884 '16' => 'old path'
885 )
886 )
887 );
888 }
889
890 /**
891 * @test
892 * @dataProvider partialRootPathDataProvider
893 *
894 * @param array $configuration
895 * @param array $expected
896 */
897 public function setViewConfigurationResolvesPartialRootPathsForPartialRootPath($configuration, $expected) {
898 $mockController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ActionController', array('dummy'), array(), '', FALSE);
899 $mockConfigurationManager = $this->getMock('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
900 $mockConfigurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($configuration));
901 $mockController->injectConfigurationManager($mockConfigurationManager);
902 $mockController->_set('request', $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\Request'), array('getControllerExtensionKey'));
903 $view = $this->getMock('TYPO3\\CMS\\Extbase\\Mvc\\View\\ViewInterface', array('setControllerContext', 'assign', 'assignMultiple', 'canRender', 'render', 'initializeView', 'setpartialRootPaths'));
904 $view->expects($this->once())->method('setpartialRootPaths')->with($expected);
905 $mockController->_call('setViewConfiguration', $view);
906 }
907
908 /**
909 * @return array
910 */
911 public function partialRootPathDataProvider() {
912 return array(
913 'old behaviour only' => array(
914 array(
915 'view' => array(
916 'partialRootPath' => 'some path'
917 )
918 ),
919 array('some path')
920 ),
921 'new behaviour only with text keys' => array(
922 array(
923 'view' => array(
924 'partialRootPaths' => array(
925 'default' => 'some path',
926 'extended' => 'some other path'
927 )
928 )
929 ),
930 array(
931 'extended' => 'some other path',
932 'default' => 'some path'
933 )
934 ),
935 'new behaviour only with numerical keys' => array(
936 array(
937 'view' => array(
938 'partialRootPaths' => array(
939 '10' => 'some path',
940 '20' => 'some other path',
941 '15' => 'intermediate specific path'
942 )
943 )
944 ),
945 array(
946 '20' => 'some other path',
947 '15' => 'intermediate specific path',
948 '10' => 'some path'
949 )
950 ),
951 'new behaviour only with mixed keys' => array(
952 array(
953 'view' => array(
954 'partialRootPaths' => array(
955 '10' => 'some path',
956 'very_specific' => 'some other path',
957 '15' => 'intermediate specific path'
958 )
959 )
960 ),
961 array(
962 '15' => 'intermediate specific path',
963 'very_specific' => 'some other path',
964 '10' => 'some path'
965 )
966 ),
967 'old and new behaviour mixed with text keys' => array(
968 array(
969 'view' => array(
970 'partialRootPath' => 'old path',
971 'partialRootPaths' => array(
972 'default' => 'some path',
973 'specific' => 'intermediate specific path',
974 'very_specific' => 'some other path'
975 )
976 )
977 ),
978 array(
979 'very_specific' => 'some other path',
980 'specific' => 'intermediate specific path',
981 'default' => 'some path',
982 '0' => 'old path'
983 )
984 ),
985 'old and new behaviour mixed with numerical keys' => array(
986 array(
987 'view' => array(
988 'partialRootPaths' => array(
989 '10' => 'some path',
990 '20' => 'intermediate specific path',
991 '30' => 'some other path'
992 ),
993 'partialRootPath' => 'old path'
994 )
995 ),
996 array(
997 '30' => 'some other path',
998 '20' => 'intermediate specific path',
999 '10' => 'some path',
1000 '31' => 'old path'
1001 )
1002 ),
1003 'old and new behaviour mixed with mixed keys' => array(
1004 array(
1005 'view' => array(
1006 'partialRootPaths' => array(
1007 '10' => 'some path',
1008 'very_specific' => 'some other path',
1009 '15' => 'intermediate specific path'
1010 ),
1011 'partialRootPath' => 'old path'
1012 )
1013 ),
1014 array(
1015 '15' => 'intermediate specific path',
1016 'very_specific' => 'some other path',
1017 '10' => 'some path',
1018 '16' => 'old path'
1019 )
1020 )
1021 );
1022 }
1023 }