View source
<?php
namespace Drupal\Tests\Core\Entity;
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityHandlerBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Exception\InvalidLinkTemplateException;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
use Symfony\Component\DependencyInjection\ContainerInterface;
class EntityTypeManagerTest extends UnitTestCase {
protected $entityTypeManager;
protected $translationManager;
protected $discovery;
protected $moduleHandler;
protected $cacheBackend;
protected $entityLastInstalledSchemaRepository;
protected function setUp() {
parent::setUp();
$this->moduleHandler = $this
->prophesize(ModuleHandlerInterface::class);
$this->moduleHandler
->getImplementations('entity_type_build')
->willReturn([]);
$this->moduleHandler
->alter('entity_type', Argument::type('array'))
->willReturn(NULL);
$this->cacheBackend = $this
->prophesize(CacheBackendInterface::class);
$this->translationManager = $this
->prophesize(TranslationInterface::class);
$this->entityLastInstalledSchemaRepository = $this
->prophesize(EntityLastInstalledSchemaRepositoryInterface::class);
$this->entityTypeManager = new TestEntityTypeManager(new \ArrayObject(), $this->moduleHandler
->reveal(), $this->cacheBackend
->reveal(), $this->translationManager
->reveal(), $this
->getClassResolverStub(), $this->entityLastInstalledSchemaRepository
->reveal());
$this->discovery = $this
->prophesize(DiscoveryInterface::class);
$this->entityTypeManager
->setDiscovery($this->discovery
->reveal());
}
protected function setUpEntityTypeDefinitions($definitions = []) {
$class = $this
->getMockClass(EntityInterface::class);
foreach ($definitions as $key => $entity_type) {
$entity_type
->getLinkTemplates()
->willReturn([]);
$entity_type
->getClass()
->willReturn($class);
$entity_type
->setClass($class)
->willReturn($entity_type
->reveal());
$definitions[$key] = $entity_type
->reveal();
}
$this->discovery
->getDefinition(Argument::cetera())
->will(function ($args) use ($definitions) {
$entity_type_id = $args[0];
$exception_on_invalid = $args[1];
if (isset($definitions[$entity_type_id])) {
return $definitions[$entity_type_id];
}
elseif (!$exception_on_invalid) {
return NULL;
}
else {
throw new PluginNotFoundException($entity_type_id);
}
});
$this->discovery
->getDefinitions()
->willReturn($definitions);
}
public function testHasHandler($entity_type_id, $expected) {
$apple = $this
->prophesize(EntityTypeInterface::class);
$apple
->hasHandlerClass('storage')
->willReturn(TRUE);
$banana = $this
->prophesize(EntityTypeInterface::class);
$banana
->hasHandlerClass('storage')
->willReturn(FALSE);
$this
->setUpEntityTypeDefinitions([
'apple' => $apple,
'banana' => $banana,
]);
$entity_type = $this->entityTypeManager
->hasHandler($entity_type_id, 'storage');
$this
->assertSame($expected, $entity_type);
}
public function providerTestHasHandler() {
return [
[
'apple',
TRUE,
],
[
'banana',
FALSE,
],
[
'pear',
FALSE,
],
];
}
public function testGetStorage() {
$class = $this
->getTestHandlerClass();
$entity = $this
->prophesize(EntityTypeInterface::class);
$entity
->getHandlerClass('storage')
->willReturn($class);
$this
->setUpEntityTypeDefinitions([
'test_entity_type' => $entity,
]);
$this
->assertInstanceOf($class, $this->entityTypeManager
->getStorage('test_entity_type'));
}
public function testGetListBuilder() {
$class = $this
->getTestHandlerClass();
$entity = $this
->prophesize(EntityTypeInterface::class);
$entity
->getHandlerClass('list_builder')
->willReturn($class);
$this
->setUpEntityTypeDefinitions([
'test_entity_type' => $entity,
]);
$this
->assertInstanceOf($class, $this->entityTypeManager
->getListBuilder('test_entity_type'));
}
public function testGetViewBuilder() {
$class = $this
->getTestHandlerClass();
$entity = $this
->prophesize(EntityTypeInterface::class);
$entity
->getHandlerClass('view_builder')
->willReturn($class);
$this
->setUpEntityTypeDefinitions([
'test_entity_type' => $entity,
]);
$this
->assertInstanceOf($class, $this->entityTypeManager
->getViewBuilder('test_entity_type'));
}
public function testGetAccessControlHandler() {
$class = $this
->getTestHandlerClass();
$entity = $this
->prophesize(EntityTypeInterface::class);
$entity
->getHandlerClass('access')
->willReturn($class);
$this
->setUpEntityTypeDefinitions([
'test_entity_type' => $entity,
]);
$this
->assertInstanceOf($class, $this->entityTypeManager
->getAccessControlHandler('test_entity_type'));
}
public function testGetFormObject() {
$apple = $this
->prophesize(EntityTypeInterface::class);
$apple
->getFormClass('default')
->willReturn(TestEntityForm::class);
$banana = $this
->prophesize(EntityTypeInterface::class);
$banana
->getFormClass('default')
->willReturn(TestEntityFormInjected::class);
$this
->setUpEntityTypeDefinitions([
'apple' => $apple,
'banana' => $banana,
]);
$apple_form = $this->entityTypeManager
->getFormObject('apple', 'default');
$this
->assertInstanceOf(TestEntityForm::class, $apple_form);
$this
->assertAttributeInstanceOf(ModuleHandlerInterface::class, 'moduleHandler', $apple_form);
$this
->assertAttributeInstanceOf(TranslationInterface::class, 'stringTranslation', $apple_form);
$banana_form = $this->entityTypeManager
->getFormObject('banana', 'default');
$this
->assertInstanceOf(TestEntityFormInjected::class, $banana_form);
$this
->assertAttributeEquals('yellow', 'color', $banana_form);
}
public function testGetFormObjectInvalidOperation() {
$entity = $this
->prophesize(EntityTypeInterface::class);
$entity
->getFormClass('edit')
->willReturn('');
$this
->setUpEntityTypeDefinitions([
'test_entity_type' => $entity,
]);
$this
->expectException(InvalidPluginDefinitionException::class);
$this->entityTypeManager
->getFormObject('test_entity_type', 'edit');
}
public function testGetHandler() {
$class = $this
->getTestHandlerClass();
$apple = $this
->prophesize(EntityTypeInterface::class);
$apple
->getHandlerClass('storage')
->willReturn($class);
$this
->setUpEntityTypeDefinitions([
'apple' => $apple,
]);
$apple_controller = $this->entityTypeManager
->getHandler('apple', 'storage');
$this
->assertInstanceOf($class, $apple_controller);
$this
->assertAttributeInstanceOf(ModuleHandlerInterface::class, 'moduleHandler', $apple_controller);
$this
->assertAttributeInstanceOf(TranslationInterface::class, 'stringTranslation', $apple_controller);
}
public function testGetHandlerMissingHandler() {
$entity = $this
->prophesize(EntityTypeInterface::class);
$entity
->getHandlerClass('storage')
->willReturn('');
$this
->setUpEntityTypeDefinitions([
'test_entity_type' => $entity,
]);
$this
->expectException(InvalidPluginDefinitionException::class);
$this->entityTypeManager
->getHandler('test_entity_type', 'storage');
}
public function testGetRouteProviders() {
$apple = $this
->prophesize(EntityTypeInterface::class);
$apple
->getRouteProviderClasses()
->willReturn([
'default' => TestRouteProvider::class,
]);
$this
->setUpEntityTypeDefinitions([
'apple' => $apple,
]);
$apple_route_provider = $this->entityTypeManager
->getRouteProviders('apple');
$this
->assertInstanceOf(TestRouteProvider::class, $apple_route_provider['default']);
$this
->assertAttributeInstanceOf(ModuleHandlerInterface::class, 'moduleHandler', $apple_route_provider['default']);
$this
->assertAttributeInstanceOf(TranslationInterface::class, 'stringTranslation', $apple_route_provider['default']);
}
public function testProcessDefinition() {
$apple = $this
->prophesize(EntityTypeInterface::class);
$this
->setUpEntityTypeDefinitions([
'apple' => $apple,
]);
$apple
->getLinkTemplates()
->willReturn([
'canonical' => 'path/to/apple',
]);
$definition = $apple
->reveal();
$this
->expectException(InvalidLinkTemplateException::class);
$this
->expectExceptionMessage("Link template 'canonical' for entity type 'apple' must start with a leading slash, the current link template is 'path/to/apple'");
$this->entityTypeManager
->processDefinition($definition, 'apple');
}
public function testGetDefinition($entity_type_id, $expected) {
$entity = $this
->prophesize(EntityTypeInterface::class);
$this
->setUpEntityTypeDefinitions([
'apple' => $entity,
'banana' => $entity,
]);
$entity_type = $this->entityTypeManager
->getDefinition($entity_type_id, FALSE);
if ($expected) {
$this
->assertInstanceOf(EntityTypeInterface::class, $entity_type);
}
else {
$this
->assertNull($entity_type);
}
}
public function providerTestGetDefinition() {
return [
[
'apple',
TRUE,
],
[
'banana',
TRUE,
],
[
'pear',
FALSE,
],
];
}
public function testGetDefinitionInvalidException() {
$this
->setUpEntityTypeDefinitions();
$this
->expectException(PluginNotFoundException::class);
$this
->expectExceptionMessage('The "pear" entity type does not exist.');
$this->entityTypeManager
->getDefinition('pear', TRUE);
}
protected function getTestHandlerClass() {
return get_class($this
->getMockForAbstractClass(EntityHandlerBase::class));
}
}
class TestEntityTypeManager extends EntityTypeManager {
public function setDiscovery(DiscoveryInterface $discovery) {
$this->discovery = $discovery;
}
}
class TestEntityForm extends EntityHandlerBase {
protected $entityManager;
protected $entityTypeManager;
public function getBaseFormId() {
return 'the_base_form_id';
}
public function getFormId() {
return 'the_form_id';
}
public function setEntity(EntityInterface $entity) {
return $this;
}
public function setOperation($operation) {
return $this;
}
public function setEntityManager(EntityManagerInterface $entity_manager) {
$this->entityManager = $entity_manager;
return $this;
}
public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
return $this;
}
}
class TestEntityFormInjected extends TestEntityForm implements ContainerInjectionInterface {
protected $color;
public function __construct($color) {
$this->color = $color;
}
public static function create(ContainerInterface $container) {
return new static('yellow');
}
}
class TestRouteProvider extends EntityHandlerBase {
}