3 namespace Drupal\Tests\Core\Entity;
5 use Drupal\Component\Plugin\Exception\PluginNotFoundException;
6 use Drupal\Core\Entity\EntityInterface;
7 use Drupal\Core\Entity\EntityTypeInterface;
8 use Drupal\Core\Entity\EntityTypeManagerInterface;
9 use Drupal\Core\Entity\EntityTypeRepository;
10 use Drupal\Core\Entity\Exception\AmbiguousEntityClassException;
11 use Drupal\Core\Entity\Exception\NoCorrespondingEntityClassException;
12 use Drupal\Tests\UnitTestCase;
13 use Prophecy\Argument;
16 * @coversDefaultClass \Drupal\Core\Entity\EntityTypeRepository
19 class EntityTypeRepositoryTest extends UnitTestCase {
22 * The entity type repository under test.
24 * @var \Drupal\Core\Entity\EntityTypeRepository
26 protected $entityTypeRepository;
29 * The entity type manager.
31 * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\Prophecy\Prophecy\ProphecyInterface
33 protected $entityTypeManager;
38 protected function setUp() {
41 $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
43 $this->entityTypeRepository = new EntityTypeRepository($this->entityTypeManager->reveal());
47 * Sets up the entity type manager to be tested.
49 * @param \Drupal\Core\Entity\EntityTypeInterface[]|\Prophecy\Prophecy\ProphecyInterface[] $definitions
50 * (optional) An array of entity type definitions.
52 protected function setUpEntityTypeDefinitions($definitions = []) {
53 $class = $this->getMockClass(EntityInterface::class);
54 foreach ($definitions as $key => $entity_type) {
55 // \Drupal\Core\Entity\EntityTypeInterface::getLinkTemplates() is called
56 // by \Drupal\Core\Entity\EntityManager::processDefinition() so it must
58 $entity_type->getLinkTemplates()->willReturn([]);
60 // Give the entity type a legitimate class to return.
61 $entity_type->getClass()->willReturn($class);
63 $definitions[$key] = $entity_type->reveal();
66 $this->entityTypeManager->getDefinition(Argument::cetera())
67 ->will(function ($args) use ($definitions) {
68 $entity_type_id = $args[0];
69 $exception_on_invalid = $args[1];
70 if (isset($definitions[$entity_type_id])) {
71 return $definitions[$entity_type_id];
73 elseif (!$exception_on_invalid) {
77 throw new PluginNotFoundException($entity_type_id);
80 $this->entityTypeManager->getDefinitions()->willReturn($definitions);
84 * Tests the getEntityTypeLabels() method.
86 * @covers ::getEntityTypeLabels
88 public function testGetEntityTypeLabels() {
89 $apple = $this->prophesize(EntityTypeInterface::class);
90 $apple->getLabel()->willReturn('Apple');
91 $apple->getBundleOf()->willReturn(NULL);
93 $banana = $this->prophesize(EntityTypeInterface::class);
94 $banana->getLabel()->willReturn('Banana');
95 $banana->getBundleOf()->willReturn(NULL);
97 $this->setUpEntityTypeDefinitions([
104 'banana' => 'Banana',
106 $this->assertSame($expected, $this->entityTypeRepository->getEntityTypeLabels());
110 * @covers ::getEntityTypeFromClass
112 public function testGetEntityTypeFromClass() {
113 $apple = $this->prophesize(EntityTypeInterface::class);
114 $banana = $this->prophesize(EntityTypeInterface::class);
116 $this->setUpEntityTypeDefinitions([
121 $apple->getOriginalClass()->willReturn('\Drupal\apple\Entity\Apple');
123 $banana->getOriginalClass()->willReturn('\Drupal\banana\Entity\Banana');
124 $banana->getClass()->willReturn('\Drupal\mango\Entity\Mango');
126 ->willReturn('banana')
127 ->shouldBeCalledTimes(2);
129 $entity_type_id = $this->entityTypeRepository->getEntityTypeFromClass('\Drupal\banana\Entity\Banana');
130 $this->assertSame('banana', $entity_type_id);
131 $entity_type_id = $this->entityTypeRepository->getEntityTypeFromClass('\Drupal\mango\Entity\Mango');
132 $this->assertSame('banana', $entity_type_id);
136 * @covers ::getEntityTypeFromClass
138 public function testGetEntityTypeFromClassNoMatch() {
139 $apple = $this->prophesize(EntityTypeInterface::class);
140 $banana = $this->prophesize(EntityTypeInterface::class);
142 $this->setUpEntityTypeDefinitions([
147 $apple->getOriginalClass()->willReturn('\Drupal\apple\Entity\Apple');
148 $banana->getOriginalClass()->willReturn('\Drupal\banana\Entity\Banana');
150 $this->setExpectedException(NoCorrespondingEntityClassException::class, 'The \Drupal\pear\Entity\Pear class does not correspond to an entity type.');
151 $this->entityTypeRepository->getEntityTypeFromClass('\Drupal\pear\Entity\Pear');
155 * @covers ::getEntityTypeFromClass
157 public function testGetEntityTypeFromClassAmbiguous() {
158 $boskoop = $this->prophesize(EntityTypeInterface::class);
159 $boskoop->getOriginalClass()->willReturn('\Drupal\apple\Entity\Apple');
160 $boskoop->id()->willReturn('boskop');
162 $gala = $this->prophesize(EntityTypeInterface::class);
163 $gala->getOriginalClass()->willReturn('\Drupal\apple\Entity\Apple');
164 $gala->id()->willReturn('gala');
166 $this->setUpEntityTypeDefinitions([
167 'boskoop' => $boskoop,
171 $this->setExpectedException(AmbiguousEntityClassException::class, 'Multiple entity types found for \Drupal\apple\Entity\Apple.');
172 $this->entityTypeRepository->getEntityTypeFromClass('\Drupal\apple\Entity\Apple');