View source
<?php
namespace Drupal\Tests\redirect\Kernel;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\redirect\Entity\Redirect;
use Drupal\Core\Language\Language;
use Drupal\redirect\Exception\RedirectLoopException;
use Drupal\KernelTests\KernelTestBase;
class RedirectAPITest extends KernelTestBase {
protected $storage;
public static $modules = [
'redirect',
'link',
'field',
'system',
'user',
'language',
'views',
'path_alias',
];
public function setUp() {
parent::setUp();
$this
->installEntitySchema('redirect');
$this
->installEntitySchema('user');
$this
->installConfig([
'redirect',
]);
$language = ConfigurableLanguage::createFromLangcode('de');
$language
->save();
$this->storage = $this->container
->get('entity_type.manager')
->getStorage('redirect');
}
public function testRedirectEntity() {
$redirect = $this->storage
->create();
$redirect
->setSource('some-url', [
'key' => 'val',
]);
$redirect
->setRedirect('node');
$redirect
->save();
$this
->assertEquals(Redirect::generateHash('some-url', [
'key' => 'val',
], Language::LANGCODE_NOT_SPECIFIED), $redirect
->getHash());
$redirect
->setSource('some-url', [
'key1' => 'val1',
]);
$redirect
->save();
$this
->assertEquals(Redirect::generateHash('some-url', [
'key1' => 'val1',
], Language::LANGCODE_NOT_SPECIFIED), $redirect
->getHash());
$redirect
->setSource('another-url', [
'key1' => 'val1',
]);
$redirect
->save();
$this
->assertEquals(Redirect::generateHash('another-url', [
'key1' => 'val1',
], Language::LANGCODE_NOT_SPECIFIED), $redirect
->getHash());
$redirect
->setLanguage('de');
$redirect
->save();
$this
->assertEquals(Redirect::generateHash('another-url', [
'key1' => 'val1',
], 'de'), $redirect
->getHash());
for ($i = 0; $i < 5; $i++) {
$redirect = $this->storage
->create();
$redirect
->setSource($this
->randomMachineName());
$redirect
->save();
}
$repository = \Drupal::service('redirect.repository');
$redirect = $repository
->findMatchingRedirect('another-url', [
'key1' => 'val1',
], 'de');
if (!empty($redirect)) {
$this
->assertEquals($redirect
->getSourceUrl(), '/another-url?key1=val1');
}
else {
$this
->fail(t('Failed to find matching redirect.'));
}
$redirects = $repository
->findBySourcePath('another-url');
$redirect = array_shift($redirects);
if (!empty($redirect)) {
$this
->assertEquals($redirect
->getSourceUrl(), '/another-url?key1=val1');
}
else {
$this
->fail(t('Failed to find redirect by source path.'));
}
$redirect = $this->storage
->create();
$redirect
->setSource('a-different-url');
$redirect
->setRedirect('node');
$redirect
->save();
$redirect = $repository
->findMatchingRedirect('a-different-url', [
'key1' => 'val1',
], 'de');
if (!empty($redirect)) {
$this
->assertEquals($redirect
->getSourceUrl(), '/a-different-url');
}
else {
$this
->fail('Failed to find redirect by source path with query string.');
}
$new_redirect = $this->storage
->create();
$new_redirect
->setSource('a-different-url', [
'foo' => 'bar',
]);
$new_redirect
->setRedirect('node');
$new_redirect
->save();
$found = $repository
->findMatchingRedirect('a-different-url', [
'foo' => 'bar',
], 'de');
if (!empty($found)) {
$this
->assertEquals($found
->getSourceUrl(), '/a-different-url?foo=bar');
}
else {
$this
->fail('Failed to find a redirect by source path with query string.');
}
$external_redirect = $this->storage
->create();
$external_redirect
->setSource('google');
$external_redirect
->setRedirect('https://google.com');
$external_redirect
->save();
$found = $repository
->findMatchingRedirect('google');
if (!empty($found)) {
$this
->assertEquals($found
->getRedirectUrl()
->toString(), 'https://google.com');
}
else {
$this
->fail('Failed to find a redirect for google.');
}
$redirect = $this->storage
->create();
$redirect
->setSource('Case-Sensitive-Path');
$redirect
->setRedirect('node');
$redirect
->save();
$found = $repository
->findBySourcePath('case-sensitive-path');
if (!empty($found)) {
$found = reset($found);
$this
->assertEquals($found
->getSourceUrl(), '/Case-Sensitive-Path');
}
else {
$this
->fail('findBySourcePath is case sensitive');
}
$found = $repository
->findMatchingRedirect('case-sensitive-path');
if (!empty($found)) {
$this
->assertEquals($found
->getSourceUrl(), '/Case-Sensitive-Path');
}
else {
$this
->fail('findMatchingRedirect is case sensitive.');
}
}
public function testDuplicateRedirectEntry() {
$redirect = $this->storage
->create();
$redirect
->setSource('/foo/foo', []);
$redirect
->setRedirect('foo');
$redirect
->save();
$redirect_repository = \Drupal::service('redirect.repository');
$matched_redirect = $redirect_repository
->findMatchingRedirect('/foo/foo', [], 'en-AU');
$this
->assertNotNull($matched_redirect);
$null_redirect = $redirect_repository
->findMatchingRedirect('/foo/foo-bar', [], 'en-AU');
$this
->assertNull($null_redirect);
}
public function testSortRecursive() {
$test_cases = [
[
'input' => [
'b' => 'aa',
'c' => [
'c2' => 'aa',
'c1' => 'aa',
],
'a' => 'aa',
],
'expected' => [
'a' => 'aa',
'b' => 'aa',
'c' => [
'c1' => 'aa',
'c2' => 'aa',
],
],
'callback' => 'ksort',
],
];
foreach ($test_cases as $index => $test_case) {
$output = $test_case['input'];
redirect_sort_recursive($output, $test_case['callback']);
$this
->assertIdentical($output, $test_case['expected']);
}
}
public function testLoopDetection() {
$one = $this->storage
->create();
$one
->setSource('my-path');
$one
->setRedirect('node');
$one
->save();
$two = $this->storage
->create();
$two
->setSource('second-path');
$two
->setRedirect('my-path');
$two
->save();
$three = $this->storage
->create();
$three
->setSource('third-path');
$three
->setRedirect('second-path');
$three
->save();
$repository = \Drupal::service('redirect.repository');
$found = $repository
->findMatchingRedirect('third-path');
if (!empty($found)) {
$this
->assertEquals($found
->getRedirectUrl()
->toString(), '/node', 'Chained redirects properly resolved in findMatchingRedirect.');
}
else {
$this
->fail('Failed to resolve a chained redirect.');
}
$one
->setRedirect('third-path');
$one
->save();
try {
$repository
->findMatchingRedirect('third-path');
$this
->fail('Failed to detect a redirect loop.');
} catch (RedirectLoopException $e) {
$this
->pass('Properly detected a redirect loop.');
}
}
public function testLoopDetectionReset() {
$source = $this->storage
->create();
$source
->setSource('source-redirect');
$source
->setRedirect('target');
$source
->save();
$target = $this->storage
->create();
$target
->setSource('target');
$target
->setRedirect('second-target');
$target
->save();
$repository = \Drupal::service('redirect.repository');
$found = $repository
->findMatchingRedirect('target');
$this
->assertEquals($target
->id(), $found
->id());
$found = $repository
->findMatchingRedirect('source-redirect');
$this
->assertEquals($target
->id(), $found
->id());
}
public function testParseURL() {
}
public function testMultilanguageCases() {
$en_redirect = $this->storage
->create();
$en_redirect
->setSource('langpath');
$en_redirect
->setRedirect('/about');
$en_redirect
->setLanguage('en');
$en_redirect
->save();
$en_redirect = $this->storage
->create();
$en_redirect
->setSource('langpath');
$en_redirect
->setRedirect('node');
$en_redirect
->setLanguage('de');
$en_redirect
->save();
$repository = \Drupal::service('redirect.repository');
$found = $repository
->findBySourcePath('langpath');
if (!empty($found)) {
$this
->assertEquals($found[1]
->getRedirectUrl()
->toString(), '/about', 'Multilingual redirect resolved properly.');
$this
->assertEquals($found[1]
->get('language')[0]->value, 'en', 'Multilingual redirect resolved properly.');
}
else {
$this
->fail('Failed to resolve the multilingual redirect.');
}
\Drupal::configFactory()
->getEditable('system.site')
->set('default_langcode', 'de')
->save();
$repository = \Drupal::service('redirect.repository');
$found = $repository
->findBySourcePath('langpath');
if (!empty($found)) {
$this
->assertEquals($found[2]
->getRedirectUrl()
->toString(), '/node', 'Multilingual redirect resolved properly.');
$this
->assertEquals($found[2]
->get('language')[0]->value, 'de', 'Multilingual redirect resolved properly.');
}
else {
$this
->fail('Failed to resolve the multilingual redirect.');
}
}
}