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->container
->environment
= ['REQUEST_URI' => 'http://shaarli/subfolder/path'];
43 $this->middleware
= new ShaarliMiddleware($this->container
);
46 public function tearDown(): void
48 unlink(static::TMP_MOCK_FILE
);
52 * Test middleware execution with valid controller call
54 public function testMiddlewareExecution(): void
56 $request = $this->createMock(Request
::class);
57 $request->method('getUri')->willReturnCallback(function (): Uri
{
58 $uri = $this->createMock(Uri
::class);
59 $uri->method('getBasePath')->willReturn('/subfolder');
64 $response = new Response();
65 $controller = function (Request
$request, Response
$response): Response
{
66 return $response->withStatus(418); // I'm a tea pot
69 /** @var Response $result */
70 $result = $this->middleware
->__invoke($request, $response, $controller);
72 static::assertInstanceOf(Response
::class, $result);
73 static::assertSame(418, $result->getStatusCode());
77 * Test middleware execution with controller throwing a known front exception
79 public function testMiddlewareExecutionWithFrontException(): void
81 $request = $this->createMock(Request
::class);
82 $request->method('getUri')->willReturnCallback(function (): Uri
{
83 $uri = $this->createMock(Uri
::class);
84 $uri->method('getBasePath')->willReturn('/subfolder');
89 $response = new Response();
90 $controller = function (): void {
91 $exception = new LoginBannedException();
96 $pageBuilder = $this->createMock(PageBuilder
::class);
97 $pageBuilder->method('render')->willReturnCallback(function (string $message): string {
100 $this->container
->pageBuilder
= $pageBuilder;
102 /** @var Response $result */
103 $result = $this->middleware
->__invoke($request, $response, $controller);
105 static::assertInstanceOf(Response
::class, $result);
106 static::assertSame(401, $result->getStatusCode());
107 static::assertContains('error', (string) $result->getBody());
111 * Test middleware execution with controller throwing a not authorized exception
113 public function testMiddlewareExecutionWithUnauthorizedException(): void
115 $request = $this->createMock(Request
::class);
116 $request->method('getUri')->willReturnCallback(function (): Uri
{
117 $uri = $this->createMock(Uri
::class);
118 $uri->method('getBasePath')->willReturn('/subfolder');
123 $response = new Response();
124 $controller = function (): void {
125 throw new UnauthorizedException();
128 /** @var Response $result */
129 $result = $this->middleware
->__invoke($request, $response, $controller);
131 static::assertSame(302, $result->getStatusCode());
133 '/subfolder/login?returnurl=' . urlencode('http://shaarli/subfolder/path'),
134 $result->getHeader('location')[0]
139 * Test middleware execution with controller throwing a not authorized exception
141 public function testMiddlewareExecutionWithServerExceptionWith(): void
143 $request = $this->createMock(Request
::class);
144 $request->method('getUri')->willReturnCallback(function (): Uri
{
145 $uri = $this->createMock(Uri
::class);
146 $uri->method('getBasePath')->willReturn('/subfolder');
151 $response = new Response();
152 $controller = function (): void {
153 throw new \
Exception();
157 $this->container
->pageBuilder
= $this->createMock(PageBuilder
::class);
158 $this->container
->pageBuilder
->method('render')->willReturnCallback(function (string $message): string {
161 $this->container
->pageBuilder
163 ->willReturnCallback(function (string $key, string $value) use (&$parameters): void {
164 $parameters[$key] = $value;
168 /** @var Response $result */
169 $result = $this->middleware
->__invoke($request, $response, $controller);
171 static::assertSame(500, $result->getStatusCode());
172 static::assertContains('error', (string) $result->getBody());
173 static::assertSame('An unexpected error occurred.', $parameters['message']);
176 public function testMiddlewareExecutionWithUpdates(): void
178 $request = $this->createMock(Request
::class);
179 $request->method('getUri')->willReturnCallback(function (): Uri
{
180 $uri = $this->createMock(Uri
::class);
181 $uri->method('getBasePath')->willReturn('/subfolder');
186 $response = new Response();
187 $controller = function (Request
$request, Response
$response): Response
{
188 return $response->withStatus(418); // I'm a tea pot
191 $this->container
->loginManager
= $this->createMock(LoginManager
::class);
192 $this->container
->loginManager
->method('isLoggedIn')->willReturn(true);
194 $this->container
->conf
= $this->createMock(ConfigManager
::class);
195 $this->container
->conf
->method('get')->willReturnCallback(function (string $key): string {
198 $this->container
->conf
->method('getConfigFileExt')->willReturn(static::TMP_MOCK_FILE
);
200 $this->container
->pageCacheManager
= $this->createMock(PageCacheManager
::class);
201 $this->container
->pageCacheManager
->expects(static::once())->method('invalidateCaches');
203 $this->container
->updater
= $this->createMock(Updater
::class);
204 $this->container
->updater
205 ->expects(static::once())
207 ->willReturn(['update123'])
209 $this->container
->updater
->method('getDoneUpdates')->willReturn($updates = ['update123', 'other']);
210 $this->container
->updater
211 ->expects(static::once())
212 ->method('writeUpdates')
213 ->with('resource.updates', $updates)
216 /** @var Response $result */
217 $result = $this->middleware
->__invoke($request, $response, $controller);
219 static::assertInstanceOf(Response
::class, $result);
220 static::assertSame(418, $result->getStatusCode());