3 namespace Drupal\Tests\redirect\Kernel;
5 use Drupal\language\Entity\ConfigurableLanguage;
6 use Drupal\redirect\Entity\Redirect;
7 use Drupal\Core\Language\Language;
8 use Drupal\redirect\Exception\RedirectLoopException;
9 use Drupal\KernelTests\KernelTestBase;
12 * Redirect entity and redirect API test coverage.
16 class RedirectAPITest extends KernelTestBase {
19 * @var \Drupal\Core\Entity\EntityStorageInterface
21 protected $controller;
28 public static $modules = array('redirect', 'link', 'field', 'system', 'user', 'language', 'views');
33 public function setUp() {
36 $this->installEntitySchema('redirect');
37 $this->installEntitySchema('user');
38 $this->installSchema('system', ['router']);
39 $this->installConfig(array('redirect'));
41 $language = ConfigurableLanguage::createFromLangcode('de');
44 $this->controller = $this->container->get('entity.manager')->getStorage('redirect');
48 * Test redirect entity logic.
50 public function testRedirectEntity() {
51 // Create a redirect and test if hash has been generated correctly.
52 /** @var \Drupal\redirect\Entity\Redirect $redirect */
53 $redirect = $this->controller->create();
54 $redirect->setSource('some-url', array('key' => 'val'));
55 $redirect->setRedirect('node');
58 $this->assertEquals(Redirect::generateHash('some-url', array('key' => 'val'), Language::LANGCODE_NOT_SPECIFIED), $redirect->getHash());
59 // Update the redirect source query and check if hash has been updated as
61 $redirect->setSource('some-url', array('key1' => 'val1'));
63 $this->assertEqual(Redirect::generateHash('some-url', array('key1' => 'val1'), Language::LANGCODE_NOT_SPECIFIED), $redirect->getHash());
64 // Update the redirect source path and check if hash has been updated as
66 $redirect->setSource('another-url', array('key1' => 'val1'));
68 $this->assertEqual(Redirect::generateHash('another-url', array('key1' => 'val1'), Language::LANGCODE_NOT_SPECIFIED), $redirect->getHash());
69 // Update the redirect language and check if hash has been updated as
71 $redirect->setLanguage('de');
73 $this->assertEqual(Redirect::generateHash('another-url', array('key1' => 'val1'), 'de'), $redirect->getHash());
74 // Create a few more redirects to test the select.
75 for ($i = 0; $i < 5; $i++) {
76 $redirect = $this->controller->create();
77 $redirect->setSource($this->randomMachineName());
80 /** @var \Drupal\redirect\RedirectRepository $repository */
81 $repository = \Drupal::service('redirect.repository');
82 $redirect = $repository->findMatchingRedirect('another-url', array('key1' => 'val1'), 'de');
83 if (!empty($redirect)) {
84 $this->assertEqual($redirect->getSourceUrl(), '/another-url?key1=val1');
87 $this->fail(t('Failed to find matching redirect.'));
90 // Load the redirect based on url.
91 $redirects = $repository->findBySourcePath('another-url');
92 $redirect = array_shift($redirects);
93 if (!empty($redirect)) {
94 $this->assertEqual($redirect->getSourceUrl(), '/another-url?key1=val1');
97 $this->fail(t('Failed to find redirect by source path.'));
100 // Test passthrough_querystring.
101 $redirect = $this->controller->create();
102 $redirect->setSource('a-different-url');
103 $redirect->setRedirect('node');
105 $redirect = $repository->findMatchingRedirect('a-different-url', ['key1' => 'val1'], 'de');
106 if (!empty($redirect)) {
107 $this->assertEqual($redirect->getSourceUrl(), '/a-different-url');
110 $this->fail('Failed to find redirect by source path with query string.');
113 // Add another redirect to the same path, with a query. This should always
114 // be found before the source without a query set.
115 /** @var \Drupal\redirect\Entity\Redirect $new_redirect */
116 $new_redirect = $this->controller->create();
117 $new_redirect->setSource('a-different-url', ['foo' => 'bar']);
118 $new_redirect->setRedirect('node');
119 $new_redirect->save();
120 $found = $repository->findMatchingRedirect('a-different-url', ['foo' => 'bar'], 'de');
121 if (!empty($found)) {
122 $this->assertEqual($found->getSourceUrl(), '/a-different-url?foo=bar');
125 $this->fail('Failed to find a redirect by source path with query string.');
128 // Hashes should be case-insensitive since the source paths are.
129 /** @var \Drupal\redirect\Entity\Redirect $redirect */
130 $redirect = $this->controller->create();
131 $redirect->setSource('Case-Sensitive-Path');
132 $redirect->setRedirect('node');
134 $found = $repository->findBySourcePath('case-sensitive-path');
135 if (!empty($found)) {
136 $found = reset($found);
137 $this->assertEqual($found->getSourceUrl(), '/Case-Sensitive-Path');
140 $this->fail('findBySourcePath is case sensitive');
142 $found = $repository->findMatchingRedirect('case-sensitive-path');
143 if (!empty($found)) {
144 $this->assertEqual($found->getSourceUrl(), '/Case-Sensitive-Path');
147 $this->fail('findMatchingRedirect is case sensitive.');
152 * Test redirect_sort_recursive().
154 public function testSortRecursive() {
157 'input' => array('b' => 'aa', 'c' => array('c2' => 'aa', 'c1' => 'aa'), 'a' => 'aa'),
158 'expected' => array('a' => 'aa', 'b' => 'aa', 'c' => array('c1' => 'aa', 'c2' => 'aa')),
159 'callback' => 'ksort',
162 foreach ($test_cases as $index => $test_case) {
163 $output = $test_case['input'];
164 redirect_sort_recursive($output, $test_case['callback']);
165 $this->assertIdentical($output, $test_case['expected']);
170 * Test loop detection.
172 public function testLoopDetection() {
173 // Add a chained redirect that isn't a loop.
174 /** @var \Drupal\redirect\Entity\Redirect $one */
175 $one = $this->controller->create();
176 $one->setSource('my-path');
177 $one->setRedirect('node');
179 /** @var \Drupal\redirect\Entity\Redirect $two */
180 $two = $this->controller->create();
181 $two->setSource('second-path');
182 $two->setRedirect('my-path');
184 /** @var \Drupal\redirect\Entity\Redirect $three */
185 $three = $this->controller->create();
186 $three->setSource('third-path');
187 $three->setRedirect('second-path');
190 /** @var \Drupal\redirect\RedirectRepository $repository */
191 $repository = \Drupal::service('redirect.repository');
192 $found = $repository->findMatchingRedirect('third-path');
193 if (!empty($found)) {
194 $this->assertEqual($found->getRedirectUrl()->toString(), '/node', 'Chained redirects properly resolved in findMatchingRedirect.');
197 $this->fail('Failed to resolve a chained redirect.');
201 $one->setRedirect('third-path');
204 $repository->findMatchingRedirect('third-path');
205 $this->fail('Failed to detect a redirect loop.');
207 catch (RedirectLoopException $e) {
208 $this->pass('Properly detected a redirect loop.');
213 * Test redirect_parse_url().
215 public function testParseURL() {
216 //$test_cases = array(
218 // 'input' => array('b' => 'aa', 'c' => array('c2' => 'aa', 'c1' => 'aa'), 'a' => 'aa'),
219 // 'expected' => array('a' => 'aa', 'b' => 'aa', 'c' => array('c1' => 'aa', 'c2' => 'aa')),
222 //foreach ($test_cases as $index => $test_case) {
223 // $output = redirect_parse_url($test_case['input']);
224 // $this->assertIdentical($output, $test_case['expected']);
229 * Test multilingual redirects.
231 public function testMultilanguageCases() {
232 // Add a redirect for english.
233 /** @var \Drupal\redirect\Entity\Redirect $en_redirect */
234 $en_redirect = $this->controller->create();
235 $en_redirect->setSource('langpath');
236 $en_redirect->setRedirect('/about');
237 $en_redirect->setLanguage('en');
238 $en_redirect->save();
240 // Add a redirect for germany.
241 /** @var \Drupal\redirect\Entity\Redirect $en_redirect */
242 $en_redirect = $this->controller->create();
243 $en_redirect->setSource('langpath');
244 $en_redirect->setRedirect('node');
245 $en_redirect->setLanguage('de');
246 $en_redirect->save();
248 // Check redirect for english.
249 /** @var \Drupal\redirect\RedirectRepository $repository */
250 $repository = \Drupal::service('redirect.repository');
252 $found = $repository->findBySourcePath('langpath');
253 if (!empty($found)) {
254 $this->assertEqual($found[1]->getRedirectUrl()->toString(), '/about', 'Multilingual redirect resolved properly.');
255 $this->assertEqual($found[1]->get('language')[0]->value, 'en', 'Multilingual redirect resolved properly.');
258 $this->fail('Failed to resolve the multilingual redirect.');
261 // Check redirect for germany.
262 \Drupal::configFactory()->getEditable('system.site')->set('default_langcode', 'de')->save();
263 /** @var \Drupal\redirect\RedirectRepository $repository */
264 $repository = \Drupal::service('redirect.repository');
265 $found = $repository->findBySourcePath('langpath');
266 if (!empty($found)) {
267 $this->assertEqual($found[2]->getRedirectUrl()->toString(), '/node', 'Multilingual redirect resolved properly.');
268 $this->assertEqual($found[2]->get('language')[0]->value, 'de', 'Multilingual redirect resolved properly.');
271 $this->fail('Failed to resolve the multilingual redirect.');