Version 1
[yaffs-website] / web / modules / contrib / redirect / tests / src / Kernel / RedirectAPITest.php
1 <?php
2
3 namespace Drupal\Tests\redirect\Kernel;
4
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;
10
11 /**
12  * Redirect entity and redirect API test coverage.
13  *
14  * @group redirect
15  */
16 class RedirectAPITest extends KernelTestBase {
17
18   /**
19    * @var \Drupal\Core\Entity\EntityStorageInterface
20    */
21   protected $controller;
22
23   /**
24    * Modules to enable.
25    *
26    * @var array
27    */
28   public static $modules = array('redirect', 'link', 'field', 'system', 'user', 'language', 'views');
29
30   /**
31    * {@inheritdoc}
32    */
33   public function setUp() {
34     parent::setUp();
35
36     $this->installEntitySchema('redirect');
37     $this->installEntitySchema('user');
38     $this->installSchema('system', ['router']);
39     $this->installConfig(array('redirect'));
40
41     $language = ConfigurableLanguage::createFromLangcode('de');
42     $language->save();
43
44     $this->controller = $this->container->get('entity.manager')->getStorage('redirect');
45   }
46
47   /**
48    * Test redirect entity logic.
49    */
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');
56
57     $redirect->save();
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
60     // expected.
61     $redirect->setSource('some-url', array('key1' => 'val1'));
62     $redirect->save();
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
65     // expected.
66     $redirect->setSource('another-url', array('key1' => 'val1'));
67     $redirect->save();
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
70     // expected.
71     $redirect->setLanguage('de');
72     $redirect->save();
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());
78       $redirect->save();
79     }
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');
85     }
86     else {
87       $this->fail(t('Failed to find matching redirect.'));
88     }
89
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');
95     }
96     else {
97       $this->fail(t('Failed to find redirect by source path.'));
98     }
99
100     // Test passthrough_querystring.
101     $redirect = $this->controller->create();
102     $redirect->setSource('a-different-url');
103     $redirect->setRedirect('node');
104     $redirect->save();
105     $redirect = $repository->findMatchingRedirect('a-different-url', ['key1' => 'val1'], 'de');
106     if (!empty($redirect)) {
107       $this->assertEqual($redirect->getSourceUrl(), '/a-different-url');
108     }
109     else {
110       $this->fail('Failed to find redirect by source path with query string.');
111     }
112
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');
123     }
124     else {
125       $this->fail('Failed to find a redirect by source path with query string.');
126     }
127
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');
133     $redirect->save();
134     $found = $repository->findBySourcePath('case-sensitive-path');
135     if (!empty($found)) {
136       $found = reset($found);
137       $this->assertEqual($found->getSourceUrl(), '/Case-Sensitive-Path');
138     }
139     else {
140       $this->fail('findBySourcePath is case sensitive');
141     }
142     $found = $repository->findMatchingRedirect('case-sensitive-path');
143     if (!empty($found)) {
144       $this->assertEqual($found->getSourceUrl(), '/Case-Sensitive-Path');
145     }
146     else {
147       $this->fail('findMatchingRedirect is case sensitive.');
148     }
149   }
150
151   /**
152    * Test redirect_sort_recursive().
153    */
154   public function testSortRecursive() {
155     $test_cases = array(
156       array(
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',
160       ),
161     );
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']);
166     }
167   }
168
169   /**
170    * Test loop detection.
171    */
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');
178     $one->save();
179     /** @var \Drupal\redirect\Entity\Redirect $two */
180     $two = $this->controller->create();
181     $two->setSource('second-path');
182     $two->setRedirect('my-path');
183     $two->save();
184     /** @var \Drupal\redirect\Entity\Redirect $three */
185     $three = $this->controller->create();
186     $three->setSource('third-path');
187     $three->setRedirect('second-path');
188     $three->save();
189
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.');
195     }
196     else {
197       $this->fail('Failed to resolve a chained redirect.');
198     }
199
200     // Create a loop.
201     $one->setRedirect('third-path');
202     $one->save();
203     try {
204       $repository->findMatchingRedirect('third-path');
205       $this->fail('Failed to detect a redirect loop.');
206     }
207     catch (RedirectLoopException $e) {
208       $this->pass('Properly detected a redirect loop.');
209     }
210   }
211
212   /**
213    * Test redirect_parse_url().
214    */
215   public function testParseURL() {
216     //$test_cases = array(
217     //  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')),
220     //  ),
221     //);
222     //foreach ($test_cases as $index => $test_case) {
223     //  $output = redirect_parse_url($test_case['input']);
224     //  $this->assertIdentical($output, $test_case['expected']);
225     //}
226   }
227
228   /**
229    * Test multilingual redirects.
230    */
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();
239
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();
247
248     // Check redirect for english.
249     /** @var \Drupal\redirect\RedirectRepository $repository */
250     $repository = \Drupal::service('redirect.repository');
251
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.');
256     }
257     else {
258       $this->fail('Failed to resolve the multilingual redirect.');
259     }
260
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.');
269     }
270     else {
271       $this->fail('Failed to resolve the multilingual redirect.');
272     }
273   }
274
275 }