UserAccountFormFieldsTest.php

Same filename in other branches
  1. 9 core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php
  2. 10 core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php
  3. 11.x core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php

Namespace

Drupal\Tests\user\Kernel

File

core/modules/user/tests/src/Kernel/UserAccountFormFieldsTest.php

View source
<?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 $this->root . '/core/includes/install.core.inc';
        require_once $this->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_type.manager')
            ->getStorage($entity_type)
            ->create($fields);
        // @see EntityFormBuilder::getForm()
        return $this->container
            ->get('entity.form_builder')
            ->getForm($entity, $operation);
    }

}

Classes

Title Deprecated Summary
UserAccountFormFieldsTest Verifies that the field order in user account forms is compatible with password managers of web browsers.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.