DispatcherTest.php 11 KB

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