class UserAdminLanguageTest

Same name and namespace in other branches
  1. 11.x core/modules/user/tests/src/Functional/UserAdminLanguageTest.php \Drupal\Tests\user\Functional\UserAdminLanguageTest
  2. 10 core/modules/user/tests/src/Functional/UserAdminLanguageTest.php \Drupal\Tests\user\Functional\UserAdminLanguageTest
  3. 8.9.x core/modules/user/tests/src/Functional/UserAdminLanguageTest.php \Drupal\Tests\user\Functional\UserAdminLanguageTest

Tests users' ability to change their own administration language.

@group user

Hierarchy

Expanded class hierarchy of UserAdminLanguageTest

File

core/modules/user/tests/src/Functional/UserAdminLanguageTest.php, line 13

Namespace

Drupal\Tests\user\Functional
View source
class UserAdminLanguageTest extends BrowserTestBase {
  
  /**
   * A user with permission to access admin pages and administer languages.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $adminUser;
  
  /**
   * A non-administrator user for this test.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $regularUser;
  
  /**
   * Modules to enable.
   *
   * @var array
   */
  protected static $modules = [
    'user',
    'language',
    'language_test',
  ];
  
  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';
  
  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    // User to add and remove language.
    $this->adminUser = $this->drupalCreateUser([
      'administer languages',
      'access administration pages',
    ]);
    // User to check non-admin access.
    $this->regularUser = $this->drupalCreateUser();
  }
  
  /**
   * Tests that admin language is not configurable in single language sites.
   */
  public function testUserAdminLanguageConfigurationNotAvailableWithOnlyOneLanguage() {
    $this->drupalLogin($this->adminUser);
    $this->setLanguageNegotiation();
    $path = 'user/' . $this->adminUser
      ->id() . '/edit';
    $this->drupalGet($path);
    // Ensure administration pages language settings widget is not available.
    $this->assertSession()
      ->fieldNotExists('edit-preferred-admin-langcode');
  }
  
  /**
   * Tests that admin language negotiation is configurable only if enabled.
   */
  public function testUserAdminLanguageConfigurationAvailableWithAdminLanguageNegotiation() {
    $this->drupalLogin($this->adminUser);
    $this->addCustomLanguage();
    $path = 'user/' . $this->adminUser
      ->id() . '/edit';
    // Checks with user administration pages language negotiation disabled.
    $this->drupalGet($path);
    // Ensure administration pages language settings widget is not available.
    $this->assertSession()
      ->fieldNotExists('edit-preferred-admin-langcode');
    // Checks with user administration pages language negotiation enabled.
    $this->setLanguageNegotiation();
    $this->drupalGet($path);
    // Ensure administration pages language settings widget is available.
    $this->assertSession()
      ->fieldExists('edit-preferred-admin-langcode');
  }
  
  /**
   * Tests that the admin language is configurable only for administrators.
   *
   * If a user has the permission "access administration pages" or
   * "view the administration theme", they should be able to see the setting to
   * pick the language they want those pages in.
   *
   * If a user does not have that permission, it would confusing for them to
   * have a setting for pages they cannot access, so they should not be able to
   * set a language for those pages.
   */
  public function testUserAdminLanguageConfigurationAvailableIfAdminLanguageNegotiationIsEnabled() {
    $this->drupalLogin($this->adminUser);
    // Adds a new language, because with only one language, setting won't show.
    $this->addCustomLanguage();
    $this->setLanguageNegotiation();
    $path = 'user/' . $this->adminUser
      ->id() . '/edit';
    $this->drupalGet($path);
    // Ensure administration pages language setting is visible for admin.
    $this->assertSession()
      ->fieldExists('edit-preferred-admin-langcode');
    // Ensure administration pages language setting is visible for editors.
    $editor = $this->drupalCreateUser([
      'view the administration theme',
    ]);
    $this->drupalLogin($editor);
    $path = 'user/' . $editor->id() . '/edit';
    $this->drupalGet($path);
    $this->assertSession()
      ->fieldExists('edit-preferred-admin-langcode');
    // Ensure administration pages language setting is hidden for non-admins.
    $this->drupalLogin($this->regularUser);
    $path = 'user/' . $this->regularUser
      ->id() . '/edit';
    $this->drupalGet($path);
    $this->assertSession()
      ->fieldNotExists('edit-preferred-admin-langcode');
  }
  
  /**
   * Tests the actual language negotiation.
   */
  public function testActualNegotiation() {
    $this->drupalLogin($this->adminUser);
    $this->addCustomLanguage();
    $this->setLanguageNegotiation();
    // Even though we have admin language negotiation, so long as the user has
    // no preference set, negotiation will fall back further.
    $path = 'user/' . $this->adminUser
      ->id() . '/edit';
    $this->drupalGet($path);
    $this->assertSession()
      ->pageTextContains('Language negotiation method: language-default');
    $this->drupalGet('xx/' . $path);
    $this->assertSession()
      ->pageTextContains('Language negotiation method: language-url');
    // Set a preferred language code for the user.
    $edit = [];
    $edit['preferred_admin_langcode'] = 'xx';
    $this->drupalGet($path);
    $this->submitForm($edit, 'Save');
    // Test negotiation with the URL method first. The admin method will only
    // be used if the URL method did not match.
    $this->drupalGet($path);
    $this->assertSession()
      ->pageTextContains('Language negotiation method: language-user-admin');
    $this->drupalGet('xx/' . $path);
    $this->assertSession()
      ->pageTextContains('Language negotiation method: language-url');
    // Test negotiation with the admin language method first. The admin method
    // will be used at all times.
    $this->setLanguageNegotiation(TRUE);
    $this->drupalGet($path);
    $this->assertSession()
      ->pageTextContains('Language negotiation method: language-user-admin');
    $this->drupalGet('xx/' . $path);
    $this->assertSession()
      ->pageTextContains('Language negotiation method: language-user-admin');
    // Unset the preferred language code for the user.
    $edit = [];
    $edit['preferred_admin_langcode'] = '';
    $this->drupalGet($path);
    $this->submitForm($edit, 'Save');
    $this->drupalGet($path);
    $this->assertSession()
      ->pageTextContains('Language negotiation method: language-default');
    $this->drupalGet('xx/' . $path);
    $this->assertSession()
      ->pageTextContains('Language negotiation method: language-url');
  }
  
  /**
   * Sets the User interface negotiation detection method.
   *
   * Enables the "Account preference for administration pages" language
   * detection method for the User interface language negotiation type.
   *
   * @param bool $admin_first
   *   Whether the admin negotiation should be first.
   */
  public function setLanguageNegotiation($admin_first = FALSE) {
    $edit = [
      'language_interface[enabled][language-user-admin]' => TRUE,
      'language_interface[enabled][language-url]' => TRUE,
      'language_interface[weight][language-user-admin]' => $admin_first ? -12 : -8,
      'language_interface[weight][language-url]' => -10,
    ];
    $this->drupalGet('admin/config/regional/language/detection');
    $this->submitForm($edit, 'Save settings');
  }
  
  /**
   * Helper method for adding a custom language.
   */
  public function addCustomLanguage() {
    $langcode = 'xx';
    // The English name for the language.
    $name = $this->randomMachineName(16);
    $edit = [
      'predefined_langcode' => 'custom',
      'langcode' => $langcode,
      'label' => $name,
      'direction' => LanguageInterface::DIRECTION_LTR,
    ];
    $this->drupalGet('admin/config/regional/language/add');
    $this->submitForm($edit, 'Add custom language');
  }

}

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