Chris@0: drupalCreateUser(['administer languages', 'access administration pages', 'view the administration theme', 'administer modules']); Chris@0: $this->drupalLogin($admin_user); Chris@0: $this->drupalPostForm('admin/config/regional/language/add', ['predefined_langcode' => 'it'], t('Add language')); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the configurable language manager. Chris@0: * Chris@0: * @return \Drupal\language\ConfigurableLanguageManager Chris@0: */ Chris@0: protected function languageManager() { Chris@0: return $this->container->get('language_manager'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets state flags for language_test module. Chris@0: * Chris@0: * Ensures to correctly update data both in the child site and the test runner Chris@0: * environment. Chris@0: * Chris@0: * @param array $values Chris@0: * The key/value pairs to set in state. Chris@0: */ Chris@0: protected function stateSet(array $values) { Chris@0: // Set the new state values. Chris@0: $this->container->get('state')->setMultiple($values); Chris@0: // Refresh in-memory static state/config caches and static variables. Chris@0: $this->refreshVariables(); Chris@0: // Refresh/rewrite language negotiation configuration, in order to pick up Chris@0: // the manipulations performed by language_test module's info alter hooks. Chris@0: $this->container->get('language_negotiator')->purgeConfiguration(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests alterations to language types/negotiation info. Chris@0: */ Chris@0: public function testInfoAlterations() { Chris@0: $this->stateSet([ Chris@0: // Enable language_test type info. Chris@0: 'language_test.language_types' => TRUE, Chris@0: // Enable language_test negotiation info (not altered yet). Chris@0: 'language_test.language_negotiation_info' => TRUE, Chris@0: // Alter LanguageInterface::TYPE_CONTENT to be configurable. Chris@0: 'language_test.content_language_type' => TRUE, Chris@0: ]); Chris@0: $this->container->get('module_installer')->install(['language_test']); Chris@0: $this->resetAll(); Chris@0: Chris@0: // Check that fixed language types are properly configured without the need Chris@0: // of saving the language negotiation settings. Chris@0: $this->checkFixedLanguageTypes(); Chris@0: Chris@0: $type = LanguageInterface::TYPE_CONTENT; Chris@0: $language_types = $this->languageManager()->getLanguageTypes(); Chris@0: $this->assertTrue(in_array($type, $language_types), 'Content language type is configurable.'); Chris@0: Chris@0: // Enable some core and custom language negotiation methods. The test Chris@0: // language type is supposed to be configurable. Chris@0: $test_type = 'test_language_type'; Chris@0: $interface_method_id = LanguageNegotiationUI::METHOD_ID; Chris@0: $test_method_id = 'test_language_negotiation_method'; Chris@0: $form_field = $type . '[enabled][' . $interface_method_id . ']'; Chris@0: $edit = [ Chris@0: $form_field => TRUE, Chris@0: $type . '[enabled][' . $test_method_id . ']' => TRUE, Chris@0: $test_type . '[enabled][' . $test_method_id . ']' => TRUE, Chris@0: $test_type . '[configurable]' => TRUE, Chris@0: ]; Chris@0: $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); Chris@0: Chris@0: // Alter language negotiation info to remove interface language negotiation Chris@0: // method. Chris@0: $this->stateSet([ Chris@0: 'language_test.language_negotiation_info_alter' => TRUE, Chris@0: ]); Chris@0: Chris@0: $negotiation = $this->config('language.types')->get('negotiation.' . $type . '.enabled'); Chris@0: $this->assertFalse(isset($negotiation[$interface_method_id]), 'Interface language negotiation method removed from the stored settings.'); Chris@0: Chris@0: $this->drupalGet('admin/config/regional/language/detection'); Chris@0: $this->assertNoFieldByName($form_field, NULL, 'Interface language negotiation method unavailable.'); Chris@0: Chris@0: // Check that type-specific language negotiation methods can be assigned Chris@0: // only to the corresponding language types. Chris@0: foreach ($this->languageManager()->getLanguageTypes() as $type) { Chris@0: $form_field = $type . '[enabled][test_language_negotiation_method_ts]'; Chris@0: if ($type == $test_type) { Chris@0: $this->assertFieldByName($form_field, NULL, format_string('Type-specific test language negotiation method available for %type.', ['%type' => $type])); Chris@0: } Chris@0: else { Chris@0: $this->assertNoFieldByName($form_field, NULL, format_string('Type-specific test language negotiation method unavailable for %type.', ['%type' => $type])); Chris@0: } Chris@0: } Chris@0: Chris@0: // Check language negotiation results. Chris@0: $this->drupalGet(''); Chris@0: $last = $this->container->get('state')->get('language_test.language_negotiation_last'); Chris@0: foreach ($this->languageManager()->getDefinedLanguageTypes() as $type) { Chris@0: $langcode = $last[$type]; Chris@0: $value = $type == LanguageInterface::TYPE_CONTENT || strpos($type, 'test') !== FALSE ? 'it' : 'en'; Chris@0: $this->assertEqual($langcode, $value, format_string('The negotiated language for %type is %language', ['%type' => $type, '%language' => $value])); Chris@0: } Chris@0: Chris@0: // Uninstall language_test and check that everything is set back to the Chris@0: // original status. Chris@0: $this->container->get('module_installer')->uninstall(['language_test']); Chris@0: $this->rebuildContainer(); Chris@0: Chris@0: // Check that only the core language types are available. Chris@0: foreach ($this->languageManager()->getDefinedLanguageTypes() as $type) { Chris@0: $this->assertTrue(strpos($type, 'test') === FALSE, format_string('The %type language is still available', ['%type' => $type])); Chris@0: } Chris@0: Chris@0: // Check that fixed language types are properly configured, even those Chris@0: // previously set to configurable. Chris@0: $this->checkFixedLanguageTypes(); Chris@0: Chris@0: // Check that unavailable language negotiation methods are not present in Chris@0: // the negotiation settings. Chris@0: $negotiation = $this->config('language.types')->get('negotiation.' . $type . '.enabled'); Chris@0: $this->assertFalse(isset($negotiation[$test_method_id]), 'The disabled test language negotiation method is not part of the content language negotiation settings.'); Chris@0: Chris@0: // Check that configuration page presents the correct options and settings. Chris@0: $this->assertNoRaw(t('Test language detection'), 'No test language type configuration available.'); Chris@0: $this->assertNoRaw(t('This is a test language negotiation method'), 'No test language negotiation method available.'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Check that language negotiation for fixed types matches the stored one. Chris@0: */ Chris@0: protected function checkFixedLanguageTypes() { Chris@0: $configurable = $this->languageManager()->getLanguageTypes(); Chris@0: foreach ($this->languageManager()->getDefinedLanguageTypesInfo() as $type => $info) { Chris@0: if (!in_array($type, $configurable) && isset($info['fixed'])) { Chris@0: $negotiation = $this->config('language.types')->get('negotiation.' . $type . '.enabled'); Chris@14: $equal = array_keys($negotiation) === array_values($info['fixed']); Chris@0: $this->assertTrue($equal, format_string('language negotiation for %type is properly set up', ['%type' => $type])); Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests altering config of configurable language types. Chris@0: */ Chris@0: public function testConfigLangTypeAlterations() { Chris@0: // Default of config. Chris@0: $test_type = LanguageInterface::TYPE_CONTENT; Chris@0: $this->assertFalse($this->isLanguageTypeConfigurable($test_type), 'Language type is not configurable.'); Chris@0: Chris@0: // Editing config. Chris@0: $edit = [$test_type . '[configurable]' => TRUE]; Chris@0: $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); Chris@0: $this->assertTrue($this->isLanguageTypeConfigurable($test_type), 'Language type is now configurable.'); Chris@0: Chris@0: // After installing another module, the config should be the same. Chris@0: $this->drupalPostForm('admin/modules', ['modules[test_module][enable]' => 1], t('Install')); Chris@0: $this->assertTrue($this->isLanguageTypeConfigurable($test_type), 'Language type is still configurable.'); Chris@0: Chris@0: // After uninstalling the other module, the config should be the same. Chris@0: $this->drupalPostForm('admin/modules/uninstall', ['uninstall[test_module]' => 1], t('Uninstall')); Chris@0: $this->assertTrue($this->isLanguageTypeConfigurable($test_type), 'Language type is still configurable.'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Checks whether the given language type is configurable. Chris@0: * Chris@0: * @param string $type Chris@0: * The language type. Chris@0: * Chris@0: * @return bool Chris@0: * TRUE if the specified language type is configurable, FALSE otherwise. Chris@0: */ Chris@0: protected function isLanguageTypeConfigurable($type) { Chris@0: $configurable_types = $this->config('language.types')->get('configurable'); Chris@0: return in_array($type, $configurable_types); Chris@0: } Chris@0: Chris@0: }