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