annotate core/modules/link/tests/src/Functional/LinkFieldUITest.php @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents a9cd425dd02b
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\link\Functional;
Chris@0 4
Chris@5 5 use Drupal\Core\Url;
Chris@0 6 use Drupal\Component\Utility\Html;
Chris@0 7 use Drupal\Core\Entity\Entity\EntityFormDisplay;
Chris@0 8 use Drupal\field\Entity\FieldConfig;
Chris@0 9 use Drupal\field\Entity\FieldStorageConfig;
Chris@0 10 use Drupal\link\LinkItemInterface;
Chris@0 11 use Drupal\Tests\BrowserTestBase;
Chris@4 12 use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
Chris@0 13
Chris@0 14 /**
Chris@0 15 * Tests link field UI functionality.
Chris@0 16 *
Chris@0 17 * @group link
Chris@0 18 */
Chris@0 19 class LinkFieldUITest extends BrowserTestBase {
Chris@0 20
Chris@0 21 use FieldUiTestTrait;
Chris@0 22
Chris@0 23 /**
Chris@0 24 * Modules to enable.
Chris@0 25 *
Chris@0 26 * @var array
Chris@0 27 */
Chris@0 28 public static $modules = ['node', 'link', 'field_ui', 'block'];
Chris@0 29
Chris@0 30 /**
Chris@0 31 * A user that can edit content types.
Chris@0 32 *
Chris@0 33 * @var \Drupal\user\UserInterface
Chris@0 34 */
Chris@0 35 protected $adminUser;
Chris@0 36
Chris@0 37 /**
Chris@0 38 * A user that should see the help texts.
Chris@0 39 *
Chris@0 40 * @var \Drupal\user\Entity\User
Chris@0 41 */
Chris@0 42 protected $helpTextUser;
Chris@0 43
Chris@0 44 /**
Chris@0 45 * The first content type to add fields to.
Chris@0 46 *
Chris@0 47 * @var \Drupal\node\Entity\NodeType
Chris@0 48 */
Chris@0 49 protected $firstContentType;
Chris@0 50
Chris@0 51 /**
Chris@0 52 * The second content type to add fields to.
Chris@0 53 *
Chris@0 54 * @var \Drupal\node\Entity\NodeType
Chris@0 55 */
Chris@0 56 protected $secondContentType;
Chris@0 57
Chris@0 58 /**
Chris@0 59 * {@inheritdoc}
Chris@0 60 */
Chris@0 61 protected function setUp() {
Chris@0 62 parent::setUp();
Chris@0 63
Chris@0 64 $this->firstContentType = $this->drupalCreateContentType();
Chris@0 65 $this->secondContentType = $this->drupalCreateContentType();
Chris@0 66 $this->adminUser = $this->drupalCreateUser(['administer content types', 'administer node fields', 'administer node display']);
Chris@0 67 $this->helpTextUser = $this->drupalCreateUser(['create ' . $this->secondContentType->id() . ' content']);
Chris@0 68 $this->drupalPlaceBlock('system_breadcrumb_block');
Chris@0 69 }
Chris@0 70
Chris@0 71 /**
Chris@0 72 * Tests the link field UI.
Chris@0 73 */
Chris@0 74 public function testFieldUI() {
Chris@0 75 foreach ($this->providerTestFieldUI() as $item) {
Chris@0 76 list($cardinality, $link_type, $title, $label, $field_name) = $item;
Chris@0 77 $this->runFieldUIItem($cardinality, $link_type, $title, $label, $field_name);
Chris@0 78 }
Chris@0 79 }
Chris@0 80
Chris@0 81 /**
Chris@0 82 * Provides test data for ::testFieldUI().
Chris@0 83 */
Chris@0 84 protected function providerTestFieldUI() {
Chris@0 85 // There are many combinations of field settings: where the description
Chris@0 86 // should show: variation on internal, external, both; cardinality (where
Chris@0 87 // the fieldset is hidden or used); and link text shown (required or
Chris@0 88 // optional) or disabled. There are two descriptions: field and URL help
Chris@0 89 // text.
Chris@0 90 $cardinalities = [1, 2];
Chris@0 91 $title_settings = [
Chris@0 92 DRUPAL_DISABLED,
Chris@0 93 DRUPAL_OPTIONAL,
Chris@0 94 ];
Chris@0 95 $link_types = [
Chris@0 96 LinkItemInterface::LINK_EXTERNAL,
Chris@0 97 LinkItemInterface::LINK_GENERIC,
Chris@0 98 LinkItemInterface::LINK_INTERNAL,
Chris@0 99 ];
Chris@0 100
Chris@0 101 // Test all variations of link types on all cardinalities.
Chris@0 102 foreach ($cardinalities as $cardinality) {
Chris@0 103 foreach ($link_types as $link_type) {
Chris@0 104 // Now, test this with both the title enabled and disabled.
Chris@0 105 foreach ($title_settings as $title_setting) {
Chris@0 106 // Test both empty and non-empty labels.
Chris@0 107 foreach ([TRUE, FALSE] as $label_provided) {
Chris@0 108 // Generate a unique machine name for the field so it can be
Chris@0 109 // identified in the test.
Chris@0 110 $id = implode('_', [
Chris@0 111 'link',
Chris@0 112 $cardinality,
Chris@0 113 $link_type,
Chris@0 114 $title_setting,
Chris@0 115 (int) $label_provided,
Chris@0 116 ]);
Chris@0 117
Chris@0 118 // Use a unique label that contains some HTML.
Chris@0 119 $label = '<img src="http://example.com">' . $id;
Chris@0 120
Chris@0 121 yield [
Chris@0 122 $cardinality,
Chris@0 123 $link_type,
Chris@0 124 $title_setting,
Chris@0 125 $label_provided ? $label : '',
Chris@0 126 $id,
Chris@0 127 ];
Chris@0 128 }
Chris@0 129 }
Chris@0 130 }
Chris@0 131 }
Chris@0 132 }
Chris@0 133
Chris@0 134 /**
Chris@0 135 * Tests one link field UI item.
Chris@0 136 *
Chris@0 137 * @param int $cardinality
Chris@0 138 * The field cardinality.
Chris@0 139 * @param int $link_type
Chris@0 140 * Determine if the link is external, internal or both.
Chris@0 141 * @param int $title
Chris@0 142 * Determine if the field will display the link text field.
Chris@0 143 * @param string $label
Chris@0 144 * The field label.
Chris@0 145 * @param string $field_name
Chris@0 146 * The unique machine name for the field.
Chris@0 147 */
Chris@0 148 public function runFieldUIItem($cardinality, $link_type, $title, $label, $field_name) {
Chris@0 149 $this->drupalLogin($this->adminUser);
Chris@0 150 $type_path = 'admin/structure/types/manage/' . $this->firstContentType->id();
Chris@0 151
Chris@0 152 // Add a link field to the newly-created type. It defaults to allowing both
Chris@0 153 // internal and external links.
Chris@0 154 $field_label = str_replace('_', ' ', $field_name);
Chris@0 155 $description = 'link field description';
Chris@0 156 $field_edit = [
Chris@0 157 'description' => $description,
Chris@0 158 ];
Chris@0 159 $this->fieldUIAddNewField($type_path, $field_name, $field_label, 'link', [], $field_edit);
Chris@0 160
Chris@0 161 // Load the formatter page to check that the settings summary does not
Chris@0 162 // generate warnings.
Chris@0 163 // @todo Mess with the formatter settings a bit here.
Chris@0 164 $this->drupalGet("$type_path/display");
Chris@0 165 $this->assertText(t('Link text trimmed to @limit characters', ['@limit' => 80]));
Chris@0 166
Chris@0 167 $storage = FieldStorageConfig::create([
Chris@0 168 'field_name' => $field_name,
Chris@0 169 'entity_type' => 'node',
Chris@0 170 'type' => 'link',
Chris@0 171 'cardinality' => $cardinality,
Chris@0 172 ]);
Chris@0 173 $storage->save();
Chris@0 174
Chris@0 175 FieldConfig::create([
Chris@0 176 'field_storage' => $storage,
Chris@0 177 'label' => $label,
Chris@0 178 'bundle' => $this->secondContentType->id(),
Chris@0 179 'settings' => [
Chris@0 180 'title' => $title,
Chris@0 181 'link_type' => $link_type,
Chris@0 182 ],
Chris@0 183 ])->save();
Chris@0 184
Chris@0 185 // Make the fields visible in the form display.
Chris@0 186 $form_display_id = implode('.', ['node', $this->secondContentType->id(), 'default']);
Chris@0 187 $form_display = EntityFormDisplay::load($form_display_id);
Chris@0 188 $form_display->setComponent($field_name, ['region' => 'content']);
Chris@0 189 $form_display->save();
Chris@0 190
Chris@0 191 // Log in a user that is allowed to create this content type, see if
Chris@0 192 // the user can see the expected help text.
Chris@0 193 $this->drupalLogin($this->helpTextUser);
Chris@0 194
Chris@0 195 $add_path = 'node/add/' . $this->secondContentType->id();
Chris@0 196 $this->drupalGet($add_path);
Chris@0 197
Chris@0 198 $expected_help_texts = [
Chris@0 199 LinkItemInterface::LINK_EXTERNAL => 'This must be an external URL such as <em class="placeholder">http://example.com</em>.',
Chris@0 200 LinkItemInterface::LINK_GENERIC => 'You can also enter an internal path such as <em class="placeholder">/node/add</em> or an external URL such as <em class="placeholder">http://example.com</em>. Enter <em class="placeholder">&lt;front&gt;</em> to link to the front page.',
Chris@5 201 LinkItemInterface::LINK_INTERNAL => rtrim(Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString(), '/'),
Chris@0 202 ];
Chris@0 203
Chris@0 204 // Check that the help texts we assume should be there, is there.
Chris@0 205 $this->assertFieldContainsRawText($field_name, $expected_help_texts[$link_type]);
Chris@0 206 if ($link_type === LinkItemInterface::LINK_INTERNAL) {
Chris@0 207 // Internal links have no "system" description. Test that none
Chris@0 208 // of the other help texts show here.
Chris@0 209 $this->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_EXTERNAL]);
Chris@0 210 $this->assertNoFieldContainsRawText($field_name, $expected_help_texts[LinkItemInterface::LINK_GENERIC]);
Chris@0 211 }
Chris@0 212 // Also assert that the description we made is here, no matter what the
Chris@0 213 // cardinality or link setting.
Chris@0 214 if (!empty($label)) {
Chris@0 215 $this->assertFieldContainsRawText($field_name, $label);
Chris@0 216 }
Chris@0 217 }
Chris@0 218
Chris@0 219 /**
Chris@0 220 * Checks that given field contains the given raw text.
Chris@0 221 *
Chris@0 222 * @param string $field_name
Chris@0 223 * The name of the field to check.
Chris@0 224 * @param string $text
Chris@0 225 * The text to check.
Chris@0 226 */
Chris@0 227 protected function assertFieldContainsRawText($field_name, $text) {
Chris@0 228 $this->assertTrue((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this->getFieldHtml($field_name)));
Chris@0 229 }
Chris@0 230
Chris@0 231 /**
Chris@0 232 * Checks that given field does not contain the given raw text.
Chris@0 233 *
Chris@0 234 * @param string $field_name
Chris@0 235 * The name of the field to check.
Chris@0 236 * @param string $text
Chris@0 237 * The text to check.
Chris@0 238 */
Chris@0 239 protected function assertNoFieldContainsRawText($field_name, $text) {
Chris@0 240 $this->assertFalse((bool) preg_match('/' . preg_quote($text, '/') . '/ui', $this->getFieldHtml($field_name)));
Chris@0 241 }
Chris@0 242
Chris@0 243 /**
Chris@0 244 * Returns the raw HTML for the given field.
Chris@0 245 *
Chris@0 246 * @param $field_name
Chris@0 247 * The name of the field for which to return the HTML.
Chris@0 248 *
Chris@0 249 * @return string
Chris@0 250 * The raw HTML.
Chris@0 251 */
Chris@0 252 protected function getFieldHtml($field_name) {
Chris@0 253 $css_id = Html::cleanCssIdentifier('edit-' . $field_name . '-wrapper');
Chris@0 254 return $this->xpath('//*[@id=:id]', [':id' => $css_id])[0]->getHtml();
Chris@0 255 }
Chris@0 256
Chris@0 257 }