6b161cf044219ade130e0390783f74359f9680d8
[yaffs-website] / web / modules / contrib / redirect / tests / src / Unit / RedirectRequestSubscriberTest.php
1 <?php
2
3 namespace Drupal\Tests\redirect\Unit;
4
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;
14
15 /**
16  * Tests the redirect logic.
17  *
18  * @group redirect
19  *
20  * @coversDefaultClass Drupal\redirect\EventSubscriber\RedirectRequestSubscriber
21  */
22 class RedirectRequestSubscriberTest extends UnitTestCase {
23
24   /**
25    * @covers ::onKernelRequestCheckRedirect
26    */
27   public function testRedirectLogicWithQueryRetaining() {
28
29     // The request query.
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;
36
37     $url = $this->getMockBuilder('Drupal\Core\Url')
38       ->disableOriginalConstructor()
39       ->getMock();
40
41     $url->expects($this->once())
42       ->method('setAbsolute')
43       ->with(TRUE)
44       ->willReturn($url);
45
46     $url->expects($this->once())
47       ->method('getOption')
48       ->with('query')
49       ->willReturn($redirect_query);
50
51     $url->expects($this->once())
52       ->method('setOption')
53       ->with('query', $final_query);
54
55     $url->expects($this->once())
56       ->method('toString')
57       ->willReturn('/test-path');
58
59     $redirect = $this->getRedirectStub($url);
60     $event = $this->callOnKernelRequestCheckRedirect($redirect, $request_query, TRUE);
61
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'));
67   }
68
69   /**
70    * @covers ::onKernelRequestCheckRedirect
71    */
72   public function testRedirectLogicWithoutQueryRetaining() {
73
74     // The request query.
75     $request_query = array('key' => 'val');
76
77     $url = $this->getMockBuilder('Drupal\Core\Url')
78       ->disableOriginalConstructor()
79       ->getMock();
80
81     $url->expects($this->once())
82       ->method('setAbsolute')
83       ->with(TRUE)
84       ->willReturn($url);
85
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');
91
92     $url->expects($this->once())
93       ->method('toString')
94       ->willReturn('/test-path');
95
96     $redirect = $this->getRedirectStub($url);
97     $event = $this->callOnKernelRequestCheckRedirect($redirect, $request_query, FALSE);
98
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'));
104   }
105
106   /**
107    * Instantiates the subscriber and runs onKernelRequestCheckRedirect()
108    *
109    * @param $redirect
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.
115    *
116    * @return \Symfony\Component\HttpKernel\Event\GetResponseEvent
117    *   THe response event.
118    */
119   protected function callOnKernelRequestCheckRedirect($redirect, $request_query, $retain_query) {
120
121     $event = $this->getGetResponseEventStub('non-existing', http_build_query($request_query));
122     $request = $event->getRequest();
123
124     $checker = $this->getMockBuilder('Drupal\redirect\RedirectChecker')
125       ->disableOriginalConstructor()
126       ->getMock();
127     $checker->expects($this->any())
128       ->method('canRedirect')
129       ->will($this->returnValue(TRUE));
130     $checker->expects($this->any())
131       ->method('isLoop')
132       ->will($this->returnValue(FALSE));
133
134     $context = $this->getMock('Symfony\Component\Routing\RequestContext');
135
136     $inbound_path_processor = $this->getMockBuilder('Drupal\Core\PathProcessor\InboundPathProcessorInterface')
137       ->disableOriginalConstructor()
138       ->getMock();
139     $inbound_path_processor->expects($this->any())
140       ->method('processInbound')
141       ->with($request->getPathInfo(), $request)
142       ->will($this->returnValue($request->getPathInfo()));
143
144     $alias_manager = $this->getMockBuilder('Drupal\Core\Path\AliasManager')
145       ->disableOriginalConstructor()
146       ->getMock();
147     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandlerInterface')
148       ->getMock();
149     $entity_manager = $this->getMockBuilder('Drupal\Core\Entity\EntityManagerInterface')
150       ->getMock();
151
152     $subscriber = new RedirectRequestSubscriber(
153       $this->getRedirectRepositoryStub('findMatchingRedirect', $redirect),
154       $this->getLanguageManagerStub(),
155       $this->getConfigFactoryStub(array('redirect.settings' => array('passthrough_querystring' => $retain_query))),
156       $alias_manager,
157       $module_handler,
158       $entity_manager,
159       $checker,
160       $context,
161       $inbound_path_processor
162     );
163
164     // Run the main redirect method.
165     $subscriber->onKernelRequestCheckRedirect($event);
166     return $event;
167   }
168
169   /**
170    * Gets the redirect repository mock object.
171    *
172    * @param $method
173    *   Method to mock - either load() or findMatchingRedirect().
174    * @param $redirect
175    *   The redirect object to be returned.
176    *
177    * @return PHPUnit_Framework_MockObject_MockObject
178    *   The redirect repository.
179    */
180   protected function getRedirectRepositoryStub($method, $redirect) {
181     $repository = $this->getMockBuilder('Drupal\redirect\RedirectRepository')
182       ->disableOriginalConstructor()
183       ->getMock();
184
185     $repository->expects($this->any())
186       ->method($method)
187       ->will($this->returnValue($redirect));
188
189     return $repository;
190   }
191
192   /**
193    * Gets the redirect mock object.
194    *
195    * @param $url
196    *   Url to be returned from getRedirectUrl
197    * @param int $status_code
198    *   The redirect status code.
199    *
200    * @return PHPUnit_Framework_MockObject_MockObject
201    *   The mocked redirect object.
202    */
203   protected function getRedirectStub($url, $status_code = 301) {
204     $redirect = $this->getMockBuilder('Drupal\redirect\Entity\Redirect')
205       ->disableOriginalConstructor()
206       ->getMock();
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())
214       ->method('id')
215       ->willReturn(1);
216     $redirect->expects($this->once())
217       ->method('getCacheTags')
218       ->willReturn(['redirect:1']);
219
220     return $redirect;
221   }
222
223   /**
224    * Gets post response event.
225    *
226    * @param array $headers
227    *   Headers to be set into the response.
228    *
229    * @return \Symfony\Component\HttpKernel\Event\PostResponseEvent
230    *   The post response event object.
231    */
232   protected function getPostResponseEvent($headers = array()) {
233     $http_kernel = $this->getMockBuilder('\Symfony\Component\HttpKernel\HttpKernelInterface')
234       ->getMock();
235     $request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')
236       ->disableOriginalConstructor()
237       ->getMock();
238
239     $response = new Response('', 301, $headers);
240
241     return new PostResponseEvent($http_kernel, $request, $response);
242   }
243
244   /**
245    * Gets response event object.
246    *
247    * @param $path_info
248    * @param $query_string
249    *
250    * @return GetResponseEvent
251    */
252   protected function getGetResponseEventStub($path_info, $query_string) {
253     $request = Request::create($path_info . '?' . $query_string, 'GET', [], [], [], ['SCRIPT_NAME' => 'index.php']);
254
255     $http_kernel = $this->getMockBuilder('\Symfony\Component\HttpKernel\HttpKernelInterface')
256       ->getMock();
257     return new GetResponseEvent($http_kernel, $request, 'test');
258   }
259
260   /**
261    * Gets the language manager mock object.
262    *
263    * @return \Drupal\language\ConfigurableLanguageManagerInterface|PHPUnit_Framework_MockObject_MockObject
264    */
265   protected function getLanguageManagerStub() {
266     $language_manager = $this->getMockBuilder('Drupal\language\ConfigurableLanguageManagerInterface')
267       ->getMock();
268     $language_manager->expects($this->any())
269       ->method('getCurrentLanguage')
270       ->will($this->returnValue(new Language(array('id' => 'en'))));
271
272     return $language_manager;
273   }
274
275 }