From 2ec3660f09b194a0a4a2ef95713327e7f7c3211d Mon Sep 17 00:00:00 2001 From: Vitor de Souza Date: Wed, 1 Nov 2023 12:15:51 -0300 Subject: [PATCH 1/2] support Conflict 409 and Gone 410 --- CHANGELOG.md | 9 ++- README.md | 2 - composer.json | 1 + composer.lock | 58 ++++++++++++++++++- src/BadRequestResponseException.php | 5 +- src/ConflictResponseException.php | 9 +++ src/Factory/ResponseExceptionFactory.php | 40 ++++++------- src/ForbiddenResponseException.php | 5 +- src/GoneResponseException.php | 9 +++ src/NotFoundResponseException.php | 5 +- src/PaymentRequiredResponseException.php | 5 +- src/RequestValidationException.php | 4 +- src/UnauthorizedResponseException.php | 5 +- src/UnexpectedResponseBodyException.php | 4 +- src/UnexpectedResponseException.php | 18 +++--- .../unit/BadRequestResponseExceptionTest.php | 27 +++++---- .../unit/ConflictResponseExceptionTest.php | 34 +++++++++++ .../Factory/ResponseExceptionsFactoryTest.php | 21 +++++-- .../unit/ForbiddenResponseExceptionTest.php | 27 +++++---- test/suite/unit/GoneResponseExceptionTest.php | 34 +++++++++++ .../unit/NotFoundResponseExceptionTest.php | 27 +++++---- .../PaymentRequiredResponseExceptionTest.php | 23 +++++--- .../unit/RequestValidationExceptionTest.php | 9 +-- .../UnauthorizedResponseExceptionTest.php | 27 +++++---- .../UnexpectedResponseBodyExceptionTest.php | 9 +-- .../unit/UnexpectedResponseExceptionTest.php | 32 +++++----- 26 files changed, 320 insertions(+), 129 deletions(-) create mode 100644 src/ConflictResponseException.php create mode 100644 src/GoneResponseException.php create mode 100644 test/suite/unit/ConflictResponseExceptionTest.php create mode 100644 test/suite/unit/GoneResponseExceptionTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index d072d70..3a3577b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [3.0.0] - 2023-11-01 +### Added + - Support for HTTP status codes 409, 410 + +### Removed + - public consts from exception classes for HTTP status codes in favor of vendor lib + ## [2.0.0] - 2022-11-21 ### Added - Php 8 support @@ -16,4 +23,4 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [1.0.1] - 2020-09-28 -## [1.0.0] - 2020-09-27 \ No newline at end of file +## [1.0.0] - 2020-09-27 diff --git a/README.md b/README.md index 50bb983..65c089d 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,6 @@ This library provides the base exceptions for the generated clients made by [api vendor/bin/phpunit -See test reports in `test-reports` directory. - ## Contributing Create a branch and open PR. diff --git a/composer.json b/composer.json index fd5423b..fe9845f 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ }, "require": { "php": "^7.4 || ^8.0", + "fig/http-message-util": "^1.1", "psr/http-client": "^1.0", "psr/http-message": "^1.0" }, diff --git a/composer.lock b/composer.lock index 638e081..6926dfe 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,64 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ad19c46ad1f3db27c7c5e50c48f5896c", + "content-hash": "4bcb71e3ccaa19b7bc82f477b7c5b1b8", "packages": [ + { + "name": "fig/http-message-util", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message-util.git", + "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message-util/zipball/9d94dc0154230ac39e5bf89398b324a86f63f765", + "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "suggest": { + "psr/http-message": "The package containing the PSR-7 interfaces" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Fig\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Utility classes and constants for use with PSR-7 (psr/http-message)", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "issues": "https://github.com/php-fig/http-message-util/issues", + "source": "https://github.com/php-fig/http-message-util/tree/1.1.5" + }, + "time": "2020-11-24T22:02:12+00:00" + }, { "name": "psr/http-client", "version": "1.0.1", diff --git a/src/BadRequestResponseException.php b/src/BadRequestResponseException.php index 71f3435..d39e4ac 100644 --- a/src/BadRequestResponseException.php +++ b/src/BadRequestResponseException.php @@ -1,8 +1,9 @@ -responseExceptions = [ - BadRequestResponseException::STATUS_CODE => BadRequestResponseException::class, - UnauthorizedResponseException::STATUS_CODE => UnauthorizedResponseException::class, - PaymentRequiredResponseException::STATUS_CODE => PaymentRequiredResponseException::class, - ForbiddenResponseException::STATUS_CODE => ForbiddenResponseException::class, - NotFoundResponseException::STATUS_CODE => NotFoundResponseException::class, - ]; - } + private const RESPONSE_EXCEPTIONS = [ + StatusCodeInterface::STATUS_BAD_REQUEST => BadRequestResponseException::class, + StatusCodeInterface::STATUS_UNAUTHORIZED => UnauthorizedResponseException::class, + StatusCodeInterface::STATUS_PAYMENT_REQUIRED => PaymentRequiredResponseException::class, + StatusCodeInterface::STATUS_FORBIDDEN => ForbiddenResponseException::class, + StatusCodeInterface::STATUS_NOT_FOUND => NotFoundResponseException::class, + StatusCodeInterface::STATUS_CONFLICT => ConflictResponseException::class, + StatusCodeInterface::STATUS_GONE => GoneResponseException::class, + ]; public function create(string $message, ResponseInterface $response): UnexpectedResponseException { - if (isset($this->responseExceptions[$response->getStatusCode()])) { - return new $this->responseExceptions[$response->getStatusCode()]($message, $response); - } - - return new UnexpectedResponseException($message, $response); + return (isset(self::RESPONSE_EXCEPTIONS[$response->getStatusCode()])) + ? (new ReflectionClass(self::RESPONSE_EXCEPTIONS[$response->getStatusCode()]))->newInstance($message, $response) + : new UnexpectedResponseException($message, $response); } -} \ No newline at end of file +} diff --git a/src/ForbiddenResponseException.php b/src/ForbiddenResponseException.php index b9b44ad..8e19e5b 100644 --- a/src/ForbiddenResponseException.php +++ b/src/ForbiddenResponseException.php @@ -1,8 +1,9 @@ -response = $response; } diff --git a/test/suite/unit/BadRequestResponseExceptionTest.php b/test/suite/unit/BadRequestResponseExceptionTest.php index b4355c0..e4aee21 100644 --- a/test/suite/unit/BadRequestResponseExceptionTest.php +++ b/test/suite/unit/BadRequestResponseExceptionTest.php @@ -1,29 +1,34 @@ -createMock(ResponseInterface::class); - $response->method('getStatusCode')->willReturn($statusCode); - $sut = new BadRequestResponseException('', $response); - $this->assertInstanceOf(Throwable::class, $sut); - $this->assertEquals($statusCode, $sut->getResponse()->getStatusCode()); + /** @var ResponseInterface|MockObject $response */ + $response = $this->createMock(ResponseInterface::class); + $response + ->expects(self::once()) + ->method('getStatusCode') + ->willReturn($statusCode); + + $sut = new BadRequestResponseException('', $response); + + self::assertInstanceOf(Throwable::class, $sut); + self::assertEquals($statusCode, $sut->getResponse()->getStatusCode()); } } diff --git a/test/suite/unit/ConflictResponseExceptionTest.php b/test/suite/unit/ConflictResponseExceptionTest.php new file mode 100644 index 0000000..c351986 --- /dev/null +++ b/test/suite/unit/ConflictResponseExceptionTest.php @@ -0,0 +1,34 @@ +createMock(ResponseInterface::class); + $response + ->expects(self::once()) + ->method('getStatusCode') + ->willReturn($statusCode); + + $sut = new ConflictResponseException('', $response); + + self::assertInstanceOf(Throwable::class, $sut); + self::assertEquals($statusCode, $sut->getResponse()->getStatusCode()); + } +} diff --git a/test/suite/unit/Factory/ResponseExceptionsFactoryTest.php b/test/suite/unit/Factory/ResponseExceptionsFactoryTest.php index 5803445..dcd6cff 100644 --- a/test/suite/unit/Factory/ResponseExceptionsFactoryTest.php +++ b/test/suite/unit/Factory/ResponseExceptionsFactoryTest.php @@ -1,26 +1,29 @@ -expectException($expectedExceptionClass); + /** @var ResponseInterface|MockObject $response */ $response = $this->createMock(ResponseInterface::class); - $response->method('getStatusCode')->willReturn($statusCode); + $response + ->expects(self::atLeastOnce()) + ->method('getStatusCode') + ->willReturn($statusCode); throw $sut->create($body, $response); } @@ -45,7 +52,9 @@ public function exceptionsDataProvider(): array [402, 'payment required', PaymentRequiredResponseException::class], [403, 'forbidden', ForbiddenResponseException::class], [404, 'not found', NotFoundResponseException::class], + [409, 'conflict', ConflictResponseException::class], + [410, 'gone', GoneResponseException::class], [456, 'others', UnexpectedResponseException::class], ]; } -} \ No newline at end of file +} diff --git a/test/suite/unit/ForbiddenResponseExceptionTest.php b/test/suite/unit/ForbiddenResponseExceptionTest.php index 19f1733..028f426 100644 --- a/test/suite/unit/ForbiddenResponseExceptionTest.php +++ b/test/suite/unit/ForbiddenResponseExceptionTest.php @@ -1,29 +1,34 @@ -createMock(ResponseInterface::class); - $response->method('getStatusCode')->willReturn($statusCode); - $sut = new ForbiddenResponseException('', $response); - $this->assertInstanceOf(Throwable::class, $sut); - $this->assertEquals($statusCode, $sut->getResponse()->getStatusCode()); + /** @var ResponseInterface|MockObject $response */ + $response = $this->createMock(ResponseInterface::class); + $response + ->expects(self::once()) + ->method('getStatusCode') + ->willReturn($statusCode); + + $sut = new ForbiddenResponseException('', $response); + + self::assertInstanceOf(Throwable::class, $sut); + self::assertEquals($statusCode, $sut->getResponse()->getStatusCode()); } } diff --git a/test/suite/unit/GoneResponseExceptionTest.php b/test/suite/unit/GoneResponseExceptionTest.php new file mode 100644 index 0000000..ee6a03c --- /dev/null +++ b/test/suite/unit/GoneResponseExceptionTest.php @@ -0,0 +1,34 @@ +createMock(ResponseInterface::class); + $response + ->expects(self::once()) + ->method('getStatusCode') + ->willReturn($statusCode); + + $sut = new GoneResponseException('', $response); + + self::assertInstanceOf(Throwable::class, $sut); + self::assertEquals($statusCode, $sut->getResponse()->getStatusCode()); + } +} diff --git a/test/suite/unit/NotFoundResponseExceptionTest.php b/test/suite/unit/NotFoundResponseExceptionTest.php index 4a9e068..e994dfc 100644 --- a/test/suite/unit/NotFoundResponseExceptionTest.php +++ b/test/suite/unit/NotFoundResponseExceptionTest.php @@ -1,29 +1,34 @@ -createMock(ResponseInterface::class); - $response->method('getStatusCode')->willReturn($statusCode); - $sut = new NotFoundResponseException('', $response); - $this->assertInstanceOf(Throwable::class, $sut); - $this->assertEquals($statusCode, $sut->getResponse()->getStatusCode()); + /** @var ResponseInterface|MockObject $response */ + $response = $this->createMock(ResponseInterface::class); + $response + ->expects(self::once()) + ->method('getStatusCode') + ->willReturn($statusCode); + + $sut = new NotFoundResponseException('', $response); + + self::assertInstanceOf(Throwable::class, $sut); + self::assertEquals($statusCode, $sut->getResponse()->getStatusCode()); } } diff --git a/test/suite/unit/PaymentRequiredResponseExceptionTest.php b/test/suite/unit/PaymentRequiredResponseExceptionTest.php index 105b639..d23aa06 100644 --- a/test/suite/unit/PaymentRequiredResponseExceptionTest.php +++ b/test/suite/unit/PaymentRequiredResponseExceptionTest.php @@ -1,27 +1,32 @@ -createMock(ResponseInterface::class); - $response->method('getStatusCode')->willReturn($statusCode); - $sut = new PaymentRequiredResponseException('', $response); + + /** @var ResponseInterface|MockObject $response */ + $response = $this->createMock(ResponseInterface::class); + $response + ->expects(self::once()) + ->method('getStatusCode') + ->willReturn($statusCode); + + $sut = new PaymentRequiredResponseException('', $response); self::assertInstanceOf(Throwable::class, $sut); self::assertEquals($statusCode, $sut->getResponse()->getStatusCode()); diff --git a/test/suite/unit/RequestValidationExceptionTest.php b/test/suite/unit/RequestValidationExceptionTest.php index ef72229..a369b28 100644 --- a/test/suite/unit/RequestValidationExceptionTest.php +++ b/test/suite/unit/RequestValidationExceptionTest.php @@ -1,4 +1,6 @@ -assertInstanceOf(Throwable::class, $exception); + self::assertInstanceOf(Throwable::class, new RequestValidationException()); } } diff --git a/test/suite/unit/UnauthorizedResponseExceptionTest.php b/test/suite/unit/UnauthorizedResponseExceptionTest.php index bb89d3c..058de6f 100644 --- a/test/suite/unit/UnauthorizedResponseExceptionTest.php +++ b/test/suite/unit/UnauthorizedResponseExceptionTest.php @@ -1,29 +1,34 @@ -createMock(ResponseInterface::class); - $response->method('getStatusCode')->willReturn($statusCode); - $sut = new UnauthorizedResponseException('', $response); - $this->assertInstanceOf(Throwable::class, $sut); - $this->assertEquals($statusCode, $sut->getResponse()->getStatusCode()); + /** @var ResponseInterface|MockObject $response */ + $response = $this->createMock(ResponseInterface::class); + $response + ->expects(self::once()) + ->method('getStatusCode') + ->willReturn($statusCode); + + $sut = new UnauthorizedResponseException('', $response); + + self::assertInstanceOf(Throwable::class, $sut); + self::assertEquals($statusCode, $sut->getResponse()->getStatusCode()); } } diff --git a/test/suite/unit/UnexpectedResponseBodyExceptionTest.php b/test/suite/unit/UnexpectedResponseBodyExceptionTest.php index 08773d5..46e497f 100644 --- a/test/suite/unit/UnexpectedResponseBodyExceptionTest.php +++ b/test/suite/unit/UnexpectedResponseBodyExceptionTest.php @@ -1,4 +1,6 @@ -assertInstanceOf(Throwable::class, $exception); + self::assertInstanceOf(Throwable::class, new UnexpectedResponseBodyException()); } } diff --git a/test/suite/unit/UnexpectedResponseExceptionTest.php b/test/suite/unit/UnexpectedResponseExceptionTest.php index e003ca1..89f8639 100644 --- a/test/suite/unit/UnexpectedResponseExceptionTest.php +++ b/test/suite/unit/UnexpectedResponseExceptionTest.php @@ -1,34 +1,36 @@ -createMock(ResponseInterface::class); - $response->method('getStatusCode')->willReturn($statusCode); - $sut = new UnexpectedResponseException($errors, $response); - $this->assertInstanceOf(Throwable::class, $sut); - $this->assertEquals($statusCode, $sut->getResponse()->getStatusCode()); - $this->assertEquals( - \sprintf('%s', $errors), - $sut->getMessage() - ); + /** @var ResponseInterface|MockObject $response */ + $response = $this->createMock(ResponseInterface::class); + $response + ->expects(self::once()) + ->method('getStatusCode') + ->willReturn($statusCode); + + $sut = new UnexpectedResponseException($errors, $response); + + self::assertInstanceOf(Throwable::class, $sut); + self::assertEquals($statusCode, $sut->getResponse()->getStatusCode()); + self::assertEquals(sprintf('%s', $errors), $sut->getMessage()); } } From 2151705973b4c75ca893330a3a123f43ab294b02 Mon Sep 17 00:00:00 2001 From: Vitor de Souza Date: Thu, 2 Nov 2023 07:12:19 -0300 Subject: [PATCH 2/2] deprecate consts instead of removing --- CHANGELOG.md | 6 +++--- src/BadRequestResponseException.php | 4 ++++ src/ForbiddenResponseException.php | 4 ++++ src/NotFoundResponseException.php | 4 ++++ src/PaymentRequiredResponseException.php | 4 ++++ src/UnauthorizedResponseException.php | 4 ++++ 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a3577b..5e514af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [3.0.0] - 2023-11-01 +## [2.1.0] - 2023-11-01 ### Added - Support for HTTP status codes 409, 410 -### Removed - - public consts from exception classes for HTTP status codes in favor of vendor lib +### Changed + - Deprecated public consts from exception classes for HTTP status codes ## [2.0.0] - 2022-11-21 ### Added diff --git a/src/BadRequestResponseException.php b/src/BadRequestResponseException.php index d39e4ac..7b84912 100644 --- a/src/BadRequestResponseException.php +++ b/src/BadRequestResponseException.php @@ -4,6 +4,10 @@ namespace DoclerLabs\ApiClientException; +use Fig\Http\Message\StatusCodeInterface; + class BadRequestResponseException extends UnexpectedResponseException { + /** @deprecated */ + public const STATUS_CODE = StatusCodeInterface::STATUS_BAD_REQUEST; } diff --git a/src/ForbiddenResponseException.php b/src/ForbiddenResponseException.php index 8e19e5b..88cae3f 100644 --- a/src/ForbiddenResponseException.php +++ b/src/ForbiddenResponseException.php @@ -4,6 +4,10 @@ namespace DoclerLabs\ApiClientException; +use Fig\Http\Message\StatusCodeInterface; + class ForbiddenResponseException extends UnexpectedResponseException { + /** @deprecated */ + public const STATUS_CODE = StatusCodeInterface::STATUS_FORBIDDEN; } diff --git a/src/NotFoundResponseException.php b/src/NotFoundResponseException.php index 626d4a3..2818574 100644 --- a/src/NotFoundResponseException.php +++ b/src/NotFoundResponseException.php @@ -4,6 +4,10 @@ namespace DoclerLabs\ApiClientException; +use Fig\Http\Message\StatusCodeInterface; + class NotFoundResponseException extends UnexpectedResponseException { + /** @deprecated */ + public const STATUS_CODE = StatusCodeInterface::STATUS_NOT_FOUND; } diff --git a/src/PaymentRequiredResponseException.php b/src/PaymentRequiredResponseException.php index bd9843a..2774e89 100644 --- a/src/PaymentRequiredResponseException.php +++ b/src/PaymentRequiredResponseException.php @@ -4,6 +4,10 @@ namespace DoclerLabs\ApiClientException; +use Fig\Http\Message\StatusCodeInterface; + class PaymentRequiredResponseException extends UnexpectedResponseException { + /** @deprecated */ + public const STATUS_CODE = StatusCodeInterface::STATUS_PAYMENT_REQUIRED; } diff --git a/src/UnauthorizedResponseException.php b/src/UnauthorizedResponseException.php index 9014632..55e644f 100644 --- a/src/UnauthorizedResponseException.php +++ b/src/UnauthorizedResponseException.php @@ -4,6 +4,10 @@ namespace DoclerLabs\ApiClientException; +use Fig\Http\Message\StatusCodeInterface; + class UnauthorizedResponseException extends UnexpectedResponseException { + /** @deprecated */ + public const STATUS_CODE = StatusCodeInterface::STATUS_UNAUTHORIZED; }