3 namespace Drupal\user\Tests;
5 use Drupal\Core\Language\LanguageInterface;
6 use Drupal\simpletest\WebTestBase;
9 * Tests users' ability to change their own administration language.
13 class UserAdminLanguageTest extends WebTestBase {
16 * A user with permission to access admin pages and administer languages.
18 * @var \Drupal\user\UserInterface
23 * A non-administrator user for this test.
25 * @var \Drupal\user\UserInterface
27 protected $regularUser;
34 public static $modules = ['user', 'language', 'language_test'];
36 protected function setUp() {
38 // User to add and remove language.
39 $this->adminUser = $this->drupalCreateUser(['administer languages', 'access administration pages']);
40 // User to check non-admin access.
41 $this->regularUser = $this->drupalCreateUser();
45 * Tests that admin language is not configurable in single language sites.
47 public function testUserAdminLanguageConfigurationNotAvailableWithOnlyOneLanguage() {
48 $this->drupalLogin($this->adminUser);
49 $this->setLanguageNegotiation();
50 $path = 'user/' . $this->adminUser->id() . '/edit';
51 $this->drupalGet($path);
52 // Ensure administration pages language settings widget is not available.
53 $this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available.');
57 * Tests that admin language negotiation is configurable only if enabled.
59 public function testUserAdminLanguageConfigurationAvailableWithAdminLanguageNegotiation() {
60 $this->drupalLogin($this->adminUser);
61 $this->addCustomLanguage();
62 $path = 'user/' . $this->adminUser->id() . '/edit';
64 // Checks with user administration pages language negotiation disabled.
65 $this->drupalGet($path);
66 // Ensure administration pages language settings widget is not available.
67 $this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available.');
69 // Checks with user administration pages language negotiation enabled.
70 $this->setLanguageNegotiation();
71 $this->drupalGet($path);
72 // Ensure administration pages language settings widget is available.
73 $this->assertFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector is available.');
77 * Tests that the admin language is configurable only for administrators.
79 * If a user has the permission "access administration pages", they should
80 * be able to see the setting to pick the language they want those pages in.
82 * If a user does not have that permission, it would confusing for them to
83 * have a setting for pages they cannot access, so they should not be able to
84 * set a language for those pages.
86 public function testUserAdminLanguageConfigurationAvailableIfAdminLanguageNegotiationIsEnabled() {
87 $this->drupalLogin($this->adminUser);
88 // Adds a new language, because with only one language, setting won't show.
89 $this->addCustomLanguage();
90 $this->setLanguageNegotiation();
91 $path = 'user/' . $this->adminUser->id() . '/edit';
92 $this->drupalGet($path);
93 // Ensure administration pages language setting is visible for admin.
94 $this->assertFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector available for admins.');
96 // Ensure administration pages language setting is hidden for non-admins.
97 $this->drupalLogin($this->regularUser);
98 $path = 'user/' . $this->regularUser->id() . '/edit';
99 $this->drupalGet($path);
100 $this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available for regular user.');
104 * Tests the actual language negotiation.
106 public function testActualNegotiation() {
107 $this->drupalLogin($this->adminUser);
108 $this->addCustomLanguage();
109 $this->setLanguageNegotiation();
111 // Even though we have admin language negotiation, so long as the user has
112 // no preference set, negotiation will fall back further.
113 $path = 'user/' . $this->adminUser->id() . '/edit';
114 $this->drupalGet($path);
115 $this->assertText('Language negotiation method: language-default');
116 $this->drupalGet('xx/' . $path);
117 $this->assertText('Language negotiation method: language-url');
119 // Set a preferred language code for the user.
121 $edit['preferred_admin_langcode'] = 'xx';
122 $this->drupalPostForm($path, $edit, t('Save'));
124 // Test negotiation with the URL method first. The admin method will only
125 // be used if the URL method did not match.
126 $this->drupalGet($path);
127 $this->assertText('Language negotiation method: language-user-admin');
128 $this->drupalGet('xx/' . $path);
129 $this->assertText('Language negotiation method: language-url');
131 // Test negotiation with the admin language method first. The admin method
132 // will be used at all times.
133 $this->setLanguageNegotiation(TRUE);
134 $this->drupalGet($path);
135 $this->assertText('Language negotiation method: language-user-admin');
136 $this->drupalGet('xx/' . $path);
137 $this->assertText('Language negotiation method: language-user-admin');
139 // Unset the preferred language code for the user.
141 $edit['preferred_admin_langcode'] = '';
142 $this->drupalPostForm($path, $edit, t('Save'));
143 $this->drupalGet($path);
144 $this->assertText('Language negotiation method: language-default');
145 $this->drupalGet('xx/' . $path);
146 $this->assertText('Language negotiation method: language-url');
150 * Sets the User interface negotiation detection method.
152 * Enables the "Account preference for administration pages" language
153 * detection method for the User interface language negotiation type.
155 * @param bool $admin_first
156 * Whether the admin negotiation should be first.
158 public function setLanguageNegotiation($admin_first = FALSE) {
160 'language_interface[enabled][language-user-admin]' => TRUE,
161 'language_interface[enabled][language-url]' => TRUE,
162 'language_interface[weight][language-user-admin]' => ($admin_first ? -12 : -8),
163 'language_interface[weight][language-url]' => -10,
165 $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
169 * Helper method for adding a custom language.
171 public function addCustomLanguage() {
173 // The English name for the language.
174 $name = $this->randomMachineName(16);
176 'predefined_langcode' => 'custom',
177 'langcode' => $langcode,
179 'direction' => LanguageInterface::DIRECTION_LTR,
181 $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));