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