[+FEATURE] Extbase (MVC): Automatic target page determination
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Utility / Extension_testcase.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Oliver Hader <oliver@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 require_once (t3lib_extMgm::extPath('extbase') . 'Tests/Fixtures/Dispatcher.php');
26
27 /**
28 * Testcase for class Tx_Extbase_Utility_Extension
29 *
30 * @package Extbase
31 * @subpackage extbase
32 */
33 class Tx_Extbase_Utility_Extension_testcase extends tx_phpunit_testcase {
34
35 /**
36 * Contains backup of $TYPO3_CONF_VARS
37 * @var array
38 */
39 protected $typo3ConfVars = array();
40
41 /**
42 * @var t3lib_DB
43 */
44 protected $typo3DbBackup;
45
46 /**
47 * @var t3lib_fe contains a backup of the current $GLOBALS['TSFE']
48 */
49 protected $tsfeBackup;
50
51 public function setUp() {
52 global $TYPO3_CONF_VARS;
53 $this->typo3ConfVars = $TYPO3_CONF_VARS;
54 $this->typo3DbBackup = $GLOBALS['TYPO3_DB'];
55 $GLOBALS['TYPO3_DB'] = $this->getMock('t3lib_DB', array('fullQuoteStr', 'exec_SELECTgetRows'));
56 $this->tsfeBackup = $GLOBALS['TSFE'];
57 if (!isset($GLOBALS['TSFE']->tmpl)) {
58 $GLOBALS['TSFE']->tmpl = new stdClass();
59 }
60 if (!isset($GLOBALS['TSFE']->tmpl->setup)) {
61 $GLOBALS['TSFE']->tmpl->setup = array();
62 }
63 $GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.'] = array(
64 '9' => 'CASE',
65 '9.' => array(
66 'key.' => array(
67 'field' => 'layout'),
68 0 => '< plugin.tt_news'
69 ),
70 'extensionname_someplugin' => 'USER',
71 'extensionname_someplugin.' => array(
72 'userFunc' => 'tx_extbase_dispatcher->dispatch',
73 'pluginName' => 'SomePlugin',
74 'extensionName' => 'ExtensionName',
75 'controller' => 'ControllerName',
76 'action' => 'index',
77 'switchableControllerActions.' => array(
78 'ControllerName.' => array(
79 'actions' => 'index,otherAction',
80 ),
81 ),
82 ),
83 'someotherextensionname_secondplugin' => 'USER',
84 'someotherextensionname_secondplugin.' => array(
85 'userFunc' => 'tx_extbase_dispatcher->dispatch',
86 'pluginName' => 'SecondPlugin',
87 'extensionName' => 'SomeOtherExtensionName',
88 'controller' => 'ControllerName',
89 'action' => 'index',
90 'switchableControllerActions.' => array(
91 'ControllerName.' => array(
92 'actions' => 'index,otherAction',
93 ),
94 'SecondControllerName.' => array(
95 'actions' => 'someAction,someOtherAction',
96 'nonCacheableActions' => 'someOtherAction',
97 ),
98 ),
99 ),
100 'extensionname_thirdplugin' => 'USER',
101 'extensionname_thirdplugin.' => array(
102 'userFunc' => 'tx_extbase_dispatcher->dispatch',
103 'pluginName' => 'ThirdPlugin',
104 'extensionName' => 'ExtensionName',
105 'controller' => 'ControllerName',
106 'action' => 'index',
107 'switchableControllerActions.' => array(
108 'ControllerName.' => array(
109 'actions' => 'otherAction,thirdAction',
110 ),
111 ),
112 ),
113 );
114 }
115
116 public function tearDown() {
117 global $TYPO3_CONF_VARS;
118 $TYPO3_CONF_VARS = $this->typo3ConfVars;
119 $GLOBALS['TSFE'] = $this->tsfeBackup;
120 }
121
122 /**
123 * @test
124 * @see Tx_Extbase_Utility_Extension::registerPlugin
125 */
126 public function configurePluginWorksForMinimalisticSetup() {
127 global $TYPO3_CONF_VARS;
128 $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
129 Tx_Extbase_Utility_Extension::configurePlugin(
130 'MyExtension',
131 'Pi1',
132 array('Blog' => 'index')
133 );
134 $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
135
136 $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
137 $this->assertContains('
138 pluginName = Pi1
139 extensionName = MyExtension', $staticTypoScript);
140
141 $this->assertNotContains('USER_INT', $staticTypoScript);
142 }
143
144
145 /**
146 * @test
147 * @see Tx_Extbase_Utility_Extension::registerPlugin
148 */
149 public function configurePluginCreatesCorrectDefaultTypoScriptSetup() {
150 global $TYPO3_CONF_VARS;
151 $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
152 Tx_Extbase_Utility_Extension::configurePlugin(
153 'MyExtension',
154 'Pi1',
155 array('Blog' => 'index')
156 );
157 $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
158 $defaultTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup'];
159 $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
160 $this->assertContains('
161 plugin.tx_myextension {
162 settings {
163 }
164 persistence {
165 storagePid =
166 classes {
167 }
168 }
169 view {
170 templateRootPath =
171 layoutRootPath =
172 partialRootPath =
173 # the defaultPid can be an integer but defaults to the string "auto" which means that the target pid is determined automatically
174 defaultPid = auto
175 }
176 }', $defaultTypoScript);
177 }
178
179 /**
180 * @test
181 * @see Tx_Extbase_Utility_Extension::registerPlugin
182 */
183 public function configurePluginWorksForASingleControllerAction() {
184 global $TYPO3_CONF_VARS;
185 $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
186 Tx_Extbase_Utility_Extension::configurePlugin(
187 'MyExtension',
188 'Pi1',
189 array(
190 'FirstController' => 'index'
191 )
192 );
193 $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
194
195 $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
196 $this->assertContains('
197 pluginName = Pi1
198 extensionName = MyExtension', $staticTypoScript);
199 $this->assertContains('
200 controller = FirstController
201 action = index', $staticTypoScript);
202 $this->assertNotContains('USER_INT', $staticTypoScript);
203 }
204
205 /**
206 * @test
207 * @see Tx_Extbase_Utility_Extension::registerPlugin
208 */
209 public function configurePluginWithEmptyPluginNameResultsInAnError() {
210 $this->setExpectedException('InvalidArgumentException');
211 Tx_Extbase_Utility_Extension::configurePlugin(
212 'MyExtension',
213 '',
214 array(
215 'FirstController' => 'index'
216 )
217 );
218 }
219
220 /**
221 * @test
222 * @see Tx_Extbase_Utility_Extension::registerPlugin
223 */
224 public function configurePluginWithEmptyExtensionNameResultsInAnError() {
225 $this->setExpectedException('InvalidArgumentException');
226 Tx_Extbase_Utility_Extension::configurePlugin(
227 '',
228 'Pi1',
229 array(
230 'FirstController' => 'index'
231 )
232 );
233 }
234
235 /**
236 * @test
237 * @see Tx_Extbase_Utility_Extension::registerPlugin
238 */
239 public function configurePluginRespectsDefaultActionAsANonCacheableAction() {
240 global $TYPO3_CONF_VARS;
241 $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
242 Tx_Extbase_Utility_Extension::configurePlugin(
243 'MyExtension',
244 'Pi1',
245 array(
246 'FirstController' => 'index,show,new,create,delete,edit,update'
247 ),
248 array(
249 'FirstController' => 'index,show'
250 )
251 );
252 $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
253 $this->assertContains('
254 tt_content.list.20.myextension_pi1 = USER
255 tt_content.list.20.myextension_pi1 {', $staticTypoScript);
256 $this->assertContains('FirstController.nonCacheableActions = index,show
257 ', $staticTypoScript);
258 }
259
260 /**
261 * @test
262 * @see Tx_Extbase_Utility_Extension::registerPlugin
263 */
264 public function configurePluginRespectsNonDefaultActionAsANonCacheableAction() {
265 global $TYPO3_CONF_VARS;
266 $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
267 Tx_Extbase_Utility_Extension::configurePlugin(
268 'MyExtension',
269 'Pi1',
270 array(
271 'FirstController' => 'index,show,new,create,delete,edit,update'
272 ),
273 array(
274 'FirstController' => 'show,new'
275 )
276 );
277 $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
278
279 $this->assertContains('
280 tt_content.list.20.myextension_pi1 = USER
281 tt_content.list.20.myextension_pi1 {', $staticTypoScript);
282 $this->assertContains('FirstController.nonCacheableActions = show,new
283 ', $staticTypoScript);
284 }
285
286 /**
287 * @test
288 * @see Tx_Extbase_Utility_Extension::registerPlugin
289 */
290 public function configurePluginWorksForMultipleControllerActionsWithCacheableActionAsDefault() {
291 global $TYPO3_CONF_VARS;
292 $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
293 Tx_Extbase_Utility_Extension::configurePlugin(
294 'MyExtension',
295 'Pi1',
296 array(
297 'FirstController' => 'index,show,new,create,delete,edit,update',
298 'SecondController' => 'index,show,delete',
299 'ThirdController' => 'create'
300 ),
301 array(
302 'FirstController' => 'new,create,edit,update',
303 'SecondController' => 'delete',
304 'ThirdController' => 'create'
305 )
306 );
307 $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
308
309 $this->assertContains('
310 tt_content.list.20.myextension_pi1 = USER
311 tt_content.list.20.myextension_pi1 {', $staticTypoScript);
312
313 $this->assertContains('FirstController.nonCacheableActions = new,create,edit,update
314 ', $staticTypoScript);
315
316 $this->assertContains('SecondController.nonCacheableActions = delete
317 ', $staticTypoScript);
318
319 $this->assertContains('ThirdController.nonCacheableActions = create
320 ', $staticTypoScript);
321 }
322
323
324 /**
325 * @test
326 * @see Tx_Extbase_Utility_Extension::registerPlugin
327 */
328 public function configurePluginWorksForMultipleControllerActionsWithNonCacheableActionAsDefault() {
329 global $TYPO3_CONF_VARS;
330 $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
331 Tx_Extbase_Utility_Extension::configurePlugin(
332 'MyExtension',
333 'Pi1',
334 array(
335 'FirstController' => 'index,show,new,create,delete,edit,update',
336 'SecondController' => 'index,show,delete',
337 'ThirdController' => 'create'
338 ),
339 array(
340 'FirstController' => 'index,new,create,edit,update',
341 'SecondController' => 'delete',
342 'ThirdController' => 'create'
343 )
344 );
345 $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
346
347 $this->assertContains('
348 tt_content.list.20.myextension_pi1 = USER
349 tt_content.list.20.myextension_pi1 {', $staticTypoScript);
350
351 $this->assertContains('FirstController.nonCacheableActions = index,new,create,edit,update
352 ', $staticTypoScript);
353
354 $this->assertContains('SecondController.nonCacheableActions = delete
355 ', $staticTypoScript);
356
357 $this->assertContains('ThirdController.nonCacheableActions = create
358 ', $staticTypoScript);
359 }
360
361 /**
362 * DataProvider for getPluginNamespaceByPluginSignatureTests()
363 *
364 * @return array
365 */
366 public function getPluginNamespaceByPluginSignatureDataProvider() {
367 return array(
368 array('someextension_someplugin', 'tx_someextension_someplugin'),
369 array('nonexistingextension_someplugin', 'tx_nonexistingextension_someplugin'),
370 array('InvalidPluginNamespace', 'tx_InvalidPluginNamespace'),
371 );
372 }
373
374 /**
375 * @test
376 * @dataProvider getPluginNamespaceByPluginSignatureDataProvider
377 */
378 public function getPluginNamespaceByPluginSignatureTests($pluginSignature, $expectedResult) {
379 $dispatcher = new Tx_Extbase_Tests_Fixtures_Dispatcher();
380 $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_AbstractConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'loadTypoScriptSetup'));
381 $dispatcher->setConfigurationManager($mockConfigurationManager);
382 $actualResult = Tx_Extbase_Utility_Extension::getPluginNamespaceByPluginSignature($pluginSignature);
383 $this->assertEquals($expectedResult, $actualResult, 'Failing for $pluginSignature: "' . $pluginSignature . '"');
384 }
385
386 /**
387 * @test
388 */
389 public function pluginNamespaceCanBeOverridden() {
390 $dispatcher = new Tx_Extbase_Tests_Fixtures_Dispatcher();
391 $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_AbstractConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'loadTypoScriptSetup', 'getFrameworkConfiguration'));
392 $mockConfigurationManager->expects($this->once())->method('getFrameworkConfiguration')->will($this->returnValue(array('view' => array('pluginNamespace' => 'overridden_plugin_namespace'))));
393 $dispatcher->setConfigurationManager($mockConfigurationManager);
394 $expectedResult = 'overridden_plugin_namespace';
395 $actualResult = Tx_Extbase_Utility_Extension::getPluginNamespaceByPluginSignature('somePluginSignature');
396 $this->assertEquals($expectedResult, $actualResult);
397 }
398
399 /**
400 * DataProvider for getPluginNameByActionTests()
401 *
402 * @return array
403 */
404 public function getPluginNameByActionDataProvider() {
405 return array(
406 array('ExtensionName', 'ControllerName', 'someNonExistingAction', NULL),
407 array('ExtensionName', 'ControllerName', 'index', 'SomePlugin'),
408 array('ExtensionName', 'ControllerName', 'thirdAction', 'ThirdPlugin'),
409 array('eXtEnSiOnNaMe', 'cOnTrOlLeRnAmE', 'thirdAction', 'ThirdPlugin'),
410 array('eXtEnSiOnNaMe', 'cOnTrOlLeRnAmE', 'ThIrDaCtIoN', NULL),
411 array('SomeOtherExtensionName', 'ControllerName', 'otherAction', 'SecondPlugin'),
412 );
413 }
414
415 /**
416 * @test
417 * @dataProvider getPluginNameByActionDataProvider
418 */
419 public function getPluginNameByActionTests($extensionName, $controllerName, $actionName, $expectedResult) {
420 $actualResult = Tx_Extbase_Utility_Extension::getPluginNameByAction($extensionName, $controllerName, $actionName);
421 $this->assertEquals($expectedResult, $actualResult, 'Failing for $extensionName: "' . $extensionName . '", $controllerName: "' . $controllerName . '", $actionName: "' . $actionName . '" - ');
422 }
423
424 /**
425 * @test
426 * @expectedException Tx_Extbase_Exception
427 */
428 public function getPluginNameByActionThrowsExceptionIfMoreThanOnePluginMatches() {
429 Tx_Extbase_Utility_Extension::getPluginNameByAction('ExtensionName', 'ControllerName', 'otherAction');
430 }
431
432 /**
433 * @test
434 */
435 public function getTargetPidByPluginSignatureReturnsNullIfConfigurationManagerIsNotInitialized() {
436 $this->assertNull(Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('plugin_signature'));
437 }
438
439 /**
440 * @test
441 */
442 public function getTargetPidByPluginSignatureReturnsNullIfDefaultPidIsNotConfigured() {
443 $dispatcher = new Tx_Extbase_Tests_Fixtures_Dispatcher();
444 $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_AbstractConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'loadTypoScriptSetup', 'getFrameworkConfiguration'));
445 $mockConfigurationManager->expects($this->once())->method('getFrameworkConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array()));
446 $dispatcher->setConfigurationManager($mockConfigurationManager);
447 $this->assertNull(Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('extensionname_someplugin'));
448 }
449
450 /**
451 * @test
452 */
453 public function getTargetPidByPluginSignatureReturnsTheConfiguredDefaultPid() {
454 $dispatcher = new Tx_Extbase_Tests_Fixtures_Dispatcher();
455 $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_AbstractConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'loadTypoScriptSetup', 'getFrameworkConfiguration'));
456 $mockConfigurationManager->expects($this->once())->method('getFrameworkConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array('view' => array('defaultPid' => '123'))));
457 $dispatcher->setConfigurationManager($mockConfigurationManager);
458 $expectedResult = 123;
459 $actualResult = Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('extensionname_someplugin');
460 $this->assertEquals($expectedResult, $actualResult);
461 }
462
463 /**
464 * @test
465 */
466 public function getTargetPidByPluginSignatureDeterminesTheTargetPidIfDefaultPidIsAuto() {
467 $dispatcher = new Tx_Extbase_Tests_Fixtures_Dispatcher();
468 $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_AbstractConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'loadTypoScriptSetup', 'getFrameworkConfiguration'));
469 $mockConfigurationManager->expects($this->once())->method('getFrameworkConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array('view' => array('defaultPid' => 'auto'))));
470 $dispatcher->setConfigurationManager($mockConfigurationManager);
471 $pluginSignature = 'extensionname_someplugin';
472 $GLOBALS['TSFE']->sys_page = $this->getMock('t3lib_pageSelect', array('enableFields'));
473 $GLOBALS['TSFE']->sys_page->expects($this->once())->method('enableFields')->with('tt_content')->will($this->returnValue(' AND enable_fields'));
474 $GLOBALS['TYPO3_DB']->expects($this->once())->method('fullQuoteStr')->with($pluginSignature, 'tt_content')->will($this->returnValue('"pluginSignature"'));
475 $GLOBALS['TYPO3_DB']->expects($this->once())->method('exec_SELECTgetRows')->with(
476 'pid',
477 'tt_content',
478 'list_type="pluginSignature" AND enable_fields',
479 '',
480 ''
481 )->will($this->returnValue(array(array('pid' => '321'))));
482 $expectedResult = 321;
483 $actualResult = Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature($pluginSignature);
484 $this->assertEquals($expectedResult, $actualResult);
485 }
486
487 /**
488 * @test
489 */
490 public function getTargetPidByPluginSignatureReturnsNullIfTargetPidCouldNotBeDetermined() {
491 $dispatcher = new Tx_Extbase_Tests_Fixtures_Dispatcher();
492 $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_AbstractConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'loadTypoScriptSetup', 'getFrameworkConfiguration'));
493 $mockConfigurationManager->expects($this->once())->method('getFrameworkConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array('view' => array('defaultPid' => 'auto'))));
494 $dispatcher->setConfigurationManager($mockConfigurationManager);
495 $GLOBALS['TSFE']->sys_page = $this->getMock('t3lib_pageSelect', array('enableFields'));
496 $GLOBALS['TSFE']->sys_page->expects($this->once())->method('enableFields')->will($this->returnValue(' AND enable_fields'));
497 $GLOBALS['TYPO3_DB']->expects($this->once())->method('fullQuoteStr')->will($this->returnValue('"pluginSignature"'));
498 $GLOBALS['TYPO3_DB']->expects($this->once())->method('exec_SELECTgetRows')->will($this->returnValue(array()));
499 $this->assertNull(Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('extensionname_someplugin'));
500 }
501
502 /**
503 * @test
504 * @expectedException Tx_Extbase_Exception
505 */
506 public function getTargetPidByPluginSignatureThrowsExceptionIfMoreThanOneTargetPidsWereFound() {
507 $dispatcher = new Tx_Extbase_Tests_Fixtures_Dispatcher();
508 $mockConfigurationManager = $this->getMock('Tx_Extbase_Configuration_AbstractConfigurationManager', array('getContextSpecificFrameworkConfiguration', 'loadTypoScriptSetup', 'getFrameworkConfiguration'));
509 $mockConfigurationManager->expects($this->once())->method('getFrameworkConfiguration')->with($GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.']['extensionname_someplugin.'])->will($this->returnValue(array('view' => array('defaultPid' => 'auto'))));
510 $dispatcher->setConfigurationManager($mockConfigurationManager);
511 $GLOBALS['TSFE']->sys_page = $this->getMock('t3lib_pageSelect', array('enableFields'));
512 $GLOBALS['TSFE']->sys_page->expects($this->once())->method('enableFields')->will($this->returnValue(' AND enable_fields'));
513 $GLOBALS['TYPO3_DB']->expects($this->once())->method('fullQuoteStr')->will($this->returnValue('"pluginSignature"'));
514 $GLOBALS['TYPO3_DB']->expects($this->once())->method('exec_SELECTgetRows')->will($this->returnValue(array(array('pid' => 123), array('pid' => 124))));
515 Tx_Extbase_Utility_Extension::getTargetPidByPluginSignature('extensionname_someplugin');
516 }
517
518 }
519
520 ?>