cd6cc657bf0d2a071ac80f54376448487fbfc1f7
[yaffs-website] / web / core / modules / user / src / Tests / UserAdminLanguageTest.php
1 <?php
2
3 namespace Drupal\user\Tests;
4
5 use Drupal\Core\Language\LanguageInterface;
6 use Drupal\simpletest\WebTestBase;
7
8 /**
9  * Tests users' ability to change their own administration language.
10  *
11  * @group user
12  */
13 class UserAdminLanguageTest extends WebTestBase {
14
15   /**
16    * A user with permission to access admin pages and administer languages.
17    *
18    * @var \Drupal\user\UserInterface
19    */
20   protected $adminUser;
21
22   /**
23    * A non-administrator user for this test.
24    *
25    * @var \Drupal\user\UserInterface
26    */
27   protected $regularUser;
28
29   /**
30    * Modules to enable.
31    *
32    * @var array
33    */
34   public static $modules = ['user', 'language', 'language_test'];
35
36   protected function setUp() {
37     parent::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();
42   }
43
44   /**
45    * Tests that admin language is not configurable in single language sites.
46    */
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.');
54   }
55
56   /**
57    * Tests that admin language negotiation is configurable only if enabled.
58    */
59   public function testUserAdminLanguageConfigurationAvailableWithAdminLanguageNegotiation() {
60     $this->drupalLogin($this->adminUser);
61     $this->addCustomLanguage();
62     $path = 'user/' . $this->adminUser->id() . '/edit';
63
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.');
68
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.');
74   }
75
76   /**
77    * Tests that the admin language is configurable only for administrators.
78    *
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.
81    *
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.
85    */
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.');
95
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.');
101   }
102
103   /**
104    * Tests the actual language negotiation.
105    */
106   public function testActualNegotiation() {
107     $this->drupalLogin($this->adminUser);
108     $this->addCustomLanguage();
109     $this->setLanguageNegotiation();
110
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');
118
119     // Set a preferred language code for the user.
120     $edit = [];
121     $edit['preferred_admin_langcode'] = 'xx';
122     $this->drupalPostForm($path, $edit, t('Save'));
123
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');
130
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');
138
139     // Unset the preferred language code for the user.
140     $edit = [];
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');
147   }
148
149   /**
150    * Sets the User interface negotiation detection method.
151    *
152    * Enables the "Account preference for administration pages" language
153    * detection method for the User interface language negotiation type.
154    *
155    * @param bool $admin_first
156    *   Whether the admin negotiation should be first.
157    */
158   public function setLanguageNegotiation($admin_first = FALSE) {
159     $edit = [
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,
164     ];
165     $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
166   }
167
168   /**
169    * Helper method for adding a custom language.
170    */
171   public function addCustomLanguage() {
172     $langcode = 'xx';
173     // The English name for the language.
174     $name = $this->randomMachineName(16);
175     $edit = [
176       'predefined_langcode' => 'custom',
177       'langcode' => $langcode,
178       'label' => $name,
179       'direction' => LanguageInterface::DIRECTION_LTR,
180     ];
181     $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
182   }
183
184 }