0

In a Kernel test I need to test the result of an url object per language. But the test doesn't consider the language settings.

Example:

public function register(ContainerBuilder $container) {
    parent::register($container);

    $language = Language::$defaultValues;
    $language['id'] = 'de';
    $language['name'] = 'German';
    $container->setParameter('language.default_values', $language);
}

protected function setUp() {
    parent::setUp();

    ConfigurableLanguage::createFromLangcode('fr')->save();
    ConfigurableLanguage::createFromLangcode('it')->save();
}

public function testUrls() {
    $languageManager = $this->container->get('language_manager');
    print_r($languageManager->getLanguages());

    $url = Url::fromRoute('<front>');
    $url->setOption('language', $languageManager->getLanguage('fr'));
    print_r($url->toString());
}

Output:

Array
(
    [de]
    [fr]
    [it]
)

# Output of toString()
/

The output of toString should be /fr instead of /

Addendum: I discovered that the \Drupal\language\HttpKernel\PathProcessorLanguage outbound processor is missing, when UrlGenerator::processPath() is called from the Kernel test. Therefore, I registered it in the Kernel test's register method, but that doesn't solve the problem.

1 Answer 1

0

Solution

I could solve it by register the PathProcessorLanguage class and add the language.types and language.negotiation config.

public function register(ContainerBuilder $container) {
  parent::register($container);

  // Define the default language.
  $language = Language::$defaultValues;
  $language['id'] = 'de';
  $language['name'] = 'German';
  $container->setParameter('language.default_values', $language);

  // Register PathProcessorLanguage.
  $container->register('path_processor_language', PathProcessorLanguage::class)
    ->addTag('path_processor_outbound', ['priority' => 100])
    ->addArgument(new Reference('config.factory'))
    ->addArgument(new Reference('language_manager'))
    ->addArgument(new Reference('language_negotiator'))
    ->addArgument(new Reference('current_user'))
    ->addArgument(new Reference('language.config_subscriber'));
}

protected function setUp() {
  parent::setUp();

  // Add additional languages.
  ConfigurableLanguage::createFromLangcode('fr')->save();
  ConfigurableLanguage::createFromLangcode('it')->save();

  // Define language settings.
  $this->config('language.types')->setData([
    'configurable' => ['language_interface'],
    'negotiation' => [
      'language_interface' => [
        'enabled' => [
          LanguageNegotiationUrl::METHOD_ID => 0,
        ],
      ],
    ],
  ])->save();

  $languageKeys = array_keys($this->container->get('language_manager')->getLanguages());
  $this->config('language.negotiation')->setData([
    'url' => [
      'source' => LanguageNegotiationUrl::CONFIG_PATH_PREFIX,
      'prefixes' => array_combine($languageKeys, $languageKeys),
    ],
  ])->save();
}

Addition

If you want to use/test path alias configs too, just register the AliasPathProcessor class...

public function register(ContainerBuilder $container) {
  parent::register($container);

  // ...

  $container->register('path_alias.path_processor', AliasPathProcessor::class)
      ->addTag('path_processor_outbound', ['priority' => 300])
      ->addArgument(new Reference('path_alias.manager'));

  //...
}

... and add the path alias entry for the specific language.

protected function setUp() {
  parent::setUp();

  // ...

  $pathAlias = PathAlias::create([
      'path' => '/foo',
      'alias' => '/bar',
      'langcode' => 'it',
    ]);
    $pathAlias->save();

  // ...
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.