View source
<?php
namespace Drupal\Tests\Core\Controller;
use Drupal\Core\Controller\ControllerResolver;
use Drupal\Core\DependencyInjection\ClassResolver;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Tests\UnitTestCase;
use Laminas\Diactoros\ResponseFactory;
use Laminas\Diactoros\ServerRequestFactory;
use Laminas\Diactoros\StreamFactory;
use Laminas\Diactoros\UploadedFileFactory;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Psr\Http\Message\ServerRequestInterface;
class ControllerResolverTest extends UnitTestCase {
public $controllerResolver;
protected $container;
protected $httpMessageFactory;
protected function setUp() : void {
parent::setUp();
$this->container = new ContainerBuilder();
$class_resolver = new ClassResolver();
$class_resolver
->setContainer($this->container);
$this->httpMessageFactory = new PsrHttpFactory(new ServerRequestFactory(), new StreamFactory(), new UploadedFileFactory(), new ResponseFactory());
$this->controllerResolver = new ControllerResolver($this->httpMessageFactory, $class_resolver);
}
public function testCreateController($controller, $class, $output) {
$this->container
->set('some_service', new MockController());
$result = $this->controllerResolver
->getControllerFromDefinition($controller);
$this
->assertCallableController($result, $class, $output);
}
public function providerTestCreateController() {
return [
[
'Drupal\\Tests\\Core\\Controller\\MockController::getResult',
'Drupal\\Tests\\Core\\Controller\\MockController',
'This is a regular controller.',
],
[
'some_service:getResult',
'Drupal\\Tests\\Core\\Controller\\MockController',
'This is a regular controller.',
],
[
'Drupal\\Tests\\Core\\Controller\\MockContainerInjection::getResult',
'Drupal\\Tests\\Core\\Controller\\MockContainerInjection',
'This used injection.',
],
[
'Drupal\\Tests\\Core\\Controller\\MockContainerAware::getResult',
'Drupal\\Tests\\Core\\Controller\\MockContainerAware',
'This is container aware.',
],
];
}
public function testCreateControllerNonExistentClass() {
$this
->expectException(\InvalidArgumentException::class);
$this->controllerResolver
->getControllerFromDefinition('Class::method');
}
public function testCreateControllerInvalidName() {
$this
->expectException(\LogicException::class);
$this->controllerResolver
->getControllerFromDefinition('ClassWithoutMethod');
}
public function testGetController($attributes, $class, $output = NULL) {
$request = new Request([], [], $attributes);
$result = $this->controllerResolver
->getController($request);
if ($class) {
$this
->assertCallableController($result, $class, $output);
}
else {
$this
->assertFalse($result);
}
}
public function providerTestGetController() {
return [
[
[
'_controller' => 'Drupal\\Tests\\Core\\Controller\\MockContainerAware::getResult',
],
'Drupal\\Tests\\Core\\Controller\\MockContainerAware',
'This is container aware.',
],
[
[],
FALSE,
],
];
}
public function testGetControllerFromDefinition($definition, $output) {
$this->container
->set('invoke_service', new MockInvokeController());
$controller = $this->controllerResolver
->getControllerFromDefinition($definition);
$this
->assertCallableController($controller, NULL, $output);
}
public function providerTestGetControllerFromDefinition() {
return [
[
[
new MockController(),
'getResult',
],
'This is a regular controller.',
],
[
'phpversion',
phpversion(),
],
[
new MockInvokeController(),
'This used __invoke().',
],
[
'Drupal\\Tests\\Core\\Controller\\MockInvokeController',
'This used __invoke().',
],
[
'invoke_service',
'This used __invoke().',
],
];
}
public function testGetControllerFromDefinitionNotCallable() {
$this
->expectException(\InvalidArgumentException::class);
$this->controllerResolver
->getControllerFromDefinition('Drupal\\Tests\\Core\\Controller\\MockController::bananas');
}
protected function assertCallableController($controller, $class, $output) {
if ($class) {
$this
->assertIsObject($controller[0]);
$this
->assertInstanceOf($class, $controller[0]);
}
$this
->assertIsCallable($controller);
$this
->assertSame($output, call_user_func($controller));
}
}
class MockController {
public function getResult() {
return 'This is a regular controller.';
}
public function getControllerWithRequestAndRouteMatch(RouteMatchInterface $route_match, Request $request) {
return 'this is another example controller';
}
}
class MockControllerPsr7 {
public function getResult() {
return [
'#markup' => 'This is a regular controller',
];
}
public function getControllerWithRequestAndRouteMatch(RouteMatchInterface $route_match, ServerRequestInterface $request) {
return [
'#markup' => 'this is another example controller',
];
}
}
class MockContainerInjection implements ContainerInjectionInterface {
protected $result;
public function __construct($result) {
$this->result = $result;
}
public static function create(ContainerInterface $container) {
return new static('This used injection.');
}
public function getResult() {
return $this->result;
}
}
class MockContainerAware implements ContainerAwareInterface {
use ContainerAwareTrait;
public function getResult() {
return 'This is container aware.';
}
}
class MockInvokeController {
public function __invoke() {
return 'This used __invoke().';
}
}