Skip to content
Snippets Groups Projects
Commit 1ae87c92 authored by christian.wiedemann's avatar christian.wiedemann
Browse files

Issue #3475857 by christian.wiedemann, pdureau: [2.0.0-beta3] Invalid instance...

Issue #3475857 by christian.wiedemann, pdureau: [2.0.0-beta3] Invalid instance of Attribute when prop type is Drupal\Core\Template\Attribute
parent c8b78329
No related branches found
No related tags found
1 merge request!223Add Attributes workaround
Pipeline #290335 passed with warnings
......@@ -58,6 +58,8 @@ class LayoutBuilderRenderTest extends UiPatternsFunctionalTestBase {
$test_data = $this->loadTestDataFixture();
$tests = [
$test_data->getTestSet('func_attributes_empty'),
$test_data->getTestSet('func_attributes_default'),
$test_data->getTestSet('textfield_default'),
$test_data->getTestSet('token_default'),
$test_data->getTestSet('context_exists_default'),
......@@ -66,16 +68,20 @@ class LayoutBuilderRenderTest extends UiPatternsFunctionalTestBase {
foreach ($tests as $test_set) {
$node = $this->createTestContentNode('page', $test_set['entity'] ?? []);
$ui_patterns_config = $this->buildUiPatternsConfig($test_set);
$config_import['third_party_settings']['layout_builder']['sections'][0]['layout_id'] = 'ui_patterns:' . str_replace('-', '_', $test_set['component']['component_id']);
$this->importConfigFixture(
'core.entity_view_display.node.page.full',
$config_import
);
$this->drupalGet('admin/structure/types/manage/page/display/full/layout');
$assert_session->elementExists('css', '.ui-patterns-test-component');
$assert_session->statusCodeEquals(200);
$component_id = str_replace('_', '-', explode(':', $test_set['component']['component_id'])[1]);
$assert_session->elementExists('css', '.ui-patterns-' . $component_id);
$this->drupalGet('node/' . $node->id());
$assert_session->elementExists('css', '.ui-patterns-test-component');
$assert_session->statusCodeEquals(200);
$assert_session->elementExists('css', '.ui-patterns-' . $component_id);
$this->validateRenderedComponent($test_set);
$node->delete();
}
}
......
......@@ -8,6 +8,7 @@ use Drupal\Core\Plugin\Component;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Theme\ComponentPluginManager;
use Drupal\ui_patterns\Plugin\UiPatterns\PropType\SlotPropType;
use Drupal\ui_patterns\PropTypeAdapterPluginManager;
/**
* Our additions to the SDC render element.
......@@ -17,7 +18,7 @@ class ComponentElementAlter implements TrustedCallbackInterface {
/**
* Constructs a ComponentElementAlter.
*/
public function __construct(protected ComponentPluginManager $componentPluginManager) {
public function __construct(protected ComponentPluginManager $componentPluginManager, protected PropTypeAdapterPluginManager $adaptersManager) {
}
/**
......@@ -68,8 +69,19 @@ class ComponentElementAlter implements TrustedCallbackInterface {
if (!isset($props[$prop_id])) {
continue;
}
$prop_type = $props[$prop_id]['ui_patterns']['type_definition'];
$element["#props"][$prop_id] = $prop_type->normalize($prop);
$definition = $props[$prop_id];
$prop_type = $definition['ui_patterns']['type_definition'];
// Normalizing attributes to an array is not working
// if the prop type is defined by type=Drupal\Core\Template\Attribute
// This should actually be done by the normalize function.
$data = $prop_type->normalize($prop);
if (isset($definition['ui_patterns']['prop_type_adapter'])) {
$prop_type_adapter_id = $definition['ui_patterns']['prop_type_adapter'];
/** @var \Drupal\ui_patterns\PropTypeAdapterInterface $prop_type_adapter */
$prop_type_adapter = $this->adaptersManager->createInstance($prop_type_adapter_id);
$data = $prop_type_adapter->transform($data);
}
$element["#props"][$prop_id] = $data;
}
return $element;
}
......
......@@ -8,7 +8,6 @@ use Drupal\Core\Plugin\Component;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Theme\ComponentPluginManager;
use Drupal\ui_patterns\ComponentPluginManager as UiPatternsComponentPluginManager;
use Drupal\ui_patterns\PropTypeAdapterPluginManager;
use Drupal\ui_patterns\PropTypePluginManager;
use Drupal\ui_patterns\SourceInterface;
use Drupal\ui_patterns\SourcePluginBase;
......@@ -32,7 +31,6 @@ class ComponentElementBuilder implements TrustedCallbackInterface {
public function __construct(
protected SourcePluginManager $sourcesManager,
protected PropTypePluginManager $propTypeManager,
protected PropTypeAdapterPluginManager $adaptersManager,
protected ComponentPluginManager $componentPluginManager,
) {
}
......@@ -86,12 +84,7 @@ class ComponentElementBuilder implements TrustedCallbackInterface {
$prop_type = $definition['ui_patterns']['type_definition'];
$build = $source->alterComponent($build);
$data = $source->getValue($prop_type);
if (isset($definition['ui_patterns']['prop_type_adapter'])) {
$prop_type_adapter_id = $definition['ui_patterns']['prop_type_adapter'];
/** @var \Drupal\ui_patterns\PropTypeAdapterInterface $prop_type_adapter */
$prop_type_adapter = $this->adaptersManager->createInstance($prop_type_adapter_id);
$data = $prop_type_adapter->transform($data);
}
if (empty($data) && $prop_type->getPluginId() !== 'attributes') {
// For JSON Schema validator, empty value is not the same as missing
// value, and we want to prevent some of the prop types rules to be
......
---
func_attributes_empty:
component:
component_id: ui_patterns_test:test-component
props:
attributes_implicit:
source_id: attributes
source:
value: ''
attributes_ui_patterns:
source_id: attributes
source:
value: ''
attributes_class:
source_id: attributes
source:
value: ''
output:
props:
attributes_implicit:
normalized_value: ''
entity: {}
func_attributes_default:
component:
component_id: ui_patterns_test:test-component
props:
attributes_implicit:
source_id: attributes
source:
value: 'ui_patterns="foo"'
attributes_ui_patterns:
source_id: attributes
source:
value: 'ui_patterns="foo"'
attributes_class:
source_id: attributes
source:
value: 'ui_patterns="foo"'
output:
props:
attributes_implicit:
value: 'ui_patterns="foo"'
attributes_ui_patterns:
value: 'ui_patterns="foo"'
attributes_class:
value: 'ui_patterns="foo"'
entity: {}
field_property_default:
# we configure a component
component:
......
......@@ -62,6 +62,26 @@ props:
type: "array"
items:
type: ["string", "integer"]
attributes_implicit:
title: "Attributes (implicit typing)"
type: object
patternProperties:
".+":
anyOf:
- type:
- string
- number
- type: array
items:
anyOf:
- type: number
- type: string
attributes_ui_patterns:
title: "Attributes (explicit typing)"
"$ref": "ui-patterns://attributes"
attributes_class:
title: "Attributes when type is a PHP namespace"
type: 'Drupal\Core\Template\Attribute'
slots:
slot:
title: "Slot"
......@@ -56,6 +56,15 @@
<span>{{ item }}</span>
{% endfor %}
</div>
<div class="ui-patterns-props-attributes_implicit">
{{ attributes_implicit }}
</div>
<div class="ui-patterns-props-attributes_ui_patterns">
{{ attributes_ui_patterns }}
</div>
<div class="ui-patterns-props-attributes_class">
{{ attributes_class }}
</div>
<div class="ui-patterns-slots-slot">
{{ slot }}
</div>
......
......@@ -4,10 +4,12 @@ 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;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
/**
* Base function testing.
......@@ -53,6 +55,52 @@ abstract class UiPatternsFunctionalTestBase extends BrowserTestBase {
if ($this->user) {
$this->drupalLogin($this->user);
}
else {
throw new AccessDeniedHttpException($this->getTextContent());
}
}
/**
* 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->configInitialize = FALSE;
$this->initializeConfig();
\Drupal::service('config.storage.sync')->write($config_id, $config);
$config_importer = $this->configImporter();
$config_importer->import();
}
/**
......@@ -82,6 +130,7 @@ abstract class UiPatternsFunctionalTestBase extends BrowserTestBase {
protected function validateRenderedComponent($test_set) {
$output = $test_set['output'] ?? [];
$page = $this->getSession()->getPage();
foreach ($output as $prop_or_slot => $prop_or_slot_item) {
foreach ($prop_or_slot_item as $prop_name => $output) {
$expected_outputs_here = ($prop_or_slot === "props") ? [$output] : $output;
......
......@@ -45,12 +45,12 @@ services:
arguments:
- "@plugin.manager.ui_patterns_source"
- "@plugin.manager.ui_patterns_prop_type"
- "@plugin.manager.ui_patterns_prop_type_adapter"
- "@plugin.manager.sdc"
ui_patterns.component_element_alter:
class: Drupal\ui_patterns\Element\ComponentElementAlter
arguments:
- "@plugin.manager.sdc"
- "@plugin.manager.ui_patterns_prop_type_adapter"
# JSON schema management.
ui_patterns.schema_stream_wrapper:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment