Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / language / tests / src / Functional / LanguageNegotiationInfoTest.php
1 <?php
2
3 namespace Drupal\Tests\language\Functional;
4
5 use Drupal\Core\Language\LanguageInterface;
6 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUI;
7 use Drupal\Tests\BrowserTestBase;
8
9 /**
10  * Tests alterations to language types/negotiation info.
11  *
12  * @group language
13  */
14 class LanguageNegotiationInfoTest extends BrowserTestBase {
15
16   /**
17    * Modules to enable.
18    *
19    * @var array
20    */
21   public static $modules = ['language', 'content_translation'];
22
23   /**
24    * {@inheritdoc}
25    */
26   protected function setUp() {
27     parent::setUp();
28     $admin_user = $this->drupalCreateUser(['administer languages', 'access administration pages', 'view the administration theme', 'administer modules']);
29     $this->drupalLogin($admin_user);
30     $this->drupalPostForm('admin/config/regional/language/add', ['predefined_langcode' => 'it'], t('Add language'));
31   }
32
33   /**
34    * Returns the configurable language manager.
35    *
36    * @return \Drupal\language\ConfigurableLanguageManager
37    */
38   protected function languageManager() {
39     return $this->container->get('language_manager');
40   }
41
42   /**
43    * Sets state flags for language_test module.
44    *
45    * Ensures to correctly update data both in the child site and the test runner
46    * environment.
47    *
48    * @param array $values
49    *   The key/value pairs to set in state.
50    */
51   protected function stateSet(array $values) {
52     // Set the new state values.
53     $this->container->get('state')->setMultiple($values);
54     // Refresh in-memory static state/config caches and static variables.
55     $this->refreshVariables();
56     // Refresh/rewrite language negotiation configuration, in order to pick up
57     // the manipulations performed by language_test module's info alter hooks.
58     $this->container->get('language_negotiator')->purgeConfiguration();
59   }
60
61   /**
62    * Tests alterations to language types/negotiation info.
63    */
64   public function testInfoAlterations() {
65     $this->stateSet([
66       // Enable language_test type info.
67       'language_test.language_types' => TRUE,
68       // Enable language_test negotiation info (not altered yet).
69       'language_test.language_negotiation_info' => TRUE,
70       // Alter LanguageInterface::TYPE_CONTENT to be configurable.
71       'language_test.content_language_type' => TRUE,
72     ]);
73     $this->container->get('module_installer')->install(['language_test']);
74     $this->resetAll();
75
76     // Check that fixed language types are properly configured without the need
77     // of saving the language negotiation settings.
78     $this->checkFixedLanguageTypes();
79
80     $type = LanguageInterface::TYPE_CONTENT;
81     $language_types = $this->languageManager()->getLanguageTypes();
82     $this->assertTrue(in_array($type, $language_types), 'Content language type is configurable.');
83
84     // Enable some core and custom language negotiation methods. The test
85     // language type is supposed to be configurable.
86     $test_type = 'test_language_type';
87     $interface_method_id = LanguageNegotiationUI::METHOD_ID;
88     $test_method_id = 'test_language_negotiation_method';
89     $form_field = $type . '[enabled][' . $interface_method_id . ']';
90     $edit = [
91       $form_field => TRUE,
92       $type . '[enabled][' . $test_method_id . ']' => TRUE,
93       $test_type . '[enabled][' . $test_method_id . ']' => TRUE,
94       $test_type . '[configurable]' => TRUE,
95     ];
96     $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
97
98     // Alter language negotiation info to remove interface language negotiation
99     // method.
100     $this->stateSet([
101       'language_test.language_negotiation_info_alter' => TRUE,
102     ]);
103
104     $negotiation = $this->config('language.types')->get('negotiation.' . $type . '.enabled');
105     $this->assertFalse(isset($negotiation[$interface_method_id]), 'Interface language negotiation method removed from the stored settings.');
106
107     $this->drupalGet('admin/config/regional/language/detection');
108     $this->assertNoFieldByName($form_field, NULL, 'Interface language negotiation method unavailable.');
109
110     // Check that type-specific language negotiation methods can be assigned
111     // only to the corresponding language types.
112     foreach ($this->languageManager()->getLanguageTypes() as $type) {
113       $form_field = $type . '[enabled][test_language_negotiation_method_ts]';
114       if ($type == $test_type) {
115         $this->assertFieldByName($form_field, NULL, format_string('Type-specific test language negotiation method available for %type.', ['%type' => $type]));
116       }
117       else {
118         $this->assertNoFieldByName($form_field, NULL, format_string('Type-specific test language negotiation method unavailable for %type.', ['%type' => $type]));
119       }
120     }
121
122     // Check language negotiation results.
123     $this->drupalGet('');
124     $last = $this->container->get('state')->get('language_test.language_negotiation_last');
125     foreach ($this->languageManager()->getDefinedLanguageTypes() as $type) {
126       $langcode = $last[$type];
127       $value = $type == LanguageInterface::TYPE_CONTENT || strpos($type, 'test') !== FALSE ? 'it' : 'en';
128       $this->assertEqual($langcode, $value, format_string('The negotiated language for %type is %language', ['%type' => $type, '%language' => $value]));
129     }
130
131     // Uninstall language_test and check that everything is set back to the
132     // original status.
133     $this->container->get('module_installer')->uninstall(['language_test']);
134     $this->rebuildContainer();
135
136     // Check that only the core language types are available.
137     foreach ($this->languageManager()->getDefinedLanguageTypes() as $type) {
138       $this->assertTrue(strpos($type, 'test') === FALSE, format_string('The %type language is still available', ['%type' => $type]));
139     }
140
141     // Check that fixed language types are properly configured, even those
142     // previously set to configurable.
143     $this->checkFixedLanguageTypes();
144
145     // Check that unavailable language negotiation methods are not present in
146     // the negotiation settings.
147     $negotiation = $this->config('language.types')->get('negotiation.' . $type . '.enabled');
148     $this->assertFalse(isset($negotiation[$test_method_id]), 'The disabled test language negotiation method is not part of the content language negotiation settings.');
149
150     // Check that configuration page presents the correct options and settings.
151     $this->assertNoRaw(t('Test language detection'), 'No test language type configuration available.');
152     $this->assertNoRaw(t('This is a test language negotiation method'), 'No test language negotiation method available.');
153   }
154
155   /**
156    * Check that language negotiation for fixed types matches the stored one.
157    */
158   protected function checkFixedLanguageTypes() {
159     $configurable = $this->languageManager()->getLanguageTypes();
160     foreach ($this->languageManager()->getDefinedLanguageTypesInfo() as $type => $info) {
161       if (!in_array($type, $configurable) && isset($info['fixed'])) {
162         $negotiation = $this->config('language.types')->get('negotiation.' . $type . '.enabled');
163         $equal = array_keys($negotiation) === array_values($info['fixed']);
164         $this->assertTrue($equal, format_string('language negotiation for %type is properly set up', ['%type' => $type]));
165       }
166     }
167   }
168
169   /**
170    * Tests altering config of configurable language types.
171    */
172   public function testConfigLangTypeAlterations() {
173     // Default of config.
174     $test_type = LanguageInterface::TYPE_CONTENT;
175     $this->assertFalse($this->isLanguageTypeConfigurable($test_type), 'Language type is not configurable.');
176
177     // Editing config.
178     $edit = [$test_type . '[configurable]' => TRUE];
179     $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings'));
180     $this->assertTrue($this->isLanguageTypeConfigurable($test_type), 'Language type is now configurable.');
181
182     // After installing another module, the config should be the same.
183     $this->drupalPostForm('admin/modules', ['modules[test_module][enable]' => 1], t('Install'));
184     $this->assertTrue($this->isLanguageTypeConfigurable($test_type), 'Language type is still configurable.');
185
186     // After uninstalling the other module, the config should be the same.
187     $this->drupalPostForm('admin/modules/uninstall', ['uninstall[test_module]' => 1], t('Uninstall'));
188     $this->assertTrue($this->isLanguageTypeConfigurable($test_type), 'Language type is still configurable.');
189   }
190
191   /**
192    * Checks whether the given language type is configurable.
193    *
194    * @param string $type
195    *   The language type.
196    *
197    * @return bool
198    *   TRUE if the specified language type is configurable, FALSE otherwise.
199    */
200   protected function isLanguageTypeConfigurable($type) {
201     $configurable_types = $this->config('language.types')->get('configurable');
202     return in_array($type, $configurable_types);
203   }
204
205 }