ContainerControllerResolverTest.php 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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\Controller;
  11. use Psr\Container\ContainerInterface;
  12. use Psr\Log\LoggerInterface;
  13. use Symfony\Component\DependencyInjection\Container;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpKernel\Controller\ContainerControllerResolver;
  16. class ContainerControllerResolverTest extends ControllerResolverTest
  17. {
  18. /**
  19. * @group legacy
  20. * @expectedDeprecation Referencing controllers with a single colon is deprecated since Symfony 4.1. Use foo::action instead.
  21. */
  22. public function testGetControllerServiceWithSingleColon()
  23. {
  24. $service = new ControllerTestService('foo');
  25. $container = $this->createMockContainer();
  26. $container->expects($this->once())
  27. ->method('has')
  28. ->with('foo')
  29. ->will($this->returnValue(true));
  30. $container->expects($this->once())
  31. ->method('get')
  32. ->with('foo')
  33. ->will($this->returnValue($service))
  34. ;
  35. $resolver = $this->createControllerResolver(null, $container);
  36. $request = Request::create('/');
  37. $request->attributes->set('_controller', 'foo:action');
  38. $controller = $resolver->getController($request);
  39. $this->assertSame($service, $controller[0]);
  40. $this->assertSame('action', $controller[1]);
  41. }
  42. public function testGetControllerService()
  43. {
  44. $service = new ControllerTestService('foo');
  45. $container = $this->createMockContainer();
  46. $container->expects($this->once())
  47. ->method('has')
  48. ->with('foo')
  49. ->will($this->returnValue(true));
  50. $container->expects($this->once())
  51. ->method('get')
  52. ->with('foo')
  53. ->will($this->returnValue($service))
  54. ;
  55. $resolver = $this->createControllerResolver(null, $container);
  56. $request = Request::create('/');
  57. $request->attributes->set('_controller', 'foo::action');
  58. $controller = $resolver->getController($request);
  59. $this->assertSame($service, $controller[0]);
  60. $this->assertSame('action', $controller[1]);
  61. }
  62. public function testGetControllerInvokableService()
  63. {
  64. $service = new InvokableControllerService('bar');
  65. $container = $this->createMockContainer();
  66. $container->expects($this->once())
  67. ->method('has')
  68. ->with('foo')
  69. ->will($this->returnValue(true))
  70. ;
  71. $container->expects($this->once())
  72. ->method('get')
  73. ->with('foo')
  74. ->will($this->returnValue($service))
  75. ;
  76. $resolver = $this->createControllerResolver(null, $container);
  77. $request = Request::create('/');
  78. $request->attributes->set('_controller', 'foo');
  79. $controller = $resolver->getController($request);
  80. $this->assertSame($service, $controller);
  81. }
  82. public function testGetControllerInvokableServiceWithClassNameAsName()
  83. {
  84. $service = new InvokableControllerService('bar');
  85. $container = $this->createMockContainer();
  86. $container->expects($this->once())
  87. ->method('has')
  88. ->with(InvokableControllerService::class)
  89. ->will($this->returnValue(true))
  90. ;
  91. $container->expects($this->once())
  92. ->method('get')
  93. ->with(InvokableControllerService::class)
  94. ->will($this->returnValue($service))
  95. ;
  96. $resolver = $this->createControllerResolver(null, $container);
  97. $request = Request::create('/');
  98. $request->attributes->set('_controller', InvokableControllerService::class);
  99. $controller = $resolver->getController($request);
  100. $this->assertSame($service, $controller);
  101. }
  102. /**
  103. * Tests where the fallback instantiation fails due to required constructor arguments.
  104. *
  105. * @expectedException \InvalidArgumentException
  106. * @expectedExceptionMessage Controller "Symfony\Component\HttpKernel\Tests\Controller\ControllerTestService" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?
  107. */
  108. public function testExceptionWhenUsingRemovedControllerServiceWithClassNameAsName()
  109. {
  110. $container = $this->getMockBuilder(Container::class)->getMock();
  111. $container->expects($this->once())
  112. ->method('has')
  113. ->with(ControllerTestService::class)
  114. ->will($this->returnValue(false))
  115. ;
  116. $container->expects($this->atLeastOnce())
  117. ->method('getRemovedIds')
  118. ->with()
  119. ->will($this->returnValue(array(ControllerTestService::class => true)))
  120. ;
  121. $resolver = $this->createControllerResolver(null, $container);
  122. $request = Request::create('/');
  123. $request->attributes->set('_controller', array(ControllerTestService::class, 'action'));
  124. $resolver->getController($request);
  125. }
  126. /**
  127. * Tests where the fallback instantiation fails due to non-existing class.
  128. *
  129. * @expectedException \InvalidArgumentException
  130. * @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"?
  131. */
  132. public function testExceptionWhenUsingRemovedControllerService()
  133. {
  134. $container = $this->getMockBuilder(Container::class)->getMock();
  135. $container->expects($this->once())
  136. ->method('has')
  137. ->with('app.my_controller')
  138. ->will($this->returnValue(false))
  139. ;
  140. $container->expects($this->atLeastOnce())
  141. ->method('getRemovedIds')
  142. ->with()
  143. ->will($this->returnValue(array('app.my_controller' => true)))
  144. ;
  145. $resolver = $this->createControllerResolver(null, $container);
  146. $request = Request::create('/');
  147. $request->attributes->set('_controller', 'app.my_controller');
  148. $resolver->getController($request);
  149. }
  150. public function getUndefinedControllers()
  151. {
  152. $tests = parent::getUndefinedControllers();
  153. $tests[0] = array('foo', \InvalidArgumentException::class, 'Controller "foo" does neither exist as service nor as class');
  154. $tests[1] = array('oof::bar', \InvalidArgumentException::class, 'Controller "oof" does neither exist as service nor as class');
  155. $tests[2] = array(array('oof', 'bar'), \InvalidArgumentException::class, 'Controller "oof" does neither exist as service nor as class');
  156. $tests[] = array(
  157. array(ControllerTestService::class, 'action'),
  158. \InvalidArgumentException::class,
  159. 'Controller "Symfony\Component\HttpKernel\Tests\Controller\ControllerTestService" has required constructor arguments and does not exist in the container. Did you forget to define such a service?',
  160. );
  161. $tests[] = array(
  162. ControllerTestService::class.'::action',
  163. \InvalidArgumentException::class, 'Controller "Symfony\Component\HttpKernel\Tests\Controller\ControllerTestService" has required constructor arguments and does not exist in the container. Did you forget to define such a service?',
  164. );
  165. $tests[] = array(
  166. InvokableControllerService::class,
  167. \InvalidArgumentException::class,
  168. 'Controller "Symfony\Component\HttpKernel\Tests\Controller\InvokableControllerService" has required constructor arguments and does not exist in the container. Did you forget to define such a service?',
  169. );
  170. return $tests;
  171. }
  172. protected function createControllerResolver(LoggerInterface $logger = null, ContainerInterface $container = null)
  173. {
  174. if (!$container) {
  175. $container = $this->createMockContainer();
  176. }
  177. return new ContainerControllerResolver($container, $logger);
  178. }
  179. protected function createMockContainer()
  180. {
  181. return $this->getMockBuilder(ContainerInterface::class)->getMock();
  182. }
  183. }
  184. class InvokableControllerService
  185. {
  186. public function __construct($bar) // mandatory argument to prevent automatic instantiation
  187. {
  188. }
  189. public function __invoke()
  190. {
  191. }
  192. }
  193. class ControllerTestService
  194. {
  195. public function __construct($foo)
  196. {
  197. }
  198. public function action()
  199. {
  200. }
  201. }