3 namespace Drupal\Tests\user\Kernel;
5 use Drupal\Core\Form\FormState;
6 use Drupal\KernelTests\KernelTestBase;
9 * Verifies that the field order in user account forms is compatible with
10 * password managers of web browsers.
14 class UserAccountFormFieldsTest extends KernelTestBase {
21 public static $modules = ['system', 'user', 'field'];
24 * Tests the root user account form section in the "Configure site" form.
26 public function testInstallConfigureForm() {
27 require_once $this->root . '/core/includes/install.core.inc';
28 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 $form = $this->container->get('form_builder')
33 ->buildForm('Drupal\Core\Installer\Form\SiteConfigureForm', $form_state);
35 // Verify name and pass field order.
36 $this->assertFieldOrder($form['admin_account']['account']);
38 // Verify that web browsers may autocomplete the email value and
39 // autofill/prefill the name and pass values.
40 foreach (['mail', 'name', 'pass'] as $key) {
41 $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found.");
46 * Tests the user registration form.
48 public function testUserRegistrationForm() {
49 // Install default configuration; required for AccountFormController.
50 $this->installConfig(['user']);
52 // Disable email confirmation to unlock the password field.
53 $this->config('user.settings')
54 ->set('verify_mail', FALSE)
57 $form = $this->buildAccountForm('register');
59 // Verify name and pass field order.
60 $this->assertFieldOrder($form['account']);
62 // Verify that web browsers may autocomplete the email value and
63 // autofill/prefill the name and pass values.
64 foreach (['mail', 'name', 'pass'] as $key) {
65 $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'$key' field: 'autocomplete' attribute not found.");
70 * Tests the user edit form.
72 public function testUserEditForm() {
73 // Install default configuration; required for AccountFormController.
74 $this->installConfig(['user']);
76 // Install the router table and then rebuild.
77 \Drupal::service('router.builder')->rebuild();
79 $form = $this->buildAccountForm('default');
81 // Verify name and pass field order.
82 $this->assertFieldOrder($form['account']);
84 // Verify that autocomplete is off on all account fields.
85 foreach (['mail', 'name', 'pass'] as $key) {
86 $this->assertIdentical($form['account'][$key]['#attributes']['autocomplete'], 'off', "'$key' field: 'autocomplete' attribute is 'off'.");
91 * Asserts that the 'name' form element is directly before the 'pass' element.
93 * @param array $elements
94 * A form array section that contains the user account form elements.
96 protected function assertFieldOrder(array $elements) {
102 foreach ($elements as $key => $element) {
103 if ($key === 'name') {
104 $name_index = $index;
105 $name_weight = $element['#weight'];
106 $this->assertTrue($element['#sorted'], "'name' field is #sorted.");
108 elseif ($key === 'pass') {
109 $pass_index = $index;
110 $pass_weight = $element['#weight'];
111 $this->assertTrue($element['#sorted'], "'pass' field is #sorted.");
115 $this->assertEqual($name_index, $pass_index - 1, "'name' field ($name_index) appears before 'pass' field ($pass_index).");
116 $this->assertTrue($name_weight < $pass_weight, "'name' field weight ($name_weight) is smaller than 'pass' field weight ($pass_weight).");
120 * Builds the user account form for a given operation.
122 * @param string $operation
123 * The entity operation; one of 'register' or 'default'.
128 protected function buildAccountForm($operation) {
129 // @see HtmlEntityFormController::getFormObject()
130 $entity_type = 'user';
132 if ($operation != 'register') {
135 $entity = $this->container->get('entity.manager')
136 ->getStorage($entity_type)
138 $this->container->get('entity.manager')
139 ->getFormObject($entity_type, $operation)
140 ->setEntity($entity);
142 // @see EntityFormBuilder::getForm()
143 return $this->container->get('entity.form_builder')->getForm($entity, $operation);