From fb9caadd904f2d356b9dab1e71e57a0b9cb66c5f Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sun, 7 Jan 2024 13:59:15 -0600 Subject: [PATCH 1/9] Starting type methods and parameters --- composer.json | 8 +-- src/Base/Body.php | 97 ++++++++++++----------------- src/Base/Schema.php | 63 +++++++++++-------- src/OpenApi/OpenApiRequestBody.php | 15 +---- src/OpenApi/OpenApiResponseBody.php | 14 +---- src/OpenApi/OpenApiSchema.php | 52 +++++++--------- src/Swagger/SwaggerRequestBody.php | 16 +---- src/Swagger/SwaggerResponseBody.php | 14 +---- src/Swagger/SwaggerSchema.php | 52 +++++++--------- 9 files changed, 134 insertions(+), 197 deletions(-) diff --git a/composer.json b/composer.json index 39de259..1164075 100644 --- a/composer.json +++ b/composer.json @@ -5,13 +5,13 @@ "prefer-stable": true, "license": "MIT", "require": { - "byjg/webrequest": "4.9.*", - "php": ">=7.4", + "byjg/webrequest": "dev-5.0.0rc", + "php": ">=8.1", "ext-json": "*" }, "require-dev": { - "phpunit/phpunit": "5.7.*|7.4.*|^9.5", - "byjg/restserver": "4.9.*" + "phpunit/phpunit": "^9.6", + "byjg/restserver": "^5.0" }, "autoload": { "psr-4": { diff --git a/src/Base/Body.php b/src/Base/Body.php index 149a73c..d334cc0 100644 --- a/src/Base/Body.php +++ b/src/Base/Body.php @@ -7,11 +7,7 @@ use ByJG\ApiTools\Exception\InvalidDefinitionException; use ByJG\ApiTools\Exception\InvalidRequestException; use ByJG\ApiTools\Exception\NotMatchedException; -use ByJG\ApiTools\OpenApi\OpenApiResponseBody; -use ByJG\ApiTools\OpenApi\OpenApiSchema; -use ByJG\ApiTools\Swagger\SwaggerResponseBody; -use ByJG\ApiTools\Swagger\SwaggerSchema; -use InvalidArgumentException; +use ByJG\ApiTools\Exception\RequiredArgumentNotFound; abstract class Body { @@ -22,17 +18,17 @@ abstract class Body /** * @var Schema */ - protected $schema; + protected Schema $schema; /** * @var array */ - protected $structure; + protected array $structure; /** * @var string */ - protected $name; + protected string $name; /** * OpenApi 2.0 does not describe null values, so this flag defines, @@ -40,7 +36,7 @@ abstract class Body * * @var bool */ - protected $allowNullValues; + protected bool $allowNullValues; /** * Body constructor. @@ -50,49 +46,35 @@ abstract class Body * @param array $structure * @param bool $allowNullValues */ - public function __construct(Schema $schema, $name, $structure, $allowNullValues = false) + public function __construct(Schema $schema, string $name, array $structure, bool $allowNullValues = false) { $this->schema = $schema; $this->name = $name; - if (!is_array($structure)) { - throw new InvalidArgumentException('I expected the structure to be an array'); - } $this->structure = $structure; $this->allowNullValues = $allowNullValues; } /** - * @param Schema $schema - * @param string $name - * @param array $structure - * @param bool $allowNullValues - * @return OpenApiResponseBody|SwaggerResponseBody + * @param mixed $body + * @throws DefinitionNotFoundException * @throws GenericSwaggerException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws NotMatchedException + * @throws RequiredArgumentNotFound + * @return bool */ - public static function getInstance(Schema $schema, $name, $structure, $allowNullValues = false) - { - if ($schema instanceof SwaggerSchema) { - return new SwaggerResponseBody($schema, $name, $structure, $allowNullValues); - } - - if ($schema instanceof OpenApiSchema) { - return new OpenApiResponseBody($schema, $name, $structure, $allowNullValues); - } - - throw new GenericSwaggerException("Cannot get instance SwaggerBody or SchemaBody from " . get_class($schema)); - } - - abstract public function match($body); + abstract public function match(mixed $body): bool; /** * @param string $name * @param array $schemaArray - * @param string $body - * @param string $type - * @return bool + * @param mixed $body + * @param mixed $type + * @return ?bool * @throws NotMatchedException */ - protected function matchString($name, $schemaArray, $body, $type) + protected function matchString(string $name, array $schemaArray, mixed $body, mixed $type): ?bool { if ($type !== 'string') { return null; @@ -113,10 +95,13 @@ protected function matchString($name, $schemaArray, $body, $type) return true; } - private function checkPattern($name, $body, $pattern) + /** + * @throws NotMatchedException + */ + private function checkPattern(string $name, mixed $body, string $pattern): void { $pattern = '/' . rtrim(ltrim($pattern, '/'), '/') . '/'; - $isSuccess = (bool) preg_match($pattern, $body, $matches); + $isSuccess = (bool) preg_match($pattern, $body); if (!$isSuccess) { throw new NotMatchedException("Value '$body' in '$name' not matched in pattern. ", $this->structure); @@ -126,11 +111,11 @@ private function checkPattern($name, $body, $pattern) /** * @param string $name * @param array $schemaArray - * @param string $body - * @param string $type - * @return bool + * @param mixed $body + * @param mixed $type + * @return bool|null */ - protected function matchFile($name, $schemaArray, $body, $type) + protected function matchFile(string $name, array $schemaArray, mixed $body, mixed $type): ?bool { if ($type !== 'file') { return null; @@ -143,10 +128,10 @@ protected function matchFile($name, $schemaArray, $body, $type) * @param string $name * @param string $body * @param string $type - * @return bool + * @return ?bool * @throws NotMatchedException */ - protected function matchNumber($name, $body, $type) + protected function matchNumber(string $name, mixed $body, mixed $type): ?bool { if ($type !== 'integer' && $type !== 'float' && $type !== 'number') { return null; @@ -167,10 +152,10 @@ protected function matchNumber($name, $body, $type) * @param string $name * @param string $body * @param string $type - * @return bool + * @return ?bool * @throws NotMatchedException */ - protected function matchBool($name, $body, $type) + protected function matchBool(string $name, mixed $body, mixed $type): ?bool { if ($type !== 'bool' && $type !== 'boolean') { return null; @@ -188,14 +173,14 @@ protected function matchBool($name, $body, $type) * @param array $schemaArray * @param string $body * @param string $type - * @return bool + * @return ?bool * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws InvalidDefinitionException * @throws InvalidRequestException * @throws NotMatchedException */ - protected function matchArray($name, $schemaArray, $body, $type) + protected function matchArray(string $name, array $schemaArray, mixed $body, mixed $type): ?bool { if ($type !== 'array') { return null; @@ -212,11 +197,11 @@ protected function matchArray($name, $schemaArray, $body, $type) /** * @param string $name - * @param array $schemaArray + * @param mixed $schemaArray * @param string $body - * @return mixed|null + * @return ?bool */ - protected function matchTypes($name, $schemaArray, $body) + protected function matchTypes(string $name, mixed $schemaArray, mixed $body): ?bool { if (!isset($schemaArray['type'])) { return null; @@ -278,7 +263,7 @@ function () use ($name, $schemaArray, $body, $type) * @throws InvalidRequestException * @throws NotMatchedException */ - public function matchObjectProperties($name, $schemaArray, $body) + public function matchObjectProperties(string $name, mixed $schemaArray, mixed $body): ?bool { if (isset($schemaArray[self::SWAGGER_ADDITIONAL_PROPERTIES]) && !isset($schemaArray[self::SWAGGER_PROPERTIES])) { $schemaArray[self::SWAGGER_PROPERTIES] = []; @@ -346,14 +331,14 @@ public function matchObjectProperties($name, $schemaArray, $body) * @param string $name * @param array $schemaArray * @param array $body - * @return bool + * @return ?bool * @throws DefinitionNotFoundException * @throws InvalidDefinitionException * @throws GenericSwaggerException * @throws InvalidRequestException * @throws NotMatchedException */ - protected function matchSchema($name, $schemaArray, $body) + protected function matchSchema(string $name, mixed $schemaArray, mixed $body): ?bool { // Match Single Types if ($this->matchTypes($name, $schemaArray, $body)) { @@ -422,10 +407,10 @@ protected function matchSchema($name, $schemaArray, $body) * @param string $body * @param string $type * @param bool $nullable - * @return bool + * @return ?bool * @throws NotMatchedException */ - protected function matchNull($name, $body, $type, $nullable) + protected function matchNull(string $name, mixed $body, mixed $type, bool $nullable): ?bool { if (!is_null($body)) { return null; diff --git a/src/Base/Schema.php b/src/Base/Schema.php index e9a898e..20a9a54 100644 --- a/src/Base/Schema.php +++ b/src/Base/Schema.php @@ -3,7 +3,6 @@ namespace ByJG\ApiTools\Base; use ByJG\ApiTools\Exception\DefinitionNotFoundException; -use ByJG\ApiTools\Exception\GenericSwaggerException; use ByJG\ApiTools\Exception\HttpMethodNotFoundException; use ByJG\ApiTools\Exception\InvalidDefinitionException; use ByJG\ApiTools\Exception\NotMatchedException; @@ -15,9 +14,9 @@ abstract class Schema { - protected $jsonFile; - protected $allowNullValues = false; - protected $specificationVersion; + protected array $jsonFile; + protected bool $allowNullValues = false; + protected string $specificationVersion; const SWAGGER_PATHS = "paths"; const SWAGGER_PARAMETERS = "parameters"; @@ -27,7 +26,7 @@ abstract class Schema * Returns the major specification version * @return string */ - public function getSpecificationVersion() + public function getSpecificationVersion(): string { return $this->specificationVersion; } @@ -42,16 +41,12 @@ public function getSpecificationVersion() * @param bool $extraArgs * @return Schema */ - public static function getInstance($data, $extraArgs = false) + public static function getInstance(array|string $data, bool $extraArgs = false): Schema { // when given a string, decode from JSON if (is_string($data)) { $data = json_decode($data, true); } - // make sure we got an array - if (!is_array($data)) { - throw new InvalidArgumentException('schema must be given as array or JSON string'); - } // check which type of file we got and dispatch to derived class constructor if (isset($data['swagger'])) { return new SwaggerSchema($data, $extraArgs); @@ -73,7 +68,7 @@ public static function getInstance($data, $extraArgs = false) * @throws NotMatchedException * @throws PathNotFoundException */ - public function getPathDefinition($path, $method) + public function getPathDefinition(string $path, string $method): mixed { $method = strtolower($method); @@ -91,7 +86,7 @@ public function getPathDefinition($path, $method) // Try inline parameter foreach (array_keys($this->jsonFile[self::SWAGGER_PATHS]) as $pathItem) { - if (strpos($pathItem, '{') === false) { + if (!str_contains($pathItem, '{')) { continue; } @@ -134,9 +129,8 @@ public function getPathDefinition($path, $method) * @throws InvalidDefinitionException * @throws NotMatchedException * @throws PathNotFoundException - * @throws GenericSwaggerException */ - public function getResponseParameters($path, $method, $status) + public function getResponseParameters(string $path, string $method, string $status): Body { $structure = $this->getPathDefinition($path, $method); @@ -152,7 +146,7 @@ public function getResponseParameters($path, $method, $status) } } - return Body::getInstance($this, "$method $status $path", $structure['responses'][$verifyStatus]); + return $this->getResponseBody($this, "$method $status $path", $structure['responses'][$verifyStatus]); } /** @@ -161,24 +155,27 @@ public function getResponseParameters($path, $method, $status) * * @return bool */ - public function isAllowNullValues() + public function isAllowNullValues(): bool { return $this->allowNullValues; } - abstract public function getServerUrl(); + /** + * @return string + */ + abstract public function getServerUrl(): string; /** - * @param $parameterIn - * @param $parameters - * @param $arguments + * @param string $parameterIn + * @param array $parameters + * @param array $arguments * @throws DefinitionNotFoundException * @throws InvalidDefinitionException * @throws NotMatchedException */ - abstract protected function validateArguments($parameterIn, $parameters, $arguments); + abstract protected function validateArguments(string $parameterIn, array $parameters, array $arguments): void; - abstract public function getBasePath(); + abstract public function getBasePath(): string; /** * @param $name @@ -186,14 +183,28 @@ abstract public function getBasePath(); * @throws DefinitionNotFoundException * @throws InvalidDefinitionException */ - abstract public function getDefinition($name); + abstract public function getDefinition($name): mixed; /** - * @param $path - * @param $method + * @param string $path + * @param string $method * @return Body * @throws HttpMethodNotFoundException * @throws PathNotFoundException + * @throws DefinitionNotFoundException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws NotMatchedException + * @throws PathNotFoundException + */ + abstract public function getRequestParameters(string $path, string $method): Body; + + /** + * @param Schema $schema + * @param string $name + * @param array $structure + * @param bool $allowNullValues + * @return Body */ - abstract public function getRequestParameters($path, $method); + abstract public function getResponseBody(Schema $schema, string $name, array $structure, bool $allowNullValues = false): Body; } diff --git a/src/OpenApi/OpenApiRequestBody.php b/src/OpenApi/OpenApiRequestBody.php index 2075768..1647285 100644 --- a/src/OpenApi/OpenApiRequestBody.php +++ b/src/OpenApi/OpenApiRequestBody.php @@ -3,26 +3,15 @@ namespace ByJG\ApiTools\OpenApi; use ByJG\ApiTools\Base\Body; -use ByJG\ApiTools\Exception\DefinitionNotFoundException; -use ByJG\ApiTools\Exception\GenericSwaggerException; use ByJG\ApiTools\Exception\InvalidDefinitionException; -use ByJG\ApiTools\Exception\InvalidRequestException; -use ByJG\ApiTools\Exception\NotMatchedException; use ByJG\ApiTools\Exception\RequiredArgumentNotFound; class OpenApiRequestBody extends Body { /** - * @param string $body - * @return bool - * @throws GenericSwaggerException - * @throws InvalidDefinitionException - * @throws InvalidRequestException - * @throws NotMatchedException - * @throws RequiredArgumentNotFound - * @throws DefinitionNotFoundException + * @inheritDoc */ - public function match($body) + public function match(mixed $body): bool { if (isset($this->structure['content']) || isset($this->structure['$ref'])) { if (isset($this->structure['required']) && $this->structure['required'] === true && empty($body)) { diff --git a/src/OpenApi/OpenApiResponseBody.php b/src/OpenApi/OpenApiResponseBody.php index 277a917..10416a8 100644 --- a/src/OpenApi/OpenApiResponseBody.php +++ b/src/OpenApi/OpenApiResponseBody.php @@ -3,24 +3,14 @@ namespace ByJG\ApiTools\OpenApi; use ByJG\ApiTools\Base\Body; -use ByJG\ApiTools\Exception\DefinitionNotFoundException; -use ByJG\ApiTools\Exception\GenericSwaggerException; -use ByJG\ApiTools\Exception\InvalidDefinitionException; -use ByJG\ApiTools\Exception\InvalidRequestException; use ByJG\ApiTools\Exception\NotMatchedException; class OpenApiResponseBody extends Body { /** - * @param string $body - * @return bool - * @throws GenericSwaggerException - * @throws InvalidRequestException - * @throws NotMatchedException - * @throws DefinitionNotFoundException - * @throws InvalidDefinitionException + * @inheritDoc */ - public function match($body) + public function match(mixed $body): bool { if (empty($this->structure['content']) && !isset($this->structure['$ref'])) { if (!empty($body)) { diff --git a/src/OpenApi/OpenApiSchema.php b/src/OpenApi/OpenApiSchema.php index 0a12fae..562d4c6 100644 --- a/src/OpenApi/OpenApiSchema.php +++ b/src/OpenApi/OpenApiSchema.php @@ -2,39 +2,33 @@ namespace ByJG\ApiTools\OpenApi; +use ByJG\ApiTools\Base\Body; use ByJG\ApiTools\Base\Schema; use ByJG\ApiTools\Exception\DefinitionNotFoundException; -use ByJG\ApiTools\Exception\HttpMethodNotFoundException; use ByJG\ApiTools\Exception\InvalidDefinitionException; use ByJG\ApiTools\Exception\NotMatchedException; -use ByJG\ApiTools\Exception\PathNotFoundException; use ByJG\Util\Uri; -use InvalidArgumentException; class OpenApiSchema extends Schema { - protected $serverVariables = []; + protected array $serverVariables = []; /** * Initialize with schema data, which can be a PHP array or encoded as JSON. * * @param array|string $data */ - public function __construct($data) + public function __construct(array|string $data) { // when given a string, decode from JSON if (is_string($data)) { $data = json_decode($data, true); } - // make sure we got an array - if (!is_array($data)) { - throw new InvalidArgumentException('schema must be given as array or JSON string'); - } $this->jsonFile = $data; } - public function getServerUrl() + public function getServerUrl(): string { if (!isset($this->jsonFile['servers'])) { return ''; @@ -50,27 +44,22 @@ public function getServerUrl() } foreach ($this->serverVariables as $var => $value) { - $serverUrl = preg_replace("/\{$var\}/", $value, $serverUrl); + $serverUrl = preg_replace("/\{$var}/", $value, $serverUrl); } return $serverUrl; } - public function getBasePath() + public function getBasePath(): string { $uriServer = new Uri($this->getServerUrl()); return $uriServer->getPath(); } /** - * @param $parameterIn - * @param $parameters - * @param $arguments - * @throws DefinitionNotFoundException - * @throws InvalidDefinitionException - * @throws NotMatchedException + * @inheritDoc */ - protected function validateArguments($parameterIn, $parameters, $arguments) + protected function validateArguments(string $parameterIn, array $parameters, array $arguments): void { foreach ($parameters as $parameter) { if (isset($parameter['$ref'])) { @@ -82,7 +71,7 @@ protected function validateArguments($parameterIn, $parameters, $arguments) } if (!isset($this->jsonFile[self::SWAGGER_COMPONENTS][self::SWAGGER_PARAMETERS][$paramParts[3]])) { throw new DefinitionNotFoundException( - "Not find reference #/components/parameters/{$paramParts[3]}" + "Not find reference #/components/parameters/$paramParts[3]" ); } $parameter = $this->jsonFile[self::SWAGGER_COMPONENTS][self::SWAGGER_PARAMETERS][$paramParts[3]]; @@ -101,7 +90,7 @@ protected function validateArguments($parameterIn, $parameters, $arguments) * @throws DefinitionNotFoundException * @throws InvalidDefinitionException */ - public function getDefinition($name) + public function getDefinition($name): mixed { $nameParts = explode('/', $name); @@ -117,16 +106,9 @@ public function getDefinition($name) } /** - * @param $path - * @param $method - * @return OpenApiRequestBody - * @throws DefinitionNotFoundException - * @throws HttpMethodNotFoundException - * @throws InvalidDefinitionException - * @throws NotMatchedException - * @throws PathNotFoundException + * @inheritDoc */ - public function getRequestParameters($path, $method) + public function getRequestParameters(string $path, string $method): Body { $structure = $this->getPathDefinition($path, $method); @@ -136,8 +118,16 @@ public function getRequestParameters($path, $method) return new OpenApiRequestBody($this, "$method $path", $structure['requestBody']); } - public function setServerVariable($var, $value) + public function setServerVariable(string $var, string $value): void { $this->serverVariables[$var] = $value; } + + /** + * @inheritDoc + */ + 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 e1a5584..2005522 100644 --- a/src/Swagger/SwaggerRequestBody.php +++ b/src/Swagger/SwaggerRequestBody.php @@ -3,26 +3,16 @@ namespace ByJG\ApiTools\Swagger; use ByJG\ApiTools\Base\Body; -use ByJG\ApiTools\Exception\DefinitionNotFoundException; -use ByJG\ApiTools\Exception\GenericSwaggerException; use ByJG\ApiTools\Exception\InvalidDefinitionException; -use ByJG\ApiTools\Exception\InvalidRequestException; use ByJG\ApiTools\Exception\NotMatchedException; use ByJG\ApiTools\Exception\RequiredArgumentNotFound; class SwaggerRequestBody extends Body { /** - * @param string $body - * @return bool - * @throws GenericSwaggerException - * @throws InvalidDefinitionException - * @throws InvalidRequestException - * @throws NotMatchedException - * @throws RequiredArgumentNotFound - * @throws DefinitionNotFoundException + * @inheritDoc */ - public function match($body) + public function match(mixed $body): bool { $hasFormData = false; foreach ($this->structure as $parameter) { @@ -37,7 +27,7 @@ public function match($body) if (isset($parameter['required']) && $parameter['required'] === true && !isset($body[$parameter['name']])) { throw new RequiredArgumentNotFound("The formData parameter '{$parameter['name']}' is required but it isn't found. "); } - if (!$this->matchTypes($parameter['name'], $parameter, (isset($body[$parameter['name']]) ? $body[$parameter['name']] : null))) { + if (!$this->matchTypes($parameter['name'], $parameter, ($body[$parameter['name']] ?? null))) { throw new NotMatchedException("The formData parameter '{$parameter['name']}' not match with the specification"); } } diff --git a/src/Swagger/SwaggerResponseBody.php b/src/Swagger/SwaggerResponseBody.php index fe52b52..df6478b 100644 --- a/src/Swagger/SwaggerResponseBody.php +++ b/src/Swagger/SwaggerResponseBody.php @@ -3,24 +3,14 @@ namespace ByJG\ApiTools\Swagger; use ByJG\ApiTools\Base\Body; -use ByJG\ApiTools\Exception\DefinitionNotFoundException; -use ByJG\ApiTools\Exception\GenericSwaggerException; -use ByJG\ApiTools\Exception\InvalidDefinitionException; -use ByJG\ApiTools\Exception\InvalidRequestException; use ByJG\ApiTools\Exception\NotMatchedException; class SwaggerResponseBody extends Body { /** - * @param string $body - * @return bool - * @throws GenericSwaggerException - * @throws InvalidRequestException - * @throws NotMatchedException - * @throws DefinitionNotFoundException - * @throws InvalidDefinitionException + * @inheritDoc */ - public function match($body) + public function match(mixed $body): bool { if (!isset($this->structure['schema'])) { if (!empty($body)) { diff --git a/src/Swagger/SwaggerSchema.php b/src/Swagger/SwaggerSchema.php index 8acbbea..2e3e26c 100644 --- a/src/Swagger/SwaggerSchema.php +++ b/src/Swagger/SwaggerSchema.php @@ -2,13 +2,11 @@ namespace ByJG\ApiTools\Swagger; +use ByJG\ApiTools\Base\Body; use ByJG\ApiTools\Base\Schema; use ByJG\ApiTools\Exception\DefinitionNotFoundException; -use ByJG\ApiTools\Exception\HttpMethodNotFoundException; use ByJG\ApiTools\Exception\InvalidDefinitionException; use ByJG\ApiTools\Exception\NotMatchedException; -use ByJG\ApiTools\Exception\PathNotFoundException; -use InvalidArgumentException; class SwaggerSchema extends Schema { @@ -18,18 +16,14 @@ class SwaggerSchema extends Schema * @param array|string $data * @param bool $allowNullValues */ - public function __construct($data, $allowNullValues = false) + public function __construct(array|string $data, bool $allowNullValues = false) { // when given a string, decode from JSON if (is_string($data)) { $data = json_decode($data, true); } - // make sure we got an array - if (!is_array($data)) { - throw new InvalidArgumentException('schema must be given as array or JSON string'); - } $this->jsonFile = $data; - $this->allowNullValues = (bool) $allowNullValues; + $this->allowNullValues = $allowNullValues; } public function getHttpSchema() @@ -39,15 +33,15 @@ public function getHttpSchema() public function getHost() { - return isset($this->jsonFile['host']) ? $this->jsonFile['host'] : ''; + return $this->jsonFile['host'] ?? ''; } - public function getBasePath() + public function getBasePath(): string { - return isset($this->jsonFile['basePath']) ? $this->jsonFile['basePath'] : ''; + return $this->jsonFile['basePath'] ?? ''; } - public function getServerUrl() + public function getServerUrl(): string { $httpSchema = $this->getHttpSchema(); if (!empty($httpSchema)) { @@ -59,12 +53,9 @@ public function getServerUrl() } /** - * @param $parameterIn - * @param $parameters - * @param $arguments - * @throws NotMatchedException + * @inheritDoc */ - protected function validateArguments($parameterIn, $parameters, $arguments) + protected function validateArguments(string $parameterIn, array $parameters, array $arguments): void { foreach ($parameters as $parameter) { if ($parameter['in'] === $parameterIn @@ -81,7 +72,7 @@ protected function validateArguments($parameterIn, $parameters, $arguments) * @throws DefinitionNotFoundException * @throws InvalidDefinitionException */ - public function getDefinition($name) + public function getDefinition($name): mixed { $nameParts = explode('/', $name); @@ -97,16 +88,9 @@ public function getDefinition($name) } /** - * @param $path - * @param $method - * @return SwaggerRequestBody - * @throws DefinitionNotFoundException - * @throws HttpMethodNotFoundException - * @throws InvalidDefinitionException - * @throws NotMatchedException - * @throws PathNotFoundException + * @inheritDoc */ - public function getRequestParameters($path, $method) + public function getRequestParameters(string $path, string $method): Body { $structure = $this->getPathDefinition($path, $method); @@ -120,10 +104,18 @@ public function getRequestParameters($path, $method) * OpenApi 2.0 doesn't describe null values, so this flag defines, * if match is ok when one of property * - * @param $value + * @param string|bool $value */ - public function setAllowNullValues($value) + public function setAllowNullValues(string|bool $value): void { $this->allowNullValues = (bool) $value; } + + /** + * @inheritDoc + */ + public function getResponseBody(Schema $schema, string $name, array $structure, bool $allowNullValues = false): Body + { + return new SwaggerResponseBody($schema, $name, $structure, $allowNullValues); + } } From eb84af80683284562bc55b1d05f48f566ce479e5 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sun, 7 Jan 2024 14:15:03 -0600 Subject: [PATCH 2/9] Starting type methods and parameters --- src/AbstractRequester.php | 94 ++++++++++++++++++--------------- src/ApiRequester.php | 17 +++--- src/ApiTestCase.php | 54 ++++++++++--------- src/Exception/BaseException.php | 4 +- src/MockRequester.php | 14 ++--- 5 files changed, 97 insertions(+), 86 deletions(-) diff --git a/src/AbstractRequester.php b/src/AbstractRequester.php index 67c2198..06f4084 100644 --- a/src/AbstractRequester.php +++ b/src/AbstractRequester.php @@ -3,12 +3,18 @@ namespace ByJG\ApiTools; use ByJG\ApiTools\Base\Schema; +use ByJG\ApiTools\Exception\DefinitionNotFoundException; +use ByJG\ApiTools\Exception\GenericSwaggerException; +use ByJG\ApiTools\Exception\HttpMethodNotFoundException; +use ByJG\ApiTools\Exception\InvalidDefinitionException; use ByJG\ApiTools\Exception\InvalidRequestException; use ByJG\ApiTools\Exception\NotMatchedException; +use ByJG\ApiTools\Exception\PathNotFoundException; +use ByJG\ApiTools\Exception\RequiredArgumentNotFound; use ByJG\ApiTools\Exception\StatusCodeNotMatchedException; -use ByJG\Util\Psr7\MessageException; +use ByJG\Util\Exception\MessageException; +use ByJG\Util\Exception\RequestException; use ByJG\Util\Psr7\Request; -use ByJG\Util\Psr7\Response; use ByJG\Util\Uri; use ByJG\Util\Psr7\MemoryStream; use Psr\Http\Message\RequestInterface; @@ -27,22 +33,23 @@ abstract class AbstractRequester { /** - * @var Schema + * @var Schema|null */ - protected $schema = null; + protected ?Schema $schema = null; - protected $statusExpected = 200; - protected $assertHeader = []; - protected $assertBody = []; + protected int $statusExpected = 200; + protected array $assertHeader = []; + protected array $assertBody = []; /** * @var RequestInterface */ - protected $psr7Request; + protected RequestInterface $psr7Request; /** * AbstractRequester constructor. * @throws MessageException + * @throws RequestException */ public function __construct() { @@ -58,13 +65,13 @@ public function __construct() * @param RequestInterface $request * @return ResponseInterface */ - abstract protected function handleRequest(RequestInterface $request); + abstract protected function handleRequest(RequestInterface $request): ResponseInterface; /** * @param Schema $schema * @return $this */ - public function withSchema($schema) + public function withSchema(Schema $schema): self { $this->schema = $schema; @@ -74,7 +81,7 @@ public function withSchema($schema) /** * @return bool */ - public function hasSchema() + public function hasSchema(): bool { return !empty($this->schema); } @@ -82,9 +89,8 @@ public function hasSchema() /** * @param string $method * @return $this - * @throws MessageException */ - public function withMethod($method) + public function withMethod(string $method): self { $this->psr7Request = $this->psr7Request->withMethod($method); @@ -95,7 +101,7 @@ public function withMethod($method) * @param string $path * @return $this */ - public function withPath($path) + public function withPath(string $path): self { $uri = $this->psr7Request->getUri()->withPath($path); $this->psr7Request = $this->psr7Request->withUri($uri); @@ -104,10 +110,10 @@ public function withPath($path) } /** - * @param array $requestHeader + * @param string|array $requestHeader * @return $this */ - public function withRequestHeader($requestHeader) + public function withRequestHeader(string|array $requestHeader): self { foreach ((array)$requestHeader as $name => $value) { $this->psr7Request = $this->psr7Request->withHeader($name, $value); @@ -117,10 +123,10 @@ public function withRequestHeader($requestHeader) } /** - * @param array $query + * @param array|null $query * @return $this */ - public function withQuery($query = null) + public function withQuery(array $query = null): self { $uri = $this->psr7Request->getUri(); @@ -143,10 +149,10 @@ public function withQuery($query = null) * @param mixed $requestBody * @return $this */ - public function withRequestBody($requestBody) + public function withRequestBody(array|string $requestBody): self { $contentType = $this->psr7Request->getHeaderLine("Content-Type"); - if (is_array($requestBody) && (empty($contentType) || strpos($contentType, "application/json") !== false)) { + if (is_array($requestBody) && (empty($contentType) || str_contains($contentType, "application/json"))) { $requestBody = json_encode($requestBody); } $this->psr7Request = $this->psr7Request->withBody(new MemoryStream($requestBody)); @@ -154,28 +160,28 @@ public function withRequestBody($requestBody) return $this; } - public function withPsr7Request(RequestInterface $requestInterface) + public function withPsr7Request(RequestInterface $requestInterface): self { $this->psr7Request = $requestInterface->withHeader("Accept", "application/json"); return $this; } - public function assertResponseCode($code) + public function assertResponseCode(int $code): self { $this->statusExpected = $code; return $this; } - public function assertHeaderContains($header, $contains) + public function assertHeaderContains(string $header, string $contains): self { $this->assertHeader[$header] = $contains; return $this; } - public function assertBodyContains($contains) + public function assertBodyContains(string $contains): self { $this->assertBody[] = $contains; @@ -183,18 +189,18 @@ public function assertBodyContains($contains) } /** - * @return Response|ResponseInterface - * @throws Exception\DefinitionNotFoundException - * @throws Exception\GenericSwaggerException - * @throws Exception\HttpMethodNotFoundException - * @throws Exception\InvalidDefinitionException - * @throws Exception\PathNotFoundException + * @return ResponseInterface + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException - * @throws MessageException - * @throws InvalidRequestException */ - public function send() + public function send(): ResponseInterface { // Process URI based on the OpenAPI schema $uriSchema = new Uri($this->schema->getServerUrl()); @@ -225,12 +231,12 @@ public function send() $requestBody = $requestBody->getContents(); $contentType = $this->psr7Request->getHeaderLine("content-type"); - if (empty($contentType) || strpos($contentType, "application/json") !== false) { + if (empty($contentType) || str_contains($contentType, "application/json")) { $requestBody = json_decode($requestBody, true); - } elseif (strpos($contentType, "multipart/") !== false) { + } elseif (str_contains($contentType, "multipart/")) { $requestBody = $this->parseMultiPartForm($contentType, $requestBody); } else { - throw new InvalidRequestException("Cannot handle Content Type '{$contentType}'"); + throw new InvalidRequestException("Cannot handle Content Type '$contentType'"); } } @@ -248,7 +254,7 @@ public function send() // Assert results if ($this->statusExpected != $statusReturned) { throw new StatusCodeNotMatchedException( - "Status code not matched: Expected {$this->statusExpected}, got {$statusReturned}", + "Status code not matched: Expected $this->statusExpected, got $statusReturned", $responseBody ); } @@ -261,7 +267,7 @@ public function send() $bodyResponseDef->match($responseBody); foreach ($this->assertHeader as $key => $value) { - if (!isset($responseHeader[$key]) || strpos($responseHeader[$key][0], $value) === false) { + if (!isset($responseHeader[$key]) || !str_contains($responseHeader[$key][0], $value)) { throw new NotMatchedException( "Does not exists header '$key' with value '$value'", $responseHeader @@ -271,8 +277,8 @@ public function send() if (!empty($responseBodyStr)) { foreach ($this->assertBody as $item) { - if (strpos($responseBodyStr, $item) === false) { - throw new NotMatchedException("Body does not contain '{$item}'"); + if (!str_contains($responseBodyStr, $item)) { + throw new NotMatchedException("Body does not contain '$item'"); } } } @@ -280,11 +286,11 @@ public function send() return $response; } - protected function parseMultiPartForm($contentType, $body) + protected function parseMultiPartForm(?string $contentType, string $body): array|null { $matchRequest = []; - if (empty($contentType) || strpos($contentType, "multipart/") === false) { + if (empty($contentType) || !str_contains($contentType, "multipart/")) { return null; } @@ -298,11 +304,11 @@ protected function parseMultiPartForm($contentType, $body) array_pop($blocks); // loop data blocks - foreach ($blocks as $id => $block) { + foreach ($blocks as $block) { if (empty($block)) continue; - if (strpos($block, 'application/octet-stream') !== false) { + if (str_contains($block, 'application/octet-stream')) { preg_match("/name=\"([^\"]*)\".*stream[\n|\r]+([^\n\r].*)?$/s", $block, $matches); } else { preg_match('/\bname=\"([^\"]*)\"\s*;.*?[\n|\r]+([^\n\r].*)?[\r|\n]$/s', $block, $matches); diff --git a/src/ApiRequester.php b/src/ApiRequester.php index af6b84f..cba891a 100644 --- a/src/ApiRequester.php +++ b/src/ApiRequester.php @@ -2,10 +2,10 @@ namespace ByJG\ApiTools; -use ByJG\Util\CurlException; +use ByJG\Util\Exception\MessageException; +use ByJG\Util\Exception\NetworkException; +use ByJG\Util\Exception\RequestException; use ByJG\Util\HttpClient; -use ByJG\Util\Psr7\MessageException; -use ByJG\Util\Psr7\Response; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -15,10 +15,11 @@ class ApiRequester extends AbstractRequester { /** @var HttpClient */ - private $httpClient; + private HttpClient $httpClient; /** * ApiRequester constructor. + * @throws RequestException * @throws MessageException */ public function __construct() @@ -31,11 +32,11 @@ public function __construct() /** * @param RequestInterface $request - * @return Response|ResponseInterface - * @throws CurlException - * @throws MessageException + * @return ResponseInterface + * @throws NetworkException + * @throws RequestException */ - protected function handleRequest(RequestInterface $request) + protected function handleRequest(RequestInterface $request): ResponseInterface { $request = $request->withHeader("User-Agent", "ByJG Swagger Test"); return $this->httpClient->sendRequest($request); diff --git a/src/ApiTestCase.php b/src/ApiTestCase.php index df094bd..518bbb1 100644 --- a/src/ApiTestCase.php +++ b/src/ApiTestCase.php @@ -7,24 +7,26 @@ use ByJG\ApiTools\Exception\GenericSwaggerException; use ByJG\ApiTools\Exception\HttpMethodNotFoundException; use ByJG\ApiTools\Exception\InvalidDefinitionException; +use ByJG\ApiTools\Exception\InvalidRequestException; use ByJG\ApiTools\Exception\NotMatchedException; use ByJG\ApiTools\Exception\PathNotFoundException; +use ByJG\ApiTools\Exception\RequiredArgumentNotFound; use ByJG\ApiTools\Exception\StatusCodeNotMatchedException; -use ByJG\Util\Psr7\MessageException; use ByJG\Util\Psr7\Response; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ResponseInterface; abstract class ApiTestCase extends TestCase { /** * @var Schema */ - protected $schema; + protected Schema $schema; /** - * @var AbstractRequester + * @var AbstractRequester|null */ - protected $requester = null; + protected ?AbstractRequester $requester = null; /** * configure the schema to use for requests @@ -33,20 +35,20 @@ abstract class ApiTestCase extends TestCase * * @param Schema|null $schema */ - public function setSchema($schema) + public function setSchema(?Schema $schema): void { $this->schema = $schema; } - public function setRequester(AbstractRequester $requester) + public function setRequester(AbstractRequester $requester): void { $this->requester = $requester; } /** - * @return AbstractRequester + * @return AbstractRequester|null */ - protected function getRequester() + protected function getRequester(): AbstractRequester|null { if (is_null($this->requester)) { $this->requester = new ApiRequester(); @@ -58,28 +60,29 @@ protected function getRequester() * @param string $method The HTTP Method: GET, PUT, DELETE, POST, etc * @param string $path The REST path call * @param int $statusExpected - * @param array|null $query - * @param array|null $requestBody + * @param string|array|null $query + * @param array|string|null $requestBody * @param array $requestHeader * @return mixed * @throws DefinitionNotFoundException * @throws GenericSwaggerException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException + * @throws InvalidRequestException * @throws NotMatchedException * @throws PathNotFoundException + * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException - * @throws MessageException * @deprecated Use assertRequest instead */ protected function makeRequest( - $method, - $path, - $statusExpected = 200, - $query = null, - $requestBody = null, - $requestHeader = [] - ) { + string $method, + string $path, + int $statusExpected = 200, + string|array|null $query = null, + array|string $requestBody = null, + array $requestHeader = [] + ): ResponseInterface { $this->checkSchema(); $body = $this->requester ->withSchema($this->schema) @@ -92,8 +95,8 @@ protected function makeRequest( ->send(); // Note: - // This code is only reached if the send is successful and - // all matches are satisfied. Otherwise an error is throwed before + // This code is only reached if to send is successful and + // all matches are satisfied. Otherwise, an error is throwed before // reach this $this->assertTrue(true); @@ -107,12 +110,13 @@ protected function makeRequest( * @throws GenericSwaggerException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException + * @throws InvalidRequestException * @throws NotMatchedException * @throws PathNotFoundException + * @throws RequiredArgumentNotFound * @throws StatusCodeNotMatchedException - * @throws MessageException */ - public function assertRequest(AbstractRequester $request) + public function assertRequest(AbstractRequester $request): ResponseInterface { // Add own schema if nothing is passed. if (!$request->hasSchema()) { @@ -124,8 +128,8 @@ public function assertRequest(AbstractRequester $request) $body = $request->send(); // Note: - // This code is only reached if the send is successful and - // all matches are satisfied. Otherwise an error is throwed before + // This code is only reached if to send is successful and + // all matches are satisfied. Otherwise, an error is throwed before // reach this $this->assertTrue(true); @@ -135,7 +139,7 @@ public function assertRequest(AbstractRequester $request) /** * @throws GenericSwaggerException */ - protected function checkSchema() + protected function checkSchema(): void { if (!$this->schema) { throw new GenericSwaggerException('You have to configure a schema for either the request or the testcase'); diff --git a/src/Exception/BaseException.php b/src/Exception/BaseException.php index 594a0b9..ac6ad73 100644 --- a/src/Exception/BaseException.php +++ b/src/Exception/BaseException.php @@ -7,7 +7,7 @@ class BaseException extends Exception { - protected $body; + protected mixed $body; public function __construct($message = "", $body = [], $code = 0, Throwable $previous = null) { @@ -21,7 +21,7 @@ public function __construct($message = "", $body = [], $code = 0, Throwable $pre /** * @return mixed */ - public function getBody() + public function getBody(): mixed { return $this->body; } diff --git a/src/MockRequester.php b/src/MockRequester.php index 273a9d2..e34e0c1 100644 --- a/src/MockRequester.php +++ b/src/MockRequester.php @@ -3,9 +3,9 @@ namespace ByJG\ApiTools; -use ByJG\Util\CurlException; +use ByJG\Util\Exception\MessageException; +use ByJG\Util\Exception\RequestException; use ByJG\Util\MockClient; -use ByJG\Util\Psr7\MessageException; use ByJG\Util\Psr7\Response; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -13,11 +13,12 @@ class MockRequester extends AbstractRequester { /** @var MockClient */ - private $httpClient; + private MockClient $httpClient; /** * MockAbstractRequest constructor. * @param Response $expectedResponse + * @throws RequestException * @throws MessageException */ public function __construct(Response $expectedResponse) @@ -28,11 +29,10 @@ public function __construct(Response $expectedResponse) /** * @param RequestInterface $request - * @return Response|ResponseInterface - * @throws CurlException - * @throws MessageException + * @return ResponseInterface + * @throws RequestException */ - protected function handleRequest(RequestInterface $request) + protected function handleRequest(RequestInterface $request): ResponseInterface { $request = $request->withHeader("User-Agent", "ByJG Swagger Test"); return $this->httpClient->sendRequest($request); From 91c268624566924776288fbd4725d62720cbafd3 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sun, 7 Jan 2024 14:16:47 -0600 Subject: [PATCH 3/9] PHP 8.1 as minimum version --- .github/workflows/phpunit.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index ed26121..ab8c251 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -16,10 +16,9 @@ jobs: strategy: matrix: php-version: + - "8.3" - "8.2" - "8.1" - - "8.0" - - "7.4" steps: - uses: actions/checkout@v4 From af3235c4fa2616af5f6c48bc45a8a02182796adb Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Fri, 13 Sep 2024 08:38:37 -0500 Subject: [PATCH 4/9] Add some build configuration and PSalm (buggy yet) --- .github/workflows/phpunit.yml | 1 + .idea/runConfigurations/PSalm.xml | 5 +++++ .travis.yml | 21 --------------------- composer.json | 7 ++++--- psalm.xml | 18 ++++++++++++++++++ tests/rest/classes/Handler.php | 5 ++--- 6 files changed, 30 insertions(+), 27 deletions(-) create mode 100644 .idea/runConfigurations/PSalm.xml delete mode 100644 .travis.yml create mode 100644 psalm.xml diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index ab8c251..5c0b2ec 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -28,6 +28,7 @@ jobs: SPEC=swagger php -S 127.0.0.1:8080 tests/rest/app.php & SPEC=openapi php -S 127.0.0.1:8081 tests/rest/app.php & - run: ./vendor/bin/phpunit + - run: ./vendor/bin/psalm Documentation: if: github.ref == 'refs/heads/master' diff --git a/.idea/runConfigurations/PSalm.xml b/.idea/runConfigurations/PSalm.xml new file mode 100644 index 0000000..bd119ce --- /dev/null +++ b/.idea/runConfigurations/PSalm.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fdc6aee..0000000 --- a/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: php -php: - - nightly - - "8.0" - - "7.4" - - "7.3" - -install: - - composer install - - SPEC=swagger php -S 127.0.0.1:8080 tests/rest/app.php & - - SPEC=openapi php -S 127.0.0.1:8081 tests/rest/app.php & - -script: - - vendor/bin/phpunit - -jobs: - include: - - stage: documentation - if: branch = master - install: skip - script: "curl https://opensource.byjg.com/add-doc.sh | bash /dev/stdin php php-swagger-test" diff --git a/composer.json b/composer.json index 1164075..b0b5491 100644 --- a/composer.json +++ b/composer.json @@ -5,13 +5,14 @@ "prefer-stable": true, "license": "MIT", "require": { - "byjg/webrequest": "dev-5.0.0rc", "php": ">=8.1", - "ext-json": "*" + "ext-json": "*", + "byjg/webrequest": "^5.0" }, "require-dev": { "phpunit/phpunit": "^9.6", - "byjg/restserver": "^5.0" + "byjg/restserver": "^5.0", + "vimeo/psalm": "^5.9" }, "autoload": { "psr-4": { diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..ebabb1a --- /dev/null +++ b/psalm.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/tests/rest/classes/Handler.php b/tests/rest/classes/Handler.php index 165d7b8..4c2948c 100644 --- a/tests/rest/classes/Handler.php +++ b/tests/rest/classes/Handler.php @@ -4,7 +4,7 @@ use ByJG\RestServer\HttpRequest; use ByJG\RestServer\HttpResponse; -use ByJG\Serializer\BinderObject; +use ByJG\Serializer\ObjectCopy; class Handler { @@ -28,12 +28,11 @@ public function getPetById($response, $request) /** * @param HttpResponse $response * @param HttpRequest $request - * @throws \ByJG\Serializer\Exception\InvalidArgumentException */ public function addPet($response, $request) { $pet = new Pet(); - BinderObject::bind(json_decode($request->payload()), $pet); + ObjectCopy::copy(json_decode($request->payload()), $pet); if ($pet->getId() == "999") { // Simulate an error From a7e68c0f49703d0275564180da08b1a97bde13e9 Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Fri, 13 Sep 2024 09:24:46 -0500 Subject: [PATCH 5/9] Fix Psalm issues. --- src/AbstractRequester.php | 10 +- src/ApiTestCase.php | 4 +- src/Base/Body.php | 39 +++--- src/Base/Schema.php | 6 +- src/OpenApi/OpenApiRequestBody.php | 4 +- src/OpenApi/OpenApiResponseBody.php | 6 +- src/OpenApi/OpenApiSchema.php | 2 +- src/Swagger/SwaggerRequestBody.php | 2 +- src/Swagger/SwaggerResponseBody.php | 2 +- tests/AbstractRequesterTest.php | 201 +++++++++++++++++----------- tests/rest/app.php | 2 +- tests/rest/classes/Category.php | 2 +- tests/rest/classes/Handler.php | 2 +- tests/rest/classes/Pet.php | 2 +- tests/rest/classes/Tag.php | 2 +- tests/rest/openapi.json | 6 +- tests/rest/swagger.json | 6 +- 17 files changed, 172 insertions(+), 126 deletions(-) diff --git a/src/AbstractRequester.php b/src/AbstractRequester.php index 06f4084..6d6c9e6 100644 --- a/src/AbstractRequester.php +++ b/src/AbstractRequester.php @@ -131,7 +131,7 @@ public function withQuery(array $query = null): self $uri = $this->psr7Request->getUri(); if (is_null($query)) { - $uri = $uri->withQuery(null); + $uri = $uri->withQuery(""); $this->psr7Request = $this->psr7Request->withUri($uri); return $this; } @@ -160,6 +160,10 @@ public function withRequestBody(array|string $requestBody): self return $this; } + /** + * @param RequestInterface $requestInterface + * @return $this + */ public function withPsr7Request(RequestInterface $requestInterface): self { $this->psr7Request = $requestInterface->withHeader("Accept", "application/json"); @@ -226,10 +230,8 @@ public function send(): ResponseInterface $this->psr7Request = $this->psr7Request->withUri($uri); // Prepare Body to Match Against Specification - $requestBody = $this->psr7Request->getBody(); + $requestBody = $this->psr7Request->getBody()->getContents(); if (!empty($requestBody)) { - $requestBody = $requestBody->getContents(); - $contentType = $this->psr7Request->getHeaderLine("content-type"); if (empty($contentType) || str_contains($contentType, "application/json")) { $requestBody = json_decode($requestBody, true); diff --git a/src/ApiTestCase.php b/src/ApiTestCase.php index 518bbb1..72e63b0 100644 --- a/src/ApiTestCase.php +++ b/src/ApiTestCase.php @@ -19,9 +19,9 @@ abstract class ApiTestCase extends TestCase { /** - * @var Schema + * @var Schema|null */ - protected Schema $schema; + protected ?Schema $schema = null; /** * @var AbstractRequester|null diff --git a/src/Base/Body.php b/src/Base/Body.php index c3083af..180a5fe 100644 --- a/src/Base/Body.php +++ b/src/Base/Body.php @@ -126,12 +126,13 @@ protected function matchFile(string $name, array $schemaArray, mixed $body, mixe /** * @param string $name - * @param string $body - * @param string $type + * @param array $schemaArray + * @param mixed $body + * @param mixed $type * @return ?bool * @throws NotMatchedException */ - protected function matchNumber(string $name, mixed $body, mixed $type): ?bool + protected function matchNumber(string $name, array $schemaArray, mixed $body, mixed $type): ?bool { if ($type !== 'integer' && $type !== 'float' && $type !== 'number') { return null; @@ -150,8 +151,8 @@ protected function matchNumber(string $name, mixed $body, mixed $type): ?bool /** * @param string $name - * @param string $body - * @param string $type + * @param mixed $body + * @param mixed $type * @return ?bool * @throws NotMatchedException */ @@ -171,8 +172,8 @@ protected function matchBool(string $name, mixed $body, mixed $type): ?bool /** * @param string $name * @param array $schemaArray - * @param string $body - * @param string $type + * @param mixed $body + * @param mixed $type * @return ?bool * @throws DefinitionNotFoundException * @throws GenericSwaggerException @@ -198,7 +199,7 @@ protected function matchArray(string $name, array $schemaArray, mixed $body, mix /** * @param string $name * @param mixed $schemaArray - * @param string $body + * @param mixed $body * @return ?bool */ protected function matchTypes(string $name, mixed $schemaArray, mixed $body): ?bool @@ -221,9 +222,9 @@ function () use ($name, $schemaArray, $body, $type) return $this->matchString($name, $schemaArray, $body, $type); }, - function () use ($name, $body, $type) + function () use ($name, $schemaArray, $body, $type) { - return $this->matchNumber($name, $body, $type); + return $this->matchNumber($name, $schemaArray, $body, $type); }, function () use ($name, $body, $type) @@ -255,7 +256,7 @@ function () use ($name, $schemaArray, $body, $type) /** * @param string $name * @param array $schemaArray - * @param string $body + * @param mixed $body * @return bool|null * @throws DefinitionNotFoundException * @throws GenericSwaggerException @@ -351,8 +352,8 @@ protected function matchSchema(string $name, mixed $schemaArray, mixed $body): ? // Get References and try to match it again if (isset($schemaArray['$ref']) && !is_array($schemaArray['$ref'])) { - $defintion = $this->schema->getDefinition($schemaArray['$ref']); - return $this->matchSchema($schemaArray['$ref'], $defintion, $body); + $definition = $this->schema->getDefinition($schemaArray['$ref']); + return $this->matchSchema($schemaArray['$ref'], $definition, $body); } // Match object properties @@ -374,16 +375,16 @@ protected function matchSchema(string $name, mixed $schemaArray, mixed $body): ? if (isset($schemaArray['oneOf'])) { $matched = false; - $catchedException = null; + $catchException = null; foreach ($schemaArray['oneOf'] as $schema) { try { $matched = $matched || $this->matchSchema($name, $schema, $body); } catch (NotMatchedException $exception) { - $catchedException = $exception; + $catchException = $exception; } } - if ($catchedException !== null && $matched === false) { - throw $catchedException; + if ($catchException !== null && $matched === false) { + throw $catchException; } return $matched; @@ -409,8 +410,8 @@ protected function matchSchema(string $name, mixed $schemaArray, mixed $body): ? /** * @param string $name - * @param string $body - * @param string $type + * @param mixed $body + * @param mixed $type * @param bool $nullable * @return ?bool * @throws NotMatchedException diff --git a/src/Base/Schema.php b/src/Base/Schema.php index 1eef4ac..992496c 100644 --- a/src/Base/Schema.php +++ b/src/Base/Schema.php @@ -66,6 +66,7 @@ public static function getInstance(array|string $data, bool $extraArgs = false): * @throws DefinitionNotFoundException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException + * @throws InvalidRequestException * @throws NotMatchedException * @throws PathNotFoundException */ @@ -126,15 +127,16 @@ public function getPathDefinition(string $path, string $method): mixed /** * @param string $path * @param string $method - * @param string $status + * @param int $status * @return Body * @throws DefinitionNotFoundException * @throws HttpMethodNotFoundException * @throws InvalidDefinitionException + * @throws InvalidRequestException * @throws NotMatchedException * @throws PathNotFoundException */ - public function getResponseParameters(string $path, string $method, string $status): Body + public function getResponseParameters(string $path, string $method, int $status): Body { $structure = $this->getPathDefinition($path, $method); diff --git a/src/OpenApi/OpenApiRequestBody.php b/src/OpenApi/OpenApiRequestBody.php index 1647285..497ca24 100644 --- a/src/OpenApi/OpenApiRequestBody.php +++ b/src/OpenApi/OpenApiRequestBody.php @@ -19,10 +19,10 @@ public function match(mixed $body): bool } if (isset($this->structure['$ref'])) { - return $this->matchSchema($this->name, $this->structure, $body); + return $this->matchSchema($this->name, $this->structure, $body) ?? false; } - return $this->matchSchema($this->name, $this->structure['content'][key($this->structure['content'])]['schema'], $body); + return $this->matchSchema($this->name, $this->structure['content'][key($this->structure['content'])]['schema'], $body) ?? false; } if (!empty($body)) { diff --git a/src/OpenApi/OpenApiResponseBody.php b/src/OpenApi/OpenApiResponseBody.php index 10416a8..18fe74b 100644 --- a/src/OpenApi/OpenApiResponseBody.php +++ b/src/OpenApi/OpenApiResponseBody.php @@ -20,10 +20,10 @@ public function match(mixed $body): bool } if(!isset($this->structure['content']) && isset($this->structure['$ref'])){ - $defintion = $this->schema->getDefinition($this->structure['$ref']); - return $this->matchSchema($this->name, $defintion, $body); + $definition = $this->schema->getDefinition($this->structure['$ref']); + return $this->matchSchema($this->name, $definition, $body) ?? false; } - return $this->matchSchema($this->name, $this->structure['content'][key($this->structure['content'])]['schema'], $body); + return $this->matchSchema($this->name, $this->structure['content'][key($this->structure['content'])]['schema'], $body) ?? false; } } diff --git a/src/OpenApi/OpenApiSchema.php b/src/OpenApi/OpenApiSchema.php index 562d4c6..e7e1f44 100644 --- a/src/OpenApi/OpenApiSchema.php +++ b/src/OpenApi/OpenApiSchema.php @@ -44,7 +44,7 @@ public function getServerUrl(): string } foreach ($this->serverVariables as $var => $value) { - $serverUrl = preg_replace("/\{$var}/", $value, $serverUrl); + $serverUrl = (string)preg_replace("/\{$var}/", $value, $serverUrl); } return $serverUrl; diff --git a/src/Swagger/SwaggerRequestBody.php b/src/Swagger/SwaggerRequestBody.php index 2005522..6382bd3 100644 --- a/src/Swagger/SwaggerRequestBody.php +++ b/src/Swagger/SwaggerRequestBody.php @@ -20,7 +20,7 @@ public function match(mixed $body): bool if (isset($parameter['required']) && $parameter['required'] === true && empty($body)) { throw new RequiredArgumentNotFound('The body is required but it is empty'); } - return $this->matchSchema($this->name, $parameter['schema'], $body); + return $this->matchSchema($this->name, $parameter['schema'], $body) ?? false; } if ($parameter['in'] === "formData") { $hasFormData = true; diff --git a/src/Swagger/SwaggerResponseBody.php b/src/Swagger/SwaggerResponseBody.php index df6478b..cd04c7a 100644 --- a/src/Swagger/SwaggerResponseBody.php +++ b/src/Swagger/SwaggerResponseBody.php @@ -18,6 +18,6 @@ public function match(mixed $body): bool } return true; } - return $this->matchSchema($this->name, $this->structure['schema'], $body); + return $this->matchSchema($this->name, $this->structure['schema'], $body) ?? false; } } diff --git a/tests/AbstractRequesterTest.php b/tests/AbstractRequesterTest.php index 10f8bb2..b32d393 100644 --- a/tests/AbstractRequesterTest.php +++ b/tests/AbstractRequesterTest.php @@ -3,7 +3,18 @@ namespace Test; use ByJG\ApiTools\ApiTestCase; +use ByJG\ApiTools\Exception\DefinitionNotFoundException; +use ByJG\ApiTools\Exception\GenericSwaggerException; +use ByJG\ApiTools\Exception\HttpMethodNotFoundException; +use ByJG\ApiTools\Exception\InvalidDefinitionException; +use ByJG\ApiTools\Exception\InvalidRequestException; +use ByJG\ApiTools\Exception\NotMatchedException; +use ByJG\ApiTools\Exception\PathNotFoundException; +use ByJG\ApiTools\Exception\RequiredArgumentNotFound; +use ByJG\ApiTools\Exception\StatusCodeNotMatchedException; use ByJG\ApiTools\MockRequester; +use ByJG\Util\Exception\MessageException; +use ByJG\Util\Exception\RequestException; use ByJG\Util\Psr7\Request; use ByJG\Util\Psr7\Response; use ByJG\Util\Uri; @@ -39,14 +50,17 @@ public function testExpectOK() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws MessageException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequestException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testExpectError() { @@ -68,14 +82,17 @@ public function testExpectError() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws MessageException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequestException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testValidateAssertResponse() { @@ -96,14 +113,17 @@ public function testValidateAssertResponse() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws MessageException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequestException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testValidateAssertResponse404() { @@ -119,14 +139,17 @@ public function testValidateAssertResponse404() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws MessageException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequestException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testValidateAssertResponse404WithContent() { @@ -146,14 +169,17 @@ public function testValidateAssertResponse404WithContent() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws MessageException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequestException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testValidateAssertResponseNotExpected() { @@ -172,14 +198,17 @@ public function testValidateAssertResponseNotExpected() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws MessageException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequestException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testValidateAssertHeaderContains() { @@ -202,14 +231,17 @@ public function testValidateAssertHeaderContains() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws MessageException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequestException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testValidateAssertHeaderContainsWrongValue() { @@ -235,14 +267,17 @@ public function testValidateAssertHeaderContainsWrongValue() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws MessageException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequestException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testValidateAssertHeaderContainsNonExistent() { @@ -267,14 +302,17 @@ public function testValidateAssertHeaderContainsNonExistent() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws MessageException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequestException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testValidateAssertBodyContains() { @@ -296,14 +334,17 @@ public function testValidateAssertBodyContains() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException - * @throws \ByJG\Util\Psr7\MessageException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException + * @throws MessageException + * @throws RequestException */ public function testValidateAssertBodyNotContains() { diff --git a/tests/rest/app.php b/tests/rest/app.php index ca5eddd..056608b 100644 --- a/tests/rest/app.php +++ b/tests/rest/app.php @@ -1,5 +1,5 @@ Date: Fri, 13 Sep 2024 09:40:02 -0500 Subject: [PATCH 6/9] Fix Code Smell --- composer.json | 2 +- src/OpenApi/OpenApiSchema.php | 2 + src/Swagger/SwaggerSchema.php | 2 + tests/AbstractRequesterTest.php | 15 +- tests/BaseExceptionTest.php | 2 +- tests/OpenApiBodyTestCase.php | 18 +- tests/OpenApiRequestBodyTest.php | 48 +++-- tests/OpenApiResponseBodyTest.php | 280 +++++++++++++++++----------- tests/OpenApiSchemaTest.php | 62 +++++-- tests/OpenApiTest.php | 2 +- tests/OpenApiTestCaseTest.php | 2 +- tests/SwaggerBodyTestCase.php | 10 +- tests/SwaggerRequestBodyTest.php | 18 +- tests/SwaggerResponseBodyTest.php | 292 +++++++++++++++++------------- tests/SwaggerSchemaTest.php | 64 ++++--- tests/SwaggerTest.php | 2 +- tests/SwaggerTestCaseTest.php | 2 +- tests/TestingTestCase.php | 80 ++++++-- tests/example/openapi4.json | 1 + tests/example/swagger.json | 4 +- tests/example/swagger2.json | 8 +- tests/rest/app.php | 2 +- tests/rest/classes/Category.php | 2 +- tests/rest/classes/Handler.php | 2 +- tests/rest/classes/Pet.php | 2 +- tests/rest/classes/Tag.php | 2 +- tests/rest/openapi.json | 6 +- tests/rest/swagger.json | 10 +- 28 files changed, 605 insertions(+), 337 deletions(-) diff --git a/composer.json b/composer.json index b0b5491..bea6e79 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ }, "autoload-dev": { "psr-4": { - "Test\\": "tests/" + "Tests\\": "tests/" } } } diff --git a/src/OpenApi/OpenApiSchema.php b/src/OpenApi/OpenApiSchema.php index e7e1f44..0880609 100644 --- a/src/OpenApi/OpenApiSchema.php +++ b/src/OpenApi/OpenApiSchema.php @@ -6,6 +6,7 @@ use ByJG\ApiTools\Base\Schema; use ByJG\ApiTools\Exception\DefinitionNotFoundException; use ByJG\ApiTools\Exception\InvalidDefinitionException; +use ByJG\ApiTools\Exception\InvalidRequestException; use ByJG\ApiTools\Exception\NotMatchedException; use ByJG\Util\Uri; @@ -107,6 +108,7 @@ public function getDefinition($name): mixed /** * @inheritDoc + * @throws InvalidRequestException */ public function getRequestParameters(string $path, string $method): Body { diff --git a/src/Swagger/SwaggerSchema.php b/src/Swagger/SwaggerSchema.php index 2e3e26c..af432ef 100644 --- a/src/Swagger/SwaggerSchema.php +++ b/src/Swagger/SwaggerSchema.php @@ -6,6 +6,7 @@ use ByJG\ApiTools\Base\Schema; use ByJG\ApiTools\Exception\DefinitionNotFoundException; use ByJG\ApiTools\Exception\InvalidDefinitionException; +use ByJG\ApiTools\Exception\InvalidRequestException; use ByJG\ApiTools\Exception\NotMatchedException; class SwaggerSchema extends Schema @@ -89,6 +90,7 @@ public function getDefinition($name): mixed /** * @inheritDoc + * @throws InvalidRequestException */ public function getRequestParameters(string $path, string $method): Body { diff --git a/tests/AbstractRequesterTest.php b/tests/AbstractRequesterTest.php index b32d393..e802e9e 100644 --- a/tests/AbstractRequesterTest.php +++ b/tests/AbstractRequesterTest.php @@ -1,6 +1,6 @@ getRequestParameters('/v2/pet/findByStatus?status=pending', 'get'); $this->assertTrue(true); } + /** + * @throws DefinitionNotFoundException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws NotMatchedException + * @throws PathNotFoundException + */ public function testMatchParameterInQuery2() { self::openApiSchema3()->getRequestParameters('/tests/12345?count=20&offset=2', 'get'); @@ -110,11 +135,12 @@ public function testMatchParameterInQuery2() /** * - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException + * @throws DefinitionNotFoundException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws InvalidRequestException */ public function testMatchParameterInQuery3() { diff --git a/tests/OpenApiResponseBodyTest.php b/tests/OpenApiResponseBodyTest.php index a2a9029..8bcce37 100644 --- a/tests/OpenApiResponseBodyTest.php +++ b/tests/OpenApiResponseBodyTest.php @@ -1,19 +1,27 @@ assertTrue($responseParameter->match($body)); } + /** + * @throws GenericSwaggerException + * @throws DefinitionNotFoundException + * @throws PathNotFoundException + * @throws NotMatchedException + * @throws InvalidRequestException + * @throws RequiredArgumentNotFound + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + */ public function testAdditionalPropertiesInObjectInResponseBody() { $body = ['value1' => 1, 'value2' => 2]; @@ -355,6 +384,15 @@ public function testAdditionalPropertiesInObjectInResponseBody() $this->assertTrue($responseParameter->match($body)); } + /** + * @throws GenericSwaggerException + * @throws DefinitionNotFoundException + * @throws PathNotFoundException + * @throws RequiredArgumentNotFound + * @throws InvalidRequestException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + */ public function testAdditionalPropertiesInObjectInResponseBodyDoNotMatch() { $this->expectExceptionMessage("Expected 'value2' to be numeric, but found 'string'"); @@ -367,13 +405,14 @@ public function testAdditionalPropertiesInObjectInResponseBodyDoNotMatch() /** * Issue #9 * - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\InvalidRequestException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequiredArgumentNotFound */ public function testIssue9() { @@ -400,13 +439,14 @@ public function testIssue9() /** * Issue #9 * - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\InvalidRequestException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequiredArgumentNotFound */ public function testIssue9Error() { @@ -433,13 +473,14 @@ public function testIssue9Error() /** * Issue #9 * - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\GenericSwaggerException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\InvalidRequestException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException + * @throws InvalidRequestException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequiredArgumentNotFound */ public function testMatchAnyValue() { @@ -456,6 +497,16 @@ public function testMatchAnyValue() $this->assertTrue($responseParameter->match($body)); } + /** + * @throws GenericSwaggerException + * @throws DefinitionNotFoundException + * @throws NotMatchedException + * @throws RequiredArgumentNotFound + * @throws HttpMethodNotFoundException + * @throws PathNotFoundException + * @throws InvalidRequestException + * @throws InvalidDefinitionException + */ public function testMatchAllOf() { $body = ["name" => "Bob", "email" => "bob@example.com"]; @@ -466,6 +517,16 @@ public function testMatchAllOf() $this->assertTrue($responseParameter->match($body)); } + /** + * @throws GenericSwaggerException + * @throws DefinitionNotFoundException + * @throws PathNotFoundException + * @throws NotMatchedException + * @throws InvalidRequestException + * @throws RequiredArgumentNotFound + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + */ public function testResponseDefault() { $body = []; @@ -473,6 +534,13 @@ public function testResponseDefault() $this->assertTrue($responseParameter->match($body)); } + /** + * @throws DefinitionNotFoundException + * @throws PathNotFoundException + * @throws NotMatchedException + * @throws InvalidRequestException + * @throws HttpMethodNotFoundException + */ public function testResponseWithNoDefault() { $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); diff --git a/tests/OpenApiSchemaTest.php b/tests/OpenApiSchemaTest.php index a2d9d81..4c61e66 100644 --- a/tests/OpenApiSchemaTest.php +++ b/tests/OpenApiSchemaTest.php @@ -1,7 +1,13 @@ assertTrue($responseParameter->match($body)); } + /** + * @throws GenericSwaggerException + * @throws DefinitionNotFoundException + * @throws PathNotFoundException + * @throws NotMatchedException + * @throws InvalidRequestException + * @throws RequiredArgumentNotFound + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + */ public function testResponseDefault() { $body = []; @@ -522,6 +561,13 @@ public function testResponseDefault() $this->assertTrue($responseParameter->match($body)); } + /** + * @throws DefinitionNotFoundException + * @throws PathNotFoundException + * @throws NotMatchedException + * @throws InvalidRequestException + * @throws HttpMethodNotFoundException + */ public function testResponseWithNoDefault() { $this->expectException(\ByJG\ApiTools\Exception\InvalidDefinitionException::class); diff --git a/tests/SwaggerSchemaTest.php b/tests/SwaggerSchemaTest.php index c496345..39d3705 100644 --- a/tests/SwaggerSchemaTest.php +++ b/tests/SwaggerSchemaTest.php @@ -1,7 +1,13 @@ assertRequest($request); } + /** + * @throws GenericSwaggerException + * @throws DefinitionNotFoundException + * @throws NotMatchedException + * @throws RequiredArgumentNotFound + * @throws HttpMethodNotFoundException + * @throws PathNotFoundException + * @throws StatusCodeNotMatchedException + * @throws RequestException + * @throws InvalidRequestException + * @throws MessageException + * @throws InvalidDefinitionException + */ public function testPost() { $body = [ @@ -68,12 +103,15 @@ public function testPost() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testAddError() { @@ -96,12 +134,15 @@ public function testAddError() } /** - * @throws \ByJG\ApiTools\Exception\DefinitionNotFoundException - * @throws \ByJG\ApiTools\Exception\HttpMethodNotFoundException - * @throws \ByJG\ApiTools\Exception\InvalidDefinitionException - * @throws \ByJG\ApiTools\Exception\NotMatchedException - * @throws \ByJG\ApiTools\Exception\PathNotFoundException - * @throws \ByJG\ApiTools\Exception\StatusCodeNotMatchedException + * @throws DefinitionNotFoundException + * @throws GenericSwaggerException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + * @throws InvalidRequestException + * @throws NotMatchedException + * @throws PathNotFoundException + * @throws RequiredArgumentNotFound + * @throws StatusCodeNotMatchedException */ public function testPostError() { @@ -124,6 +165,19 @@ public function testPostError() $this->assertRequest($request); } + /** + * @throws GenericSwaggerException + * @throws PathNotFoundException + * @throws DefinitionNotFoundException + * @throws StatusCodeNotMatchedException + * @throws RequestException + * @throws NotMatchedException + * @throws RequiredArgumentNotFound + * @throws InvalidRequestException + * @throws MessageException + * @throws HttpMethodNotFoundException + * @throws InvalidDefinitionException + */ public function testMultipart() { $multipart = [ diff --git a/tests/example/openapi4.json b/tests/example/openapi4.json index 40dbd76..a844cd3 100644 --- a/tests/example/openapi4.json +++ b/tests/example/openapi4.json @@ -1,5 +1,6 @@ { "openapi": "3.0.0", + "paths": {}, "info": { "description": "This is a sample server Petstore server. You can find out more about\nSwagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net,\n`special-key` to test the authorization filters.", "version": "1.0.0", diff --git a/tests/example/swagger.json b/tests/example/swagger.json index ce69078..24dade5 100644 --- a/tests/example/swagger.json +++ b/tests/example/swagger.json @@ -21,7 +21,7 @@ "description": "Everything about your Pets", "externalDocs": { "description": "Find out more", - "url": "http://swagger.io" + "url": "https://swagger.io" } }, { @@ -33,7 +33,7 @@ "description": "Operations about user", "externalDocs": { "description": "Find out more about our store", - "url": "http://swagger.io" + "url": "https://swagger.io" } } ], diff --git a/tests/example/swagger2.json b/tests/example/swagger2.json index 52b4d64..76f10fc 100644 --- a/tests/example/swagger2.json +++ b/tests/example/swagger2.json @@ -1,16 +1,16 @@ { "swagger": "2.0", "info": { - "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", + "description": "This is a sample server Petstore server. You can find out more about Swagger at [https://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.", "version": "1.0.0", "title": "Swagger Petstore", - "termsOfService": "http://swagger.io/terms/", + "termsOfService": "https://swagger.io/terms/", "contact": { "email": "apiteam@swagger.io" }, "license": { "name": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" } }, "host": "petstore.swagger.io", @@ -149,6 +149,6 @@ }, "externalDocs": { "description": "Find out more about Swagger", - "url": "http://swagger.io" + "url": "https://swagger.io" } } diff --git a/tests/rest/app.php b/tests/rest/app.php index 056608b..4ab23d8 100644 --- a/tests/rest/app.php +++ b/tests/rest/app.php @@ -1,5 +1,5 @@ Date: Fri, 13 Sep 2024 12:25:25 -0500 Subject: [PATCH 7/9] Fix Test Namespaces --- .idea/runConfigurations/{Test_Project.xml => Main.xml} | 4 ++-- .idea/runConfigurations/{PSalm.xml => Psalm.xml} | 2 +- tests/{rest/classes => Classes}/Category.php | 2 +- tests/{rest/classes => Classes}/Handler.php | 2 +- tests/{rest/classes => Classes}/Pet.php | 2 +- tests/{rest/classes => Classes}/Tag.php | 2 +- tests/rest/app.php | 6 ------ tests/rest/openapi.json | 6 +++--- tests/rest/swagger.json | 6 +++--- 9 files changed, 13 insertions(+), 19 deletions(-) rename .idea/runConfigurations/{Test_Project.xml => Main.xml} (62%) rename .idea/runConfigurations/{PSalm.xml => Psalm.xml} (74%) rename tests/{rest/classes => Classes}/Category.php (96%) rename tests/{rest/classes => Classes}/Handler.php (98%) rename tests/{rest/classes => Classes}/Pet.php (98%) rename tests/{rest/classes => Classes}/Tag.php (96%) diff --git a/.idea/runConfigurations/Test_Project.xml b/.idea/runConfigurations/Main.xml similarity index 62% rename from .idea/runConfigurations/Test_Project.xml rename to .idea/runConfigurations/Main.xml index e276fab..97a74c9 100644 --- a/.idea/runConfigurations/Test_Project.xml +++ b/.idea/runConfigurations/Main.xml @@ -1,6 +1,6 @@ - + - + \ No newline at end of file diff --git a/.idea/runConfigurations/PSalm.xml b/.idea/runConfigurations/Psalm.xml similarity index 74% rename from .idea/runConfigurations/PSalm.xml rename to .idea/runConfigurations/Psalm.xml index bd119ce..6f80a21 100644 --- a/.idea/runConfigurations/PSalm.xml +++ b/.idea/runConfigurations/Psalm.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/tests/rest/classes/Category.php b/tests/Classes/Category.php similarity index 96% rename from tests/rest/classes/Category.php rename to tests/Classes/Category.php index a61f55a..8a03cfd 100644 --- a/tests/rest/classes/Category.php +++ b/tests/Classes/Category.php @@ -1,6 +1,6 @@ Date: Mon, 16 Sep 2024 10:24:20 -0500 Subject: [PATCH 8/9] Upgrade breaking change from `byjg\webrequest` and `byjg\jwt-wrapper` --- docs/mock-requests.md | 6 +++--- src/AbstractRequester.php | 8 ++++---- src/ApiRequester.php | 8 ++++---- src/ApiTestCase.php | 2 +- src/MockRequester.php | 8 ++++---- tests/AbstractRequesterTest.php | 10 +++++----- tests/TestingTestCase.php | 14 +++++++------- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/mock-requests.md b/docs/mock-requests.md index 137aeb9..5d6b337 100644 --- a/docs/mock-requests.md +++ b/docs/mock-requests.md @@ -11,8 +11,8 @@ class MyTest extends ApiTestCase { public function testExpectOK() { - $expectedResponse = \ByJG\Util\Psr7\Response::getInstance(200) - ->withBody(new \ByJG\Util\Psr7\MemoryStream(json_encode([ + $expectedResponse = \ByJG\WebRequest\Psr7\Response::getInstance(200) + ->withBody(new \ByJG\WebRequest\Psr7\MemoryStream(json_encode([ "id" => 1, "name" => "Spike", "photoUrls" => [] @@ -39,7 +39,7 @@ e.g. ```php withMethod("GET") ->withBody('{"foo":"bar"}'); diff --git a/src/AbstractRequester.php b/src/AbstractRequester.php index 6d6c9e6..18ad4ad 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\Exception\MessageException; -use ByJG\Util\Exception\RequestException; -use ByJG\Util\Psr7\Request; +use ByJG\WebRequest\Exception\MessageException; +use ByJG\WebRequest\Exception\RequestException; +use ByJG\WebRequest\Psr7\Request; use ByJG\Util\Uri; -use ByJG\Util\Psr7\MemoryStream; +use ByJG\WebRequest\Psr7\MemoryStream; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; diff --git a/src/ApiRequester.php b/src/ApiRequester.php index cba891a..336883a 100644 --- a/src/ApiRequester.php +++ b/src/ApiRequester.php @@ -2,10 +2,10 @@ namespace ByJG\ApiTools; -use ByJG\Util\Exception\MessageException; -use ByJG\Util\Exception\NetworkException; -use ByJG\Util\Exception\RequestException; -use ByJG\Util\HttpClient; +use ByJG\WebRequest\Exception\MessageException; +use ByJG\WebRequest\Exception\NetworkException; +use ByJG\WebRequest\Exception\RequestException; +use ByJG\WebRequest\HttpClient; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; diff --git a/src/ApiTestCase.php b/src/ApiTestCase.php index 72e63b0..88e890c 100644 --- a/src/ApiTestCase.php +++ b/src/ApiTestCase.php @@ -12,7 +12,7 @@ use ByJG\ApiTools\Exception\PathNotFoundException; use ByJG\ApiTools\Exception\RequiredArgumentNotFound; use ByJG\ApiTools\Exception\StatusCodeNotMatchedException; -use ByJG\Util\Psr7\Response; +use ByJG\WebRequest\Psr7\Response; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; diff --git a/src/MockRequester.php b/src/MockRequester.php index e34e0c1..27d10d0 100644 --- a/src/MockRequester.php +++ b/src/MockRequester.php @@ -3,10 +3,10 @@ namespace ByJG\ApiTools; -use ByJG\Util\Exception\MessageException; -use ByJG\Util\Exception\RequestException; -use ByJG\Util\MockClient; -use ByJG\Util\Psr7\Response; +use ByJG\WebRequest\Exception\MessageException; +use ByJG\WebRequest\Exception\RequestException; +use ByJG\WebRequest\MockClient; +use ByJG\WebRequest\Psr7\Response; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; diff --git a/tests/AbstractRequesterTest.php b/tests/AbstractRequesterTest.php index e802e9e..0c4a1db 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\Exception\MessageException; -use ByJG\Util\Exception\RequestException; -use ByJG\Util\Psr7\Request; -use ByJG\Util\Psr7\Response; +use ByJG\WebRequest\Exception\MessageException; +use ByJG\WebRequest\Exception\RequestException; +use ByJG\WebRequest\Psr7\Request; +use ByJG\WebRequest\Psr7\Response; use ByJG\Util\Uri; -use ByJG\Util\Psr7\MemoryStream; +use ByJG\WebRequest\Psr7\MemoryStream; abstract class AbstractRequesterTest extends ApiTestCase { diff --git a/tests/TestingTestCase.php b/tests/TestingTestCase.php index 208bf5d..ddfa8b6 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\Exception\MessageException; -use ByJG\Util\Exception\RequestException; -use ByJG\Util\Helper\RequestMultiPart; -use ByJG\Util\MultiPartItem; -use ByJG\Util\Psr7\Request; -use ByJG\Util\Psr7\Response; +use ByJG\WebRequest\Exception\MessageException; +use ByJG\WebRequest\Exception\RequestException; +use ByJG\WebRequest\Helper\RequestMultiPart; +use ByJG\WebRequest\MultiPartItem; +use ByJG\WebRequest\Psr7\Request; +use ByJG\WebRequest\Psr7\Response; use ByJG\Util\Uri; -use ByJG\Util\Psr7\MemoryStream; +use ByJG\WebRequest\Psr7\MemoryStream; /** * Class TestingTestCase From 47f4deaeb9959f8c6ccb63c6e31f1bce53c8117b Mon Sep 17 00:00:00 2001 From: Joao Gilberto Magalhaes Date: Sun, 27 Oct 2024 10:19:41 -0500 Subject: [PATCH 9/9] Limit PHP Version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bea6e79..064e2d3 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "prefer-stable": true, "license": "MIT", "require": { - "php": ">=8.1", + "php": ">=8.1 <8.4", "ext-json": "*", "byjg/webrequest": "^5.0" },