1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
<?php
declare(strict_types=1);
namespace Drupal\Tests\language\Kernel;
use Drupal\Core\Language\LanguageInterface;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationContentEntity;
use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\Routing\Route;
/**
* Tests the language of entity URLs.
*
* @group language
*/
class EntityUrlLanguageTest extends LanguageTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['entity_test', 'user'];
/**
* The entity being used for testing.
*
* @var \Drupal\Core\Entity\ContentEntityInterface
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installEntitySchema('entity_test');
$this->installEntitySchema('configurable_language');
// In order to reflect the changes for a multilingual site in the container
// we have to rebuild it.
ConfigurableLanguage::createFromLangcode('es')->save();
ConfigurableLanguage::createFromLangcode('fr')->save();
$config = $this->config('language.negotiation');
$config->set('url.prefixes', ['en' => 'en', 'es' => 'es', 'fr' => 'fr'])
->save();
\Drupal::service('kernel')->rebuildContainer();
$this->createTranslatableEntity();
}
/**
* Ensures that entity URLs in a language have the right language prefix.
*/
public function testEntityUrlLanguage(): void {
$this->assertStringContainsString('/en/entity_test/' . $this->entity->id(), $this->entity->toUrl()->toString());
$this->assertStringContainsString('/es/entity_test/' . $this->entity->id(), $this->entity->getTranslation('es')->toUrl()->toString());
$this->assertStringContainsString('/fr/entity_test/' . $this->entity->id(), $this->entity->getTranslation('fr')->toUrl()->toString());
}
/**
* Ensures correct entity URLs with the method language-content-entity enabled.
*
* Test case with the method language-content-entity enabled and configured
* with higher and also with lower priority than the method language-url.
*/
public function testEntityUrlLanguageWithLanguageContentEnabled(): void {
// Define the method language-content-entity with a higher priority than
// language-url.
$config = $this->config('language.types');
$config->set('configurable', [LanguageInterface::TYPE_INTERFACE, LanguageInterface::TYPE_CONTENT]);
$config->set('negotiation.language_content.enabled', [
LanguageNegotiationContentEntity::METHOD_ID => 0,
LanguageNegotiationUrl::METHOD_ID => 1,
]);
$config->save();
// Without being on a content entity route the default entity URL tests
// should still pass.
$this->testEntityUrlLanguage();
// Now switching to an entity route, so that the URL links are generated
// while being on an entity route.
$this->setCurrentRequestForRoute('/entity_test/{entity_test}', 'entity.entity_test.canonical');
// The method language-content-entity should run before language-url and
// append query parameter for the content language and prevent language-url
// from overwriting the URL.
$this->assertStringContainsString('/en/entity_test/' . $this->entity->id() . '?' . LanguageNegotiationContentEntity::QUERY_PARAMETER . '=en', $this->entity->toUrl('canonical')->toString());
$this->assertStringContainsString('/en/entity_test/' . $this->entity->id() . '?' . LanguageNegotiationContentEntity::QUERY_PARAMETER . '=es', $this->entity->getTranslation('es')->toUrl('canonical')->toString());
$this->assertStringContainsString('/en/entity_test/' . $this->entity->id() . '?' . LanguageNegotiationContentEntity::QUERY_PARAMETER . '=fr', $this->entity->getTranslation('fr')->toUrl('canonical')->toString());
// Define the method language-url with a higher priority than
// language-content-entity. This configuration should match the default one,
// where the language-content-entity is turned off.
$config->set('negotiation.language_content.enabled', [
LanguageNegotiationUrl::METHOD_ID => 0,
LanguageNegotiationContentEntity::METHOD_ID => 1,
]);
$config->save();
// The default entity URL tests should pass again with the current
// configuration.
$this->testEntityUrlLanguage();
}
/**
* Creates a translated entity.
*/
protected function createTranslatableEntity(): void {
$this->entity = EntityTest::create();
$this->entity->addTranslation('es', ['name' => 'name spanish']);
$this->entity->addTranslation('fr', ['name' => 'name french']);
$this->entity->save();
}
/**
* Sets the current request to a specific path with the corresponding route.
*
* @param string $path
* The path for which the current request should be created.
* @param string $route_name
* The route name for which the route object for the request should be
* created.
*/
protected function setCurrentRequestForRoute($path, $route_name): void {
$request = Request::create($path);
$request->attributes->set(RouteObjectInterface::ROUTE_NAME, $route_name);
$request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route($path));
$request->setSession(new Session(new MockArraySessionStorage()));
$this->container->get('request_stack')->push($request);
}
}
|