Skip to content

Commit

Permalink
Add dev dependency httpsoft/http-server-request
Browse files Browse the repository at this point in the history
  • Loading branch information
devanych committed Aug 23, 2020
1 parent e854f88 commit a83be60
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 25 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"psr/http-server-middleware": "^1.0"
},
"require-dev": {
"httpsoft/http-request": "^1.0",
"httpsoft/http-server-request": "^1.0",
"phpunit/phpunit": "^9.3",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^3.14"
Expand Down
2 changes: 2 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
</projectFiles>

<issueHandlers>
<MixedArgument errorLevel="info" />
<MixedArrayAccess errorLevel="info" />
<MixedArrayOffset errorLevel="info" />
<MixedReturnTypeCoercion errorLevel="info" />
</issueHandlers>
Expand Down
7 changes: 3 additions & 4 deletions src/ErrorResponseGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use HttpSoft\Response\HtmlResponse;
use HttpSoft\Response\JsonResponse;
use HttpSoft\Response\ResponseStatusCodeInterface;
use HttpSoft\Response\TextResponse;
use HttpSoft\Response\XmlResponse;
use Psr\Http\Message\ResponseInterface;
Expand All @@ -21,7 +20,7 @@
use function trim;
use function uasort;

final class ErrorResponseGenerator implements ErrorResponseGeneratorInterface, ResponseStatusCodeInterface
final class ErrorResponseGenerator implements ErrorResponseGeneratorInterface
{
/**
* {@inheritDoc}
Expand All @@ -31,12 +30,12 @@ public function generate(Throwable $error, ServerRequestInterface $request): Res
$errorCode = (int) $error->getCode();
$responseCode = self::STATUS_INTERNAL_SERVER_ERROR;

if ($errorCode >= 400 && $errorCode < 600 && array_key_exists($errorCode, self::PHRASES)) {
if (array_key_exists($errorCode, self::ERROR_PHRASES)) {
$responseCode = $errorCode;
}

$requestMimeTypes = $this->getSortedMimeTypesByRequest($request);
return $this->getResponse($responseCode, self::PHRASES[$responseCode], $requestMimeTypes);
return $this->getResponse($responseCode, self::ERROR_PHRASES[$responseCode], $requestMimeTypes);
}

/**
Expand Down
53 changes: 52 additions & 1 deletion src/ErrorResponseGeneratorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,63 @@

namespace HttpSoft\ErrorHandler;

use HttpSoft\Response\ResponseStatusCodeInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;

interface ErrorResponseGeneratorInterface
interface ErrorResponseGeneratorInterface extends ResponseStatusCodeInterface
{
/**
* Map of error HTTP status code and reason phrases.
*
* @link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
*/
public const ERROR_PHRASES = [
// Client Errors 4xx
self::STATUS_BAD_REQUEST => 'Bad Request',
self::STATUS_UNAUTHORIZED => 'Unauthorized',
self::STATUS_PAYMENT_REQUIRED => 'Payment Required',
self::STATUS_FORBIDDEN => 'Forbidden',
self::STATUS_NOT_FOUND => 'Not Found',
self::STATUS_METHOD_NOT_ALLOWED => 'Method Not Allowed',
self::STATUS_NOT_ACCEPTABLE => 'Not Acceptable',
self::STATUS_PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required',
self::STATUS_REQUEST_TIMEOUT => 'Request Timeout',
self::STATUS_CONFLICT => 'Conflict',
self::STATUS_GONE => 'Gone',
self::STATUS_LENGTH_REQUIRED => 'Length Required',
self::STATUS_PRECONDITION_FAILED => 'Precondition Failed',
self::STATUS_PAYLOAD_TOO_LARGE => 'Payload Too Large',
self::STATUS_URI_TOO_LONG => 'URI Too Long',
self::STATUS_UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type',
self::STATUS_RANGE_NOT_SATISFIABLE => 'Range Not Satisfiable',
self::STATUS_EXPECTATION_FAILED => 'Expectation Failed',
self::STATUS_IM_A_TEAPOT => 'I\'m a teapot',
self::STATUS_MISDIRECTED_REQUEST => 'Misdirected Request',
self::STATUS_UNPROCESSABLE_ENTITY => 'Unprocessable Entity',
self::STATUS_LOCKED => 'Locked',
self::STATUS_FAILED_DEPENDENCY => 'Failed Dependency',
self::STATUS_TOO_EARLY => 'Too Early',
self::STATUS_UPGRADE_REQUIRED => 'Upgrade Required',
self::STATUS_PRECONDITION_REQUIRED => 'Precondition Required',
self::STATUS_TOO_MANY_REQUESTS => 'Too Many Requests',
self::STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large',
self::STATUS_UNAVAILABLE_FOR_LEGAL_REASONS => 'Unavailable For Legal Reasons',
// Server Errors 5xx
self::STATUS_INTERNAL_SERVER_ERROR => 'Internal Server Error',
self::STATUS_NOT_IMPLEMENTED => 'Not Implemented',
self::STATUS_BAD_GATEWAY => 'Bad Gateway',
self::STATUS_SERVICE_UNAVAILABLE => 'Service Unavailable',
self::STATUS_GATEWAY_TIMEOUT => 'Gateway Timeout',
self::STATUS_VERSION_NOT_SUPPORTED => 'HTTP Version Not Supported',
self::STATUS_VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates',
self::STATUS_INSUFFICIENT_STORAGE => 'Insufficient Storage',
self::STATUS_LOOP_DETECTED => 'Loop Detected',
self::STATUS_NOT_EXTENDED => 'Not Extended',
self::STATUS_NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required',
];

/**
* Generates an instance of `Psr\Http\Message\ResponseInterface` with information about the handled error.
*
Expand Down
16 changes: 9 additions & 7 deletions tests/ErrorHandlerMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use HttpSoft\ErrorHandler\ErrorHandlerMiddleware;
use HttpSoft\ErrorHandler\ErrorResponseGeneratorInterface;
use HttpSoft\Request\ServerRequestFactory;
use HttpSoft\ServerRequest\ServerRequestCreator;
use HttpSoft\Response\ResponseStatusCodeInterface;
use HttpSoft\Tests\ErrorHandler\TestAsset\ErrorRequestHandler;
use HttpSoft\Tests\ErrorHandler\TestAsset\ThrowableRequestHandler;
Expand All @@ -25,6 +25,8 @@

class ErrorHandlerMiddlewareTest extends TestCase implements ResponseStatusCodeInterface
{
private const PHRASES = ErrorResponseGeneratorInterface::ERROR_PHRASES;

/**
* @var int
*/
Expand All @@ -43,7 +45,7 @@ class ErrorHandlerMiddlewareTest extends TestCase implements ResponseStatusCodeI
public function setUp(): void
{
$this->errorHandler = new ErrorHandlerMiddleware();
$this->request = ServerRequestFactory::create();
$this->request = ServerRequestCreator::create();
$this->errorReporting = error_reporting();
}

Expand All @@ -57,15 +59,15 @@ public function testWithRequestHandlerAndWithStatusOk(): void
$response = $this->errorHandler->process($this->request, $this->createRequestHandler());
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_OK, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_OK], $response->getReasonPhrase());
$this->assertSame('OK', $response->getReasonPhrase());
}

public function testWithRequestHandlerAndWithStatusCreated(): void
{
$response = $this->errorHandler->process($this->request, $this->createRequestHandler(self::STATUS_CREATED));
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_CREATED, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_CREATED], $response->getReasonPhrase());
$this->assertSame('Created', $response->getReasonPhrase());
}

public function testWithRequestHandlerAndWithErrorResponseGeneratorMock(): void
Expand All @@ -74,7 +76,7 @@ public function testWithRequestHandlerAndWithErrorResponseGeneratorMock(): void
$response = $errorHandler->process($this->request, $this->createRequestHandler());
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_OK, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_OK], $response->getReasonPhrase());
$this->assertSame('OK', $response->getReasonPhrase());
}

public function testWithThrowableRequestHandlerAndWithDefaultError(): void
Expand Down Expand Up @@ -112,7 +114,7 @@ public function testWithErrorRequestHandlerAndWithoutCaughtError(): void
$response = $this->errorHandler->process($this->request, $this->createErrorRequestHandler(E_ERROR));
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_OK, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_OK], $response->getReasonPhrase());
$this->assertSame('OK', $response->getReasonPhrase());
}

public function testWithErrorRequestHandlerAndWithCaughtError(): void
Expand All @@ -134,7 +136,7 @@ public function testWithRequestHandlerAndWithAdditionOfListeners(): void

$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_OK, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_OK], $response->getReasonPhrase());
$this->assertSame('OK', $response->getReasonPhrase());

$this->assertFalse($firstListener->triggered());
$this->assertFalse($secondListener->triggered());
Expand Down
16 changes: 9 additions & 7 deletions tests/ErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use HttpSoft\ErrorHandler\ErrorHandler;
use HttpSoft\ErrorHandler\ErrorResponseGeneratorInterface;
use HttpSoft\Request\ServerRequestFactory;
use HttpSoft\ServerRequest\ServerRequestCreator;
use HttpSoft\Response\ResponseStatusCodeInterface;
use HttpSoft\Tests\ErrorHandler\TestAsset\ErrorRequestHandler;
use HttpSoft\Tests\ErrorHandler\TestAsset\ThrowableRequestHandler;
Expand All @@ -25,6 +25,8 @@

class ErrorHandlerTest extends TestCase implements ResponseStatusCodeInterface
{
private const PHRASES = ErrorResponseGeneratorInterface::ERROR_PHRASES;

/**
* @var int
*/
Expand All @@ -37,7 +39,7 @@ class ErrorHandlerTest extends TestCase implements ResponseStatusCodeInterface

public function setUp(): void
{
$this->request = ServerRequestFactory::create();
$this->request = ServerRequestCreator::create();
$this->errorReporting = error_reporting();
}

Expand All @@ -52,7 +54,7 @@ public function testWithRequestHandlerAndWithStatusOk(): void
$response = $errorHandler->handle($this->request);
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_OK, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_OK], $response->getReasonPhrase());
$this->assertSame('OK', $response->getReasonPhrase());
}

public function testWithRequestHandlerAndWithStatusCreated(): void
Expand All @@ -61,7 +63,7 @@ public function testWithRequestHandlerAndWithStatusCreated(): void
$response = $errorHandler->handle($this->request);
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_CREATED, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_CREATED], $response->getReasonPhrase());
$this->assertSame('Created', $response->getReasonPhrase());
}

public function testWithRequestHandlerAndWithErrorResponseGeneratorMock(): void
Expand All @@ -71,7 +73,7 @@ public function testWithRequestHandlerAndWithErrorResponseGeneratorMock(): void
$response = $errorHandler->handle($this->request);
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_OK, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_OK], $response->getReasonPhrase());
$this->assertSame('OK', $response->getReasonPhrase());
}

public function testWithThrowableRequestHandlerAndWithDefaultError(): void
Expand Down Expand Up @@ -107,7 +109,7 @@ public function testWithErrorRequestHandlerAndWithoutCaughtError(): void
$response = $errorHandler->handle($this->request);
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_OK, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_OK], $response->getReasonPhrase());
$this->assertSame('OK', $response->getReasonPhrase());
}

public function testWithErrorRequestHandlerAndWithCaughtError(): void
Expand All @@ -128,7 +130,7 @@ public function testWithRequestHandlerAndWithAdditionOfListeners(): void

$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame(self::STATUS_OK, $response->getStatusCode());
$this->assertSame(self::PHRASES[self::STATUS_OK], $response->getReasonPhrase());
$this->assertSame('OK', $response->getReasonPhrase());

$this->assertFalse($firstListener->triggered());
$this->assertFalse($secondListener->triggered());
Expand Down
5 changes: 4 additions & 1 deletion tests/ErrorResponseGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

use Exception;
use HttpSoft\ErrorHandler\ErrorResponseGenerator;
use HttpSoft\Request\ServerRequest;
use HttpSoft\ErrorHandler\ErrorResponseGeneratorInterface;
use HttpSoft\Message\ServerRequest;
use HttpSoft\Response\HtmlResponse;
use HttpSoft\Response\JsonResponse;
use HttpSoft\Response\ResponseStatusCodeInterface;
Expand All @@ -19,6 +20,8 @@

class ErrorResponseGeneratorTest extends TestCase implements ResponseStatusCodeInterface
{
private const PHRASES = ErrorResponseGeneratorInterface::ERROR_PHRASES;

private ErrorResponseGenerator $generator;

public function setUp(): void
Expand Down
4 changes: 2 additions & 2 deletions tests/TestAsset/ErrorRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace HttpSoft\Tests\ErrorHandler\TestAsset;

use HttpSoft\Response\ResponseFactory;
use HttpSoft\Message\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
Expand All @@ -21,6 +21,6 @@ public function handle(ServerRequestInterface $request): ResponseInterface
{
$array = [];
$array['undefined'];
return ResponseFactory::create();
return new Response();
}
}
4 changes: 2 additions & 2 deletions tests/TestAsset/RequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace HttpSoft\Tests\ErrorHandler\TestAsset;

use HttpSoft\Response\ResponseFactory;
use HttpSoft\Message\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
Expand All @@ -30,6 +30,6 @@ public function __construct(int $code = null)
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->code ? ResponseFactory::create($this->code) : ResponseFactory::create();
return $this->code ? new Response($this->code) : new Response();
}
}

0 comments on commit a83be60

Please sign in to comment.