3 namespace Drupal\Tests\redirect\Unit;
5 use Drupal\Core\Language\Language;
6 use Drupal\redirect\EventSubscriber\RedirectRequestSubscriber;
7 use Drupal\Tests\UnitTestCase;
8 use PHPUnit_Framework_MockObject_MockObject;
9 use Symfony\Component\HttpFoundation\RedirectResponse;
10 use Symfony\Component\HttpFoundation\Request;
11 use Symfony\Component\HttpFoundation\Response;
12 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
13 use Symfony\Component\HttpKernel\Event\PostResponseEvent;
16 * Tests the redirect logic.
20 * @coversDefaultClass Drupal\redirect\EventSubscriber\RedirectRequestSubscriber
22 class RedirectRequestSubscriberTest extends UnitTestCase {
25 * @covers ::onKernelRequestCheckRedirect
27 public function testRedirectLogicWithQueryRetaining() {
30 $request_query = array('key' => 'val');
31 // The query defined by the redirect entity.
32 $redirect_query = array('dummy' => 'value');
33 // The expected final query. This query must contain values defined
34 // by the redirect entity and values from the accessed url.
35 $final_query = $redirect_query + $request_query;
37 $url = $this->getMockBuilder('Drupal\Core\Url')
38 ->disableOriginalConstructor()
41 $url->expects($this->once())
42 ->method('setAbsolute')
46 $url->expects($this->once())
49 ->willReturn($redirect_query);
51 $url->expects($this->once())
53 ->with('query', $final_query);
55 $url->expects($this->once())
57 ->willReturn('/test-path');
59 $redirect = $this->getRedirectStub($url);
60 $event = $this->callOnKernelRequestCheckRedirect($redirect, $request_query, TRUE);
62 $this->assertTrue($event->getResponse() instanceof RedirectResponse);
63 $response = $event->getResponse();
64 $this->assertEquals('/test-path', $response->getTargetUrl());
65 $this->assertEquals(301, $response->getStatusCode());
66 $this->assertEquals(1, $response->headers->get('X-Redirect-ID'));
70 * @covers ::onKernelRequestCheckRedirect
72 public function testRedirectLogicWithoutQueryRetaining() {
75 $request_query = array('key' => 'val');
77 $url = $this->getMockBuilder('Drupal\Core\Url')
78 ->disableOriginalConstructor()
81 $url->expects($this->once())
82 ->method('setAbsolute')
86 // No query retaining, so getOption should not be called.
87 $url->expects($this->never())
88 ->method('getOption');
89 $url->expects($this->never())
90 ->method('setOption');
92 $url->expects($this->once())
94 ->willReturn('/test-path');
96 $redirect = $this->getRedirectStub($url);
97 $event = $this->callOnKernelRequestCheckRedirect($redirect, $request_query, FALSE);
99 $this->assertTrue($event->getResponse() instanceof RedirectResponse);
100 $response = $event->getResponse();
101 $this->assertEquals('/test-path', $response->getTargetUrl());
102 $this->assertEquals(301, $response->getStatusCode());
103 $this->assertEquals(1, $response->headers->get('X-Redirect-ID'));
107 * Instantiates the subscriber and runs onKernelRequestCheckRedirect()
110 * The redirect entity.
111 * @param array $request_query
112 * The query that is supposed to come via request.
113 * @param bool $retain_query
114 * Flag if to retain the query through the redirect.
116 * @return \Symfony\Component\HttpKernel\Event\GetResponseEvent
117 * THe response event.
119 protected function callOnKernelRequestCheckRedirect($redirect, $request_query, $retain_query) {
121 $event = $this->getGetResponseEventStub('non-existing', http_build_query($request_query));
122 $request = $event->getRequest();
124 $checker = $this->getMockBuilder('Drupal\redirect\RedirectChecker')
125 ->disableOriginalConstructor()
127 $checker->expects($this->any())
128 ->method('canRedirect')
129 ->will($this->returnValue(TRUE));
130 $checker->expects($this->any())
132 ->will($this->returnValue(FALSE));
134 $context = $this->getMock('Symfony\Component\Routing\RequestContext');
136 $inbound_path_processor = $this->getMockBuilder('Drupal\Core\PathProcessor\InboundPathProcessorInterface')
137 ->disableOriginalConstructor()
139 $inbound_path_processor->expects($this->any())
140 ->method('processInbound')
141 ->with($request->getPathInfo(), $request)
142 ->will($this->returnValue($request->getPathInfo()));
144 $alias_manager = $this->getMockBuilder('Drupal\Core\Path\AliasManager')
145 ->disableOriginalConstructor()
147 $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandlerInterface')
149 $entity_manager = $this->getMockBuilder('Drupal\Core\Entity\EntityManagerInterface')
152 $subscriber = new RedirectRequestSubscriber(
153 $this->getRedirectRepositoryStub('findMatchingRedirect', $redirect),
154 $this->getLanguageManagerStub(),
155 $this->getConfigFactoryStub(array('redirect.settings' => array('passthrough_querystring' => $retain_query))),
161 $inbound_path_processor
164 // Run the main redirect method.
165 $subscriber->onKernelRequestCheckRedirect($event);
170 * Gets the redirect repository mock object.
173 * Method to mock - either load() or findMatchingRedirect().
175 * The redirect object to be returned.
177 * @return PHPUnit_Framework_MockObject_MockObject
178 * The redirect repository.
180 protected function getRedirectRepositoryStub($method, $redirect) {
181 $repository = $this->getMockBuilder('Drupal\redirect\RedirectRepository')
182 ->disableOriginalConstructor()
185 $repository->expects($this->any())
187 ->will($this->returnValue($redirect));
193 * Gets the redirect mock object.
196 * Url to be returned from getRedirectUrl
197 * @param int $status_code
198 * The redirect status code.
200 * @return PHPUnit_Framework_MockObject_MockObject
201 * The mocked redirect object.
203 protected function getRedirectStub($url, $status_code = 301) {
204 $redirect = $this->getMockBuilder('Drupal\redirect\Entity\Redirect')
205 ->disableOriginalConstructor()
207 $redirect->expects($this->once())
208 ->method('getRedirectUrl')
209 ->will($this->returnValue($url));
210 $redirect->expects($this->any())
211 ->method('getStatusCode')
212 ->will($this->returnValue($status_code));
213 $redirect->expects($this->any())
216 $redirect->expects($this->once())
217 ->method('getCacheTags')
218 ->willReturn(['redirect:1']);
224 * Gets post response event.
226 * @param array $headers
227 * Headers to be set into the response.
229 * @return \Symfony\Component\HttpKernel\Event\PostResponseEvent
230 * The post response event object.
232 protected function getPostResponseEvent($headers = array()) {
233 $http_kernel = $this->getMockBuilder('\Symfony\Component\HttpKernel\HttpKernelInterface')
235 $request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')
236 ->disableOriginalConstructor()
239 $response = new Response('', 301, $headers);
241 return new PostResponseEvent($http_kernel, $request, $response);
245 * Gets response event object.
248 * @param $query_string
250 * @return GetResponseEvent
252 protected function getGetResponseEventStub($path_info, $query_string) {
253 $request = Request::create($path_info . '?' . $query_string, 'GET', [], [], [], ['SCRIPT_NAME' => 'index.php']);
255 $http_kernel = $this->getMockBuilder('\Symfony\Component\HttpKernel\HttpKernelInterface')
257 return new GetResponseEvent($http_kernel, $request, 'test');
261 * Gets the language manager mock object.
263 * @return \Drupal\language\ConfigurableLanguageManagerInterface|PHPUnit_Framework_MockObject_MockObject
265 protected function getLanguageManagerStub() {
266 $language_manager = $this->getMockBuilder('Drupal\language\ConfigurableLanguageManagerInterface')
268 $language_manager->expects($this->any())
269 ->method('getCurrentLanguage')
270 ->will($this->returnValue(new Language(array('id' => 'en'))));
272 return $language_manager;