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