Updated to Drupal 8.6.4, which is PHP 7.3 friendly. Also updated HTMLaw library....
[yaffs-website] / web / core / modules / layout_builder / tests / src / Unit / OverridesSectionStorageTest.php
1 <?php
2
3 namespace Drupal\Tests\layout_builder\Unit;
4
5 use Drupal\Core\Entity\EntityFieldManagerInterface;
6 use Drupal\Core\Entity\EntityStorageInterface;
7 use Drupal\Core\Entity\EntityTypeInterface;
8 use Drupal\Core\Entity\EntityTypeManagerInterface;
9 use Drupal\Core\Entity\FieldableEntityInterface;
10 use Drupal\Core\Field\FieldStorageDefinitionInterface;
11 use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage;
12 use Drupal\layout_builder\SectionStorage\SectionStorageDefinition;
13 use Drupal\Tests\UnitTestCase;
14 use Prophecy\Argument;
15 use Symfony\Component\Routing\Route;
16 use Symfony\Component\Routing\RouteCollection;
17
18 /**
19  * @coversDefaultClass \Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage
20  *
21  * @group layout_builder
22  */
23 class OverridesSectionStorageTest extends UnitTestCase {
24
25   /**
26    * The plugin.
27    *
28    * @var \Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage
29    */
30   protected $plugin;
31
32   /**
33    * The entity type manager.
34    *
35    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
36    */
37   protected $entityTypeManager;
38
39   /**
40    * The entity field manager.
41    *
42    * @var \Drupal\Core\Entity\EntityFieldManagerInterface
43    */
44   protected $entityFieldManager;
45
46   /**
47    * {@inheritdoc}
48    */
49   protected function setUp() {
50     parent::setUp();
51
52     $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
53     $this->entityFieldManager = $this->prophesize(EntityFieldManagerInterface::class);
54
55     $definition = new SectionStorageDefinition([
56       'id' => 'overrides',
57       'class' => OverridesSectionStorage::class,
58     ]);
59     $this->plugin = new OverridesSectionStorage([], 'overrides', $definition, $this->entityTypeManager->reveal(), $this->entityFieldManager->reveal());
60   }
61
62   /**
63    * @covers ::extractIdFromRoute
64    *
65    * @dataProvider providerTestExtractIdFromRoute
66    */
67   public function testExtractIdFromRoute($expected, $value, array $defaults) {
68     $result = $this->plugin->extractIdFromRoute($value, [], 'the_parameter_name', $defaults);
69     $this->assertSame($expected, $result);
70   }
71
72   /**
73    * Provides data for ::testExtractIdFromRoute().
74    */
75   public function providerTestExtractIdFromRoute() {
76     $data = [];
77     $data['with value, with layout'] = [
78       'my_entity_type.entity_with_layout',
79       'my_entity_type.entity_with_layout',
80       [],
81     ];
82     $data['with value, without layout'] = [
83       NULL,
84       'my_entity_type',
85       [],
86     ];
87     $data['empty value, populated defaults'] = [
88       'my_entity_type.entity_with_layout',
89       '',
90       [
91         'entity_type_id' => 'my_entity_type',
92         'my_entity_type' => 'entity_with_layout',
93       ],
94     ];
95     $data['empty value, empty defaults'] = [
96       NULL,
97       '',
98       [],
99     ];
100     return $data;
101   }
102
103   /**
104    * @covers ::getSectionListFromId
105    *
106    * @dataProvider providerTestGetSectionListFromId
107    */
108   public function testGetSectionListFromId($success, $expected_entity_type_id, $id) {
109     $defaults['the_parameter_name'] = $id;
110
111     if ($expected_entity_type_id) {
112       $entity_storage = $this->prophesize(EntityStorageInterface::class);
113
114       $entity_without_layout = $this->prophesize(FieldableEntityInterface::class);
115       $entity_without_layout->hasField('layout_builder__layout')->willReturn(FALSE);
116       $entity_without_layout->get('layout_builder__layout')->shouldNotBeCalled();
117       $entity_storage->load('entity_without_layout')->willReturn($entity_without_layout->reveal());
118
119       $entity_with_layout = $this->prophesize(FieldableEntityInterface::class);
120       $entity_with_layout->hasField('layout_builder__layout')->willReturn(TRUE);
121       $entity_with_layout->get('layout_builder__layout')->willReturn('the_return_value');
122       $entity_storage->load('entity_with_layout')->willReturn($entity_with_layout->reveal());
123
124       $this->entityTypeManager->getStorage($expected_entity_type_id)->willReturn($entity_storage->reveal());
125     }
126     else {
127       $this->entityTypeManager->getStorage(Argument::any())->shouldNotBeCalled();
128     }
129
130     if (!$success) {
131       $this->setExpectedException(\InvalidArgumentException::class);
132     }
133
134     $result = $this->plugin->getSectionListFromId($id);
135     if ($success) {
136       $this->assertEquals('the_return_value', $result);
137     }
138   }
139
140   /**
141    * Provides data for ::testGetSectionListFromId().
142    */
143   public function providerTestGetSectionListFromId() {
144     $data = [];
145     $data['with value, with layout'] = [
146       TRUE,
147       'my_entity_type',
148       'my_entity_type.entity_with_layout',
149     ];
150     $data['with value, without layout'] = [
151       FALSE,
152       'my_entity_type',
153       'my_entity_type.entity_without_layout',
154     ];
155     $data['empty value, empty defaults'] = [
156       FALSE,
157       NULL,
158       '',
159     ];
160     return $data;
161   }
162
163   /**
164    * @covers ::buildRoutes
165    * @covers ::hasIntegerId
166    * @covers ::getEntityTypes
167    */
168   public function testBuildRoutes() {
169     $entity_types = [];
170
171     $not_fieldable = $this->prophesize(EntityTypeInterface::class);
172     $not_fieldable->entityClassImplements(FieldableEntityInterface::class)->willReturn(FALSE);
173     $entity_types['not_fieldable'] = $not_fieldable->reveal();
174
175     $no_view_builder = $this->prophesize(EntityTypeInterface::class);
176     $no_view_builder->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
177     $no_view_builder->hasViewBuilderClass()->willReturn(FALSE);
178     $entity_types['no_view_builder'] = $no_view_builder->reveal();
179
180     $no_canonical_link = $this->prophesize(EntityTypeInterface::class);
181     $no_canonical_link->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
182     $no_canonical_link->hasViewBuilderClass()->willReturn(TRUE);
183     $no_canonical_link->hasLinkTemplate('canonical')->willReturn(FALSE);
184     $entity_types['no_canonical_link'] = $no_canonical_link->reveal();
185     $this->entityFieldManager->getFieldStorageDefinitions('no_canonical_link')->shouldNotBeCalled();
186
187     $with_string_id = $this->prophesize(EntityTypeInterface::class);
188     $with_string_id->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
189     $with_string_id->hasViewBuilderClass()->willReturn(TRUE);
190     $with_string_id->hasLinkTemplate('canonical')->willReturn(TRUE);
191     $with_string_id->getLinkTemplate('canonical')->willReturn('/entity/{entity}');
192     $with_string_id->id()->willReturn('with_string_id');
193     $with_string_id->getKey('id')->willReturn('id');
194     $entity_types['with_string_id'] = $with_string_id->reveal();
195     $string_id = $this->prophesize(FieldStorageDefinitionInterface::class);
196     $string_id->getType()->willReturn('string');
197     $this->entityFieldManager->getFieldStorageDefinitions('with_string_id')->willReturn(['id' => $string_id->reveal()]);
198
199     $with_integer_id = $this->prophesize(EntityTypeInterface::class);
200     $with_integer_id->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
201     $with_integer_id->hasViewBuilderClass()->willReturn(TRUE);
202     $with_integer_id->hasLinkTemplate('canonical')->willReturn(TRUE);
203     $with_integer_id->getLinkTemplate('canonical')->willReturn('/entity/{entity}');
204     $with_integer_id->id()->willReturn('with_integer_id');
205     $with_integer_id->getKey('id')->willReturn('id');
206     $entity_types['with_integer_id'] = $with_integer_id->reveal();
207     $integer_id = $this->prophesize(FieldStorageDefinitionInterface::class);
208     $integer_id->getType()->willReturn('integer');
209     $this->entityFieldManager->getFieldStorageDefinitions('with_integer_id')->willReturn(['id' => $integer_id->reveal()]);
210
211     $this->entityTypeManager->getDefinitions()->willReturn($entity_types);
212
213     $expected = [
214       'layout_builder.overrides.with_string_id.view' => new Route(
215         '/entity/{entity}/layout',
216         [
217           'entity_type_id' => 'with_string_id',
218           'section_storage_type' => 'overrides',
219           'section_storage' => '',
220           'is_rebuilding' => FALSE,
221           '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::layout',
222           '_title_callback' => '\Drupal\layout_builder\Controller\LayoutBuilderController::title',
223         ],
224         [
225           '_has_layout_section' => 'true',
226           '_layout_builder_access' => 'view',
227         ],
228         [
229           'parameters' => [
230             'section_storage' => ['layout_builder_tempstore' => TRUE],
231             'with_string_id' => ['type' => 'entity:with_string_id'],
232           ],
233           '_layout_builder' => TRUE,
234         ]
235       ),
236       'layout_builder.overrides.with_string_id.save' => new Route(
237         '/entity/{entity}/layout/save',
238         [
239           'entity_type_id' => 'with_string_id',
240           'section_storage_type' => 'overrides',
241           'section_storage' => '',
242           '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::saveLayout',
243         ],
244         [
245           '_has_layout_section' => 'true',
246           '_layout_builder_access' => 'view',
247         ],
248         [
249           'parameters' => [
250             'section_storage' => ['layout_builder_tempstore' => TRUE],
251             'with_string_id' => ['type' => 'entity:with_string_id'],
252           ],
253           '_layout_builder' => TRUE,
254         ]
255       ),
256       'layout_builder.overrides.with_string_id.cancel' => new Route(
257         '/entity/{entity}/layout/cancel',
258         [
259           'entity_type_id' => 'with_string_id',
260           'section_storage_type' => 'overrides',
261           'section_storage' => '',
262           '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::cancelLayout',
263         ],
264         [
265           '_has_layout_section' => 'true',
266           '_layout_builder_access' => 'view',
267         ],
268         [
269           'parameters' => [
270             'section_storage' => ['layout_builder_tempstore' => TRUE],
271             'with_string_id' => ['type' => 'entity:with_string_id'],
272           ],
273           '_layout_builder' => TRUE,
274         ]
275       ),
276       'layout_builder.overrides.with_string_id.revert' => new Route(
277         '/entity/{entity}/layout/revert',
278         [
279           'entity_type_id' => 'with_string_id',
280           'section_storage_type' => 'overrides',
281           'section_storage' => '',
282           '_form' => '\Drupal\layout_builder\Form\RevertOverridesForm',
283         ],
284         [
285           '_has_layout_section' => 'true',
286           '_layout_builder_access' => 'view',
287         ],
288         [
289           'parameters' => [
290             'section_storage' => ['layout_builder_tempstore' => TRUE],
291             'with_string_id' => ['type' => 'entity:with_string_id'],
292           ],
293           '_layout_builder' => TRUE,
294         ]
295       ),
296       'layout_builder.overrides.with_integer_id.view' => new Route(
297         '/entity/{entity}/layout',
298         [
299           'entity_type_id' => 'with_integer_id',
300           'section_storage_type' => 'overrides',
301           'section_storage' => '',
302           'is_rebuilding' => FALSE,
303           '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::layout',
304           '_title_callback' => '\Drupal\layout_builder\Controller\LayoutBuilderController::title',
305         ],
306         [
307           '_has_layout_section' => 'true',
308           '_layout_builder_access' => 'view',
309           'with_integer_id' => '\d+',
310         ],
311         [
312           'parameters' => [
313             'section_storage' => ['layout_builder_tempstore' => TRUE],
314             'with_integer_id' => ['type' => 'entity:with_integer_id'],
315           ],
316           '_layout_builder' => TRUE,
317         ]
318       ),
319       'layout_builder.overrides.with_integer_id.save' => new Route(
320         '/entity/{entity}/layout/save',
321         [
322           'entity_type_id' => 'with_integer_id',
323           'section_storage_type' => 'overrides',
324           'section_storage' => '',
325           '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::saveLayout',
326         ],
327         [
328           '_has_layout_section' => 'true',
329           '_layout_builder_access' => 'view',
330           'with_integer_id' => '\d+',
331         ],
332         [
333           'parameters' => [
334             'section_storage' => ['layout_builder_tempstore' => TRUE],
335             'with_integer_id' => ['type' => 'entity:with_integer_id'],
336           ],
337           '_layout_builder' => TRUE,
338         ]
339       ),
340       'layout_builder.overrides.with_integer_id.cancel' => new Route(
341         '/entity/{entity}/layout/cancel',
342         [
343           'entity_type_id' => 'with_integer_id',
344           'section_storage_type' => 'overrides',
345           'section_storage' => '',
346           '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::cancelLayout',
347         ],
348         [
349           '_has_layout_section' => 'true',
350           '_layout_builder_access' => 'view',
351           'with_integer_id' => '\d+',
352         ],
353         [
354           'parameters' => [
355             'section_storage' => ['layout_builder_tempstore' => TRUE],
356             'with_integer_id' => ['type' => 'entity:with_integer_id'],
357           ],
358           '_layout_builder' => TRUE,
359         ]
360       ),
361       'layout_builder.overrides.with_integer_id.revert' => new Route(
362         '/entity/{entity}/layout/revert',
363         [
364           'entity_type_id' => 'with_integer_id',
365           'section_storage_type' => 'overrides',
366           'section_storage' => '',
367           '_form' => '\Drupal\layout_builder\Form\RevertOverridesForm',
368         ],
369         [
370           '_has_layout_section' => 'true',
371           '_layout_builder_access' => 'view',
372           'with_integer_id' => '\d+',
373         ],
374         [
375           'parameters' => [
376             'section_storage' => ['layout_builder_tempstore' => TRUE],
377             'with_integer_id' => ['type' => 'entity:with_integer_id'],
378           ],
379           '_layout_builder' => TRUE,
380         ]
381       ),
382     ];
383
384     $collection = new RouteCollection();
385     $this->plugin->buildRoutes($collection);
386     $this->assertEquals($expected, $collection->all());
387     $this->assertSame(array_keys($expected), array_keys($collection->all()));
388   }
389
390 }