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\DataCollector;
14 use PHPUnit\Framework\TestCase;
15 use Symfony\Component\HttpFoundation\RedirectResponse;
16 use Symfony\Component\HttpFoundation\Session\Session;
17 use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
18 use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
19 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
20 use Symfony\Component\HttpKernel\HttpKernel;
21 use Symfony\Component\HttpKernel\HttpKernelInterface;
22 use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector;
23 use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
24 use Symfony\Component\HttpFoundation\Request;
25 use Symfony\Component\HttpFoundation\Response;
26 use Symfony\Component\HttpFoundation\Cookie;
27 use Symfony\Component\EventDispatcher\EventDispatcher;
28 use Symfony\Component\VarDumper\Cloner\Data;
29 use Symfony\Component\VarDumper\Cloner\VarCloner;
31 class RequestDataCollectorTest extends TestCase
33 public function testCollect()
35 $c = new RequestDataCollector();
37 $c->collect($request = $this->createRequest(), $this->createResponse());
39 $cloner = new VarCloner();
40 $attributes = $c->getRequestAttributes();
42 $this->assertSame('request', $c->getName());
43 $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestHeaders());
44 $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestServer());
45 $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestCookies());
46 $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $attributes);
47 $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestRequest());
48 $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestQuery());
49 $this->assertSame('html', $c->getFormat());
50 $this->assertEquals('foobar', $c->getRoute());
51 $this->assertEquals(array('name' => $cloner->cloneVar(array('name' => 'foo'))->seek('name')), $c->getRouteParams());
52 $this->assertSame(array(), $c->getSessionAttributes());
53 $this->assertSame('en', $c->getLocale());
54 $this->assertEquals($cloner->cloneVar($request->attributes->get('resource')), $attributes->get('resource'));
55 $this->assertEquals($cloner->cloneVar($request->attributes->get('object')), $attributes->get('object'));
57 $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getResponseHeaders());
58 $this->assertSame('OK', $c->getStatusText());
59 $this->assertSame(200, $c->getStatusCode());
60 $this->assertSame('application/json', $c->getContentType());
63 public function testCollectWithoutRouteParams()
65 $request = $this->createRequest(array());
67 $c = new RequestDataCollector();
68 $c->collect($request, $this->createResponse());
70 $this->assertEquals(array(), $c->getRouteParams());
73 public function testKernelResponseDoesNotStartSession()
75 $kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
76 $request = new Request();
77 $session = new Session(new MockArraySessionStorage());
78 $request->setSession($session);
79 $response = new Response();
81 $c = new RequestDataCollector();
82 $c->onKernelResponse(new FilterResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response));
84 $this->assertFalse($session->isStarted());
88 * @dataProvider provideControllerCallables
90 public function testControllerInspection($name, $callable, $expected)
92 $c = new RequestDataCollector();
93 $request = $this->createRequest();
94 $response = $this->createResponse();
95 $this->injectController($c, $callable, $request);
96 $c->collect($request, $response);
98 $this->assertSame($expected, $c->getController(), sprintf('Testing: %s', $name));
101 public function provideControllerCallables()
103 // make sure we always match the line number
104 $r1 = new \ReflectionMethod($this, 'testControllerInspection');
105 $r2 = new \ReflectionMethod($this, 'staticControllerMethod');
106 $r3 = new \ReflectionClass($this);
108 // test name, callable, expected
111 '"Regular" callable',
112 array($this, 'testControllerInspection'),
114 'class' => __NAMESPACE__.'\RequestDataCollectorTest',
115 'method' => 'testControllerInspection',
117 'line' => $r1->getStartLine(),
123 function () { return 'foo'; },
125 'class' => __NAMESPACE__.'\{closure}',
128 'line' => __LINE__ - 5,
133 'Static callback as string',
134 __NAMESPACE__.'\RequestDataCollectorTest::staticControllerMethod',
136 'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
137 'method' => 'staticControllerMethod',
139 'line' => $r2->getStartLine(),
144 'Static callable with instance',
145 array($this, 'staticControllerMethod'),
147 'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
148 'method' => 'staticControllerMethod',
150 'line' => $r2->getStartLine(),
155 'Static callable with class name',
156 array('Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest', 'staticControllerMethod'),
158 'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
159 'method' => 'staticControllerMethod',
161 'line' => $r2->getStartLine(),
166 'Callable with instance depending on __call()',
167 array($this, 'magicMethod'),
169 'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
170 'method' => 'magicMethod',
177 'Callable with class name depending on __callStatic()',
178 array('Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest', 'magicMethod'),
180 'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
181 'method' => 'magicMethod',
188 'Invokable controller',
191 'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
194 'line' => $r3->getStartLine(),
200 public function testItIgnoresInvalidCallables()
202 $request = $this->createRequestWithSession();
203 $response = new RedirectResponse('/');
205 $c = new RequestDataCollector();
206 $c->collect($request, $response);
208 $this->assertSame('n/a', $c->getController());
211 protected function createRequest($routeParams = array('name' => 'foo'))
213 $request = Request::create('http://test.com/foo?bar=baz');
214 $request->attributes->set('foo', 'bar');
215 $request->attributes->set('_route', 'foobar');
216 $request->attributes->set('_route_params', $routeParams);
217 $request->attributes->set('resource', fopen(__FILE__, 'r'));
218 $request->attributes->set('object', new \stdClass());
223 private function createRequestWithSession()
225 $request = $this->createRequest();
226 $request->attributes->set('_controller', 'Foo::bar');
227 $request->setSession(new Session(new MockArraySessionStorage()));
228 $request->getSession()->start();
233 protected function createResponse()
235 $response = new Response();
236 $response->setStatusCode(200);
237 $response->headers->set('Content-Type', 'application/json');
238 $response->headers->set('X-Foo-Bar', null);
239 $response->headers->setCookie(new Cookie('foo', 'bar', 1, '/foo', 'localhost', true, true));
240 $response->headers->setCookie(new Cookie('bar', 'foo', new \DateTime('@946684800')));
241 $response->headers->setCookie(new Cookie('bazz', 'foo', '2000-12-12'));
247 * Inject the given controller callable into the data collector.
249 protected function injectController($collector, $controller, $request)
251 $resolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface')->getMock();
252 $httpKernel = new HttpKernel(new EventDispatcher(), $resolver, null, $this->getMockBuilder(ArgumentResolverInterface::class)->getMock());
253 $event = new FilterControllerEvent($httpKernel, $controller, $request, HttpKernelInterface::MASTER_REQUEST);
254 $collector->onKernelController($event);
258 * Dummy method used as controller callable.
260 public static function staticControllerMethod()
262 throw new \LogicException('Unexpected method call');
266 * Magic method to allow non existing methods to be called and delegated.
268 public function __call($method, $args)
270 throw new \LogicException('Unexpected method call');
274 * Magic method to allow non existing methods to be called and delegated.
276 public static function __callStatic($method, $args)
278 throw new \LogicException('Unexpected method call');
281 public function __invoke()
283 throw new \LogicException('Unexpected method call');