diff --git a/modules/ui_patterns_blocks/src/Plugin/Block/ComponentBlock.php b/modules/ui_patterns_blocks/src/Plugin/Block/ComponentBlock.php index f81a48a6abed8b469ea57e6ccae8a7d1a614a098..ba16ef0e3c25b8ebf399ed0e8f66dc527b3087c2 100644 --- a/modules/ui_patterns_blocks/src/Plugin/Block/ComponentBlock.php +++ b/modules/ui_patterns_blocks/src/Plugin/Block/ComponentBlock.php @@ -127,7 +127,7 @@ class ComponentBlock extends BlockBase implements ContainerFactoryPluginInterfac * @return array * Source contexts. */ - protected function getComponentSourceContexts(FormStateInterface $form_state = NULL): array { + protected function getComponentSourceContexts(?FormStateInterface $form_state = NULL): array { if (!isset($this->context['entity']) || !($this->context['entity']->getContextValue() instanceof EntityInterface)) { $contexts = $this->context; if ($form_state !== NULL) { diff --git a/modules/ui_patterns_field_formatters/tests/src/Functional/FieldFormatterRenderTest.php b/modules/ui_patterns_field_formatters/tests/src/Functional/FieldFormatterRenderTest.php index d792950f184d5ac02ef7b0f80bcd1ef04e344c4d..eac1dd2d756fd1fc97f46221191e2f12f653738d 100644 --- a/modules/ui_patterns_field_formatters/tests/src/Functional/FieldFormatterRenderTest.php +++ b/modules/ui_patterns_field_formatters/tests/src/Functional/FieldFormatterRenderTest.php @@ -8,7 +8,7 @@ use Drupal\Tests\ui_patterns\Traits\TestDataTrait; /** * Test pattern preview rendering. * - * @group ui_patterns_layouts + * @group ui_patterns_field_formatters */ class FieldFormatterRenderTest extends UiPatternsFunctionalTestBase { diff --git a/modules/ui_patterns_field_formatters/tests/src/Functional/LayoutBuilderFieldFormatterRenderTest.php b/modules/ui_patterns_field_formatters/tests/src/Functional/LayoutBuilderFieldFormatterRenderTest.php index dfba6cd4fc67dc4d65bfeea186284b34ca0b56e8..e8b7f4196296c2422108368d09ba4e9d2ba89520 100644 --- a/modules/ui_patterns_field_formatters/tests/src/Functional/LayoutBuilderFieldFormatterRenderTest.php +++ b/modules/ui_patterns_field_formatters/tests/src/Functional/LayoutBuilderFieldFormatterRenderTest.php @@ -8,7 +8,7 @@ use Drupal\Tests\ui_patterns\Traits\TestDataTrait; /** * Test pattern preview rendering. * - * @group ui_patterns_layouts + * @group ui_patterns_field_formatters */ class LayoutBuilderFieldFormatterRenderTest extends UiPatternsFunctionalTestBase { @@ -21,7 +21,6 @@ class LayoutBuilderFieldFormatterRenderTest extends UiPatternsFunctionalTestBase 'node', 'ui_patterns', 'ui_patterns_test', - 'ui_patterns_layouts', 'ui_patterns_field_formatters', 'field_ui', 'layout_builder', @@ -90,49 +89,6 @@ class LayoutBuilderFieldFormatterRenderTest extends UiPatternsFunctionalTestBase $this->assertSessionObject($test_set["assertSession"]); } } - $tests = $test_data->getTestSets(); - foreach ($tests as $test_set) { - if (!isset($test_set["component"]["slots"]) || !is_array($test_set["component"]["slots"]) || count($test_set["component"]["slots"]) < 1) { - continue; - } - $node = $this->createTestContentNode('page', $test_set['entity'] ?? []); - $ui_patterns_config_to_set = $this->buildUiPatternsConfig($test_set); - // ----- - // Layout builder classic - $config_import = $this->loadConfigFixture(__DIR__ . '/../../fixtures/config/core.entity_view_display.node.page.full.layout_builder.section_component.yml'); - $ui_patterns_config_lb_1 = &$config_import['third_party_settings']['layout_builder']['sections'][0]['layout_settings']['ui_patterns']; - $ui_patterns_config_lb_1 = $ui_patterns_config_to_set; - $field_name = (isset($test_set["contexts"]) && isset($test_set["contexts"]["field_name"])) ? $test_set["contexts"]["field_name"] : "body"; - if (!empty($field_name) && $field_name !== "body") { - - $config_id = $config_import['third_party_settings']['layout_builder']['sections'][0]['components']['2b7726dd-cf0a-4b6c-b2d6-3c7e9b3bab33']['configuration']['id']; - $config_import['third_party_settings']['layout_builder']['sections'][0]['components']['2b7726dd-cf0a-4b6c-b2d6-3c7e9b3bab33']['configuration']['id'] = str_replace(":body", ":" . $field_name, $config_id); - } - $slots_of_component = $test_set["component"]["slots"]; - $first_slot = array_keys($slots_of_component)[0]; - $config_import['third_party_settings']['layout_builder']['sections'][0]['components']['2b7726dd-cf0a-4b6c-b2d6-3c7e9b3bab33']["region"] = $first_slot; - $config_import['third_party_settings']['layout_builder']['sections'][0]['layout_id'] = sprintf("ui_patterns:%s", str_replace("-", "_", $ui_patterns_config_to_set["component_id"])); - $this->importConfigFixture('core.entity_view_display.node.page.full', $config_import); - $this->drupalGet('node/' . $node->id()); - $status_code = $this->getSession()->getStatusCode(); - $this->assertTrue($status_code === 200, sprintf('Status code is $status_code for test %s. %s', $test_set['name'], $this->getSession()->getPage()->getContent())); - $assert_session->statusCodeEquals(200); - $this->validateRenderedComponent([ - "component" => $test_set["component"], - "output" => [ - "slots" => [ - "wrapper" => [ - [ - "normalized_value" => "entity exists: 1", - ], - ], - ], - ], - ]); - if (isset($test_set["assertSession"])) { - $this->assertSessionObject($test_set["assertSession"]); - } - } } } diff --git a/modules/ui_patterns_field_formatters/tests/src/Functional/LayoutFieldFormatterRenderTest.php b/modules/ui_patterns_field_formatters/tests/src/Functional/LayoutFieldFormatterRenderTest.php index 4ee4e8ed0616c77ba26c29d798e81704b4571741..e0c2f126544b448d24cf9372bc867e3421f31255 100644 --- a/modules/ui_patterns_field_formatters/tests/src/Functional/LayoutFieldFormatterRenderTest.php +++ b/modules/ui_patterns_field_formatters/tests/src/Functional/LayoutFieldFormatterRenderTest.php @@ -21,26 +21,12 @@ class LayoutFieldFormatterRenderTest extends UiPatternsFunctionalTestBase { 'node', 'ui_patterns', 'ui_patterns_test', - 'ui_patterns_layouts', 'ui_patterns_field_formatters', 'field_ui', 'field_layout', 'block', ]; - /** - * {@inheritdoc} - */ - protected function setUp(): void { - parent::setUp(); - if ($this->user) { - /* $this->drupalCreateRole(['configure any layout'], 'custom_role'); - $this->user->addRole('custom_role'); - $this->user->save(); - */ - } - } - /** * Tests preview and output of props. */ @@ -70,47 +56,6 @@ class LayoutFieldFormatterRenderTest extends UiPatternsFunctionalTestBase { $this->assertSessionObject($test_set["assertSession"]); } } - $tests = $test_data->getTestSets(); - foreach ($tests as $test_set) { - if (!isset($test_set["component"]["slots"]) || !is_array($test_set["component"]["slots"]) || count($test_set["component"]["slots"]) < 1) { - continue; - } - $node = $this->createTestContentNode('page', $test_set['entity'] ?? []); - $ui_patterns_config_to_set = $this->buildUiPatternsConfig($test_set); - $slots_of_component = $test_set["component"]["slots"]; - $first_slot = array_keys($slots_of_component)[0]; - // ----- - // Field Layout with a component section - $config_import = $this->loadConfigFixture(__DIR__ . '/../../fixtures/config/core.entity_view_display.node.page.full.layout.section_component.yml'); - $ui_patterns_config_layout_2 = &$config_import['third_party_settings']['field_layout']['settings']['ui_patterns']; - $ui_patterns_config_layout_2 = $ui_patterns_config_to_set; - $field_name = (isset($test_set["contexts"]) && isset($test_set["contexts"]["field_name"])) ? $test_set["contexts"]["field_name"] : "body"; - if (!empty($field_name) && $field_name !== "body") { - $config_import['content'][$field_name] = $config_import['content']["body"]; - unset($config_import['content']["body"]); - } - $config_import['content'][$field_name]["region"] = $first_slot; - $config_import['third_party_settings']['field_layout']['id'] = sprintf("ui_patterns:%s", str_replace("-", "_", $ui_patterns_config_to_set["component_id"])); - $this->importConfigFixture('core.entity_view_display.node.page.full', $config_import); - $this->drupalGet('node/' . $node->id()); - $status_code = $this->getSession()->getStatusCode(); - $this->assertTrue($status_code === 200, sprintf('Status code is $status_code for test %s. %s', $test_set['name'], $this->getSession()->getPage()->getContent())); - $this->validateRenderedComponent([ - "component" => $test_set["component"], - "output" => [ - "slots" => [ - "wrapper" => [ - [ - "normalized_value" => "entity exists: 1", - ], - ], - ], - ], - ]); - if (isset($test_set["assertSession"])) { - $this->assertSessionObject($test_set["assertSession"]); - } - } } } diff --git a/modules/ui_patterns_field_formatters/tests/src/Kernel/SourcesDeriverTest.php b/modules/ui_patterns_field_formatters/tests/src/Kernel/SourcesDeriverTest.php index e6888338c0ced9741377e128a8867c25277aa880..c510ac29f6970fc3376c19f500f88119e3fb6c12 100644 --- a/modules/ui_patterns_field_formatters/tests/src/Kernel/SourcesDeriverTest.php +++ b/modules/ui_patterns_field_formatters/tests/src/Kernel/SourcesDeriverTest.php @@ -7,8 +7,8 @@ namespace Drupal\Tests\ui_patterns_field_formatters\Kernel; use Drupal\Component\Plugin\PluginBase; use Drupal\Core\Plugin\Context\ContextDefinition; use Drupal\Core\Plugin\Context\EntityContextDefinition; -use Drupal\node\Entity\NodeType; use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; +use Drupal\node\Entity\NodeType; use Drupal\ui_patterns_field_formatters\Plugin\UiPatterns\Source\FieldFormatterSource; /** diff --git a/modules/ui_patterns_layouts/src/Plugin/Layout/ComponentLayout.php b/modules/ui_patterns_layouts/src/Plugin/Layout/ComponentLayout.php index f90ecd94d29da606b9fd86676645455a0d82e2d1..e80d83d23cca4c4eb238162fdb9d9fa5d6cc92e4 100644 --- a/modules/ui_patterns_layouts/src/Plugin/Layout/ComponentLayout.php +++ b/modules/ui_patterns_layouts/src/Plugin/Layout/ComponentLayout.php @@ -13,7 +13,6 @@ use Drupal\Core\Plugin\Context\Context; use Drupal\Core\Plugin\Context\ContextDefinition; use Drupal\Core\Plugin\Context\EntityContext; use Drupal\Core\Plugin\ContextAwarePluginInterface; -use Drupal\Core\Plugin\PluginFormInterface; use Drupal\ui_patterns\Form\ComponentFormBuilderTrait; use Drupal\ui_patterns\Resolver\ChainContextEntityResolverInterface; use Drupal\ui_patterns\SourcePluginBase; @@ -27,7 +26,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; id: "ui_patterns", deriver: DerivativeComponentLayout::class )] -class ComponentLayout extends LayoutDefault implements ContainerFactoryPluginInterface, PluginFormInterface { +class ComponentLayout extends LayoutDefault implements ContainerFactoryPluginInterface { use ComponentFormBuilderTrait; @@ -105,7 +104,7 @@ class ComponentLayout extends LayoutDefault implements ContainerFactoryPluginInt * @return array * Source contexts. */ - protected function getComponentSourceContexts(FormStateInterface $form_state = NULL): array { + protected function getComponentSourceContexts(?FormStateInterface $form_state = NULL): array { if (!isset($this->context['entity']) || !($this->context['entity']->getContextValue() instanceof EntityInterface)) { $contexts = $this->context; if ($form_state !== NULL) { diff --git a/modules/ui_patterns_field_formatters/tests/fixtures/config/core.entity_view_display.node.page.full.layout.section_component.yml b/modules/ui_patterns_layouts/tests/fixtures/config/core.entity_view_display.node.page.full.layout.section_component.yml similarity index 100% rename from modules/ui_patterns_field_formatters/tests/fixtures/config/core.entity_view_display.node.page.full.layout.section_component.yml rename to modules/ui_patterns_layouts/tests/fixtures/config/core.entity_view_display.node.page.full.layout.section_component.yml index 7085278de1c93790ac017e5784b93db47221a8a5..4f6c6edd3fae198cc00776dc997571f13b0a0317 100644 --- a/modules/ui_patterns_field_formatters/tests/fixtures/config/core.entity_view_display.node.page.full.layout.section_component.yml +++ b/modules/ui_patterns_layouts/tests/fixtures/config/core.entity_view_display.node.page.full.layout.section_component.yml @@ -9,8 +9,8 @@ dependencies: module: - field_layout - ui_patterns - - ui_patterns_field_formatters - ui_patterns_layouts + - ui_patterns_field_formatters - user third_party_settings: field_layout: diff --git a/modules/ui_patterns_field_formatters/tests/fixtures/config/core.entity_view_display.node.page.full.layout_builder.section_component.yml b/modules/ui_patterns_layouts/tests/fixtures/config/core.entity_view_display.node.page.full.layout_builder.section_component.yml similarity index 100% rename from modules/ui_patterns_field_formatters/tests/fixtures/config/core.entity_view_display.node.page.full.layout_builder.section_component.yml rename to modules/ui_patterns_layouts/tests/fixtures/config/core.entity_view_display.node.page.full.layout_builder.section_component.yml index 167438dac6da3ba6bb180de42d8315f9e60df68c..7174f3b90108b710a74cd6f4a3577a06c5f50837 100644 --- a/modules/ui_patterns_field_formatters/tests/fixtures/config/core.entity_view_display.node.page.full.layout_builder.section_component.yml +++ b/modules/ui_patterns_layouts/tests/fixtures/config/core.entity_view_display.node.page.full.layout_builder.section_component.yml @@ -9,8 +9,8 @@ dependencies: module: - layout_builder - ui_patterns - - ui_patterns_field_formatters - ui_patterns_layouts + - ui_patterns_field_formatters - user third_party_settings: layout_builder: diff --git a/modules/ui_patterns_layouts/tests/src/fixtures/core.entity_view_display.node.page.full.yml b/modules/ui_patterns_layouts/tests/fixtures/config/core.entity_view_display.node.page.full.yml similarity index 100% rename from modules/ui_patterns_layouts/tests/src/fixtures/core.entity_view_display.node.page.full.yml rename to modules/ui_patterns_layouts/tests/fixtures/config/core.entity_view_display.node.page.full.yml diff --git a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/components/one-column/one-column.component.yml b/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/components/one-column/one-column.component.yml deleted file mode 100644 index 2dcedb6456344df41bcbf1a5e030235167dbeb2e..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/components/one-column/one-column.component.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: One columns -description: Widget Test with One Column -libraryOverrides: - dependencies: - - core/drupal -props: - type: object - properties: - heading: - title: Heading - description: The title for the banner text. - examples: - - Join us at The Conference - type: string -slots: - body: - title: Body - description: The contents of the banner. - examples: - - <p>Foo is <strong>NOT</strong> bar.</p> diff --git a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/components/one-column/one-column.twig b/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/components/one-column/one-column.twig deleted file mode 100644 index 27e50ffff0a1f59bdccd21597df12bfd41805038..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/components/one-column/one-column.twig +++ /dev/null @@ -1,4 +0,0 @@ -<div> -{% block body %} -{% endblock %} -</div> diff --git a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/config/install/core.entity_view_display.node.article.default.yml b/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/config/install/core.entity_view_display.node.article.default.yml deleted file mode 100644 index 5def63eb0f36e5061b098189b6962fe83a4c5c93..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/config/install/core.entity_view_display.node.article.default.yml +++ /dev/null @@ -1,30 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.field.node.article.body - - node.type.article - module: - - field_layout - - text - - ui_patterns_layouts_test - - user -third_party_settings: - field_layout: - id: ui_patterns_layouts_test:one_column - settings: - pattern: {} -id: node.article.default -targetEntityType: node -bundle: article -mode: default -content: - body: - type: text_default - weight: 0 - region: body - label: hidden - settings: {} - third_party_settings: {} -hidden: - links: true diff --git a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/config/install/field.field.node.article.body.yml b/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/config/install/field.field.node.article.body.yml deleted file mode 100644 index 472a420d03e0c89fa43cd2173c929e1bd05b159e..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/config/install/field.field.node.article.body.yml +++ /dev/null @@ -1,21 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.node.body - - node.type.article - module: - - text -id: node.article.body -field_name: body -entity_type: node -bundle: article -label: Body -description: "" -required: false -translatable: true -default_value: {} -default_value_callback: "" -settings: - display_summary: true -field_type: text_with_summary diff --git a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/config/install/node.type.article.yml b/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/config/install/node.type.article.yml deleted file mode 100644 index 148f23dc9f5d7aa6c023be9915f4194d2d542be6..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/config/install/node.type.article.yml +++ /dev/null @@ -1,10 +0,0 @@ -langcode: en -status: true -dependencies: {} -name: Article -type: article -description: "" -help: "" -new_revision: true -preview_mode: 1 -display_submitted: true diff --git a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/ui_patterns_layouts_test.info.yml b/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/ui_patterns_layouts_test.info.yml deleted file mode 100644 index 02edd04219f70fcb03774aaed96ee14a2a7d4a5e..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/modules/ui_patterns_layouts_test/ui_patterns_layouts_test.info.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: "UI Patterns Layouts Test" -type: module -description: "Test module for UI Patterns." -package: "Testing" -dependencies: - - drupal:field_layout - - drupal:field_ui - - drupal:node - - drupal:text - - ui_patterns:ui_patterns - - ui_patterns:ui_patterns_layouts -config_devel: - install: - - field.field.node.article.body - - node.type.article - - core.entity_view_display.node.article.default diff --git a/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderFieldFormatterRenderTest.php b/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderFieldFormatterRenderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2ababd0afd8c975cd2e29af329fb7fd33dfe6847 --- /dev/null +++ b/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderFieldFormatterRenderTest.php @@ -0,0 +1,93 @@ +<?php + +namespace Drupal\Tests\ui_patterns_layouts\Functional; + +use Drupal\Tests\ui_patterns\Functional\UiPatternsFunctionalTestBase; +use Drupal\Tests\ui_patterns\Traits\TestDataTrait; + +/** + * Test pattern preview rendering. + * + * @group ui_patterns_layouts + */ +class LayoutBuilderFieldFormatterRenderTest extends UiPatternsFunctionalTestBase { + + use TestDataTrait; + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'node', + 'ui_patterns', + 'ui_patterns_test', + 'ui_patterns_layouts', + 'ui_patterns_field_formatters', + 'field_ui', + 'layout_builder', + 'block', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + if ($this->user) { + $this->drupalCreateRole(['configure any layout'], 'custom_role'); + $this->user->addRole('custom_role'); + $this->user->save(); + } + } + + /** + * Tests preview and output of props. + */ + public function testRender(): void { + $assert_session = $this->assertSession(); + $test_data = self::loadTestDataFixture(); + $tests = $test_data->getTestSets(); + foreach ($tests as $test_set) { + if (!isset($test_set["component"]["slots"]) || !is_array($test_set["component"]["slots"]) || count($test_set["component"]["slots"]) < 1) { + continue; + } + $node = $this->createTestContentNode('page', $test_set['entity'] ?? []); + $ui_patterns_config_to_set = $this->buildUiPatternsConfig($test_set); + // ----- + // Layout builder classic + $config_import = $this->loadConfigFixture(__DIR__ . '/../../fixtures/config/core.entity_view_display.node.page.full.layout_builder.section_component.yml'); + $ui_patterns_config_lb_1 = &$config_import['third_party_settings']['layout_builder']['sections'][0]['layout_settings']['ui_patterns']; + $ui_patterns_config_lb_1 = $ui_patterns_config_to_set; + $field_name = (isset($test_set["contexts"]) && isset($test_set["contexts"]["field_name"])) ? $test_set["contexts"]["field_name"] : "body"; + if (!empty($field_name) && $field_name !== "body") { + + $config_id = $config_import['third_party_settings']['layout_builder']['sections'][0]['components']['2b7726dd-cf0a-4b6c-b2d6-3c7e9b3bab33']['configuration']['id']; + $config_import['third_party_settings']['layout_builder']['sections'][0]['components']['2b7726dd-cf0a-4b6c-b2d6-3c7e9b3bab33']['configuration']['id'] = str_replace(":body", ":" . $field_name, $config_id); + } + $slots_of_component = $test_set["component"]["slots"]; + $first_slot = array_keys($slots_of_component)[0]; + $config_import['third_party_settings']['layout_builder']['sections'][0]['components']['2b7726dd-cf0a-4b6c-b2d6-3c7e9b3bab33']["region"] = $first_slot; + $config_import['third_party_settings']['layout_builder']['sections'][0]['layout_id'] = sprintf("ui_patterns:%s", str_replace("-", "_", $ui_patterns_config_to_set["component_id"])); + $this->importConfigFixture('core.entity_view_display.node.page.full', $config_import); + $this->drupalGet('node/' . $node->id()); + $status_code = $this->getSession()->getStatusCode(); + $this->assertTrue($status_code === 200, sprintf('Status code is $status_code for test %s. %s', $test_set['name'], $this->getSession()->getPage()->getContent())); + $assert_session->statusCodeEquals(200); + $this->validateRenderedComponent([ + "component" => $test_set["component"], + "output" => [ + "slots" => [ + "wrapper" => [ + [ + "normalized_value" => "entity exists: 1", + ], + ], + ], + ], + ]); + // We do not run assertSession tests, because when used as sections + // the component is not rendered as expected by the test. + } + } + +} diff --git a/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderRenderTest.php b/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderRenderTest.php index 8b23c5b2631f808a8bc2f25489f2bc04d34d1392..cdb8c1281f31d4719f7138f601bacec6a1f6324b 100644 --- a/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderRenderTest.php +++ b/modules/ui_patterns_layouts/tests/src/Functional/LayoutBuilderRenderTest.php @@ -33,7 +33,7 @@ class LayoutBuilderRenderTest extends UiPatternsFunctionalTestBase { */ public function testContextInForm(): void { $assert_session = $this->assertSession(); - $config_import = $this->loadConfigFixture(__DIR__ . '/../fixtures/core.entity_view_display.node.page.full.yml'); + $config_import = $this->loadConfigFixture(__DIR__ . '/../../fixtures/config/core.entity_view_display.node.page.full.yml'); $ui_patterns_config = &$config_import['third_party_settings']['layout_builder']['sections'][0]['layout_settings']['ui_patterns']; $test_data = $this->loadTestDataFixture(); $test_set = $test_data->getTestSet('context_exists_default'); @@ -53,7 +53,7 @@ class LayoutBuilderRenderTest extends UiPatternsFunctionalTestBase { */ public function testRenderProps(): void { $assert_session = $this->assertSession(); - $config_import = $this->loadConfigFixture(__DIR__ . '/../fixtures/core.entity_view_display.node.page.full.yml'); + $config_import = $this->loadConfigFixture(__DIR__ . '/../../fixtures/config/core.entity_view_display.node.page.full.yml'); $ui_patterns_config = &$config_import['third_party_settings']['layout_builder']['sections'][0]['layout_settings']['ui_patterns']; $test_data = $this->loadTestDataFixture(); @@ -84,7 +84,7 @@ class LayoutBuilderRenderTest extends UiPatternsFunctionalTestBase { */ public function testRenderSlots(): void { $node = $this->createTestContentNode('page', ['field_text_1' => ['value' => 'field_text_1 value']]); - $config_import = $this->loadConfigFixture(__DIR__ . '/../fixtures/core.entity_view_display.node.page.full.yml'); + $config_import = $this->loadConfigFixture(__DIR__ . '/../../fixtures/config/core.entity_view_display.node.page.full.yml'); $this->importConfigFixture( 'core.entity_view_display.node.page.full', $config_import diff --git a/modules/ui_patterns_layouts/tests/src/Functional/LayoutFieldFormatterRenderTest.php b/modules/ui_patterns_layouts/tests/src/Functional/LayoutFieldFormatterRenderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..06bf3c3802eb7bd68d8a278192649eaa4083a8a7 --- /dev/null +++ b/modules/ui_patterns_layouts/tests/src/Functional/LayoutFieldFormatterRenderTest.php @@ -0,0 +1,78 @@ +<?php + +namespace Drupal\Tests\ui_patterns_layouts\Functional; + +use Drupal\Tests\ui_patterns\Functional\UiPatternsFunctionalTestBase; +use Drupal\Tests\ui_patterns\Traits\TestDataTrait; + +/** + * Test pattern preview rendering. + * + * @group ui_patterns_layouts + */ +class LayoutFieldFormatterRenderTest extends UiPatternsFunctionalTestBase { + + use TestDataTrait; + + /** + * {@inheritdoc} + */ + protected static $modules = [ + 'node', + 'ui_patterns', + 'ui_patterns_test', + 'ui_patterns_field_formatters', + 'ui_patterns_layouts', + 'field_ui', + 'field_layout', + 'block', + ]; + + /** + * Tests preview and output of props. + */ + public function testRender(): void { + $test_data = self::loadTestDataFixture(); + $tests = $test_data->getTestSets(); + foreach ($tests as $test_set) { + if (!isset($test_set["component"]["slots"]) || !is_array($test_set["component"]["slots"]) || count($test_set["component"]["slots"]) < 1) { + continue; + } + $node = $this->createTestContentNode('page', $test_set['entity'] ?? []); + $ui_patterns_config_to_set = $this->buildUiPatternsConfig($test_set); + $slots_of_component = $test_set["component"]["slots"]; + $first_slot = array_keys($slots_of_component)[0]; + // ----- + // Field Layout with a component section + $config_import = $this->loadConfigFixture(__DIR__ . '/../../fixtures/config/core.entity_view_display.node.page.full.layout.section_component.yml'); + $ui_patterns_config_layout_2 = &$config_import['third_party_settings']['field_layout']['settings']['ui_patterns']; + $ui_patterns_config_layout_2 = $ui_patterns_config_to_set; + $field_name = (isset($test_set["contexts"]) && isset($test_set["contexts"]["field_name"])) ? $test_set["contexts"]["field_name"] : "body"; + if (!empty($field_name) && $field_name !== "body") { + $config_import['content'][$field_name] = $config_import['content']["body"]; + unset($config_import['content']["body"]); + } + $config_import['content'][$field_name]["region"] = $first_slot; + $config_import['third_party_settings']['field_layout']['id'] = sprintf("ui_patterns:%s", str_replace("-", "_", $ui_patterns_config_to_set["component_id"])); + $this->importConfigFixture('core.entity_view_display.node.page.full', $config_import); + $this->drupalGet('node/' . $node->id()); + $status_code = $this->getSession()->getStatusCode(); + $this->assertTrue($status_code === 200, sprintf('Status code is $status_code for test %s. %s', $test_set['name'], $this->getSession()->getPage()->getContent())); + $this->validateRenderedComponent([ + "component" => $test_set["component"], + "output" => [ + "slots" => [ + "wrapper" => [ + [ + "normalized_value" => "entity exists: 1", + ], + ], + ], + ], + ]); + // We do not run assertSession tests, because when used as sections + // the component is not rendered as expected by the test. + } + } + +} diff --git a/modules/ui_patterns_layouts/tests/src/Kernel/RenderFieldFormatterTest.php b/modules/ui_patterns_layouts/tests/src/Kernel/RenderFieldFormatterTest.php deleted file mode 100644 index bf3f676df7f5c3e7275c740ffabd0c9e7bb0052c..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/src/Kernel/RenderFieldFormatterTest.php +++ /dev/null @@ -1,220 +0,0 @@ -<?php - -namespace Drupal\Tests\ui_patterns_layouts\Kernel; - -/** - * Render test with field formatter. - * - * @group ui_patterns_layouts - */ -class RenderFieldFormatterTest extends UIPatternsLayoutsTestBase { - - /** - * {@inheritdoc} - */ - protected function setUp(): void { - static::$additionalModules = ['ui_patterns_field_formatters']; - parent::setUp(); - } - - /** - * Test render. - * - * @param string $field_name - * Field name. - * @param array $field_items - * Field items. - * @param array $display_component_settings - * Display component settings. - * @param array $third_party_settings - * Third party settings. - * @param string $expected_output - * Expected output. - * - * @throws \Drupal\Core\Entity\EntityStorageException - * - * @dataProvider providerFieldMapping - */ - public function testRender( - string $field_name, - array $field_items, - array $display_component_settings, - array $third_party_settings, - string $expected_output, - ) : void { - $this->doTestRender($field_name, $field_items, $display_component_settings, $third_party_settings, $expected_output); - } - - /** - * Test render. - * - * @param string $entity_type_id - * Entity type id. - * @param string $bundle - * Bundle. - * @param string $field_name - * Field name. - * @param array $field_items - * Field items. - * @param array $display_component_settings - * Display component settings. - * @param array $third_party_settings - * Third party settings. - * @param string $expected_output - * Expected output. - * - * @throws \Drupal\Core\Entity\EntityStorageException - * - * @dataProvider providerFieldMappingBundle - */ - public function testRenderBundle( - string $entity_type_id, - string $bundle, - string $field_name, - array $field_items, - array $display_component_settings, - array $third_party_settings, - string $expected_output, - ) : void { - $this->doTestRenderBundle($entity_type_id, $bundle, $field_name, $field_items, $display_component_settings, $third_party_settings, $expected_output); - } - - /** - * Callback data provider to test one slot, one prop. - * - * @return array[] - * Data provider for function testRender. - */ - public static function providerFieldMapping(): array { - $field_type = 'text'; - $field_item = "Hello"; - $field_name = sprintf('field_%s', $field_type); - $test_field_layout = []; - $third_party_settings = [ - "field_layout" => [ - "id" => "ui_patterns:ui_patterns_tests_components:slot_test", - "settings" => [ - "label" => "alert layout", - "ui_patterns" => [ - "component_id" => NULL, - "variant_id" => NULL, - "slots" => [], - "props" => [], - ], - ], - ], - ]; - $test_field_layout[] = [ - $field_name, - [$field_name => [$field_item]], - /*'display_component_settings' => */[ - "type" => "ui_patterns_component_per_item", - "settings" => [ - "ui_patterns" => [ - "component_id" => "ui_patterns_tests_components:slot_test", - "variant_id" => NULL, - "props" => [], - "slots" => [ - "my_slot" => [ - "sources" => [ - 0 => [ - "source_id" => "field_property:node:field_text:processed", - "_weight" => "0", - ], - ], - ], - ], - ], - ], - "label" => "hidden", - "third_party_settings" => [], - "weight" => "0", - "region" => "my_slot", - ], - $third_party_settings, - /*"expected" => */<<<EXPECTED -<div data-component-id="ui_patterns_tests_components:slot_test" class="test-class"><div><div> -<div data-component-id="ui_patterns_tests_components:slot_test" class="test-class"> -<p>$field_item</p> -</div> -</div></div></div> -EXPECTED - ]; - - return $test_field_layout; - } - - /** - * Callback data provider to test one slot, one prop. - * - * @return array[] - * Data provider for function testRender. - */ - public static function providerFieldMappingBundle(): array { - $entity_type_id = "node"; - $bundle = self::$defaultNodeBundle; - $field_type = 'text'; - $field_item = "Hello"; - $field_name = sprintf('field_%s', $field_type); - $test_field_layout = []; - $third_party_settings = [ - "field_layout" => [ - "id" => "ui_patterns:ui_patterns_tests_components:slot_test", - "settings" => [ - "label" => "alert layout", - "ui_patterns" => [ - "component_id" => NULL, - "variant_id" => NULL, - "slots" => [], - "props" => [], - ], - ], - ], - ]; - - $test_field_layout[] = [ - $entity_type_id, - $bundle, - $field_name, - [$field_name => [$field_item]], - /*'display_component_settings' => */[ - "type" => "ui_patterns_component_per_item", - "settings" => [ - "ui_patterns" => [ - "component_id" => "ui_patterns_tests_components:slot_test", - "variant_id" => NULL, - "props" => [], - "slots" => [ - "my_slot" => [ - "sources" => [ - 0 => [ - "source_id" => "field_formatter:$entity_type_id:$bundle:field_text", - "source" => [ - "type" => "text_default", - ], - "_weight" => "0", - ], - ], - ], - ], - ], - ], - "label" => "hidden", - "third_party_settings" => [], - "weight" => "0", - "region" => "my_slot", - ], - $third_party_settings, - /*"expected" => */<<<EXPECTED -<div data-component-id="ui_patterns_tests_components:slot_test" class="test-class"><div><div> -<div data-component-id="ui_patterns_tests_components:slot_test" class="test-class"> -<p>$field_item</p> -</div> -</div></div></div> -EXPECTED - ]; - - return $test_field_layout; - } - -} diff --git a/modules/ui_patterns_layouts/tests/src/Kernel/RenderLayoutBuilderTest.php b/modules/ui_patterns_layouts/tests/src/Kernel/RenderLayoutBuilderTest.php deleted file mode 100644 index b4b8a29e8b6fd79f640b41c5788759446f44237c..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/src/Kernel/RenderLayoutBuilderTest.php +++ /dev/null @@ -1,192 +0,0 @@ -<?php - -namespace Drupal\Tests\ui_patterns_layouts\Kernel; - -use Drupal\Component\Uuid\UuidInterface; -use Drupal\layout_builder\Section; - -/** - * Render test with field formatter. - * - * @group ui_patterns_layouts - */ -class RenderLayoutBuilderTest extends UIPatternsLayoutsTestBase { - - /** - * Uuid service. - * - * @var \Drupal\Component\Uuid\UuidInterface - */ - protected UuidInterface $uuidService; - - /** - * {@inheritdoc} - */ - protected function setUp(): void { - static::$additionalModules = ['ui_patterns_field_formatters', 'layout_builder']; - parent::setUp(); - $this->uuidService = $this->container->get('uuid'); - } - - /** - * Test render. - * - * @param string $entity_type_id - * Entity type id. - * @param string $bundle - * Bundle. - * @param string $field_name - * Field name. - * @param array $field_items - * Field items. - * @param array|null $display_component_settings - * Display component settings. - * @param array $third_party_settings - * Third party settings. - * @param string $expected_output - * Expected output. - * - * @throws \Drupal\Core\Entity\EntityStorageException - * - * @dataProvider providerFieldMappingBundle - */ - public function testRenderBundle( - string $entity_type_id, - string $bundle, - string $field_name, - array $field_items, - ?array $display_component_settings, - array $third_party_settings, - string $expected_output, - ) : void { - $this->doTestRenderBundle($entity_type_id, $bundle, $field_name, $field_items, $display_component_settings, $third_party_settings, $expected_output); - } - - /** - * Callback data provider to test one slot, one prop. - * - * @return array[] - * Data provider for function testRender. - */ - public static function providerFieldMappingBundle(): array { - $entity_type_id = "node"; - $bundle = self::$defaultNodeBundle; - $field_type = 'text'; - $field_item = "Hello"; - $field_name = sprintf('field_%s', $field_type); - $test_field_layout = []; - - $layoutBuilderSection = new Section( - "ui_patterns:ui_patterns_tests_components:slot_test", - [ - "label" => "alert layout", - "context_mapping" => [ - "entity" => "layout_builder.entity", - ], - "ui_patterns" => [ - "component_id" => NULL, - "variant_id" => NULL, - "slots" => [], - "props" => [], - ], - ], - [], - [] - ); - // Section component will be added automatically with field config. - $third_party_settings = [ - "field_layout" => [ - "id" => "ui_patterns:ui_patterns_tests_components:slot_test", - "settings" => [ - "label" => "alert layout", - "ui_patterns" => [ - "component_id" => NULL, - "variant_id" => NULL, - "slots" => [], - "props" => [], - ], - ], - ], - "layout_builder" => [ - "enabled" => TRUE, - "sections" => [$layoutBuilderSection], - ], - ]; - $test_field_layout[] = [ - $entity_type_id, - $bundle, - $field_name, - [$field_name => [$field_item]], - /*'display_component_settings' => */[ - "type" => "ui_patterns_component_per_item", - "label" => "hidden", - "settings" => [ - "ui_patterns" => [ - "component_id" => "ui_patterns_tests_components:slot_test", - "variant_id" => NULL, - "props" => [], - "slots" => [ - "my_slot" => [ - "sources" => [ - 0 => [ - "source_id" => "field_property:node:field_text:processed", - "_weight" => "0", - ], - ], - ], - ], - ], - ], - ], - $third_party_settings, - /*"expected" => */<<<EXPECTED -<div data-component-id="ui_patterns_tests_components:slot_test" class="test-class"><div><div> -<div data-component-id="ui_patterns_tests_components:slot_test" class="test-class"> -<p>$field_item</p> -</div> -</div></div></div> -EXPECTED - ]; - - $test_field_layout[] = [ - $entity_type_id, - $bundle, - $field_name, - [$field_name => [$field_item]], - /*'display_component_settings' => */[ - "type" => "ui_patterns_component_per_item", - "label" => "hidden", - "settings" => [ - "ui_patterns" => [ - "component_id" => "ui_patterns_tests_components:slot_test", - "variant_id" => NULL, - "props" => [], - "slots" => [ - "my_slot" => [ - "sources" => [ - 0 => [ - "source_id" => "field_formatter:$entity_type_id:$bundle:field_text", - "source" => [ - "type" => "text_default", - ], - "_weight" => "0", - ], - ], - ], - ], - ], - ], - ], - $third_party_settings, - /*"expected" => */<<<EXPECTED -<div data-component-id="ui_patterns_tests_components:slot_test" class="test-class"><div><div> -<div data-component-id="ui_patterns_tests_components:slot_test" class="test-class"> -<p>$field_item</p> -</div> -</div></div></div> -EXPECTED - ]; - return $test_field_layout; - } - -} diff --git a/modules/ui_patterns_layouts/tests/src/Kernel/RenderTest.php b/modules/ui_patterns_layouts/tests/src/Kernel/RenderTest.php deleted file mode 100644 index fc90a6eaec89b863bdbd80c40deee45474197bc9..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/src/Kernel/RenderTest.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php - -namespace Drupal\Tests\ui_patterns_layouts\Kernel; - -/** - * Render test. - * - * @group ui_patterns_layouts - */ -class RenderTest extends UIPatternsLayoutsTestBase { - - /** - * Test render. - * - * @param string $field_name - * Field name. - * @param array $field_items - * Field items. - * @param array $display_component_settings - * Display component settings. - * @param array $third_party_settings - * Third party settings. - * @param string $expected_output - * Expected output. - * - * @throws \Drupal\Core\Entity\EntityStorageException - * - * @dataProvider providerFieldMapping - */ - public function testRender( - string $field_name, - array $field_items, - array $display_component_settings, - array $third_party_settings, - string $expected_output, - ) : void { - $this->doTestRender($field_name, $field_items, $display_component_settings, $third_party_settings, $expected_output); - } - - /** - * Callback data provider to test one slot, one prop. - * - * @return array[] - * Data provider for function testRender. - */ - public static function providerFieldMapping(): array { - $field_type = 'text'; - $field_item = "Hello"; - $field_name = sprintf('field_%s', $field_type); - $test_field_layout = []; - $third_party_settings = [ - "field_layout" => [ - "id" => "ui_patterns:ui_patterns_tests_components:slot_test", - "settings" => [ - "label" => "alert layout", - "ui_patterns" => [ - "component_id" => NULL, - "variant_id" => NULL, - "slots" => [], - "props" => [], - ], - ], - ], - ]; - $test_field_layout[] = [ - $field_name, - [$field_name => [$field_item]], - /*'display_component_settings' => */[ - "type" => "text_default", - "label" => "hidden", - "settings" => [], - "third_party_settings" => [], - "weight" => "0", - "region" => "my_slot", - ], - $third_party_settings, - '<div data-component-id="ui_patterns_tests_components:slot_test" class="test-class"><div><div><p>' . $field_item . '</p></div></div></div>', - ]; - - return $test_field_layout; - } - -} diff --git a/modules/ui_patterns_layouts/tests/src/Kernel/SourcesDeriverTest.php b/modules/ui_patterns_layouts/tests/src/Kernel/SourcesDeriverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..48b0cc852abcb10788c80ec7d93f4d96986a7d05 --- /dev/null +++ b/modules/ui_patterns_layouts/tests/src/Kernel/SourcesDeriverTest.php @@ -0,0 +1,72 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns_layouts\Kernel; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; +use Drupal\ui_patterns_layouts\Plugin\Layout\ComponentLayout; + +/** + * Tests UI patterns layouts plugin deriver. + * + * @group ui_patterns_layouts + */ +class SourcesDeriverTest extends SourcePluginsTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['layout_discovery', 'ui_patterns', 'ui_patterns_test', 'ui_patterns_layouts']; + + /** + * {@inheritdoc} + */ + protected $strictConfigSchema = FALSE; + + /** + * The layout plugin manager. + * + * @var \Drupal\Core\Layout\LayoutPluginManagerInterface + */ + protected $layoutManager; + + /** + * The component plugin manager. + * + * @var \Drupal\ui_patterns\ComponentPluginManager + */ + protected $componentManager; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + $this->layoutManager = $this->container->get('plugin.manager.core.layout'); + $this->componentManager = $this->container->get('plugin.manager.sdc'); + } + + /** + * Tests creating fields of all types on a content type. + */ + public function testDerivedPluginPerComponent() { + $components = $this->componentManager->getSortedDefinitions(); + foreach ($components as $component) { + $component_instance = $this->componentManager->find($component['id']); + $id = str_replace('-', '_', (string) $component['id']); + $layout_plugin_id = sprintf('ui_patterns:%s', $id); + $layout = $this->layoutManager->createInstance($layout_plugin_id); + $this->assertNotNull($layout, "Layout for component {$component['id']} is missing"); + $this->assertInstanceOf(ComponentLayout::class, $layout); + /** @var \Drupal\Core\Layout\LayoutDefinition $layout_definition */ + $layout_definition = $layout->getPluginDefinition(); + $regions = array_keys($layout_definition->getRegions()); + $slots = $component_instance->metadata->slots ?? []; + foreach (array_keys($slots) as $slot_id) { + $this->assertContains($slot_id, $regions, "Slot {$slot_id} is missing in layout for component {$component['id']}"); + } + } + } + +} diff --git a/modules/ui_patterns_layouts/tests/src/Kernel/UIPatternsLayoutsTestBase.php b/modules/ui_patterns_layouts/tests/src/Kernel/UIPatternsLayoutsTestBase.php deleted file mode 100644 index 553cb29318b919a161974def826cd43da32cc029..0000000000000000000000000000000000000000 --- a/modules/ui_patterns_layouts/tests/src/Kernel/UIPatternsLayoutsTestBase.php +++ /dev/null @@ -1,147 +0,0 @@ -<?php - -namespace Drupal\Tests\ui_patterns_layouts\Kernel; - -use Drupal\Component\Render\FormattableMarkup; -use Drupal\Core\Cache\Cache; -use Drupal\Core\Entity\Display\EntityDisplayInterface; -use Drupal\Core\Entity\Entity\EntityFormDisplay; -use Drupal\Core\Entity\Entity\EntityViewDisplay; -use Drupal\Core\Render\Markup; -use Drupal\field_layout\Display\EntityDisplayWithLayoutInterface; -use Drupal\Tests\ui_patterns\Kernel\EntityTestBase; -use Symfony\Component\Yaml\Yaml; - -/** - * Defines a base class for node access kernel tests. - */ -abstract class UIPatternsLayoutsTestBase extends EntityTestBase { - - /** - * Additional modules to activate (child classes should set this). - * - * @var array - */ - protected static array $additionalModules = []; - /** - * {@inheritdoc} - */ - protected $strictConfigSchema = FALSE; - - /** - * {@inheritdoc} - */ - protected static $modules = []; - - /** - * Config factory. - * - * @var \Drupal\Core\Config\ConfigFactoryInterface - */ - protected $configFactory; - - /** - * Test render. - * - * @param string $field_name - * Field name. - * @param array $field_items - * Field items. - * @param array|null $display_component_settings - * Display component settings. - * @param array $third_party_settings - * Third party settings. - * @param string $expected_output - * Expected output. - * - * @throws \Drupal\Core\Entity\EntityStorageException - */ - public function doTestRender( - string $field_name, - array $field_items, - ?array $display_component_settings, - array $third_party_settings, - string $expected_output, - ) : void { - foreach ($this->entityTypes as $oneEntityType) { - $bundle = (string) $oneEntityType->id(); - $entity_type_id = $oneEntityType->getEntityType()->getBundleOf(); - $this->doTestRenderBundle($entity_type_id, $bundle, $field_name, $field_items, $display_component_settings, $third_party_settings, $expected_output); - } - } - - /** - * Test render. - * - * @param string $entity_type_id - * Entity type id. - * @param string $bundle - * Bundle. - * @param string $field_name - * Field name. - * @param array $field_items - * Field items. - * @param array|null $display_component_settings - * Display component settings. - * @param array $third_party_settings - * Third party settings. - * @param string $expected_output - * Expected output. - * - * @throws \Drupal\Core\Entity\EntityStorageException - */ - public function doTestRenderBundle( - string $entity_type_id, - string $bundle, - string $field_name, - array $field_items, - ?array $display_component_settings, - array $third_party_settings, - string $expected_output, - ) : void { - $this->setUpFieldDisplay($entity_type_id, (string) $bundle, $field_name, $display_component_settings, $third_party_settings); - $node = $this->drupalCreateNode( - array_merge([ - 'type' => $bundle, - ], $field_items) - ); - foreach ($field_items as $field_items_field_name => $field_items_per_field_name) { - $node->set($field_items_field_name, $field_items_per_field_name); - } - $produced = $this->renderEntity($node); - $produced = $this->normalizeMarkupString($produced); - $expected_output = $this->normalizeMarkupString($expected_output); - - $config = $this->configFactory->get(sprintf("core.entity_view_display.%s.%s.default", $entity_type_id, $bundle)); - $config = Yaml::dump($config->get(), 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK); - $error_string = new FormattableMarkup("failed to verify produced markup for entity render.\nOutput is:\n---\n@output\n---\nExpected is:\n---\n@expected\n---\nFormatter settings is:\n @settings.\n @third_party_settings.\n @config.", [ - '@output' => Markup::create($produced), - '@expected' => Markup::create($expected_output), - '@settings' => Markup::create(print_r($display_component_settings, TRUE)), - '@third_party_settings' => Markup::create(print_r($third_party_settings, TRUE)), - '@config' => Markup::create(print_r($config, TRUE)), - ]); - $this->assertEquals($expected_output, $produced, $error_string); - } - - /** - * {@inheritdoc} - */ - protected function setUp(): void { - self::$modules = array_merge(parent::$modules, ['field_layout', 'layout_discovery', 'ui_patterns_layouts'], static::$additionalModules); - parent::setUp(); - $this->installConfig('field_layout'); - $entity_save = function (EntityDisplayInterface $entity) { - if ($entity instanceof EntityDisplayWithLayoutInterface) { - $entity->ensureLayout()->save(); - } - }; - array_map($entity_save, EntityViewDisplay::loadMultiple()); - array_map($entity_save, EntityFormDisplay::loadMultiple()); - - // Invalidate the render cache since all content will now have a layout. - Cache::invalidateTags(['rendered']); - $this->configFactory = $this->container->get('config.factory'); - } - -} diff --git a/src/ComponentPluginManager.php b/src/ComponentPluginManager.php index 7df32b98235e6a6553182ad30b851d6eb2a5686b..ced2f347726f0222f84eeffbf3905d8daa2134fa 100644 --- a/src/ComponentPluginManager.php +++ b/src/ComponentPluginManager.php @@ -242,7 +242,7 @@ class ComponentPluginManager extends SdcPluginManager implements CategorizingPlu /** * {@inheritdoc} */ - public function getSortedDefinitions(array $definitions = NULL) { + public function getSortedDefinitions(?array $definitions = NULL) { // Sort the plugins first by group, then by label. $definitions = $definitions ?? $this->getDefinitions(); $label_key = 'name'; diff --git a/src/Form/ComponentFormBuilderTrait.php b/src/Form/ComponentFormBuilderTrait.php index a2eade37796c115521141f0cce60ff5d3b7382ec..3e153f1aff19b1b5260b960b3bd58392d0cab4cd 100644 --- a/src/Form/ComponentFormBuilderTrait.php +++ b/src/Form/ComponentFormBuilderTrait.php @@ -131,7 +131,7 @@ trait ComponentFormBuilderTrait { protected function buildComponentsForm( FormStateInterface $form_state, ?array $source_contexts = [], - string $initial_component_id = NULL, + ?string $initial_component_id = NULL, bool $render_slots = TRUE, bool $render_props = TRUE, string $configuration_id = 'ui_patterns', diff --git a/src/Plugin/UiPatterns/Source/ListTextareaWidget.php b/src/Plugin/UiPatterns/Source/ListTextareaWidget.php index a18381ed655f992b2b976b8fa8428a4fda8efe30..1fa1d62b9d86dd01565e752e731176a5f97f51cb 100644 --- a/src/Plugin/UiPatterns/Source/ListTextareaWidget.php +++ b/src/Plugin/UiPatterns/Source/ListTextareaWidget.php @@ -25,7 +25,71 @@ class ListTextareaWidget extends SourcePluginBase { */ public function getPropValue(): mixed { $long_text = $this->getSetting('value') ?? ''; - return preg_split("/\r\n|\n|\r/", $long_text); + $list_of_items = (array) preg_split("/\r\n|\n|\r/", $long_text); + // Cast items if required. + $items_types = $this->propDefinition['items']['type'] ?? []; + if (!empty($items_types) && is_string($items_types)) { + $items_types = [$items_types]; + } + if (!is_array($items_types)) { + return $list_of_items; + } + return $this->castValues($list_of_items, $items_types); + } + + /** + * Cast values. + * + * @param array $values + * The values to cast. + * @param array $types + * The types to cast to. + * + * @return array + * The casted values. + */ + private function castValues(array $values, array $types): array { + $casted_values = []; + foreach ($values as $value) { + $converted = NULL; + if ($value === "" && in_array("string", $types, TRUE)) { + $casted_values[] = $value; + continue; + } + foreach ($types as $type) { + $converted = $this->castValue($value, $type); + if ($converted !== NULL) { + break; + } + } + $casted_values[] = ($converted !== NULL) ? $converted : $value; + } + return $casted_values; + } + + /** + * Cast value. + * + * @param mixed $value + * The value to cast. + * @param string $type + * The type to cast to. + * + * @return mixed + * The casted value or NULL. + */ + private function castValue($value, string $type): mixed { + try { + return match ($type) { + 'integer' => (is_int($value) || is_numeric($value) || ($value === "")) ? (int) $value : NULL, + 'float', 'decimal' => is_float($value) ? $value : (float) $value, + 'boolean' => is_bool($value) ? $value : (boolean) $value, + default => NULL, + }; + } + catch (\Exception) { + } + return NULL; } /** diff --git a/src/Resolver/LayoutBuilderContextEntityResolver.php b/src/Resolver/LayoutBuilderContextEntityResolver.php index 2326093687f060d675fb7d268cd1d38d24d6a3cf..b9292f3a7c11bd2682afd335f86c6811917b279c 100644 --- a/src/Resolver/LayoutBuilderContextEntityResolver.php +++ b/src/Resolver/LayoutBuilderContextEntityResolver.php @@ -50,7 +50,7 @@ class LayoutBuilderContextEntityResolver implements ContextEntityResolverInterfa * @return \Drupal\layout_builder\SectionStorageInterface|null * The section storage or null. */ - protected function getLayoutBuilderSectionStorage(FormStateInterface $form_state = NULL) : ?SectionStorageInterface { + protected function getLayoutBuilderSectionStorage(?FormStateInterface $form_state = NULL) : ?SectionStorageInterface { if ($form_state !== NULL) { $form_object = $form_state->getFormObject(); if ($form_object instanceof ConfigureSectionForm) { diff --git a/tests/fixtures/TestDataSet.yml b/tests/fixtures/TestDataSet.yml index 154710146cee1aae1d56b1f48a9831c3dd8e771a..a3fe6a47f77aac5709cd3fd0497b81ec8d202adf 100644 --- a/tests/fixtures/TestDataSet.yml +++ b/tests/fixtures/TestDataSet.yml @@ -1,5 +1,6 @@ --- field_property_default: + # we configure a component component: component_id: ui_patterns_test:test-component slots: @@ -7,17 +8,30 @@ field_property_default: sources: - source_id: field_property:node:field_text_1:value + # we add some data to the entity entity: field_text_1: value: 'value_text_1' + # contexts are injected into the source for Kernel source tests + # the field_name in context will also be used in field formatter for example + # to decide on which field to apply the formatter contexts: field_name: 'field_text_1' bundle: 'page' + # output is reserved for the raw data returned by each source configured + # on a slot or a prop. output: slots: slot: - rendered_value: "value_text_1" + # those tests will be done in functional tests + # typically, the component is rendered entirely in a specific situation + # We assert if the output generated verifies some conditions + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-slots-slot') and contains(text(), 'value_text_1')]" ] select_integer: component: component_id: ui_patterns_test:test-component @@ -105,16 +119,16 @@ token_2: value: '[node:body]' entity: body: - value: 'value_text_1' + value: 'value_text_token_2' output: props: string: - value: 'value_text_1' + value: 'value_text_token_2' assertSession: elementExists: - [ 'css', '.ui-patterns-test-component' ] elementTextEquals: - - [ 'xpath', "//div[@class='ui-patterns-props-string']/text()",'value_text_1'] + - [ 'xpath', "//div[@class='ui-patterns-props-string']/text()",'value_text_token_2'] context_exists_default: component: @@ -127,3 +141,284 @@ context_exists_default: string: value: 'entity exists: 1' entity: {} + +checkboxes_1: + component: + component_id: ui_patterns_test:test-component + props: + enum_list: + source_id: checkboxes + source: + value: + B: B + entity: + body: + value: 'value_text_1' + output: + props: + enum_list: + same: + B: "B" + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-enum_list')]//span[contains(text(), 'B')]" ] + elementsCount: + - [ 'xpath', "//div[@class='ui-patterns-props-enum_list']//span", 1 ] +checkboxes_2: + component: + component_id: ui_patterns_test:test-component + props: + enum_list: + source_id: checkboxes + source: + value: + A: A + B: B + entity: + body: + value: 'value_text_1' + output: + props: + enum_list: + same: + A: A + B: B + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-enum_list')]//span[contains(text(), 'A')]" ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-enum_list')]//span[contains(text(), 'B')]" ] + elementsCount: + - [ 'xpath', "//div[@class='ui-patterns-props-enum_list']//span", 2 ] + +component_1: + component: + component_id: ui_patterns_test:test-component + slots: + slot: + sources: + - source_id: component + source: + component: + component_id: 'ui_patterns_test:test-wrapper-component' + props: + attributes: + source_id: attributes + source: + value: '' + output: + slots: + slot: + - rendered_value: '<div class="ui-patterns-wrapper"><div class="ui-patterns-slots-wrapper"></div></div>' + assertSession: + elementExists: + - [ 'css', '.ui-patterns-wrapper' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-wrapper')]//div[contains(@class, 'ui-patterns-slots-wrapper')]" ] + elementsCount: + - [ 'xpath', "//div[@class='ui-patterns-wrapper']//div[contains(@class, 'ui-patterns-slots-wrapper')]", 1] + +entity_field_1: + component: + component_id: ui_patterns_test:test-component + props: + string: + source_id: entity_field + source: + derivable_context: 'field:node:page:title' + 'field:node:page:title': + value: + source_id: 'field_property:node:title:value' + entity: + title: + value: 'title_entity_1' + field_text: + - value: "1" + contexts: + field_name: 'field_text' + output: + props: + string: + value: "title_entity_1" + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-string') and contains(text(), 'title_entity_1')]" ] +entity_field_2: + component: + component_id: ui_patterns_test:test-component + props: + integer: + source_id: entity_field + source: + derivable_context: 'field:node:page:nid' + 'field:node:page:nid': + value: + source_id: 'field_property:node:nid:value' + entity: {} + output: + props: + integer: + regEx: /[0-9]+/ + +entity_links_1: + component: + component_id: ui_patterns_test:test-component + props: + string: + source_id: entity_link + source: + template: edit-form + entity: { } + output: + props: + string: + regEx: '/\/node\/\d+\/edit/' + +list_textarea_1: + component: + component_id: ui_patterns_test:test-component + props: + list_string: + source_id: list_textarea + source: + value: "A\r\nB" + entity: {} + output: + props: + list_string: + same: + - 'A' + - 'B' + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-list_string')]//span[contains(text(), 'A')]" ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-list_string')]//span[contains(text(), 'B')]" ] + elementsCount: + - [ 'xpath', "//div[@class='ui-patterns-props-list_string']//span", 2 ] +list_textarea_2: + component: + component_id: ui_patterns_test:test-component + props: + list_integer: + source_id: list_textarea + source: + value: "1\r\n-1" + entity: {} + output: + props: + list_integer: + same: + - 1 + - -1 + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-list_integer')]//span[contains(text(), '1')]" ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-list_integer')]//span[contains(text(), '-1')]" ] + elementsCount: + - [ 'xpath', "//div[@class='ui-patterns-props-list_integer']//span", 2 ] + + +list_textarea_3: + component: + component_id: ui_patterns_test:test-component + props: + list_mixed: + source_id: list_textarea + source: + value: "1\r\nA" + entity: {} + output: + props: + list_mixed: + same: + - 1 + - "A" + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-list_mixed')]//span[contains(text(), '1')]" ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-props-list_mixed')]//span[contains(text(), 'A')]" ] + elementsCount: + - [ 'xpath', "//div[@class='ui-patterns-props-list_mixed']//span", 2 ] + +number_default: + component: + component_id: ui_patterns_test:test-component + props: + number: + source_id: number + source: + value: '2' + output: + props: + number: + same: 2 + entity: {} + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + elementTextEquals: + - [ 'css', '.ui-patterns-props-number', '2' ] + + +path_1: + component: + component_id: ui_patterns_test:test-component + props: + url: + source_id: path + source: + value: '/user' + output: + props: + url: + value: '/user' + entity: {} + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + elementTextEquals: + - [ 'css', '.ui-patterns-props-url', '/user' ] +url_1: + component: + component_id: ui_patterns_test:test-component + props: + url: + source_id: url + source: + value: 'https://drupal.org?k=v#anchor' + output: + props: + url: + value: 'https://drupal.org?k=v#anchor' + entity: {} + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + elementTextEquals: + - [ 'css', '.ui-patterns-props-url', 'https://drupal.org?k=v#anchor' ] + +wysiwyg_1: + component: + component_id: ui_patterns_test:test-component + slots: + slot: + sources: + - + source_id: wysiwyg + source: + value: + value: 'Test text' + format: plain_text + output: + slots: + slot: + - + rendered_value: "<p>Test text</p>" + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-slots-slot')]//p[contains(text(), 'Test text')]" ] diff --git a/tests/fixtures/block_tests.yml b/tests/fixtures/block_tests.yml new file mode 100644 index 0000000000000000000000000000000000000000..f3d973d10a557381b626e355e74341dbaa9fc4f3 --- /dev/null +++ b/tests/fixtures/block_tests.yml @@ -0,0 +1,19 @@ +--- +block_1: + component: + component_id: ui_patterns_test:test-component + slots: + slot: + sources: + - + source_id: 'block' + source: + plugin_id: 'ui_patterns_test_block' + settings: + display_message: "value_text_X" + entity: {} + output: + slots: + slot: + - + rendered_value: "value_text_X" diff --git a/tests/fixtures/config/filter.format.html.yml b/tests/fixtures/config/filter.format.html.yml new file mode 100644 index 0000000000000000000000000000000000000000..3d96d2b27376e2f03325187229972941c6f869af --- /dev/null +++ b/tests/fixtures/config/filter.format.html.yml @@ -0,0 +1,27 @@ +uuid: c8f1581f-e499-46a7-aba7-3c6209c9599c +langcode: en +status: true +_core: + default_config_hash: vpZysv3RHJjhYzq7O_q5q8mVlHdrSzKELmXyiX6RtV0 +name: 'HTML' +format: html +weight: 2 +filters: + filter_align: + id: filter_align + provider: filter + status: false + weight: 8 + settings: { } + filter_caption: + id: filter_caption + provider: filter + status: false + weight: 9 + settings: { } + filter_htmlcorrector: + id: filter_htmlcorrector + provider: filter + status: true + weight: 10 + settings: { } diff --git a/tests/fixtures/menu_tests.yml b/tests/fixtures/menu_tests.yml new file mode 100644 index 0000000000000000000000000000000000000000..5f8cc956c8bb1e181b0590b22baf75ca042bd61a --- /dev/null +++ b/tests/fixtures/menu_tests.yml @@ -0,0 +1,11 @@ +--- +menu_1: + component: + component_id: ui_patterns_test:test-component + props: + links: + source_id: "menu" + source: + menu: main + level: '1' + depth: '0' diff --git a/tests/fixtures/source_only_tests.yml b/tests/fixtures/source_only_tests.yml new file mode 100644 index 0000000000000000000000000000000000000000..84915933fe6eed695a15f10a8671abfe8e067a78 --- /dev/null +++ b/tests/fixtures/source_only_tests.yml @@ -0,0 +1,17 @@ +--- +attributes_1: + component: + component_id: ui_patterns_test:test-component + props: + attributes: + source_id: attributes + source: + value: 'key="value"' + entity: + body: + value: 'value_text_1' + output: + props: + attributes: + same: + key: value diff --git a/tests/fixtures/wysiwyg_tests.yml b/tests/fixtures/wysiwyg_tests.yml new file mode 100644 index 0000000000000000000000000000000000000000..0c057c6fc9092a261e5b285794192aabafb202c4 --- /dev/null +++ b/tests/fixtures/wysiwyg_tests.yml @@ -0,0 +1,22 @@ +--- +wysiwyg_html: + component: + component_id: ui_patterns_test:test-component + slots: + slot: + sources: + - + source_id: wysiwyg + source: + value: + value: '<div class="class"><h1 data-a="b">Test text</h1></div>' + format: html + output: + slots: + slot: + - + rendered_value: '<div class="class"><h1 data-a="b">Test text</h1></div>' + assertSession: + elementExists: + - [ 'css', '.ui-patterns-test-component' ] + - [ 'xpath', "//div[contains(@class, 'ui-patterns-test-component')]//div[contains(@class, 'ui-patterns-slots-slot')]//div[contains(@class, 'class')]//h1[contains(text(), 'Test text')]" ] diff --git a/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml b/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml index 97cbbc3fdd519feab3409853a26cce89727e791c..0c5569b0c70b69e1cc25fa6a96c980505c150b28 100644 --- a/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml +++ b/tests/modules/ui_patterns_test/components/test-component/test-component.component.yml @@ -5,6 +5,24 @@ props: string: title: "String" type: "string" + integer: + title: "Integer" + type: "integer" + number: + title: "Number" + type: "number" + url: + title: "URL" + $ref: "ui-patterns://url" + machine_name: + title: "Machine Name" + $ref: "ui-patterns://machine_name" + boolean: + title: "Boolean" + $ref: "ui-patterns://boolean" + links: + title: "Links" + $ref: 'ui-patterns://links' enum_integer: title: "Enum Integer" type: "integer" @@ -19,7 +37,31 @@ props: enum: - "2" - "3" + enum_list : + title: 'Enum List' + $ref: 'ui-patterns://enum_list' + items: + enum: + - A + - B + 'meta:enum': + A: 'Label A' + B: 'Label B' + list_string: + title: "List String" + type: "array" + items: + type: "string" + list_integer: + title: "List Integer" + type: "array" + items: + type: "integer" + list_mixed: + title: "List String" + type: "array" + items: + type: ["string", "integer"] slots: slot: title: "Slot" - description: "Slot." diff --git a/tests/modules/ui_patterns_test/components/test-component/test-component.twig b/tests/modules/ui_patterns_test/components/test-component/test-component.twig index 8c0d0364144d429ab2f387a014f26b82c45805ec..02559dbcd000a243187537e01a79150ef0e544bc 100644 --- a/tests/modules/ui_patterns_test/components/test-component/test-component.twig +++ b/tests/modules/ui_patterns_test/components/test-component/test-component.twig @@ -2,12 +2,60 @@ <div class="ui-patterns-props-string"> {{ string }} </div> + <div class="ui-patterns-props-integer"> + {{ integer }} + </div> + <div class="ui-patterns-props-number"> + {{ number }} + </div> + <div class="ui-patterns-props-url"> + {{ url }} + </div> + <div class="ui-patterns-props-machine_name"> + {{ machine_name }} + </div> + <div class="ui-patterns-props-boolean"> + {{ boolean }} + </div> + <div class="ui-patterns-props-links"> + {% for item in links %} + {% if item.url %} + <li> + <a href="{{ item.url }}">{{ item.title }}</a> + </li> + {% else %} + <li> + {{ item.title }} + </li> + {% endif %} + {% endfor %} + </div> <div class="ui-patterns-props-enum_integer"> {{ enum_integer }} </div> <div class="ui-patterns-props-enum_string"> {{ enum_string }} </div> + <div class="ui-patterns-props-enum_list"> + {% for item in enum_list %} + <span>{{ item }}</span> + {% endfor %} + </div> + <div class="ui-patterns-props-list_string"> + {% for item in list_string %} + <span>{{ item }}</span> + {% endfor %} + </div> + <div class="ui-patterns-props-list_integer"> + {% for item in list_integer %} + <span>{{ item }}</span> + {% endfor %} + </div> + <div class="ui-patterns-props-list_mixed"> + {% for item in list_mixed %} + <span>{{ item }}</span> + {% endfor %} + </div> <div class="ui-patterns-slots-slot"> {{ slot }} </div> diff --git a/tests/modules/ui_patterns_test/src/Plugin/Block/TestBlock.php b/tests/modules/ui_patterns_test/src/Plugin/Block/TestBlock.php new file mode 100644 index 0000000000000000000000000000000000000000..437e8f6d9a639b5b6125ba424053c0eabc336350 --- /dev/null +++ b/tests/modules/ui_patterns_test/src/Plugin/Block/TestBlock.php @@ -0,0 +1,56 @@ +<?php + +namespace Drupal\ui_patterns_test\Plugin\Block; + +use Drupal\Core\Block\Attribute\Block; +use Drupal\Core\Block\BlockBase; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Provides a basic block for testing block instantiation and configuration. + */ +#[Block( + id: "ui_patterns_test_block", + admin_label: new TranslatableMarkup("Display message") + )] + class TestBlock extends BlockBase { + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'display_message' => 'no message set', + ]; + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, FormStateInterface $form_state) { + $form['display_message'] = [ + '#type' => 'textfield', + '#title' => $this->t('Display message'), + '#default_value' => $this->configuration['display_message'], + ]; + return $form; + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, FormStateInterface $form_state) : void { + $this->configuration['display_message'] = $form_state->getValue('display_message'); + } + + /** + * {@inheritdoc} + */ + public function build() { + return [ + '#children' => $this->configuration['display_message'], + ]; + } + + } diff --git a/tests/modules/ui_patterns_tests_components/components/multi_prop_type_test/multi_prop_type_test.component.yml b/tests/modules/ui_patterns_tests_components/components/multi_prop_type_test/multi_prop_type_test.component.yml deleted file mode 100644 index 31f764ab296bcccb8a6cc5f3c76cd13da9598410..0000000000000000000000000000000000000000 --- a/tests/modules/ui_patterns_tests_components/components/multi_prop_type_test/multi_prop_type_test.component.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: "Multi Prop types tests" -props: - type: object - properties: - prop_string: - title: "String" - type: "string" - prop_boolean: - title: "Boolean" - type: "boolean" - prop_integer: - title: "Integer" - type: "integer" - prop_number: - title: "Number (float or integer)" - type: "number" diff --git a/tests/modules/ui_patterns_tests_components/components/multi_prop_type_test/multi_prop_type_test.twig b/tests/modules/ui_patterns_tests_components/components/multi_prop_type_test/multi_prop_type_test.twig deleted file mode 100644 index 0ef7e302a5d8afe7a1bcf5d9c6daf1ae881080be..0000000000000000000000000000000000000000 --- a/tests/modules/ui_patterns_tests_components/components/multi_prop_type_test/multi_prop_type_test.twig +++ /dev/null @@ -1,12 +0,0 @@ -{% if prop_string is defined and prop_string is not null %} -<div{{ attributes.addClass('prop-string') }}>{{ prop_string }}</div> -{% endif %} -{% if prop_boolean is defined and prop_boolean is not null %} - <div{{ attributes.addClass('prop-boolean') }}>{{ prop_boolean }}</div> -{% endif %} -{% if prop_integer is defined and prop_integer is not null %} - <div{{ attributes.addClass('prop-integer') }}>{{ prop_integer }}</div> -{% endif %} -{% if prop_number is defined and prop_number is not null %} - <div{{ attributes.addClass('prop-number') }}>{{ prop_number }}</div> -{% endif %} diff --git a/tests/modules/ui_patterns_tests_components/components/slot_test/slot_test.component.yml b/tests/modules/ui_patterns_tests_components/components/slot_test/slot_test.component.yml deleted file mode 100644 index 9ade7f6b95b5ce62c316cd06afe2bf9f5592c590..0000000000000000000000000000000000000000 --- a/tests/modules/ui_patterns_tests_components/components/slot_test/slot_test.component.yml +++ /dev/null @@ -1,8 +0,0 @@ -name: "Prop types tests" -slots: - my_slot: - title: "my_slot" - description: "my_slot" -props: - type: object - properties: {} diff --git a/tests/modules/ui_patterns_tests_components/components/slot_test/slot_test.twig b/tests/modules/ui_patterns_tests_components/components/slot_test/slot_test.twig deleted file mode 100644 index 64ae832676aa63649b8a1b3fc2ed0aec34340783..0000000000000000000000000000000000000000 --- a/tests/modules/ui_patterns_tests_components/components/slot_test/slot_test.twig +++ /dev/null @@ -1 +0,0 @@ -<div{{ attributes.addClass('test-class') }}>{{ my_slot }}</div> diff --git a/tests/modules/ui_patterns_tests_components/components/string_prop_type_test/string_prop_type_test.component.yml b/tests/modules/ui_patterns_tests_components/components/string_prop_type_test/string_prop_type_test.component.yml deleted file mode 100644 index b76de35b25c9c9f336ae8703c5b7a0c327ef2c04..0000000000000000000000000000000000000000 --- a/tests/modules/ui_patterns_tests_components/components/string_prop_type_test/string_prop_type_test.component.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: "Prop types tests" -props: - type: object - properties: - string_prop: - title: "String" - type: "string" diff --git a/tests/modules/ui_patterns_tests_components/components/string_prop_type_test/string_prop_type_test.twig b/tests/modules/ui_patterns_tests_components/components/string_prop_type_test/string_prop_type_test.twig deleted file mode 100644 index 18c836ecb649411d577e717c63d6460458ff8ab8..0000000000000000000000000000000000000000 --- a/tests/modules/ui_patterns_tests_components/components/string_prop_type_test/string_prop_type_test.twig +++ /dev/null @@ -1 +0,0 @@ -<div{{ attributes.addClass('prop-test') }}>{{ string_prop }}</div> diff --git a/tests/modules/ui_patterns_tests_components/ui_patterns_tests_components.info.yml b/tests/modules/ui_patterns_tests_components/ui_patterns_tests_components.info.yml deleted file mode 100644 index bb8d28b8a1ef5e96405cf48f9c8b2ea22b17a875..0000000000000000000000000000000000000000 --- a/tests/modules/ui_patterns_tests_components/ui_patterns_tests_components.info.yml +++ /dev/null @@ -1,4 +0,0 @@ -name: "UI Patterns Tests components" -type: module -description: "Provides test components." -package: "Testing" diff --git a/tests/src/Functional/UiPatternsFunctionalTestBase.php b/tests/src/Functional/UiPatternsFunctionalTestBase.php index af4af9e2b7173cb35d422317e4c6f9d805f59ce0..a176ef528fc4213360638051416b10e51b737295 100644 --- a/tests/src/Functional/UiPatternsFunctionalTestBase.php +++ b/tests/src/Functional/UiPatternsFunctionalTestBase.php @@ -4,8 +4,8 @@ declare(strict_types=1); namespace Drupal\Tests\ui_patterns\Functional; -use Drupal\Component\Serialization\Yaml; use Drupal\Tests\BrowserTestBase; +use Drupal\Tests\ui_patterns\Traits\ConfigImporterTrait; use Drupal\Tests\ui_patterns\Traits\TestContentCreationTrait; use Drupal\Tests\ui_patterns\Traits\TestDataTrait; @@ -18,6 +18,7 @@ abstract class UiPatternsFunctionalTestBase extends BrowserTestBase { use TestContentCreationTrait; use TestDataTrait; + use ConfigImporterTrait; /** * {@inheritdoc} @@ -41,11 +42,6 @@ abstract class UiPatternsFunctionalTestBase extends BrowserTestBase { */ protected mixed $user = FALSE; - /** - * Config is initialized. - */ - private bool $configInitialize = FALSE; - /** * {@inheritdoc} */ @@ -59,48 +55,6 @@ abstract class UiPatternsFunctionalTestBase extends BrowserTestBase { } } - /** - * Initialize config. - */ - private function initializeConfig() { - if ($this->configInitialize === FALSE) { - $this->copyConfig(\Drupal::service('config.storage'), \Drupal::service('config.storage.sync')); - } - $this->configInitialize = TRUE; - } - - /** - * Load a configure fixture. - * - * @param string $path - * The path to the fixture. - * - * @return array - * The fixture. - */ - public function loadConfigFixture(string $path):array { - $yaml = file_get_contents($path); - if ($yaml === FALSE) { - throw new \InvalidArgumentException($path . ' not found.'); - } - return Yaml::decode($yaml); - } - - /** - * Import config fixture. - * - * @param string $config_id - * The config id. - * @param array $config - * The config fixture. - */ - public function importConfigFixture(string $config_id, array $config) { - $this->initializeConfig(); - \Drupal::service('config.storage.sync')->write($config_id, $config); - $config_importer = $this->configImporter(); - $config_importer->import(); - } - /** * Build UI Patterns compatible configuration for given test_set. * @@ -143,12 +97,14 @@ abstract class UiPatternsFunctionalTestBase extends BrowserTestBase { $prop_value = $element->getHtml(); // Replace "same" by normalized_value. if (isset($expected_output["same"])) { - if (!isset($expected_output["normalized_value"])) { + if (!is_array($expected_output["same"]) && !isset($expected_output["normalized_value"])) { $expected_output["normalized_value"] = "" . $expected_output["same"]; } unset($expected_output["same"]); } - $this->assertExpectedOutput($expected_output, $prop_value, $message); + if (count($expected_output) > 0) { + $this->assertExpectedOutput($expected_output, $prop_value, $message); + } } } } diff --git a/tests/src/Kernel/EntityTestBase.php b/tests/src/Kernel/EntityTestBase.php deleted file mode 100644 index b9673a5bb705bacd27f23acb7e560837cee65236..0000000000000000000000000000000000000000 --- a/tests/src/Kernel/EntityTestBase.php +++ /dev/null @@ -1,335 +0,0 @@ -<?php - -namespace Drupal\Tests\ui_patterns\Kernel; - -use Drupal\Core\Entity\ContentEntityInterface; -use Drupal\Core\Entity\EntityDisplayRepositoryInterface; -use Drupal\Core\Field\FieldStorageDefinitionInterface; -use Drupal\field\Entity\FieldConfig; -use Drupal\field\Entity\FieldStorageConfig; -use Drupal\field\FieldConfigInterface; -use Drupal\KernelTests\KernelTestBase; -use Drupal\node\Entity\NodeType; -use Drupal\Tests\node\Traits\NodeCreationTrait; -use Drupal\Tests\user\Traits\UserCreationTrait; -use Drupal\user\Entity\Role; -use Drupal\user\Entity\User; -use org\bovigo\vfs\vfsStreamWrapper; - -/** - * Defines a base class for node access kernel tests. - */ -abstract class EntityTestBase extends KernelTestBase { - - use NodeCreationTrait { - createNode as drupalCreateNode; - } - use UserCreationTrait { - createUser as drupalCreateUser; - } - - /** - * {@inheritdoc} - */ - protected string $defaultTheme = 'ui_patterns_test_theme'; - - - /** - * Default node bundle. - * - * @var string - */ - protected static string $defaultNodeBundle = 'page'; - - /** - * {@inheritdoc} - */ - protected static $modules = [ - 'user', - 'system', - 'sdc', - 'field', - 'text', - 'datetime', - 'filter', - 'ui_patterns', - 'ui_patterns_test', - 'ui_patterns_tests_components', - 'node', - ]; - - /** - * The source plugin manager. - * - * @var \Drupal\ui_patterns\SourcePluginManager - */ - protected $sourceManager; - - /** - * The field type plugin manager. - * - * @var \Drupal\Core\Field\FieldTypePluginManager - */ - protected $fieldTypeManager; - - /** - * Renderer. - * - * @var \Drupal\Core\Render\RendererInterface - */ - protected $renderer; - - /** - * Display repository. - * - * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface - */ - protected $displayRepository; - - /** - * Entity Type Manager. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface - */ - protected $entityTypeManager; - - - /** - * Entity Type. - * - * @var array<\Drupal\node\NodeTypeInterface> - */ - protected $entityTypes = []; - - /** - * Fields. - * - * @var array<\Drupal\field\FieldConfigInterface> - */ - protected $fields; - - /** - * {@inheritdoc} - */ - protected function setUp(): void { - vfsStreamWrapper::register(); - parent::setUp(); - $this->installSchema('user', 'users_data'); - $this->installConfig(['system', 'user']); - $this->installEntitySchema('user'); - // $this->drupalCreateUser(); - $this->installConfig('filter'); - $this->installEntitySchema('date_format'); - $this->fieldTypeManager = $this->container->get('plugin.manager.field.field_type'); - $this->sourceManager = $this->container->get('plugin.manager.ui_patterns_source'); - $this->setUpNode(); - $this->displayRepository = $this->container->get('entity_display.repository'); - $this->renderer = $this->container->get('renderer'); - $this->entityTypeManager = $this->container->get('entity_type.manager'); - \Drupal::service('theme_installer') - ->install([ - 'ui_patterns_test_theme', - ]); - $this->config('system.theme')->set('default', 'ui_patterns_test_theme')->save(); - - // Create a role with the desired permission. - $role = Role::create([ - 'id' => 'custom_role', - 'label' => 'Custom role', - ]); - // Example permission. - $role->grantPermission('access content'); - $role->save(); - - // Create a user and assign the role. - $user = User::create([ - 'name' => 'test_user', - 'status' => 1, - ]); - $user->addRole((string) $role->id()); - $user->save(); - - // Set the current user to the created user. - \Drupal::service('account_switcher')->switchTo($user); - // \Drupal::currentUser()->setAccount($user); - } - - /** - * Set up the node with fields. - * - * @throws \Drupal\Core\Entity\EntityStorageException - */ - private function setUpNode() : void { - $this->installSchema('node', 'node_access'); - $this->installEntitySchema('node'); - $this->installConfig(['field', 'node']); - // $this->randomMachineName(); - $bundle = self::$defaultNodeBundle; - $type = NodeType::load($bundle); - if (!$type) { - $type = NodeType::create([ - 'name' => $this->randomString(10), - 'type' => $bundle, - ]); - $type->save(); - } - $this->entityTypes[] = $type; - - $field_types = $this->fieldTypeManager->getDefinitions(); - - foreach (array_keys($field_types) as $field_type_id) { - $field_name = sprintf("field_%s_%s", $field_type_id, 1); - $bundle = (string) $type->id(); - $this->fields[$field_name] = - $this->createEntityField($type->getEntityType()->getBundleOf(), $bundle, $field_name, $field_type_id, 1); - $field_name = sprintf("field_%s", $field_type_id); - $this->fields[$field_name] = - $this->createEntityField($type->getEntityType()->getBundleOf(), $bundle, $field_name, $field_type_id, - FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); - } - } - - /** - * Create a field on a content type. - */ - protected function createEntityField( - string $entity_type, - string $bundle, - string $field_name, - string $field_type_id, - int $cardinality = FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED, - ) : FieldConfigInterface { - $field_type_definition = $this->fieldTypeManager->getDefinition($field_type_id); - // Create a field storage. - $field_storage = [ - 'field_name' => $field_name, - 'entity_type' => $entity_type, - 'type' => $field_type_id, - 'settings' => [], - 'cardinality' => $cardinality, - ]; - FieldStorageConfig::create($field_storage)->save(); - // Create a field instance on the content type. - $field = [ - 'field_name' => $field_storage['field_name'], - 'entity_type' => $entity_type, - 'bundle' => $bundle, - 'label' => $field_type_definition['label'], - 'settings' => [], - ]; - $field_config = FieldConfig::create($field); - $field_config->save(); - // Set cardinality. - $field_storage_reload = FieldStorageConfig::loadByName($entity_type, $field_name); - $field_storage_reload->setCardinality($cardinality); - $field_storage_reload->save(); - return $field_config; - } - - /** - * Normalize a string of markup for comparison. - */ - protected function normalizeMarkupString(string $markup): string { - $markup = preg_replace('/\s+/', ' ', $markup); - $markup = preg_replace('/\s*>\s*/', '>', $markup); - $markup = preg_replace('/\s*</', '<', $markup); - $markup = str_replace("\n", "", $markup); - $markup = trim($markup); - return $markup; - } - - /** - * Create a component settings. - * - * @param string $component_id - * The component id. - * @param array $props_data - * Array with source and source_id. - * @param array $slots_data - * Array of arrays with source and source_id. - * - * @return array<string, array|string> - * The component Settings - */ - protected function getComponentSettings(string $component_id, array $props_data, array $slots_data) : array { - $ui_patterns = [ - 'component_id' => $component_id, - 'variant_id' => '', - 'slots' => [], - 'props' => [], - ]; - foreach ($slots_data as $key_map => $slot_data_sources_for_slot) { - $ui_patterns["slots"][$key_map] = [ - "sources" => $slot_data_sources_for_slot, - /* - "sources" => [ - [ - "source" => $source_settings, - "source_id" => $source_id, - ], - ], - */ - ]; - } - foreach ($props_data as $key_map => $prop_data_sources_for_prop) { - $ui_patterns["props"][$key_map] = $prop_data_sources_for_prop; - } - return $ui_patterns; - } - - /** - * Render an entity. - * - * @param \Drupal\Core\Entity\ContentEntityInterface $entity - * The entity. - * @param string $view_mode - * (optional) The view mode. Defaults to self::DEFAULT_DISPLAY_MODE. - */ - public function renderEntity( - ContentEntityInterface $entity, - string $view_mode = EntityDisplayRepositoryInterface::DEFAULT_DISPLAY_MODE, - ) : mixed { - /** @var \Drupal\Core\Entity\EntityViewBuilderInterface $viewBuilder */ - $viewBuilder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId()); - $build = $viewBuilder->view($entity, $view_mode); - // $entity_display = $this->displayRepository->getViewDisplay( - // $entity->getEntityTypeId(), $entity->bundle(), $view_mode); - // $build = $entity_display->build($entity); - $this->renderer->renderRoot($build); - return (string) $build['#markup']; - } - - /** - * Set up the node with a field display. - * - * @param string $entity_type_id - * Entity type id. - * @param string $bundle - * Bundle. - * @param string $field_name - * Field name. - * @param array|null $display_component_settings - * Display Component settings for field. - * @param array $third_party_settings - * Display Component third party settings for field. - * - * @throws \Drupal\Core\Entity\EntityStorageException - */ - protected function setUpFieldDisplay(string $entity_type_id, string $bundle, string $field_name, ?array $display_component_settings, array $third_party_settings = []) : void { - $entity_display = $this->displayRepository->getViewDisplay($entity_type_id, $bundle); - $display_components = $entity_display->getComponents(); - foreach (array_keys($display_components) as $name) { - $entity_display->removeComponent($name); - } - if (is_array($display_component_settings)) { - $entity_display->setComponent($field_name, $display_component_settings); - foreach ($third_party_settings as $module => $third_party_settings_module) { - foreach ($third_party_settings_module as $key => $value) { - $entity_display->setThirdPartySetting($module, $key, $value); - } - } - } - $entity_display->save(); - } - -} diff --git a/tests/src/Kernel/FieldPropertySourceDeriverTest.php b/tests/src/Kernel/FieldPropertySourceDeriverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f647df9d6455fc463d441a70b9f76ae41174d063 --- /dev/null +++ b/tests/src/Kernel/FieldPropertySourceDeriverTest.php @@ -0,0 +1,140 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel; + +use Drupal\Component\Plugin\PluginBase; +use Drupal\Core\Plugin\Context\ContextDefinition; +use Drupal\Core\Plugin\Context\EntityContextDefinition; +use Drupal\Tests\ui_patterns\Traits\TestContentCreationTrait; +use Drupal\ui_patterns\Plugin\UiPatterns\Source\FieldPropertySource; + +/** + * Tests UI patterns field properties plugin deriver. + * + * @group ui_patterns + */ +class FieldPropertySourceDeriverTest extends SourcePluginsTestBase { + + use TestContentCreationTrait; + + /** + * {@inheritdoc} + */ + protected static $modules = ['ui_patterns', 'ui_patterns_test']; + + /** + * {@inheritdoc} + */ + protected $strictConfigSchema = FALSE; + + /** + * The source plugin manager. + * + * @var \Drupal\ui_patterns\SourcePluginManager + */ + protected $sourceManager; + + /** + * The field type plugin manager. + * + * @var \Drupal\Core\Field\FieldTypePluginManager + */ + protected $fieldTypeManager; + + /** + * The entity field manager. + * + * @var \Drupal\Core\Entity\EntityFieldManagerInterface + */ + protected $entityFieldManager; + + /** + * The ui patterns prop type plugin manager. + * + * @var \Drupal\ui_patterns\PropTypePluginManager + */ + protected $propTypePluginManager; + + /** + * The bundle. + * + * @var string + */ + protected $bundle = 'page'; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + $this->fieldTypeManager = $this->container->get('plugin.manager.field.field_type'); + $this->sourceManager = $this->container->get('plugin.manager.ui_patterns_source'); + $this->entityFieldManager = $this->container->get('entity_field.manager'); + $this->propTypePluginManager = $this->container->get('plugin.manager.ui_patterns_prop_type'); + $this->bundle = $this->randomMachineName(); + $this->createTestContentContentType($this->bundle); + } + + /** + * Tests creating fields of all types on a content type. + */ + public function testDerivedPluginPerFieldType() { + $field_maps = $this->entityFieldManager->getFieldMap(); + $this->sourceManager->clearCachedDefinitions(); + $definitions = $this->sourceManager->getDefinitions(); + foreach ($field_maps as $entity_type_id => $field_map) { + $field_storage_definitions = $this->entityFieldManager->getFieldStorageDefinitions($entity_type_id); + foreach (array_keys($field_map) as $field_name) { + if (!array_key_exists($field_name, $field_storage_definitions)) { + continue; + } + $field_storage_definition = $field_storage_definitions[$field_name]; + foreach ($field_storage_definition->getPropertyDefinitions() as $property_id => $property_definition) { + $prop_types = $this->propTypePluginManager->getAllPropTypeByTypedData($property_definition->getDataType()); + if (count($prop_types) === 0) { + continue; + } + $plugin_id = implode(PluginBase::DERIVATIVE_SEPARATOR, [ + 'field_property', + $entity_type_id, + $field_name, + $property_id, + ]); + $this->assertContains($plugin_id, array_keys($definitions), implode("\n", array_keys($definitions))); + $this->assertTrue($this->sourceManager->hasDefinition($plugin_id)); + $plugin = $this->sourceManager->getDefinition($plugin_id); + $this->assertEquals(FieldPropertySource::class, $plugin['class']); + $this->assertIsArray($plugin['prop_types']); + $prop_types = $plugin['prop_types']; + $this->assertTrue(count($prop_types) > 0); + $this->assertIsArray($plugin['context_definitions']); + $context_definitions = $plugin['context_definitions']; + $this->assertArrayHasKey('entity', $context_definitions); + $this->assertArrayHasKey('bundle', $context_definitions); + $this->assertArrayHasKey('field_name', $context_definitions); + $this->assertArrayHasKey('context_requirements', $context_definitions); + $this->assertCount(4, $context_definitions); + $entity_context = $context_definitions['entity']; + $this->assertInstanceOf(EntityContextDefinition::class, $entity_context); + /** @var \Drupal\Core\Plugin\Context\ContextDefinition $bundle_context */ + $bundle_context = $context_definitions['bundle']; + $this->assertInstanceOf(ContextDefinition::class, $entity_context); + $constraints = $bundle_context->getConstraints(); + $this->assertArrayHasKey('AllowedValues', $constraints); + $this->assertContains("", $constraints['AllowedValues']); + $field_name_context = $context_definitions['field_name']; + $this->assertInstanceOf(ContextDefinition::class, $field_name_context); + $this->assertArrayHasKey('AllowedValues', $field_name_context->getConstraints()); + $this->assertContains($field_name, $field_name_context->getConstraints()['AllowedValues']); + $this->assertIsArray($plugin['metadata']); + $metadata = $plugin['metadata']; + $this->assertArrayHasKey('field', $metadata); + $this->assertArrayHasKey('field_name', $metadata); + } + } + } + } + +} diff --git a/tests/src/Kernel/Source/AttributesWidgetTest.php b/tests/src/Kernel/Source/AttributesWidgetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d451eff6b4522996c763d40f2d2d1b5d1311ce69 --- /dev/null +++ b/tests/src/Kernel/Source/AttributesWidgetTest.php @@ -0,0 +1,25 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test AttributesWidget. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\AttributesWidget + * @group ui_patterns + */ +class AttributesWidgetTest extends SourcePluginsTestBase { + + /** + * Test AttributesWidget Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('attributes_'); + $this->runSourcePluginTests('attributes_', __DIR__ . "/../../../fixtures/source_only_tests.yml"); + } + +} diff --git a/tests/src/Kernel/Source/BlockSourceTest.php b/tests/src/Kernel/Source/BlockSourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8e784a77d39f71c5353a8874d04abbfcb760c042 --- /dev/null +++ b/tests/src/Kernel/Source/BlockSourceTest.php @@ -0,0 +1,25 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test BlockSource. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\BlockSource + * @group ui_patterns + */ +class BlockSourceTest extends SourcePluginsTestBase { + + /** + * Test BlockSource Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('block_'); + $this->runSourcePluginTests('block_', __DIR__ . "/../../../fixtures/block_tests.yml"); + } + +} diff --git a/tests/src/Kernel/Source/CheckboxWidgetTest.php b/tests/src/Kernel/Source/CheckboxWidgetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..67a667fb4871dd69dfb94197bc9ca3ad6f5bf3ce --- /dev/null +++ b/tests/src/Kernel/Source/CheckboxWidgetTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test CheckboxWidget. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\CheckboxWidget + * @group ui_patterns + */ +class CheckboxWidgetTest extends SourcePluginsTestBase { + + /** + * Test CheckboxWidget Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('checkbox_'); + } + +} diff --git a/tests/src/Kernel/Source/CheckboxesWidgetTest.php b/tests/src/Kernel/Source/CheckboxesWidgetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..efbdf1c6f1a44fd81065972f7e06fcca439bb98b --- /dev/null +++ b/tests/src/Kernel/Source/CheckboxesWidgetTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test CheckboxesWidget. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\CheckboxesWidget + * @group ui_patterns + */ +class CheckboxesWidgetTest extends SourcePluginsTestBase { + + /** + * Test CheckboxesWidget Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('checkboxes_'); + } + +} diff --git a/tests/src/Kernel/Source/ComponentSourceTest.php b/tests/src/Kernel/Source/ComponentSourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..37ad7175680f2450d6c37ad105c617262333a5fd --- /dev/null +++ b/tests/src/Kernel/Source/ComponentSourceTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test ComponentSource. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\ComponentSource + * @group ui_patterns + */ +class ComponentSourceTest extends SourcePluginsTestBase { + + /** + * Test ComponentSource Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('component_'); + } + +} diff --git a/tests/src/Kernel/Source/EntityFieldSourceTest.php b/tests/src/Kernel/Source/EntityFieldSourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3ad8942375fa91b3d97075dbc03366ba52383d19 --- /dev/null +++ b/tests/src/Kernel/Source/EntityFieldSourceTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test EntityFieldSource. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\EntityFieldSource + * @group ui_patterns + */ +class EntityFieldSourceTest extends SourcePluginsTestBase { + + /** + * Test EntityFieldSource Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('entity_field_'); + } + +} diff --git a/tests/src/Kernel/Source/EntityLinksSourceTest.php b/tests/src/Kernel/Source/EntityLinksSourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f5c0519b525722d1e240847579f76f929a7b5532 --- /dev/null +++ b/tests/src/Kernel/Source/EntityLinksSourceTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test EntityLinksSource. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\EntityLinksSource + * @group ui_patterns + */ +class EntityLinksSourceTest extends SourcePluginsTestBase { + + /** + * Test EntityLinksSource Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('entity_links_'); + } + +} diff --git a/tests/src/Kernel/Source/FieldPropertySourceTest.php b/tests/src/Kernel/Source/FieldPropertySourceTest.php index 6f0db193680bf39e328b8b0c0d95a069ffd2f2ac..6604ce510747265086ab73dbcd75c85cf77f61e3 100644 --- a/tests/src/Kernel/Source/FieldPropertySourceTest.php +++ b/tests/src/Kernel/Source/FieldPropertySourceTest.php @@ -15,17 +15,10 @@ use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; class FieldPropertySourceTest extends SourcePluginsTestBase { /** - * Test Field Property Plugin. + * Test FieldPropertySource Plugin. */ public function testPlugin(): void { - $testData = self::loadTestDataFixture(__DIR__ . "/../../../fixtures/TestDataSet.yml"); - $testSets = $testData->getTestSets(); - foreach ($testSets as $test_set_name => $test_set) { - if (!str_starts_with($test_set_name, 'field_property_')) { - continue; - } - $this->runSourcePluginTest($test_set); - } + $this->runSourcePluginTests('field_property_'); } } diff --git a/tests/src/Kernel/Source/ListTextareaWidgetTest.php b/tests/src/Kernel/Source/ListTextareaWidgetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d8c8ffb226ed9e1c03251cb81bc4a3d451f93854 --- /dev/null +++ b/tests/src/Kernel/Source/ListTextareaWidgetTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test ListTextareaWidget. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\ListTextareaWidget + * @group ui_patterns + */ +class ListTextareaWidgetTest extends SourcePluginsTestBase { + + /** + * Test ListTextareaWidget Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('list_textarea_'); + } + +} diff --git a/tests/src/Kernel/Source/MenuSourceTest.php b/tests/src/Kernel/Source/MenuSourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4c91dd451f0502cb7739b99f635d07638ebf3ea9 --- /dev/null +++ b/tests/src/Kernel/Source/MenuSourceTest.php @@ -0,0 +1,61 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; +use Drupal\menu_link_content\Entity\MenuLinkContent; + +/** + * Test MenuSource. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\MenuSource + * @group ui_patterns + */ +class MenuSourceTest extends SourcePluginsTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ["link", "menu_link_content", "menu_ui"]; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + // @todo Change the autogenerated stub + parent::setUp(); + $this->installEntitySchema('menu_link_content'); + $this->installEntitySchema('user'); + $link = MenuLinkContent::create([ + 'menu_name' => 'main', + 'link' => [['uri' => 'internal:/example-path']], + 'weight' => 5, + ]); + $link->save(); + } + + /** + * Test MenuSource Plugin. + */ + public function testPlugin(): void { + $testData = self::loadTestDataFixture(__DIR__ . "/../../../fixtures/menu_tests.yml"); + $testSet = $testData->getTestSet("menu_1"); + $testSet["output"] = [ + "props" => [ + "links" => [ + "closure" => function ($output_of_source) { + $this->assertNotNull($output_of_source); + $this->assertTrue(is_array($output_of_source)); + $this->assertTrue(count($output_of_source) > 0); + $this->assertTrue(is_array($output_of_source[0])); + $this->assertEquals($output_of_source[0]["url"], "/example-path"); + }, + ], + ], + ]; + $this->runSourcePluginTest($testSet); + } + +} diff --git a/tests/src/Kernel/Source/NumberWidgetTest.php b/tests/src/Kernel/Source/NumberWidgetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0035564ebbcb73141b05e65fc11a8c6233eec872 --- /dev/null +++ b/tests/src/Kernel/Source/NumberWidgetTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test NumberWidget. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\NumberWidget + * @group ui_patterns + */ +class NumberWidgetTest extends SourcePluginsTestBase { + + /** + * Test NumberWidget Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('number_'); + } + +} diff --git a/tests/src/Kernel/Source/PathSourceTest.php b/tests/src/Kernel/Source/PathSourceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..643270616bc6a3e8b44c22242f6845440da399ac --- /dev/null +++ b/tests/src/Kernel/Source/PathSourceTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test PathSource. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\PathSource + * @group ui_patterns + */ +class PathSourceTest extends SourcePluginsTestBase { + + /** + * Test PathSource Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('path_'); + } + +} diff --git a/tests/src/Kernel/Source/SelectWidgetTest.php b/tests/src/Kernel/Source/SelectWidgetTest.php index d73cb98ab85a4ff66ed3e6d22e20065ed8e0ef7f..43133b76c6482d6b60772639c4c9d01841a31703 100644 --- a/tests/src/Kernel/Source/SelectWidgetTest.php +++ b/tests/src/Kernel/Source/SelectWidgetTest.php @@ -9,22 +9,16 @@ use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; /** * Test SelectWidget. * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\SelectWidget * @group ui_patterns */ class SelectWidgetTest extends SourcePluginsTestBase { /** - * Test UI Patterns source core plugins. + * Test SelectWidget Plugin. */ public function testPlugin(): void { - $testData = self::loadTestDataFixture(__DIR__ . "/../../../fixtures/TestDataSet.yml"); - $testSets = $testData->getTestSets(); - foreach ($testSets as $test_set_name => $test_set) { - if (!str_starts_with($test_set_name, 'select_')) { - continue; - } - $this->runSourcePluginTest($test_set); - } + $this->runSourcePluginTests('select_'); } } diff --git a/tests/src/Kernel/Source/TextWidgetTest.php b/tests/src/Kernel/Source/TextWidgetTest.php deleted file mode 100644 index f268b19e1119e627655b4c511d47424d7ac2b360..0000000000000000000000000000000000000000 --- a/tests/src/Kernel/Source/TextWidgetTest.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\Tests\ui_patterns\Kernel\Source; - -use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; - -/** - * Test SourcePluginManager. - * - * @group ui_patterns - */ -class TextWidgetTest extends SourcePluginsTestBase { - - /** - * Test UI Patterns source core plugins. - */ - public function testPlugin(): void { - $testData = self::loadTestDataFixture(__DIR__ . "/../../../fixtures/TestDataSet.yml"); - $testSets = $testData->getTestSets(); - foreach ($testSets as $test_set_name => $test_set) { - if (!str_starts_with($test_set_name, 'textfield_')) { - continue; - } - $this->runSourcePluginTest($test_set); - } - } - -} diff --git a/tests/src/Kernel/Source/TextfieldWidgetTest.php b/tests/src/Kernel/Source/TextfieldWidgetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..feb076c6b91e1b047cbe8f48ccc89a0ac634c087 --- /dev/null +++ b/tests/src/Kernel/Source/TextfieldWidgetTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test TextfieldWidget. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\TextfieldWidget + * @group ui_patterns + */ +class TextfieldWidgetTest extends SourcePluginsTestBase { + + /** + * Test TextfieldWidget Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('textfield_'); + } + +} diff --git a/tests/src/Kernel/Source/TokenSourceTest.php b/tests/src/Kernel/Source/TokenSourceTest.php index 522647989cc85ddd15e9baf446e6e48ce427c3ad..6cf47e1c1176e0ed7596fc26a0008600fb00e115 100644 --- a/tests/src/Kernel/Source/TokenSourceTest.php +++ b/tests/src/Kernel/Source/TokenSourceTest.php @@ -7,24 +7,18 @@ namespace Drupal\Tests\ui_patterns\Kernel\Source; use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; /** - * Test SourcePluginManager. + * Test TokenSource. * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\TokenSource * @group ui_patterns */ class TokenSourceTest extends SourcePluginsTestBase { /** - * Test UI Patterns source core plugins. + * Test TokenSource Plugin. */ public function testPlugin(): void { - $testData = self::loadTestDataFixture(__DIR__ . "/../../../fixtures/TestDataSet.yml"); - $testSets = $testData->getTestSets(); - foreach ($testSets as $test_set_name => $test_set) { - if (!str_starts_with($test_set_name, 'token_')) { - continue; - } - $this->runSourcePluginTest($test_set); - } + $this->runSourcePluginTests('token_'); } } diff --git a/tests/src/Kernel/Source/UrlWidgetTest.php b/tests/src/Kernel/Source/UrlWidgetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f48418a04af7f9a86a6398778889450c0a4b1947 --- /dev/null +++ b/tests/src/Kernel/Source/UrlWidgetTest.php @@ -0,0 +1,24 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test UrlWidget. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\UrlWidget + * @group ui_patterns + */ +class UrlWidgetTest extends SourcePluginsTestBase { + + /** + * Test UrlWidget Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('url_'); + } + +} diff --git a/tests/src/Kernel/Source/WysiwygWidgetTest.php b/tests/src/Kernel/Source/WysiwygWidgetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e5eb9c17a3b060702cc29bb4567f411a95573eb7 --- /dev/null +++ b/tests/src/Kernel/Source/WysiwygWidgetTest.php @@ -0,0 +1,34 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Kernel\Source; + +use Drupal\Tests\ui_patterns\Kernel\SourcePluginsTestBase; + +/** + * Test WysiwygWidget. + * + * @coversDefaultClass \Drupal\ui_patterns\Plugin\UiPatterns\Source\WysiwygWidget + * @group ui_patterns + */ +class WysiwygWidgetTest extends SourcePluginsTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['editor', 'filter', 'text']; + + /** + * Test WysiwygWidget Plugin. + */ + public function testPlugin(): void { + $this->runSourcePluginTests('wysiwyg_'); + $config_import = $this->loadConfigFixture(__DIR__ . '/../../../fixtures/config/filter.format.html.yml'); + $this->importConfigFixture('filter.format.html', $config_import); + $testData = self::loadTestDataFixture(__DIR__ . "/../../../fixtures/wysiwyg_tests.yml"); + $testSet = $testData->getTestSet("wysiwyg_html"); + $this->runSourcePluginTest($testSet); + } + +} diff --git a/tests/src/Kernel/SourcePluginManagerTest.php b/tests/src/Kernel/SourcePluginManagerTest.php index 3d4dff365643640e8991501cf5b9d8501bd12ff5..264f1ea226788daa2a2eb87d8a0214e034b1b60b 100644 --- a/tests/src/Kernel/SourcePluginManagerTest.php +++ b/tests/src/Kernel/SourcePluginManagerTest.php @@ -5,8 +5,8 @@ declare(strict_types=1); namespace Drupal\Tests\ui_patterns\Kernel; use Drupal\Core\Plugin\Context\EntityContext; -use Drupal\entity_test\Entity\EntityTest; use Drupal\KernelTests\KernelTestBase; +use Drupal\entity_test\Entity\EntityTest; use Drupal\ui_patterns\SourcePluginBase; use Drupal\ui_patterns\SourcePluginManager; diff --git a/tests/src/Kernel/SourcePluginsTestBase.php b/tests/src/Kernel/SourcePluginsTestBase.php index 874a5a5b00effe08ca2e04b27ebac7e2c13d1135..3b6b3c0631137af4e54b8e3bfe4868ea4f2505c3 100644 --- a/tests/src/Kernel/SourcePluginsTestBase.php +++ b/tests/src/Kernel/SourcePluginsTestBase.php @@ -6,6 +6,7 @@ namespace Drupal\Tests\ui_patterns\Kernel; use Drupal\Core\Plugin\Context\EntityContext; use Drupal\KernelTests\KernelTestBase; +use Drupal\Tests\ui_patterns\Traits\ConfigImporterTrait; use Drupal\Tests\ui_patterns\Traits\RunSourcePluginTestTrait; use Drupal\Tests\ui_patterns\Traits\TestContentCreationTrait; @@ -18,6 +19,7 @@ class SourcePluginsTestBase extends KernelTestBase { use RunSourcePluginTestTrait; use TestContentCreationTrait; + use ConfigImporterTrait; /** * {@inheritdoc} @@ -58,4 +60,23 @@ class SourcePluginsTestBase extends KernelTestBase { return $context; } + /** + * Run source plugin tests against a test set. + * + * @param string|null $test_starts_with + * The prefix of the test set name to run. + * @param string|null $tests_path + * The path to the test data fixture. + */ + public function runSourcePluginTests(?string $test_starts_with = NULL, ?string $tests_path = NULL): void { + $testData = self::loadTestDataFixture($tests_path ?? __DIR__ . "/../../fixtures/TestDataSet.yml"); + $testSets = $testData->getTestSets(); + foreach ($testSets as $test_set_name => $test_set) { + if ($test_starts_with && !str_starts_with($test_set_name, $test_starts_with)) { + continue; + } + $this->runSourcePluginTest($test_set); + } + } + } diff --git a/tests/src/Traits/ConfigImporterTrait.php b/tests/src/Traits/ConfigImporterTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..854b3186baaec193be3db54c057158c23b39d937 --- /dev/null +++ b/tests/src/Traits/ConfigImporterTrait.php @@ -0,0 +1,61 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\ui_patterns\Traits; + +use Drupal\Component\Serialization\Yaml; + +/** + * Entity test data trait. + */ +trait ConfigImporterTrait { + + /** + * Config is initialized. + */ + private bool $configInitialize = FALSE; + + /** + * Initialize config. + */ + private function initializeConfig() { + if ($this->configInitialize === FALSE) { + $this->copyConfig(\Drupal::service('config.storage'), \Drupal::service('config.storage.sync')); + } + $this->configInitialize = TRUE; + } + + /** + * Load a configure fixture. + * + * @param string $path + * The path to the fixture. + * + * @return array + * The fixture. + */ + public function loadConfigFixture(string $path):array { + $yaml = file_get_contents($path); + if ($yaml === FALSE) { + throw new \InvalidArgumentException($path . ' not found.'); + } + return Yaml::decode($yaml); + } + + /** + * Import config fixture. + * + * @param string $config_id + * The config id. + * @param array $config + * The config fixture. + */ + public function importConfigFixture(string $config_id, array $config) { + $this->initializeConfig(); + \Drupal::service('config.storage.sync')->write($config_id, $config); + $config_importer = $this->configImporter(); + $config_importer->import(); + } + +} diff --git a/tests/src/Traits/TestContentCreationTrait.php b/tests/src/Traits/TestContentCreationTrait.php index f2e9b8a0ed2a4da1a21d31473036b13f980f2a64..e7add3bc1f9babccde714146fa787f4e5706a656 100644 --- a/tests/src/Traits/TestContentCreationTrait.php +++ b/tests/src/Traits/TestContentCreationTrait.php @@ -6,12 +6,12 @@ namespace Drupal\Tests\ui_patterns\Traits; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\FieldTypePluginManager; +use Drupal\Tests\node\Traits\NodeCreationTrait; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\field\FieldConfigInterface; use Drupal\node\Entity\NodeType; use Drupal\node\NodeInterface; -use Drupal\Tests\node\Traits\NodeCreationTrait; /** * Entity test data trait. diff --git a/tests/src/Traits/TestDataTrait.php b/tests/src/Traits/TestDataTrait.php index 74338d9ea59bcc91c06c4ac2e5a70b83a0ec3e71..61d2c856f146e2f7255e9733bcb349667d67dab2 100644 --- a/tests/src/Traits/TestDataTrait.php +++ b/tests/src/Traits/TestDataTrait.php @@ -77,6 +77,12 @@ trait TestDataTrait { $assert_done = TRUE; } if (isset($expected_result['regEx'])) { + if (is_array($result)) { + throw new \Exception("invalid result to test for regEx: " . print_r($result, TRUE)); + } + if (!is_string($result)) { + $result = "" . $result; + } $this->assertTrue(preg_match($expected_result['regEx'], $result) === 1, $message); $assert_done = TRUE; } @@ -88,7 +94,7 @@ trait TestDataTrait { } $normalized_rendered = self::normalizeMarkupString($rendered); if (isset($expected_result['rendered_value'])) { - $this->assertContains($expected_result['rendered_value'], [$normalized_rendered], sprintf("%s: '%s' VS '%s'", $message, $normalized_rendered, $normalized_rendered)); + $this->assertContains($expected_result['rendered_value'], [$normalized_rendered], sprintf("%s: '%s' VS '%s' (%s)", $message, $expected_result['rendered_value'], $normalized_rendered, print_r($result, TRUE))); } if (isset($expected_result['rendered_value_plain'])) { $rendered_plain = Xss::filter($normalized_rendered); @@ -96,6 +102,10 @@ trait TestDataTrait { } $assert_done = TRUE; } + if (isset($expected_result['closure'])) { + $expected_result['closure']($result); + $assert_done = TRUE; + } if (!$assert_done) { throw new \RuntimeException(sprintf('Missing "value" or "regEx" in expected result %s', print_r($expected_result, TRUE))); }