Implemented HttpException

This commit is contained in:
Igor Scheller 2018-11-13 17:48:07 +01:00 committed by msquare
parent 2588bbf7bc
commit 9788c5095a
4 changed files with 137 additions and 1 deletions

View File

@ -0,0 +1,51 @@
<?php
namespace Engelsystem\Http\Exceptions;
use RuntimeException;
use Throwable;
class HttpException extends RuntimeException
{
/** @var int */
protected $statusCode;
/** @var array */
protected $headers = [];
/**
* @param int $statusCode
* @param string $message
* @param array $headers
* @param int $code
* @param Throwable|null $previous
*/
public function __construct(
int $statusCode,
string $message = '',
array $headers = [],
int $code = 0,
Throwable $previous = null
) {
$this->headers = $headers;
$this->statusCode = $statusCode;
parent::__construct($message, $code, $previous);
}
/**
* @return array
*/
public function getHeaders(): array
{
return $this->headers;
}
/**
* @return int
*/
public function getStatusCode(): int
{
return $this->statusCode;
}
}

View File

@ -2,6 +2,7 @@
namespace Engelsystem\Middleware; namespace Engelsystem\Middleware;
use Engelsystem\Http\Exceptions\HttpException;
use Engelsystem\Http\Response; use Engelsystem\Http\Response;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
@ -38,7 +39,11 @@ class ErrorHandler implements MiddlewareInterface
ServerRequestInterface $request, ServerRequestInterface $request,
RequestHandlerInterface $handler RequestHandlerInterface $handler
): ResponseInterface { ): ResponseInterface {
$response = $handler->handle($request); try {
$response = $handler->handle($request);
} catch (HttpException $e) {
$response = $this->createResponse($e->getMessage(), $e->getStatusCode(), $e->getHeaders());
}
$statusCode = $response->getStatusCode(); $statusCode = $response->getStatusCode();
if ($statusCode < 400 || !$response instanceof Response) { if ($statusCode < 400 || !$response instanceof Response) {
@ -77,4 +82,18 @@ class ErrorHandler implements MiddlewareInterface
return 'default'; return 'default';
} }
/**
* Create a new response
*
* @param string $content
* @param int $status
* @param array $headers
* @return Response
* @codeCoverageIgnore
*/
protected function createResponse(string $content = '', int $status = 200, array $headers = [])
{
return response($content, $status, $headers);
}
} }

View File

@ -0,0 +1,26 @@
<?php
namespace Engelsystem\Test\Unit\Http\Exceptions;
use Engelsystem\Http\Exceptions\HttpException;
use PHPUnit\Framework\TestCase;
class HttpExceptionTest extends TestCase
{
/**
* @covers \Engelsystem\Http\Exceptions\HttpException::__construct
* @covers \Engelsystem\Http\Exceptions\HttpException::getStatusCode
* @covers \Engelsystem\Http\Exceptions\HttpException::getHeaders
*/
public function testConstruct()
{
$exception = new HttpException(123);
$this->assertEquals(123, $exception->getStatusCode());
$this->assertEquals('', $exception->getMessage());
$this->assertEquals([], $exception->getHeaders());
$exception = new HttpException(404, 'Nothing found', ['page' => '/test']);
$this->assertEquals('Nothing found', $exception->getMessage());
$this->assertEquals(['page' => '/test'], $exception->getHeaders());
}
}

View File

@ -2,6 +2,7 @@
namespace Engelsystem\Test\Unit\Middleware; namespace Engelsystem\Test\Unit\Middleware;
use Engelsystem\Http\Exceptions\HttpException;
use Engelsystem\Http\Response; use Engelsystem\Http\Response;
use Engelsystem\Middleware\ErrorHandler; use Engelsystem\Middleware\ErrorHandler;
use Engelsystem\Test\Unit\Middleware\Stub\ReturnResponseMiddlewareHandler; use Engelsystem\Test\Unit\Middleware\Stub\ReturnResponseMiddlewareHandler;
@ -85,4 +86,43 @@ class ErrorHandlerTest extends TestCase
$errorHandler->process($request, $returnResponseHandler); $errorHandler->process($request, $returnResponseHandler);
$errorHandler->process($request, $returnResponseHandler); $errorHandler->process($request, $returnResponseHandler);
} }
/**
* @covers \Engelsystem\Middleware\ErrorHandler::process
*/
public function testProcessException()
{
/** @var ServerRequestInterface|MockObject $request */
$request = $this->createMock(ServerRequestInterface::class);
/** @var ResponseInterface|MockObject $psrResponse */
$psrResponse = $this->getMockForAbstractClass(ResponseInterface::class);
/** @var ReturnResponseMiddlewareHandler|MockObject $returnResponseHandler */
$returnResponseHandler = $this->getMockBuilder(ReturnResponseMiddlewareHandler::class)
->disableOriginalConstructor()
->getMock();
$psrResponse->expects($this->once())
->method('getStatusCode')
->willReturn(300);
$returnResponseHandler->expects($this->once())
->method('handle')
->willReturnCallback(function () {
throw new HttpException(300, 'Some response', ['lor' => 'em']);
});
/** @var ErrorHandler|MockObject $errorHandler */
$errorHandler = $this->getMockBuilder(ErrorHandler::class)
->disableOriginalConstructor()
->setMethods(['createResponse'])
->getMock();
$errorHandler->expects($this->once())
->method('createResponse')
->with('Some response', 300, ['lor' => 'em'])
->willReturn($psrResponse);
$return = $errorHandler->process($request, $returnResponseHandler);
$this->assertEquals($psrResponse, $return);
}
} }