DispatcherTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * Redistributions of files must retain the above copyright notice
  8. *
  9. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  10. * @link http://cakephp.org CakePHP(tm) Project
  11. * @since 1.2.0
  12. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Cake\Test\TestCase\Routing;
  15. use Cake\Controller\Controller;
  16. use Cake\Core\Configure;
  17. use Cake\Core\Plugin;
  18. use Cake\Network\Request;
  19. use Cake\Network\Response;
  20. use Cake\Network\Session;
  21. use Cake\Routing\Dispatcher;
  22. use Cake\Routing\Filter\ControllerFactoryFilter;
  23. use Cake\TestSuite\TestCase;
  24. /**
  25. * DispatcherTest class
  26. *
  27. */
  28. class DispatcherTest extends TestCase
  29. {
  30. /**
  31. * setUp method
  32. *
  33. * @return void
  34. */
  35. public function setUp()
  36. {
  37. parent::setUp();
  38. $_GET = [];
  39. Configure::write('App.base', false);
  40. Configure::write('App.baseUrl', false);
  41. Configure::write('App.dir', 'app');
  42. Configure::write('App.webroot', 'webroot');
  43. Configure::write('App.namespace', 'TestApp');
  44. $this->dispatcher = new Dispatcher();
  45. $this->dispatcher->addFilter(new ControllerFactoryFilter());
  46. }
  47. /**
  48. * tearDown method
  49. *
  50. * @return void
  51. */
  52. public function tearDown()
  53. {
  54. parent::tearDown();
  55. Plugin::unload();
  56. }
  57. /**
  58. * testMissingController method
  59. *
  60. * @expectedException \Cake\Routing\Exception\MissingControllerException
  61. * @expectedExceptionMessage Controller class SomeController could not be found.
  62. * @return void
  63. */
  64. public function testMissingController()
  65. {
  66. $request = new Request([
  67. 'url' => 'some_controller/home',
  68. 'params' => [
  69. 'controller' => 'SomeController',
  70. 'action' => 'home',
  71. ]
  72. ]);
  73. $response = $this->getMock('Cake\Network\Response');
  74. $this->dispatcher->dispatch($request, $response, ['return' => 1]);
  75. }
  76. /**
  77. * testMissingControllerInterface method
  78. *
  79. * @expectedException \Cake\Routing\Exception\MissingControllerException
  80. * @expectedExceptionMessage Controller class Interface could not be found.
  81. * @return void
  82. */
  83. public function testMissingControllerInterface()
  84. {
  85. $request = new Request([
  86. 'url' => 'interface/index',
  87. 'params' => [
  88. 'controller' => 'Interface',
  89. 'action' => 'index',
  90. ]
  91. ]);
  92. $url = new Request('dispatcher_test_interface/index');
  93. $response = $this->getMock('Cake\Network\Response');
  94. $this->dispatcher->dispatch($request, $response, ['return' => 1]);
  95. }
  96. /**
  97. * testMissingControllerInterface method
  98. *
  99. * @expectedException \Cake\Routing\Exception\MissingControllerException
  100. * @expectedExceptionMessage Controller class Abstract could not be found.
  101. * @return void
  102. */
  103. public function testMissingControllerAbstract()
  104. {
  105. $request = new Request([
  106. 'url' => 'abstract/index',
  107. 'params' => [
  108. 'controller' => 'Abstract',
  109. 'action' => 'index',
  110. ]
  111. ]);
  112. $response = $this->getMock('Cake\Network\Response');
  113. $this->dispatcher->dispatch($request, $response, ['return' => 1]);
  114. }
  115. /**
  116. * Test that lowercase controller names result in missing controller errors.
  117. *
  118. * In case-insensitive file systems, lowercase controller names will kind of work.
  119. * This causes annoying deployment issues for lots of folks.
  120. *
  121. * @expectedException \Cake\Routing\Exception\MissingControllerException
  122. * @expectedExceptionMessage Controller class somepages could not be found.
  123. * @return void
  124. */
  125. public function testMissingControllerLowercase()
  126. {
  127. $request = new Request([
  128. 'url' => 'pages/home',
  129. 'params' => [
  130. 'controller' => 'somepages',
  131. 'action' => 'display',
  132. 'pass' => ['home'],
  133. ]
  134. ]);
  135. $response = $this->getMock('Cake\Network\Response');
  136. $this->dispatcher->dispatch($request, $response, ['return' => 1]);
  137. }
  138. /**
  139. * testDispatch method
  140. *
  141. * @return void
  142. */
  143. public function testDispatchBasic()
  144. {
  145. $url = new Request([
  146. 'url' => 'pages/home',
  147. 'params' => [
  148. 'controller' => 'Pages',
  149. 'action' => 'display',
  150. 'pass' => ['extract'],
  151. ]
  152. ]);
  153. $response = $this->getMock('Cake\Network\Response');
  154. $response->expects($this->once())
  155. ->method('send');
  156. $result = $this->dispatcher->dispatch($url, $response);
  157. $this->assertNull($result);
  158. }
  159. /**
  160. * Test that Dispatcher handles actions that return response objects.
  161. *
  162. * @return void
  163. */
  164. public function testDispatchActionReturnsResponse()
  165. {
  166. $request = new Request([
  167. 'url' => 'some_pages/responseGenerator',
  168. 'params' => [
  169. 'controller' => 'SomePages',
  170. 'action' => 'responseGenerator',
  171. 'pass' => []
  172. ]
  173. ]);
  174. $response = $this->getMock('Cake\Network\Response', ['_sendHeader']);
  175. ob_start();
  176. $this->dispatcher->dispatch($request, $response);
  177. $result = ob_get_clean();
  178. $this->assertEquals('new response', $result);
  179. }
  180. /**
  181. * test forbidden controller names.
  182. *
  183. * @expectedException \Cake\Routing\Exception\MissingControllerException
  184. * @expectedExceptionMessage Controller class TestPlugin.Tests could not be found.
  185. * @return void
  186. */
  187. public function testDispatchBadPluginName()
  188. {
  189. Plugin::load('TestPlugin');
  190. $request = new Request([
  191. 'url' => 'TestPlugin.Tests/index',
  192. 'params' => [
  193. 'plugin' => '',
  194. 'controller' => 'TestPlugin.Tests',
  195. 'action' => 'index',
  196. 'pass' => [],
  197. 'return' => 1
  198. ]
  199. ]);
  200. $response = $this->getMock('Cake\Network\Response');
  201. $this->dispatcher->dispatch($request, $response);
  202. }
  203. /**
  204. * test forbidden controller names.
  205. *
  206. * @expectedException \Cake\Routing\Exception\MissingControllerException
  207. * @expectedExceptionMessage Controller class TestApp\Controller\PostsController could not be found.
  208. * @return void
  209. */
  210. public function testDispatchBadName()
  211. {
  212. $request = new Request([
  213. 'url' => 'TestApp%5CController%5CPostsController/index',
  214. 'params' => [
  215. 'plugin' => '',
  216. 'controller' => 'TestApp\Controller\PostsController',
  217. 'action' => 'index',
  218. 'pass' => [],
  219. 'return' => 1
  220. ]
  221. ]);
  222. $response = $this->getMock('Cake\Network\Response');
  223. $this->dispatcher->dispatch($request, $response);
  224. }
  225. /**
  226. * Test dispatcher filters being called.
  227. *
  228. * @return void
  229. */
  230. public function testDispatcherFilter()
  231. {
  232. $filter = $this->getMock(
  233. 'Cake\Routing\DispatcherFilter',
  234. ['beforeDispatch', 'afterDispatch']
  235. );
  236. $filter->expects($this->at(0))
  237. ->method('beforeDispatch');
  238. $filter->expects($this->at(1))
  239. ->method('afterDispatch');
  240. $this->dispatcher->addFilter($filter);
  241. $request = new Request([
  242. 'url' => '/',
  243. 'params' => [
  244. 'controller' => 'Pages',
  245. 'action' => 'display',
  246. 'home',
  247. 'pass' => []
  248. ]
  249. ]);
  250. $response = $this->getMock('Cake\Network\Response', ['send']);
  251. $this->dispatcher->dispatch($request, $response);
  252. }
  253. /**
  254. * Test dispatcher filters being called and changing the response.
  255. *
  256. * @return void
  257. */
  258. public function testBeforeDispatchAbortDispatch()
  259. {
  260. $response = $this->getMock('Cake\Network\Response', ['send']);
  261. $response->expects($this->once())
  262. ->method('send');
  263. $filter = $this->getMock(
  264. 'Cake\Routing\DispatcherFilter',
  265. ['beforeDispatch', 'afterDispatch']
  266. );
  267. $filter->expects($this->once())
  268. ->method('beforeDispatch')
  269. ->will($this->returnValue($response));
  270. $filter->expects($this->never())
  271. ->method('afterDispatch');
  272. $request = new Request([
  273. 'url' => '/',
  274. 'params' => [
  275. 'controller' => 'Pages',
  276. 'action' => 'display',
  277. 'home',
  278. 'pass' => []
  279. ]
  280. ]);
  281. $res = new Response();
  282. $this->dispatcher->addFilter($filter);
  283. $this->dispatcher->dispatch($request, $res);
  284. }
  285. /**
  286. * Test dispatcher filters being called and changing the response.
  287. *
  288. * @return void
  289. */
  290. public function testAfterDispatchReplaceResponse()
  291. {
  292. $response = $this->getMock('Cake\Network\Response', ['_sendHeader', 'send']);
  293. $response->expects($this->once())
  294. ->method('send');
  295. $filter = $this->getMock(
  296. 'Cake\Routing\DispatcherFilter',
  297. ['beforeDispatch', 'afterDispatch']
  298. );
  299. $filter->expects($this->once())
  300. ->method('afterDispatch')
  301. ->will($this->returnValue($response));
  302. $request = new Request([
  303. 'url' => '/posts',
  304. 'params' => [
  305. 'plugin' => null,
  306. 'controller' => 'Posts',
  307. 'action' => 'index',
  308. 'pass' => [],
  309. ],
  310. 'session' => new Session
  311. ]);
  312. $this->dispatcher->addFilter($filter);
  313. $this->dispatcher->dispatch($request, $response);
  314. }
  315. }