46d5ed74d1203232014863bea3ae3d954484b524
[yaffs-website] / web / core / modules / language / src / Tests / LanguageConfigurationTest.php
1 <?php
2
3 namespace Drupal\language\Tests;
4
5 use Drupal\Core\Language\LanguageInterface;
6 use Drupal\language\Entity\ConfigurableLanguage;
7 use Drupal\simpletest\WebTestBase;
8
9 /**
10  * Adds and configures languages to check negotiation changes.
11  *
12  * @group language
13  */
14 class LanguageConfigurationTest extends WebTestBase {
15
16   /**
17    * Modules to enable.
18    *
19    * @var array
20    */
21   public static $modules = ['language'];
22
23   /**
24    * Functional tests for adding, editing and deleting languages.
25    */
26   public function testLanguageConfiguration() {
27     // Ensure the after installing the language module the weight of the English
28     // language is still 0.
29     $this->assertEqual(ConfigurableLanguage::load('en')->getWeight(), 0, 'The English language has a weight of 0.');
30
31     // User to add and remove language.
32     $admin_user = $this->drupalCreateUser(['administer languages', 'access administration pages']);
33     $this->drupalLogin($admin_user);
34
35     // Check if the Default English language has no path prefix.
36     $this->drupalGet('admin/config/regional/language/detection/url');
37     $this->assertFieldByXPath('//input[@name="prefix[en]"]', '', 'Default English has no path prefix.');
38
39     // Check that Add language is a primary button.
40     $this->drupalGet('admin/config/regional/language/add');
41     $this->assertFieldByXPath('//input[contains(@class, "button--primary")]', 'Add language', 'Add language is a primary button');
42
43     // Add predefined language.
44     $edit = [
45       'predefined_langcode' => 'fr',
46     ];
47     $this->drupalPostForm(NULL, $edit, 'Add language');
48     $this->assertText('French');
49     $this->assertUrl(\Drupal::url('entity.configurable_language.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
50     // Langcode for Languages is always 'en'.
51     $language = $this->config('language.entity.fr')->get();
52     $this->assertEqual($language['langcode'], 'en');
53
54     // Check if the Default English language has no path prefix.
55     $this->drupalGet('admin/config/regional/language/detection/url');
56     $this->assertFieldByXPath('//input[@name="prefix[en]"]', '', 'Default English has no path prefix.');
57     // Check if French has a path prefix.
58     $this->drupalGet('admin/config/regional/language/detection/url');
59     $this->assertFieldByXPath('//input[@name="prefix[fr]"]', 'fr', 'French has a path prefix.');
60
61     // Check if we can change the default language.
62     $this->drupalGet('admin/config/regional/language');
63     $this->assertFieldChecked('edit-site-default-language-en', 'English is the default language.');
64
65     // Change the default language.
66     $edit = [
67       'site_default_language' => 'fr',
68     ];
69     $this->drupalPostForm(NULL, $edit, t('Save configuration'));
70     $this->rebuildContainer();
71     $this->assertFieldChecked('edit-site-default-language-fr', 'Default language updated.');
72     $this->assertUrl(\Drupal::url('entity.configurable_language.collection', [], ['absolute' => TRUE, 'langcode' => 'fr']), [], 'Correct page redirection.');
73
74     // Check if a valid language prefix is added after changing the default
75     // language.
76     $this->drupalGet('admin/config/regional/language/detection/url');
77     $this->assertFieldByXPath('//input[@name="prefix[en]"]', 'en', 'A valid path prefix has been added to the previous default language.');
78     // Check if French still has a path prefix.
79     $this->drupalGet('admin/config/regional/language/detection/url');
80     $this->assertFieldByXPath('//input[@name="prefix[fr]"]', 'fr', 'French still has a path prefix.');
81
82     // Check that prefix can be changed.
83     $edit = [
84       'prefix[fr]' => 'french',
85     ];
86     $this->drupalPostForm(NULL, $edit, t('Save configuration'));
87     $this->assertFieldByXPath('//input[@name="prefix[fr]"]', 'french', 'French path prefix has changed.');
88
89     // Check that the prefix can be removed.
90     $edit = [
91       'prefix[fr]' => '',
92     ];
93     $this->drupalPostForm(NULL, $edit, t('Save configuration'));
94     $this->assertNoText(t('The prefix may only be left blank for the selected detection fallback language.'), 'The path prefix can be removed for the default language');
95
96     // Change default negotiation language.
97     $this->config('language.negotiation')->set('selected_langcode', 'fr')->save();
98     // Check that the prefix of a language that is not the negotiation one
99     // cannot be changed to empty string.
100     $edit = [
101       'prefix[en]' => '',
102     ];
103     $this->drupalPostForm(NULL, $edit, t('Save configuration'));
104     $this->assertText(t('The prefix may only be left blank for the selected detection fallback language.'));
105
106     //  Check that prefix cannot be changed to contain a slash.
107     $edit = [
108       'prefix[en]' => 'foo/bar',
109     ];
110     $this->drupalPostForm(NULL, $edit, t('Save configuration'));
111     $this->assertText(t('The prefix may not contain a slash.'), 'English prefix cannot be changed to contain a slash.');
112
113     // Remove English language and add a new Language to check if langcode of
114     // Language entity is 'en'.
115     $this->drupalPostForm('admin/config/regional/language/delete/en', [], t('Delete'));
116     $this->rebuildContainer();
117     $this->assertRaw(t('The %language (%langcode) language has been removed.', ['%language' => 'English', '%langcode' => 'en']));
118
119     // Ensure that French language has a weight of 1 after being created through
120     // the UI.
121     $french = ConfigurableLanguage::load('fr');
122     $this->assertEqual($french->getWeight(), 1, 'The French language has a weight of 1.');
123     // Ensure that French language can now have a weight of 0.
124     $french->setWeight(0)->save();
125     $this->assertEqual($french->getWeight(), 0, 'The French language has a weight of 0.');
126     // Ensure that new languages created through the API get a weight of 0.
127     $afrikaans = ConfigurableLanguage::createFromLangcode('af');
128     $afrikaans->save();
129     $this->assertEqual($afrikaans->getWeight(), 0, 'The Afrikaans language has a weight of 0.');
130     // Ensure that a new language can be created with any weight.
131     $arabic = ConfigurableLanguage::createFromLangcode('ar');
132     $arabic->setWeight(4)->save();
133     $this->assertEqual($arabic->getWeight(), 4, 'The Arabic language has a weight of 0.');
134
135     $edit = [
136       'predefined_langcode' => 'de',
137     ];
138     $this->drupalPostForm('admin/config/regional/language/add', $edit, 'Add language');
139     $language = $this->config('language.entity.de')->get();
140     $this->assertEqual($language['langcode'], 'fr');
141
142     // Ensure that German language has a weight of 5 after being created through
143     // the UI.
144     $french = ConfigurableLanguage::load('de');
145     $this->assertEqual($french->getWeight(), 5, 'The German language has a weight of 5.');
146   }
147
148   /**
149    * Functional tests for setting system language weight on adding, editing and deleting languages.
150    */
151   public function testLanguageConfigurationWeight() {
152     // User to add and remove language.
153     $admin_user = $this->drupalCreateUser(['administer languages', 'access administration pages']);
154     $this->drupalLogin($admin_user);
155     $this->checkConfigurableLanguageWeight();
156
157     // Add predefined language.
158     $edit = [
159       'predefined_langcode' => 'fr',
160     ];
161     $this->drupalPostForm('admin/config/regional/language/add', $edit, 'Add language');
162     $this->checkConfigurableLanguageWeight('after adding new language');
163
164     // Re-ordering languages.
165     $edit = [
166       'languages[en][weight]' => $this->getHighestConfigurableLanguageWeight() + 1,
167     ];
168     $this->drupalPostForm('admin/config/regional/language', $edit, 'Save configuration');
169     $this->checkConfigurableLanguageWeight('after re-ordering');
170
171     // Remove predefined language.
172     $edit = [
173       'confirm' => 1,
174     ];
175     $this->drupalPostForm('admin/config/regional/language/delete/fr', $edit, 'Delete');
176     $this->checkConfigurableLanguageWeight('after deleting a language');
177   }
178
179   /**
180    * Validates system languages are ordered after configurable languages.
181    *
182    * @param string $state
183    *   (optional) A string for customizing assert messages, containing the
184    *   description of the state of the check, for example: 'after re-ordering'.
185    *   Defaults to 'by default'.
186    */
187   protected function checkConfigurableLanguageWeight($state = 'by default') {
188     // Reset language list.
189     \Drupal::languageManager()->reset();
190     $max_configurable_language_weight = $this->getHighestConfigurableLanguageWeight();
191     $replacements = ['@event' => $state];
192     foreach (\Drupal::languageManager()->getLanguages(LanguageInterface::STATE_LOCKED) as $locked_language) {
193       $replacements['%language'] = $locked_language->getName();
194       $this->assertTrue($locked_language->getWeight() > $max_configurable_language_weight, format_string('System language %language has higher weight than configurable languages @event', $replacements));
195     }
196   }
197
198   /**
199    * Helper to get maximum weight of configurable (unlocked) languages.
200    *
201    * @return int
202    *   Maximum weight of configurable languages.
203    */
204   protected function getHighestConfigurableLanguageWeight(){
205     $max_weight = 0;
206
207     $storage = $this->container->get('entity_type.manager')
208       ->getStorage('configurable_language');
209     $storage->resetCache();
210     /* @var $languages \Drupal\Core\Language\LanguageInterface[] */
211     $languages = $storage->loadMultiple();
212     foreach ($languages as $language) {
213       if (!$language->isLocked()) {
214         $max_weight = max($max_weight, $language->getWeight());
215       }
216     }
217
218     return $max_weight;
219   }
220
221 }