‪TYPO3CMS  9.5
SiteBaseRedirectResolverTest.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types = 1);
3 
5 
6 /*
7  * This file is part of the TYPO3 CMS project.
8  *
9  * It is free software; you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License, either version 2
11  * of the License, or any later version.
12  *
13  * For the full copyright and license information, please read the
14  * LICENSE.txt file that was distributed with this source code.
15  *
16  * The TYPO3 project - inspiring people to share!
17  */
18 
19 use Psr\Http\Message\ResponseInterface;
20 use Psr\Http\Message\ServerRequestInterface;
21 use Psr\Http\Server\RequestHandlerInterface;
31 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
32 
33 class ‪SiteBaseRedirectResolverTest extends UnitTestCase
34 {
38  protected ‪$resetSingletonInstances = true;
39 
44 
48  protected function ‪setUp(): void
49  {
50  // A request handler which expects a site to be found.
51  $this->siteFoundRequestHandler = new class implements RequestHandlerInterface {
52  public function handle(ServerRequestInterface $request): ResponseInterface
53  {
56  $site = $request->getAttribute('site', false);
57  $language = $request->getAttribute('language', false);
58  if ($site && $language) {
59  return new ‪JsonResponse(
60  [
61  'site' => $site->getIdentifier(),
62  'language-id' => $language->getLanguageId(),
63  'language-base' => (string)$language->getBase(),
64  'rootpage' => $site->getRootPageId()
65  ]
66  );
67  }
68  return new ‪NullResponse();
69  }
70  };
71  }
72 
77  {
78  $site1 = new ‪Site('outside-site', 13, [
79  'base' => 'https://twenty.one/',
80  'languages' => [
81  0 => [
82  'languageId' => 0,
83  'locale' => 'en_US.UTF-8',
84  'base' => '/en/'
85  ],
86  1 => [
87  'languageId' => 1,
88  'locale' => 'fr_CA.UTF-8',
89  'base' => '/fr'
90  ]
91  ]
92  ]);
93  $site2 = new ‪Site('sub-site', 14, [
94  'base' => 'https://twenty.one/mysubsite/',
95  'languages' => [
96  2 => [
97  'languageId' => 2,
98  'locale' => 'it_IT.UTF-8',
99  'base' => '/'
100  ]
101  ]
102  ]);
103 
104  return [
105  'redirect to first language' => [
106  'https://twenty.one/',
107  'https://twenty.one/en/',
108  $site1,
109  null,
110  ''
111  ],
112  'redirect to first language adding the slash' => [
113  'https://twenty.one/en',
114  'https://twenty.one/en/',
115  $site1,
116  null,
117  ''
118  ],
119  'redirect to second language removing a slash' => [
120  'https://twenty.one/fr/',
121  'https://twenty.one/fr',
122  $site1,
123  $site1->getLanguageById(1),
124  '/'
125  ],
126  'redirect to subsite by adding a slash' => [
127  'https://twenty.one/mysubsite',
128  'https://twenty.one/mysubsite/',
129  $site2,
130  null,
131  ''
132  ],
133  'redirect to first language and remove nested arguments' => [
134  'https://twenty.one/?foo[bar]=foobar&bar=foo',
135  'https://twenty.one/en/',
136  $site1,
137  null,
138  ''
139  ],
140  'redirect to second language removing a slash but keeping the nested arguments' => [
141  'https://twenty.one/fr/?foo[bar]=foobar&bar=foo',
142  'https://twenty.one/fr?foo%5Bbar%5D=foobar&bar=foo',
143  $site1,
144  $site1->getLanguageById(1),
145  '/'
146  ],
147  ];
148  }
149 
160  string $incomingUrl,
161  string $expectedRedirectUrl,
162  ‪Site $site,
163  ?‪SiteLanguage $language,
164  string $tail
165  ) {
166  $routeResult = new ‪SiteRouteResult(new ‪Uri($incomingUrl), $site, $language, $tail);
167  $request = new ‪ServerRequest($incomingUrl, 'GET');
168  $request = $request->withAttribute('site', $site);
169  $request = $request->withAttribute('language', $language);
170  $request = $request->withAttribute('routing', $routeResult);
171 
172  $subject = new ‪SiteBaseRedirectResolver();
173  $response = $subject->process($request, $this->siteFoundRequestHandler);
174  $this->assertEquals(307, $response->getStatusCode());
175  $this->assertEquals($expectedRedirectUrl, $response->getHeader('Location')[0] ?? '');
176  }
177 
182  {
183  return [
184  'disabled site language' => ['https://twenty.one/en/pilots/', 404, 0],
185  'enabled site language' => ['https://twenty.one/fr/pilots/', 200, 1],
186  ];
187  }
188 
198  string $url,
199  int $expectedStatusCode,
200  int $languageId
201  ) {
202  $site = new ‪Site('mixed-site', 13, [
203  'base' => '/',
204  'errorHandling' => [
205  [
206  'errorCode' => 404,
207  'errorHandler' => 'PHP',
208  'errorPhpClassFQCN' => PhpError::class
209  ]
210  ],
211  'languages' => [
212  0 => [
213  'languageId' => 0,
214  'locale' => 'en_US.UTF-8',
215  'base' => '/en/',
216  'enabled' => false
217  ],
218  1 => [
219  'languageId' => 1,
220  'locale' => 'fr_CA.UTF-8',
221  'base' => '/fr/',
222  'enabled' => true
223  ]
224  ]
225  ]);
226 
227  // Request to default page
228  $request = new ‪ServerRequest($url, 'GET');
229  $request = $request->withAttribute('site', $site);
230  $request = $request->withAttribute('language', $site->‪getLanguageById($languageId));
231  $subject = new ‪SiteBaseRedirectResolver();
232  $response = $subject->process($request, $this->siteFoundRequestHandler);
233  $this->assertEquals($expectedStatusCode, $response->getStatusCode());
234  }
235 
239  public function ‪doNotRedirectOnBaseWithoutQueryDataProvider(): array
240  {
241  $site1 = new ‪Site('outside-site', 13, [
242  'base' => 'https://twenty.one/',
243  'languages' => [
244  0 => [
245  'languageId' => 0,
246  'locale' => 'en_US.UTF-8',
247  'base' => '/en/'
248  ],
249  1 => [
250  'languageId' => 1,
251  'locale' => 'fr_CA.UTF-8',
252  'base' => '/fr'
253  ]
254  ]
255  ]);
256  return [
257  'no redirect for base' => [
258  'https://twenty.one/en/',
259  $site1,
260  $site1->getLanguageById(0),
261  ''
262  ],
263  'no redirect for base when ID is given' => [
264  'https://twenty.one/index.php?id=2',
265  $site1,
266  $site1->getLanguageById(0),
267  ''
268  ],
269  'no redirect for base and nested arguments' => [
270  'https://twenty.one/en/?foo[bar]=foobar&bar=foo',
271  $site1,
272  $site1->getLanguageById(0),
273  ''
274  ],
275  ];
276  }
277 
286  public function ‪doNotRedirectOnBaseWithoutQuery(
287  string $incomingUrl,
288  ‪Site $site,
289  ?‪SiteLanguage $language,
290  string $tail
291  ): void {
292  $routeResult = new ‪SiteRouteResult(new ‪Uri($incomingUrl), $site, $language, $tail);
293  $request = new ‪ServerRequest($incomingUrl, 'GET');
294  $request = $request->withAttribute('site', $site);
295  $request = $request->withAttribute('language', $language);
296  $request = $request->withAttribute('routing', $routeResult);
297 
298  $subject = new ‪SiteBaseRedirectResolver();
299  $response = $subject->process($request, $this->siteFoundRequestHandler);
300  self::assertEquals(200, $response->getStatusCode());
301  }
302 }
‪TYPO3\CMS\Frontend\Middleware\SiteBaseRedirectResolver
Definition: SiteBaseRedirectResolver.php:40
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\checkIf404IsSiteLanguageIsDisabledInFrontend
‪checkIf404IsSiteLanguageIsDisabledInFrontend(string $url, int $expectedStatusCode, int $languageId)
Definition: SiteBaseRedirectResolverTest.php:195
‪TYPO3\CMS\Core\Site\Entity\Site\getLanguageById
‪SiteLanguage getLanguageById(int $languageId)
Definition: Site.php:234
‪TYPO3\CMS\Core\Tests\Functional\Fixtures\Frontend\PhpError
Definition: PhpError.php:27
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest
Definition: SiteBaseRedirectResolverTest.php:34
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\$siteFoundRequestHandler
‪RequestHandlerInterface $siteFoundRequestHandler
Definition: SiteBaseRedirectResolverTest.php:41
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\checkIf404IsSiteLanguageIsDisabledInFrontendDataProvider
‪array checkIf404IsSiteLanguageIsDisabledInFrontendDataProvider()
Definition: SiteBaseRedirectResolverTest.php:179
‪TYPO3\CMS\Core\Http\NullResponse
Definition: NullResponse.php:24
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\setUp
‪setUp()
Definition: SiteBaseRedirectResolverTest.php:46
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\$resetSingletonInstances
‪bool $resetSingletonInstances
Definition: SiteBaseRedirectResolverTest.php:37
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:27
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:39
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\doNotRedirectOnBaseWithoutQueryDataProvider
‪array doNotRedirectOnBaseWithoutQueryDataProvider()
Definition: SiteBaseRedirectResolverTest.php:237
‪TYPO3\CMS\Core\Site\Entity\SiteLanguage
Definition: SiteLanguage.php:25
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\doRedirectOnMissingOrSuperfluousRequestUrl
‪doRedirectOnMissingOrSuperfluousRequestUrl(string $incomingUrl, string $expectedRedirectUrl, Site $site, ?SiteLanguage $language, string $tail)
Definition: SiteBaseRedirectResolverTest.php:157
‪TYPO3\CMS\Core\Routing\SiteRouteResult
Definition: SiteRouteResult.php:29
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware
Definition: PageArgumentValidatorTest.php:4
‪TYPO3\CMS\Core\Http\ServerRequest
Definition: ServerRequest.php:35
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\doNotRedirectOnBaseWithoutQuery
‪doNotRedirectOnBaseWithoutQuery(string $incomingUrl, Site $site, ?SiteLanguage $language, string $tail)
Definition: SiteBaseRedirectResolverTest.php:284
‪TYPO3\CMS\Core\Http\JsonResponse
Definition: JsonResponse.php:25
‪TYPO3\CMS\Frontend\Tests\Unit\Middleware\SiteBaseRedirectResolverTest\doRedirectOnMissingOrSuperfluousRequestUrlDataProvider
‪array doRedirectOnMissingOrSuperfluousRequestUrlDataProvider()
Definition: SiteBaseRedirectResolverTest.php:74