UserAccountFormFieldsTest.php 4.56 KB
Newer Older
1 2
<?php

3
namespace Drupal\Tests\user\Kernel;
4

5
use Drupal\Core\Form\FormState;
6
use Drupal\KernelTests\KernelTestBase;
7 8

/**
9 10 11 12
 * Verifies that the field order in user account forms is compatible with
 * password managers of web browsers.
 *
 * @group user
13
 */
14
class UserAccountFormFieldsTest extends KernelTestBase {
15 16 17 18 19 20

  /**
   * Modules to enable.
   *
   * @var array
   */
21
  public static $modules = ['system', 'user', 'field'];
22 23 24 25

  /**
   * Tests the root user account form section in the "Configure site" form.
   */
26
  public function testInstallConfigureForm() {
27 28
    require_once $this->root . '/core/includes/install.core.inc';
    require_once $this->root . '/core/includes/install.inc';
29
    $install_state = install_state_defaults();
30
    $form_state = new FormState();
31
    $form_state->addBuildInfo('args', [&$install_state]);
32 33 34 35 36 37 38 39
    $form = $this->container->get('form_builder')
      ->buildForm('Drupal\Core\Installer\Form\SiteConfigureForm', $form_state);

    // Verify name and pass field order.
    $this->assertFieldOrder($form['admin_account']['account']);

    // Verify that web browsers may autocomplete the email value and
    // autofill/prefill the name and pass values.
40
    foreach (['mail', 'name', 'pass'] as $key) {
41 42 43 44 45 46 47
      $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found.");
    }
  }

  /**
   * Tests the user registration form.
   */
48
  public function testUserRegistrationForm() {
49
    // Install default configuration; required for AccountFormController.
50
    $this->installConfig(['user']);
51 52

    // Disable email confirmation to unlock the password field.
53
    $this->config('user.settings')
54 55 56 57 58 59 60 61 62 63
      ->set('verify_mail', FALSE)
      ->save();

    $form = $this->buildAccountForm('register');

    // Verify name and pass field order.
    $this->assertFieldOrder($form['account']);

    // Verify that web browsers may autocomplete the email value and
    // autofill/prefill the name and pass values.
64
    foreach (['mail', 'name', 'pass'] as $key) {
65 66 67 68 69 70 71
      $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found.");
    }
  }

  /**
   * Tests the user edit form.
   */
72
  public function testUserEditForm() {
73
    // Install default configuration; required for AccountFormController.
74
    $this->installConfig(['user']);
75

76 77 78
    // Install the router table and then rebuild.
    \Drupal::service('router.builder')->rebuild();

79 80 81 82 83 84
    $form = $this->buildAccountForm('default');

    // Verify name and pass field order.
    $this->assertFieldOrder($form['account']);

    // Verify that autocomplete is off on all account fields.
85
    foreach (['mail', 'name', 'pass'] as $key) {
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
      $this->assertIdentical($form['account'][$key]['#attributes']['autocomplete'], 'off', "'$key' field: 'autocomplete' attribute is 'off'.");
    }
  }

  /**
   * Asserts that the 'name' form element is directly before the 'pass' element.
   *
   * @param array $elements
   *   A form array section that contains the user account form elements.
   */
  protected function assertFieldOrder(array $elements) {
    $name_index = 0;
    $name_weight = 0;
    $pass_index = 0;
    $pass_weight = 0;
    $index = 0;
    foreach ($elements as $key => $element) {
      if ($key === 'name') {
        $name_index = $index;
        $name_weight = $element['#weight'];
        $this->assertTrue($element['#sorted'], "'name' field is #sorted.");
      }
      elseif ($key === 'pass') {
        $pass_index = $index;
        $pass_weight = $element['#weight'];
        $this->assertTrue($element['#sorted'], "'pass' field is #sorted.");
      }
      $index++;
    }
    $this->assertEqual($name_index, $pass_index - 1, "'name' field ($name_index) appears before 'pass' field ($pass_index).");
    $this->assertTrue($name_weight < $pass_weight, "'name' field weight ($name_weight) is smaller than 'pass' field weight ($pass_weight).");
  }

  /**
   * Builds the user account form for a given operation.
   *
   * @param string $operation
   *   The entity operation; one of 'register' or 'default'.
   *
   * @return array
   *   The form array.
   */
  protected function buildAccountForm($operation) {
    // @see HtmlEntityFormController::getFormObject()
    $entity_type = 'user';
131
    $fields = [];
132 133 134
    if ($operation != 'register') {
      $fields['uid'] = 2;
    }
135
    $entity = $this->container->get('entity_type.manager')
136 137 138 139 140 141 142 143
      ->getStorage($entity_type)
      ->create($fields);

    // @see EntityFormBuilder::getForm()
    return $this->container->get('entity.form_builder')->getForm($entity, $operation);
  }

}