Issue #3130107 by stefanos.petrakis, rpayanm, smustgrave, jungle: Extend unit test coverage for LanguageNegotiationContentEntity
parent
d8408c2c43
commit
d2eb0235cc
|
@ -2,15 +2,18 @@
|
|||
|
||||
namespace Drupal\Tests\language\Unit\Plugin\LanguageNegotiation;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Drupal\Core\Cache\Context\CacheContextsManager;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Entity\EntityTypeManager;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Render\BubbleableMetadata;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\language\ConfigurableLanguageManagerInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity;
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\ServerBag;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
/**
|
||||
* Tests the LanguageNegotiationContentEntity plugin class.
|
||||
|
@ -19,7 +22,7 @@ use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity;
|
|||
* @coversDefaultClass \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity
|
||||
* @see \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity
|
||||
*/
|
||||
class LanguageNegotiationContentEntityTest extends UnitTestCase {
|
||||
class LanguageNegotiationContentEntityTest extends LanguageNegotiationTestBase {
|
||||
|
||||
/**
|
||||
* An array of mock LanguageInterface objects.
|
||||
|
@ -36,11 +39,11 @@ class LanguageNegotiationContentEntityTest extends UnitTestCase {
|
|||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* A mock object implementing the AccountInterface.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $user;
|
||||
protected function getPluginClass(): string {
|
||||
return LanguageNegotiationContentEntity::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -53,32 +56,39 @@ class LanguageNegotiationContentEntityTest extends UnitTestCase {
|
|||
$language_de->expects($this->any())
|
||||
->method('getId')
|
||||
->will($this->returnValue('de'));
|
||||
$language_de->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('German'));
|
||||
$language_en = $this->createMock(LanguageInterface::class);
|
||||
$language_en->expects($this->any())
|
||||
->method('getId')
|
||||
->will($this->returnValue('en'));
|
||||
$languages = [
|
||||
$language_en->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('English'));
|
||||
$this->languages = [
|
||||
'de' => $language_de,
|
||||
'en' => $language_en,
|
||||
];
|
||||
$this->languages = $languages;
|
||||
|
||||
$language_manager = $this->getMockBuilder(ConfigurableLanguageManagerInterface::class)
|
||||
->getMock();
|
||||
$language_manager = $this->createMock(ConfigurableLanguageManagerInterface::class);
|
||||
$language_manager->expects($this->any())
|
||||
->method('getLanguages')
|
||||
->will($this->returnValue($languages));
|
||||
->will($this->returnValue($this->languages));
|
||||
$language_manager->expects($this->any())
|
||||
->method('getNativeLanguages')
|
||||
->will($this->returnValue($this->languages));
|
||||
$this->languageManager = $language_manager;
|
||||
|
||||
$this->user = $this->getMockBuilder(AccountInterface::class)
|
||||
->getMock();
|
||||
|
||||
$cache_contexts_manager = $this->getMockBuilder(CacheContextsManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$cache_contexts_manager->method('assertValidTokens')->willReturn(TRUE);
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$cache_contexts_manager = $this->createMock(CacheContextsManager::class);
|
||||
$cache_contexts_manager->method('assertValidTokens')->willReturn(TRUE);
|
||||
$container->set('cache_contexts_manager', $cache_contexts_manager);
|
||||
|
||||
$entityTypeManager = $this->createMock(EntityTypeManager::class);
|
||||
$container->set('entity_type.manager', $entityTypeManager);
|
||||
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
||||
|
@ -86,32 +96,148 @@ class LanguageNegotiationContentEntityTest extends UnitTestCase {
|
|||
* @covers ::getLangcode
|
||||
*/
|
||||
public function testGetLangcode() {
|
||||
$entityTypeManagerMock = $this->getMockBuilder(EntityTypeManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$languageNegotiationContentEntity = new LanguageNegotiationContentEntity($entityTypeManagerMock);
|
||||
$languageNegotiationContentEntity = $this->createLanguageNegotiationPlugin();
|
||||
|
||||
// Case 1: Empty request.
|
||||
$this->assertEquals(NULL, $languageNegotiationContentEntity->getLangcode());
|
||||
|
||||
// Case 2: A request is available, but the languageManager is not set and
|
||||
// the static::QUERY_PARAMETER is not provided as a named parameter.
|
||||
$request = Request::create('/de/foo', 'GET');
|
||||
$request->query = new ParameterBag();
|
||||
$this->assertEquals(NULL, $languageNegotiationContentEntity->getLangcode($request));
|
||||
|
||||
// Case 3: A request is available, the languageManager is set, but the
|
||||
// static::QUERY_PARAMETER is not provided as a named parameter.
|
||||
$languageNegotiationContentEntity->setLanguageManager($this->languageManager);
|
||||
$this->assertEquals(NULL, $languageNegotiationContentEntity->getLangcode($request));
|
||||
|
||||
// Case 4: A request is available, the languageManager is set and the
|
||||
// static::QUERY_PARAMETER is provided as a named parameter.
|
||||
$expectedLangcode = 'de';
|
||||
$request->query->set(LanguageNegotiationContentEntity::QUERY_PARAMETER, $expectedLangcode);
|
||||
$this->assertEquals($expectedLangcode, $languageNegotiationContentEntity->getLangcode($request));
|
||||
|
||||
// Case 5: A request is available, the languageManager is set and the
|
||||
// static::QUERY_PARAMETER is provided as a named parameter with a given
|
||||
// langcode that is not one of the system supported ones.
|
||||
$unknownLangcode = 'xx';
|
||||
$request->query->set(LanguageNegotiationContentEntity::QUERY_PARAMETER, $unknownLangcode);
|
||||
$this->assertNull($languageNegotiationContentEntity->getLangcode($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::processOutbound
|
||||
*/
|
||||
public function testProcessOutbound() {
|
||||
|
||||
// Case 1: Not all processing conditions are met.
|
||||
$languageNegotiationContentEntityMock = $this->createPartialMock($this->getPluginClass(),
|
||||
['hasLowerLanguageNegotiationWeight', 'meetsContentEntityRoutesCondition']);
|
||||
$languageNegotiationContentEntityMock->expects($this->exactly(2))
|
||||
->method('hasLowerLanguageNegotiationWeight')
|
||||
->willReturnOnConsecutiveCalls(
|
||||
FALSE,
|
||||
TRUE
|
||||
);
|
||||
$languageNegotiationContentEntityMock->expects($this->once())
|
||||
->method('meetsContentEntityRoutesCondition')
|
||||
->willReturnOnConsecutiveCalls(
|
||||
FALSE
|
||||
);
|
||||
$options = [];
|
||||
$path = $this->randomMachineName();
|
||||
|
||||
// Case 1a: Empty request.
|
||||
$this->assertEquals($path, $languageNegotiationContentEntityMock->processOutbound($path));
|
||||
$request = Request::create('/foo', 'GET');
|
||||
$request->server = new ServerBag();
|
||||
// Case 1b: Missing the route key in $options.
|
||||
$this->assertEquals($path, $languageNegotiationContentEntityMock->processOutbound($path, $options, $request));
|
||||
$options = ['route' => $this->createMock(Route::class)];
|
||||
// Case 1c: hasLowerLanguageNegotiationWeight() returns FALSE.
|
||||
$this->assertEquals($path, $languageNegotiationContentEntityMock->processOutbound($path, $options, $request));
|
||||
// Case 1d: meetsContentEntityRoutesCondition() returns FALSE.
|
||||
$this->assertEquals($path, $languageNegotiationContentEntityMock->processOutbound($path, $options, $request));
|
||||
|
||||
// Case 2: Cannot figure out the langcode.
|
||||
$languageNegotiationContentEntityMock = $this->createPartialMock($this->getPluginClass(),
|
||||
['hasLowerLanguageNegotiationWeight', 'meetsContentEntityRoutesCondition', 'getLangcode']);
|
||||
$languageNegotiationContentEntityMock->expects($this->any())
|
||||
->method('hasLowerLanguageNegotiationWeight')
|
||||
->will($this->returnValue(TRUE));
|
||||
$languageNegotiationContentEntityMock->expects($this->any())
|
||||
->method('meetsContentEntityRoutesCondition')
|
||||
->will($this->returnValue(TRUE));
|
||||
$languageNegotiationContentEntityMock->expects($this->exactly(2))
|
||||
->method('getLangcode')
|
||||
->willReturnOnConsecutiveCalls(
|
||||
NULL,
|
||||
'de'
|
||||
);
|
||||
$this->assertEquals($path, $languageNegotiationContentEntityMock->processOutbound($path, $options, $request));
|
||||
|
||||
// Case 3: Can figure out the langcode.
|
||||
// Case 3a: via $options['language'].
|
||||
$options['language'] = $this->languages['en'];
|
||||
$options['query'] = NULL;
|
||||
$bubbleableMetadataMock = $this->createMock(BubbleableMetadata::class);
|
||||
$bubbleableMetadataMock->expects($this->exactly(3))
|
||||
->method('addCacheContexts')
|
||||
->with(['url.query_args:' . LanguageNegotiationContentEntity::QUERY_PARAMETER]);
|
||||
$this->assertEquals($path, $languageNegotiationContentEntityMock->processOutbound($path, $options, $request, $bubbleableMetadataMock));
|
||||
$this->assertFalse(isset($options['language']));
|
||||
$this->assertTrue(isset($options['query'][LanguageNegotiationContentEntity::QUERY_PARAMETER]));
|
||||
$this->assertEquals('en', $options['query'][LanguageNegotiationContentEntity::QUERY_PARAMETER]);
|
||||
|
||||
// Case 3a1: via $options['language'] with an additional $options['query'][static::QUERY_PARAMETER].
|
||||
$options['language'] = $this->languages['en'];
|
||||
$options['query'][LanguageNegotiationContentEntity::QUERY_PARAMETER] = 'xx';
|
||||
$this->assertEquals($path, $languageNegotiationContentEntityMock->processOutbound($path, $options, $request, $bubbleableMetadataMock));
|
||||
$this->assertFalse(isset($options['language']));
|
||||
$this->assertEquals('xx', $options['query'][LanguageNegotiationContentEntity::QUERY_PARAMETER]);
|
||||
|
||||
// Case 3b: via getLangcode().
|
||||
unset($options['query'][LanguageNegotiationContentEntity::QUERY_PARAMETER]);
|
||||
$this->assertEquals($path, $languageNegotiationContentEntityMock->processOutbound($path, $options, $request, $bubbleableMetadataMock));
|
||||
$this->assertEquals('de', $options['query'][LanguageNegotiationContentEntity::QUERY_PARAMETER]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getLanguageSwitchLinks
|
||||
*/
|
||||
public function testGetLanguageSwitchLinks() {
|
||||
$languageNegotiationContentEntity = $this->createLanguageNegotiationPlugin();
|
||||
$languageNegotiationContentEntity->setLanguageManager($this->languageManager);
|
||||
|
||||
// Case 1: NULL request object argument.
|
||||
$this->assertNull($languageNegotiationContentEntity->getLangcode());
|
||||
|
||||
// Case 2: A request object is available, but the languageManager is not
|
||||
// set.
|
||||
$request = Request::create('/foo', 'GET');
|
||||
$this->assertNull($languageNegotiationContentEntity->getLangcode($request));
|
||||
|
||||
// Case 3: A request object is available, but static::QUERY_PARAMETER is
|
||||
// set to a non-enabled language.
|
||||
$request = Request::create('/foo', 'GET',
|
||||
[LanguageNegotiationContentEntity::QUERY_PARAMETER => 'it']);
|
||||
$this->assertNull($languageNegotiationContentEntity->getLangcode($request));
|
||||
|
||||
// Case 4: A request object is available and static::QUERY_PARAMETER is
|
||||
// set to an enabled language.
|
||||
$request = Request::create('/foo', 'GET',
|
||||
[LanguageNegotiationContentEntity::QUERY_PARAMETER => 'de']);
|
||||
$this->assertSame('de', $languageNegotiationContentEntity->getLangcode($request));
|
||||
$request = Request::create('/foo', 'GET', ['param1' => 'xyz']);
|
||||
$url = Url::fromUri('base:' . $this->randomMachineName());
|
||||
|
||||
$expectedLanguageSwitchLinksArray = [
|
||||
'de' => [
|
||||
'url' => $url,
|
||||
'title' => $this->languages['de']->getName(),
|
||||
'attributes' => ['class' => ['language-link']],
|
||||
'query' => [
|
||||
LanguageNegotiationContentEntity::QUERY_PARAMETER => 'de',
|
||||
'param1' => 'xyz',
|
||||
],
|
||||
],
|
||||
'en' => [
|
||||
'url' => $url,
|
||||
'title' => $this->languages['en']->getName(),
|
||||
'attributes' => ['class' => ['language-link']],
|
||||
'query' => [
|
||||
LanguageNegotiationContentEntity::QUERY_PARAMETER => 'en',
|
||||
'param1' => 'xyz',
|
||||
],
|
||||
],
|
||||
];
|
||||
$providedLanguageSwitchLinksArray = $languageNegotiationContentEntity->getLanguageSwitchLinks($request, $this->randomMachineName(), $url);
|
||||
$this->assertEquals(
|
||||
$expectedLanguageSwitchLinksArray,
|
||||
$providedLanguageSwitchLinksArray
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\language\Unit\Plugin\LanguageNegotiation;
|
||||
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* Base class used for testing the various LanguageNegotiation plugins.
|
||||
*
|
||||
* @group language
|
||||
*/
|
||||
abstract class LanguageNegotiationTestBase extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Returns the plugin class to use for creating the language negotiation plugin.
|
||||
*
|
||||
* @return string
|
||||
* The plugin class name.
|
||||
*/
|
||||
abstract protected function getPluginClass(): string;
|
||||
|
||||
/**
|
||||
* Creates a @LanguageNegotiation plugin using the factory ::create method.
|
||||
*
|
||||
* @return \Drupal\language\LanguageNegotiationMethodInterface
|
||||
*/
|
||||
protected function createLanguageNegotiationPlugin(array $configuration = [], $plugin_definition = NULL) {
|
||||
$class = $this->getPluginClass();
|
||||
$this->assertTrue(in_array(ContainerFactoryPluginInterface::class, class_implements($class)));
|
||||
return $class::create(\Drupal::getContainer(), $configuration, $class::METHOD_ID, $plugin_definition);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue