8bedf0750f035607795b0bb79f7d99e37c1fb53d
[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 {
105           throw new PluginNotFoundException($entity_type_id);
106         }
107       });
108     $this->entityTypeManager->getDefinitions()->willReturn($definitions);
109   }
110
111   /**
112    * @covers ::onFieldDefinitionCreate
113    */
114   public function testOnFieldDefinitionCreateNewField() {
115     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
116     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
117     $field_definition->getTargetBundle()->willReturn('test_bundle');
118     $field_definition->getName()->willReturn('test_field');
119     $field_definition->getType()->willReturn('test_type');
120
121     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
122     $storage->onFieldDefinitionCreate($field_definition->reveal())->shouldBeCalledTimes(1);
123     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
124
125     $entity = $this->prophesize(EntityTypeInterface::class);
126     $this->setUpEntityManager(['test_entity_type' => $entity]);
127
128     // Set up the stored bundle field map.
129     $key_value_store = $this->prophesize(KeyValueStoreInterface::class);
130     $this->keyValueFactory->get('entity.definitions.bundle_field_map')->willReturn($key_value_store->reveal());
131     $key_value_store->get('test_entity_type')->willReturn([]);
132     $key_value_store->set('test_entity_type', [
133       'test_field' => [
134         'type' => 'test_type',
135         'bundles' => ['test_bundle' => 'test_bundle'],
136       ],
137     ])->shouldBeCalled();
138
139     $this->fieldDefinitionListener->onFieldDefinitionCreate($field_definition->reveal());
140   }
141
142   /**
143    * @covers ::onFieldDefinitionCreate
144    */
145   public function testOnFieldDefinitionCreateExistingField() {
146     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
147     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
148     $field_definition->getTargetBundle()->willReturn('test_bundle');
149     $field_definition->getName()->willReturn('test_field');
150
151     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
152     $storage->onFieldDefinitionCreate($field_definition->reveal())->shouldBeCalledTimes(1);
153     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
154
155     $entity = $this->prophesize(EntityTypeInterface::class);
156     $this->setUpEntityManager(['test_entity_type' => $entity]);
157
158     // Set up the stored bundle field map.
159     $key_value_store = $this->prophesize(KeyValueStoreInterface::class);
160     $this->keyValueFactory->get('entity.definitions.bundle_field_map')->willReturn($key_value_store->reveal());
161     $key_value_store->get('test_entity_type')->willReturn([
162       'test_field' => [
163         'type' => 'test_type',
164         'bundles' => ['existing_bundle' => 'existing_bundle'],
165       ],
166     ]);
167     $key_value_store->set('test_entity_type', [
168       'test_field' => [
169         'type' => 'test_type',
170         'bundles' => ['existing_bundle' => 'existing_bundle', 'test_bundle' => 'test_bundle'],
171       ],
172     ])
173       ->shouldBeCalled();
174
175     $this->fieldDefinitionListener->onFieldDefinitionCreate($field_definition->reveal());
176   }
177
178   /**
179    * @covers ::onFieldDefinitionUpdate
180    */
181   public function testOnFieldDefinitionUpdate() {
182     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
183     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
184
185     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
186     $storage->onFieldDefinitionUpdate($field_definition->reveal(), $field_definition->reveal())->shouldBeCalledTimes(1);
187     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
188
189     $entity = $this->prophesize(EntityTypeInterface::class);
190     $this->setUpEntityManager(['test_entity_type' => $entity]);
191
192     $this->fieldDefinitionListener->onFieldDefinitionUpdate($field_definition->reveal(), $field_definition->reveal());
193   }
194
195   /**
196    * @covers ::onFieldDefinitionDelete
197    */
198   public function testOnFieldDefinitionDeleteMultipleBundles() {
199     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
200     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
201     $field_definition->getTargetBundle()->willReturn('test_bundle');
202     $field_definition->getName()->willReturn('test_field');
203
204     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
205     $storage->onFieldDefinitionDelete($field_definition->reveal())->shouldBeCalledTimes(1);
206     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
207
208     $entity = $this->prophesize(EntityTypeInterface::class);
209     $this->setUpEntityManager(['test_entity_type' => $entity]);
210
211     // Set up the stored bundle field map.
212     $key_value_store = $this->prophesize(KeyValueStoreInterface::class);
213     $this->keyValueFactory->get('entity.definitions.bundle_field_map')->willReturn($key_value_store->reveal());
214     $key_value_store->get('test_entity_type')->willReturn([
215       'test_field' => [
216         'type' => 'test_type',
217         'bundles' => ['test_bundle' => 'test_bundle'],
218       ],
219       'second_field' => [
220         'type' => 'test_type',
221         'bundles' => ['test_bundle' => 'test_bundle'],
222       ],
223     ]);
224     $key_value_store->set('test_entity_type', [
225       'second_field' => [
226         'type' => 'test_type',
227         'bundles' => ['test_bundle' => 'test_bundle'],
228       ],
229     ])
230       ->shouldBeCalled();
231
232     $this->fieldDefinitionListener->onFieldDefinitionDelete($field_definition->reveal());
233   }
234
235
236   /**
237    * @covers ::onFieldDefinitionDelete
238    */
239   public function testOnFieldDefinitionDeleteSingleBundles() {
240     $field_definition = $this->prophesize(FieldDefinitionInterface::class);
241     $field_definition->getTargetEntityTypeId()->willReturn('test_entity_type');
242     $field_definition->getTargetBundle()->willReturn('test_bundle');
243     $field_definition->getName()->willReturn('test_field');
244
245     $storage = $this->prophesize(DynamicallyFieldableEntityStorageInterface::class);
246     $storage->onFieldDefinitionDelete($field_definition->reveal())->shouldBeCalledTimes(1);
247     $this->entityTypeManager->getStorage('test_entity_type')->willReturn($storage->reveal());
248
249     $entity = $this->prophesize(EntityTypeInterface::class);
250     $this->setUpEntityManager(['test_entity_type' => $entity]);
251
252     // Set up the stored bundle field map.
253     $key_value_store = $this->prophesize(KeyValueStoreInterface::class);
254     $this->keyValueFactory->get('entity.definitions.bundle_field_map')->willReturn($key_value_store->reveal());
255     $key_value_store->get('test_entity_type')->willReturn([
256       'test_field' => [
257         'type' => 'test_type',
258         'bundles' => ['test_bundle' => 'test_bundle', 'second_bundle' => 'second_bundle'],
259       ],
260     ]);
261     $key_value_store->set('test_entity_type', [
262       'test_field' => [
263         'type' => 'test_type',
264         'bundles' => ['second_bundle' => 'second_bundle'],
265       ],
266     ])
267       ->shouldBeCalled();
268
269     $this->fieldDefinitionListener->onFieldDefinitionDelete($field_definition->reveal());
270   }
271
272 }