Mercurial > hg > isophonics-drupal-site
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/modules/options/tests/src/Functional/OptionsWidgetsTest.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,494 @@ +<?php + +namespace Drupal\Tests\options\Functional; + +use Drupal\entity_test\Entity\EntityTest; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Tests\FieldTestBase; +use Drupal\field\Entity\FieldStorageConfig; + +/** + * Tests the Options widgets. + * + * @group options + */ +class OptionsWidgetsTest extends FieldTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = ['node', 'options', 'entity_test', 'options_test', 'taxonomy', 'field_ui']; + + /** + * A field storage with cardinality 1 to use in this test class. + * + * @var \Drupal\field\Entity\FieldStorageConfig + */ + protected $card1; + + /** + * A field storage with cardinality 2 to use in this test class. + * + * @var \Drupal\field\Entity\FieldStorageConfig + */ + protected $card2; + + + protected function setUp() { + parent::setUp(); + + // Field storage with cardinality 1. + $this->card1 = FieldStorageConfig::create([ + 'field_name' => 'card_1', + 'entity_type' => 'entity_test', + 'type' => 'list_integer', + 'cardinality' => 1, + 'settings' => [ + 'allowed_values' => [ + // Make sure that 0 works as an option. + 0 => 'Zero', + 1 => 'One', + // Make sure that option text is properly sanitized. + 2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>', + // Make sure that HTML entities in option text are not double-encoded. + 3 => 'Some HTML encoded markup with < & >', + ], + ], + ]); + $this->card1->save(); + + // Field storage with cardinality 2. + $this->card2 = FieldStorageConfig::create([ + 'field_name' => 'card_2', + 'entity_type' => 'entity_test', + 'type' => 'list_integer', + 'cardinality' => 2, + 'settings' => [ + 'allowed_values' => [ + // Make sure that 0 works as an option. + 0 => 'Zero', + 1 => 'One', + // Make sure that option text is properly sanitized. + 2 => 'Some <script>dangerous</script> & unescaped <strong>markup</strong>', + ], + ], + ]); + $this->card2->save(); + + // Create a web user. + $this->drupalLogin($this->drupalCreateUser(['view test entity', 'administer entity_test content'])); + } + + /** + * Tests the 'options_buttons' widget (single select). + */ + public function testRadioButtons() { + // Create an instance of the 'single value' field. + $field = FieldConfig::create([ + 'field_storage' => $this->card1, + 'bundle' => 'entity_test', + ]); + $field->save(); + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($this->card1->getName(), [ + 'type' => 'options_buttons', + ]) + ->save(); + + // Create an entity. + $entity = EntityTest::create([ + 'user_id' => 1, + 'name' => $this->randomMachineName(), + ]); + $entity->save(); + $entity_init = clone $entity; + + // With no field data, no buttons are checked. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertNoFieldChecked('edit-card-1-0'); + $this->assertNoFieldChecked('edit-card-1-1'); + $this->assertNoFieldChecked('edit-card-1-2'); + $this->assertRaw('Some dangerous & unescaped <strong>markup</strong>', 'Option text was properly filtered.'); + $this->assertRaw('Some HTML encoded markup with < & >'); + + // Select first option. + $edit = ['card_1' => 0]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_1', [0]); + + // Check that the selected button is checked. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertFieldChecked('edit-card-1-0'); + $this->assertNoFieldChecked('edit-card-1-1'); + $this->assertNoFieldChecked('edit-card-1-2'); + + // Unselect option. + $edit = ['card_1' => '_none']; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_1', []); + + // Check that required radios with one option is auto-selected. + $this->card1->setSetting('allowed_values', [99 => 'Only allowed value']); + $this->card1->save(); + $field->setRequired(TRUE); + $field->save(); + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertFieldChecked('edit-card-1-99'); + } + + /** + * Tests the 'options_buttons' widget (multiple select). + */ + public function testCheckBoxes() { + // Create an instance of the 'multiple values' field. + $field = FieldConfig::create([ + 'field_storage' => $this->card2, + 'bundle' => 'entity_test', + ]); + $field->save(); + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($this->card2->getName(), [ + 'type' => 'options_buttons', + ]) + ->save(); + + // Create an entity. + $entity = EntityTest::create([ + 'user_id' => 1, + 'name' => $this->randomMachineName(), + ]); + $entity->save(); + $entity_init = clone $entity; + + // Display form: with no field data, nothing is checked. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertNoFieldChecked('edit-card-2-0'); + $this->assertNoFieldChecked('edit-card-2-1'); + $this->assertNoFieldChecked('edit-card-2-2'); + $this->assertRaw('Some dangerous & unescaped <strong>markup</strong>', 'Option text was properly filtered.'); + + // Submit form: select first and third options. + $edit = [ + 'card_2[0]' => TRUE, + 'card_2[1]' => FALSE, + 'card_2[2]' => TRUE, + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_2', [0, 2]); + + // Display form: check that the right options are selected. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertFieldChecked('edit-card-2-0'); + $this->assertNoFieldChecked('edit-card-2-1'); + $this->assertFieldChecked('edit-card-2-2'); + + // Submit form: select only first option. + $edit = [ + 'card_2[0]' => TRUE, + 'card_2[1]' => FALSE, + 'card_2[2]' => FALSE, + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_2', [0]); + + // Display form: check that the right options are selected. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertFieldChecked('edit-card-2-0'); + $this->assertNoFieldChecked('edit-card-2-1'); + $this->assertNoFieldChecked('edit-card-2-2'); + + // Submit form: select the three options while the field accepts only 2. + $edit = [ + 'card_2[0]' => TRUE, + 'card_2[1]' => TRUE, + 'card_2[2]' => TRUE, + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('this field cannot hold more than 2 values', 'Validation error was displayed.'); + + // Submit form: uncheck all options. + $edit = [ + 'card_2[0]' => FALSE, + 'card_2[1]' => FALSE, + 'card_2[2]' => FALSE, + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + // Check that the value was saved. + $this->assertFieldValues($entity_init, 'card_2', []); + + // Required checkbox with one option is auto-selected. + $this->card2->setSetting('allowed_values', [99 => 'Only allowed value']); + $this->card2->save(); + $field->setRequired(TRUE); + $field->save(); + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertFieldChecked('edit-card-2-99'); + } + + /** + * Tests the 'options_select' widget (single select). + */ + public function testSelectListSingle() { + // Create an instance of the 'single value' field. + $field = FieldConfig::create([ + 'field_storage' => $this->card1, + 'bundle' => 'entity_test', + 'required' => TRUE, + ]); + $field->save(); + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($this->card1->getName(), [ + 'type' => 'options_select', + ]) + ->save(); + + // Create an entity. + $entity = EntityTest::create([ + 'user_id' => 1, + 'name' => $this->randomMachineName(), + ]); + $entity->save(); + $entity_init = clone $entity; + + // Display form. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + // A required field without any value has a "none" option. + $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.'); + + // With no field data, nothing is selected. + $this->assertNoOptionSelected('edit-card-1', '_none'); + $this->assertNoOptionSelected('edit-card-1', 0); + $this->assertNoOptionSelected('edit-card-1', 1); + $this->assertNoOptionSelected('edit-card-1', 2); + $this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.'); + + // Submit form: select invalid 'none' option. + $edit = ['card_1' => '_none']; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertRaw(t('@title field is required.', ['@title' => $field->getName()]), 'Cannot save a required field when selecting "none" from the select list.'); + + // Submit form: select first option. + $edit = ['card_1' => 0]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_1', [0]); + + // Display form: check that the right options are selected. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + // A required field with a value has no 'none' option. + $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.'); + $this->assertOptionSelected('edit-card-1', 0); + $this->assertNoOptionSelected('edit-card-1', 1); + $this->assertNoOptionSelected('edit-card-1', 2); + + // Make the field non required. + $field->setRequired(FALSE); + $field->save(); + + // Display form. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + // A non-required field has a 'none' option. + $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.'); + // Submit form: Unselect the option. + $edit = ['card_1' => '_none']; + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_1', []); + + // Test optgroups. + + $this->card1->setSetting('allowed_values', []); + $this->card1->setSetting('allowed_values_function', 'options_test_allowed_values_callback'); + $this->card1->save(); + + // Display form: with no field data, nothing is selected + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertNoOptionSelected('edit-card-1', 0); + $this->assertNoOptionSelected('edit-card-1', 1); + $this->assertNoOptionSelected('edit-card-1', 2); + $this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.'); + $this->assertRaw('More <script>dangerous</script> markup', 'Option group text was properly filtered.'); + $this->assertRaw('Group 1', 'Option groups are displayed.'); + + // Submit form: select first option. + $edit = ['card_1' => 0]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_1', [0]); + + // Display form: check that the right options are selected. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertOptionSelected('edit-card-1', 0); + $this->assertNoOptionSelected('edit-card-1', 1); + $this->assertNoOptionSelected('edit-card-1', 2); + + // Submit form: Unselect the option. + $edit = ['card_1' => '_none']; + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_1', []); + } + + /** + * Tests the 'options_select' widget (multiple select). + */ + public function testSelectListMultiple() { + // Create an instance of the 'multiple values' field. + $field = FieldConfig::create([ + 'field_storage' => $this->card2, + 'bundle' => 'entity_test', + ]); + $field->save(); + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($this->card2->getName(), [ + 'type' => 'options_select', + ]) + ->save(); + + // Create an entity. + $entity = EntityTest::create([ + 'user_id' => 1, + 'name' => $this->randomMachineName(), + ]); + $entity->save(); + $entity_init = clone $entity; + + // Display form: with no field data, nothing is selected. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertOptionSelected("edit-card-2", '_none'); + $this->assertNoOptionSelected('edit-card-2', 0); + $this->assertNoOptionSelected('edit-card-2', 1); + $this->assertNoOptionSelected('edit-card-2', 2); + $this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.'); + + // Submit form: select first and third options. + $edit = ['card_2[]' => [0 => 0, 2 => 2]]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_2', [0, 2]); + + // Display form: check that the right options are selected. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertOptionSelected('edit-card-2', 0); + $this->assertNoOptionSelected('edit-card-2', 1); + $this->assertOptionSelected('edit-card-2', 2); + + // Submit form: select only first option. + $edit = ['card_2[]' => [0 => 0]]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_2', [0]); + + // Display form: check that the right options are selected. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertOptionSelected('edit-card-2', 0); + $this->assertNoOptionSelected('edit-card-2', 1); + $this->assertNoOptionSelected('edit-card-2', 2); + + // Submit form: select the three options while the field accepts only 2. + $edit = ['card_2[]' => [0 => 0, 1 => 1, 2 => 2]]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('this field cannot hold more than 2 values', 'Validation error was displayed.'); + + // Submit form: uncheck all options. + $edit = ['card_2[]' => []]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_2', []); + + // Test the 'None' option. + + // Check that the 'none' option has no effect if actual options are selected + // as well. + $edit = ['card_2[]' => ['_none' => '_none', 0 => 0]]; + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_2', [0]); + + // Check that selecting the 'none' option empties the field. + $edit = ['card_2[]' => ['_none' => '_none']]; + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_2', []); + + // A required select list does not have an empty key. + $field->setRequired(TRUE); + $field->save(); + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertFalse($this->xpath('//select[@id=:id]//option[@value=""]', [':id' => 'edit-card-2']), 'A required select list does not have an empty key.'); + + // We do not have to test that a required select list with one option is + // auto-selected because the browser does it for us. + + // Test optgroups. + + // Use a callback function defining optgroups. + $this->card2->setSetting('allowed_values', []); + $this->card2->setSetting('allowed_values_function', 'options_test_allowed_values_callback'); + $this->card2->save(); + $field->setRequired(FALSE); + $field->save(); + + // Display form: with no field data, nothing is selected. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertNoOptionSelected('edit-card-2', 0); + $this->assertNoOptionSelected('edit-card-2', 1); + $this->assertNoOptionSelected('edit-card-2', 2); + $this->assertRaw('Some dangerous & unescaped markup', 'Option text was properly filtered.'); + $this->assertRaw('More <script>dangerous</script> markup', 'Option group text was properly filtered.'); + $this->assertRaw('Group 1', 'Option groups are displayed.'); + + // Submit form: select first option. + $edit = ['card_2[]' => [0 => 0]]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_2', [0]); + + // Display form: check that the right options are selected. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertOptionSelected('edit-card-2', 0); + $this->assertNoOptionSelected('edit-card-2', 1); + $this->assertNoOptionSelected('edit-card-2', 2); + + // Submit form: Unselect the option. + $edit = ['card_2[]' => ['_none' => '_none']]; + $this->drupalPostForm('entity_test/manage/' . $entity->id() . '/edit', $edit, t('Save')); + $this->assertFieldValues($entity_init, 'card_2', []); + } + + /** + * Tests the 'options_select' and 'options_button' widget for empty value. + */ + public function testEmptyValue() { + // Create an instance of the 'single value' field. + $field = FieldConfig::create([ + 'field_storage' => $this->card1, + 'bundle' => 'entity_test', + ]); + $field->save(); + + // Change it to the check boxes/radio buttons widget. + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($this->card1->getName(), [ + 'type' => 'options_buttons', + ]) + ->save(); + + // Create an entity. + $entity = EntityTest::create([ + 'user_id' => 1, + 'name' => $this->randomMachineName(), + ]); + $entity->save(); + + // Display form: check that _none options are present and has label. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + $this->assertTrue($this->xpath('//div[@id=:id]//input[@value=:value]', [':id' => 'edit-card-1', ':value' => '_none']), 'A test radio button has a "None" choice.'); + $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.'); + + // Change it to the select widget. + entity_get_form_display('entity_test', 'entity_test', 'default') + ->setComponent($this->card1->getName(), [ + 'type' => 'options_select', + ]) + ->save(); + + // Display form: check that _none options are present and has label. + $this->drupalGet('entity_test/manage/' . $entity->id() . '/edit'); + // A required field without any value has a "none" option. + $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.'); + } + +}