comparison core/modules/options/tests/src/Functional/OptionsWidgetsTest.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 129ea1e6d783
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 namespace Drupal\Tests\options\Functional;
4
5 use Drupal\entity_test\Entity\EntityTest;
6 use Drupal\field\Entity\FieldConfig;
7 use Drupal\field\Tests\FieldTestBase;
8 use Drupal\field\Entity\FieldStorageConfig;
9
10 /**
11 * Tests the Options widgets.
12 *
13 * @group options
14 */
15 class OptionsWidgetsTest extends FieldTestBase {
16
17 /**
18 * Modules to enable.
19 *
20 * @var array
21 */
22 public static $modules = ['node', 'options', 'entity_test', 'options_test', 'taxonomy', 'field_ui'];
23
24 /**
25 * A field storage with cardinality 1 to use in this test class.
26 *
27 * @var \Drupal\field\Entity\FieldStorageConfig
28 */
29 protected $card1;
30
31 /**
32 * A field storage with cardinality 2 to use in this test class.
33 *
34 * @var \Drupal\field\Entity\FieldStorageConfig
35 */
36 protected $card2;
37
38
39 protected function setUp() {
40 parent::setUp();
41
42 // Field storage with cardinality 1.
43 $this->card1 = FieldStorageConfig::create([
44 'field_name' => 'card_1',
45 'entity_type' => 'entity_test',
46 'type' => 'list_integer',
47 'cardinality' => 1,
48 'settings' => [
49 'allowed_values' => [
50 // Make sure that 0 works as an option.
51 0 => 'Zero',
52 1 => 'One',
53 // Make sure that option text is properly sanitized.
54 2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>',
55 // Make sure that HTML entities in option text are not double-encoded.
56 3 => 'Some HTML encoded markup with &lt; &amp; &gt;',
57 ],
58 ],
59 ]);
60 $this->card1->save();
61
62 // Field storage with cardinality 2.
63 $this->card2 = FieldStorageConfig::create([
64 'field_name' => 'card_2',
65 'entity_type' => 'entity_test',
66 'type' => 'list_integer',
67 'cardinality' => 2,
68 'settings' => [
69 'allowed_values' => [
70 // Make sure that 0 works as an option.
71 0 => 'Zero',
72 1 => 'One',
73 // Make sure that option text is properly sanitized.
74 2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>',
75 ],
76 ],
77 ]);
78 $this->card2->save();
79
80 // Create a web user.
81 $this->drupalLogin($this->drupalCreateUser(['view test entity', 'administer entity_test content']));
82 }
83
84 /**
85 * Tests the 'options_buttons' widget (single select).
86 */
87 public function testRadioButtons() {
88 // Create an instance of the 'single value' field.
89 $field = FieldConfig::create([
90 'field_storage' => $this->card1,
91 'bundle' => 'entity_test',
92 ]);
93 $field->save();
94 entity_get_form_display('entity_test', 'entity_test', 'default')
95 ->setComponent($this->card1->getName(), [
96 'type' => 'options_buttons',
97 ])
98 ->save();
99
100 // Create an entity.
101 $entity = EntityTest::create([
102 'user_id' => 1,
103 'name' => $this->randomMachineName(),
104 ]);
105 $entity->save();
106 $entity_init = clone $entity;
107
108 // With no field data, no buttons are checked.
109 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
110 $this->assertNoFieldChecked('edit-card-1-0');
111 $this->assertNoFieldChecked('edit-card-1-1');
112 $this->assertNoFieldChecked('edit-card-1-2');
113 $this->assertRaw('Some dangerous &amp; unescaped <strong>markup</strong>', 'Option text was properly filtered.');
114 $this->assertRaw('Some HTML encoded markup with &lt; &amp; &gt;');
115
116 // Select first option.
117 $edit = ['card_1' => 0];
118 $this->drupalPostForm(NULL, $edit, t('Save'));
119 $this->assertFieldValues($entity_init, 'card_1', [0]);
120
121 // Check that the selected button is checked.
122 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
123 $this->assertFieldChecked('edit-card-1-0');
124 $this->assertNoFieldChecked('edit-card-1-1');
125 $this->assertNoFieldChecked('edit-card-1-2');
126
127 // Unselect option.
128 $edit = ['card_1' => '_none'];
129 $this->drupalPostForm(NULL, $edit, t('Save'));
130 $this->assertFieldValues($entity_init, 'card_1', []);
131
132 // Check that required radios with one option is auto-selected.
133 $this->card1->setSetting('allowed_values', [99 => 'Only allowed value']);
134 $this->card1->save();
135 $field->setRequired(TRUE);
136 $field->save();
137 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
138 $this->assertFieldChecked('edit-card-1-99');
139 }
140
141 /**
142 * Tests the 'options_buttons' widget (multiple select).
143 */
144 public function testCheckBoxes() {
145 // Create an instance of the 'multiple values' field.
146 $field = FieldConfig::create([
147 'field_storage' => $this->card2,
148 'bundle' => 'entity_test',
149 ]);
150 $field->save();
151 entity_get_form_display('entity_test', 'entity_test', 'default')
152 ->setComponent($this->card2->getName(), [
153 'type' => 'options_buttons',
154 ])
155 ->save();
156
157 // Create an entity.
158 $entity = EntityTest::create([
159 'user_id' => 1,
160 'name' => $this->randomMachineName(),
161 ]);
162 $entity->save();
163 $entity_init = clone $entity;
164
165 // Display form: with no field data, nothing is checked.
166 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
167 $this->assertNoFieldChecked('edit-card-2-0');
168 $this->assertNoFieldChecked('edit-card-2-1');
169 $this->assertNoFieldChecked('edit-card-2-2');
170 $this->assertRaw('Some dangerous &amp; unescaped <strong>markup</strong>', 'Option text was properly filtered.');
171
172 // Submit form: select first and third options.
173 $edit = [
174 'card_2[0]' => TRUE,
175 'card_2[1]' => FALSE,
176 'card_2[2]' => TRUE,
177 ];
178 $this->drupalPostForm(NULL, $edit, t('Save'));
179 $this->assertFieldValues($entity_init, 'card_2', [0, 2]);
180
181 // Display form: check that the right options are selected.
182 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
183 $this->assertFieldChecked('edit-card-2-0');
184 $this->assertNoFieldChecked('edit-card-2-1');
185 $this->assertFieldChecked('edit-card-2-2');
186
187 // Submit form: select only first option.
188 $edit = [
189 'card_2[0]' => TRUE,
190 'card_2[1]' => FALSE,
191 'card_2[2]' => FALSE,
192 ];
193 $this->drupalPostForm(NULL, $edit, t('Save'));
194 $this->assertFieldValues($entity_init, 'card_2', [0]);
195
196 // Display form: check that the right options are selected.
197 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
198 $this->assertFieldChecked('edit-card-2-0');
199 $this->assertNoFieldChecked('edit-card-2-1');
200 $this->assertNoFieldChecked('edit-card-2-2');
201
202 // Submit form: select the three options while the field accepts only 2.
203 $edit = [
204 'card_2[0]' => TRUE,
205 'card_2[1]' => TRUE,
206 'card_2[2]' => TRUE,
207 ];
208 $this->drupalPostForm(NULL, $edit, t('Save'));
209 $this->assertText('this field cannot hold more than 2 values', 'Validation error was displayed.');
210
211 // Submit form: uncheck all options.
212 $edit = [
213 'card_2[0]' => FALSE,
214 'card_2[1]' => FALSE,
215 'card_2[2]' => FALSE,
216 ];
217 $this->drupalPostForm(NULL, $edit, t('Save'));
218 // Check that the value was saved.
219 $this->assertFieldValues($entity_init, 'card_2', []);
220
221 // Required checkbox with one option is auto-selected.
222 $this->card2->setSetting('allowed_values', [99 => 'Only allowed value']);
223 $this->card2->save();
224 $field->setRequired(TRUE);
225 $field->save();
226 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
227 $this->assertFieldChecked('edit-card-2-99');
228 }
229
230 /**
231 * Tests the 'options_select' widget (single select).
232 */
233 public function testSelectListSingle() {
234 // Create an instance of the 'single value' field.
235 $field = FieldConfig::create([
236 'field_storage' => $this->card1,
237 'bundle' => 'entity_test',
238 'required' => TRUE,
239 ]);
240 $field->save();
241 entity_get_form_display('entity_test', 'entity_test', 'default')
242 ->setComponent($this->card1->getName(), [
243 'type' => 'options_select',
244 ])
245 ->save();
246
247 // Create an entity.
248 $entity = EntityTest::create([
249 'user_id' => 1,
250 'name' => $this->randomMachineName(),
251 ]);
252 $entity->save();
253 $entity_init = clone $entity;
254
255 // Display form.
256 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
257 // A required field without any value has a "none" option.
258 $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', [':id' => 'edit-card-1', ':label' => t('- Select a value -')]), 'A required select list has a "Select a value" choice.');
259
260 // With no field data, nothing is selected.
261 $this->assertNoOptionSelected('edit-card-1', '_none');
262 $this->assertNoOptionSelected('edit-card-1', 0);
263 $this->assertNoOptionSelected('edit-card-1', 1);
264 $this->assertNoOptionSelected('edit-card-1', 2);
265 $this->assertRaw('Some dangerous &amp; unescaped markup', 'Option text was properly filtered.');
266
267 // Submit form: select invalid 'none' option.
268 $edit = ['card_1' => '_none'];
269 $this->drupalPostForm(NULL, $edit, t('Save'));
270 $this->assertRaw(t('@title field is required.', ['@title' => $field->getName()]), 'Cannot save a required field when selecting "none" from the select list.');
271
272 // Submit form: select first option.
273 $edit = ['card_1' => 0];
274 $this->drupalPostForm(NULL, $edit, t('Save'));
275 $this->assertFieldValues($entity_init, 'card_1', [0]);
276
277 // Display form: check that the right options are selected.
278 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
279 // A required field with a value has no 'none' option.
280 $this->assertFalse($this->xpath('//select[@id=:id]//option[@value="_none"]', [':id' => 'edit-card-1']), 'A required select list with an actual value has no "none" choice.');
281 $this->assertOptionSelected('edit-card-1', 0);
282 $this->assertNoOptionSelected('edit-card-1', 1);
283 $this->assertNoOptionSelected('edit-card-1', 2);
284
285 // Make the field non required.
286 $field->setRequired(FALSE);
287 $field->save();
288
289 // Display form.
290 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
291 // A non-required field has a 'none' option.
292 $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', [':id' => 'edit-card-1', ':label' => t('- None -')]), 'A non-required select list has a "None" choice.');
293 // Submit form: Unselect the option.
294 $edit = ['card_1' => '_none'];
295 $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save'));
296 $this->assertFieldValues($entity_init, 'card_1', []);
297
298 // Test optgroups.
299
300 $this->card1->setSetting('allowed_values', []);
301 $this->card1->setSetting('allowed_values_function', 'options_test_allowed_values_callback');
302 $this->card1->save();
303
304 // Display form: with no field data, nothing is selected
305 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
306 $this->assertNoOptionSelected('edit-card-1', 0);
307 $this->assertNoOptionSelected('edit-card-1', 1);
308 $this->assertNoOptionSelected('edit-card-1', 2);
309 $this->assertRaw('Some dangerous &amp; unescaped markup', 'Option text was properly filtered.');
310 $this->assertRaw('More &lt;script&gt;dangerous&lt;/script&gt; markup', 'Option group text was properly filtered.');
311 $this->assertRaw('Group 1', 'Option groups are displayed.');
312
313 // Submit form: select first option.
314 $edit = ['card_1' => 0];
315 $this->drupalPostForm(NULL, $edit, t('Save'));
316 $this->assertFieldValues($entity_init, 'card_1', [0]);
317
318 // Display form: check that the right options are selected.
319 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
320 $this->assertOptionSelected('edit-card-1', 0);
321 $this->assertNoOptionSelected('edit-card-1', 1);
322 $this->assertNoOptionSelected('edit-card-1', 2);
323
324 // Submit form: Unselect the option.
325 $edit = ['card_1' => '_none'];
326 $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save'));
327 $this->assertFieldValues($entity_init, 'card_1', []);
328 }
329
330 /**
331 * Tests the 'options_select' widget (multiple select).
332 */
333 public function testSelectListMultiple() {
334 // Create an instance of the 'multiple values' field.
335 $field = FieldConfig::create([
336 'field_storage' => $this->card2,
337 'bundle' => 'entity_test',
338 ]);
339 $field->save();
340 entity_get_form_display('entity_test', 'entity_test', 'default')
341 ->setComponent($this->card2->getName(), [
342 'type' => 'options_select',
343 ])
344 ->save();
345
346 // Create an entity.
347 $entity = EntityTest::create([
348 'user_id' => 1,
349 'name' => $this->randomMachineName(),
350 ]);
351 $entity->save();
352 $entity_init = clone $entity;
353
354 // Display form: with no field data, nothing is selected.
355 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
356 $this->assertOptionSelected("edit-card-2", '_none');
357 $this->assertNoOptionSelected('edit-card-2', 0);
358 $this->assertNoOptionSelected('edit-card-2', 1);
359 $this->assertNoOptionSelected('edit-card-2', 2);
360 $this->assertRaw('Some dangerous &amp; unescaped markup', 'Option text was properly filtered.');
361
362 // Submit form: select first and third options.
363 $edit = ['card_2[]' => [0 => 0, 2 => 2]];
364 $this->drupalPostForm(NULL, $edit, t('Save'));
365 $this->assertFieldValues($entity_init, 'card_2', [0, 2]);
366
367 // Display form: check that the right options are selected.
368 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
369 $this->assertOptionSelected('edit-card-2', 0);
370 $this->assertNoOptionSelected('edit-card-2', 1);
371 $this->assertOptionSelected('edit-card-2', 2);
372
373 // Submit form: select only first option.
374 $edit = ['card_2[]' => [0 => 0]];
375 $this->drupalPostForm(NULL, $edit, t('Save'));
376 $this->assertFieldValues($entity_init, 'card_2', [0]);
377
378 // Display form: check that the right options are selected.
379 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
380 $this->assertOptionSelected('edit-card-2', 0);
381 $this->assertNoOptionSelected('edit-card-2', 1);
382 $this->assertNoOptionSelected('edit-card-2', 2);
383
384 // Submit form: select the three options while the field accepts only 2.
385 $edit = ['card_2[]' => [0 => 0, 1 => 1, 2 => 2]];
386 $this->drupalPostForm(NULL, $edit, t('Save'));
387 $this->assertText('this field cannot hold more than 2 values', 'Validation error was displayed.');
388
389 // Submit form: uncheck all options.
390 $edit = ['card_2[]' => []];
391 $this->drupalPostForm(NULL, $edit, t('Save'));
392 $this->assertFieldValues($entity_init, 'card_2', []);
393
394 // Test the 'None' option.
395
396 // Check that the 'none' option has no effect if actual options are selected
397 // as well.
398 $edit = ['card_2[]' => ['_none' => '_none', 0 => 0]];
399 $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save'));
400 $this->assertFieldValues($entity_init, 'card_2', [0]);
401
402 // Check that selecting the 'none' option empties the field.
403 $edit = ['card_2[]' => ['_none' => '_none']];
404 $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save'));
405 $this->assertFieldValues($entity_init, 'card_2', []);
406
407 // A required select list does not have an empty key.
408 $field->setRequired(TRUE);
409 $field->save();
410 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
411 $this->assertFalse($this->xpath('//select[@id=:id]//option[@value=""]', [':id' => 'edit-card-2']), 'A required select list does not have an empty key.');
412
413 // We do not have to test that a required select list with one option is
414 // auto-selected because the browser does it for us.
415
416 // Test optgroups.
417
418 // Use a callback function defining optgroups.
419 $this->card2->setSetting('allowed_values', []);
420 $this->card2->setSetting('allowed_values_function', 'options_test_allowed_values_callback');
421 $this->card2->save();
422 $field->setRequired(FALSE);
423 $field->save();
424
425 // Display form: with no field data, nothing is selected.
426 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
427 $this->assertNoOptionSelected('edit-card-2', 0);
428 $this->assertNoOptionSelected('edit-card-2', 1);
429 $this->assertNoOptionSelected('edit-card-2', 2);
430 $this->assertRaw('Some dangerous &amp; unescaped markup', 'Option text was properly filtered.');
431 $this->assertRaw('More &lt;script&gt;dangerous&lt;/script&gt; markup', 'Option group text was properly filtered.');
432 $this->assertRaw('Group 1', 'Option groups are displayed.');
433
434 // Submit form: select first option.
435 $edit = ['card_2[]' => [0 => 0]];
436 $this->drupalPostForm(NULL, $edit, t('Save'));
437 $this->assertFieldValues($entity_init, 'card_2', [0]);
438
439 // Display form: check that the right options are selected.
440 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
441 $this->assertOptionSelected('edit-card-2', 0);
442 $this->assertNoOptionSelected('edit-card-2', 1);
443 $this->assertNoOptionSelected('edit-card-2', 2);
444
445 // Submit form: Unselect the option.
446 $edit = ['card_2[]' => ['_none' => '_none']];
447 $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save'));
448 $this->assertFieldValues($entity_init, 'card_2', []);
449 }
450
451 /**
452 * Tests the 'options_select' and 'options_button' widget for empty value.
453 */
454 public function testEmptyValue() {
455 // Create an instance of the 'single value' field.
456 $field = FieldConfig::create([
457 'field_storage' => $this->card1,
458 'bundle' => 'entity_test',
459 ]);
460 $field->save();
461
462 // Change it to the check boxes/radio buttons widget.
463 entity_get_form_display('entity_test', 'entity_test', 'default')
464 ->setComponent($this->card1->getName(), [
465 'type' => 'options_buttons',
466 ])
467 ->save();
468
469 // Create an entity.
470 $entity = EntityTest::create([
471 'user_id' => 1,
472 'name' => $this->randomMachineName(),
473 ]);
474 $entity->save();
475
476 // Display form: check that _none options are present and has label.
477 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
478 $this->assertTrue($this->xpath('//div[@id=:id]//input[@value=:value]', [':id' => 'edit-card-1', ':value' => '_none']), 'A test radio button has a "None" choice.');
479 $this->assertTrue($this->xpath('//div[@id=:id]//label[@for=:for and text()=:label]', [':id' => 'edit-card-1', ':for' => 'edit-card-1-none', ':label' => 'N/A']), 'A test radio button has a "N/A" choice.');
480
481 // Change it to the select widget.
482 entity_get_form_display('entity_test', 'entity_test', 'default')
483 ->setComponent($this->card1->getName(), [
484 'type' => 'options_select',
485 ])
486 ->save();
487
488 // Display form: check that _none options are present and has label.
489 $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit');
490 // A required field without any value has a "none" option.
491 $this->assertTrue($this->xpath('//select[@id=:id]//option[@value="_none" and text()=:label]', [':id' => 'edit-card-1', ':label' => t('- None -')]), 'A test select has a "None" choice.');
492 }
493
494 }