HttpKernelTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpKernel\Tests;
  11. use Symfony\Component\HttpKernel\HttpKernel;
  12. use Symfony\Component\HttpKernel\HttpKernelInterface;
  13. use Symfony\Component\HttpKernel\KernelEvents;
  14. use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
  15. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpFoundation\RedirectResponse;
  19. use Symfony\Component\EventDispatcher\EventDispatcher;
  20. class HttpKernelTest extends \PHPUnit_Framework_TestCase
  21. {
  22. protected function setUp()
  23. {
  24. if (!class_exists('Symfony\Component\EventDispatcher\EventDispatcher')) {
  25. $this->markTestSkipped('The "EventDispatcher" component is not available');
  26. }
  27. if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
  28. $this->markTestSkipped('The "HttpFoundation" component is not available');
  29. }
  30. }
  31. /**
  32. * @expectedException RuntimeException
  33. */
  34. public function testHandleWhenControllerThrowsAnExceptionAndRawIsTrue()
  35. {
  36. $kernel = new HttpKernel(new EventDispatcher(), $this->getResolver(function () { throw new \RuntimeException(); }));
  37. $kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, true);
  38. }
  39. /**
  40. * @expectedException RuntimeException
  41. */
  42. public function testHandleWhenControllerThrowsAnExceptionAndRawIsFalseAndNoListenerIsRegistered()
  43. {
  44. $kernel = new HttpKernel(new EventDispatcher(), $this->getResolver(function () { throw new \RuntimeException(); }));
  45. $kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, false);
  46. }
  47. public function testHandleWhenControllerThrowsAnExceptionAndRawIsFalse()
  48. {
  49. $dispatcher = new EventDispatcher();
  50. $dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
  51. $event->setResponse(new Response($event->getException()->getMessage()));
  52. });
  53. $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new \RuntimeException('foo'); }));
  54. $response = $kernel->handle(new Request());
  55. $this->assertEquals('500', $response->getStatusCode());
  56. $this->assertEquals('foo', $response->getContent());
  57. }
  58. public function testHandleExceptionWithARedirectionResponse()
  59. {
  60. $dispatcher = new EventDispatcher();
  61. $dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
  62. $event->setResponse(new RedirectResponse('/login', 301));
  63. });
  64. $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new AccessDeniedHttpException(); }));
  65. $response = $kernel->handle(new Request());
  66. $this->assertEquals('301', $response->getStatusCode());
  67. $this->assertEquals('/login', $response->headers->get('Location'));
  68. }
  69. public function testHandleHttpException()
  70. {
  71. $dispatcher = new EventDispatcher();
  72. $dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
  73. $event->setResponse(new Response($event->getException()->getMessage()));
  74. });
  75. $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new MethodNotAllowedHttpException(array('POST')); }));
  76. $response = $kernel->handle(new Request());
  77. $this->assertEquals('405', $response->getStatusCode());
  78. $this->assertEquals('POST', $response->headers->get('Allow'));
  79. }
  80. /**
  81. * @dataProvider getStatusCodes
  82. */
  83. public function testHandleWhenAnExceptionIsHandledWithASpecificStatusCode($responseStatusCode, $expectedStatusCode)
  84. {
  85. $dispatcher = new EventDispatcher();
  86. $dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) use ($responseStatusCode, $expectedStatusCode) {
  87. $event->setResponse(new Response('', $responseStatusCode, array('X-Status-Code' => $expectedStatusCode)));
  88. });
  89. $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new \RuntimeException(); }));
  90. $response = $kernel->handle(new Request());
  91. $this->assertEquals($expectedStatusCode, $response->getStatusCode());
  92. $this->assertFalse($response->headers->has('X-Status-Code'));
  93. }
  94. public function getStatusCodes()
  95. {
  96. return array(
  97. array(200, 404),
  98. array(404, 200),
  99. array(301, 200),
  100. array(500, 200),
  101. );
  102. }
  103. public function testHandleWhenAListenerReturnsAResponse()
  104. {
  105. $dispatcher = new EventDispatcher();
  106. $dispatcher->addListener(KernelEvents::REQUEST, function ($event) {
  107. $event->setResponse(new Response('hello'));
  108. });
  109. $kernel = new HttpKernel($dispatcher, $this->getResolver());
  110. $this->assertEquals('hello', $kernel->handle(new Request())->getContent());
  111. }
  112. /**
  113. * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
  114. */
  115. public function testHandleWhenNoControllerIsFound()
  116. {
  117. $dispatcher = new EventDispatcher();
  118. $kernel = new HttpKernel($dispatcher, $this->getResolver(false));
  119. $kernel->handle(new Request());
  120. }
  121. /**
  122. * @expectedException LogicException
  123. */
  124. public function testHandleWhenTheControllerIsNotACallable()
  125. {
  126. $dispatcher = new EventDispatcher();
  127. $kernel = new HttpKernel($dispatcher, $this->getResolver('foobar'));
  128. $kernel->handle(new Request());
  129. }
  130. public function testHandleWhenTheControllerIsAClosure()
  131. {
  132. $response = new Response('foo');
  133. $dispatcher = new EventDispatcher();
  134. $kernel = new HttpKernel($dispatcher, $this->getResolver(function () use ($response) { return $response; }));
  135. $this->assertSame($response, $kernel->handle(new Request()));
  136. }
  137. public function testHandleWhenTheControllerIsAnObjectWithInvoke()
  138. {
  139. $dispatcher = new EventDispatcher();
  140. $kernel = new HttpKernel($dispatcher, $this->getResolver(new Controller()));
  141. $this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
  142. }
  143. public function testHandleWhenTheControllerIsAFunction()
  144. {
  145. $dispatcher = new EventDispatcher();
  146. $kernel = new HttpKernel($dispatcher, $this->getResolver('Symfony\Component\HttpKernel\Tests\controller_func'));
  147. $this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
  148. }
  149. public function testHandleWhenTheControllerIsAnArray()
  150. {
  151. $dispatcher = new EventDispatcher();
  152. $kernel = new HttpKernel($dispatcher, $this->getResolver(array(new Controller(), 'controller')));
  153. $this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
  154. }
  155. public function testHandleWhenTheControllerIsAStaticArray()
  156. {
  157. $dispatcher = new EventDispatcher();
  158. $kernel = new HttpKernel($dispatcher, $this->getResolver(array('Symfony\Component\HttpKernel\Tests\Controller', 'staticcontroller')));
  159. $this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
  160. }
  161. /**
  162. * @expectedException LogicException
  163. */
  164. public function testHandleWhenTheControllerDoesNotReturnAResponse()
  165. {
  166. $dispatcher = new EventDispatcher();
  167. $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { return 'foo'; }));
  168. $kernel->handle(new Request());
  169. }
  170. public function testHandleWhenTheControllerDoesNotReturnAResponseButAViewIsRegistered()
  171. {
  172. $dispatcher = new EventDispatcher();
  173. $dispatcher->addListener(KernelEvents::VIEW, function ($event) {
  174. $event->setResponse(new Response($event->getControllerResult()));
  175. });
  176. $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { return 'foo'; }));
  177. $this->assertEquals('foo', $kernel->handle(new Request())->getContent());
  178. }
  179. public function testHandleWithAResponseListener()
  180. {
  181. $dispatcher = new EventDispatcher();
  182. $dispatcher->addListener(KernelEvents::RESPONSE, function ($event) {
  183. $event->setResponse(new Response('foo'));
  184. });
  185. $kernel = new HttpKernel($dispatcher, $this->getResolver());
  186. $this->assertEquals('foo', $kernel->handle(new Request())->getContent());
  187. }
  188. public function testTerminate()
  189. {
  190. $dispatcher = new EventDispatcher();
  191. $kernel = new HttpKernel($dispatcher, $this->getResolver());
  192. $dispatcher->addListener(KernelEvents::TERMINATE, function ($event) use (&$called, &$capturedKernel, &$capturedRequest, &$capturedResponse) {
  193. $called = true;
  194. $capturedKernel = $event->getKernel();
  195. $capturedRequest = $event->getRequest();
  196. $capturedResponse = $event->getResponse();
  197. });
  198. $kernel->terminate($request = Request::create('/'), $response = new Response());
  199. $this->assertTrue($called);
  200. $this->assertEquals($kernel, $capturedKernel);
  201. $this->assertEquals($request, $capturedRequest);
  202. $this->assertEquals($response, $capturedResponse);
  203. }
  204. protected function getResolver($controller = null)
  205. {
  206. if (null === $controller) {
  207. $controller = function() { return new Response('Hello'); };
  208. }
  209. $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
  210. $resolver->expects($this->any())
  211. ->method('getController')
  212. ->will($this->returnValue($controller));
  213. $resolver->expects($this->any())
  214. ->method('getArguments')
  215. ->will($this->returnValue(array()));
  216. return $resolver;
  217. }
  218. protected function assertResponseEquals(Response $expected, Response $actual)
  219. {
  220. $expected->setDate($actual->getDate());
  221. $this->assertEquals($expected, $actual);
  222. }
  223. }
  224. class Controller
  225. {
  226. public function __invoke()
  227. {
  228. return new Response('foo');
  229. }
  230. public function controller()
  231. {
  232. return new Response('foo');
  233. }
  234. public static function staticController()
  235. {
  236. return new Response('foo');
  237. }
  238. }
  239. function controller_func()
  240. {
  241. return new Response('foo');
  242. }