Same name and namespace in other branches
  1. 8.9.x core/tests/Drupal/Tests/Core/Entity/EntityTypeManagerTest.php \Drupal\Tests\Core\Entity\EntityTypeManagerTest
  2. 9 core/tests/Drupal/Tests/Core/Entity/EntityTypeManagerTest.php \Drupal\Tests\Core\Entity\EntityTypeManagerTest

@coversDefaultClass \Drupal\Core\Entity\EntityTypeManager @group Entity

Hierarchy

Expanded class hierarchy of EntityTypeManagerTest

File

core/tests/Drupal/Tests/Core/Entity/EntityTypeManagerTest.php, line 30

Namespace

Drupal\Tests\Core\Entity
View source
class EntityTypeManagerTest extends UnitTestCase {

  /**
   * The entity type manager under test.
   *
   * @var \Drupal\Core\Entity\EntityTypeManager
   */
  protected $entityTypeManager;

  /**
   * The translation manager.
   *
   * @var \Drupal\Core\StringTranslation\TranslationInterface|\Prophecy\Prophecy\ProphecyInterface
   */
  protected $translationManager;

  /**
   * The plugin discovery.
   *
   * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface|\Prophecy\Prophecy\ProphecyInterface
   */
  protected $discovery;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface|\Prophecy\Prophecy\ProphecyInterface
   */
  protected $moduleHandler;

  /**
   * The cache backend.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface|\Prophecy\Prophecy\ProphecyInterface
   */
  protected $cacheBackend;

  /**
   * The entity last installed schema repository.
   *
   * @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface|\Prophecy\Prophecy\ProphecyInterface
   */
  protected $entityLastInstalledSchemaRepository;

  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    $this->moduleHandler = $this
      ->prophesize(ModuleHandlerInterface::class);
    $this->cacheBackend = $this
      ->prophesize(CacheBackendInterface::class);
    $this->translationManager = $this
      ->prophesize(TranslationInterface::class);
    $this->entityLastInstalledSchemaRepository = $this
      ->prophesize(EntityLastInstalledSchemaRepositoryInterface::class);
    $container = $this
      ->prophesize(Container::class);
    $this->entityTypeManager = new TestEntityTypeManager(new \ArrayObject(), $this->moduleHandler
      ->reveal(), $this->cacheBackend
      ->reveal(), $this->translationManager
      ->reveal(), $this
      ->getClassResolverStub(), $this->entityLastInstalledSchemaRepository
      ->reveal(), $container
      ->reveal());
    $this->discovery = $this
      ->prophesize(DiscoveryInterface::class);
    $this->entityTypeManager
      ->setDiscovery($this->discovery
      ->reveal());
  }

  /**
   * Sets up the entity type manager to be tested.
   *
   * @param \Drupal\Core\Entity\EntityTypeInterface[]|\Prophecy\Prophecy\ProphecyInterface[] $definitions
   *   (optional) An array of entity type definitions.
   */
  protected function setUpEntityTypeDefinitions($definitions = []) {
    $class = get_class($this
      ->createMock(EntityInterface::class));
    foreach ($definitions as $key => $entity_type) {

      // \Drupal\Core\Entity\EntityTypeInterface::getLinkTemplates() is called
      // by \Drupal\Core\Entity\EntityTypeManager::processDefinition() so it must
      // always be mocked.
      $entity_type
        ->getLinkTemplates()
        ->willReturn([]);

      // Give the entity type a legitimate class to return.
      $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);
  }

  /**
   * Tests the hasHandler() method.
   *
   * @covers ::hasHandler
   *
   * @dataProvider providerTestHasHandler
   */
  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);
  }

  /**
   * Provides test data for testHasHandler().
   *
   * @return array
   *   Test data.
   */
  public static function providerTestHasHandler() {
    return [
      [
        'apple',
        TRUE,
      ],
      [
        'banana',
        FALSE,
      ],
      [
        'pear',
        FALSE,
      ],
    ];
  }

  /**
   * Tests the getStorage() method.
   *
   * @covers ::getStorage
   */
  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'));
  }

  /**
   * Tests the getListBuilder() method.
   *
   * @covers ::getListBuilder
   */
  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'));
  }

  /**
   * Tests the getViewBuilder() method.
   *
   * @covers ::getViewBuilder
   */
  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'));
  }

  /**
   * Tests the getAccessControlHandler() method.
   *
   * @covers ::getAccessControlHandler
   */
  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'));
  }

  /**
   * Tests the getFormObject() method.
   *
   * @covers ::getFormObject
   */
  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
      ->assertInstanceOf(ModuleHandlerInterface::class, $apple_form->moduleHandler);
    $this
      ->assertInstanceOf(TranslationInterface::class, $apple_form->stringTranslation);
    $banana_form = $this->entityTypeManager
      ->getFormObject('banana', 'default');
    $this
      ->assertInstanceOf(TestEntityFormInjected::class, $banana_form);
    $this
      ->assertEquals('yellow', $banana_form->color);
  }

  /**
   * Provides test data for testGetFormObjectInvalidOperation().
   *
   * @return array
   *   Test data.
   */
  public static function provideFormObjectInvalidOperationData() : array {
    return [
      'missing_form_handler' => [
        'test_entity_type',
        'edit',
        '',
        'The "test_entity_type" entity type did not specify a "edit" form class.',
      ],
      'missing_form_handler_class' => [
        'test_entity_type',
        'edit',
        'Drupal\\test_entity_type\\Form\\NonExistingClass',
        'The "edit" form handler of the "test_entity_type" entity type specifies a non-existent class "Drupal\\test_entity_type\\Form\\NonExistingClass".',
      ],
    ];
  }

  /**
   * Tests the getFormObject() method with an invalid operation.
   *
   * @covers ::getFormObject
   *
   * @dataProvider provideFormObjectInvalidOperationData
   */
  public function testGetFormObjectInvalidOperation(string $entity_type_id, string $operation, string $form_class, string $exception_message) : void {
    $entity = $this
      ->prophesize(EntityTypeInterface::class);
    $entity
      ->getFormClass($operation)
      ->willReturn(NULL);
    if (!$form_class) {
      $entity
        ->getHandlerClasses()
        ->willReturn([]);
    }
    else {
      $entity
        ->getHandlerClasses()
        ->willReturn([
        'form' => [
          $operation => $form_class,
        ],
      ]);
    }
    $this
      ->setUpEntityTypeDefinitions([
      $entity_type_id => $entity,
    ]);
    $this
      ->expectException(InvalidPluginDefinitionException::class);
    $this
      ->expectExceptionMessage($exception_message);
    $this->entityTypeManager
      ->getFormObject($entity_type_id, $operation);
  }

  /**
   * Tests the getHandler() method.
   *
   * @covers ::getHandler
   */
  public function testGetHandler() {
    $class = get_class($this
      ->getMockForAbstractClass(TestEntityHandlerBase::class));
    $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
      ->assertInstanceOf(ModuleHandlerInterface::class, $apple_controller->moduleHandler);
    $this
      ->assertInstanceOf(TranslationInterface::class, $apple_controller->stringTranslation);
  }

  /**
   * Provides test data for testGetHandlerMissingHandler().
   *
   * @return array
   *   Test data.
   */
  public static function provideMissingHandlerData() : array {
    return [
      'missing_handler' => [
        'test_entity_type',
        'storage',
        '',
        'The "test_entity_type" entity type did not specify a storage handler.',
      ],
      'missing_handler_class' => [
        'test_entity_type',
        'storage',
        'Non_Existing_Class',
        'The storage handler of the "test_entity_type" entity type specifies a non-existent class "Non_Existing_Class".',
      ],
    ];
  }

  /**
   * Tests the getHandler() method when no controller is defined.
   *
   * @covers ::getHandler
   *
   * @dataProvider provideMissingHandlerData
   */
  public function testGetHandlerMissingHandler(string $entity_type, string $handler_name, string $handler_class, $exception_message) : void {
    $entity = $this
      ->prophesize(EntityTypeInterface::class);
    $entity
      ->getHandlerClass($handler_name)
      ->willReturn(NULL);
    if (!$handler_class) {
      $entity
        ->getHandlerClasses()
        ->willReturn([]);
    }
    else {
      $entity
        ->getHandlerClasses()
        ->willReturn([
        $handler_name => $handler_class,
      ]);
    }
    $this
      ->setUpEntityTypeDefinitions([
      $entity_type => $entity,
    ]);
    $this
      ->expectException(InvalidPluginDefinitionException::class);
    $this
      ->expectExceptionMessage($exception_message);
    $this->entityTypeManager
      ->getHandler($entity_type, $handler_name);
  }

  /**
   * @covers ::getRouteProviders
   */
  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
      ->assertInstanceOf(ModuleHandlerInterface::class, $apple_route_provider['default']->moduleHandler);
    $this
      ->assertInstanceOf(TranslationInterface::class, $apple_route_provider['default']->stringTranslation);
  }

  /**
   * Tests the processDefinition() method.
   *
   * @covers ::processDefinition
   */
  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');
  }

  /**
   * Tests the getDefinition() method.
   *
   * @covers ::getDefinition
   *
   * @dataProvider providerTestGetDefinition
   */
  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);
    }
  }

  /**
   * Provides test data for testGetDefinition().
   *
   * @return array
   *   Test data.
   */
  public static function providerTestGetDefinition() {
    return [
      [
        'apple',
        TRUE,
      ],
      [
        'banana',
        TRUE,
      ],
      [
        'pear',
        FALSE,
      ],
    ];
  }

  /**
   * Tests the getDefinition() method with an invalid definition.
   *
   * @covers ::getDefinition
   */
  public function testGetDefinitionInvalidException() {
    $this
      ->setUpEntityTypeDefinitions();
    $this
      ->expectException(PluginNotFoundException::class);
    $this
      ->expectExceptionMessage('The "pear" entity type does not exist.');
    $this->entityTypeManager
      ->getDefinition('pear', TRUE);
  }

  /**
   * Gets a mock controller class name.
   *
   * @return string
   *   A mock controller class name.
   */
  protected function getTestHandlerClass() {
    return get_class($this
      ->getMockForAbstractClass(EntityHandlerBase::class));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
EntityTypeManagerTest::$cacheBackend protected property The cache backend.
EntityTypeManagerTest::$discovery protected property The plugin discovery.
EntityTypeManagerTest::$entityLastInstalledSchemaRepository protected property The entity last installed schema repository.
EntityTypeManagerTest::$entityTypeManager protected property The entity type manager under test.
EntityTypeManagerTest::$moduleHandler protected property The module handler.
EntityTypeManagerTest::$translationManager protected property The translation manager.
EntityTypeManagerTest::getTestHandlerClass protected function Gets a mock controller class name.
EntityTypeManagerTest::provideFormObjectInvalidOperationData public static function Provides test data for testGetFormObjectInvalidOperation().
EntityTypeManagerTest::provideMissingHandlerData public static function Provides test data for testGetHandlerMissingHandler().
EntityTypeManagerTest::providerTestGetDefinition public static function Provides test data for testGetDefinition().
EntityTypeManagerTest::providerTestHasHandler public static function Provides test data for testHasHandler().
EntityTypeManagerTest::setUp protected function Overrides UnitTestCase::setUp
EntityTypeManagerTest::setUpEntityTypeDefinitions protected function Sets up the entity type manager to be tested.
EntityTypeManagerTest::testGetAccessControlHandler public function Tests the getAccessControlHandler() method.
EntityTypeManagerTest::testGetDefinition public function Tests the getDefinition() method.
EntityTypeManagerTest::testGetDefinitionInvalidException public function Tests the getDefinition() method with an invalid definition.
EntityTypeManagerTest::testGetFormObject public function Tests the getFormObject() method.
EntityTypeManagerTest::testGetFormObjectInvalidOperation public function Tests the getFormObject() method with an invalid operation.
EntityTypeManagerTest::testGetHandler public function Tests the getHandler() method.
EntityTypeManagerTest::testGetHandlerMissingHandler public function Tests the getHandler() method when no controller is defined.
EntityTypeManagerTest::testGetListBuilder public function Tests the getListBuilder() method.
EntityTypeManagerTest::testGetRouteProviders public function @covers ::getRouteProviders
EntityTypeManagerTest::testGetStorage public function Tests the getStorage() method.
EntityTypeManagerTest::testGetViewBuilder public function Tests the getViewBuilder() method.
EntityTypeManagerTest::testHasHandler public function Tests the hasHandler() method.
EntityTypeManagerTest::testProcessDefinition public function Tests the processDefinition() method.
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.
RandomGeneratorTrait::getRandomGenerator protected function Gets the random generator for the utility methods.
RandomGeneratorTrait::randomMachineName protected function Generates a unique random string containing letters and numbers.
RandomGeneratorTrait::randomObject public function Generates a random PHP object.
RandomGeneratorTrait::randomString public function Generates a pseudo-random string of ASCII characters of codes 32 to 126.
RandomGeneratorTrait::randomStringValidate Deprecated public function Callback for random string validation.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::setUpBeforeClass public static function
UnitTestCase::__get public function