diff --git a/core/modules/link/tests/src/Functional/LinkFieldUITest.php b/core/modules/link/tests/src/Functional/LinkFieldUITest.php index 0f37f38578..5b35412244 100644 --- a/core/modules/link/tests/src/Functional/LinkFieldUITest.php +++ b/core/modules/link/tests/src/Functional/LinkFieldUITest.php @@ -2,7 +2,11 @@ namespace Drupal\Tests\link\Functional; +use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Unicode; +use Drupal\Core\Entity\Entity\EntityFormDisplay; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; use Drupal\field_ui\Tests\FieldUiTestTrait; use Drupal\link\LinkItemInterface; use Drupal\Tests\BrowserTestBase; @@ -48,7 +52,6 @@ function testFieldUI() { // Add a content type. $type = $this->drupalCreateContentType(); $type_path = 'admin/structure/types/manage/' . $type->id(); - $add_path = 'node/add/' . $type->id(); // Add a link field to the newly-created type. It defaults to allowing both // internal and external links. @@ -66,10 +69,14 @@ function testFieldUI() { $this->drupalGet("$type_path/display"); $this->assertText(t('Link text trimmed to @limit characters', ['@limit' => 80])); - // There are many combinations of UI settings, where the description should - // show: variation on internal, external, both; cardinality (where the - // fieldset is hidden or used); and link text shown (required or optional) - // or disabled. There are two descriptions: field and URL help text. + // Test the displaying of help texts for the link field. + $test_cases = []; + + // There are many combinations of field settings: where the description + // should show: variation on internal, external, both; cardinality (where + // the fieldset is hidden or used); and link text shown (required or + // optional) or disabled. There are two descriptions: field and URL help + // text. $cardinalities = [1, 2]; $title_settings = [ DRUPAL_DISABLED, @@ -80,74 +87,134 @@ function testFieldUI() { LinkItemInterface::LINK_GENERIC, LinkItemInterface::LINK_INTERNAL, ]; - $help_texts = [ - LinkItemInterface::LINK_EXTERNAL => 'This must be an external URL such as http://example.com.', - LinkItemInterface::LINK_GENERIC => 'You can also enter an internal path such as /node/add or an external URL such as http://example.com. Enter <front> to link to the front page.', - LinkItemInterface::LINK_INTERNAL => rtrim(\Drupal::url('', [], ['absolute' => TRUE]), '/'), - ]; - - // Log in an admin to set up a content type for this test. - $this->drupalLogin($this->adminUser); - - // Add a new content type. - $type = $this->drupalCreateContentType(); - $type_path = 'admin/structure/types/manage/' . $type->id(); - $add_path = 'node/add/' . $type->id(); - $field_count = 0; // Test all variations of link types on all cardinalities. foreach ($cardinalities as $cardinality) { foreach ($link_types as $link_type) { // Now, test this with both the title enabled and disabled. foreach ($title_settings as $title_setting) { - // Both test empty descriptions and not empty descriptions. - foreach ([TRUE, FALSE] as $description_enabled) { - $field_count++; - - // Create a field for this content type with the current cardinality - // and link field settings. - $label = "link_field_label_$field_count"; - $description = 'link field description with html ' . $field_count; - $field_name = Unicode::strtolower($label); - $storage_edit = ['cardinality_number' => $cardinality]; - $field_edit = [ - 'settings[link_type]' => $link_type, - 'description' => $description_enabled ? $description : '', - 'settings[title]' => $title_setting, + // Test both empty and non-empty labels. + foreach ([TRUE, FALSE] as $label_provided) { + // Generate a unique ID for the field so it can be identified in the + // test. + $id = implode('_', [ + 'link', + $cardinality, + $link_type, + $title_setting, + (int) $label_provided, + ]); + + // Use a unique label that contains some HTML. + $label = '' . $id; + + $test_cases[$id] = [ + 'cardinality' => $cardinality, + 'link_type' => $link_type, + 'title' => $title_setting, + 'label' => $label_provided ? $label : '', ]; - $this->fieldUIAddNewField($type_path, $field_name, $label, 'link', $storage_edit, $field_edit); } } } } + // Create a new content type and add the test fields to it. + $type = $this->drupalCreateContentType(); + foreach ($test_cases as $field_name => $test_case) { + $storage = FieldStorageConfig::create([ + 'field_name' => $field_name, + 'entity_type' => 'node', + 'type' => 'link', + 'cardinality' => $test_case['cardinality'], + ]); + $storage->save(); + + FieldConfig::create([ + 'field_storage' => $storage, + 'label' => $test_case['label'], + 'bundle' => $type->id(), + 'settings' => [ + 'title' => $test_case['title'], + 'link_type' => $test_case['link_type'], + ], + ])->save(); + } + + // Make the fields visible in the form display. + $form_display_id = implode('.', ['node', $type->id(), 'default']); + $form_display = EntityFormDisplay::load($form_display_id); + foreach ($test_cases as $field_name => $test_case) { + $form_display->setComponent($field_name, ['region' => 'content']); + } + $form_display->save(); + // Log in a user that is allowed to create this content type, see if // the user can see the expected help text. $this->drupalLogin($this->drupalCreateUser(['create ' . $type->id() . ' content'])); + $add_path = 'node/add/' . $type->id(); $this->drupalGet($add_path); - $field_count = 0; - // Test all variations of link types on all cardinalities. - foreach ($cardinalities as $cardinality) { - foreach ($link_types as $link_type) { - // Now, test this with both the title enabled and disabled. - foreach ($title_settings as $title_setting) { - // Both test empty descriptions and not empty descriptions. - foreach ([TRUE, FALSE] as $description_enabled) { - $field_count++; - $description = 'link field description with html ' . $field_count; - // Check that the help texts we assume should be there, is there. - $this->assertRaw($help_texts[$link_type]); - // Also assert that the description we made is here, no matter what - // the cardinality or link setting. - if ($description_enabled) { - $this->assertRaw($description); - } - } - } + $expected_help_texts = [ + LinkItemInterface::LINK_EXTERNAL => 'This must be an external URL such as http://example.com.', + LinkItemInterface::LINK_GENERIC => 'You can also enter an internal path such as /node/add or an external URL such as http://example.com. Enter <front> to link to the front page.', + LinkItemInterface::LINK_INTERNAL => rtrim(\Drupal::url('', [], ['absolute' => TRUE]), '/'), + ]; + + foreach($test_cases as $field_name => $test_case) { + // Check that the help texts we assume should be there, is there. + $this->assertFieldContainsRawText($field_name, $expected_help_texts[$test_case['link_type']]); + if ($test_case['link_type'] === LinkItemInterface::LINK_INTERNAL) { + // Internal links have no "system" description. Test that none + // of the other help texts show here. + $this->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_EXTERNAL]); + $this->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_GENERIC]); + } + // Also assert that the description we made is here, no matter what the + // cardinality or link setting. + if (!empty($test_case['label'])) { + $this->assertFieldContainsRawText($field_name, $test_case['label']); } } } + /** + * Checks that given field contains the given raw text. + * + * @param string $field_name + * The name of the field to check. + * @param string $text + * The text to check. + */ + protected function assertFieldContainsRawText($field_name, $text) { + $this->assertTrue((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this->getFieldHtml($field_name))); + } + + /** + * Checks that given field does not contain the given raw text. + * + * @param string $field_name + * The name of the field to check. + * @param string $text + * The text to check. + */ + protected function assertNoFieldContainsRawText($field_name, $text) { + $this->assertFalse((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this->getFieldHtml($field_name))); + } + + /** + * Returns the raw HTML for the given field. + * + * @param $field_name + * The name of the field for which to return the HTML. + * + * @return string + * The raw HTML. + */ + protected function getFieldHtml($field_name) { + $css_id = Html::cleanCssIdentifier("edit-$field_name-wrapper"); + return $this->xpath("//div[@id='$css_id']")[0]->getHtml(); + } + }