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