From 5c8753e00323a9ef4934b1245a22111bcd833044 Mon Sep 17 00:00:00 2001 From: nod_ <nod_@598310.no-reply.drupal.org> Date: Sun, 11 Aug 2024 07:03:41 +0200 Subject: [PATCH] Issue #3465855 by catch, smustgrave: Split up FormTest (cherry picked from commit c3dd9aa0b632c815b6f9f843557d132dfe885bfc) --- .../field/tests/src/Functional/FormTest.php | 135 ---------- .../src/Functional/MultipleWidgetFormTest.php | 245 ++++++++++++++++++ 2 files changed, 245 insertions(+), 135 deletions(-) create mode 100644 core/modules/field/tests/src/Functional/MultipleWidgetFormTest.php diff --git a/core/modules/field/tests/src/Functional/FormTest.php b/core/modules/field/tests/src/Functional/FormTest.php index 80fcfd6198c3..97c7a36980b2 100644 --- a/core/modules/field/tests/src/Functional/FormTest.php +++ b/core/modules/field/tests/src/Functional/FormTest.php @@ -17,7 +17,6 @@ * Tests field form handling. * * @group field - * @group #slow */ class FormTest extends FieldTestBase { @@ -29,7 +28,6 @@ class FormTest extends FieldTestBase { * @var array */ protected static $modules = [ - 'node', 'field_test', 'options', 'entity_test', @@ -49,13 +47,6 @@ class FormTest extends FieldTestBase { */ protected $fieldStorageSingle; - /** - * An array of values defining a field multiple. - * - * @var array - */ - protected $fieldStorageMultiple; - /** * An array of values defining a field with unlimited cardinality. * @@ -88,12 +79,6 @@ protected function setUp(): void { 'entity_type' => 'entity_test', 'type' => 'test_field', ]; - $this->fieldStorageMultiple = [ - 'field_name' => 'field_multiple', - 'entity_type' => 'entity_test', - 'type' => 'test_field', - 'cardinality' => 4, - ]; $this->fieldStorageUnlimited = [ 'field_name' => 'field_unlimited', 'entity_type' => 'entity_test', @@ -436,62 +421,6 @@ public function testFieldFormMultivalueWithRequiredRadio(): void { $this->assertSession()->fieldNotExists("{$field_name}[2][value]"); } - /** - * Tests widgets handling multiple values. - */ - public function testFieldFormMultipleWidget(): void { - // Create a field with fixed cardinality, configure the form to use a - // "multiple" widget. - $field_storage = $this->fieldStorageMultiple; - $field_name = $field_storage['field_name']; - $this->field['field_name'] = $field_name; - FieldStorageConfig::create($field_storage)->save(); - FieldConfig::create($this->field)->save(); - $form = \Drupal::service('entity_display.repository')->getFormDisplay($this->field['entity_type'], $this->field['bundle'], 'default') - ->setComponent($field_name, [ - 'type' => 'test_field_widget_multiple', - ]); - $form->save(); - $session = $this->assertSession(); - - // Display creation form. - $this->drupalGet('entity_test/add'); - $this->assertSession()->fieldValueEquals($field_name, ''); - - // Create entity with three values. - $edit = [ - $field_name => '1, 2, 3', - ]; - $this->submitForm($edit, 'Save'); - preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match); - $id = $match[1]; - - // Check that the values were saved. - $entity_init = EntityTest::load($id); - $this->assertFieldValues($entity_init, $field_name, [1, 2, 3]); - - // Display the form, check that the values are correctly filled in. - $this->drupalGet('entity_test/manage/' . $id . '/edit'); - $this->assertSession()->fieldValueEquals($field_name, '1, 2, 3'); - - // Submit the form with more values than the field accepts. - $edit = [$field_name => '1, 2, 3, 4, 5']; - $this->submitForm($edit, 'Save'); - $this->assertSession()->pageTextContains('this field cannot hold more than 4 values'); - // Check that the field values were not submitted. - $this->assertFieldValues($entity_init, $field_name, [1, 2, 3]); - - // Check that Attributes are rendered on the multivalue container if it is - // a multiple widget form. - $form->setComponent($field_name, [ - 'type' => 'entity_reference_autocomplete', - ]) - ->save(); - $this->drupalGet('entity_test/manage/' . $id . '/edit'); - $name = str_replace('_', '-', $field_name); - $session->responseContains('data-drupal-selector="edit-' . $name . '"'); - } - /** * Tests fields with no 'edit' access. */ @@ -704,68 +633,4 @@ public function testLabelOnMultiValueFields(): void { $this->assertSession()->assertEscaped("<script>alert('a configurable field');</script>"); } - /** - * Tests hook_field_widget_complete_form_alter(). - */ - public function testFieldFormMultipleWidgetAlter(): void { - $this->widgetAlterTest('hook_field_widget_complete_form_alter', 'test_field_widget_multiple'); - } - - /** - * Tests hook_field_widget_complete_form_alter() with single value elements. - */ - public function testFieldFormMultipleWidgetAlterSingleValues(): void { - $this->widgetAlterTest('hook_field_widget_complete_form_alter', 'test_field_widget_multiple_single_value'); - } - - /** - * Tests hook_field_widget_complete_WIDGET_TYPE_form_alter(). - */ - public function testFieldFormMultipleWidgetTypeAlter(): void { - $this->widgetAlterTest('hook_field_widget_complete_WIDGET_TYPE_form_alter', 'test_field_widget_multiple'); - } - - /** - * Tests hook_field_widget_complete_WIDGET_TYPE_form_alter() with single value elements. - */ - public function testFieldFormMultipleWidgetTypeAlterSingleValues(): void { - $this->widgetAlterTest('hook_field_widget_complete_WIDGET_TYPE_form_alter', 'test_field_widget_multiple_single_value'); - } - - /** - * Tests widget alter hooks for a given hook name. - */ - protected function widgetAlterTest($hook, $widget) { - // Create a field with fixed cardinality, configure the form to use a - // "multiple" widget. - $field_storage = $this->fieldStorageMultiple; - $field_name = $field_storage['field_name']; - $this->field['field_name'] = $field_name; - FieldStorageConfig::create($field_storage)->save(); - FieldConfig::create($this->field)->save(); - - // Set a flag in state so that the hook implementations will run. - \Drupal::state()->set("field_test.widget_alter_test", [ - 'hook' => $hook, - 'field_name' => $field_name, - 'widget' => $widget, - ]); - \Drupal::service('entity_display.repository')->getFormDisplay($this->field['entity_type'], $this->field['bundle'], 'default') - ->setComponent($field_name, [ - 'type' => $widget, - ]) - ->save(); - - // We need to rebuild hook information after setting the component through - // the API. - $this->rebuildAll(); - - $this->drupalGet('entity_test/add'); - $this->assertSession()->pageTextMatchesCount(1, '/From ' . $hook . '.* prefix on ' . $field_name . ' parent element\./'); - if ($widget === 'test_field_widget_multiple_single_value') { - $suffix_text = "From $hook(): suffix on $field_name child element."; - $this->assertEquals($field_storage['cardinality'], substr_count($this->getTextContent(), $suffix_text), "'$suffix_text' was found {$field_storage['cardinality']} times using widget $widget"); - } - } - } diff --git a/core/modules/field/tests/src/Functional/MultipleWidgetFormTest.php b/core/modules/field/tests/src/Functional/MultipleWidgetFormTest.php new file mode 100644 index 000000000000..3dd8da2e89ee --- /dev/null +++ b/core/modules/field/tests/src/Functional/MultipleWidgetFormTest.php @@ -0,0 +1,245 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\field\Functional; + +use Drupal\Core\Entity\Entity\EntityFormDisplay; +use Drupal\entity_test\Entity\EntityTest; +use Drupal\entity_test\Entity\EntityTestBaseFieldDisplay; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; + +/** + * Tests field form handling. + * + * @group field + */ +class MultipleWidgetFormTest extends FieldTestBase { + + /** + * Modules to enable. + * + * Locale is installed so that TranslatableMarkup actually does something. + * + * @var array + */ + protected static $modules = [ + 'field_test', + 'options', + 'entity_test', + 'locale', + 'field_ui', + ]; + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * An array of values defining a field multiple. + * + * @var array + */ + protected $fieldStorageMultiple; + + /** + * An array of values defining a field. + * + * @var array + */ + protected $field; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + + $web_user = $this->drupalCreateUser([ + 'view test entity', + 'administer entity_test content', + 'administer entity_test fields', + ]); + $this->drupalLogin($web_user); + + $this->fieldStorageMultiple = [ + 'field_name' => 'field_multiple', + 'entity_type' => 'entity_test', + 'type' => 'test_field', + 'cardinality' => 4, + ]; + + $this->field = [ + 'entity_type' => 'entity_test', + 'bundle' => 'entity_test', + 'label' => $this->randomMachineName() . '_label', + 'description' => '[site:name]_description', + 'weight' => mt_rand(0, 127), + 'settings' => [ + 'test_field_setting' => $this->randomMachineName(), + ], + ]; + } + + /** + * Tests widgets handling multiple values. + */ + public function testFieldFormMultipleWidget(): void { + // Create a field with fixed cardinality, configure the form to use a + // "multiple" widget. + $field_storage = $this->fieldStorageMultiple; + $field_name = $field_storage['field_name']; + $this->field['field_name'] = $field_name; + FieldStorageConfig::create($field_storage)->save(); + FieldConfig::create($this->field)->save(); + $form = \Drupal::service('entity_display.repository')->getFormDisplay($this->field['entity_type'], $this->field['bundle'], 'default') + ->setComponent($field_name, [ + 'type' => 'test_field_widget_multiple', + ]); + $form->save(); + $session = $this->assertSession(); + + // Display creation form. + $this->drupalGet('entity_test/add'); + $this->assertSession()->fieldValueEquals($field_name, ''); + + // Create entity with three values. + $edit = [ + $field_name => '1, 2, 3', + ]; + $this->submitForm($edit, 'Save'); + preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match); + $id = $match[1]; + + // Check that the values were saved. + $entity_init = EntityTest::load($id); + $this->assertFieldValues($entity_init, $field_name, [1, 2, 3]); + + // Display the form, check that the values are correctly filled in. + $this->drupalGet('entity_test/manage/' . $id . '/edit'); + $this->assertSession()->fieldValueEquals($field_name, '1, 2, 3'); + + // Submit the form with more values than the field accepts. + $edit = [$field_name => '1, 2, 3, 4, 5']; + $this->submitForm($edit, 'Save'); + $this->assertSession()->pageTextContains('this field cannot hold more than 4 values'); + // Check that the field values were not submitted. + $this->assertFieldValues($entity_init, $field_name, [1, 2, 3]); + + // Check that Attributes are rendered on the multivalue container if it is + // a multiple widget form. + $form->setComponent($field_name, [ + 'type' => 'entity_reference_autocomplete', + ]) + ->save(); + $this->drupalGet('entity_test/manage/' . $id . '/edit'); + $name = str_replace('_', '-', $field_name); + $session->responseContains('data-drupal-selector="edit-' . $name . '"'); + } + + /** + * Tests the form display of the label for multi-value fields. + */ + public function testLabelOnMultiValueFields(): void { + $user = $this->drupalCreateUser(['administer entity_test content']); + $this->drupalLogin($user); + + // Ensure that the 'bar' bundle exists, to avoid config validation errors. + entity_test_create_bundle('bar', entity_type: 'entity_test_base_field_display'); + + FieldStorageConfig::create([ + 'entity_type' => 'entity_test_base_field_display', + 'field_name' => 'foo', + 'type' => 'text', + 'cardinality' => FieldStorageConfig::CARDINALITY_UNLIMITED, + ])->save(); + FieldConfig::create([ + 'entity_type' => 'entity_test_base_field_display', + 'bundle' => 'bar', + 'field_name' => 'foo', + // Set a dangerous label to test XSS filtering. + 'label' => "<script>alert('a configurable field');</script>", + ])->save(); + EntityFormDisplay::create([ + 'targetEntityType' => 'entity_test_base_field_display', + 'bundle' => 'bar', + 'mode' => 'default', + ])->setComponent('foo', ['type' => 'text_textfield'])->enable()->save(); + + $entity = EntityTestBaseFieldDisplay::create(['type' => 'bar']); + $entity->save(); + + $this->drupalGet('entity_test_base_field_display/manage/' . $entity->id()); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextContains('A field with multiple values'); + // Test if labels were XSS filtered. + $this->assertSession()->assertEscaped("<script>alert('a configurable field');</script>"); + } + + /** + * Tests hook_field_widget_complete_form_alter(). + */ + public function testFieldFormMultipleWidgetAlter(): void { + $this->widgetAlterTest('hook_field_widget_complete_form_alter', 'test_field_widget_multiple'); + } + + /** + * Tests hook_field_widget_complete_form_alter() with single value elements. + */ + public function testFieldFormMultipleWidgetAlterSingleValues(): void { + $this->widgetAlterTest('hook_field_widget_complete_form_alter', 'test_field_widget_multiple_single_value'); + } + + /** + * Tests hook_field_widget_complete_WIDGET_TYPE_form_alter(). + */ + public function testFieldFormMultipleWidgetTypeAlter(): void { + $this->widgetAlterTest('hook_field_widget_complete_WIDGET_TYPE_form_alter', 'test_field_widget_multiple'); + } + + /** + * Tests hook_field_widget_complete_WIDGET_TYPE_form_alter() with single value elements. + */ + public function testFieldFormMultipleWidgetTypeAlterSingleValues(): void { + $this->widgetAlterTest('hook_field_widget_complete_WIDGET_TYPE_form_alter', 'test_field_widget_multiple_single_value'); + } + + /** + * Tests widget alter hooks for a given hook name. + */ + protected function widgetAlterTest($hook, $widget) { + // Create a field with fixed cardinality, configure the form to use a + // "multiple" widget. + $field_storage = $this->fieldStorageMultiple; + $field_name = $field_storage['field_name']; + $this->field['field_name'] = $field_name; + FieldStorageConfig::create($field_storage)->save(); + FieldConfig::create($this->field)->save(); + + // Set a flag in state so that the hook implementations will run. + \Drupal::state()->set("field_test.widget_alter_test", [ + 'hook' => $hook, + 'field_name' => $field_name, + 'widget' => $widget, + ]); + \Drupal::service('entity_display.repository')->getFormDisplay($this->field['entity_type'], $this->field['bundle'], 'default') + ->setComponent($field_name, [ + 'type' => $widget, + ]) + ->save(); + + // We need to rebuild hook information after setting the component through + // the API. + $this->rebuildAll(); + + $this->drupalGet('entity_test/add'); + $this->assertSession()->pageTextMatchesCount(1, '/From ' . $hook . '.* prefix on ' . $field_name . ' parent element\./'); + if ($widget === 'test_field_widget_multiple_single_value') { + $suffix_text = "From $hook(): suffix on $field_name child element."; + $this->assertEquals($field_storage['cardinality'], substr_count($this->getTextContent(), $suffix_text), "'$suffix_text' was found {$field_storage['cardinality']} times using widget $widget"); + } + } + +} -- GitLab