You are here

public function FormTest::testDisabledElements in Drupal 8

Same name and namespace in other branches
  1. 9 core/modules/system/tests/src/Functional/Form/FormTest.php \Drupal\Tests\system\Functional\Form\FormTest::testDisabledElements()

Test handling of disabled elements.

See also

_form_test_disabled_elements()

File

core/modules/system/tests/src/Functional/Form/FormTest.php, line 721

Class

FormTest
Tests various form element validation mechanisms.

Namespace

Drupal\Tests\system\Functional\Form

Code

public function testDisabledElements() {

  // Get the raw form in its original state.
  $form_state = new FormState();
  $form = (new FormTestDisabledElementsForm())
    ->buildForm([], $form_state);

  // Build a submission that tries to hijack the form by submitting input for
  // elements that are disabled.
  $edit = [];
  foreach (Element::children($form) as $key) {
    if (isset($form[$key]['#test_hijack_value'])) {
      if (is_array($form[$key]['#test_hijack_value'])) {
        foreach ($form[$key]['#test_hijack_value'] as $subkey => $value) {
          $edit[$key . '[' . $subkey . ']'] = $value;
        }
      }
      else {
        $edit[$key] = $form[$key]['#test_hijack_value'];
      }
    }
  }

  // Submit the form with no input, as the browser does for disabled elements,
  // and fetch the $form_state->getValues() that is passed to the submit handler.
  $this
    ->drupalPostForm('form-test/disabled-elements', [], t('Submit'));
  $returned_values['normal'] = Json::decode($this
    ->getSession()
    ->getPage()
    ->getContent());

  // Do the same with input, as could happen if JavaScript un-disables an
  // element. drupalPostForm() emulates a browser by not submitting input for
  // disabled elements, so we need to un-disable those elements first.
  $this
    ->drupalGet('form-test/disabled-elements');
  $disabled_elements = [];
  foreach ($this
    ->xpath('//*[@disabled]') as $element) {
    $disabled_elements[] = (string) $element
      ->getAttribute('name');
  }

  // All the elements should be marked as disabled, including the ones below
  // the disabled container.
  $actual_count = count($disabled_elements);
  $expected_count = 42;
  $this
    ->assertEqual($actual_count, $expected_count, new FormattableMarkup('Found @actual elements with disabled property (expected @expected).', [
    '@actual' => count($disabled_elements),
    '@expected' => $expected_count,
  ]));

  // Mink does not "see" hidden elements, so we need to set the value of the
  // hidden element directly.
  $this
    ->assertSession()
    ->elementExists('css', 'input[name="hidden"]')
    ->setValue($edit['hidden']);
  unset($edit['hidden']);
  $this
    ->drupalPostForm(NULL, $edit, t('Submit'));
  $returned_values['hijacked'] = Json::decode($this
    ->getSession()
    ->getPage()
    ->getContent());

  // Ensure that the returned values match the form's default values in both
  // cases.
  foreach ($returned_values as $values) {
    $this
      ->assertFormValuesDefault($values, $form);
  }
}