Version 1
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Field / FieldDefinitionListenerTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Field;
4
5 use Drupal\Component\Plugin\Exception\PluginNotFoundException;
6 use Drupal\Core\Cache\CacheBackendInterface;
7 use Drupal\Core\Entity\DynamicallyFieldableEntityStorageInterface;
8 use Drupal\Core\Entity\EntityFieldManagerInterface;
9 use Drupal\Core\Entity\EntityInterface;
10 use Drupal\Core\Entity\EntityTypeInterface;
11 use Drupal\Core\Entity\EntityTypeManagerInterface;
12 use Drupal\Core\Field\FieldDefinitionInterface;
13 use Drupal\Core\Field\FieldDefinitionListener;
14 use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
15 use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
16 use Drupal\Tests\UnitTestCase;
17 use Prophecy\Argument;
18
19 /**
20  * @coversDefaultClass \Drupal\Core\Field\FieldDefinitionListener
21  * @group Field
22  */
23 class FieldDefinitionListenerTest extends UnitTestCase {
24
25   /**
26    * The key-value factory.
27    *
28    * @var \Drupal\Core\KeyValueStore\KeyValueFactoryInterface|\Prophecy\Prophecy\ProphecyInterface
29    */
30   protected $keyValueFactory;
31
32   /**
33    * The entity type manager.
34    *
35    * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\Prophecy\Prophecy\ProphecyInterface
36    */
37   protected $entityTypeManager;
38
39   /**
40    * The entity field manager.
41    *
42    * @var \Drupal\Core\Entity\EntityFieldManagerInterface|\Prophecy\Prophecy\ProphecyInterface
43    */
44   protected $entityFieldManager;
45
46   /**
47    * The cache backend.
48    *
49    * @var \Drupal\Core\Cache\CacheBackendInterface|\Prophecy\Prophecy\ProphecyInterface
50    */
51   protected $cacheBackend;
52
53   /**
54    * The field definition listener under test.
55    *
56    * @var \Drupal\Core\Field\FieldDefinitionListener
57    */
58   protected $fieldDefinitionListener;
59
60   /**
61    * {@inheritdoc}
62    */
63   protected function setUp() {
64     parent::setUp();
65
66     $this->keyValueFactory = $this->prophesize(KeyValueFactoryInterface::class);
67     $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
68     $this->entityFieldManager = $this->prophesize(EntityFieldManagerInterface::class);
69     $this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
70
71     $this->fieldDefinitionListener = new FieldDefinitionListener($this->entityTypeManager->reveal(), $this->entityFieldManager->reveal(), $this->keyValueFactory->reveal(), $this->cacheBackend->reveal());
72   }
73
74   /**
75    * Sets up the entity manager to be tested.
76    *
77    * @param \Drupal\Core\Entity\EntityTypeInterface[]|\Prophecy\Prophecy\ProphecyInterface[] $definitions
78    *   (optional) An array of entity type definitions.
79    */
80   protected function setUpEntityManager($definitions = []) {
81     $class = $this->getMockClass(EntityInterface::class);
82     foreach ($definitions as $key => $entity_type) {
83       // \Drupal\Core\Entity\EntityTypeInterface::getLinkTemplates() is called
84       // by \Drupal\Core\Entity\EntityManager::processDefinition() so it must
85       // always be mocked.
86       $entity_type->getLinkTemplates()->willReturn([]);
87
88       // Give the entity type a legitimate class to return.
89       $entity_type->getClass()->willReturn($class);
90
91       $definitions[$key] = $entity_type->reveal();
92     }
93
94     $this->entityTypeManager->getDefinition(Argument::cetera())
95       ->will(function ($args) use ($definitions) {
96         $entity_type_id = $args[0];
97         $exception_on_invalid = $args[1];
98         if (isset($definitions[$entity_type_id])) {
99           return $definitions[$entity_type_id];
100         }
101         elseif (!$exception_on_invalid) {
102           return NULL;
103         }
104         else throw new PluginNotFoundException($entity_type_id);
105       });
106     $this->entityTypeManager->getDefinitions()->willReturn($definitions);
107   }
108
109   /**
110    * @covers ::onFieldDefinitionCreate
111    */
112   public function testOnFieldDefinitionCreateNewField() {
113     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
114     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
115     $field_definition->getTargetBundle()->willReturn('test_bundle');
116     $field_definition->getName()->willReturn('test_field');
117     $field_definition->getType()->willReturn('test_type');
118
119     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
120     $storage->onFieldDefinitionCreate($field_definition->reveal())->shouldBeCalledTimes(1);
121     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
122
123     $entity = $this->prophesize(EntityTypeInterface::class);
124     $this->setUpEntityManager(['test_entity_type' => $entity]);
125
126     // Set up the stored bundle field map.
127     $key_value_store = $this->prophesize(KeyValueStoreInterface::class);
128     $this->keyValueFactory->get('entity.definitions.bundle_field_map')->willReturn($key_value_store->reveal());
129     $key_value_store->get('test_entity_type')->willReturn([]);
130     $key_value_store->set('test_entity_type', [
131       'test_field' => [
132         'type' => 'test_type',
133         'bundles' => ['test_bundle' => 'test_bundle'],
134       ],
135     ])->shouldBeCalled();
136
137     $this->fieldDefinitionListener->onFieldDefinitionCreate($field_definition->reveal());
138   }
139
140   /**
141    * @covers ::onFieldDefinitionCreate
142    */
143   public function testOnFieldDefinitionCreateExistingField() {
144     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
145     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
146     $field_definition->getTargetBundle()->willReturn('test_bundle');
147     $field_definition->getName()->willReturn('test_field');
148
149     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
150     $storage->onFieldDefinitionCreate($field_definition->reveal())->shouldBeCalledTimes(1);
151     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
152
153     $entity = $this->prophesize(EntityTypeInterface::class);
154     $this->setUpEntityManager(['test_entity_type' => $entity]);
155
156     // Set up the stored bundle field map.
157     $key_value_store = $this->prophesize(KeyValueStoreInterface::class);
158     $this->keyValueFactory->get('entity.definitions.bundle_field_map')->willReturn($key_value_store->reveal());
159     $key_value_store->get('test_entity_type')->willReturn([
160       'test_field' => [
161         'type' => 'test_type',
162         'bundles' => ['existing_bundle' => 'existing_bundle'],
163       ],
164     ]);
165     $key_value_store->set('test_entity_type', [
166       'test_field' => [
167         'type' => 'test_type',
168         'bundles' => ['existing_bundle' => 'existing_bundle', 'test_bundle' => 'test_bundle'],
169       ],
170     ])
171       ->shouldBeCalled();
172
173     $this->fieldDefinitionListener->onFieldDefinitionCreate($field_definition->reveal());
174   }
175
176   /**
177    * @covers ::onFieldDefinitionUpdate
178    */
179   public function testOnFieldDefinitionUpdate() {
180     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
181     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
182
183     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
184     $storage->onFieldDefinitionUpdate($field_definition->reveal(), $field_definition->reveal())->shouldBeCalledTimes(1);
185     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
186
187     $entity = $this->prophesize(EntityTypeInterface::class);
188     $this->setUpEntityManager(['test_entity_type' => $entity]);
189
190     $this->fieldDefinitionListener->onFieldDefinitionUpdate($field_definition->reveal(), $field_definition->reveal());
191   }
192
193   /**
194    * @covers ::onFieldDefinitionDelete
195    */
196   public function testOnFieldDefinitionDeleteMultipleBundles() {
197     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
198     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
199     $field_definition->getTargetBundle()->willReturn('test_bundle');
200     $field_definition->getName()->willReturn('test_field');
201
202     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
203     $storage->onFieldDefinitionDelete($field_definition->reveal())->shouldBeCalledTimes(1);
204     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
205
206     $entity = $this->prophesize(EntityTypeInterface::class);
207     $this->setUpEntityManager(['test_entity_type' => $entity]);
208
209     // Set up the stored bundle field map.
210     $key_value_store = $this->prophesize(KeyValueStoreInterface::class);
211     $this->keyValueFactory->get('entity.definitions.bundle_field_map')->willReturn($key_value_store->reveal());
212     $key_value_store->get('test_entity_type')->willReturn([
213       'test_field' => [
214         'type' => 'test_type',
215         'bundles' => ['test_bundle' => 'test_bundle'],
216       ],
217       'second_field' => [
218         'type' => 'test_type',
219         'bundles' => ['test_bundle' => 'test_bundle'],
220       ],
221     ]);
222     $key_value_store->set('test_entity_type', [
223       'second_field' => [
224         'type' => 'test_type',
225         'bundles' => ['test_bundle' => 'test_bundle'],
226       ],
227     ])
228       ->shouldBeCalled();
229
230     $this->fieldDefinitionListener->onFieldDefinitionDelete($field_definition->reveal());
231   }
232
233
234   /**
235    * @covers ::onFieldDefinitionDelete
236    */
237   public function testOnFieldDefinitionDeleteSingleBundles() {
238     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
239     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
240     $field_definition->getTargetBundle()->willReturn('test_bundle');
241     $field_definition->getName()->willReturn('test_field');
242
243     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
244     $storage->onFieldDefinitionDelete($field_definition->reveal())->shouldBeCalledTimes(1);
245     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
246
247     $entity = $this->prophesize(EntityTypeInterface::class);
248     $this->setUpEntityManager(['test_entity_type' => $entity]);
249
250     // Set up the stored bundle field map.
251     $key_value_store = $this->prophesize(KeyValueStoreInterface::class);
252     $this->keyValueFactory->get('entity.definitions.bundle_field_map')->willReturn($key_value_store->reveal());
253     $key_value_store->get('test_entity_type')->willReturn([
254       'test_field' => [
255         'type' => 'test_type',
256         'bundles' => ['test_bundle' => 'test_bundle', 'second_bundle' => 'second_bundle'],
257       ],
258     ]);
259     $key_value_store->set('test_entity_type', [
260       'test_field' => [
261         'type' => 'test_type',
262         'bundles' => ['second_bundle' => 'second_bundle'],
263       ],
264     ])
265       ->shouldBeCalled();
266
267     $this->fieldDefinitionListener->onFieldDefinitionDelete($field_definition->reveal());
268   }
269
270 }