2 declare(strict_types = 1);
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;
48 protected function setUp():
void
51 $this->siteFoundRequestHandler =
new class implements RequestHandlerInterface {
52 public function handle(ServerRequestInterface $request): ResponseInterface
56 $site = $request->getAttribute(
'site',
false);
57 $language = $request->getAttribute(
'language',
false);
58 if ($site && $language) {
61 'site' => $site->getIdentifier(),
62 'language-id' => $language->getLanguageId(),
63 'language-base' => (
string)$language->getBase(),
64 'rootpage' => $site->getRootPageId()
78 $site1 =
new Site(
'outside-site', 13, [
79 'base' =>
'https://twenty.one/',
83 'locale' =>
'en_US.UTF-8',
88 'locale' =>
'fr_CA.UTF-8',
93 $site2 =
new Site(
'sub-site', 14, [
94 'base' =>
'https://twenty.one/mysubsite/',
98 'locale' =>
'it_IT.UTF-8',
105 'redirect to first language' => [
106 'https://twenty.one/',
107 'https://twenty.one/en/',
112 'redirect to first language adding the slash' => [
113 'https://twenty.one/en',
114 'https://twenty.one/en/',
119 'redirect to second language removing a slash' => [
120 'https://twenty.one/fr/',
121 'https://twenty.one/fr',
123 $site1->getLanguageById(1),
126 'redirect to subsite by adding a slash' => [
127 'https://twenty.one/mysubsite',
128 'https://twenty.one/mysubsite/',
133 'redirect to first language and remove nested arguments' => [
134 'https://twenty.one/?foo[bar]=foobar&bar=foo',
135 'https://twenty.one/en/',
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',
144 $site1->getLanguageById(1),
161 string $expectedRedirectUrl,
168 $request = $request->withAttribute(
'site', $site);
169 $request = $request->withAttribute(
'language', $language);
170 $request = $request->withAttribute(
'routing', $routeResult);
173 $response = $subject->process($request, $this->siteFoundRequestHandler);
174 $this->assertEquals(307, $response->getStatusCode());
175 $this->assertEquals($expectedRedirectUrl, $response->getHeader(
'Location')[0] ??
'');
184 'disabled site language' => [
'https://twenty.one/en/pilots/', 404, 0],
185 'enabled site language' => [
'https://twenty.one/fr/pilots/', 200, 1],
199 int $expectedStatusCode,
202 $site =
new Site(
'mixed-site', 13, [
207 'errorHandler' =>
'PHP',
208 'errorPhpClassFQCN' => PhpError::class
214 'locale' =>
'en_US.UTF-8',
220 'locale' =>
'fr_CA.UTF-8',
229 $request = $request->withAttribute(
'site', $site);
230 $request = $request->withAttribute(
'language', $site->
getLanguageById($languageId));
232 $response = $subject->process($request, $this->siteFoundRequestHandler);
233 $this->assertEquals($expectedStatusCode, $response->getStatusCode());
241 $site1 =
new Site(
'outside-site', 13, [
242 'base' =>
'https://twenty.one/',
246 'locale' =>
'en_US.UTF-8',
251 'locale' =>
'fr_CA.UTF-8',
257 'no redirect for base' => [
258 'https://twenty.one/en/',
260 $site1->getLanguageById(0),
263 'no redirect for base when ID is given' => [
264 'https://twenty.one/index.php?id=2',
266 $site1->getLanguageById(0),
269 'no redirect for base and nested arguments' => [
270 'https://twenty.one/en/?foo[bar]=foobar&bar=foo',
272 $site1->getLanguageById(0),
294 $request = $request->withAttribute(
'site', $site);
295 $request = $request->withAttribute(
'language', $language);
296 $request = $request->withAttribute(
'routing', $routeResult);
299 $response = $subject->process($request, $this->siteFoundRequestHandler);
300 self::assertEquals(200, $response->getStatusCode());