3 namespace Drupal\Tests\layout_builder\Unit;
5 use Drupal\Core\Entity\EntityStorageInterface;
6 use Drupal\Core\Entity\EntityType;
7 use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
8 use Drupal\Core\Entity\EntityTypeInterface;
9 use Drupal\Core\Entity\EntityTypeManagerInterface;
10 use Drupal\Core\Entity\FieldableEntityInterface;
11 use Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator;
12 use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
13 use Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage;
14 use Drupal\layout_builder\SectionStorage\SectionStorageDefinition;
15 use Drupal\Tests\UnitTestCase;
16 use Symfony\Component\Routing\Route;
17 use Symfony\Component\Routing\RouteCollection;
20 * @coversDefaultClass \Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage
22 * @group layout_builder
24 class DefaultsSectionStorageTest extends UnitTestCase {
29 * @var \Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage
36 * @var \Drupal\Core\Entity\EntityManagerInterface
38 protected $entityTypeManager;
43 protected function setUp() {
46 $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
47 $entity_type_bundle_info = $this->prophesize(EntityTypeBundleInfoInterface::class);
48 $sample_entity_generator = $this->prophesize(LayoutBuilderSampleEntityGenerator::class);
50 $definition = new SectionStorageDefinition([
52 'class' => DefaultsSectionStorage::class,
54 $this->plugin = new DefaultsSectionStorage([], '', $definition, $this->entityTypeManager->reveal(), $entity_type_bundle_info->reveal(), $sample_entity_generator->reveal());
58 * @covers ::getThirdPartySetting
59 * @covers ::setThirdPartySetting
61 public function testThirdPartySettings() {
62 // Set an initial value on the section list.
63 $section_list = $this->prophesize(LayoutEntityDisplayInterface::class);
64 $section_list->getThirdPartySetting('the_module', 'the_key', NULL)->willReturn('value 1');
65 $this->plugin->setSectionList($section_list->reveal());
67 // The plugin returns the initial value.
68 $this->assertSame('value 1', $this->plugin->getThirdPartySetting('the_module', 'the_key'));
70 // When the section list is updated, also update the result returned.
71 $section_list->setThirdPartySetting('the_module', 'the_key', 'value 2')->shouldBeCalled()->will(function ($args) {
72 $this->getThirdPartySetting('the_module', 'the_key', NULL)->willReturn($args[2]);
75 // Update the plugin value.
76 $this->plugin->setThirdPartySetting('the_module', 'the_key', 'value 2');
77 // Assert that the returned value matches.
78 $this->assertSame('value 2', $this->plugin->getThirdPartySetting('the_module', 'the_key'));
82 * @covers ::extractIdFromRoute
84 * @dataProvider providerTestExtractIdFromRoute
86 public function testExtractIdFromRoute($expected, $value, array $defaults) {
87 $result = $this->plugin->extractIdFromRoute($value, [], 'the_parameter_name', $defaults);
88 $this->assertSame($expected, $result);
92 * Provides data for ::testExtractIdFromRoute().
94 public function providerTestExtractIdFromRoute() {
96 $data['with value'] = [
101 $data['empty value, without bundle'] = [
102 'my_entity_type.bundle_name.default',
105 'entity_type_id' => 'my_entity_type',
106 'view_mode_name' => 'default',
107 'bundle_key' => 'my_bundle',
108 'my_bundle' => 'bundle_name',
111 $data['empty value, with bundle'] = [
112 'my_entity_type.bundle_name.default',
115 'entity_type_id' => 'my_entity_type',
116 'view_mode_name' => 'default',
117 'bundle' => 'bundle_name',
120 $data['without value, empty defaults'] = [
129 * @covers ::getSectionListFromId
131 * @dataProvider providerTestGetSectionListFromId
133 public function testGetSectionListFromId($success, $expected_entity_id, $value) {
134 if ($expected_entity_id) {
135 $entity_storage = $this->prophesize(EntityStorageInterface::class);
136 $entity_storage->load($expected_entity_id)->willReturn('the_return_value');
138 $this->entityTypeManager->getDefinition('entity_view_display')->willReturn(new EntityType(['id' => 'entity_view_display']));
139 $this->entityTypeManager->getStorage('entity_view_display')->willReturn($entity_storage->reveal());
142 $this->entityTypeManager->getDefinition('entity_view_display')->shouldNotBeCalled();
143 $this->entityTypeManager->getStorage('entity_view_display')->shouldNotBeCalled();
147 $this->setExpectedException(\InvalidArgumentException::class);
150 $result = $this->plugin->getSectionListFromId($value);
152 $this->assertEquals('the_return_value', $result);
157 * Provides data for ::testGetSectionListFromId().
159 public function providerTestGetSectionListFromId() {
161 $data['with value'] = [
166 $data['without value, empty defaults'] = [
175 * @covers ::getSectionListFromId
177 public function testGetSectionListFromIdCreate() {
178 $expected = 'the_return_value';
179 $value = 'foo.bar.baz';
180 $expected_create_values = [
181 'targetEntityType' => 'foo',
186 $entity_storage = $this->prophesize(EntityStorageInterface::class);
187 $entity_storage->load($value)->willReturn(NULL);
188 $entity_storage->create($expected_create_values)->willReturn($expected);
190 $this->entityTypeManager->getDefinition('entity_view_display')->willReturn(new EntityType(['id' => 'entity_view_display']));
191 $this->entityTypeManager->getStorage('entity_view_display')->willReturn($entity_storage->reveal());
193 $result = $this->plugin->getSectionListFromId($value);
194 $this->assertSame($expected, $result);
198 * @covers ::buildRoutes
199 * @covers ::getEntityTypes
201 public function testBuildRoutes() {
204 $not_fieldable = $this->prophesize(EntityTypeInterface::class);
205 $not_fieldable->entityClassImplements(FieldableEntityInterface::class)->willReturn(FALSE);
206 $entity_types['not_fieldable'] = $not_fieldable->reveal();
208 $no_view_builder = $this->prophesize(EntityTypeInterface::class);
209 $no_view_builder->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
210 $no_view_builder->hasViewBuilderClass()->willReturn(FALSE);
211 $entity_types['no_view_builder'] = $no_view_builder->reveal();
213 $no_field_ui_route = $this->prophesize(EntityTypeInterface::class);
214 $no_field_ui_route->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
215 $no_field_ui_route->hasViewBuilderClass()->willReturn(TRUE);
216 $no_field_ui_route->get('field_ui_base_route')->willReturn(NULL);
217 $entity_types['no_field_ui_route'] = $no_field_ui_route->reveal();
219 $unknown_field_ui_route = $this->prophesize(EntityTypeInterface::class);
220 $unknown_field_ui_route->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
221 $unknown_field_ui_route->hasViewBuilderClass()->willReturn(TRUE);
222 $unknown_field_ui_route->get('field_ui_base_route')->willReturn('unknown');
223 $entity_types['unknown_field_ui_route'] = $unknown_field_ui_route->reveal();
225 $with_bundle_key = $this->prophesize(EntityTypeInterface::class);
226 $with_bundle_key->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
227 $with_bundle_key->hasViewBuilderClass()->willReturn(TRUE);
228 $with_bundle_key->get('field_ui_base_route')->willReturn('known');
229 $with_bundle_key->hasKey('bundle')->willReturn(TRUE);
230 $with_bundle_key->getBundleEntityType()->willReturn('my_bundle_type');
231 $entity_types['with_bundle_key'] = $with_bundle_key->reveal();
233 $with_bundle_parameter = $this->prophesize(EntityTypeInterface::class);
234 $with_bundle_parameter->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
235 $with_bundle_parameter->hasViewBuilderClass()->willReturn(TRUE);
236 $with_bundle_parameter->get('field_ui_base_route')->willReturn('with_bundle');
237 $entity_types['with_bundle_parameter'] = $with_bundle_parameter->reveal();
238 $this->entityTypeManager->getDefinitions()->willReturn($entity_types);
241 'known' => new Route('/admin/entity/whatever', [], [], ['_admin_route' => TRUE]),
242 'with_bundle' => new Route('/admin/entity/{bundle}'),
243 'layout_builder.defaults.with_bundle_key.view' => new Route(
244 '/admin/entity/whatever/display-layout/{view_mode_name}',
246 'entity_type_id' => 'with_bundle_key',
247 'bundle_key' => 'my_bundle_type',
248 'section_storage_type' => 'defaults',
249 'section_storage' => '',
250 'is_rebuilding' => FALSE,
251 '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::layout',
252 '_title_callback' => '\Drupal\layout_builder\Controller\LayoutBuilderController::title',
255 '_field_ui_view_mode_access' => 'administer with_bundle_key display',
256 '_has_layout_section' => 'true',
257 '_layout_builder_access' => 'view',
261 'section_storage' => ['layout_builder_tempstore' => TRUE],
263 '_layout_builder' => TRUE,
264 '_admin_route' => FALSE,
267 'layout_builder.defaults.with_bundle_key.save' => new Route(
268 '/admin/entity/whatever/display-layout/{view_mode_name}/save',
270 'entity_type_id' => 'with_bundle_key',
271 'bundle_key' => 'my_bundle_type',
272 'section_storage_type' => 'defaults',
273 'section_storage' => '',
274 '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::saveLayout',
277 '_field_ui_view_mode_access' => 'administer with_bundle_key display',
278 '_has_layout_section' => 'true',
279 '_layout_builder_access' => 'view',
283 'section_storage' => ['layout_builder_tempstore' => TRUE],
285 '_layout_builder' => TRUE,
286 '_admin_route' => FALSE,
289 'layout_builder.defaults.with_bundle_key.cancel' => new Route(
290 '/admin/entity/whatever/display-layout/{view_mode_name}/cancel',
292 'entity_type_id' => 'with_bundle_key',
293 'bundle_key' => 'my_bundle_type',
294 'section_storage_type' => 'defaults',
295 'section_storage' => '',
296 '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::cancelLayout',
299 '_field_ui_view_mode_access' => 'administer with_bundle_key display',
300 '_has_layout_section' => 'true',
301 '_layout_builder_access' => 'view',
305 'section_storage' => ['layout_builder_tempstore' => TRUE],
307 '_layout_builder' => TRUE,
308 '_admin_route' => FALSE,
311 'layout_builder.defaults.with_bundle_key.disable' => new Route(
312 '/admin/entity/whatever/display-layout/{view_mode_name}/disable',
314 'entity_type_id' => 'with_bundle_key',
315 'bundle_key' => 'my_bundle_type',
316 'section_storage_type' => 'defaults',
317 'section_storage' => '',
318 '_form' => '\Drupal\layout_builder\Form\LayoutBuilderDisableForm',
321 '_field_ui_view_mode_access' => 'administer with_bundle_key display',
322 '_has_layout_section' => 'true',
323 '_layout_builder_access' => 'view',
327 'section_storage' => ['layout_builder_tempstore' => TRUE],
331 'layout_builder.defaults.with_bundle_parameter.view' => new Route(
332 '/admin/entity/{bundle}/display-layout/{view_mode_name}',
334 'entity_type_id' => 'with_bundle_parameter',
335 'section_storage_type' => 'defaults',
336 'section_storage' => '',
337 'is_rebuilding' => FALSE,
338 '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::layout',
339 '_title_callback' => '\Drupal\layout_builder\Controller\LayoutBuilderController::title',
342 '_field_ui_view_mode_access' => 'administer with_bundle_parameter display',
343 '_has_layout_section' => 'true',
344 '_layout_builder_access' => 'view',
348 'section_storage' => ['layout_builder_tempstore' => TRUE],
350 '_layout_builder' => TRUE,
351 '_admin_route' => FALSE,
354 'layout_builder.defaults.with_bundle_parameter.save' => new Route(
355 '/admin/entity/{bundle}/display-layout/{view_mode_name}/save',
357 'entity_type_id' => 'with_bundle_parameter',
358 'section_storage_type' => 'defaults',
359 'section_storage' => '',
360 '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::saveLayout',
363 '_field_ui_view_mode_access' => 'administer with_bundle_parameter display',
364 '_has_layout_section' => 'true',
365 '_layout_builder_access' => 'view',
369 'section_storage' => ['layout_builder_tempstore' => TRUE],
371 '_layout_builder' => TRUE,
372 '_admin_route' => FALSE,
375 'layout_builder.defaults.with_bundle_parameter.cancel' => new Route(
376 '/admin/entity/{bundle}/display-layout/{view_mode_name}/cancel',
378 'entity_type_id' => 'with_bundle_parameter',
379 'section_storage_type' => 'defaults',
380 'section_storage' => '',
381 '_controller' => '\Drupal\layout_builder\Controller\LayoutBuilderController::cancelLayout',
384 '_field_ui_view_mode_access' => 'administer with_bundle_parameter display',
385 '_has_layout_section' => 'true',
386 '_layout_builder_access' => 'view',
390 'section_storage' => ['layout_builder_tempstore' => TRUE],
392 '_layout_builder' => TRUE,
393 '_admin_route' => FALSE,
396 'layout_builder.defaults.with_bundle_parameter.disable' => new Route(
397 '/admin/entity/{bundle}/display-layout/{view_mode_name}/disable',
399 'entity_type_id' => 'with_bundle_parameter',
400 'section_storage_type' => 'defaults',
401 'section_storage' => '',
402 '_form' => '\Drupal\layout_builder\Form\LayoutBuilderDisableForm',
405 '_field_ui_view_mode_access' => 'administer with_bundle_parameter display',
406 '_has_layout_section' => 'true',
407 '_layout_builder_access' => 'view',
411 'section_storage' => ['layout_builder_tempstore' => TRUE],
417 $collection = new RouteCollection();
418 $collection->add('known', new Route('/admin/entity/whatever', [], [], ['_admin_route' => TRUE]));
419 $collection->add('with_bundle', new Route('/admin/entity/{bundle}'));
421 $this->plugin->buildRoutes($collection);
422 $this->assertEquals($expected, $collection->all());
423 $this->assertSame(array_keys($expected), array_keys($collection->all()));