Chris@0: firstContentType = $this->drupalCreateContentType();
Chris@14: $this->secondContentType = $this->drupalCreateContentType();
Chris@0: $this->adminUser = $this->drupalCreateUser(['administer content types', 'administer node fields', 'administer node display']);
Chris@14: $this->helpTextUser = $this->drupalCreateUser(['create ' . $this->secondContentType->id() . ' content']);
Chris@0: $this->drupalPlaceBlock('system_breadcrumb_block');
Chris@0: }
Chris@0:
Chris@0: /**
Chris@0: * Tests the link field UI.
Chris@0: */
Chris@0: public function testFieldUI() {
Chris@14: foreach ($this->providerTestFieldUI() as $item) {
Chris@14: list($cardinality, $link_type, $title, $label, $field_name) = $item;
Chris@14: $this->runFieldUIItem($cardinality, $link_type, $title, $label, $field_name);
Chris@14: }
Chris@14: }
Chris@14:
Chris@14: /**
Chris@14: * Provides test data for ::testFieldUI().
Chris@14: */
Chris@14: protected function providerTestFieldUI() {
Chris@14: // There are many combinations of field settings: where the description
Chris@14: // should show: variation on internal, external, both; cardinality (where
Chris@14: // the fieldset is hidden or used); and link text shown (required or
Chris@14: // optional) or disabled. There are two descriptions: field and URL help
Chris@14: // text.
Chris@14: $cardinalities = [1, 2];
Chris@14: $title_settings = [
Chris@14: DRUPAL_DISABLED,
Chris@14: DRUPAL_OPTIONAL,
Chris@14: ];
Chris@14: $link_types = [
Chris@14: LinkItemInterface::LINK_EXTERNAL,
Chris@14: LinkItemInterface::LINK_GENERIC,
Chris@14: LinkItemInterface::LINK_INTERNAL,
Chris@14: ];
Chris@14:
Chris@14: // Test all variations of link types on all cardinalities.
Chris@14: foreach ($cardinalities as $cardinality) {
Chris@14: foreach ($link_types as $link_type) {
Chris@14: // Now, test this with both the title enabled and disabled.
Chris@14: foreach ($title_settings as $title_setting) {
Chris@14: // Test both empty and non-empty labels.
Chris@14: foreach ([TRUE, FALSE] as $label_provided) {
Chris@14: // Generate a unique machine name for the field so it can be
Chris@14: // identified in the test.
Chris@14: $id = implode('_', [
Chris@14: 'link',
Chris@14: $cardinality,
Chris@14: $link_type,
Chris@14: $title_setting,
Chris@14: (int) $label_provided,
Chris@14: ]);
Chris@14:
Chris@14: // Use a unique label that contains some HTML.
Chris@14: $label = '
' . $id;
Chris@14:
Chris@14: yield [
Chris@14: $cardinality,
Chris@14: $link_type,
Chris@14: $title_setting,
Chris@14: $label_provided ? $label : '',
Chris@14: $id,
Chris@14: ];
Chris@14: }
Chris@14: }
Chris@14: }
Chris@14: }
Chris@14: }
Chris@14:
Chris@14: /**
Chris@14: * Tests one link field UI item.
Chris@14: *
Chris@14: * @param int $cardinality
Chris@14: * The field cardinality.
Chris@14: * @param int $link_type
Chris@14: * Determine if the link is external, internal or both.
Chris@14: * @param int $title
Chris@14: * Determine if the field will display the link text field.
Chris@14: * @param string $label
Chris@14: * The field label.
Chris@14: * @param string $field_name
Chris@14: * The unique machine name for the field.
Chris@14: */
Chris@14: public function runFieldUIItem($cardinality, $link_type, $title, $label, $field_name) {
Chris@14: $this->drupalLogin($this->adminUser);
Chris@14: $type_path = 'admin/structure/types/manage/' . $this->firstContentType->id();
Chris@0:
Chris@0: // Add a link field to the newly-created type. It defaults to allowing both
Chris@0: // internal and external links.
Chris@14: $field_label = str_replace('_', ' ', $field_name);
Chris@14: $description = 'link field description';
Chris@14: $field_edit = [
Chris@14: 'description' => $description,
Chris@14: ];
Chris@14: $this->fieldUIAddNewField($type_path, $field_name, $field_label, 'link', [], $field_edit);
Chris@0:
Chris@0: // Load the formatter page to check that the settings summary does not
Chris@0: // generate warnings.
Chris@0: // @todo Mess with the formatter settings a bit here.
Chris@0: $this->drupalGet("$type_path/display");
Chris@0: $this->assertText(t('Link text trimmed to @limit characters', ['@limit' => 80]));
Chris@0:
Chris@14: $storage = FieldStorageConfig::create([
Chris@14: 'field_name' => $field_name,
Chris@14: 'entity_type' => 'node',
Chris@14: 'type' => 'link',
Chris@14: 'cardinality' => $cardinality,
Chris@14: ]);
Chris@14: $storage->save();
Chris@14:
Chris@14: FieldConfig::create([
Chris@14: 'field_storage' => $storage,
Chris@14: 'label' => $label,
Chris@14: 'bundle' => $this->secondContentType->id(),
Chris@14: 'settings' => [
Chris@14: 'title' => $title,
Chris@14: 'link_type' => $link_type,
Chris@14: ],
Chris@14: ])->save();
Chris@14:
Chris@14: // Make the fields visible in the form display.
Chris@14: $form_display_id = implode('.', ['node', $this->secondContentType->id(), 'default']);
Chris@14: $form_display = EntityFormDisplay::load($form_display_id);
Chris@14: $form_display->setComponent($field_name, ['region' => 'content']);
Chris@14: $form_display->save();
Chris@14:
Chris@14: // Log in a user that is allowed to create this content type, see if
Chris@14: // the user can see the expected help text.
Chris@14: $this->drupalLogin($this->helpTextUser);
Chris@14:
Chris@14: $add_path = 'node/add/' . $this->secondContentType->id();
Chris@0: $this->drupalGet($add_path);
Chris@0:
Chris@14: $expected_help_texts = [
Chris@14: LinkItemInterface::LINK_EXTERNAL => 'This must be an external URL such as http://example.com.',
Chris@14: 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.',
Chris@18: LinkItemInterface::LINK_INTERNAL => rtrim(Url::fromRoute('', [], ['absolute' => TRUE])->toString(), '/'),
Chris@14: ];
Chris@0:
Chris@14: // Check that the help texts we assume should be there, is there.
Chris@14: $this->assertFieldContainsRawText($field_name, $expected_help_texts[$link_type]);
Chris@14: if ($link_type === LinkItemInterface::LINK_INTERNAL) {
Chris@14: // Internal links have no "system" description. Test that none
Chris@14: // of the other help texts show here.
Chris@14: $this->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_EXTERNAL]);
Chris@14: $this->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_GENERIC]);
Chris@14: }
Chris@14: // Also assert that the description we made is here, no matter what the
Chris@14: // cardinality or link setting.
Chris@14: if (!empty($label)) {
Chris@14: $this->assertFieldContainsRawText($field_name, $label);
Chris@14: }
Chris@14: }
Chris@0:
Chris@14: /**
Chris@14: * Checks that given field contains the given raw text.
Chris@14: *
Chris@14: * @param string $field_name
Chris@14: * The name of the field to check.
Chris@14: * @param string $text
Chris@14: * The text to check.
Chris@14: */
Chris@14: protected function assertFieldContainsRawText($field_name, $text) {
Chris@14: $this->assertTrue((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this->getFieldHtml($field_name)));
Chris@14: }
Chris@0:
Chris@14: /**
Chris@14: * Checks that given field does not contain the given raw text.
Chris@14: *
Chris@14: * @param string $field_name
Chris@14: * The name of the field to check.
Chris@14: * @param string $text
Chris@14: * The text to check.
Chris@14: */
Chris@14: protected function assertNoFieldContainsRawText($field_name, $text) {
Chris@14: $this->assertFalse((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this->getFieldHtml($field_name)));
Chris@14: }
Chris@14:
Chris@14: /**
Chris@14: * Returns the raw HTML for the given field.
Chris@14: *
Chris@14: * @param $field_name
Chris@14: * The name of the field for which to return the HTML.
Chris@14: *
Chris@14: * @return string
Chris@14: * The raw HTML.
Chris@14: */
Chris@14: protected function getFieldHtml($field_name) {
Chris@14: $css_id = Html::cleanCssIdentifier('edit-' . $field_name . '-wrapper');
Chris@14: return $this->xpath('//*[@id=:id]', [':id' => $css_id])[0]->getHtml();
Chris@0: }
Chris@0:
Chris@0: }