7 * This source file is subject to the new BSD license that is bundled
8 * with this package in the file LICENSE.txt.
9 * It is also available through the world-wide-web at this URL:
10 * http://framework.zend.com/license/new-bsd
11 * If you did not receive a copy of the license and are unable to
12 * obtain it through the world-wide-web, please send an email
13 * to license@zend.com so we can send you a copy immediately.
16 * @package Zend_Controller
17 * @subpackage UnitTests
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
19 * @license http://framework.zend.com/license/new-bsd New BSD License
23 // Call Zend_Controller_Dispatcher_StandardTest::main() if this source file is executed directly.
24 if (!defined("PHPUnit_MAIN_METHOD")) {
25 define("PHPUnit_MAIN_METHOD", "Zend_Controller_Dispatcher_StandardTest::main");
28 require_once dirname(__FILE__
) . '/../../../TestHelper.php';
30 require_once 'Zend/Controller/Dispatcher/Standard.php';
31 require_once 'Zend/Controller/Action/HelperBroker.php';
32 require_once 'Zend/Controller/Front.php';
33 require_once 'Zend/Controller/Request/Http.php';
34 require_once 'Zend/Controller/Request/Simple.php';
35 require_once 'Zend/Controller/Response/Cli.php';
39 * @package Zend_Controller
40 * @subpackage UnitTests
41 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
42 * @license http://framework.zend.com/license/new-bsd New BSD License
43 * @group Zend_Controller
44 * @group Zend_Controller_Dispatcher
46 class Zend_Controller_Dispatcher_StandardTest
extends PHPUnit_Framework_TestCase
48 protected $_dispatcher;
51 * Runs the test methods of this class.
56 public static function main()
58 $suite = new PHPUnit_Framework_TestSuite("Zend_Controller_Dispatcher_StandardTest");
59 $result = PHPUnit_TextUI_TestRunner
::run($suite);
62 public function setUp()
64 if (isset($this->error
)) {
67 $front = Zend_Controller_Front
::getInstance();
68 $front->resetInstance();
69 Zend_Controller_Action_HelperBroker
::removeHelper('viewRenderer');
70 $this->_dispatcher
= new Zend_Controller_Dispatcher_Standard();
71 $this->_dispatcher
->setControllerDirectory(array(
72 'default' => dirname(__FILE__
) . DIRECTORY_SEPARATOR
. '..' . DIRECTORY_SEPARATOR
. '_files',
73 'admin' => dirname(__FILE__
) . DIRECTORY_SEPARATOR
. '..' . DIRECTORY_SEPARATOR
. '_files' . DIRECTORY_SEPARATOR
. 'Admin'
77 public function tearDown()
79 unset($this->_dispatcher
);
82 public function testFormatControllerName()
84 $this->assertEquals('IndexController', $this->_dispatcher
->formatControllerName('index'));
85 $this->assertEquals('Site_CustomController', $this->_dispatcher
->formatControllerName('site_custom'));
88 public function testFormatActionName()
90 $this->assertEquals('indexAction', $this->_dispatcher
->formatActionName('index'));
91 $this->assertEquals('myindexAction', $this->_dispatcher
->formatActionName('myIndex'));
92 $this->assertEquals('myindexAction', $this->_dispatcher
->formatActionName('my_index'));
93 $this->assertEquals('myIndexAction', $this->_dispatcher
->formatActionName('my.index'));
94 $this->assertEquals('myIndexAction', $this->_dispatcher
->formatActionName('my-index'));
97 public function testSetGetControllerDirectory()
100 'default' => dirname(__FILE__
) . DIRECTORY_SEPARATOR
. '..' . DIRECTORY_SEPARATOR
. '_files',
101 'admin' => dirname(__FILE__
) . DIRECTORY_SEPARATOR
. '..' . DIRECTORY_SEPARATOR
. '_files' . DIRECTORY_SEPARATOR
. 'Admin'
103 $dirs = $this->_dispatcher
->getControllerDirectory();
104 $this->assertEquals($expected, $dirs);
107 public function testIsDispatchable()
109 $request = new Zend_Controller_Request_Http();
111 $this->assertFalse($this->_dispatcher
->isDispatchable($request));
113 $request->setControllerName('index');
114 $this->assertTrue($this->_dispatcher
->isDispatchable($request));
116 $request->setControllerName('foo');
117 $this->assertTrue($this->_dispatcher
->isDispatchable($request));
119 // True, because it will dispatch to default controller
120 $request->setControllerName('bogus');
121 $this->assertFalse($this->_dispatcher
->isDispatchable($request));
124 public function testModuleIsDispatchable()
126 $request = new Zend_Controller_Request_Http();
127 $request->setModuleName('admin');
128 $request->setControllerName('foo');
129 $request->setActionName('bar');
131 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
133 $request->setModuleName('bogus');
134 $request->setControllerName('bogus');
135 $request->setActionName('bar');
136 $this->assertFalse($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
142 public function testIsDispatchableManuallyIncludedController()
144 require_once dirname(__FILE__
) . '/../_files/ManuallyIncludedControllers.php';
145 $request = new Zend_Controller_Request_Http();
148 $this->_dispatcher
->setParam('prefixDefaultModule', true);
150 $request->setControllerName('included');
151 $this->assertFalse($this->_dispatcher
->isDispatchable($request));
153 $request->setControllerName('included-prefix');
154 $this->assertTrue($this->_dispatcher
->isDispatchable($request));
156 $this->_dispatcher
->setParam('prefixDefaultModule', false);
158 $request->setModuleName('admin');
159 $request->setControllerName('included-admin');
160 $this->assertTrue($this->_dispatcher
->isDispatchable($request));
163 public function testSetGetResponse()
165 $response = new Zend_Controller_Response_Cli();
166 $this->_dispatcher
->setResponse($response);
167 $this->assertTrue($response === $this->_dispatcher
->getResponse());
170 public function testSetGetDefaultControllerName()
172 $this->assertEquals('index', $this->_dispatcher
->getDefaultControllerName());
174 $this->_dispatcher
->setDefaultControllerName('foo');
175 $this->assertEquals('foo', $this->_dispatcher
->getDefaultControllerName());
178 public function testSetGetDefaultAction()
180 $this->assertEquals('index', $this->_dispatcher
->getDefaultAction());
182 $this->_dispatcher
->setDefaultAction('bar');
183 $this->assertEquals('bar', $this->_dispatcher
->getDefaultAction());
186 public function testDispatchValidControllerDefaultAction()
188 $request = new Zend_Controller_Request_Http();
189 $request->setControllerName('index');
190 $response = new Zend_Controller_Response_Cli();
191 $this->_dispatcher
->dispatch($request, $response);
193 $this->assertContains('Index action called', $this->_dispatcher
->getResponse()->getBody());
196 public function testDispatchValidControllerAndAction()
198 $request = new Zend_Controller_Request_Http();
199 $request->setControllerName('index');
200 $request->setActionName('index');
201 $response = new Zend_Controller_Response_Cli();
202 $this->_dispatcher
->dispatch($request, $response);
204 $this->assertContains('Index action called', $this->_dispatcher
->getResponse()->getBody());
207 public function testDispatchValidControllerWithInvalidAction()
209 $request = new Zend_Controller_Request_Http();
210 $request->setControllerName('index');
211 $request->setActionName('foo');
212 $response = new Zend_Controller_Response_Cli();
215 $this->_dispatcher
->dispatch($request, $response);
216 $this->fail('Exception should be raised by __call');
217 } catch (Exception
$e) {
222 public function testDispatchInvalidController()
224 $request = new Zend_Controller_Request_Http();
225 $request->setControllerName('bogus');
226 $response = new Zend_Controller_Response_Cli();
229 $this->_dispatcher
->dispatch($request, $response);
230 $this->fail('Exception should be raised; no such controller');
231 } catch (Exception
$e) {
236 public function testDispatchInvalidControllerUsingDefaults()
238 $request = new Zend_Controller_Request_Http();
239 $request->setControllerName('bogus');
240 $response = new Zend_Controller_Response_Cli();
242 $this->_dispatcher
->setParam('useDefaultControllerAlways', true);
245 $this->_dispatcher
->dispatch($request, $response);
246 $this->assertEquals('index', $request->getControllerName());
247 $this->assertEquals('index', $request->getActionName());
248 } catch (Exception
$e) {
249 $this->fail('Exception should not be raised when useDefaultControllerAlways set; message: ' . $e->getMessage());
256 public function testUsingDefaultControllerAlwaysShouldRewriteActionNameToDefault()
258 $request = new Zend_Controller_Request_Http();
259 $request->setControllerName('bogus');
260 $request->setActionName('really');
261 $request->setParam('action', 'really'); // router sets action as a param
262 $response = new Zend_Controller_Response_Cli();
264 $this->_dispatcher
->setParam('useDefaultControllerAlways', true);
267 $this->_dispatcher
->dispatch($request, $response);
268 } catch (Zend_Controller_Dispatcher_Exception
$e) {
269 $this->fail('Exception should not be raised when useDefaultControllerAlways set; message: ' . $e->getMessage());
272 $this->assertEquals('index', $request->getControllerName());
273 $this->assertEquals('index', $request->getActionName());
276 public function testDispatchInvalidControllerUsingDefaultsWithDefaultModule()
278 $request = new Zend_Controller_Request_Http();
279 $request->setControllerName('bogus')
280 ->setModuleName('default');
281 $response = new Zend_Controller_Response_Cli();
283 $this->_dispatcher
->setParam('useDefaultControllerAlways', true);
286 $this->_dispatcher
->dispatch($request, $response);
287 $this->assertSame('default', $request->getModuleName());
288 $this->assertSame('index', $request->getControllerName());
289 $this->assertSame('index', $request->getActionName());
290 } catch (Exception
$e) {
291 $this->fail('Exception should not be raised when useDefaultControllerAlways set; exception: ' . $e->getMessage());
295 public function testDispatchValidControllerWithPrePostDispatch()
297 $request = new Zend_Controller_Request_Http();
298 $request->setControllerName('foo');
299 $request->setActionName('bar');
300 $response = new Zend_Controller_Response_Cli();
301 $this->_dispatcher
->dispatch($request, $response);
303 $body = $this->_dispatcher
->getResponse()->getBody();
304 $this->assertContains('Bar action called', $body);
305 $this->assertContains('preDispatch called', $body);
306 $this->assertContains('postDispatch called', $body);
309 public function testDispatchNoControllerUsesDefaults()
311 $request = new Zend_Controller_Request_Http();
312 $response = new Zend_Controller_Response_Cli();
313 $this->_dispatcher
->dispatch($request, $response);
315 $this->assertEquals('index', $request->getControllerName());
316 $this->assertEquals('index', $request->getActionName());
320 * Tests ZF-637 -- action names with underscores not being correctly changed to camelCase
322 public function testZf637()
324 $test = $this->_dispatcher
->formatActionName('view_entry');
325 $this->assertEquals('viewentryAction', $test);
328 public function testWordDelimiter()
330 $this->assertEquals(array('-', '.'), $this->_dispatcher
->getWordDelimiter());
331 $this->_dispatcher
->setWordDelimiter(':');
332 $this->assertEquals(array(':'), $this->_dispatcher
->getWordDelimiter());
335 public function testPathDelimiter()
337 $this->assertEquals('_', $this->_dispatcher
->getPathDelimiter());
338 $this->_dispatcher
->setPathDelimiter(':');
339 $this->assertEquals(':', $this->_dispatcher
->getPathDelimiter());
343 * Test that classes are found in modules, using a prefix
345 public function testModules()
347 $request = new Zend_Controller_Request_Http();
348 $request->setModuleName('admin');
349 $request->setControllerName('foo');
350 $request->setActionName('bar');
352 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
354 $response = new Zend_Controller_Response_Cli();
355 $this->_dispatcher
->dispatch($request, $response);
356 $body = $this->_dispatcher
->getResponse()->getBody();
357 $this->assertContains("Admin_Foo::bar action called", $body, $body);
360 public function testModuleControllerInSubdirWithCamelCaseAction()
362 $request = new Zend_Controller_Request_Http();
363 $request->setModuleName('admin');
364 $request->setControllerName('foo-bar');
365 $request->setActionName('baz.bat');
367 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
369 $response = new Zend_Controller_Response_Cli();
370 $this->_dispatcher
->dispatch($request, $response);
371 $body = $this->_dispatcher
->getResponse()->getBody();
372 $this->assertContains("Admin_FooBar::bazBat action called", $body, $body);
375 public function testUseModuleDefaultController()
377 $this->_dispatcher
->setDefaultControllerName('foo')
378 ->setParam('useDefaultControllerAlways', true);
380 $request = new Zend_Controller_Request_Http();
381 $request->setModuleName('admin');
383 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
385 $response = new Zend_Controller_Response_Cli();
386 $this->_dispatcher
->dispatch($request, $response);
387 $body = $this->_dispatcher
->getResponse()->getBody();
388 $this->assertContains("Admin_Foo::index action called", $body, $body);
391 public function testNoModuleOrControllerDefaultsCorrectly()
393 $request = new Zend_Controller_Request_Http('http://example.com/');
395 $this->assertFalse($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
397 $response = new Zend_Controller_Response_Cli();
398 $this->_dispatcher
->dispatch($request, $response);
399 $body = $this->_dispatcher
->getResponse()->getBody();
400 $this->assertContains("Index action called", $body, $body);
403 public function testOutputBuffering()
405 $request = new Zend_Controller_Request_Http();
406 $request->setControllerName('ob');
407 $request->setActionName('index');
409 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
411 $response = new Zend_Controller_Response_Cli();
412 $this->_dispatcher
->dispatch($request, $response);
413 $body = $this->_dispatcher
->getResponse()->getBody();
414 $this->assertContains("OB index action called", $body, $body);
417 public function testDisableOutputBuffering()
419 if (!defined('TESTS_ZEND_CONTROLLER_DISPATCHER_OB') ||
!TESTS_ZEND_CONTROLLER_DISPATCHER_OB
) {
420 $this->markTestSkipped('Skipping output buffer disabling in Zend_Controller_Dispatcher_Standard');
423 $request = new Zend_Controller_Request_Http();
424 $request->setControllerName('ob');
425 $request->setActionName('index');
426 $this->_dispatcher
->setParam('disableOutputBuffering', true);
428 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
430 $response = new Zend_Controller_Response_Cli();
431 $this->_dispatcher
->dispatch($request, $response);
432 $body = $this->_dispatcher
->getResponse()->getBody();
433 $this->assertEquals('', $body, $body);
436 public function testModuleSubdirControllerFound()
438 Zend_Controller_Front
::getInstance()
439 ->setDispatcher($this->_dispatcher
)
440 ->addControllerDirectory(
441 dirname(__FILE__
) . DIRECTORY_SEPARATOR
. '..' . DIRECTORY_SEPARATOR
. '_files' . DIRECTORY_SEPARATOR
. 'modules' . DIRECTORY_SEPARATOR
. 'foo' . DIRECTORY_SEPARATOR
. 'controllers',
445 $request = new Zend_Controller_Request_Http();
446 $request->setModuleName('foo');
447 $request->setControllerName('admin_index');
448 $request->setActionName('index');
450 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
452 $response = new Zend_Controller_Response_Cli();
453 $this->_dispatcher
->dispatch($request, $response);
454 $body = $this->_dispatcher
->getResponse()->getBody();
455 $this->assertContains("Foo_Admin_IndexController::indexAction() called", $body, $body);
458 public function testDefaultModule()
460 $this->assertEquals('default', $this->_dispatcher
->getDefaultModule());
461 $this->_dispatcher
->setDefaultModule('foobar');
462 $this->assertEquals('foobar', $this->_dispatcher
->getDefaultModule());
465 public function testModuleValid()
467 $this->assertTrue($this->_dispatcher
->isValidModule('default'));
468 $this->assertTrue($this->_dispatcher
->isValidModule('admin'));
469 $this->assertFalse($this->_dispatcher
->isValidModule('bogus'));
470 $this->assertFalse($this->_dispatcher
->isValidModule(null));
471 $this->assertFalse($this->_dispatcher
->isValidModule($this));
472 $this->assertFalse($this->_dispatcher
->isValidModule(array()));
478 public function testIsValidModuleShouldNormalizeModuleName()
480 $this->assertTrue($this->_dispatcher
->isValidModule('Admin'));
483 public function testSanelyDiscardOutputBufferOnException()
485 $request = new Zend_Controller_Request_Http();
486 $request->setControllerName('ob');
487 $request->setActionName('exception');
489 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
491 $response = new Zend_Controller_Response_Cli();
493 $this->_dispatcher
->dispatch($request, $response);
494 $this->fail('Exception should have been rethrown');
495 } catch (Exception
$e) {
497 $body = $this->_dispatcher
->getResponse()->getBody();
498 $this->assertNotContains("In exception action", $body, $body);
499 $this->assertNotContains("Foo", $body, $body);
502 public function testGetDefaultControllerClassResetsRequestObject()
504 $request = new Zend_Controller_Request_Http();
505 $request->setModuleName('foobar')
506 ->setControllerName('bazbatbegone')
507 ->setActionName('bebop');
508 $this->_dispatcher
->getDefaultControllerClass($request);
509 $this->assertEquals($this->_dispatcher
->getDefaultModule(), $request->getModuleName());
510 $this->assertEquals($this->_dispatcher
->getDefaultControllerName(), $request->getControllerName());
511 $this->assertNull($request->getActionName());
514 public function testLoadClassLoadsControllerInDefaultModuleWithoutModulePrefix()
516 $request = new Zend_Controller_Request_Simple();
517 $request->setControllerName('empty');
518 $class = $this->_dispatcher
->getControllerClass($request);
519 $this->assertEquals('EmptyController', $class);
520 $test = $this->_dispatcher
->loadClass($class);
521 $this->assertEquals($class, $test);
522 $this->assertTrue(class_exists($class));
525 public function testLoadClassLoadsControllerInSpecifiedModuleWithModulePrefix()
527 Zend_Controller_Front
::getInstance()
528 ->setDispatcher($this->_dispatcher
)
529 ->addModuleDirectory(dirname(__FILE__
) . '/../_files/modules');
530 $request = new Zend_Controller_Request_Simple();
531 $request->setControllerName('index')
532 ->setModuleName('bar');
533 $class = $this->_dispatcher
->getControllerClass($request);
534 $this->assertEquals('IndexController', $class);
535 $test = $this->_dispatcher
->loadClass($class);
536 $this->assertEquals('Bar_IndexController', $test);
537 $this->assertTrue(class_exists($test));
540 public function testLoadClassLoadsControllerInDefaultModuleWithModulePrefixWhenRequested()
542 Zend_Controller_Front
::getInstance()
543 ->setDispatcher($this->_dispatcher
)
544 ->addModuleDirectory(dirname(__FILE__
) . '/../_files/modules');
545 $this->_dispatcher
->setDefaultModule('foo')
546 ->setParam('prefixDefaultModule', true);
547 $request = new Zend_Controller_Request_Simple();
548 $request->setControllerName('index');
549 $class = $this->_dispatcher
->getControllerClass($request);
550 $this->assertEquals('IndexController', $class);
551 $test = $this->_dispatcher
->loadClass($class);
552 $this->assertEquals('Foo_IndexController', $test);
553 $this->assertTrue(class_exists($test));
559 public function testCanRemoveControllerDirectory()
561 Zend_Controller_Front
::getInstance()
562 ->setDispatcher($this->_dispatcher
)
563 ->addModuleDirectory(dirname(__FILE__
) . '/../_files/modules');
564 $dirs = $this->_dispatcher
->getControllerDirectory();
565 $this->_dispatcher
->removeControllerDirectory('foo');
566 $test = $this->_dispatcher
->getControllerDirectory();
567 $this->assertNotEquals($dirs, $test);
568 $this->assertFalse(array_key_exists('foo', $test));
574 public function testCamelCasedActionsNotRequestedWithWordSeparatorsShouldNotResolve()
576 $request = new Zend_Controller_Request_Http();
577 $request->setModuleName('admin');
578 $request->setControllerName('foo-bar');
579 $request->setActionName('bazBat');
580 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
582 $response = new Zend_Controller_Response_Cli();
584 $this->_dispatcher
->dispatch($request, $response);
585 $this->fail('Invalid camelCased action should raise exception');
586 } catch (Zend_Controller_Exception
$e) {
587 $this->assertContains('does not exist', $e->getMessage());
594 public function testCamelCasedActionsNotRequestedWithWordSeparatorsShouldResolveIfForced()
596 $this->_dispatcher
->setParam('useCaseSensitiveActions', true);
597 $request = new Zend_Controller_Request_Http();
598 $request->setModuleName('admin');
599 $request->setControllerName('foo-bar');
600 $request->setActionName('bazBat');
601 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
603 $response = new Zend_Controller_Response_Cli();
604 $oldLevel = error_reporting(0);
606 $this->_dispatcher
->dispatch($request, $response);
607 $body = $this->_dispatcher
->getResponse()->getBody();
608 error_reporting($oldLevel);
609 $this->assertContains("Admin_FooBar::bazBat action called", $body, $body);
610 } catch (Zend_Controller_Exception
$e) {
611 error_reporting($oldLevel);
612 $this->fail('camelCased actions should succeed when forced');
616 public function handleErrors($errno, $errstr)
618 $this->error
= $errstr;
624 public function testForcingCamelCasedActionsNotRequestedWithWordSeparatorsShouldRaiseNotices()
626 $this->_dispatcher
->setParam('useCaseSensitiveActions', true);
627 $request = new Zend_Controller_Request_Http();
628 $request->setModuleName('admin');
629 $request->setControllerName('foo-bar');
630 $request->setActionName('bazBat');
631 $this->assertTrue($this->_dispatcher
->isDispatchable($request), var_export($this->_dispatcher
->getControllerDirectory(), 1));
633 $response = new Zend_Controller_Response_Cli();
634 set_error_handler(array($this, 'handleErrors'));
636 $this->_dispatcher
->dispatch($request, $response);
637 $body = $this->_dispatcher
->getResponse()->getBody();
638 restore_error_handler();
639 $this->assertTrue(isset($this->error
));
640 $this->assertContains('deprecated', $this->error
);
641 } catch (Zend_Controller_Exception
$e) {
642 restore_error_handler();
643 $this->fail('camelCased actions should succeed when forced');
650 public function testGetControllerClassThrowsExceptionIfNoDefaultModuleDefined()
652 $this->_dispatcher
->setControllerDirectory(array());
654 $request = new Zend_Controller_Request_Simple();
655 $request->setControllerName('empty');
657 $class = $this->_dispatcher
->getControllerClass($request);
658 } catch (Zend_Controller_Exception
$e) {
659 $this->assertContains('No default module', $e->getMessage());
664 // Call Zend_Controller_Dispatcher_StandardTest::main() if this source file is executed directly.
665 if (PHPUnit_MAIN_METHOD
== "Zend_Controller_Dispatcher_StandardTest::main") {
666 Zend_Controller_Dispatcher_StandardTest
::main();