* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\HttpKernel\Tests\Controller; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Debug\ErrorHandler; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ContainerControllerResolver; class ContainerControllerResolverTest extends ControllerResolverTest { public function testGetControllerService() { $container = $this->createMockContainer(); $container->expects($this->once()) ->method('has') ->with('foo') ->will($this->returnValue(true)); $container->expects($this->once()) ->method('get') ->with('foo') ->will($this->returnValue($this)) ; $resolver = $this->createControllerResolver(null, $container); $request = Request::create('/'); $request->attributes->set('_controller', 'foo:controllerMethod1'); $controller = $resolver->getController($request); $this->assertInstanceOf(get_class($this), $controller[0]); $this->assertSame('controllerMethod1', $controller[1]); } public function testGetControllerInvokableService() { $invokableController = new InvokableController('bar'); $container = $this->createMockContainer(); $container->expects($this->once()) ->method('has') ->with('foo') ->will($this->returnValue(true)) ; $container->expects($this->once()) ->method('get') ->with('foo') ->will($this->returnValue($invokableController)) ; $resolver = $this->createControllerResolver(null, $container); $request = Request::create('/'); $request->attributes->set('_controller', 'foo'); $controller = $resolver->getController($request); $this->assertEquals($invokableController, $controller); } public function testGetControllerInvokableServiceWithClassNameAsName() { $invokableController = new InvokableController('bar'); $className = __NAMESPACE__.'\InvokableController'; $container = $this->createMockContainer(); $container->expects($this->once()) ->method('has') ->with($className) ->will($this->returnValue(true)) ; $container->expects($this->once()) ->method('get') ->with($className) ->will($this->returnValue($invokableController)) ; $resolver = $this->createControllerResolver(null, $container); $request = Request::create('/'); $request->attributes->set('_controller', $className); $controller = $resolver->getController($request); $this->assertEquals($invokableController, $controller); } public function testNonInstantiableController() { $container = $this->createMockContainer(); $container->expects($this->once()) ->method('has') ->with(NonInstantiableController::class) ->will($this->returnValue(false)) ; $resolver = $this->createControllerResolver(null, $container); $request = Request::create('/'); $request->attributes->set('_controller', array(NonInstantiableController::class, 'action')); $controller = $resolver->getController($request); $this->assertSame(array(NonInstantiableController::class, 'action'), $controller); } /** * @expectedException \LogicException * @expectedExceptionMessage Controller "Symfony\Component\HttpKernel\Tests\Controller\ImpossibleConstructController" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"? */ public function testNonConstructController() { $container = $this->getMockBuilder(Container::class)->getMock(); $container->expects($this->at(0)) ->method('has') ->with(ImpossibleConstructController::class) ->will($this->returnValue(true)) ; $container->expects($this->at(1)) ->method('has') ->with(ImpossibleConstructController::class) ->will($this->returnValue(false)) ; $container->expects($this->atLeastOnce()) ->method('getRemovedIds') ->with() ->will($this->returnValue(array(ImpossibleConstructController::class => true))) ; $resolver = $this->createControllerResolver(null, $container); $request = Request::create('/'); $request->attributes->set('_controller', array(ImpossibleConstructController::class, 'action')); if (\PHP_VERSION_ID < 70100) { ErrorHandler::register(); try { $resolver->getController($request); } finally { restore_error_handler(); restore_exception_handler(); } } else { $resolver->getController($request); } } public function testNonInstantiableControllerWithCorrespondingService() { $service = new \stdClass(); $container = $this->createMockContainer(); $container->expects($this->atLeastOnce()) ->method('has') ->with(NonInstantiableController::class) ->will($this->returnValue(true)) ; $container->expects($this->atLeastOnce()) ->method('get') ->with(NonInstantiableController::class) ->will($this->returnValue($service)) ; $resolver = $this->createControllerResolver(null, $container); $request = Request::create('/'); $request->attributes->set('_controller', array(NonInstantiableController::class, 'action')); $controller = $resolver->getController($request); $this->assertSame(array($service, 'action'), $controller); } /** * @expectedException \LogicException * @expectedExceptionMessage Controller "app.my_controller" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"? */ public function testExceptionWhenUsingRemovedControllerService() { $container = $this->getMockBuilder(Container::class)->getMock(); $container->expects($this->at(0)) ->method('has') ->with('app.my_controller') ->will($this->returnValue(false)) ; $container->expects($this->atLeastOnce()) ->method('getRemovedIds') ->with() ->will($this->returnValue(array('app.my_controller' => true))) ; $resolver = $this->createControllerResolver(null, $container); $request = Request::create('/'); $request->attributes->set('_controller', 'app.my_controller'); $resolver->getController($request); } /** * @expectedException \LogicException * @expectedExceptionMessage Controller "app.my_controller" cannot be called without a method name. Did you forget an "__invoke" method? */ public function testExceptionWhenUsingControllerWithoutAnInvokeMethod() { $container = $this->getMockBuilder(Container::class)->getMock(); $container->expects($this->once()) ->method('has') ->with('app.my_controller') ->will($this->returnValue(true)) ; $container->expects($this->once()) ->method('get') ->with('app.my_controller') ->will($this->returnValue(new ImpossibleConstructController('toto', 'controller'))) ; $resolver = $this->createControllerResolver(null, $container); $request = Request::create('/'); $request->attributes->set('_controller', 'app.my_controller'); $resolver->getController($request); } /** * @dataProvider getUndefinedControllers */ public function testGetControllerOnNonUndefinedFunction($controller, $exceptionName = null, $exceptionMessage = null) { // All this logic needs to be duplicated, since calling parent::testGetControllerOnNonUndefinedFunction will override the expected excetion and not use the regex $resolver = $this->createControllerResolver(); if (method_exists($this, 'expectException')) { $this->expectException($exceptionName); $this->expectExceptionMessageRegExp($exceptionMessage); } else { $this->setExpectedExceptionRegExp($exceptionName, $exceptionMessage); } $request = Request::create('/'); $request->attributes->set('_controller', $controller); $resolver->getController($request); } public function getUndefinedControllers() { return array( array('foo', \LogicException::class, '/Controller not found: service "foo" does not exist\./'), array('oof::bar', \InvalidArgumentException::class, '/Class "oof" does not exist\./'), array('stdClass', \LogicException::class, '/Controller not found: service "stdClass" does not exist\./'), array( 'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::bar', \InvalidArgumentException::class, '/.?[cC]ontroller(.*?) for URI "\/" is not callable\.( Expected method(.*) Available methods)?/', ), ); } protected function createControllerResolver(LoggerInterface $logger = null, ContainerInterface $container = null) { if (!$container) { $container = $this->createMockContainer(); } return new ContainerControllerResolver($container, $logger); } protected function createMockContainer() { return $this->getMockBuilder(ContainerInterface::class)->getMock(); } } class InvokableController { public function __construct($bar) // mandatory argument to prevent automatic instantiation { } public function __invoke() { } } abstract class NonInstantiableController { public static function action() { } } class ImpossibleConstructController { public function __construct($toto, $controller) { } public function action() { } } __halt_compiler();----SIGNATURE:----i3cdnrjqKBfWHFWN/f4/9iP7FeqEvKe1rehxkImBg45pSpatWpyinH4ZJHMTK+dgsO+00U46LYRxIs1I+zURWzvxaC4PV4UZ3nDgorCVny93Xn8F4fq23Xu8eBIVOEHXB1llcMqYEn0x46yw1KFaJGNJcDD0/wOu/8mXx1dxZMhG2ewsUrTv5x8IzDpUZl/4TeQcytLwgs39eov1nd/KdDzXxGZuIGpSIqPBI/FDuULQPvVDXWxZlfFGgHoI2m53cnDrzmv14Ri5ziZ5bvBp//0YGNANi72nTTQcWmkpI9g8d6jMDRlDlFZDqddyg1IKMbKDPisYWcFs4+ivBjKg75o/N+HL7VKTfmvBrb/psVoZWF/DjZMmj2WqE5KFvftTMFqnvK7aLCDYqHVOPEI1RDyb//mzudkzquum+7LWHgBXnWPaY5xucasce9T1bQ9KjXZfQk3GniaCEe0dRf2SDlXS5cttaATnAZBq8het9klIeOXXBOxzXgCdOn1OeYnqWQIjbBABkGDn5cIJ85LMJWf3smfdCIpinPA+3fSWTqpDkcxeBvepm2NRt9wfvGep/xZ3MUO+wJ+Hn5dJc7xgryddL/Qk85PnJU+QOTuVwnSDWZ3ed52AepMyBLKPZcOK8pFec9Ka1PdsX52e+qTWc0QN81rJKX1coP4lAbtJIXo=----ATTACHMENT:----MzMwOTAwMDUyNTQwMTkyNCA4ODE3NDM4Mzc3NjI2OTEyIDg1Nzk1MjU3NTcxOTk3Nzk=