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\Fragment;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\EventDispatcher\EventDispatcher;
16 use Symfony\Component\HttpFoundation\Request;
17 use Symfony\Component\HttpFoundation\RequestStack;
18 use Symfony\Component\HttpFoundation\Response;
19 use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
20 use Symfony\Component\HttpKernel\Controller\ControllerReference;
21 use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
22 use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer;
23 use Symfony\Component\HttpKernel\HttpKernel;
24 use Symfony\Component\HttpKernel\KernelEvents;
26 class InlineFragmentRendererTest extends TestCase
28 public function testRender()
30 $strategy = new InlineFragmentRenderer($this->getKernel($this->returnValue(new Response('foo'))));
32 $this->assertEquals('foo', $strategy->render('/', Request::create('/'))->getContent());
35 public function testRenderWithControllerReference()
37 $strategy = new InlineFragmentRenderer($this->getKernel($this->returnValue(new Response('foo'))));
39 $this->assertEquals('foo', $strategy->render(new ControllerReference('main_controller', array(), array()), Request::create('/'))->getContent());
42 public function testRenderWithObjectsAsAttributes()
44 $object = new \stdClass();
46 $subRequest = Request::create('/_fragment?_path=_format%3Dhtml%26_locale%3Den%26_controller%3Dmain_controller');
47 $subRequest->attributes->replace(array('object' => $object, '_format' => 'html', '_controller' => 'main_controller', '_locale' => 'en'));
48 $subRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
49 $subRequest->headers->set('forwarded', array('for="127.0.0.1";host="localhost";proto=http'));
50 $subRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
51 $subRequest->server->set('HTTP_FORWARDED', 'for="127.0.0.1";host="localhost";proto=http');
53 $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($subRequest));
55 $this->assertSame('foo', $strategy->render(new ControllerReference('main_controller', array('object' => $object), array()), Request::create('/'))->getContent());
61 public function testRenderWithObjectsAsAttributesPassedAsObjectsInTheControllerLegacy()
63 $resolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver')->setMethods(array('getController'))->getMock();
65 ->expects($this->once())
66 ->method('getController')
67 ->will($this->returnValue(function (\stdClass $object, Bar $object1) {
68 return new Response($object1->getBar());
72 $kernel = new HttpKernel(new EventDispatcher(), $resolver, new RequestStack());
73 $renderer = new InlineFragmentRenderer($kernel);
75 $response = $renderer->render(new ControllerReference('main_controller', array('object' => new \stdClass(), 'object1' => new Bar()), array()), Request::create('/'));
76 $this->assertEquals('bar', $response->getContent());
82 public function testRenderWithObjectsAsAttributesPassedAsObjectsInTheController()
84 $resolver = $this->getMockBuilder(ControllerResolverInterface::class)->getMock();
86 ->expects($this->once())
87 ->method('getController')
88 ->will($this->returnValue(function (\stdClass $object, Bar $object1) {
89 return new Response($object1->getBar());
93 $kernel = new HttpKernel(new EventDispatcher(), $resolver, new RequestStack(), new ArgumentResolver());
94 $renderer = new InlineFragmentRenderer($kernel);
96 $response = $renderer->render(new ControllerReference('main_controller', array('object' => new \stdClass(), 'object1' => new Bar()), array()), Request::create('/'));
97 $this->assertEquals('bar', $response->getContent());
100 public function testRenderWithTrustedHeaderDisabled()
102 Request::setTrustedProxies(array(), 0);
104 $expectedSubRequest = Request::create('/');
105 $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
106 $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
108 $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
109 $this->assertSame('foo', $strategy->render('/', Request::create('/'))->getContent());
111 Request::setTrustedProxies(array(), -1);
115 * @expectedException \RuntimeException
117 public function testRenderExceptionNoIgnoreErrors()
119 $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
120 $dispatcher->expects($this->never())->method('dispatch');
122 $strategy = new InlineFragmentRenderer($this->getKernel($this->throwException(new \RuntimeException('foo'))), $dispatcher);
124 $this->assertEquals('foo', $strategy->render('/', Request::create('/'))->getContent());
127 public function testRenderExceptionIgnoreErrors()
129 $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
130 $dispatcher->expects($this->once())->method('dispatch')->with(KernelEvents::EXCEPTION);
132 $strategy = new InlineFragmentRenderer($this->getKernel($this->throwException(new \RuntimeException('foo'))), $dispatcher);
134 $this->assertEmpty($strategy->render('/', Request::create('/'), array('ignore_errors' => true))->getContent());
137 public function testRenderExceptionIgnoreErrorsWithAlt()
139 $strategy = new InlineFragmentRenderer($this->getKernel($this->onConsecutiveCalls(
140 $this->throwException(new \RuntimeException('foo')),
141 $this->returnValue(new Response('bar'))
144 $this->assertEquals('bar', $strategy->render('/', Request::create('/'), array('ignore_errors' => true, 'alt' => '/foo'))->getContent());
147 private function getKernel($returnValue)
149 $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
151 ->expects($this->any())
159 public function testExceptionInSubRequestsDoesNotMangleOutputBuffers()
161 $controllerResolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface')->getMock();
163 ->expects($this->once())
164 ->method('getController')
165 ->will($this->returnValue(function () {
168 throw new \RuntimeException();
172 $argumentResolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolverInterface')->getMock();
174 ->expects($this->once())
175 ->method('getArguments')
176 ->will($this->returnValue(array()))
179 $kernel = new HttpKernel(new EventDispatcher(), $controllerResolver, new RequestStack(), $argumentResolver);
180 $renderer = new InlineFragmentRenderer($kernel);
182 // simulate a main request with output buffering
186 // simulate a sub-request with output buffering and an exception
187 $renderer->render('/', Request::create('/'), array('ignore_errors' => true));
189 $this->assertEquals('Foo', ob_get_clean());
192 public function testLocaleAndFormatAreIsKeptInSubrequest()
194 $expectedSubRequest = Request::create('/');
195 $expectedSubRequest->attributes->set('_format', 'foo');
196 $expectedSubRequest->setLocale('fr');
197 if (Request::HEADER_X_FORWARDED_FOR & Request::getTrustedHeaderSet()) {
198 $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
199 $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
201 $expectedSubRequest->headers->set('forwarded', array('for="127.0.0.1";host="localhost";proto=http'));
202 $expectedSubRequest->server->set('HTTP_FORWARDED', 'for="127.0.0.1";host="localhost";proto=http');
204 $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
206 $request = Request::create('/');
207 $request->attributes->set('_format', 'foo');
208 $request->setLocale('fr');
209 $strategy->render('/', $request);
212 public function testESIHeaderIsKeptInSubrequest()
214 $expectedSubRequest = Request::create('/');
215 $expectedSubRequest->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
217 if (Request::HEADER_X_FORWARDED_FOR & Request::getTrustedHeaderSet()) {
218 $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
219 $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
221 $expectedSubRequest->headers->set('forwarded', array('for="127.0.0.1";host="localhost";proto=http'));
222 $expectedSubRequest->server->set('HTTP_FORWARDED', 'for="127.0.0.1";host="localhost";proto=http');
224 $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
226 $request = Request::create('/');
227 $request->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
228 $strategy->render('/', $request);
231 public function testESIHeaderIsKeptInSubrequestWithTrustedHeaderDisabled()
233 Request::setTrustedProxies(array(), Request::HEADER_FORWARDED);
235 $this->testESIHeaderIsKeptInSubrequest();
237 Request::setTrustedProxies(array(), -1);
240 public function testHeadersPossiblyResultingIn304AreNotAssignedToSubrequest()
242 $expectedSubRequest = Request::create('/');
243 $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
244 $expectedSubRequest->headers->set('forwarded', array('for="127.0.0.1";host="localhost";proto=http'));
245 $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
246 $expectedSubRequest->server->set('HTTP_FORWARDED', 'for="127.0.0.1";host="localhost";proto=http');
248 $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
249 $request = Request::create('/', 'GET', array(), array(), array(), array('HTTP_IF_MODIFIED_SINCE' => 'Fri, 01 Jan 2016 00:00:00 GMT', 'HTTP_IF_NONE_MATCH' => '*'));
250 $strategy->render('/', $request);
253 public function testFirstTrustedProxyIsSetAsRemote()
255 Request::setTrustedProxies(array('1.1.1.1'), -1);
257 $expectedSubRequest = Request::create('/');
258 $expectedSubRequest->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
259 $expectedSubRequest->server->set('REMOTE_ADDR', '127.0.0.1');
260 $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
261 $expectedSubRequest->headers->set('forwarded', array('for="127.0.0.1";host="localhost";proto=http'));
262 $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
263 $expectedSubRequest->server->set('HTTP_FORWARDED', 'for="127.0.0.1";host="localhost";proto=http');
265 $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
267 $request = Request::create('/');
268 $request->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
269 $strategy->render('/', $request);
271 Request::setTrustedProxies(array(), -1);
274 public function testIpAddressOfRangedTrustedProxyIsSetAsRemote()
276 $expectedSubRequest = Request::create('/');
277 $expectedSubRequest->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
278 $expectedSubRequest->server->set('REMOTE_ADDR', '127.0.0.1');
279 $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
280 $expectedSubRequest->headers->set('forwarded', array('for="127.0.0.1";host="localhost";proto=http'));
281 $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
282 $expectedSubRequest->server->set('HTTP_FORWARDED', 'for="127.0.0.1";host="localhost";proto=http');
284 Request::setTrustedProxies(array('1.1.1.1/24'), -1);
286 $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
288 $request = Request::create('/');
289 $request->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
290 $strategy->render('/', $request);
292 Request::setTrustedProxies(array(), -1);
296 * Creates a Kernel expecting a request equals to $request
297 * Allows delta in comparison in case REQUEST_TIME changed by 1 second.
299 private function getKernelExpectingRequest(Request $request, $strict = false)
301 $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
303 ->expects($this->once())
305 ->with($this->equalTo($request, 1))
306 ->willReturn(new Response('foo'));
316 public function getBar()