Version 1
[yaffs-website] / web / core / modules / user / tests / src / Kernel / UserAccountFormFieldsTest.php
diff --git a/web/core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php b/web/core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php
new file mode 100644 (file)
index 0000000..6433021
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+
+namespace Drupal\Tests\user\Kernel;
+
+use Drupal\Core\Form\FormState;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Verifies that the field order in user account forms is compatible with
+ * password managers of web browsers.
+ *
+ * @group user
+ */
+class UserAccountFormFieldsTest extends KernelTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['system', 'user', 'field'];
+
+  /**
+   * Tests the root user account form section in the "Configure site" form.
+   */
+  public function testInstallConfigureForm() {
+    require_once \Drupal::root() . '/core/includes/install.core.inc';
+    require_once \Drupal::root() . '/core/includes/install.inc';
+    $install_state = install_state_defaults();
+    $form_state = new FormState();
+    $form_state->addBuildInfo('args', [&$install_state]);
+    $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.
+    foreach (['mail', 'name', 'pass'] as $key) {
+      $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found.");
+    }
+  }
+
+  /**
+   * Tests the user registration form.
+   */
+  public function testUserRegistrationForm() {
+    // Install default configuration; required for AccountFormController.
+    $this->installConfig(['user']);
+
+    // Disable email confirmation to unlock the password field.
+    $this->config('user.settings')
+      ->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.
+    foreach (['mail', 'name', 'pass'] as $key) {
+      $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found.");
+    }
+  }
+
+  /**
+   * Tests the user edit form.
+   */
+  public function testUserEditForm() {
+    // Install default configuration; required for AccountFormController.
+    $this->installConfig(['user']);
+
+    // Install the router table and then rebuild.
+    \Drupal::service('router.builder')->rebuild();
+
+    $form = $this->buildAccountForm('default');
+
+    // Verify name and pass field order.
+    $this->assertFieldOrder($form['account']);
+
+    // Verify that autocomplete is off on all account fields.
+    foreach (['mail', 'name', 'pass'] as $key) {
+      $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';
+    $fields = [];
+    if ($operation != 'register') {
+      $fields['uid'] = 2;
+    }
+    $entity = $this->container->get('entity.manager')
+      ->getStorage($entity_type)
+      ->create($fields);
+    $this->container->get('entity.manager')
+      ->getFormObject($entity_type, $operation)
+      ->setEntity($entity);
+
+    // @see EntityFormBuilder::getForm()
+    return $this->container->get('entity.form_builder')->getForm($entity, $operation);
+  }
+
+}