InlineFragmentRendererTest.php 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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\Fragment;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\HttpFoundation\RequestStack;
  13. use Symfony\Component\HttpKernel\Controller\ControllerReference;
  14. use Symfony\Component\HttpKernel\HttpKernel;
  15. use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer;
  16. use Symfony\Component\HttpKernel\KernelEvents;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use Symfony\Component\EventDispatcher\EventDispatcher;
  20. class InlineFragmentRendererTest extends TestCase
  21. {
  22. public function testRender()
  23. {
  24. $strategy = new InlineFragmentRenderer($this->getKernel($this->returnValue(new Response('foo'))));
  25. $this->assertEquals('foo', $strategy->render('/', Request::create('/'))->getContent());
  26. }
  27. public function testRenderWithControllerReference()
  28. {
  29. $strategy = new InlineFragmentRenderer($this->getKernel($this->returnValue(new Response('foo'))));
  30. $this->assertEquals('foo', $strategy->render(new ControllerReference('main_controller', array(), array()), Request::create('/'))->getContent());
  31. }
  32. public function testRenderWithObjectsAsAttributes()
  33. {
  34. $object = new \stdClass();
  35. $subRequest = Request::create('/_fragment?_path=_format%3Dhtml%26_locale%3Den%26_controller%3Dmain_controller');
  36. $subRequest->attributes->replace(array('object' => $object, '_format' => 'html', '_controller' => 'main_controller', '_locale' => 'en'));
  37. $subRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
  38. $subRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
  39. $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($subRequest));
  40. $this->assertSame('foo', $strategy->render(new ControllerReference('main_controller', array('object' => $object), array()), Request::create('/'))->getContent());
  41. }
  42. public function testRenderWithTrustedHeaderDisabled()
  43. {
  44. Request::setTrustedProxies(array(), 0);
  45. $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest(Request::create('/')));
  46. $this->assertSame('foo', $strategy->render('/', Request::create('/'))->getContent());
  47. Request::setTrustedProxies(array(), -1);
  48. }
  49. /**
  50. * @expectedException \RuntimeException
  51. */
  52. public function testRenderExceptionNoIgnoreErrors()
  53. {
  54. $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
  55. $dispatcher->expects($this->never())->method('dispatch');
  56. $strategy = new InlineFragmentRenderer($this->getKernel($this->throwException(new \RuntimeException('foo'))), $dispatcher);
  57. $this->assertEquals('foo', $strategy->render('/', Request::create('/'))->getContent());
  58. }
  59. public function testRenderExceptionIgnoreErrors()
  60. {
  61. $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
  62. $dispatcher->expects($this->once())->method('dispatch')->with(KernelEvents::EXCEPTION);
  63. $strategy = new InlineFragmentRenderer($this->getKernel($this->throwException(new \RuntimeException('foo'))), $dispatcher);
  64. $this->assertEmpty($strategy->render('/', Request::create('/'), array('ignore_errors' => true))->getContent());
  65. }
  66. public function testRenderExceptionIgnoreErrorsWithAlt()
  67. {
  68. $strategy = new InlineFragmentRenderer($this->getKernel($this->onConsecutiveCalls(
  69. $this->throwException(new \RuntimeException('foo')),
  70. $this->returnValue(new Response('bar'))
  71. )));
  72. $this->assertEquals('bar', $strategy->render('/', Request::create('/'), array('ignore_errors' => true, 'alt' => '/foo'))->getContent());
  73. }
  74. private function getKernel($returnValue)
  75. {
  76. $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
  77. $kernel
  78. ->expects($this->any())
  79. ->method('handle')
  80. ->will($returnValue)
  81. ;
  82. return $kernel;
  83. }
  84. public function testExceptionInSubRequestsDoesNotMangleOutputBuffers()
  85. {
  86. $controllerResolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface')->getMock();
  87. $controllerResolver
  88. ->expects($this->once())
  89. ->method('getController')
  90. ->will($this->returnValue(function () {
  91. ob_start();
  92. echo 'bar';
  93. throw new \RuntimeException();
  94. }))
  95. ;
  96. $argumentResolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolverInterface')->getMock();
  97. $argumentResolver
  98. ->expects($this->once())
  99. ->method('getArguments')
  100. ->will($this->returnValue(array()))
  101. ;
  102. $kernel = new HttpKernel(new EventDispatcher(), $controllerResolver, new RequestStack(), $argumentResolver);
  103. $renderer = new InlineFragmentRenderer($kernel);
  104. // simulate a main request with output buffering
  105. ob_start();
  106. echo 'Foo';
  107. // simulate a sub-request with output buffering and an exception
  108. $renderer->render('/', Request::create('/'), array('ignore_errors' => true));
  109. $this->assertEquals('Foo', ob_get_clean());
  110. }
  111. public function testESIHeaderIsKeptInSubrequest()
  112. {
  113. $expectedSubRequest = Request::create('/');
  114. $expectedSubRequest->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
  115. if (Request::HEADER_X_FORWARDED_FOR & Request::getTrustedHeaderSet()) {
  116. $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
  117. $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
  118. }
  119. $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
  120. $request = Request::create('/');
  121. $request->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
  122. $strategy->render('/', $request);
  123. }
  124. public function testESIHeaderIsKeptInSubrequestWithTrustedHeaderDisabled()
  125. {
  126. Request::setTrustedProxies(array(), 0);
  127. $this->testESIHeaderIsKeptInSubrequest();
  128. Request::setTrustedProxies(array(), -1);
  129. }
  130. public function testHeadersPossiblyResultingIn304AreNotAssignedToSubrequest()
  131. {
  132. $expectedSubRequest = Request::create('/');
  133. if (Request::HEADER_X_FORWARDED_FOR & Request::getTrustedHeaderSet()) {
  134. $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
  135. $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
  136. }
  137. $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
  138. $request = Request::create('/', 'GET', array(), array(), array(), array('HTTP_IF_MODIFIED_SINCE' => 'Fri, 01 Jan 2016 00:00:00 GMT', 'HTTP_IF_NONE_MATCH' => '*'));
  139. $strategy->render('/', $request);
  140. }
  141. /**
  142. * Creates a Kernel expecting a request equals to $request
  143. * Allows delta in comparison in case REQUEST_TIME changed by 1 second.
  144. */
  145. private function getKernelExpectingRequest(Request $request, $strict = false)
  146. {
  147. $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
  148. $kernel
  149. ->expects($this->once())
  150. ->method('handle')
  151. ->with($this->equalTo($request, 1))
  152. ->willReturn(new Response('foo'));
  153. return $kernel;
  154. }
  155. }
  156. class Bar
  157. {
  158. public $bar = 'bar';
  159. public function getBar()
  160. {
  161. return $this->bar;
  162. }
  163. }