diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php index c55c67e537a0..d9e20878e5ab 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php @@ -11,19 +11,110 @@ namespace Symfony\Bundle\WebProfilerBundle\Tests\Controller; -use PHPUnit\Framework\TestCase; +use Symfony\Bundle\FrameworkBundle\Client; +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController; use Symfony\Bundle\WebProfilerBundle\Csp\ContentSecurityPolicyHandler; +use Symfony\Bundle\WebProfilerBundle\Tests\Functional\WebProfilerBundleKernel; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Profiler\Profile; -class ProfilerControllerTest extends TestCase +class ProfilerControllerTest extends WebTestCase { + public function testHomeActionWithProfilerDisabled() + { + $this->expectException(NotFoundHttpException::class); + $this->expectExceptionMessage('The profiler must be enabled.'); + + $urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock(); + $twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock(); + + $controller = new ProfilerController($urlGenerator, null, $twig, []); + $controller->homeAction(); + } + + public function testHomeActionRedirect() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + + $client->request('GET', '/_profiler/'); + + $this->assertSame(302, $client->getResponse()->getStatusCode()); + $this->assertSame('/_profiler/empty/search/results?limit=10', $client->getResponse()->getTargetUrl()); + } + + public function testPanelActionWithLatestTokenWhenNoTokensExist() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + + $client->request('GET', '/_profiler/latest'); + + $this->assertStringContainsString('No profiles found.', $client->getResponse()->getContent()); + } + + public function testPanelActionWithLatestToken() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + + $client->request('GET', '/'); + $client->request('GET', '/_profiler/latest'); + + $this->assertStringContainsString('kernel:homepageController', $client->getResponse()->getContent()); + } + + public function testPanelActionWithoutValidToken() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + + $client->request('GET', '/_profiler/this-token-does-not-exist'); + + $this->assertStringContainsString('Token "this-token-does-not-exist" not found.', $client->getResponse()->getContent()); + } + + public function testPanelActionWithWrongPanel() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + + $client->request('GET', '/'); + $client->request('GET', '/_profiler/latest?panel=this-panel-does-not-exist'); + + $this->assertSame(404, $client->getResponse()->getStatusCode()); + } + + public function testPanelActionWithValidPanelAndToken() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + + $client->request('GET', '/'); + $crawler = $client->request('GET', '/_profiler/latest?panel=router'); + + $this->assertSame('_', $crawler->filter('.metrics .metric .value')->eq(0)->text()); + $this->assertSame('12', $crawler->filter('.metrics .metric .value')->eq(1)->text()); + } + + public function testToolbarActionWithProfilerDisabled() + { + $this->expectException(NotFoundHttpException::class); + $this->expectExceptionMessage('The profiler must be enabled.'); + + $urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock(); + $twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock(); + + $controller = new ProfilerController($urlGenerator, null, $twig, []); + $controller->toolbarAction(Request::create('/_wdt/foo-token'), null); + } + /** * @dataProvider getEmptyTokenCases */ - public function testEmptyToken($token) + public function testToolbarActionWithEmptyToken($token) { $urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock(); $twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock(); @@ -111,10 +202,36 @@ public function testReturns404onTokenNotFound($withCsp) $this->assertEquals(404, $response->getStatusCode()); } + public function testSearchBarActionWithProfilerDisabled() + { + $this->expectException(NotFoundHttpException::class); + $this->expectExceptionMessage('The profiler must be enabled.'); + + $urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock(); + $twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock(); + + $controller = new ProfilerController($urlGenerator, null, $twig, []); + $controller->searchBarAction(Request::create('/_profiler/search_bar')); + } + + public function testSearchBarActionDefaultPage() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + + $crawler = $client->request('GET', '/_profiler/search_bar'); + + $this->assertSame(200, $client->getResponse()->getStatusCode()); + + foreach (['ip', 'status_code', 'url', 'token', 'start', 'end'] as $searchCriteria) { + $this->assertSame('', $crawler->filter(sprintf('form input[name="%s"]', $searchCriteria))->text()); + } + } + /** * @dataProvider provideCspVariants */ - public function testSearchResult($withCsp) + public function testSearchResultsAction($withCsp) { $twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock(); $profiler = $this @@ -177,6 +294,67 @@ public function testSearchResult($withCsp) $this->assertEquals(200, $response->getStatusCode()); } + public function testSearchActionWithProfilerDisabled() + { + $this->expectException(NotFoundHttpException::class); + $this->expectExceptionMessage('The profiler must be enabled.'); + + $urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock(); + $twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock(); + + $controller = new ProfilerController($urlGenerator, null, $twig, []); + $controller->searchBarAction(Request::create('/_profiler/search')); + } + + public function testSearchActionWithToken() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + + $client->request('GET', '/'); + $token = $client->getResponse()->headers->get('x-debug-token'); + $client->request('GET', '/_profiler/search?token='.$token); + + $this->assertSame(302, $client->getResponse()->getStatusCode()); + $this->assertSame('/_profiler/'.$token, $client->getResponse()->getTargetUrl()); + } + + public function testSearchActionWithoutToken() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + $client->followRedirects(); + + $client->request('GET', '/'); + $token = $client->getResponse()->headers->get('x-debug-token'); + $client->request('GET', '/_profiler/search?ip=&method=GET&status_code=&url=&token=&start=&end=&limit=10'); + + $this->assertStringContainsString('1 results found', $client->getResponse()->getContent()); + $this->assertStringContainsString(sprintf('%s', $token, $token), $client->getResponse()->getContent()); + } + + public function testPhpinfoActionWithProfilerDisabled() + { + $this->expectException(NotFoundHttpException::class); + $this->expectExceptionMessage('The profiler must be enabled.'); + + $urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock(); + $twig = $this->getMockBuilder('Twig\Environment')->disableOriginalConstructor()->getMock(); + + $controller = new ProfilerController($urlGenerator, null, $twig, []); + $controller->phpinfoAction(Request::create('/_profiler/phpinfo')); + } + + public function testPhpinfoAction() + { + $kernel = new WebProfilerBundleKernel(); + $client = new Client($kernel); + + $client->request('GET', '/_profiler/phpinfo'); + + $this->assertStringContainsString('PHP License', $client->getResponse()->getContent()); + } + public function provideCspVariants() { return [ diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php new file mode 100644 index 000000000000..5470ca7dc685 --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Functional/WebProfilerBundleKernel.php @@ -0,0 +1,80 @@ +name) { + $this->name = parent::getName().substr(md5(__CLASS__), -16); + } + + return $this->name; + } + + public function registerBundles() + { + return [ + new FrameworkBundle(), + new TwigBundle(), + new WebProfilerBundle(), + ]; + } + + protected function configureRoutes(RouteCollectionBuilder $routes) + { + $routes->import(__DIR__.'/../../Resources/config/routing/profiler.xml', '/_profiler'); + $routes->import(__DIR__.'/../../Resources/config/routing/wdt.xml', '/_wdt'); + $routes->add('/', 'kernel:homepageController'); + } + + protected function configureContainer(ContainerBuilder $containerBuilder, LoaderInterface $loader) + { + $containerBuilder->loadFromExtension('framework', [ + 'secret' => 'foo-secret', + 'profiler' => ['only_exceptions' => false], + 'session' => ['storage_id' => 'session.storage.mock_file'], + ]); + + $containerBuilder->loadFromExtension('web_profiler', [ + 'toolbar' => true, + 'intercept_redirects' => false, + ]); + } + + public function getCacheDir() + { + return sys_get_temp_dir().'/cache-'.spl_object_hash($this); + } + + public function getLogDir() + { + return sys_get_temp_dir().'/log-'.spl_object_hash($this); + } + + public function homepageController() + { + return new Response('Homepage Controller.'); + } +} diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index c82ef0fe0093..6f254c67cc48 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -17,21 +17,22 @@ ], "require": { "php": "^5.5.9|>=7.0.8", + "symfony/config": "~3.4|~4.0", "symfony/http-kernel": "~3.4.25|^4.2.6", "symfony/polyfill-php70": "~1.0", - "symfony/routing": "~2.8|~3.0|~4.0", - "symfony/twig-bundle": "~2.8|~3.0|~4.0", + "symfony/routing": "~3.4.7|~4.0", + "symfony/twig-bundle": "~3.4|~4.0", "symfony/var-dumper": "~3.3|~4.0", "twig/twig": "~1.34|~2.4" }, "require-dev": { - "symfony/config": "~3.4|~4.0", - "symfony/console": "~2.8|~3.0|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/stopwatch": "~2.8|~3.0|~4.0" + "symfony/browser-kit": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/css-selector": "~3.4|~4.0", + "symfony/framework-bundle": "~3.4|~4.0", + "symfony/stopwatch": "~3.4|~4.0" }, "conflict": { - "symfony/config": "<3.4", "symfony/dependency-injection": "<3.4", "symfony/event-dispatcher": "<3.3.1", "symfony/var-dumper": "<3.3"