‪TYPO3CMS  ‪main
MiddlewareDispatcherTest.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\Container\ContainerInterface;
21 use Psr\Http\Message\ResponseInterface;
22 use Psr\Http\Message\ServerRequestInterface;
23 use Psr\Http\Server\MiddlewareInterface;
24 use Psr\Http\Server\RequestHandlerInterface;
29 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
30 
31 final class ‪MiddlewareDispatcherTest extends UnitTestCase
32 {
37  {
38  $kernel = new class () implements RequestHandlerInterface {
39  public function handle(ServerRequestInterface $request): ResponseInterface
40  {
41  return (new ‪Response())->withStatus(204);
42  }
43  };
44 
45  $dispatcher = new ‪MiddlewareDispatcher($kernel);
46  $response = $dispatcher->handle(new ‪ServerRequest());
47 
48  self::assertSame(204, $response->getStatusCode());
49  }
50 
54  public function ‪executesMiddlewaresLastInFirstOut(): void
55  {
56  $kernel = new class () implements RequestHandlerInterface {
57  public function handle(ServerRequestInterface $request): ResponseInterface
58  {
59  return (new ‪Response())
60  ->withStatus(204)
61  ->withHeader('X-SEQ-PRE-REQ-HANDLER', $request->getHeader('X-SEQ-PRE-REQ-HANDLER'));
62  }
63  };
64 
65  $middleware1 = new class () implements MiddlewareInterface {
66  public $id = '0';
67 
68  public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
69  {
70  $request = $request->withAddedHeader('X-SEQ-PRE-REQ-HANDLER', $this->id);
71  $response = $handler->handle($request);
72 
73  return $response->withAddedHeader('X-SEQ-POST-REQ-HANDLER', $this->id);
74  }
75  };
76 
77  $middleware2 = clone $middleware1;
78  $middleware2->id = '1';
79 
81 
82  $middleware4 = clone $middleware1;
83  $middleware4->id = '3';
84 
85  $dispatcher = new ‪MiddlewareDispatcher($kernel, [$middleware1, $middleware2]);
86  $dispatcher->lazy(MiddlewareFixture::class);
87  $dispatcher->add($middleware4);
88 
89  $response = $dispatcher->handle(new ‪ServerRequest());
90 
91  self::assertSame(['3', '2', '1', '0'], $response->getHeader('X-SEQ-PRE-REQ-HANDLER'));
92  self::assertSame(['0', '1', '2', '3'], $response->getHeader('X-SEQ-POST-REQ-HANDLER'));
93  self::assertSame(204, $response->getStatusCode());
94  }
95 
100  {
101  $kernel = new class () implements RequestHandlerInterface {
102  public function handle(ServerRequestInterface $request): ResponseInterface
103  {
104  return new ‪Response();
105  }
106  };
107  $middleware = new class () implements MiddlewareInterface {
108  public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
109  {
110  return (new ‪Response())->withStatus(404);
111  }
112  };
113 
115  $dispatcher = new ‪MiddlewareDispatcher($kernel, [MiddlewareFixture::class, $middleware]);
116  $response = $dispatcher->handle(new ‪ServerRequest());
117 
119  self::assertSame(404, $response->getStatusCode());
120  }
121 
126  {
127  $this->expectException(\InvalidArgumentException::class);
128  $this->expectExceptionCode(1516821342);
129 
130  $kernel = new class () implements RequestHandlerInterface {
131  public function handle(ServerRequestInterface $request): ResponseInterface
132  {
133  return new ‪Response();
134  }
135  };
136 
138  $dispatcher = new ‪MiddlewareDispatcher($kernel);
139  $dispatcher->lazy(\stdClass::class);
140  $dispatcher->handle(new ‪ServerRequest());
141  }
142 
146  public function ‪canBeExecutedMultipleTimes(): void
147  {
148  $kernel = new class () implements RequestHandlerInterface {
149  public function handle(ServerRequestInterface $request): ResponseInterface
150  {
151  return new ‪Response();
152  }
153  };
154  $middleware = new class () implements MiddlewareInterface {
155  public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
156  {
157  return (new ‪Response())->withStatus(204);
158  }
159  };
160 
161  $dispatcher = new ‪MiddlewareDispatcher($kernel);
162  $dispatcher->add($middleware);
163 
164  $response1 = $dispatcher->handle(new ‪ServerRequest());
165  $response2 = $dispatcher->handle(new ‪ServerRequest());
166 
167  self::assertSame(204, $response1->getStatusCode());
168  self::assertSame(204, $response2->getStatusCode());
169  }
170 
175  {
176  $kernel = new class () implements RequestHandlerInterface {
177  public function handle(ServerRequestInterface $request): ResponseInterface
178  {
179  return new ‪Response();
180  }
181  };
182 
183  $dispatcher = new ‪MiddlewareDispatcher($kernel);
184 
185  $dispatcher->add(new class ($dispatcher) implements MiddlewareInterface {
186  private $dispatcher;
187 
188  public function __construct(RequestHandlerInterface $dispatcher)
189  {
190  $this->dispatcher = $dispatcher;
191  }
192 
193  public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
194  {
195  if ($request->hasHeader('X-NESTED')) {
196  return (new ‪Response())->withStatus(204)->withAddedHeader('X-TRACE', 'nested');
197  }
198 
199  $response = $this->dispatcher->handle($request->withAddedHeader('X-NESTED', '1'));
200 
201  return $response->withAddedHeader('X-TRACE', 'outer');
202  }
203  });
204 
205  $response = $dispatcher->handle(new ‪ServerRequest());
206 
207  self::assertSame(204, $response->getStatusCode());
208  self::assertSame(['nested', 'outer'], $response->getHeader('X-TRACE'));
209  }
210 
214  public function ‪fetchesMiddlewareFromContainer(): void
215  {
216  $kernel = new class () implements RequestHandlerInterface {
217  public function handle(ServerRequestInterface $request): ResponseInterface
218  {
219  return new ‪Response();
220  }
221  };
222 
223  $middleware = new class () implements MiddlewareInterface {
224  public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
225  {
226  return (new ‪Response())->withStatus(404);
227  }
228  };
229 
230  $containerMock = $this->createMock(ContainerInterface::class);
231  $containerMock->method('has')->with('somemiddlewarename')->willReturn(true);
232  $containerMock->method('get')->with('somemiddlewarename')->willReturn($middleware);
233 
234  $dispatcher = new ‪MiddlewareDispatcher($kernel, ['somemiddlewarename'], $containerMock);
235  $response = $dispatcher->handle(new ‪ServerRequest());
236 
237  self::assertSame(404, $response->getStatusCode());
238  }
239 }
‪TYPO3\CMS\Core\Tests\Unit\Http
Definition: ApplicationTypeTest.php:18
‪TYPO3\CMS\Core\Tests\Unit\Http\MiddlewareDispatcherTest\throwsExceptionForLazyNonMiddlewareInterfaceClasses
‪throwsExceptionForLazyNonMiddlewareInterfaceClasses()
Definition: MiddlewareDispatcherTest.php:125
‪TYPO3\CMS\Core\Tests\Unit\Http\MiddlewareDispatcherTest\fetchesMiddlewareFromContainer
‪fetchesMiddlewareFromContainer()
Definition: MiddlewareDispatcherTest.php:214
‪TYPO3\CMS\Core\Tests\Unit\Http\MiddlewareDispatcherTest\canBeExecutedMultipleTimes
‪canBeExecutedMultipleTimes()
Definition: MiddlewareDispatcherTest.php:146
‪TYPO3\CMS\Core\Tests\Unit\Http\MiddlewareDispatcherTest\canBeReExecutedRecursivelyDuringDispatch
‪canBeReExecutedRecursivelyDuringDispatch()
Definition: MiddlewareDispatcherTest.php:174
‪TYPO3\CMS\Core\Http\MiddlewareDispatcher
Definition: MiddlewareDispatcher.php:35
‪TYPO3\CMS\Core\Http\Response
Definition: Response.php:32
‪TYPO3\CMS\Core\Tests\Unit\Http\MiddlewareDispatcherTest
Definition: MiddlewareDispatcherTest.php:32
‪TYPO3\CMS\Core\Tests\Unit\Http\Fixtures\MiddlewareFixture
Definition: MiddlewareFixture.php:29
‪TYPO3\CMS\Core\Http\ServerRequest
Definition: ServerRequest.php:39
‪TYPO3\CMS\Core\Tests\Unit\Http\MiddlewareDispatcherTest\executesMiddlewaresLastInFirstOut
‪executesMiddlewaresLastInFirstOut()
Definition: MiddlewareDispatcherTest.php:54
‪TYPO3\CMS\Core\Tests\Unit\Http\Fixtures\MiddlewareFixture\$hasBeenInstantiated
‪static bool $hasBeenInstantiated
Definition: MiddlewareFixture.php:34
‪TYPO3\CMS\Core\Tests\Unit\Http\MiddlewareDispatcherTest\executesKernelWithEmptyMiddlewareStack
‪executesKernelWithEmptyMiddlewareStack()
Definition: MiddlewareDispatcherTest.php:36
‪TYPO3\CMS\Core\Tests\Unit\Http\Fixtures\MiddlewareFixture\$id
‪static string $id
Definition: MiddlewareFixture.php:30
‪TYPO3\CMS\Core\Tests\Unit\Http\MiddlewareDispatcherTest\doesNotInstantiateLazyMiddlewareInCaseOfAnEarlyReturningOuterMiddleware
‪doesNotInstantiateLazyMiddlewareInCaseOfAnEarlyReturningOuterMiddleware()
Definition: MiddlewareDispatcherTest.php:99