View source
<?php
namespace Drupal\Tests\redirect\Unit;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\Language;
use Drupal\path_alias\AliasManagerInterface;
use Drupal\redirect\EventSubscriber\RedirectRequestSubscriber;
use Drupal\Tests\UnitTestCase;
use PHPUnit_Framework_MockObject_MockObject;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class RedirectRequestSubscriberTest extends UnitTestCase {
public function testRedirectLogicWithQueryRetaining($request_uri, $request_query, $redirect_uri, $redirect_query) {
$final_query = $redirect_query + $request_query;
$url = $this
->getMockBuilder('Drupal\\Core\\Url')
->disableOriginalConstructor()
->getMock();
$url
->expects($this
->once())
->method('setAbsolute')
->with(TRUE)
->willReturn($url);
$url
->expects($this
->once())
->method('getOption')
->with('query')
->willReturn($redirect_query);
$url
->expects($this
->once())
->method('setOption')
->with('query', $final_query);
$url
->expects($this
->once())
->method('toString')
->willReturn($redirect_uri);
$redirect = $this
->getRedirectStub($url);
$event = $this
->callOnKernelRequestCheckRedirect($redirect, $request_uri, $request_query, TRUE);
$this
->assertTrue($event
->getResponse() instanceof RedirectResponse);
$response = $event
->getResponse();
$this
->assertEquals('/test-path', $response
->getTargetUrl());
$this
->assertEquals(301, $response
->getStatusCode());
$this
->assertEquals(1, $response->headers
->get('X-Redirect-ID'));
}
public function testRedirectLogicWithoutQueryRetaining($request_uri, $request_query, $redirect_uri) {
$url = $this
->getMockBuilder('Drupal\\Core\\Url')
->disableOriginalConstructor()
->getMock();
$url
->expects($this
->once())
->method('setAbsolute')
->with(TRUE)
->willReturn($url);
$url
->expects($this
->never())
->method('getOption');
$url
->expects($this
->never())
->method('setOption');
$url
->expects($this
->once())
->method('toString')
->willReturn($redirect_uri);
$redirect = $this
->getRedirectStub($url);
$event = $this
->callOnKernelRequestCheckRedirect($redirect, $request_uri, $request_query, FALSE);
$this
->assertTrue($event
->getResponse() instanceof RedirectResponse);
$response = $event
->getResponse();
$this
->assertEquals($redirect_uri, $response
->getTargetUrl());
$this
->assertEquals(301, $response
->getStatusCode());
$this
->assertEquals(1, $response->headers
->get('X-Redirect-ID'));
}
public function getRedirectData() {
return [
[
'non-existing',
[
'key' => 'val',
],
'/test-path',
[
'dummy' => 'value',
],
],
[
'non-existing/',
[
'key' => 'val',
],
'/test-path',
[
'dummy' => 'value',
],
],
[
'system/files/file.txt',
[],
'/test-path',
[],
],
];
}
protected function callOnKernelRequestCheckRedirect($redirect, $request_uri, $request_query, $retain_query) {
$event = $this
->getGetResponseEventStub($request_uri, http_build_query($request_query));
$request = $event
->getRequest();
$checker = $this
->getMockBuilder('Drupal\\redirect\\RedirectChecker')
->disableOriginalConstructor()
->getMock();
$checker
->expects($this
->any())
->method('canRedirect')
->will($this
->returnValue(TRUE));
$context = $this
->createMock('Symfony\\Component\\Routing\\RequestContext');
$inbound_path_processor = $this
->getMockBuilder('Drupal\\Core\\PathProcessor\\InboundPathProcessorInterface')
->disableOriginalConstructor()
->getMock();
$inbound_path_processor
->expects($this
->any())
->method('processInbound')
->with($request
->getPathInfo(), $request)
->willReturnCallback(function ($path, Request $request) {
if (strpos($path, '/system/files/') === 0 && !$request->query
->has('file')) {
$path = '/system/files';
}
return $path;
});
$alias_manager = $this
->createMock(AliasManagerInterface::class);
$module_handler = $this
->createMock(ModuleHandlerInterface::class);
$entity_type_manager = $this
->createMock(EntityTypeManagerInterface::class);
$subscriber = new RedirectRequestSubscriber($this
->getRedirectRepositoryStub('findMatchingRedirect', $redirect), $this
->getLanguageManagerStub(), $this
->getConfigFactoryStub([
'redirect.settings' => [
'passthrough_querystring' => $retain_query,
],
]), $alias_manager, $module_handler, $entity_type_manager, $checker, $context, $inbound_path_processor);
$subscriber
->onKernelRequestCheckRedirect($event);
return $event;
}
protected function getRedirectRepositoryStub($method, $redirect) {
$repository = $this
->getMockBuilder('Drupal\\redirect\\RedirectRepository')
->disableOriginalConstructor()
->getMock();
if ($method === 'findMatchingRedirect') {
$repository
->expects($this
->any())
->method($method)
->willReturnCallback(function ($source_path) use ($redirect) {
return $source_path === 'system/files' ? NULL : $redirect;
});
}
else {
$repository
->expects($this
->any())
->method($method)
->will($this
->returnValue($redirect));
}
return $repository;
}
protected function getRedirectStub($url, $status_code = 301) {
$redirect = $this
->getMockBuilder('Drupal\\redirect\\Entity\\Redirect')
->disableOriginalConstructor()
->getMock();
$redirect
->expects($this
->once())
->method('getRedirectUrl')
->will($this
->returnValue($url));
$redirect
->expects($this
->any())
->method('getStatusCode')
->will($this
->returnValue($status_code));
$redirect
->expects($this
->any())
->method('id')
->willReturn(1);
$redirect
->expects($this
->once())
->method('getCacheTags')
->willReturn([
'redirect:1',
]);
return $redirect;
}
protected function getPostResponseEvent($headers = []) {
$http_kernel = $this
->getMockBuilder('\\Symfony\\Component\\HttpKernel\\HttpKernelInterface')
->getMock();
$request = $this
->getMockBuilder('Symfony\\Component\\HttpFoundation\\Request')
->disableOriginalConstructor()
->getMock();
$response = new Response('', 301, $headers);
return new PostResponseEvent($http_kernel, $request, $response);
}
protected function getGetResponseEventStub($path_info, $query_string) {
$request = Request::create($path_info . '?' . $query_string, 'GET', [], [], [], [
'SCRIPT_NAME' => 'index.php',
]);
$http_kernel = $this
->getMockBuilder('\\Symfony\\Component\\HttpKernel\\HttpKernelInterface')
->getMock();
return new GetResponseEvent($http_kernel, $request, HttpKernelInterface::MASTER_REQUEST);
}
protected function getLanguageManagerStub() {
$language_manager = $this
->getMockBuilder('Drupal\\language\\ConfigurableLanguageManagerInterface')
->getMock();
$language_manager
->expects($this
->any())
->method('getCurrentLanguage')
->will($this
->returnValue(new Language([
'id' => 'en',
])));
return $language_manager;
}
}