namespace Symfony\Component\HttpKernel\Tests\DataCollector;
use PHPUnit\Framework\TestCase;
+use Symfony\Component\HttpFoundation\ParameterBag;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Session\Session;
+use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector;
{
$c = new RequestDataCollector();
- $c->collect($this->createRequest(), $this->createResponse());
+ $c->collect($request = $this->createRequest(), $this->createResponse());
+ $c->lateCollect();
$attributes = $c->getRequestAttributes();
$this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $attributes);
$this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestRequest());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestQuery());
+ $this->assertInstanceOf(ParameterBag::class, $c->getResponseCookies());
$this->assertSame('html', $c->getFormat());
- $this->assertSame('foobar', $c->getRoute());
- $this->assertSame(array('name' => 'foo'), $c->getRouteParams());
+ $this->assertEquals('foobar', $c->getRoute());
+ $this->assertEquals(array('name' => 'foo'), $c->getRouteParams());
$this->assertSame(array(), $c->getSessionAttributes());
$this->assertSame('en', $c->getLocale());
- $this->assertRegExp('/Resource\(stream#\d+\)/', $attributes->get('resource'));
- $this->assertSame('Object(stdClass)', $attributes->get('object'));
+ $this->assertContains(__FILE__, $attributes->get('resource'));
+ $this->assertSame('stdClass', $attributes->get('object')->getType());
$this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getResponseHeaders());
$this->assertSame('OK', $c->getStatusText());
$this->assertSame('application/json', $c->getContentType());
}
+ public function testCollectWithoutRouteParams()
+ {
+ $request = $this->createRequest(array());
+
+ $c = new RequestDataCollector();
+ $c->collect($request, $this->createResponse());
+ $c->lateCollect();
+
+ $this->assertEquals(array(), $c->getRouteParams());
+ }
+
/**
- * Test various types of controller callables.
+ * @dataProvider provideControllerCallables
*/
- public function testControllerInspection()
+ public function testControllerInspection($name, $callable, $expected)
+ {
+ $c = new RequestDataCollector();
+ $request = $this->createRequest();
+ $response = $this->createResponse();
+ $this->injectController($c, $callable, $request);
+ $c->collect($request, $response);
+ $c->lateCollect();
+
+ $this->assertSame($expected, $c->getController()->getValue(true), sprintf('Testing: %s', $name));
+ }
+
+ public function provideControllerCallables()
{
// make sure we always match the line number
$r1 = new \ReflectionMethod($this, 'testControllerInspection');
$r2 = new \ReflectionMethod($this, 'staticControllerMethod');
$r3 = new \ReflectionClass($this);
+
// test name, callable, expected
- $controllerTests = array(
+ return array(
array(
'"Regular" callable',
array($this, 'testControllerInspection'),
array(
- 'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
+ 'class' => __NAMESPACE__.'\RequestDataCollectorTest',
'method' => 'testControllerInspection',
'file' => __FILE__,
'line' => $r1->getStartLine(),
array(
'Static callback as string',
- 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest::staticControllerMethod',
- 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest::staticControllerMethod',
+ __NAMESPACE__.'\RequestDataCollectorTest::staticControllerMethod',
+ array(
+ 'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
+ 'method' => 'staticControllerMethod',
+ 'file' => __FILE__,
+ 'line' => $r2->getStartLine(),
+ ),
),
array(
),
),
);
+ }
+
+ public function testItIgnoresInvalidCallables()
+ {
+ $request = $this->createRequestWithSession();
+ $response = new RedirectResponse('/');
$c = new RequestDataCollector();
+ $c->collect($request, $response);
+
+ $this->assertSame('n/a', $c->getController());
+ }
+
+ public function testItAddsRedirectedAttributesWhenRequestContainsSpecificCookie()
+ {
$request = $this->createRequest();
+ $request->cookies->add(array(
+ 'sf_redirect' => '{}',
+ ));
+
+ $kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
+
+ $c = new RequestDataCollector();
+ $c->onKernelResponse(new FilterResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $this->createResponse()));
+
+ $this->assertTrue($request->attributes->get('_redirected'));
+ }
+
+ public function testItSetsARedirectCookieIfTheResponseIsARedirection()
+ {
+ $c = new RequestDataCollector();
+
$response = $this->createResponse();
- foreach ($controllerTests as $controllerTest) {
- $this->injectController($c, $controllerTest[1], $request);
- $c->collect($request, $response);
- $this->assertSame($controllerTest[2], $c->getController(), sprintf('Testing: %s', $controllerTest[0]));
- }
+ $response->setStatusCode(302);
+ $response->headers->set('Location', '/somewhere-else');
+
+ $c->collect($request = $this->createRequest(), $response);
+ $c->lateCollect();
+
+ $cookie = $this->getCookieByName($response, 'sf_redirect');
+
+ $this->assertNotEmpty($cookie->getValue());
+ }
+
+ public function testItCollectsTheRedirectionAndClearTheCookie()
+ {
+ $c = new RequestDataCollector();
+
+ $request = $this->createRequest();
+ $request->attributes->set('_redirected', true);
+ $request->cookies->add(array(
+ 'sf_redirect' => '{"method": "POST"}',
+ ));
+
+ $c->collect($request, $response = $this->createResponse());
+ $c->lateCollect();
+
+ $this->assertEquals('POST', $c->getRedirect()['method']);
+
+ $cookie = $this->getCookieByName($response, 'sf_redirect');
+ $this->assertNull($cookie->getValue());
}
- protected function createRequest()
+ protected function createRequest($routeParams = array('name' => 'foo'))
{
$request = Request::create('http://test.com/foo?bar=baz');
$request->attributes->set('foo', 'bar');
$request->attributes->set('_route', 'foobar');
- $request->attributes->set('_route_params', array('name' => 'foo'));
+ $request->attributes->set('_route_params', $routeParams);
$request->attributes->set('resource', fopen(__FILE__, 'r'));
$request->attributes->set('object', new \stdClass());
return $request;
}
+ private function createRequestWithSession()
+ {
+ $request = $this->createRequest();
+ $request->attributes->set('_controller', 'Foo::bar');
+ $request->setSession(new Session(new MockArraySessionStorage()));
+ $request->getSession()->start();
+
+ return $request;
+ }
+
protected function createResponse()
{
$response = new Response();
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'application/json');
+ $response->headers->set('X-Foo-Bar', null);
$response->headers->setCookie(new Cookie('foo', 'bar', 1, '/foo', 'localhost', true, true));
$response->headers->setCookie(new Cookie('bar', 'foo', new \DateTime('@946684800')));
$response->headers->setCookie(new Cookie('bazz', 'foo', '2000-12-12'));
protected function injectController($collector, $controller, $request)
{
$resolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface')->getMock();
- $httpKernel = new HttpKernel(new EventDispatcher(), $resolver);
+ $httpKernel = new HttpKernel(new EventDispatcher(), $resolver, null, $this->getMockBuilder(ArgumentResolverInterface::class)->getMock());
$event = new FilterControllerEvent($httpKernel, $controller, $request, HttpKernelInterface::MASTER_REQUEST);
$collector->onKernelController($event);
}
{
throw new \LogicException('Unexpected method call');
}
+
+ private function getCookieByName(Response $response, $name)
+ {
+ foreach ($response->headers->getCookies() as $cookie) {
+ if ($cookie->getName() == $name) {
+ return $cookie;
+ }
+ }
+
+ throw new \InvalidArgumentException(sprintf('Cookie named "%s" is not in response', $name));
+ }
}