4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\HttpKernel\Tests;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\HttpKernel\HttpKernel;
16 use Symfony\Component\HttpKernel\HttpKernelInterface;
17 use Symfony\Component\HttpKernel\KernelEvents;
18 use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
19 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
20 use Symfony\Component\HttpFoundation\Request;
21 use Symfony\Component\HttpFoundation\Response;
22 use Symfony\Component\HttpFoundation\RedirectResponse;
23 use Symfony\Component\EventDispatcher\EventDispatcher;
25 class HttpKernelTest extends TestCase
28 * @expectedException \RuntimeException
30 public function testHandleWhenControllerThrowsAnExceptionAndCatchIsTrue()
32 $kernel = new HttpKernel(new EventDispatcher(), $this->getResolver(function () { throw new \RuntimeException(); }));
34 $kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, true);
38 * @expectedException \RuntimeException
40 public function testHandleWhenControllerThrowsAnExceptionAndCatchIsFalseAndNoListenerIsRegistered()
42 $kernel = new HttpKernel(new EventDispatcher(), $this->getResolver(function () { throw new \RuntimeException(); }));
44 $kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, false);
47 public function testHandleWhenControllerThrowsAnExceptionAndCatchIsTrueWithAHandlingListener()
49 $dispatcher = new EventDispatcher();
50 $dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
51 $event->setResponse(new Response($event->getException()->getMessage()));
54 $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new \RuntimeException('foo'); }));
55 $response = $kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, true);
57 $this->assertEquals('500', $response->getStatusCode());
58 $this->assertEquals('foo', $response->getContent());
61 public function testHandleWhenControllerThrowsAnExceptionAndCatchIsTrueWithANonHandlingListener()
63 $exception = new \RuntimeException();
65 $dispatcher = new EventDispatcher();
66 $dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
67 // should set a response, but does not
70 $kernel = new HttpKernel($dispatcher, $this->getResolver(function () use ($exception) { throw $exception; }));
73 $kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, true);
74 $this->fail('LogicException expected');
75 } catch (\RuntimeException $e) {
76 $this->assertSame($exception, $e);
80 public function testHandleExceptionWithARedirectionResponse()
82 $dispatcher = new EventDispatcher();
83 $dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
84 $event->setResponse(new RedirectResponse('/login', 301));
87 $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new AccessDeniedHttpException(); }));
88 $response = $kernel->handle(new Request());
90 $this->assertEquals('301', $response->getStatusCode());
91 $this->assertEquals('/login', $response->headers->get('Location'));
94 public function testHandleHttpException()
96 $dispatcher = new EventDispatcher();
97 $dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
98 $event->setResponse(new Response($event->getException()->getMessage()));
101 $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new MethodNotAllowedHttpException(array('POST')); }));
102 $response = $kernel->handle(new Request());
104 $this->assertEquals('405', $response->getStatusCode());
105 $this->assertEquals('POST', $response->headers->get('Allow'));
109 * @dataProvider getStatusCodes
111 public function testHandleWhenAnExceptionIsHandledWithASpecificStatusCode($responseStatusCode, $expectedStatusCode)
113 $dispatcher = new EventDispatcher();
114 $dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) use ($responseStatusCode, $expectedStatusCode) {
115 $event->setResponse(new Response('', $responseStatusCode, array('X-Status-Code' => $expectedStatusCode)));
118 $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new \RuntimeException(); }));
119 $response = $kernel->handle(new Request());
121 $this->assertEquals($expectedStatusCode, $response->getStatusCode());
122 $this->assertFalse($response->headers->has('X-Status-Code'));
125 public function getStatusCodes()
135 public function testHandleWhenAListenerReturnsAResponse()
137 $dispatcher = new EventDispatcher();
138 $dispatcher->addListener(KernelEvents::REQUEST, function ($event) {
139 $event->setResponse(new Response('hello'));
142 $kernel = new HttpKernel($dispatcher, $this->getResolver());
144 $this->assertEquals('hello', $kernel->handle(new Request())->getContent());
148 * @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
150 public function testHandleWhenNoControllerIsFound()
152 $dispatcher = new EventDispatcher();
153 $kernel = new HttpKernel($dispatcher, $this->getResolver(false));
155 $kernel->handle(new Request());
159 * @expectedException \LogicException
161 public function testHandleWhenTheControllerIsNotACallable()
163 $dispatcher = new EventDispatcher();
164 $kernel = new HttpKernel($dispatcher, $this->getResolver('foobar'));
166 $kernel->handle(new Request());
169 public function testHandleWhenTheControllerIsAClosure()
171 $response = new Response('foo');
172 $dispatcher = new EventDispatcher();
173 $kernel = new HttpKernel($dispatcher, $this->getResolver(function () use ($response) { return $response; }));
175 $this->assertSame($response, $kernel->handle(new Request()));
178 public function testHandleWhenTheControllerIsAnObjectWithInvoke()
180 $dispatcher = new EventDispatcher();
181 $kernel = new HttpKernel($dispatcher, $this->getResolver(new Controller()));
183 $this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
186 public function testHandleWhenTheControllerIsAFunction()
188 $dispatcher = new EventDispatcher();
189 $kernel = new HttpKernel($dispatcher, $this->getResolver('Symfony\Component\HttpKernel\Tests\controller_func'));
191 $this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
194 public function testHandleWhenTheControllerIsAnArray()
196 $dispatcher = new EventDispatcher();
197 $kernel = new HttpKernel($dispatcher, $this->getResolver(array(new Controller(), 'controller')));
199 $this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
202 public function testHandleWhenTheControllerIsAStaticArray()
204 $dispatcher = new EventDispatcher();
205 $kernel = new HttpKernel($dispatcher, $this->getResolver(array('Symfony\Component\HttpKernel\Tests\Controller', 'staticcontroller')));
207 $this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
211 * @expectedException \LogicException
213 public function testHandleWhenTheControllerDoesNotReturnAResponse()
215 $dispatcher = new EventDispatcher();
216 $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { return 'foo'; }));
218 $kernel->handle(new Request());
221 public function testHandleWhenTheControllerDoesNotReturnAResponseButAViewIsRegistered()
223 $dispatcher = new EventDispatcher();
224 $dispatcher->addListener(KernelEvents::VIEW, function ($event) {
225 $event->setResponse(new Response($event->getControllerResult()));
227 $kernel = new HttpKernel($dispatcher, $this->getResolver(function () { return 'foo'; }));
229 $this->assertEquals('foo', $kernel->handle(new Request())->getContent());
232 public function testHandleWithAResponseListener()
234 $dispatcher = new EventDispatcher();
235 $dispatcher->addListener(KernelEvents::RESPONSE, function ($event) {
236 $event->setResponse(new Response('foo'));
238 $kernel = new HttpKernel($dispatcher, $this->getResolver());
240 $this->assertEquals('foo', $kernel->handle(new Request())->getContent());
243 public function testTerminate()
245 $dispatcher = new EventDispatcher();
246 $kernel = new HttpKernel($dispatcher, $this->getResolver());
247 $dispatcher->addListener(KernelEvents::TERMINATE, function ($event) use (&$called, &$capturedKernel, &$capturedRequest, &$capturedResponse) {
249 $capturedKernel = $event->getKernel();
250 $capturedRequest = $event->getRequest();
251 $capturedResponse = $event->getResponse();
254 $kernel->terminate($request = Request::create('/'), $response = new Response());
255 $this->assertTrue($called);
256 $this->assertEquals($kernel, $capturedKernel);
257 $this->assertEquals($request, $capturedRequest);
258 $this->assertEquals($response, $capturedResponse);
261 public function testVerifyRequestStackPushPopDuringHandle()
263 $request = new Request();
265 $stack = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestStack')->setMethods(array('push', 'pop'))->getMock();
266 $stack->expects($this->at(0))->method('push')->with($this->equalTo($request));
267 $stack->expects($this->at(1))->method('pop');
269 $dispatcher = new EventDispatcher();
270 $kernel = new HttpKernel($dispatcher, $this->getResolver(), $stack);
272 $kernel->handle($request, HttpKernelInterface::MASTER_REQUEST);
276 * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
278 public function testInconsistentClientIpsOnMasterRequests()
280 $dispatcher = new EventDispatcher();
281 $dispatcher->addListener(KernelEvents::REQUEST, function ($event) {
282 $event->getRequest()->getClientIp();
285 $kernel = new HttpKernel($dispatcher, $this->getResolver());
287 $request = new Request();
288 $request->setTrustedProxies(array('1.1.1.1'));
289 $request->server->set('REMOTE_ADDR', '1.1.1.1');
290 $request->headers->set('FORWARDED', 'for=2.2.2.2');
291 $request->headers->set('X_FORWARDED_FOR', '3.3.3.3');
293 $kernel->handle($request, $kernel::MASTER_REQUEST, false);
296 protected function getResolver($controller = null)
298 if (null === $controller) {
299 $controller = function () { return new Response('Hello'); };
302 $resolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface')->getMock();
303 $resolver->expects($this->any())
304 ->method('getController')
305 ->will($this->returnValue($controller));
306 $resolver->expects($this->any())
307 ->method('getArguments')
308 ->will($this->returnValue(array()));
313 protected function assertResponseEquals(Response $expected, Response $actual)
315 $expected->setDate($actual->getDate());
316 $this->assertEquals($expected, $actual);
322 public function __invoke()
324 return new Response('foo');
327 public function controller()
329 return new Response('foo');
332 public static function staticController()
334 return new Response('foo');
338 function controller_func()
340 return new Response('foo');