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