From 35a52fedffee40a0f1e4edc5d95373b451f7d52d Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Tue, 3 Jun 2025 03:29:24 -0500 Subject: [PATCH 1/6] Update PHP version, dependencies, and configuration Added support for PHP 8.4 in workflows and updated dependency versions for compatibility. Adjusted PHPUnit configuration for more robust error reporting and updated schema to PHPUnit 10.5. Corrected VSCode debug port and improved README formatting. --- .github/workflows/phpunit.yml | 1 + .vscode/launch.json | 4 ++-- README.md | 4 ++-- composer.json | 10 +++++----- phpunit.xml.dist | 30 +++++++++++++++--------------- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 5c0b2ec..82582f3 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -16,6 +16,7 @@ jobs: strategy: matrix: php-version: + - "8.4" - "8.3" - "8.2" - "8.1" diff --git a/.vscode/launch.json b/.vscode/launch.json index bf0bc51..e6be422 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -46,7 +46,7 @@ "request": "launch", "program": "${file}", "cwd": "${fileDirname}", - "port": 0, + "port": 9003, "runtimeArgs": [ "-dxdebug.start_with_request=yes" ], @@ -61,7 +61,7 @@ "request": "launch", "program": "${workspaceFolder}/vendor/bin/phpunit", "cwd": "${workspaceFolder}", - "port": 0, + "port": 9003, "runtimeArgs": [ "-dxdebug.start_with_request=yes" ], diff --git a/README.md b/README.md index 41a2797..e5bbaec 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -# PHP Swagger Test - [![Build Status](https://github.com/byjg/php-swagger-test/actions/workflows/phpunit.yml/badge.svg?branch=master)](https://github.com/byjg/php-swagger-test/actions/workflows/phpunit.yml) [![Opensource ByJG](https://img.shields.io/badge/opensource-byjg-success.svg)](http://opensource.byjg.com) [![GitHub source](https://img.shields.io/badge/Github-source-informational?logo=github)](https://github.com/byjg/php-swagger-test/) @@ -7,6 +5,8 @@ [![GitHub release](https://img.shields.io/github/release/byjg/php-swagger-test.svg)](https://github.com/byjg/php-swagger-test/releases/) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/byjg/php-swagger-test/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/byjg/php-swagger-test/?branch=master) +# PHP Swagger Test + A set of tools for testing your REST calls based on the OpenApi specification using PHPUnit. Currently, this library supports the OpenApi specifications `2.0` (formerly swagger) and `3.0`. Some features like callbacks, links and references to external documents/objects weren't implemented. diff --git a/composer.json b/composer.json index 064e2d3..a24269f 100644 --- a/composer.json +++ b/composer.json @@ -5,14 +5,14 @@ "prefer-stable": true, "license": "MIT", "require": { - "php": ">=8.1 <8.4", + "php": ">=8.1 <8.5", "ext-json": "*", - "byjg/webrequest": "^5.0" + "byjg/webrequest": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^9.6", - "byjg/restserver": "^5.0", - "vimeo/psalm": "^5.9" + "phpunit/phpunit": "^10.5|^11.5", + "byjg/restserver": "^6.0", + "vimeo/psalm": "^5.9|^6.2" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8441f55..dfdc156 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -6,31 +6,31 @@ and open the template in the editor. --> - + displayDetailsOnTestsThatTriggerDeprecations="true" + displayDetailsOnTestsThatTriggerErrors="true" + displayDetailsOnTestsThatTriggerNotices="true" + displayDetailsOnTestsThatTriggerWarnings="true" + displayDetailsOnPhpunitDeprecations="true" + stopOnFailure="false" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"> - + - - - - ./src - - - + + + ./src/ + + ./tests/ - From fa96678f7f25bb0980d2c6af227043ba1f041301 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Tue, 3 Jun 2025 03:46:25 -0500 Subject: [PATCH 2/6] Add strict type declarations to classes and test methods Updated method signatures and class properties across various files with strict type declarations. This enhances type safety and ensures better compatibility with modern PHP practices. --- src/AbstractRequester.php | 6 +-- src/Base/Body.php | 8 ++-- src/Base/Schema.php | 4 +- src/Exception/BaseException.php | 2 +- src/OpenApi/OpenApiSchema.php | 4 +- src/Swagger/SwaggerSchema.php | 8 ++-- tests/AbstractRequesterTest.php | 26 +++++------ tests/BaseExceptionTest.php | 2 +- tests/Classes/Category.php | 26 +++++------ tests/Classes/Handler.php | 6 +-- tests/Classes/Pet.php | 74 +++++++++++++++---------------- tests/Classes/Tag.php | 26 +++++------ tests/OpenApiRequestBodyTest.php | 31 ++++++------- tests/OpenApiResponseBodyTest.php | 45 +++++++++---------- tests/OpenApiSchemaTest.php | 59 +++++++++++------------- tests/SwaggerRequestBodyTest.php | 23 +++++----- tests/SwaggerResponseBodyTest.php | 45 +++++++++---------- tests/SwaggerSchemaTest.php | 30 ++++++------- tests/TestingTestCase.php | 14 +++--- 19 files changed, 207 insertions(+), 232 deletions(-) diff --git a/src/AbstractRequester.php b/src/AbstractRequester.php index 18ad4ad..e50f852 100644 --- a/src/AbstractRequester.php +++ b/src/AbstractRequester.php @@ -12,11 +12,11 @@ use ByJG\ApiTools\Exception\PathNotFoundException; use ByJG\ApiTools\Exception\RequiredArgumentNotFound; use ByJG\ApiTools\Exception\StatusCodeNotMatchedException; +use ByJG\Util\Uri; use ByJG\WebRequest\Exception\MessageException; use ByJG\WebRequest\Exception\RequestException; -use ByJG\WebRequest\Psr7\Request; -use ByJG\Util\Uri; use ByJG\WebRequest\Psr7\MemoryStream; +use ByJG\WebRequest\Psr7\Request; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -126,7 +126,7 @@ public function withRequestHeader(string|array $requestHeader): self * @param array|null $query * @return $this */ - public function withQuery(array $query = null): self + public function withQuery(?array $query = null): self { $uri = $this->psr7Request->getUri(); diff --git a/src/Base/Body.php b/src/Base/Body.php index 180a5fe..ea25709 100644 --- a/src/Base/Body.php +++ b/src/Base/Body.php @@ -96,7 +96,9 @@ protected function matchString(string $name, array $schemaArray, mixed $body, mi } /** - * @throws NotMatchedException + * @param numeric $body + *@throws NotMatchedException + * */ private function checkPattern(string $name, mixed $body, string $pattern): void { @@ -330,8 +332,8 @@ public function matchObjectProperties(string $name, mixed $schemaArray, mixed $b /** * @param string $name - * @param array $schemaArray - * @param array $body + * @param mixed $schemaArray + * @param mixed $body * @return ?bool * @throws DefinitionNotFoundException * @throws InvalidDefinitionException diff --git a/src/Base/Schema.php b/src/Base/Schema.php index 992496c..deb302a 100644 --- a/src/Base/Schema.php +++ b/src/Base/Schema.php @@ -184,12 +184,12 @@ abstract protected function validateArguments(string $parameterIn, array $parame abstract public function getBasePath(): string; /** - * @param $name + * @param string $name * @return mixed * @throws DefinitionNotFoundException * @throws InvalidDefinitionException */ - abstract public function getDefinition($name): mixed; + abstract public function getDefinition(string $name): mixed; /** * @param string $path diff --git a/src/Exception/BaseException.php b/src/Exception/BaseException.php index ac6ad73..8e71199 100644 --- a/src/Exception/BaseException.php +++ b/src/Exception/BaseException.php @@ -9,7 +9,7 @@ class BaseException extends Exception { protected mixed $body; - public function __construct($message = "", $body = [], $code = 0, Throwable $previous = null) + public function __construct(string $message = "", mixed $body = [], int $code = 0, ?Throwable $previous = null) { $this->body = $body; if (!empty($body)) { diff --git a/src/OpenApi/OpenApiSchema.php b/src/OpenApi/OpenApiSchema.php index 0880609..ce1bd86 100644 --- a/src/OpenApi/OpenApiSchema.php +++ b/src/OpenApi/OpenApiSchema.php @@ -86,12 +86,12 @@ protected function validateArguments(string $parameterIn, array $parameters, arr } /** - * @param $name + * @param string $name * @return mixed * @throws DefinitionNotFoundException * @throws InvalidDefinitionException */ - public function getDefinition($name): mixed + public function getDefinition(string $name): mixed { $nameParts = explode('/', $name); diff --git a/src/Swagger/SwaggerSchema.php b/src/Swagger/SwaggerSchema.php index af432ef..0fd4c9e 100644 --- a/src/Swagger/SwaggerSchema.php +++ b/src/Swagger/SwaggerSchema.php @@ -27,12 +27,12 @@ public function __construct(array|string $data, bool $allowNullValues = false) $this->allowNullValues = $allowNullValues; } - public function getHttpSchema() + public function getHttpSchema(): string { return isset($this->jsonFile['schemes']) ? $this->jsonFile['schemes'][0] : ''; } - public function getHost() + public function getHost(): string { return $this->jsonFile['host'] ?? ''; } @@ -68,12 +68,12 @@ protected function validateArguments(string $parameterIn, array $parameters, arr } /** - * @param $name + * @param string $name * @return mixed * @throws DefinitionNotFoundException * @throws InvalidDefinitionException */ - public function getDefinition($name): mixed + public function getDefinition(string $name): mixed { $nameParts = explode('/', $name); diff --git a/tests/AbstractRequesterTest.php b/tests/AbstractRequesterTest.php index 0c4a1db..b9199a3 100644 --- a/tests/AbstractRequesterTest.php +++ b/tests/AbstractRequesterTest.php @@ -13,12 +13,12 @@ use ByJG\ApiTools\Exception\RequiredArgumentNotFound; use ByJG\ApiTools\Exception\StatusCodeNotMatchedException; use ByJG\ApiTools\MockRequester; +use ByJG\Util\Uri; use ByJG\WebRequest\Exception\MessageException; use ByJG\WebRequest\Exception\RequestException; +use ByJG\WebRequest\Psr7\MemoryStream; use ByJG\WebRequest\Psr7\Request; use ByJG\WebRequest\Psr7\Response; -use ByJG\Util\Uri; -use ByJG\WebRequest\Psr7\MemoryStream; abstract class AbstractRequesterTest extends ApiTestCase { @@ -35,7 +35,7 @@ abstract class AbstractRequesterTest extends ApiTestCase * @throws MessageException * @throws InvalidDefinitionException */ - public function testExpectOK() + public function testExpectOK(): void { $expectedResponse = Response::getInstance(200) ->withBody(new MemoryStream(json_encode([ @@ -75,7 +75,7 @@ public function testExpectOK() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testExpectError() + public function testExpectError(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Required property 'name'"); @@ -107,7 +107,7 @@ public function testExpectError() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testValidateAssertResponse() + public function testValidateAssertResponse(): void { $expectedResponse = Response::getInstance(200) ->withBody(new MemoryStream(json_encode([ @@ -138,7 +138,7 @@ public function testValidateAssertResponse() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testValidateAssertResponse404() + public function testValidateAssertResponse404(): void { $expectedResponse = Response::getInstance(404); @@ -164,7 +164,7 @@ public function testValidateAssertResponse404() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testValidateAssertResponse404WithContent() + public function testValidateAssertResponse404WithContent(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Expected empty body for GET 404 /v2/pet/1"); @@ -194,7 +194,7 @@ public function testValidateAssertResponse404WithContent() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testValidateAssertResponseNotExpected() + public function testValidateAssertResponseNotExpected(): void { $this->expectException(\ByJG\ApiTools\Exception\StatusCodeNotMatchedException::class); $this->expectExceptionMessage("Status code not matched: Expected 404, got 522"); @@ -223,7 +223,7 @@ public function testValidateAssertResponseNotExpected() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testValidateAssertHeaderContains() + public function testValidateAssertHeaderContains(): void { $expectedResponse = Response::getInstance(200) ->withBody(new MemoryStream(json_encode([ @@ -256,7 +256,7 @@ public function testValidateAssertHeaderContains() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testValidateAssertHeaderContainsWrongValue() + public function testValidateAssertHeaderContainsWrongValue(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Does not exists header 'X-Test' with value 'Different'"); @@ -292,7 +292,7 @@ public function testValidateAssertHeaderContainsWrongValue() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testValidateAssertHeaderContainsNonExistent() + public function testValidateAssertHeaderContainsNonExistent(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Does not exists header 'X-Test' with value 'Different'"); @@ -327,7 +327,7 @@ public function testValidateAssertHeaderContainsNonExistent() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testValidateAssertBodyContains() + public function testValidateAssertBodyContains(): void { $expectedResponse = Response::getInstance(200) ->withBody(new MemoryStream(json_encode([ @@ -359,7 +359,7 @@ public function testValidateAssertBodyContains() * @throws MessageException * @throws RequestException */ - public function testValidateAssertBodyNotContains() + public function testValidateAssertBodyNotContains(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Body does not contain 'Doris'"); diff --git a/tests/BaseExceptionTest.php b/tests/BaseExceptionTest.php index da91dbb..cac0cab 100644 --- a/tests/BaseExceptionTest.php +++ b/tests/BaseExceptionTest.php @@ -8,7 +8,7 @@ class BaseExceptionTest extends TestCase { - public function testGetBody() + public function testGetBody(): void { $exception = new GenericSwaggerException("message", ["a" => 10]); diff --git a/tests/Classes/Category.php b/tests/Classes/Category.php index 8a03cfd..02149c8 100644 --- a/tests/Classes/Category.php +++ b/tests/Classes/Category.php @@ -4,15 +4,15 @@ class Category { - protected $id; - protected $name; + protected int $id; + protected string $name; /** * Category constructor. - * @param $id - * @param $name + * @param int $id + * @param string $name */ - public function __construct($id, $name) + public function __construct(int $id, string $name) { $this->id = $id; $this->name = $name; @@ -20,33 +20,33 @@ public function __construct($id, $name) /** - * @return mixed + * @return int */ - public function getId() + public function getId(): int { return $this->id; } /** - * @param mixed $id + * @param int $id */ - public function setId($id) + public function setId(int $id): void { $this->id = $id; } /** - * @return mixed + * @return string */ - public function getName() + public function getName(): string { return $this->name; } /** - * @param mixed $name + * @param string $name */ - public function setName($name) + public function setName(string $name): void { $this->name = $name; } diff --git a/tests/Classes/Handler.php b/tests/Classes/Handler.php index a18cae0..63ab503 100644 --- a/tests/Classes/Handler.php +++ b/tests/Classes/Handler.php @@ -12,7 +12,7 @@ class Handler * @param HttpResponse $response * @param HttpRequest $request */ - public function getPetById($response, $request) + public function getPetById($response, $request): void { $pet = new Pet( $request->param("petId"), @@ -29,7 +29,7 @@ public function getPetById($response, $request) * @param HttpResponse $response * @param HttpRequest $request */ - public function addPet($response, $request) + public function addPet($response, $request): void { $pet = new Pet(); ObjectCopy::copy(json_decode($request->payload()), $pet); @@ -46,7 +46,7 @@ public function addPet($response, $request) * @param HttpResponse $response * @param HttpRequest $request */ - public function processUpload($response, $request) + public function processUpload($response, $request): void { $pet = new Pet( 200, diff --git a/tests/Classes/Pet.php b/tests/Classes/Pet.php index c556e2d..0c76fa0 100644 --- a/tests/Classes/Pet.php +++ b/tests/Classes/Pet.php @@ -4,23 +4,23 @@ class Pet { - protected $id; - protected $category; - protected $name; - protected $photoUrls; - protected $tags; - protected $status; + protected int $id; + protected ?object $category; + protected string $name; + protected array $photoUrls; + protected array $tags; + protected string $status; /** * Pet constructor. - * @param $id - * @param $category - * @param $name - * @param $photoUrls - * @param $tags - * @param $status + * @param int $id + * @param object|null $category + * @param string $name + * @param array $photoUrls + * @param array $tags + * @param string $status */ - public function __construct($id = "", $category = "", $name = "", $photoUrls = "", $tags = "", $status = "") + public function __construct(int $id = 0, ?object $category = null, string $name = "", array $photoUrls = [], array $tags = [], string $status = "") { $this->id = $id; $this->category = $category; @@ -32,97 +32,97 @@ public function __construct($id = "", $category = "", $name = "", $photoUrls = " /** - * @return mixed + * @return int */ - public function getId() + public function getId(): int { return $this->id; } /** - * @param mixed $id + * @param int $id */ - public function setId($id) + public function setId(int $id): void { $this->id = $id; } /** - * @return mixed + * @return object|null */ - public function getCategory() + public function getCategory(): ?object { return $this->category; } /** - * @param mixed $category + * @param object|null $category */ - public function setCategory($category) + public function setCategory(?object $category): void { $this->category = $category; } /** - * @return mixed + * @return string */ - public function getName() + public function getName(): string { return $this->name; } /** - * @param mixed $name + * @param string $name */ - public function setName($name) + public function setName(string $name): void { $this->name = $name; } /** - * @return mixed + * @return array */ - public function getPhotoUrls() + public function getPhotoUrls(): array { return $this->photoUrls; } /** - * @param mixed $photoUrls + * @param array $photoUrls */ - public function setPhotoUrls($photoUrls) + public function setPhotoUrls(array $photoUrls): void { $this->photoUrls = $photoUrls; } /** - * @return mixed + * @return array */ - public function getTags() + public function getTags(): array { return $this->tags; } /** - * @param mixed $tags + * @param array $tags */ - public function setTags($tags) + public function setTags(array $tags): void { $this->tags = $tags; } /** - * @return mixed + * @return string */ - public function getStatus() + public function getStatus(): string { return $this->status; } /** - * @param mixed $status + * @param string $status */ - public function setStatus($status) + public function setStatus(string $status): void { $this->status = $status; } diff --git a/tests/Classes/Tag.php b/tests/Classes/Tag.php index 383281a..dc219db 100644 --- a/tests/Classes/Tag.php +++ b/tests/Classes/Tag.php @@ -4,48 +4,48 @@ class Tag { - protected $id; - protected $name; + protected int $id; + protected string $name; /** * Category constructor. - * @param $id - * @param $name + * @param int $id + * @param string $name */ - public function __construct($id, $name) + public function __construct(int $id, string $name) { $this->id = $id; $this->name = $name; } /** - * @return mixed + * @return int */ - public function getId() + public function getId(): int { return $this->id; } /** - * @param mixed $id + * @param int $id */ - public function setId($id) + public function setId(int $id): void { $this->id = $id; } /** - * @return mixed + * @return string */ - public function getName() + public function getName(): string { return $this->name; } /** - * @param mixed $name + * @param string $name */ - public function setName($name) + public function setName(string $name): void { $this->name = $name; } diff --git a/tests/OpenApiRequestBodyTest.php b/tests/OpenApiRequestBodyTest.php index c16b8ee..fffbb7c 100644 --- a/tests/OpenApiRequestBodyTest.php +++ b/tests/OpenApiRequestBodyTest.php @@ -21,7 +21,7 @@ class OpenApiRequestBodyTest extends OpenApiBodyTestCase * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBody() + public function testMatchRequestBody(): void { $body = [ "id" => "10", @@ -37,7 +37,6 @@ public function testMatchRequestBody() } /** - * * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException * @throws \ByJG\ApiTools\Exception\GenericSwaggerException * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException @@ -47,7 +46,7 @@ public function testMatchRequestBody() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequiredRequestBodyEmpty() + public function testMatchRequiredRequestBodyEmpty(): void { $this->expectException(\ByJG\ApiTools\Exception\RequiredArgumentNotFound::class); $this->expectExceptionMessage("The body is required"); @@ -57,7 +56,6 @@ public function testMatchRequiredRequestBodyEmpty() } /** - * * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException * @throws \ByJG\ApiTools\Exception\GenericSwaggerException * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException @@ -67,7 +65,7 @@ public function testMatchRequiredRequestBodyEmpty() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchInexistantBodyDefinition() + public function testMatchInexistantBodyDefinition(): void { $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); $this->expectExceptionMessage("Body is passed but there is no request body definition"); @@ -86,7 +84,6 @@ public function testMatchInexistantBodyDefinition() } /** - * * @throws DefinitionNotFoundException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException @@ -94,7 +91,7 @@ public function testMatchInexistantBodyDefinition() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testMatchDataType() + public function testMatchDataType(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Path expected an integer value"); @@ -113,7 +110,7 @@ public function testMatchDataType() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testMatchParameterInQuery() + public function testMatchParameterInQuery(): void { self::openApiSchema()->getRequestParameters('/v2/pet/findByStatus?status=pending', 'get'); $this->assertTrue(true); @@ -127,14 +124,13 @@ public function testMatchParameterInQuery() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testMatchParameterInQuery2() + public function testMatchParameterInQuery2(): void { self::openApiSchema3()->getRequestParameters('/tests/12345?count=20&offset=2', 'get'); $this->assertTrue(true); } /** - * * @throws DefinitionNotFoundException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException @@ -142,7 +138,7 @@ public function testMatchParameterInQuery2() * @throws PathNotFoundException * @throws InvalidRequestException */ - public function testMatchParameterInQuery3() + public function testMatchParameterInQuery3(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Path expected an integer value"); @@ -153,7 +149,6 @@ public function testMatchParameterInQuery3() /** - * * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException * @throws \ByJG\ApiTools\Exception\GenericSwaggerException * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException @@ -163,7 +158,7 @@ public function testMatchParameterInQuery3() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequired1() + public function testMatchRequestBodyRequired1(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Required property"); @@ -190,7 +185,7 @@ public function testMatchRequestBodyRequired1() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequiredNullsNotAllowed() + public function testMatchRequestBodyRequiredNullsNotAllowed(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Value of property 'name' is null, but should be of type 'string'"); @@ -216,7 +211,7 @@ public function testMatchRequestBodyRequiredNullsNotAllowed() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequiredNullsAllowed() + public function testMatchRequestBodyRequiredNullsAllowed(): void { $allowNullValues = true; $body = [ @@ -243,7 +238,7 @@ public function testMatchRequestBodyRequiredNullsAllowed() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequired3() + public function testMatchRequestBodyRequired3(): void { $body = [ "id" => "10", @@ -268,7 +263,7 @@ public function testMatchRequestBodyRequired3() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequired_Issue21() + public function testMatchRequestBodyRequired_Issue21(): void { // Full Request $body = [ @@ -292,7 +287,7 @@ public function testMatchRequestBodyRequired_Issue21() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequired_Issue21_Required() + public function testMatchRequestBodyRequired_Issue21_Required(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Required property 'user_uuid'"); diff --git a/tests/OpenApiResponseBodyTest.php b/tests/OpenApiResponseBodyTest.php index 8bcce37..d3b2c55 100644 --- a/tests/OpenApiResponseBodyTest.php +++ b/tests/OpenApiResponseBodyTest.php @@ -23,7 +23,7 @@ class OpenApiResponseBodyTest extends OpenApiBodyTestCase * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBody() + public function testMatchResponseBody(): void { $openApiSchema = self::openApiSchema(); @@ -75,7 +75,7 @@ public function testMatchResponseBody() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyWithRefInsteadOfContent() + public function testMatchResponseBodyWithRefInsteadOfContent(): void { $openApiSchema = self::openApiSchema5(); @@ -89,7 +89,6 @@ public function testMatchResponseBodyWithRefInsteadOfContent() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -99,7 +98,7 @@ public function testMatchResponseBodyWithRefInsteadOfContent() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyEnumError() + public function testMatchResponseBodyEnumError(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Value 'notfound' in 'status' not matched in ENUM"); @@ -118,7 +117,6 @@ public function testMatchResponseBodyEnumError() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -128,7 +126,7 @@ public function testMatchResponseBodyEnumError() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyWrongNumber() + public function testMatchResponseBodyWrongNumber(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Expected 'id' to be numeric, but found 'ABC'"); @@ -147,7 +145,6 @@ public function testMatchResponseBodyWrongNumber() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -157,7 +154,7 @@ public function testMatchResponseBodyWrongNumber() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyMoreThanExpected() + public function testMatchResponseBodyMoreThanExpected(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("The property(ies) 'more' has not defined in '#/components/schemas/Order'"); @@ -186,7 +183,7 @@ public function testMatchResponseBodyMoreThanExpected() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyLessFields() + public function testMatchResponseBodyLessFields(): void { $body = [ "id" => 10, @@ -208,7 +205,7 @@ public function testMatchResponseBodyLessFields() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyAllowNullValues() + public function testMatchResponseBodyAllowNullValues(): void { $allowNullValues = true; $body = [ @@ -226,7 +223,6 @@ public function testMatchResponseBodyAllowNullValues() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -236,7 +232,7 @@ public function testMatchResponseBodyAllowNullValues() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyNotAllowNullValues() + public function testMatchResponseBodyNotAllowNullValues(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Value of property 'complete' is null, but should be of type 'boolean'"); @@ -261,7 +257,7 @@ public function testMatchResponseBodyNotAllowNullValues() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyEmpty() + public function testMatchResponseBodyEmpty(): void { $body = null; @@ -270,7 +266,6 @@ public function testMatchResponseBodyEmpty() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -280,7 +275,7 @@ public function testMatchResponseBodyEmpty() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyNotEmpty() + public function testMatchResponseBodyNotEmpty(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Expected empty body for"); @@ -301,7 +296,7 @@ public function testMatchResponseBodyNotEmpty() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyComplex() + public function testMatchResponseBodyComplex(): void { $body = [ "id" => 10, @@ -340,7 +335,7 @@ public function testMatchResponseBodyComplex() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyWhenValueWithNestedPropertiesIsNullAndNullsAreAllowed() + public function testMatchResponseBodyWhenValueWithNestedPropertiesIsNullAndNullsAreAllowed(): void { $allowNullValues = true; $body = [ @@ -377,7 +372,7 @@ public function testMatchResponseBodyWhenValueWithNestedPropertiesIsNullAndNulls * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException */ - public function testAdditionalPropertiesInObjectInResponseBody() + public function testAdditionalPropertiesInObjectInResponseBody(): void { $body = ['value1' => 1, 'value2' => 2]; $responseParameter = self::openApiSchema5()->getResponseParameters('/tests/additional_properties', 'get', 200); @@ -393,7 +388,7 @@ public function testAdditionalPropertiesInObjectInResponseBody() * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException */ - public function testAdditionalPropertiesInObjectInResponseBodyDoNotMatch() + public function testAdditionalPropertiesInObjectInResponseBodyDoNotMatch(): void { $this->expectExceptionMessage("Expected 'value2' to be numeric, but found 'string'"); $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); @@ -414,7 +409,7 @@ public function testAdditionalPropertiesInObjectInResponseBodyDoNotMatch() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testIssue9() + public function testIssue9(): void { $body = [ @@ -448,7 +443,7 @@ public function testIssue9() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testIssue9Error() + public function testIssue9Error(): void { $this->expectException(InvalidRequestException::class); $this->expectExceptionMessageMatches("/I expected an array here.*/"); @@ -482,7 +477,7 @@ public function testIssue9Error() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchAnyValue() + public function testMatchAnyValue(): void { $body = "string"; $responseParameter = $this->openApiSchema2()->getResponseParameters('/v2/anyvalue', 'get', 200); @@ -507,7 +502,7 @@ public function testMatchAnyValue() * @throws InvalidRequestException * @throws InvalidDefinitionException */ - public function testMatchAllOf() + public function testMatchAllOf(): void { $body = ["name" => "Bob", "email" => "bob@example.com"]; $responseParameter = $this->openApiSchema2()->getResponseParameters('/v2/allof', 'get', 200); @@ -527,7 +522,7 @@ public function testMatchAllOf() * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException */ - public function testResponseDefault() + public function testResponseDefault(): void { $body = []; $responseParameter = $this->openApiSchema()->getResponseParameters('/v2/user', 'post', 503); @@ -541,7 +536,7 @@ public function testResponseDefault() * @throws InvalidRequestException * @throws HttpMethodNotFoundException */ - public function testResponseWithNoDefault() + public function testResponseWithNoDefault(): void { $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); $this->expectExceptionMessage("Could not found status code '503'"); diff --git a/tests/OpenApiSchemaTest.php b/tests/OpenApiSchemaTest.php index 4c61e66..0ccacc5 100644 --- a/tests/OpenApiSchemaTest.php +++ b/tests/OpenApiSchemaTest.php @@ -28,7 +28,7 @@ public function tearDown(): void $this->openapiObject = null; } - public function testGetBasePath() + public function testGetBasePath(): void { $this->assertEquals('/v2', $this->openapiObject->getBasePath()); } @@ -41,7 +41,7 @@ public function testGetBasePath() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathDirectMatch() + public function testGetPathDirectMatch(): void { $this->assertEquals( [ @@ -113,7 +113,7 @@ public function testGetPathDirectMatch() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathPatternMatch() + public function testGetPathPatternMatch(): void { $this->assertEquals( [ @@ -278,7 +278,7 @@ public function testGetPathPatternMatch() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathPatternMatch2() + public function testGetPathPatternMatch2(): void { $this->assertEquals( [ @@ -347,7 +347,6 @@ public function testGetPathPatternMatch2() } /** - * * @throws DefinitionNotFoundException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException @@ -355,15 +354,14 @@ public function testGetPathPatternMatch2() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathFail() + public function testGetPathFail(): void { - $this->expectException(\ByJG\ApiTools\Exception\PathNotFoundException::class); + $this->expectException(PathNotFoundException::class); $this->openapiObject->getPathDefinition('/v2/pets', 'get'); } /** - * * @throws DefinitionNotFoundException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException @@ -371,9 +369,9 @@ public function testGetPathFail() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testPathExistsButMethodDont() + public function testPathExistsButMethodDont(): void { - $this->expectException(\ByJG\ApiTools\Exception\HttpMethodNotFoundException::class); + $this->expectException(HttpMethodNotFoundException::class); $this->openapiObject->getPathDefinition('/v2/pet', 'GET'); } @@ -386,7 +384,7 @@ public function testPathExistsButMethodDont() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathStructure() + public function testGetPathStructure(): void { $pathDefintion = $this->openapiObject->getPathDefinition('/v2/pet', 'PUT'); $this->assertEquals( @@ -425,46 +423,43 @@ public function testGetPathStructure() } /** - * - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException + * @throws DefinitionNotFoundException + * @throws InvalidDefinitionException */ - public function testGetDefinitionFailed() + public function testGetDefinitionFailed(): void { - $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); + $this->expectException(InvalidDefinitionException::class); $this->openapiObject->getDefinition('Order'); } /** - * - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException + * @throws DefinitionNotFoundException + * @throws InvalidDefinitionException */ - public function testGetDefinitionFailed2() + public function testGetDefinitionFailed2(): void { - $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); + $this->expectException(InvalidDefinitionException::class); $this->openapiObject->getDefinition('1/2/Order'); } /** - * - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException + * @throws DefinitionNotFoundException + * @throws InvalidDefinitionException */ - public function testGetDefinitionFailed3() + public function testGetDefinitionFailed3(): void { - $this->expectException(\ByJG\ApiTools\Exception\DefinitionNotFoundException::class); + $this->expectException(DefinitionNotFoundException::class); $this->openapiObject->getDefinition('#/components/schemas/OrderNOtFound'); } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException + * @throws DefinitionNotFoundException + * @throws InvalidDefinitionException */ - public function testGetDefinition() + public function testGetDefinition(): void { $expected = [ "type" => "object", @@ -508,19 +503,19 @@ public function testGetDefinition() $this->assertEquals($expected, $order); } - public function testGetServerUrl() + public function testGetServerUrl(): void { $this->assertEquals("http://petstore.swagger.io/v2", $this->openapiObject->getServerUrl()); } - public function testGetServerUrlVariables() + public function testGetServerUrlVariables(): void { $this->openapiObject = new OpenApiSchema(file_get_contents(__DIR__ . '/example/openapi4.json')); $this->assertEquals("https://www.domain.com/api/v2", $this->openapiObject->getServerUrl()); } - public function testGetServerUrlVariables2() + public function testGetServerUrlVariables2(): void { $this->openapiObject = new OpenApiSchema(file_get_contents(__DIR__ . '/example/openapi4.json')); $this->openapiObject->setServerVariable("environment", "staging"); diff --git a/tests/SwaggerRequestBodyTest.php b/tests/SwaggerRequestBodyTest.php index 0acd411..c9a4273 100644 --- a/tests/SwaggerRequestBodyTest.php +++ b/tests/SwaggerRequestBodyTest.php @@ -21,7 +21,7 @@ class SwaggerRequestBodyTest extends SwaggerBodyTestCase * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBody() + public function testMatchRequestBody(): void { $body = [ "id" => "10", @@ -45,7 +45,7 @@ public function testMatchRequestBody() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequiredRequestBodyEmpty() + public function testMatchRequiredRequestBodyEmpty(): void { $this->expectException(\ByJG\ApiTools\Exception\RequiredArgumentNotFound::class); $this->expectExceptionMessage("The body is required"); @@ -55,7 +55,6 @@ public function testMatchRequiredRequestBodyEmpty() } /** - * * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException * @throws \ByJG\ApiTools\Exception\GenericSwaggerException * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException @@ -65,7 +64,7 @@ public function testMatchRequiredRequestBodyEmpty() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchInexistantBodyDefinition() + public function testMatchInexistantBodyDefinition(): void { $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); $this->expectExceptionMessage("Body is passed but there is no request body definition"); @@ -83,7 +82,6 @@ public function testMatchInexistantBodyDefinition() } /** - * * @throws DefinitionNotFoundException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException @@ -91,7 +89,7 @@ public function testMatchInexistantBodyDefinition() * @throws PathNotFoundException * @throws InvalidRequestException */ - public function testMatchDataType() + public function testMatchDataType(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Path expected an integer value"); @@ -101,7 +99,6 @@ public function testMatchDataType() } /** - * * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException * @throws \ByJG\ApiTools\Exception\GenericSwaggerException * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException @@ -111,7 +108,7 @@ public function testMatchDataType() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequired1() + public function testMatchRequestBodyRequired1(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Required property"); @@ -137,7 +134,7 @@ public function testMatchRequestBodyRequired1() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequiredNullsNotAllowed() + public function testMatchRequestBodyRequiredNullsNotAllowed(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Value of property 'name' is null, but should be of type 'string'"); @@ -162,7 +159,7 @@ public function testMatchRequestBodyRequiredNullsNotAllowed() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequiredNullsAllowed() + public function testMatchRequestBodyRequiredNullsAllowed(): void { $allowNullValues = true; $body = [ @@ -188,7 +185,7 @@ public function testMatchRequestBodyRequiredNullsAllowed() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequired3() + public function testMatchRequestBodyRequired3(): void { $body = [ "id" => "10", @@ -212,7 +209,7 @@ public function testMatchRequestBodyRequired3() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequired_Issue21() + public function testMatchRequestBodyRequired_Issue21(): void { // Full Request $body = [ @@ -235,7 +232,7 @@ public function testMatchRequestBodyRequired_Issue21() * @throws \ByJG\ApiTools\Exception\PathNotFoundException * @throws \ByJG\ApiTools\Exception\RequiredArgumentNotFound */ - public function testMatchRequestBodyRequired_Issue21_Required() + public function testMatchRequestBodyRequired_Issue21_Required(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Required property 'user_uuid'"); diff --git a/tests/SwaggerResponseBodyTest.php b/tests/SwaggerResponseBodyTest.php index f1d4bda..516c8fd 100644 --- a/tests/SwaggerResponseBodyTest.php +++ b/tests/SwaggerResponseBodyTest.php @@ -23,7 +23,7 @@ class SwaggerResponseBodyTest extends SwaggerBodyTestCase * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBody() + public function testMatchResponseBody(): void { $schema = self::swaggerSchema(); @@ -63,7 +63,6 @@ public function testMatchResponseBody() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -73,7 +72,7 @@ public function testMatchResponseBody() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyEnumError() + public function testMatchResponseBodyEnumError(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Value 'notfound' in 'status' not matched in ENUM"); @@ -91,7 +90,6 @@ public function testMatchResponseBodyEnumError() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -101,7 +99,7 @@ public function testMatchResponseBodyEnumError() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyWrongNumber() + public function testMatchResponseBodyWrongNumber(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Expected 'id' to be numeric, but found 'ABC'"); @@ -119,7 +117,6 @@ public function testMatchResponseBodyWrongNumber() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -129,7 +126,7 @@ public function testMatchResponseBodyWrongNumber() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyMoreThanExpected() + public function testMatchResponseBodyMoreThanExpected(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("The property(ies) 'more' has not defined in '#/definitions/Order'"); @@ -157,7 +154,7 @@ public function testMatchResponseBodyMoreThanExpected() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyLessFields() + public function testMatchResponseBodyLessFields(): void { $body = [ "id" => 10, @@ -178,7 +175,7 @@ public function testMatchResponseBodyLessFields() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyAllowNullValues() + public function testMatchResponseBodyAllowNullValues(): void { $allowNullValues = true; $body = [ @@ -195,7 +192,6 @@ public function testMatchResponseBodyAllowNullValues() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -205,7 +201,7 @@ public function testMatchResponseBodyAllowNullValues() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyNotAllowNullValues() + public function testMatchResponseBodyNotAllowNullValues(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Value of property 'complete' is null, but should be of type 'boolean'"); @@ -229,7 +225,7 @@ public function testMatchResponseBodyNotAllowNullValues() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyEmpty() + public function testMatchResponseBodyEmpty(): void { $body = null; $responseParameter = self::swaggerSchema()->getResponseParameters('/v2/pet/10', 'get', 400); @@ -237,7 +233,6 @@ public function testMatchResponseBodyEmpty() } /** - * * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException @@ -247,7 +242,7 @@ public function testMatchResponseBodyEmpty() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyNotEmpty() + public function testMatchResponseBodyNotEmpty(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Expected empty body for"); @@ -267,7 +262,7 @@ public function testMatchResponseBodyNotEmpty() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyComplex() + public function testMatchResponseBodyComplex(): void { $body = [ "id" => 10, @@ -305,7 +300,7 @@ public function testMatchResponseBodyComplex() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyWhenValueWithNestedPropertiesIsNullAndNullsAreAllowed() + public function testMatchResponseBodyWhenValueWithNestedPropertiesIsNullAndNullsAreAllowed(): void { $allowNullValues = true; $body = [ @@ -341,7 +336,7 @@ public function testMatchResponseBodyWhenValueWithNestedPropertiesIsNullAndNulls * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testNotMatchResponseBodyWhenValueWithPatterns() + public function testNotMatchResponseBodyWhenValueWithPatterns(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage(<<<'EOL' @@ -373,7 +368,7 @@ public function testNotMatchResponseBodyWhenValueWithPatterns() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyWhenValueWithPatterns() + public function testMatchResponseBodyWhenValueWithPatterns(): void { $allowNullValues = false; $body = [ @@ -394,7 +389,7 @@ public function testMatchResponseBodyWhenValueWithPatterns() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyWhenValueWithStringPatternError() + public function testMatchResponseBodyWhenValueWithStringPatternError(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage(<<<'EOL' @@ -427,7 +422,7 @@ public function testMatchResponseBodyWhenValueWithStringPatternError() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchResponseBodyWhenValueWithNumberPatternError() + public function testMatchResponseBodyWhenValueWithNumberPatternError(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage(<<<'EOL' @@ -462,7 +457,7 @@ public function testMatchResponseBodyWhenValueWithNumberPatternError() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testIssue9() + public function testIssue9(): void { $body = [ @@ -495,7 +490,7 @@ public function testIssue9() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testIssue9Error() + public function testIssue9Error(): void { $this->expectException(InvalidRequestException::class); $this->expectExceptionMessageMatches("/I expected an array here.*/"); @@ -529,7 +524,7 @@ public function testIssue9Error() * @throws PathNotFoundException * @throws RequiredArgumentNotFound */ - public function testMatchAnyValue() + public function testMatchAnyValue(): void { $body = "string"; $responseParameter = $this->swaggerSchema2()->getResponseParameters('/v2/anyvalue', 'get', 200); @@ -554,7 +549,7 @@ public function testMatchAnyValue() * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException */ - public function testResponseDefault() + public function testResponseDefault(): void { $body = []; $responseParameter = $this->swaggerSchema()->getResponseParameters('/v2/user', 'post', 503); @@ -568,7 +563,7 @@ public function testResponseDefault() * @throws InvalidRequestException * @throws HttpMethodNotFoundException */ - public function testResponseWithNoDefault() + public function testResponseWithNoDefault(): void { $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); $this->expectExceptionMessage("Could not found status code '503'"); diff --git a/tests/SwaggerSchemaTest.php b/tests/SwaggerSchemaTest.php index 39d3705..68a1d7d 100644 --- a/tests/SwaggerSchemaTest.php +++ b/tests/SwaggerSchemaTest.php @@ -28,7 +28,7 @@ public function tearDown(): void $this->object = null; } - public function testGetBasePath() + public function testGetBasePath(): void { $this->assertEquals('/v2', $this->object->getBasePath()); } @@ -41,7 +41,7 @@ public function testGetBasePath() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathDirectMatch() + public function testGetPathDirectMatch(): void { $this->assertEquals( [ @@ -145,7 +145,7 @@ public function testGetPathDirectMatch() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathPatternMatch() + public function testGetPathPatternMatch(): void { $this->assertEquals( [ @@ -303,7 +303,7 @@ public function testGetPathPatternMatch() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathPatternMatch2() + public function testGetPathPatternMatch2(): void { $this->assertEquals( [ @@ -365,7 +365,6 @@ public function testGetPathPatternMatch2() } /** - * * @throws DefinitionNotFoundException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException @@ -373,7 +372,7 @@ public function testGetPathPatternMatch2() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathFail() + public function testGetPathFail(): void { $this->expectException(\ByJG\ApiTools\Exception\PathNotFoundException::class); @@ -388,7 +387,7 @@ public function testGetPathFail() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testPathExistsButMethodDont() + public function testPathExistsButMethodDont(): void { $this->expectException(\ByJG\ApiTools\Exception\HttpMethodNotFoundException::class); @@ -403,7 +402,7 @@ public function testPathExistsButMethodDont() * @throws NotMatchedException * @throws PathNotFoundException */ - public function testGetPathStructure() + public function testGetPathStructure(): void { $pathDefintion = $this->object->getPathDefinition('/v2/pet', 'PUT'); @@ -459,11 +458,10 @@ public function testGetPathStructure() } /** - * * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException */ - public function testGetDefinitionFailed() + public function testGetDefinitionFailed(): void { $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); @@ -471,11 +469,10 @@ public function testGetDefinitionFailed() } /** - * * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException */ - public function testGetDefinitionFailed2() + public function testGetDefinitionFailed2(): void { $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); @@ -483,11 +480,10 @@ public function testGetDefinitionFailed2() } /** - * * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException */ - public function testGetDefinitionFailed3() + public function testGetDefinitionFailed3(): void { $this->expectException(\ByJG\ApiTools\Exception\DefinitionNotFoundException::class); @@ -498,7 +494,7 @@ public function testGetDefinitionFailed3() * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException */ - public function testGetDefinition() + public function testGetDefinition(): void { $order = $this->object->getDefinition('#/definitions/Order'); @@ -544,13 +540,13 @@ public function testGetDefinition() ); } - public function testItNotAllowsNullValuesByDefault() + public function testItNotAllowsNullValuesByDefault(): void { $schema = \ByJG\ApiTools\Base\Schema::getInstance('{"swagger": "2.0"}'); $this->assertFalse($schema->isAllowNullValues()); } - public function testItAllowsNullValues() + public function testItAllowsNullValues(): void { $allowNullValues = true; $schema = \ByJG\ApiTools\Base\Schema::getInstance('{"swagger": "2.0"}', $allowNullValues); diff --git a/tests/TestingTestCase.php b/tests/TestingTestCase.php index ddfa8b6..4cad047 100644 --- a/tests/TestingTestCase.php +++ b/tests/TestingTestCase.php @@ -14,14 +14,14 @@ use ByJG\ApiTools\Exception\RequiredArgumentNotFound; use ByJG\ApiTools\Exception\StatusCodeNotMatchedException; use ByJG\ApiTools\MockRequester; +use ByJG\Util\Uri; use ByJG\WebRequest\Exception\MessageException; use ByJG\WebRequest\Exception\RequestException; use ByJG\WebRequest\Helper\RequestMultiPart; use ByJG\WebRequest\MultiPartItem; +use ByJG\WebRequest\Psr7\MemoryStream; use ByJG\WebRequest\Psr7\Request; use ByJG\WebRequest\Psr7\Response; -use ByJG\Util\Uri; -use ByJG\WebRequest\Psr7\MemoryStream; /** * Class TestingTestCase @@ -46,7 +46,7 @@ abstract class TestingTestCase extends ApiTestCase * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException */ - public function testGet() + public function testGet(): void { $request = new ApiRequester(); $request @@ -69,7 +69,7 @@ public function testGet() * @throws MessageException * @throws InvalidDefinitionException */ - public function testPost() + public function testPost(): void { $body = [ 'id' => 1, @@ -113,7 +113,7 @@ public function testPost() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testAddError() + public function testAddError(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Required property 'name'"); @@ -144,7 +144,7 @@ public function testAddError() * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException */ - public function testPostError() + public function testPostError(): void { $this->expectException(\ByJG\ApiTools\Exception\NotMatchedException::class); $this->expectExceptionMessage("Expected empty body"); @@ -178,7 +178,7 @@ public function testPostError() * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException */ - public function testMultipart() + public function testMultipart(): void { $multipart = [ new MultiPartItem("note", "somenote"), From 29e207d434deeaed5b700c604ef5655c0b21d368 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Tue, 3 Jun 2025 04:57:46 -0500 Subject: [PATCH 3/6] Add #[Override] attributes to applicable methods This update ensures methods explicitly indicate they override a parent class or interface method for better code clarity and consistency. Additionally, minor type adjustments and improvements to return type declarations were made to enhance code robustness. --- src/ApiRequester.php | 2 ++ src/Base/Body.php | 14 +++++++------- src/Base/Schema.php | 4 ++-- src/MockRequester.php | 1 + src/OpenApi/OpenApiRequestBody.php | 1 + src/OpenApi/OpenApiResponseBody.php | 1 + src/OpenApi/OpenApiSchema.php | 6 ++++++ src/Swagger/SwaggerRequestBody.php | 1 + src/Swagger/SwaggerResponseBody.php | 1 + src/Swagger/SwaggerSchema.php | 6 ++++++ tests/OpenApiBodyTestCase.php | 25 +++++++++++++------------ tests/OpenApiSchemaTest.php | 2 ++ tests/OpenApiTest.php | 3 +-- tests/OpenApiTestCaseTest.php | 1 + tests/SwaggerBodyTestCase.php | 8 ++++---- tests/SwaggerSchemaTest.php | 2 ++ tests/SwaggerTest.php | 1 + tests/SwaggerTestCaseTest.php | 1 + 18 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/ApiRequester.php b/src/ApiRequester.php index 336883a..fe48b43 100644 --- a/src/ApiRequester.php +++ b/src/ApiRequester.php @@ -6,6 +6,7 @@ use ByJG\WebRequest\Exception\NetworkException; use ByJG\WebRequest\Exception\RequestException; use ByJG\WebRequest\HttpClient; +use Override; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -36,6 +37,7 @@ public function __construct() * @throws NetworkException * @throws RequestException */ + #[Override] protected function handleRequest(RequestInterface $request): ResponseInterface { $request = $request->withHeader("User-Agent", "ByJG Swagger Test"); diff --git a/src/Base/Body.php b/src/Base/Body.php index ea25709..24e72f1 100644 --- a/src/Base/Body.php +++ b/src/Base/Body.php @@ -103,7 +103,7 @@ protected function matchString(string $name, array $schemaArray, mixed $body, mi private function checkPattern(string $name, mixed $body, string $pattern): void { $pattern = '/' . rtrim(ltrim($pattern, '/'), '/') . '/'; - $isSuccess = (bool) preg_match($pattern, $body); + $isSuccess = (bool)preg_match($pattern, (string)$body); if (!$isSuccess) { throw new NotMatchedException("Value '$body' in '$name' not matched in pattern. ", $this->structure); @@ -214,32 +214,32 @@ protected function matchTypes(string $name, mixed $schemaArray, mixed $body): ?b $nullable = isset($schemaArray['nullable']) ? (bool)$schemaArray['nullable'] : $this->schema->isAllowNullValues(); $validators = [ - function () use ($name, $body, $type, $nullable) + function () use ($name, $body, $type, $nullable): bool|null { return $this->matchNull($name, $body, $type, $nullable); }, - function () use ($name, $schemaArray, $body, $type) + function () use ($name, $schemaArray, $body, $type): bool|null { return $this->matchString($name, $schemaArray, $body, $type); }, - function () use ($name, $schemaArray, $body, $type) + function () use ($name, $schemaArray, $body, $type): bool|null { return $this->matchNumber($name, $schemaArray, $body, $type); }, - function () use ($name, $body, $type) + function () use ($name, $body, $type): bool|null { return $this->matchBool($name, $body, $type); }, - function () use ($name, $schemaArray, $body, $type) + function () use ($name, $schemaArray, $body, $type): bool|null { return $this->matchArray($name, $schemaArray, $body, $type); }, - function () use ($name, $schemaArray, $body, $type) + function () use ($name, $schemaArray, $body, $type): bool|null { return $this->matchFile($name, $schemaArray, $body, $type); }, diff --git a/src/Base/Schema.php b/src/Base/Schema.php index deb302a..6c8e88f 100644 --- a/src/Base/Schema.php +++ b/src/Base/Schema.php @@ -40,9 +40,9 @@ public function getSpecificationVersion(): string * * @param array|string $data * @param bool $extraArgs - * @return Schema + * @return SwaggerSchema|OpenApiSchema */ - public static function getInstance(array|string $data, bool $extraArgs = false): Schema + public static function getInstance(array|string $data, bool $extraArgs = false): SwaggerSchema|OpenApiSchema { // when given a string, decode from JSON if (is_string($data)) { diff --git a/src/MockRequester.php b/src/MockRequester.php index 27d10d0..9b765c8 100644 --- a/src/MockRequester.php +++ b/src/MockRequester.php @@ -32,6 +32,7 @@ public function __construct(Response $expectedResponse) * @return ResponseInterface * @throws RequestException */ + #[\Override] protected function handleRequest(RequestInterface $request): ResponseInterface { $request = $request->withHeader("User-Agent", "ByJG Swagger Test"); diff --git a/src/OpenApi/OpenApiRequestBody.php b/src/OpenApi/OpenApiRequestBody.php index 497ca24..a137dca 100644 --- a/src/OpenApi/OpenApiRequestBody.php +++ b/src/OpenApi/OpenApiRequestBody.php @@ -11,6 +11,7 @@ class OpenApiRequestBody extends Body /** * @inheritDoc */ + #[\Override] public function match(mixed $body): bool { if (isset($this->structure['content']) || isset($this->structure['$ref'])) { diff --git a/src/OpenApi/OpenApiResponseBody.php b/src/OpenApi/OpenApiResponseBody.php index 18fe74b..6614f5a 100644 --- a/src/OpenApi/OpenApiResponseBody.php +++ b/src/OpenApi/OpenApiResponseBody.php @@ -10,6 +10,7 @@ class OpenApiResponseBody extends Body /** * @inheritDoc */ + #[\Override] public function match(mixed $body): bool { if (empty($this->structure['content']) && !isset($this->structure['$ref'])) { diff --git a/src/OpenApi/OpenApiSchema.php b/src/OpenApi/OpenApiSchema.php index ce1bd86..c1f0b20 100644 --- a/src/OpenApi/OpenApiSchema.php +++ b/src/OpenApi/OpenApiSchema.php @@ -29,6 +29,7 @@ public function __construct(array|string $data) $this->jsonFile = $data; } + #[\Override] public function getServerUrl(): string { if (!isset($this->jsonFile['servers'])) { @@ -51,6 +52,7 @@ public function getServerUrl(): string return $serverUrl; } + #[\Override] public function getBasePath(): string { $uriServer = new Uri($this->getServerUrl()); @@ -60,6 +62,7 @@ public function getBasePath(): string /** * @inheritDoc */ + #[\Override] protected function validateArguments(string $parameterIn, array $parameters, array $arguments): void { foreach ($parameters as $parameter) { @@ -91,6 +94,7 @@ protected function validateArguments(string $parameterIn, array $parameters, arr * @throws DefinitionNotFoundException * @throws InvalidDefinitionException */ + #[\Override] public function getDefinition(string $name): mixed { $nameParts = explode('/', $name); @@ -110,6 +114,7 @@ public function getDefinition(string $name): mixed * @inheritDoc * @throws InvalidRequestException */ + #[\Override] public function getRequestParameters(string $path, string $method): Body { $structure = $this->getPathDefinition($path, $method); @@ -128,6 +133,7 @@ public function setServerVariable(string $var, string $value): void /** * @inheritDoc */ + #[\Override] public function getResponseBody(Schema $schema, string $name, array $structure, bool $allowNullValues = false): Body { return new OpenApiResponseBody($schema, $name, $structure, $allowNullValues); diff --git a/src/Swagger/SwaggerRequestBody.php b/src/Swagger/SwaggerRequestBody.php index 6382bd3..f9e4105 100644 --- a/src/Swagger/SwaggerRequestBody.php +++ b/src/Swagger/SwaggerRequestBody.php @@ -12,6 +12,7 @@ class SwaggerRequestBody extends Body /** * @inheritDoc */ + #[\Override] public function match(mixed $body): bool { $hasFormData = false; diff --git a/src/Swagger/SwaggerResponseBody.php b/src/Swagger/SwaggerResponseBody.php index cd04c7a..d8b58b9 100644 --- a/src/Swagger/SwaggerResponseBody.php +++ b/src/Swagger/SwaggerResponseBody.php @@ -10,6 +10,7 @@ class SwaggerResponseBody extends Body /** * @inheritDoc */ + #[\Override] public function match(mixed $body): bool { if (!isset($this->structure['schema'])) { diff --git a/src/Swagger/SwaggerSchema.php b/src/Swagger/SwaggerSchema.php index 0fd4c9e..30de915 100644 --- a/src/Swagger/SwaggerSchema.php +++ b/src/Swagger/SwaggerSchema.php @@ -37,11 +37,13 @@ public function getHost(): string return $this->jsonFile['host'] ?? ''; } + #[\Override] public function getBasePath(): string { return $this->jsonFile['basePath'] ?? ''; } + #[\Override] public function getServerUrl(): string { $httpSchema = $this->getHttpSchema(); @@ -56,6 +58,7 @@ public function getServerUrl(): string /** * @inheritDoc */ + #[\Override] protected function validateArguments(string $parameterIn, array $parameters, array $arguments): void { foreach ($parameters as $parameter) { @@ -73,6 +76,7 @@ protected function validateArguments(string $parameterIn, array $parameters, arr * @throws DefinitionNotFoundException * @throws InvalidDefinitionException */ + #[\Override] public function getDefinition(string $name): mixed { $nameParts = explode('/', $name); @@ -92,6 +96,7 @@ public function getDefinition(string $name): mixed * @inheritDoc * @throws InvalidRequestException */ + #[\Override] public function getRequestParameters(string $path, string $method): Body { $structure = $this->getPathDefinition($path, $method); @@ -116,6 +121,7 @@ public function setAllowNullValues(string|bool $value): void /** * @inheritDoc */ + #[\Override] public function getResponseBody(Schema $schema, string $name, array $structure, bool $allowNullValues = false): Body { return new SwaggerResponseBody($schema, $name, $structure, $allowNullValues); diff --git a/tests/OpenApiBodyTestCase.php b/tests/OpenApiBodyTestCase.php index 29432b2..fa8a095 100644 --- a/tests/OpenApiBodyTestCase.php +++ b/tests/OpenApiBodyTestCase.php @@ -2,6 +2,7 @@ namespace Tests; +use ByJG\ApiTools\Base\Schema; use ByJG\ApiTools\OpenApi\OpenApiSchema; use PHPUnit\Framework\TestCase; @@ -19,7 +20,7 @@ class OpenApiBodyTestCase extends TestCase */ protected static function openApiSchema(bool $allowNullValues = false): OpenApiSchema { - return \ByJG\ApiTools\Base\Schema::getInstance( + return Schema::getInstance( self::getOpenApiJsonContent(), $allowNullValues ); @@ -31,7 +32,7 @@ protected static function openApiSchema(bool $allowNullValues = false): OpenApiS */ protected static function openApiSchema2(bool $allowNullValues = false): OpenApiSchema { - return \ByJG\ApiTools\Base\Schema::getInstance( + return Schema::getInstance( self::getOpenApiJsonContent_No2(), $allowNullValues ); @@ -43,7 +44,7 @@ protected static function openApiSchema2(bool $allowNullValues = false): OpenApi */ protected static function openApiSchema3(bool $allowNullValues = false): OpenApiSchema { - return \ByJG\ApiTools\Base\Schema::getInstance( + return Schema::getInstance( self::getOpenApiJsonContent_No3(), $allowNullValues ); @@ -55,40 +56,40 @@ protected static function openApiSchema3(bool $allowNullValues = false): OpenApi */ protected static function openApiSchema5(bool $allowNullValues = false): OpenApiSchema { - return \ByJG\ApiTools\Base\Schema::getInstance( + return Schema::getInstance( self::getOpenApiJsonContent_No5(), $allowNullValues ); } /** - * @return string + * @return false|string */ - protected static function getOpenApiJsonContent(): string + protected static function getOpenApiJsonContent(): string|false { return file_get_contents(__DIR__ . '/example/openapi.json'); } /** - * @return string + * @return false|string */ - protected static function getOpenApiJsonContent_No2(): string + protected static function getOpenApiJsonContent_No2(): string|false { return file_get_contents(__DIR__ . '/example/openapi2.json'); } /** - * @return string + * @return false|string */ - protected static function getOpenApiJsonContent_No3(): string + protected static function getOpenApiJsonContent_No3(): string|false { return file_get_contents(__DIR__ . '/example/openapi3.json'); } /** - * @return string + * @return false|string */ - protected static function getOpenApiJsonContent_No5(): string + protected static function getOpenApiJsonContent_No5(): string|false { return file_get_contents(__DIR__ . '/example/openapi5.json'); } diff --git a/tests/OpenApiSchemaTest.php b/tests/OpenApiSchemaTest.php index 0ccacc5..f158706 100644 --- a/tests/OpenApiSchemaTest.php +++ b/tests/OpenApiSchemaTest.php @@ -18,11 +18,13 @@ class OpenApiSchemaTest extends TestCase */ protected $openapiObject; + #[\Override] public function setUp(): void { $this->openapiObject = new OpenApiSchema(file_get_contents(__DIR__ . '/example/openapi.json')); } + #[\Override] public function tearDown(): void { $this->openapiObject = null; diff --git a/tests/OpenApiTest.php b/tests/OpenApiTest.php index eaf084c..03c1c6b 100644 --- a/tests/OpenApiTest.php +++ b/tests/OpenApiTest.php @@ -4,13 +4,12 @@ namespace Tests; use ByJG\ApiTools\Base\Schema; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; require_once "AbstractRequesterTest.php"; class OpenApiTest extends AbstractRequesterTest { + #[\Override] public function setUp(): void { $schema = Schema::getInstance(file_get_contents(__DIR__ . '/rest/openapi.json')); diff --git a/tests/OpenApiTestCaseTest.php b/tests/OpenApiTestCaseTest.php index b02463a..c3557a6 100644 --- a/tests/OpenApiTestCaseTest.php +++ b/tests/OpenApiTestCaseTest.php @@ -7,6 +7,7 @@ class OpenApiTestCaseTest extends TestingTestCase { + #[\Override] public function setUp(): void { $schema = Schema::getInstance(file_get_contents(__DIR__ . '/rest/openapi.json')); diff --git a/tests/SwaggerBodyTestCase.php b/tests/SwaggerBodyTestCase.php index d75f3fd..6de8f8d 100644 --- a/tests/SwaggerBodyTestCase.php +++ b/tests/SwaggerBodyTestCase.php @@ -39,17 +39,17 @@ protected static function swaggerSchema2(bool $allowNullValues = false): Swagger } /** - * @return string + * @return false|string */ - protected static function getSwaggerJsonContent(): string + protected static function getSwaggerJsonContent(): string|false { return file_get_contents(__DIR__ . '/example/swagger.json'); } /** - * @return string + * @return false|string */ - protected static function getSwaggerJsonContent_No2(): string + protected static function getSwaggerJsonContent_No2(): string|false { return file_get_contents(__DIR__ . '/example/swagger2.json'); } diff --git a/tests/SwaggerSchemaTest.php b/tests/SwaggerSchemaTest.php index 68a1d7d..325906a 100644 --- a/tests/SwaggerSchemaTest.php +++ b/tests/SwaggerSchemaTest.php @@ -18,11 +18,13 @@ class SwaggerSchemaTest extends TestCase */ protected $object; + #[\Override] public function setUp(): void { $this->object = \ByJG\ApiTools\Base\Schema::getInstance(file_get_contents(__DIR__ . '/example/swagger.json')); } + #[\Override] public function tearDown(): void { $this->object = null; diff --git a/tests/SwaggerTest.php b/tests/SwaggerTest.php index ba260ae..2741b7b 100644 --- a/tests/SwaggerTest.php +++ b/tests/SwaggerTest.php @@ -10,6 +10,7 @@ class SwaggerTest extends AbstractRequesterTest { + #[\Override] public function setUp(): void { $schema = Schema::getInstance(file_get_contents(__DIR__ . '/rest/swagger.json')); diff --git a/tests/SwaggerTestCaseTest.php b/tests/SwaggerTestCaseTest.php index 675cb5c..e5a35b7 100644 --- a/tests/SwaggerTestCaseTest.php +++ b/tests/SwaggerTestCaseTest.php @@ -7,6 +7,7 @@ class SwaggerTestCaseTest extends TestingTestCase { + #[\Override] public function setUp(): void { $schema = Schema::getInstance(file_get_contents(__DIR__ . '/rest/swagger.json')); From f87c925eb12b349d7c8aabdebaae2d6dd696a603 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Tue, 3 Jun 2025 05:04:04 -0500 Subject: [PATCH 4/6] Add documentation for schema classes and RestServer integration Created a new document, `schema-classes.md`, detailing the features of `SwaggerSchema` and `OpenApiSchema`. Updated README and `contract-tests.md` to reference schema documentation and added guidance on using the `RestServer` component. --- README.md | 20 ++++-- docs/contract-tests.md | 29 ++++++++- docs/functional-tests.md | 4 ++ docs/mock-requests.md | 4 ++ docs/runtime-parameters-validator.md | 4 ++ docs/schema-classes.md | 95 ++++++++++++++++++++++++++++ 6 files changed, 150 insertions(+), 6 deletions(-) create mode 100644 docs/schema-classes.md diff --git a/README.md b/README.md index e5bbaec..cf8fa51 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,22 @@ A set of tools for testing your REST calls based on the OpenApi specification using PHPUnit. Currently, this library supports the OpenApi specifications `2.0` (formerly swagger) and `3.0`. -Some features like callbacks, links and references to external documents/objects weren't implemented. -PHP Swagger Test can help you to test your REST Api. You can use this tool both for Unit Tests or Functional Tests. +Some features of the OpenAPI specification are not fully implemented: -This tool reads a previously Swagger JSON file (not YAML) and enables you to test the request and response. +- Callbacks (OpenAPI 3.0) +- Links (OpenAPI 3.0) +- References to external documents/objects +- Complex schema validations + +For details on the schema classes and their specific features, see [Schema Classes](docs/schema-classes.md). + +PHP Swagger Test can help you to test your REST API. You can use this tool both for Unit Tests or Functional Tests. + +This tool reads an OpenAPI/Swagger specification in JSON format (not YAML) and enables you to test the request and +response. You can use the tool "[https://github.com/zircote/swagger-php](https://github.com/zircote/swagger-php)" for creating the JSON file when you are developing your -rest API. +REST API. The ApiTestCase's assertion process is based on throwing exceptions if some validation or test failed. @@ -27,6 +36,7 @@ You can use the Swagger Test library as: - [Contract test cases](docs/contract-tests.md) - [Runtime parameters validator](docs/runtime-parameters-validator.md) - [Mocking Requests and Validate your specification](docs/mock-requests.md) +- [Working with different schema versions](docs/schema-classes.md) Who is using this library? @@ -64,4 +74,4 @@ flowchart TD byjg/swagger-test --> byjg/webrequest ``` ---- -[Open source ByJG](http://opensource.byjg.com) \ No newline at end of file +[Open source ByJG](http://opensource.byjg.com) diff --git a/docs/contract-tests.md b/docs/contract-tests.md index 8156df5..343fc45 100644 --- a/docs/contract-tests.md +++ b/docs/contract-tests.md @@ -1,3 +1,7 @@ +--- +sidebar_position: 2 +--- + # Contract Tests Sometimes, you want to run functional tests without making the actual HTTP @@ -29,7 +33,30 @@ You now use an instance of this class in place of the `ApiRequester` class from Of course, if you need to apply changes to the request, or the response in order to fit your framework, this is exactly the right place to do it. -@todo: Explain in the Docs sections the `RestServer` component +## Using with RestServer component + +The [byjg/restserver](https://github.com/byjg/php-restserver) component can be used to create a server that handles +requests based on OpenAPI/Swagger specifications. This is useful for testing your API without setting up a full web +server. + +```php +handle($routeDefinition); +``` + +This code will create a server that handles requests according to the routes defined in your OpenAPI/Swagger +specification. ## Using it as Unit Test cases diff --git a/docs/functional-tests.md b/docs/functional-tests.md index fdcabe9..7d022ff 100644 --- a/docs/functional-tests.md +++ b/docs/functional-tests.md @@ -1,3 +1,7 @@ +--- +sidebar_position: 1 +--- + # Functional Test cases Swagger Test provides the class `ApiTestCase` for you extend and create a PHPUnit test case. The code will try to diff --git a/docs/mock-requests.md b/docs/mock-requests.md index 5d6b337..fa0c26d 100644 --- a/docs/mock-requests.md +++ b/docs/mock-requests.md @@ -1,3 +1,7 @@ +--- +sidebar_position: 4 +--- + # Mock Requests PHP Swagger has the class `MockRequester` with exact the same functionalities of `ApiRequester` class. The only diff --git a/docs/runtime-parameters-validator.md b/docs/runtime-parameters-validator.md index b99243d..94ff244 100644 --- a/docs/runtime-parameters-validator.md +++ b/docs/runtime-parameters-validator.md @@ -1,3 +1,7 @@ +--- +sidebar_position: 3 +--- + # Runtime parameters validator This tool was not developed only for unit and functional tests. You can use to validate if the required body diff --git a/docs/schema-classes.md b/docs/schema-classes.md new file mode 100644 index 0000000..b6a5c36 --- /dev/null +++ b/docs/schema-classes.md @@ -0,0 +1,95 @@ +--- +sidebar_position: 5 +--- + +# Schema Classes + +PHP Swagger Test provides two main schema classes for working with different versions of the OpenAPI specification: + +- `SwaggerSchema` - For OpenAPI 2.0 (formerly known as Swagger) +- `OpenApiSchema` - For OpenAPI 3.0 + +Both classes extend the abstract `Schema` class and provide specific implementations for their respective specification +versions. + +## Creating Schema Instances + +You can create a schema instance using the static `getInstance` method, which automatically determines the schema type +based on the provided data: + +```php +setAllowNullValues(true); // Allow null values +$schema->setAllowNullValues(false); // Don't allow null values +``` + +## OpenApiSchema Specific Features + +The `OpenApiSchema` class provides specific methods for working with OpenAPI 3.0 specifications: + +### Server Variables + +OpenAPI 3.0 allows defining server URLs with variables. The `OpenApiSchema` class provides a way to set these variables: + +```php + '3.0.0', + 'servers' => [ + [ + 'url' => 'https://{environment}.example.com/v1', + 'variables' => [ + 'environment' => [ + 'default' => 'api', + 'enum' => ['api', 'api.dev', 'api.staging'] + ] + ] + ] + ] +]; + +$schema = new \ByJG\ApiTools\OpenApi\OpenApiSchema($openApiSpec); + +// Set a server variable +$schema->setServerVariable('environment', 'api.dev'); + +// Now getServerUrl() will return 'https://api.dev.example.com/v1' +echo $schema->getServerUrl(); +``` + +## Common Methods + +Both schema classes provide the following common methods: + +- `getServerUrl()` - Get the server URL from the specification +- `getBasePath()` - Get the base path from the specification +- `getPathDefinition($path, $method)` - Get the definition for a specific path and method +- `getRequestParameters($path, $method)` - Get the request parameters for a specific path and method +- `getResponseParameters($path, $method, $status)` - Get the response parameters for a specific path, method, and status + code +- `getDefinition($name)` - Get a definition by name From 5f98702ba367bcbd6012d4a1a0891ad728d95912 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Tue, 3 Jun 2025 05:12:02 -0500 Subject: [PATCH 5/6] Update schema type hints to support both Swagger and OpenAPI Expanded return type hints in test cases to accept both `SwaggerSchema` and `OpenApiSchema`. This ensures compatibility with both schema types and improves flexibility in schema handling across tests. --- tests/OpenApiBodyTestCase.php | 17 +++++++++-------- tests/SwaggerBodyTestCase.php | 9 +++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/OpenApiBodyTestCase.php b/tests/OpenApiBodyTestCase.php index fa8a095..38f7385 100644 --- a/tests/OpenApiBodyTestCase.php +++ b/tests/OpenApiBodyTestCase.php @@ -4,6 +4,7 @@ use ByJG\ApiTools\Base\Schema; use ByJG\ApiTools\OpenApi\OpenApiSchema; +use ByJG\ApiTools\Swagger\SwaggerSchema; use PHPUnit\Framework\TestCase; /** @@ -16,9 +17,9 @@ class OpenApiBodyTestCase extends TestCase { /** * @param bool $allowNullValues - * @return OpenApiSchema + * @return OpenApiSchema|SwaggerSchema */ - protected static function openApiSchema(bool $allowNullValues = false): OpenApiSchema + protected static function openApiSchema(bool $allowNullValues = false): OpenApiSchema|SwaggerSchema { return Schema::getInstance( self::getOpenApiJsonContent(), @@ -28,9 +29,9 @@ protected static function openApiSchema(bool $allowNullValues = false): OpenApiS /** * @param bool $allowNullValues - * @return OpenApiSchema + * @return OpenApiSchema|SwaggerSchema */ - protected static function openApiSchema2(bool $allowNullValues = false): OpenApiSchema + protected static function openApiSchema2(bool $allowNullValues = false): OpenApiSchema|SwaggerSchema { return Schema::getInstance( self::getOpenApiJsonContent_No2(), @@ -40,9 +41,9 @@ protected static function openApiSchema2(bool $allowNullValues = false): OpenApi /** * @param bool $allowNullValues - * @return OpenApiSchema + * @return OpenApiSchema|SwaggerSchema */ - protected static function openApiSchema3(bool $allowNullValues = false): OpenApiSchema + protected static function openApiSchema3(bool $allowNullValues = false): OpenApiSchema|SwaggerSchema { return Schema::getInstance( self::getOpenApiJsonContent_No3(), @@ -52,9 +53,9 @@ protected static function openApiSchema3(bool $allowNullValues = false): OpenApi /** * @param bool $allowNullValues - * @return OpenApiSchema + * @return OpenApiSchema|SwaggerSchema */ - protected static function openApiSchema5(bool $allowNullValues = false): OpenApiSchema + protected static function openApiSchema5(bool $allowNullValues = false): OpenApiSchema|SwaggerSchema { return Schema::getInstance( self::getOpenApiJsonContent_No5(), diff --git a/tests/SwaggerBodyTestCase.php b/tests/SwaggerBodyTestCase.php index 6de8f8d..83ab4fc 100644 --- a/tests/SwaggerBodyTestCase.php +++ b/tests/SwaggerBodyTestCase.php @@ -2,6 +2,7 @@ namespace Tests; +use ByJG\ApiTools\OpenApi\OpenApiSchema; use ByJG\ApiTools\Swagger\SwaggerSchema; use PHPUnit\Framework\TestCase; @@ -16,9 +17,9 @@ class SwaggerBodyTestCase extends TestCase /** * @param bool $allowNullValues - * @return SwaggerSchema + * @return SwaggerSchema|OpenApiSchema */ - protected static function swaggerSchema(bool $allowNullValues = false): SwaggerSchema + protected static function swaggerSchema(bool $allowNullValues = false): SwaggerSchema|OpenApiSchema { return \ByJG\ApiTools\Base\Schema::getInstance( self::getSwaggerJsonContent(), @@ -28,9 +29,9 @@ protected static function swaggerSchema(bool $allowNullValues = false): SwaggerS /** * @param bool $allowNullValues - * @return SwaggerSchema + * @return SwaggerSchema|OpenApiSchema */ - protected static function swaggerSchema2(bool $allowNullValues = false): SwaggerSchema + protected static function swaggerSchema2(bool $allowNullValues = false): SwaggerSchema|OpenApiSchema { return \ByJG\ApiTools\Base\Schema::getInstance( self::getSwaggerJsonContent_No2(), From 6aea717a4fc565c4625e147cc2d097240deaad12 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Tue, 3 Jun 2025 05:20:46 -0500 Subject: [PATCH 6/6] Rename test classes and base class to remove "Test" suffix Updated class names to better reflect their purpose by removing the "Test" suffix. This change applies to both the abstract base class and the specific test classes, aligning class naming with their actual roles. --- tests/{AbstractRequesterTest.php => AbstractRequester.php} | 2 +- tests/{OpenApiTest.php => OpenApi.php} | 4 ++-- tests/{SwaggerTest.php => Swagger.php} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename tests/{AbstractRequesterTest.php => AbstractRequester.php} (99%) rename tests/{OpenApiTest.php => OpenApi.php} (73%) rename tests/{SwaggerTest.php => Swagger.php} (73%) diff --git a/tests/AbstractRequesterTest.php b/tests/AbstractRequester.php similarity index 99% rename from tests/AbstractRequesterTest.php rename to tests/AbstractRequester.php index b9199a3..1dfa509 100644 --- a/tests/AbstractRequesterTest.php +++ b/tests/AbstractRequester.php @@ -20,7 +20,7 @@ use ByJG\WebRequest\Psr7\Request; use ByJG\WebRequest\Psr7\Response; -abstract class AbstractRequesterTest extends ApiTestCase +abstract class AbstractRequester extends ApiTestCase { /** * @throws GenericSwaggerException diff --git a/tests/OpenApiTest.php b/tests/OpenApi.php similarity index 73% rename from tests/OpenApiTest.php rename to tests/OpenApi.php index 03c1c6b..992dbda 100644 --- a/tests/OpenApiTest.php +++ b/tests/OpenApi.php @@ -5,9 +5,9 @@ use ByJG\ApiTools\Base\Schema; -require_once "AbstractRequesterTest.php"; +require_once "AbstractRequester.php"; -class OpenApiTest extends AbstractRequesterTest +class OpenApi extends AbstractRequester { #[\Override] public function setUp(): void diff --git a/tests/SwaggerTest.php b/tests/Swagger.php similarity index 73% rename from tests/SwaggerTest.php rename to tests/Swagger.php index 2741b7b..051f18a 100644 --- a/tests/SwaggerTest.php +++ b/tests/Swagger.php @@ -5,10 +5,10 @@ use ByJG\ApiTools\Base\Schema; -require_once "AbstractRequesterTest.php"; +require_once "AbstractRequester.php"; -class SwaggerTest extends AbstractRequesterTest +class Swagger extends AbstractRequester { #[\Override] public function setUp(): void