Updated to Drupal 8.5. Core Media not yet in use.
[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    * @dataProvider getRedirectData
27    */
28   public function testRedirectLogicWithQueryRetaining($request_uri, $request_query, $redirect_uri, $redirect_query) {
29
30     // The expected final query. This query must contain values defined
31     // by the redirect entity and values from the accessed url.
32     $final_query = $redirect_query + $request_query;
33
34     $url = $this->getMockBuilder('Drupal\Core\Url')
35       ->disableOriginalConstructor()
36       ->getMock();
37
38     $url->expects($this->once())
39       ->method('setAbsolute')
40       ->with(TRUE)
41       ->willReturn($url);
42
43     $url->expects($this->once())
44       ->method('getOption')
45       ->with('query')
46       ->willReturn($redirect_query);
47
48     $url->expects($this->once())
49       ->method('setOption')
50       ->with('query', $final_query);
51
52     $url->expects($this->once())
53       ->method('toString')
54       ->willReturn($redirect_uri);
55
56     $redirect = $this->getRedirectStub($url);
57     $event = $this->callOnKernelRequestCheckRedirect($redirect, $request_uri, $request_query, TRUE);
58
59     $this->assertTrue($event->getResponse() instanceof RedirectResponse);
60     $response = $event->getResponse();
61     $this->assertEquals('/test-path', $response->getTargetUrl());
62     $this->assertEquals(301, $response->getStatusCode());
63     $this->assertEquals(1, $response->headers->get('X-Redirect-ID'));
64   }
65
66   /**
67    * @covers ::onKernelRequestCheckRedirect
68    * @dataProvider getRedirectData
69    */
70   public function testRedirectLogicWithoutQueryRetaining($request_uri, $request_query, $redirect_uri) {
71
72     $url = $this->getMockBuilder('Drupal\Core\Url')
73       ->disableOriginalConstructor()
74       ->getMock();
75
76     $url->expects($this->once())
77       ->method('setAbsolute')
78       ->with(TRUE)
79       ->willReturn($url);
80
81     // No query retaining, so getOption should not be called.
82     $url->expects($this->never())
83       ->method('getOption');
84     $url->expects($this->never())
85       ->method('setOption');
86
87     $url->expects($this->once())
88       ->method('toString')
89       ->willReturn($redirect_uri);
90
91     $redirect = $this->getRedirectStub($url);
92     $event = $this->callOnKernelRequestCheckRedirect($redirect, $request_uri, $request_query, FALSE);
93
94     $this->assertTrue($event->getResponse() instanceof RedirectResponse);
95     $response = $event->getResponse();
96     $this->assertEquals($redirect_uri, $response->getTargetUrl());
97     $this->assertEquals(301, $response->getStatusCode());
98     $this->assertEquals(1, $response->headers->get('X-Redirect-ID'));
99   }
100
101   /**
102    * Data provider for both tests.
103    */
104   public function getRedirectData() {
105     return [
106       ['non-existing', ['key' => 'val'], '/test-path', ['dummy' => 'value']],
107       ['non-existing/', ['key' => 'val'], '/test-path', ['dummy' => 'value']],
108     ];
109   }
110
111   /**
112    * Instantiates the subscriber and runs onKernelRequestCheckRedirect()
113    *
114    * @param $redirect
115    *   The redirect entity.
116    * @param $request_uri
117    *   The URI of the request.
118    * @param array $request_query
119    *   The query that is supposed to come via request.
120    * @param bool $retain_query
121    *   Flag if to retain the query through the redirect.
122    *
123    * @return \Symfony\Component\HttpKernel\Event\GetResponseEvent
124    *   THe response event.
125    */
126   protected function callOnKernelRequestCheckRedirect($redirect, $request_uri, $request_query, $retain_query) {
127
128     $event = $this->getGetResponseEventStub($request_uri, http_build_query($request_query));
129     $request = $event->getRequest();
130
131     $checker = $this->getMockBuilder('Drupal\redirect\RedirectChecker')
132       ->disableOriginalConstructor()
133       ->getMock();
134     $checker->expects($this->any())
135       ->method('canRedirect')
136       ->will($this->returnValue(TRUE));
137     $checker->expects($this->any())
138       ->method('isLoop')
139       ->will($this->returnValue(FALSE));
140
141     $context = $this->getMock('Symfony\Component\Routing\RequestContext');
142
143     $inbound_path_processor = $this->getMockBuilder('Drupal\Core\PathProcessor\InboundPathProcessorInterface')
144       ->disableOriginalConstructor()
145       ->getMock();
146     $inbound_path_processor->expects($this->any())
147       ->method('processInbound')
148       ->with($request->getPathInfo(), $request)
149       ->will($this->returnValue($request->getPathInfo()));
150
151     $alias_manager = $this->getMockBuilder('Drupal\Core\Path\AliasManager')
152       ->disableOriginalConstructor()
153       ->getMock();
154     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandlerInterface')
155       ->getMock();
156     $entity_manager = $this->getMockBuilder('Drupal\Core\Entity\EntityManagerInterface')
157       ->getMock();
158
159     $subscriber = new RedirectRequestSubscriber(
160       $this->getRedirectRepositoryStub('findMatchingRedirect', $redirect),
161       $this->getLanguageManagerStub(),
162       $this->getConfigFactoryStub(array('redirect.settings' => array('passthrough_querystring' => $retain_query))),
163       $alias_manager,
164       $module_handler,
165       $entity_manager,
166       $checker,
167       $context,
168       $inbound_path_processor
169     );
170
171     // Run the main redirect method.
172     $subscriber->onKernelRequestCheckRedirect($event);
173     return $event;
174   }
175
176   /**
177    * Gets the redirect repository mock object.
178    *
179    * @param $method
180    *   Method to mock - either load() or findMatchingRedirect().
181    * @param $redirect
182    *   The redirect object to be returned.
183    *
184    * @return PHPUnit_Framework_MockObject_MockObject
185    *   The redirect repository.
186    */
187   protected function getRedirectRepositoryStub($method, $redirect) {
188     $repository = $this->getMockBuilder('Drupal\redirect\RedirectRepository')
189       ->disableOriginalConstructor()
190       ->getMock();
191
192     $repository->expects($this->any())
193       ->method($method)
194       ->will($this->returnValue($redirect));
195
196     return $repository;
197   }
198
199   /**
200    * Gets the redirect mock object.
201    *
202    * @param $url
203    *   Url to be returned from getRedirectUrl
204    * @param int $status_code
205    *   The redirect status code.
206    *
207    * @return PHPUnit_Framework_MockObject_MockObject
208    *   The mocked redirect object.
209    */
210   protected function getRedirectStub($url, $status_code = 301) {
211     $redirect = $this->getMockBuilder('Drupal\redirect\Entity\Redirect')
212       ->disableOriginalConstructor()
213       ->getMock();
214     $redirect->expects($this->once())
215       ->method('getRedirectUrl')
216       ->will($this->returnValue($url));
217     $redirect->expects($this->any())
218       ->method('getStatusCode')
219       ->will($this->returnValue($status_code));
220     $redirect->expects($this->any())
221       ->method('id')
222       ->willReturn(1);
223     $redirect->expects($this->once())
224       ->method('getCacheTags')
225       ->willReturn(['redirect:1']);
226
227     return $redirect;
228   }
229
230   /**
231    * Gets post response event.
232    *
233    * @param array $headers
234    *   Headers to be set into the response.
235    *
236    * @return \Symfony\Component\HttpKernel\Event\PostResponseEvent
237    *   The post response event object.
238    */
239   protected function getPostResponseEvent($headers = array()) {
240     $http_kernel = $this->getMockBuilder('\Symfony\Component\HttpKernel\HttpKernelInterface')
241       ->getMock();
242     $request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')
243       ->disableOriginalConstructor()
244       ->getMock();
245
246     $response = new Response('', 301, $headers);
247
248     return new PostResponseEvent($http_kernel, $request, $response);
249   }
250
251   /**
252    * Gets response event object.
253    *
254    * @param $path_info
255    * @param $query_string
256    *
257    * @return GetResponseEvent
258    */
259   protected function getGetResponseEventStub($path_info, $query_string) {
260     $request = Request::create($path_info . '?' . $query_string, 'GET', [], [], [], ['SCRIPT_NAME' => 'index.php']);
261
262     $http_kernel = $this->getMockBuilder('\Symfony\Component\HttpKernel\HttpKernelInterface')
263       ->getMock();
264     return new GetResponseEvent($http_kernel, $request, 'test');
265   }
266
267   /**
268    * Gets the language manager mock object.
269    *
270    * @return \Drupal\language\ConfigurableLanguageManagerInterface|PHPUnit_Framework_MockObject_MockObject
271    */
272   protected function getLanguageManagerStub() {
273     $language_manager = $this->getMockBuilder('Drupal\language\ConfigurableLanguageManagerInterface')
274       ->getMock();
275     $language_manager->expects($this->any())
276       ->method('getCurrentLanguage')
277       ->will($this->returnValue(new Language(array('id' => 'en'))));
278
279     return $language_manager;
280   }
281
282 }