getMock('\Drupal\Core\Language\LanguageInterface'); $language_de->expects($this->any()) ->method('getId') ->will($this->returnValue('de')); $language_en = $this->getMock('\Drupal\Core\Language\LanguageInterface'); $language_en->expects($this->any()) ->method('getId') ->will($this->returnValue('en')); $languages = [ 'de' => $language_de, 'en' => $language_en, ]; $this->languages = $languages; // Create a language manager stub. $language_manager = $this->getMockBuilder('Drupal\language\ConfigurableLanguageManagerInterface') ->getMock(); $language_manager->expects($this->any()) ->method('getLanguages') ->will($this->returnValue($languages)); $this->languageManager = $language_manager; // Create a user stub. $this->user = $this->getMockBuilder('Drupal\Core\Session\AccountInterface') ->getMock(); $cache_contexts_manager = $this->getMockBuilder('Drupal\Core\Cache\Context\CacheContextsManager') ->disableOriginalConstructor() ->getMock(); $cache_contexts_manager->method('assertValidTokens')->willReturn(TRUE); $container = new ContainerBuilder(); $container->set('cache_contexts_manager', $cache_contexts_manager); \Drupal::setContainer($container); } /** * Test path prefix language negotiation and outbound path processing. * * @dataProvider providerTestPathPrefix */ public function testPathPrefix($prefix, $prefixes, $expected_langcode) { $this->languageManager->expects($this->any()) ->method('getCurrentLanguage') ->will($this->returnValue($this->languages[(in_array($expected_langcode, ['en', 'de'])) ? $expected_langcode : 'en'])); $config = $this->getConfigFactoryStub([ 'language.negotiation' => [ 'url' => [ 'source' => LanguageNegotiationUrl::CONFIG_PATH_PREFIX, 'prefixes' => $prefixes, ], ], ]); $request = Request::create('/' . $prefix . '/foo', 'GET'); $method = new LanguageNegotiationUrl(); $method->setLanguageManager($this->languageManager); $method->setConfig($config); $method->setCurrentUser($this->user); $this->assertEquals($expected_langcode, $method->getLangcode($request)); $cacheability = new BubbleableMetadata(); $options = []; $method->processOutbound('foo', $options, $request, $cacheability); $expected_cacheability = new BubbleableMetadata(); if ($expected_langcode) { $this->assertSame($prefix . '/', $options['prefix']); $expected_cacheability->setCacheContexts(['languages:' . LanguageInterface::TYPE_URL]); } else { $this->assertFalse(isset($options['prefix'])); } $this->assertEquals($expected_cacheability, $cacheability); } /** * Provides data for the path prefix test. * * @return array * An array of data for checking path prefix negotiation. */ public function providerTestPathPrefix() { $path_prefix_configuration[] = [ 'prefix' => 'de', 'prefixes' => [ 'de' => 'de', 'en-uk' => 'en', ], 'expected_langcode' => 'de', ]; $path_prefix_configuration[] = [ 'prefix' => 'en-uk', 'prefixes' => [ 'de' => 'de', 'en' => 'en-uk', ], 'expected_langcode' => 'en', ]; // No configuration. $path_prefix_configuration[] = [ 'prefix' => 'de', 'prefixes' => [], 'expected_langcode' => FALSE, ]; // Non-matching prefix. $path_prefix_configuration[] = [ 'prefix' => 'de', 'prefixes' => [ 'en-uk' => 'en', ], 'expected_langcode' => FALSE, ]; // Non-existing language. $path_prefix_configuration[] = [ 'prefix' => 'it', 'prefixes' => [ 'it' => 'it', 'en-uk' => 'en', ], 'expected_langcode' => FALSE, ]; return $path_prefix_configuration; } /** * Test domain language negotiation and outbound path processing. * * @dataProvider providerTestDomain */ public function testDomain($http_host, $domains, $expected_langcode) { $this->languageManager->expects($this->any()) ->method('getCurrentLanguage') ->will($this->returnValue($this->languages['en'])); $config = $this->getConfigFactoryStub([ 'language.negotiation' => [ 'url' => [ 'source' => LanguageNegotiationUrl::CONFIG_DOMAIN, 'domains' => $domains, ], ], ]); $request = Request::create('', 'GET', [], [], [], ['HTTP_HOST' => $http_host]); $method = new LanguageNegotiationUrl(); $method->setLanguageManager($this->languageManager); $method->setConfig($config); $method->setCurrentUser($this->user); $this->assertEquals($expected_langcode, $method->getLangcode($request)); $cacheability = new BubbleableMetadata(); $options = []; $this->assertSame('foo', $method->processOutbound('foo', $options, $request, $cacheability)); $expected_cacheability = new BubbleableMetadata(); if ($expected_langcode !== FALSE && count($domains) > 1) { $expected_cacheability->setCacheMaxAge(Cache::PERMANENT)->setCacheContexts(['languages:' . LanguageInterface::TYPE_URL, 'url.site']); } $this->assertEquals($expected_cacheability, $cacheability); } /** * Provides data for the domain test. * * @return array * An array of data for checking domain negotiation. */ public function providerTestDomain() { $domain_configuration[] = [ 'http_host' => 'example.de', 'domains' => [ 'de' => 'http://example.de', ], 'expected_langcode' => 'de', ]; // No configuration. $domain_configuration[] = [ 'http_host' => 'example.de', 'domains' => [], 'expected_langcode' => FALSE, ]; // HTTP host with a port. $domain_configuration[] = [ 'http_host' => 'example.de:8080', 'domains' => [ 'de' => 'http://example.de', ], 'expected_langcode' => 'de', ]; // Domain configuration with https://. $domain_configuration[] = [ 'http_host' => 'example.de', 'domains' => [ 'de' => 'https://example.de', ], 'expected_langcode' => 'de', ]; // Non-matching HTTP host. $domain_configuration[] = [ 'http_host' => 'example.com', 'domains' => [ 'de' => 'http://example.com', ], 'expected_langcode' => 'de', ]; // Testing a non-existing language. $domain_configuration[] = [ 'http_host' => 'example.com', 'domains' => [ 'it' => 'http://example.it', ], 'expected_langcode' => FALSE, ]; // Multiple domain configurations. $domain_configuration[] = [ 'http_host' => 'example.com', 'domains' => [ 'de' => 'http://example.de', 'en' => 'http://example.com', ], 'expected_langcode' => 'en', ]; return $domain_configuration; } } // @todo Remove as part of https://www.drupal.org/node/2481833. namespace Drupal\language\Plugin\LanguageNegotiation; if (!function_exists('base_path')) { function base_path() { return '/'; } }