Improved response middleware, added tests

This commit is contained in:
Chris 2024-03-13 22:20:54 +01:00
parent 7c14b51333
commit 952b13535d
3 changed files with 71 additions and 11 deletions

View File

@ -24,7 +24,7 @@ phpstan: ## Run static analysis
.PHONY: phpunit
phpunit: ## Run unit tests
@phpunit --testdox --no-progress
@phpunit --testdox --no-progress --display-warnings
.PHONY: coverage
coverage: ## Code coverage

View File

@ -35,7 +35,14 @@ class ResponseMiddleware
{
$promise = new Promise(
function (callable $resolve) use ($request, $next) {
$resolve($next($request));
try {
$resolve($next($request));
} catch (SecurityException $t) {
$resolve(Response::plaintext("Access Denied")->withStatus(Response::STATUS_UNAUTHORIZED));
} catch (\Throwable $t) {
$this->logger->warning(get_class($t).": ".$t->getMessage(), [ 'file'=>$t->getFile(), 'line'=>$t->getLine() ]);
$resolve(Response::plaintext("500: Internal Server Error (".$t->getMessage().")\n")->withStatus(500));
}
}
);
return $promise->then(
@ -50,19 +57,10 @@ class ResponseMiddleware
return Response::plaintext($response);
}
return Response::plaintext((string)$response);
},
function (Throwable $t) {
if ($t instanceof SecurityException) {
return Response::plaintext("Access Denied")->withStatus(Response::STATUS_UNAUTHORIZED);
}
$this->logger->warning(get_class($t).": ".$t->getMessage(), [ 'file'=>$t->getFile(), 'line'=>$t->getLine() ]);
return Response::plaintext("500: Internal Server Error (".$t->getMessage().")\n")->withStatus(500);
}
)->then(
function ($response) use ($request) {
assert("\$response instanceof ResponseInterface");
$host = ($request->getServerParams()['SERVER_ADDR']??"");
//. ":" . ($request->getServerParams()['SERVER_PORT']??"80");
$this->logger->debug(sprintf("%s %s %s → %3d (%d)",
$request->getServerParams()['REMOTE_ADDR'],
$request->getMethod(),

View File

@ -0,0 +1,62 @@
<?php
namespace NoccyLabs\Mercureact\Http\Middleware;
use NoccyLabs\Mercureact\Configuration;
use NoccyLabs\Mercureact\Exception\SecurityException;
use PHPUnit\Framework\Attributes\CoversClass;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\NullLogger;
use React\Http\Message\Response;
use React\Http\Message\ServerRequest;
#[CoversClass(ResponseMiddleware::class)]
#[CoversClass(Configuration::class)]
class ResponseMiddlewareTest extends \PHPUnit\Framework\TestCase
{
public function testResponseIsValid()
{
$logger = new NullLogger();
$config = Configuration::createDefault();
$request = new ServerRequest("GET", "/", serverParams:['REMOTE_ADDR'=>'127.0.0.1']);
$return = null; // chained response
$next = function ($chainedRequest) use ($request, &$return) {
$this->assertInstanceOf(ServerRequestInterface::class, $chainedRequest);
$return = $chainedRequest;
return "response";
};
$middleware = new ResponseMiddleware($config, $logger);
$middleware->__invoke($request, $next)->then(function ($result) {
$this->assertInstanceOf(Response::class, $result);
$this->assertEquals("response", $result->getBody());
});
}
public function testSecurityExceptionsAreHandled()
{
$logger = new NullLogger();
$config = Configuration::createDefault();
$request = new ServerRequest("GET", "/", serverParams:['REMOTE_ADDR'=>'127.0.0.1']);
$return = null; // chained response
$next = function ($chainedRequest) use ($request, &$return) {
$this->assertInstanceOf(ServerRequestInterface::class, $chainedRequest);
$return = $chainedRequest;
throw new SecurityException();
};
$middleware = new ResponseMiddleware($config, $logger);
$middleware->__invoke($request, $next)->then(function ($result) {
$this->assertInstanceOf(Response::class, $result);
$this->assertEquals("Access Denied", (string)$result->getBody());
});
}
}