3 declare(strict_types
=1);
5 namespace Shaarli\Front
;
7 use PHPUnit\Framework\TestCase
;
8 use Shaarli\Config\ConfigManager
;
9 use Shaarli\Container\ShaarliContainer
;
10 use Shaarli\Front\Exception\LoginBannedException
;
11 use Shaarli\Front\Exception\UnauthorizedException
;
12 use Shaarli\Render\PageBuilder
;
13 use Shaarli\Render\PageCacheManager
;
14 use Shaarli\Security\LoginManager
;
15 use Shaarli\Updater\Updater
;
16 use Slim\Http\Request
;
17 use Slim\Http\Response
;
20 class ShaarliMiddlewareTest
extends TestCase
22 protected const TMP_MOCK_FILE
= '.tmp';
24 /** @var ShaarliContainer */
27 /** @var ShaarliMiddleware */
28 protected $middleware;
30 public function setUp(): void
32 $this->container
= $this->createMock(ShaarliContainer
::class);
34 touch(static::TMP_MOCK_FILE
);
36 $this->container
->conf
= $this->createMock(ConfigManager
::class);
37 $this->container
->conf
->method('getConfigFileExt')->willReturn(static::TMP_MOCK_FILE
);
39 $this->container
->loginManager
= $this->createMock(LoginManager
::class);
41 $this->middleware
= new ShaarliMiddleware($this->container
);
44 public function tearDown()
46 unlink(static::TMP_MOCK_FILE
);
50 * Test middleware execution with valid controller call
52 public function testMiddlewareExecution(): void
54 $request = $this->createMock(Request
::class);
55 $request->method('getUri')->willReturnCallback(function (): Uri
{
56 $uri = $this->createMock(Uri
::class);
57 $uri->method('getBasePath')->willReturn('/subfolder');
62 $response = new Response();
63 $controller = function (Request
$request, Response
$response): Response
{
64 return $response->withStatus(418); // I'm a tea pot
67 /** @var Response $result */
68 $result = $this->middleware
->__invoke($request, $response, $controller);
70 static::assertInstanceOf(Response
::class, $result);
71 static::assertSame(418, $result->getStatusCode());
75 * Test middleware execution with controller throwing a known front exception
77 public function testMiddlewareExecutionWithFrontException(): void
79 $request = $this->createMock(Request
::class);
80 $request->method('getUri')->willReturnCallback(function (): Uri
{
81 $uri = $this->createMock(Uri
::class);
82 $uri->method('getBasePath')->willReturn('/subfolder');
87 $response = new Response();
88 $controller = function (): void {
89 $exception = new LoginBannedException();
94 $pageBuilder = $this->createMock(PageBuilder
::class);
95 $pageBuilder->method('render')->willReturnCallback(function (string $message): string {
98 $this->container
->pageBuilder
= $pageBuilder;
100 /** @var Response $result */
101 $result = $this->middleware
->__invoke($request, $response, $controller);
103 static::assertInstanceOf(Response
::class, $result);
104 static::assertSame(401, $result->getStatusCode());
105 static::assertContains('error', (string) $result->getBody());
109 * Test middleware execution with controller throwing a not authorized exception
111 public function testMiddlewareExecutionWithUnauthorizedException(): void
113 $request = $this->createMock(Request
::class);
114 $request->method('getUri')->willReturnCallback(function (): Uri
{
115 $uri = $this->createMock(Uri
::class);
116 $uri->method('getBasePath')->willReturn('/subfolder');
121 $response = new Response();
122 $controller = function (): void {
123 throw new UnauthorizedException();
126 /** @var Response $result */
127 $result = $this->middleware
->__invoke($request, $response, $controller);
129 static::assertSame(302, $result->getStatusCode());
130 static::assertSame('/subfolder/login', $result->getHeader('location')[0]);
134 * Test middleware execution with controller throwing a not authorized exception
136 public function testMiddlewareExecutionWithServerExceptionWith(): void
138 $request = $this->createMock(Request
::class);
139 $request->method('getUri')->willReturnCallback(function (): Uri
{
140 $uri = $this->createMock(Uri
::class);
141 $uri->method('getBasePath')->willReturn('/subfolder');
146 $response = new Response();
147 $controller = function (): void {
148 throw new \
Exception();
152 $this->container
->pageBuilder
= $this->createMock(PageBuilder
::class);
153 $this->container
->pageBuilder
->method('render')->willReturnCallback(function (string $message): string {
156 $this->container
->pageBuilder
158 ->willReturnCallback(function (string $key, string $value) use (&$parameters): void {
159 $parameters[$key] = $value;
163 /** @var Response $result */
164 $result = $this->middleware
->__invoke($request, $response, $controller);
166 static::assertSame(500, $result->getStatusCode());
167 static::assertContains('error', (string) $result->getBody());
168 static::assertSame('An unexpected error occurred.', $parameters['message']);
171 public function testMiddlewareExecutionWithUpdates(): void
173 $request = $this->createMock(Request
::class);
174 $request->method('getUri')->willReturnCallback(function (): Uri
{
175 $uri = $this->createMock(Uri
::class);
176 $uri->method('getBasePath')->willReturn('/subfolder');
181 $response = new Response();
182 $controller = function (Request
$request, Response
$response): Response
{
183 return $response->withStatus(418); // I'm a tea pot
186 $this->container
->loginManager
= $this->createMock(LoginManager
::class);
187 $this->container
->loginManager
->method('isLoggedIn')->willReturn(true);
189 $this->container
->conf
= $this->createMock(ConfigManager
::class);
190 $this->container
->conf
->method('get')->willReturnCallback(function (string $key): string {
193 $this->container
->conf
->method('getConfigFileExt')->willReturn(static::TMP_MOCK_FILE
);
195 $this->container
->pageCacheManager
= $this->createMock(PageCacheManager
::class);
196 $this->container
->pageCacheManager
->expects(static::once())->method('invalidateCaches');
198 $this->container
->updater
= $this->createMock(Updater
::class);
199 $this->container
->updater
200 ->expects(static::once())
202 ->willReturn(['update123'])
204 $this->container
->updater
->method('getDoneUpdates')->willReturn($updates = ['update123', 'other']);
205 $this->container
->updater
206 ->expects(static::once())
207 ->method('writeUpdates')
208 ->with('resource.updates', $updates)
211 /** @var Response $result */
212 $result = $this->middleware
->__invoke($request, $response, $controller);
214 static::assertInstanceOf(Response
::class, $result);
215 static::assertSame(418, $result->getStatusCode());