‪TYPO3CMS  10.4
SiteBaseRedirectResolverTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
22 use Psr\Http\Server\RequestHandlerInterface;
32 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
33 
34 class ‪SiteBaseRedirectResolverTest extends UnitTestCase
35 {
39  protected ‪$resetSingletonInstances = true;
40 
45 
49  protected function ‪setUp(): void
50  {
51  parent::setUp();
52  // A request handler which expects a site to be found.
53  $this->siteFoundRequestHandler = new class() implements RequestHandlerInterface {
54  public function handle(ServerRequestInterface $request): ResponseInterface
55  {
58  $site = $request->getAttribute('site', false);
59  $language = $request->getAttribute('language', false);
60  if ($site && $language) {
61  return new ‪JsonResponse(
62  [
63  'site' => $site->getIdentifier(),
64  'language-id' => $language->getLanguageId(),
65  'language-base' => (string)$language->getBase(),
66  'rootpage' => $site->getRootPageId()
67  ]
68  );
69  }
70  return new ‪NullResponse();
71  }
72  };
73  }
74 
79  {
80  $site1 = new ‪Site('outside-site', 13, [
81  'base' => 'https://twenty.one/',
82  'languages' => [
83  0 => [
84  'languageId' => 0,
85  'locale' => 'en_US.UTF-8',
86  'base' => '/en/'
87  ],
88  1 => [
89  'languageId' => 1,
90  'locale' => 'fr_CA.UTF-8',
91  'base' => '/fr'
92  ]
93  ]
94  ]);
95  $site2 = new ‪Site('sub-site', 14, [
96  'base' => 'https://twenty.one/mysubsite/',
97  'languages' => [
98  2 => [
99  'languageId' => 2,
100  'locale' => 'it_IT.UTF-8',
101  'base' => '/'
102  ]
103  ]
104  ]);
105 
106  return [
107  'redirect to first language' => [
108  'https://twenty.one/',
109  'https://twenty.one/en/',
110  $site1,
111  null,
112  ''
113  ],
114  'redirect to first language adding the slash' => [
115  'https://twenty.one/en',
116  'https://twenty.one/en/',
117  $site1,
118  null,
119  ''
120  ],
121  'redirect to second language removing a slash' => [
122  'https://twenty.one/fr/',
123  'https://twenty.one/fr',
124  $site1,
125  $site1->getLanguageById(1),
126  '/'
127  ],
128  'redirect to subsite by adding a slash' => [
129  'https://twenty.one/mysubsite',
130  'https://twenty.one/mysubsite/',
131  $site2,
132  null,
133  ''
134  ],
135  'redirect to first language and remove nested arguments' => [
136  'https://twenty.one/?foo[bar]=foobar&bar=foo',
137  'https://twenty.one/en/',
138  $site1,
139  null,
140  ''
141  ],
142  'redirect to second language removing a slash but keeping the nested arguments' => [
143  'https://twenty.one/fr/?foo[bar]=foobar&bar=foo',
144  'https://twenty.one/fr?foo%5Bbar%5D=foobar&bar=foo',
145  $site1,
146  $site1->getLanguageById(1),
147  '/'
148  ],
149  ];
150  }
151 
162  string $incomingUrl,
163  string $expectedRedirectUrl,
164  ‪Site $site,
165  ?‪SiteLanguage $language,
166  string $tail
167  ) {
168  $routeResult = new ‪SiteRouteResult(new ‪Uri($incomingUrl), $site, $language, $tail);
169  $request = new ‪ServerRequest($incomingUrl, 'GET');
170  $request = $request->withAttribute('site', $site);
171  $request = $request->withAttribute('language', $language);
172  $request = $request->withAttribute('routing', $routeResult);
173 
174  $subject = new ‪SiteBaseRedirectResolver();
175  $response = $subject->process($request, $this->siteFoundRequestHandler);
176  self::assertEquals(307, $response->getStatusCode());
177  self::assertEquals($expectedRedirectUrl, $response->getHeader('Location')[0] ?? '');
178  }
179 
184  {
185  return [
186  'disabled site language' => ['https://twenty.one/en/pilots/', 404, 0],
187  'enabled site language' => ['https://twenty.one/fr/pilots/', 200, 1],
188  ];
189  }
190 
200  string $url,
201  int $expectedStatusCode,
202  int $languageId
203  ) {
204  $site = new ‪Site('mixed-site', 13, [
205  'base' => '/',
206  'errorHandling' => [
207  [
208  'errorCode' => 404,
209  'errorHandler' => 'PHP',
210  'errorPhpClassFQCN' => PhpError::class
211  ]
212  ],
213  'languages' => [
214  0 => [
215  'languageId' => 0,
216  'locale' => 'en_US.UTF-8',
217  'base' => '/en/',
218  'enabled' => false
219  ],
220  1 => [
221  'languageId' => 1,
222  'locale' => 'fr_CA.UTF-8',
223  'base' => '/fr/',
224  'enabled' => true
225  ]
226  ]
227  ]);
228 
229  // Request to default page
230  $request = new ‪ServerRequest($url, 'GET');
231  $request = $request->withAttribute('site', $site);
232  $request = $request->withAttribute('language', $site->‪getLanguageById($languageId));
233  $subject = new ‪SiteBaseRedirectResolver();
234  $response = $subject->process($request, $this->siteFoundRequestHandler);
235  self::assertEquals($expectedStatusCode, $response->getStatusCode());
236  }
237 
241  public function ‪doNotRedirectOnBaseWithoutQueryDataProvider(): array
242  {
243  $site1 = new ‪Site('outside-site', 13, [
244  'base' => 'https://twenty.one/',
245  'languages' => [
246  0 => [
247  'languageId' => 0,
248  'locale' => 'en_US.UTF-8',
249  'base' => '/en/'
250  ],
251  1 => [
252  'languageId' => 1,
253  'locale' => 'fr_CA.UTF-8',
254  'base' => '/fr'
255  ]
256  ]
257  ]);
258  return [
259  'no redirect for base' => [
260  'https://twenty.one/en/',
261  $site1,
262  $site1->getLanguageById(0),
263  ''
264  ],
265  'no redirect for base when ID is given' => [
266  'https://twenty.one/index.php?id=2',
267  $site1,
268  $site1->getLanguageById(0),
269  ''
270  ],
271  'no redirect for base and nested arguments' => [
272  'https://twenty.one/en/?foo[bar]=foobar&bar=foo',
273  $site1,
274  $site1->getLanguageById(0),
275  ''
276  ],
277  ];
278  }
279 
288  public function ‪doNotRedirectOnBaseWithoutQuery(
289  string $incomingUrl,
290  ‪Site $site,
291  ?‪SiteLanguage $language,
292  string $tail
293  ): void {
294  $routeResult = new ‪SiteRouteResult(new ‪Uri($incomingUrl), $site, $language, $tail);
295  $request = new ‪ServerRequest($incomingUrl, 'GET');
296  $request = $request->withAttribute('site', $site);
297  $request = $request->withAttribute('language', $language);
298  $request = $request->withAttribute('routing', $routeResult);
299 
300  $subject = new ‪SiteBaseRedirectResolver();
301  $response = $subject->process($request, $this->siteFoundRequestHandler);
302  self::assertEquals(200, $response->getStatusCode());
303  }
304 
308  public function ‪useDefaultLanguageIfNoLanguageIsGiven(): void
309  {
310  $incomingUrl = 'https://twenty.one/';
311  $site = new ‪Site('random-site', 13, [
312  'base' => 'https://twenty.one/',
313  'languages' => [
314  0 => [
315  'languageId' => 0,
316  'locale' => 'en_US.UTF-8',
317  'base' => '/en/'
318  ],
319  1 => [
320  'languageId' => 1,
321  'locale' => 'fr_FR.UTF-8',
322  'base' => '/fr'
323  ],
324  2 => [
325  'languageId' => 2,
326  'locale' => 'fr_CA.UTF-8',
327  'base' => '/fr_ca'
328  ]
329  ]
330  ]);
331 
332  $routeResult = new ‪SiteRouteResult(new ‪Uri($incomingUrl), $site);
333  $request = new ‪ServerRequest($incomingUrl, 'GET');
334  $request = $request->withAttribute('site', $site);
335  $request = $request->withAttribute('routing', $routeResult);
336 
337  $subject = new ‪SiteBaseRedirectResolver();
338  $response = $subject->process($request, $this->siteFoundRequestHandler);
339  self::assertEquals('https://twenty.one/en/', $response->getHeader('Location')[0]);
340  }
341 
346  {
347  $incomingUrl = 'https://twenty.one/';
348  $site = new ‪Site('random-site', 13, [
349  'base' => 'https://twenty.one/',
350  'languages' => [
351  0 => [
352  'languageId' => 0,
353  'enabled' => false,
354  'locale' => 'en_US.UTF-8',
355  'base' => '/en/'
356  ],
357  1 => [
358  'languageId' => 1,
359  'enabled' => false,
360  'locale' => 'fr_FR.UTF-8',
361  'base' => '/fr'
362  ],
363  2 => [
364  'languageId' => 2,
365  'locale' => 'fr_CA.UTF-8',
366  'base' => '/fr_ca'
367  ]
368  ]
369  ]);
370 
371  $routeResult = new ‪SiteRouteResult(new ‪Uri($incomingUrl), $site);
372  $request = new ‪ServerRequest($incomingUrl, 'GET');
373  $request = $request->withAttribute('site', $site);
374  $request = $request->withAttribute('routing', $routeResult);
375 
376  $subject = new ‪SiteBaseRedirectResolver();
377  $response = $subject->process($request, $this->siteFoundRequestHandler);
378  self::assertEquals('https://twenty.one/fr_ca', $response->getHeader('Location')[0]);
379  }
380 }
‪TYPO3\CMS\Frontend\Middleware\SiteBaseRedirectResolver
Definition: SiteBaseRedirectResolver.php:42
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\checkIf404IsSiteLanguageIsDisabledInFrontend
‪checkIf404IsSiteLanguageIsDisabledInFrontend(string $url, int $expectedStatusCode, int $languageId)
Definition: SiteBaseRedirectResolverTest.php:197
‪TYPO3\CMS\Core\Site\Entity\Site\getLanguageById
‪SiteLanguage getLanguageById(int $languageId)
Definition: Site.php:235
‪TYPO3\CMS\Core\Tests\Functional\Fixtures\Frontend\PhpError
Definition: PhpError.php:29
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest
Definition: SiteBaseRedirectResolverTest.php:35
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\$siteFoundRequestHandler
‪RequestHandlerInterface $siteFoundRequestHandler
Definition: SiteBaseRedirectResolverTest.php:42
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\checkIf404IsSiteLanguageIsDisabledInFrontendDataProvider
‪array checkIf404IsSiteLanguageIsDisabledInFrontendDataProvider()
Definition: SiteBaseRedirectResolverTest.php:181
‪TYPO3\CMS\Core\Http\NullResponse
Definition: NullResponse.php:26
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\setUp
‪setUp()
Definition: SiteBaseRedirectResolverTest.php:47
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\$resetSingletonInstances
‪bool $resetSingletonInstances
Definition: SiteBaseRedirectResolverTest.php:38
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\useDefaultLanguageIfNoLanguageIsGiven
‪useDefaultLanguageIfNoLanguageIsGiven()
Definition: SiteBaseRedirectResolverTest.php:306
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:29
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:40
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\doNotRedirectOnBaseWithoutQueryDataProvider
‪array doNotRedirectOnBaseWithoutQueryDataProvider()
Definition: SiteBaseRedirectResolverTest.php:239
‪TYPO3\CMS\Core\Site\Entity\SiteLanguage
Definition: SiteLanguage.php:26
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\doRedirectOnMissingOrSuperfluousRequestUrl
‪doRedirectOnMissingOrSuperfluousRequestUrl(string $incomingUrl, string $expectedRedirectUrl, Site $site, ?SiteLanguage $language, string $tail)
Definition: SiteBaseRedirectResolverTest.php:159
‪TYPO3\CMS\Core\Routing\SiteRouteResult
Definition: SiteRouteResult.php:30
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware
Definition: PageArgumentValidatorTest.php:18
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\useFirstAvailableLanguageIfDefaultLanguageIsNotEnabledAndLanguageIsGiven
‪useFirstAvailableLanguageIfDefaultLanguageIsNotEnabledAndLanguageIsGiven()
Definition: SiteBaseRedirectResolverTest.php:343
‪TYPO3\CMS\Core\Http\ServerRequest
Definition: ServerRequest.php:37
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\doNotRedirectOnBaseWithoutQuery
‪doNotRedirectOnBaseWithoutQuery(string $incomingUrl, Site $site, ?SiteLanguage $language, string $tail)
Definition: SiteBaseRedirectResolverTest.php:286
‪TYPO3\CMS\Core\Http\JsonResponse
Definition: JsonResponse.php:26
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\doRedirectOnMissingOrSuperfluousRequestUrlDataProvider
‪array doRedirectOnMissingOrSuperfluousRequestUrlDataProvider()
Definition: SiteBaseRedirectResolverTest.php:76