diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4cb5b25..f970c7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,11 +18,12 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 - with: - tools: phpcs - - name: Run phpcs - run: phpcs + - name: Install composer dependencies + uses: ramsey/composer-install@v2 + + - name: Check coding style + run: vendor/bin/php-cs-fixer fix --dry-run tests: name: Tests diff --git a/.gitignore b/.gitignore index 41fcb16..d86755b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ composer.lock vendor phpcs.xml phpunit.xml -.phpunit.result.cache \ No newline at end of file +.phpunit.result.cache +.php-cs-fixer.cache \ No newline at end of file diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..fdb2201 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,238 @@ +in(__DIR__ . '/src') + ->in(__DIR__ . '/tests'); +; + +$config = new PhpCsFixer\Config(); +return $config->setRules([ + '@PSR12' => true, + 'align_multiline_comment' => [ + 'comment_type' => 'all_multiline', + ], + 'array_indentation' => true, + 'assign_null_coalescing_to_coalesce_equal' => true, + 'binary_operator_spaces' => [ + 'default' => 'single_space', + ], + 'cast_spaces' => [ + 'space' => 'single', + ], + 'class_attributes_separation' => [ + 'elements' => ['const' => 'one', 'method' => 'one', 'property' => 'one', 'trait_import' => 'none', 'case' => 'none'], + ], + 'class_reference_name_casing' => true, + 'clean_namespace' => true, + 'combine_consecutive_issets' => true, + 'concat_space' => [ + 'spacing' => 'one', + ], + 'declare_parentheses' => true, + 'explicit_indirect_variable' => true, + 'explicit_string_variable' => true, + 'fully_qualified_strict_types' => true, + 'function_typehint_space' => true, + 'general_phpdoc_tag_rename' => [ + 'replacements' => ['inheritDocs' => 'inheritDoc'], + ], + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => true, + 'import_functions' => true, + ], + 'heredoc_indentation' => [ + 'indentation' => 'same_as_start', + ], + 'include' => true, + 'integer_literal_case' => true, + 'lambda_not_used_import' => true, + 'linebreak_after_opening_tag' => true, + 'list_syntax' => [ + 'syntax' => 'short', + ], + 'magic_constant_casing' => true, + 'magic_method_casing' => true, + 'method_chaining_indentation' => true, + 'multiline_comment_opening_closing' => true, + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line', + ], + 'native_function_casing' => true, + 'native_function_type_declaration_casing' => true, + 'no_alias_language_construct_call' => true, + 'no_alternative_syntax' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => [ + 'tokens' => ['extra'], + ], + 'no_leading_namespace_whitespace' => true, + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_null_property_initialization' => true, + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_around_offset' => true, + 'no_superfluous_phpdoc_tags' => [ + 'allow_mixed' => false, + 'allow_unused_params' => false, + 'remove_inheritdoc' => false, + ], + 'no_trailing_comma_in_singleline' => [ + 'elements' => ['arguments', 'array_destructuring', 'array', 'group_import'], + ], + 'no_unneeded_control_parentheses' => [ + 'statements' => [ + 'break', + 'clone', + 'continue', + 'echo_print', + 'negative_instanceof', + 'others', 'return', + 'switch_case', + 'yield', + 'yield_from', + ], + ], + 'no_unneeded_curly_braces' => [ + 'namespaces' => false, + ], + 'no_unneeded_import_alias' => true, + 'no_unset_cast' => true, + 'no_unused_imports' => true, + 'no_useless_concat_operator' => true, + 'no_useless_else' => true, + 'no_useless_nullsafe_operator' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => [ + 'after_heredoc' => false, + ], + 'normalize_index_brace' => true, + 'not_operator_with_successor_space' => true, + 'nullable_type_declaration_for_default_null_value' => [ + 'use_nullable_type_declaration' => true, + ], + 'object_operator_without_whitespace' => true, + 'operator_linebreak' => [ + 'only_booleans' => false, + 'position' => 'beginning', + ], + 'ordered_interfaces' => [ + 'direction' => 'ascend', + 'order' => 'alpha', + ], + 'php_unit_method_casing' => [ + 'case' => 'snake_case', + ], + 'phpdoc_align' => [ + 'align' => 'vertical', + 'tags' => ['method', 'param', 'property', 'property-read', 'property-write', 'return', 'throws', 'type', 'var'], + ], + 'phpdoc_annotation_without_dot' => true, + 'phpdoc_indent' => true, + 'phpdoc_inline_tag_normalizer' => [ + 'tags' => ['example', 'id', 'internal', 'inheritdoc', 'inheritdocs', 'link', 'source', 'toc', 'tutorial'], + ], + 'phpdoc_line_span' => [ + 'const' => 'single', + 'method' => 'single', + 'property' => 'single', + ], + 'phpdoc_no_alias_tag' => [ + 'replacements' => ['type' => 'var', 'link' => 'see'], + ], + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_order' => [ + 'order' => ['param', 'return', 'throws'], + ], + 'phpdoc_order_by_value' => [ + 'annotations' => [ + 'author', + 'covers', + 'coversNothing', + 'dataProvider', + 'depends', + 'group', + 'internal', + 'method', + 'mixin', + 'property', + 'property-read', + 'property-write', + 'requires', + 'throws', + 'uses', + ], + ], + 'phpdoc_return_self_reference' => [ + 'replacements' => [ + 'this' => 'self', + '@this' => 'self', + '$self' => 'self', + '@self' => 'self', + '$static' => 'static', + '@static' => 'static', + ], + ], + 'phpdoc_scalar' => [ + 'types' => ['boolean', 'callback', 'double', 'integer', 'real', 'str'], + ], + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_summary' => true, + 'phpdoc_tag_casing' => [ + 'tags' => ['inheritDoc'], + ], + 'phpdoc_tag_type' => true, + 'phpdoc_to_comment' => [ + 'ignored_tags' => ['var'], + ], + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_types' => [ + 'groups' => ['alias', 'meta', 'simple'], + ], + 'phpdoc_var_annotation_correct_order' => true, + 'phpdoc_var_without_name' => true, + 'protected_to_private' => true, + 'return_assignment' => true, + 'self_static_accessor' => true, + 'semicolon_after_instruction' => true, + 'simple_to_complex_string_variable' => true, + 'simplified_if_return' => true, + 'simplified_null_return' => true, + 'single_line_comment_spacing' => true, + 'single_line_comment_style' => [ + 'comment_types' => ['asterisk', 'hash'], + ], + 'single_quote' => [ + 'strings_containing_single_quote_chars' => false, + ], + 'single_space_around_construct' => true, + 'space_after_semicolon' => [ + 'remove_in_empty_for_expressions' => true, + ], + 'standardize_increment' => true, + 'standardize_not_equals' => true, + 'switch_case_semicolon_to_colon' => true, + 'switch_continue_to_break' => true, + 'ternary_to_null_coalescing' => true, + 'trailing_comma_in_multiline' => true, + 'trim_array_spaces' => true, + 'types_spaces' => [ + 'space' => 'none', + 'space_multiple_catch' => null, + ], + 'unary_operator_spaces' => true, + 'whitespace_after_comma_in_array' => true, + 'yoda_style' => [ + 'always_move_variable' => false, + 'equal' => false, + 'identical' => false, + 'less_and_greater' => false, + ], + ]) + ->setFinder($finder) +; diff --git a/composer.json b/composer.json index 4f6b9e3..c835b14 100644 --- a/composer.json +++ b/composer.json @@ -32,9 +32,9 @@ "symfony/psr-http-message-bridge": "^2.0" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^3.17", "phpunit/phpunit": "^9.0", - "rector/rector": "^0.17.1", - "squizlabs/php_codesniffer": "^3.5" + "rector/rector": "^0.17.1" }, "autoload": { "psr-4": { @@ -48,7 +48,7 @@ }, "scripts": { "test": "phpunit", - "fix": "phpcbf src tests", + "fix": "php-cs-fixer fix -v", "refactor": "rector process" }, "extra": { diff --git a/phpcs.xml.dist b/phpcs.xml.dist deleted file mode 100644 index 111de29..0000000 --- a/phpcs.xml.dist +++ /dev/null @@ -1,18 +0,0 @@ - - - The coding standard of openapi-httpfoundation-testing package - - - - - - - - - - - - - src - tests - \ No newline at end of file diff --git a/src/Adapters/AdapterInterface.php b/src/Adapters/AdapterInterface.php index f20355b..58289bb 100644 --- a/src/Adapters/AdapterInterface.php +++ b/src/Adapters/AdapterInterface.php @@ -5,14 +5,17 @@ namespace Osteel\OpenApi\Testing\Adapters; use Psr\Http\Message\MessageInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; interface AdapterInterface { /** * Convert a HTTP message to a PSR-7 HTTP message. * - * @param object $message The HTTP message to convert. - * @return MessageInterface + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to convert */ - public function convert(object $message): MessageInterface; + public function convert(Request|Response|ResponseInterface|ServerRequestInterface $message): MessageInterface; } diff --git a/src/Adapters/HttpFoundationAdapter.php b/src/Adapters/HttpFoundationAdapter.php index 87d01f4..87b1c45 100644 --- a/src/Adapters/HttpFoundationAdapter.php +++ b/src/Adapters/HttpFoundationAdapter.php @@ -4,7 +4,6 @@ namespace Osteel\OpenApi\Testing\Adapters; -use InvalidArgumentException; use Nyholm\Psr7\Factory\Psr17Factory; use Psr\Http\Message\MessageInterface; use Psr\Http\Message\ResponseInterface; @@ -16,29 +15,23 @@ final class HttpFoundationAdapter implements AdapterInterface { /** - * {@inheritDoc} + * @inheritDoc * - * @param object $message The HTTP message to convert. - * @return MessageInterface - * @throws InvalidArgumentException + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to convert */ - public function convert(object $message): MessageInterface + public function convert(Request|Response|ResponseInterface|ServerRequestInterface $message): MessageInterface { if ($message instanceof ResponseInterface || $message instanceof ServerRequestInterface) { return $message; } - $psr17Factory = new Psr17Factory(); + $psr17Factory = new Psr17Factory(); $psrHttpFactory = new PsrHttpFactory($psr17Factory, $psr17Factory, $psr17Factory, $psr17Factory); if ($message instanceof Response) { return $psrHttpFactory->createResponse($message); } - if ($message instanceof Request) { - return $psrHttpFactory->createRequest($message); - } - - throw new InvalidArgumentException(sprintf('Unsupported %s object received', $message::class)); + return $psrHttpFactory->createRequest($message); } } diff --git a/src/Exceptions/ValidationException.php b/src/Exceptions/ValidationException.php index 7418b0a..4923cbe 100644 --- a/src/Exceptions/ValidationException.php +++ b/src/Exceptions/ValidationException.php @@ -10,15 +10,11 @@ class ValidationException extends Exception { - /** - * Build a new exception from a ValidationFailed exception. - * - * @return ValidationException - */ + /** Build a new exception from a ValidationFailed exception. */ public static function fromValidationFailed(ValidationFailed $exception): ValidationException { $previous = $exception; - $message = $exception->getMessage(); + $message = $exception->getMessage(); while ($exception = $exception->getPrevious()) { $message .= sprintf(': %s', $exception->getMessage()); diff --git a/src/Validator.php b/src/Validator.php index c410938..b6e83fc 100644 --- a/src/Validator.php +++ b/src/Validator.php @@ -4,7 +4,6 @@ namespace Osteel\OpenApi\Testing; -use InvalidArgumentException; use League\OpenAPIValidation\PSR7\Exception\ValidationFailed; use League\OpenAPIValidation\PSR7\OperationAddress; use League\OpenAPIValidation\PSR7\ResponseValidator; @@ -12,6 +11,9 @@ use Osteel\OpenApi\Testing\Adapters\AdapterInterface; use Osteel\OpenApi\Testing\Exceptions\ValidationException; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; final class Validator implements ValidatorInterface { @@ -23,18 +25,20 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritDoc + * + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * @param string $method the HTTP method * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @param string $method The HTTP method. - * @return bool - * @throws InvalidArgumentException * @throws ValidationException */ - public function validate(object $message, string $path, string $method): bool - { - $message = $this->adapter->convert($message); + public function validate( + Request|Response|ResponseInterface|ServerRequestInterface $message, + string $path, + string $method, + ): bool { + $message = $this->adapter->convert($message); $operation = $this->getOperationAddress($path, $method); $validator = $message instanceof ResponseInterface ? $this->responseValidator : $this->requestValidator; @@ -50,9 +54,8 @@ public function validate(object $message, string $path, string $method): bool /** * Build and return an OperationAddress object from the path and method. * - * @param string $path The OpenAPI path. - * @param string $method The HTTP method. - * @return OperationAddress + * @param string $path the OpenAPI path + * @param string $method the HTTP method */ private function getOperationAddress(string $path, string $method): OperationAddress { @@ -63,105 +66,105 @@ private function getOperationAddress(string $path, string $method): OperationAdd } /** - * {@inheritdoc} + * @inheritDoc + * + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool * @throws ValidationFailed */ - public function delete(object $message, string $path): bool + public function delete(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool { return $this->validate($message, $path, 'delete'); } /** - * {@inheritdoc} + * @inheritDoc + * + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool * @throws ValidationFailed */ - public function get(object $message, string $path): bool + public function get(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool { return $this->validate($message, $path, 'get'); } /** - * {@inheritdoc} + * @inheritDoc + * + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool * @throws ValidationFailed */ - public function head(object $message, string $path): bool + public function head(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool { return $this->validate($message, $path, 'head'); } /** - * {@inheritdoc} + * @inheritDoc + * + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool * @throws ValidationFailed */ - public function options(object $message, string $path): bool + public function options(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool { return $this->validate($message, $path, 'options'); } /** - * {@inheritdoc} + * @inheritDoc + * + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool * @throws ValidationFailed */ - public function patch(object $message, string $path): bool + public function patch(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool { return $this->validate($message, $path, 'patch'); } /** - * {@inheritdoc} + * @inheritDoc + * + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool * @throws ValidationFailed */ - public function post(object $message, string $path): bool + public function post(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool { return $this->validate($message, $path, 'post'); } /** - * {@inheritdoc} + * @inheritDoc + * + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool * @throws ValidationFailed */ - public function put(object $message, string $path): bool + public function put(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool { return $this->validate($message, $path, 'put'); } /** - * {@inheritdoc} + * @inheritDoc + * + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool * @throws ValidationFailed */ - public function trace(object $message, string $path): bool + public function trace(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool { return $this->validate($message, $path, 'trace'); } diff --git a/src/ValidatorBuilder.php b/src/ValidatorBuilder.php index 9759068..8f53109 100644 --- a/src/ValidatorBuilder.php +++ b/src/ValidatorBuilder.php @@ -21,94 +21,83 @@ public function __construct(private BaseValidatorBuilder $validatorBuilder) } /** - * {@inheritdoc} + * @inheritDoc * - * @param string $definition The OpenAPI definition. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition */ public static function fromYaml(string $definition): ValidatorBuilderInterface { $method = is_file($definition) ? 'fromYamlFile' : 'fromYaml'; - return static::fromMethod($method, $definition); + return self::fromMethod($method, $definition); } /** - * {@inheritdoc} + * @inheritDoc * - * @param string $definition The OpenAPI definition. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition */ public static function fromJson(string $definition): ValidatorBuilderInterface { $method = is_file($definition) ? 'fromJsonFile' : 'fromJson'; - return static::fromMethod($method, $definition); + return self::fromMethod($method, $definition); } /** - * {@inheritdoc} + * @inheritDoc * - * @param string $definition The OpenAPI definition's file. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition's file */ public static function fromYamlFile(string $definition): ValidatorBuilderInterface { - return static::fromMethod('fromYamlFile', $definition); + return self::fromMethod('fromYamlFile', $definition); } /** - * {@inheritdoc} + * @inheritDoc * - * @param string $definition The OpenAPI definition's file. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition's file */ public static function fromJsonFile(string $definition): ValidatorBuilderInterface { - return static::fromMethod('fromJsonFile', $definition); + return self::fromMethod('fromJsonFile', $definition); } /** - * {@inheritdoc} + * @inheritDoc * - * @param string $definition The OpenAPI definition as YAML text. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition as YAML text */ public static function fromYamlString(string $definition): ValidatorBuilderInterface { - return static::fromMethod('fromYaml', $definition); + return self::fromMethod('fromYaml', $definition); } /** - * {@inheritdoc} + * @inheritDoc * - * @param string $definition The OpenAPI definition as JSON text. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition as JSON text */ public static function fromJsonString(string $definition): ValidatorBuilderInterface { - return static::fromMethod('fromJson', $definition); + return self::fromMethod('fromJson', $definition); } /** * Create a Validator object based on an OpenAPI definition. * - * @param string $method The ValidatorBuilder object's method to use. - * @param string $definition The OpenAPI definition. - * @return ValidatorBuilderInterface + * @param string $method the ValidatorBuilder object's method to use + * @param string $definition the OpenAPI definition */ private static function fromMethod(string $method, string $definition): ValidatorBuilderInterface { - $builder = (new BaseValidatorBuilder())->$method($definition); + $builder = (new BaseValidatorBuilder())->{$method}($definition); return new ValidatorBuilder($builder); } - /** - * {@inheritdoc} - * - * @return ValidatorInterface - */ + /** @inheritDoc */ public function getValidator(): ValidatorInterface { return new Validator( @@ -122,8 +111,8 @@ public function getValidator(): ValidatorInterface * Change the adapter to use. The provided class must implement * \Osteel\OpenApi\Testing\Adapters\AdapterInterface. * - * @param string $class The adapter's class. - * @return ValidatorBuilder + * @param string $class the adapter's class + * * @throws InvalidArgumentException */ public function setAdapter(string $class): ValidatorBuilder diff --git a/src/ValidatorBuilderInterface.php b/src/ValidatorBuilderInterface.php index c078b44..04a2036 100644 --- a/src/ValidatorBuilderInterface.php +++ b/src/ValidatorBuilderInterface.php @@ -9,55 +9,45 @@ interface ValidatorBuilderInterface /** * Create a ValidatorBuilderInterface object based on a YAML OpenAPI definition. * - * @param string $definition The OpenAPI definition. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition */ public static function fromYaml(string $definition): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a JSON OpenAPI definition. * - * @param string $definition The OpenAPI definition. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition */ public static function fromJson(string $definition): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a YAML OpenAPI definition. * - * @param string $file The OpenAPI definition's file. - * @return ValidatorBuilderInterface + * @param string $file the OpenAPI definition's file */ public static function fromYamlFile(string $file): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a JSON OpenAPI definition. * - * @param string $file The OpenAPI definition's file. - * @return ValidatorBuilderInterface + * @param string $file the OpenAPI definition's file */ public static function fromJsonFile(string $file): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a YAML OpenAPI definition. * - * @param string $definition The OpenAPI definition as YAML text. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition as YAML text */ public static function fromYamlString(string $definition): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a JSON OpenAPI definition. * - * @param string $definition The OpenAPI definition as JSON text. - * @return ValidatorBuilderInterface + * @param string $definition the OpenAPI definition as JSON text */ public static function fromJsonString(string $definition): ValidatorBuilderInterface; - /** - * Return the validator. - * - * @return ValidatorInterface - */ + /** Return the validator. */ public function getValidator(): ValidatorInterface; } diff --git a/src/ValidatorInterface.php b/src/ValidatorInterface.php index 11b265b..98b7fda 100644 --- a/src/ValidatorInterface.php +++ b/src/ValidatorInterface.php @@ -6,97 +6,101 @@ use League\OpenAPIValidation\PSR7\Exception\ValidationFailed; use Osteel\OpenApi\Testing\Exceptions\ValidationException; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; interface ValidatorInterface { /** * Validate a HTTP message against the specified OpenAPI definition. * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @param string $method The HTTP method. - * @return bool + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * @param string $method the HTTP method + * * @throws ValidationException */ - public function validate(object $message, string $path, string $method): bool; + public function validate(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path, string $method): bool; /** * Validate a HTTP message for a DELETE operation on the provided OpenAPI definition path. * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * * @throws ValidationFailed */ - public function delete(object $message, string $path): bool; + public function delete(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool; /** * Validate a HTTP message for a GET operation on the provided OpenAPI definition path. * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * * @throws ValidationFailed */ - public function get(object $message, string $path): bool; + public function get(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool; /** * Validate a HTTP message for a HEAD operation on the provided OpenAPI definition path. * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * * @throws ValidationFailed */ - public function head(object $message, string $path): bool; + public function head(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool; /** * Validate a HTTP message for a OPTIONS operation on the provided OpenAPI definition path. * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * * @throws ValidationFailed */ - public function options(object $message, string $path): bool; + public function options(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool; /** * Validate a HTTP message for a PATCH operation on the provided OpenAPI definition path. * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * * @throws ValidationFailed */ - public function patch(object $message, string $path): bool; + public function patch(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool; /** * Validate a HTTP message for a POST operation on the provided OpenAPI definition path. * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * * @throws ValidationFailed */ - public function post(object $message, string $path): bool; + public function post(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool; /** * Validate a HTTP message for a PUT operation on the provided OpenAPI definition path. * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * * @throws ValidationFailed */ - public function put(object $message, string $path): bool; + public function put(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool; /** * Validate a HTTP message for a TRACE operation on the provided OpenAPI definition path. * - * @param object $message The HTTP message to validate. - * @param string $path The OpenAPI path. - * @return bool + * @param Request|Response|ResponseInterface|ServerRequestInterface $message the HTTP message to validate + * @param string $path the OpenAPI path + * * @throws ValidationFailed */ - public function trace(object $message, string $path): bool; + public function trace(Request|Response|ResponseInterface|ServerRequestInterface $message, string $path): bool; } diff --git a/tests/Adapters/HttpFoundationAdapterTest.php b/tests/Adapters/HttpFoundationAdapterTest.php index 1d46dd8..00e8c26 100644 --- a/tests/Adapters/HttpFoundationAdapterTest.php +++ b/tests/Adapters/HttpFoundationAdapterTest.php @@ -2,7 +2,6 @@ namespace Osteel\OpenApi\Testing\Tests\Adapters; -use InvalidArgumentException; use Osteel\OpenApi\Testing\Adapters\HttpFoundationAdapter; use Osteel\OpenApi\Testing\Tests\TestCase; use Psr\Http\Message\ResponseInterface; @@ -21,40 +20,32 @@ protected function setUp(): void $this->sut = new HttpFoundationAdapter(); } - public function testItDoesNotConvertTheMessageBecauseTheTypeIsNotSupported() - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Unsupported InvalidArgumentException object received'); - - $this->sut->convert(new InvalidArgumentException()); - } - - public function testItConvertsTheHttpFoundationRequest() + public function test_it_converts_the_http_foundation_request() { $result = $this->sut->convert(Request::create('/foo')); $this->assertInstanceOf(ServerRequestInterface::class, $result); } - public function testItLeavesTheRequestInterfaceUntouched() + public function test_it_leaves_the_request_interface_untouched() { $request = $this->createMock(ServerRequestInterface::class); - $result = $this->sut->convert($request); + $result = $this->sut->convert($request); $this->assertEquals($request, $result); } - public function testItConvertsAHttpFoundationResponse() + public function test_it_converts_a_http_foundation_response() { $result = $this->sut->convert(new Response()); $this->assertInstanceOf(ResponseInterface::class, $result); } - public function testItLeavesTheResponseInterfaceUntouched() + public function test_it_leaves_the_response_interface_untouched() { $response = $this->createMock(ResponseInterface::class); - $result = $this->sut->convert($response); + $result = $this->sut->convert($response); $this->assertEquals($response, $result); } diff --git a/tests/Exceptions/ValidationExceptionTest.php b/tests/Exceptions/ValidationExceptionTest.php index 418a26d..76da908 100644 --- a/tests/Exceptions/ValidationExceptionTest.php +++ b/tests/Exceptions/ValidationExceptionTest.php @@ -11,12 +11,12 @@ class ValidationExceptionTest extends TestCase { - public function testItCreatesAnExceptionFromAValidationFailedException() + public function test_it_creates_an_exception_from_a_validation_failed_exception() { $breadCrumb = new BreadCrumb('qux'); - $previous = (new SchemaMismatch('baz'))->withBreadCrumb($breadCrumb); - $exception = new ValidationFailed('foo', 0, new Exception('bar', 0, $previous)); - $sut = ValidationException::fromValidationFailed($exception); + $previous = (new SchemaMismatch('baz'))->withBreadCrumb($breadCrumb); + $exception = new ValidationFailed('foo', 0, new Exception('bar', 0, $previous)); + $sut = ValidationException::fromValidationFailed($exception); $this->assertEquals('foo: bar: baz Field: qux', $sut->getMessage()); $this->assertEquals($exception, $sut->getPrevious()); diff --git a/tests/TestCase.php b/tests/TestCase.php index de0a3da..2aaece9 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -13,24 +13,17 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase { private const BASE_URI = 'http://localhost:8000/api'; - protected const PATH = '/test'; - /** - * @var string - */ + protected const PATH = '/test'; + + /** @var string */ protected static $yamlDefinition = __DIR__ . '/stubs/example.yaml'; - /** - * @var string - */ + /** @var string */ protected static $jsonDefinition = __DIR__ . '/stubs/example.json'; - /** - * Return a HttpFoundation response with the provided content. - * - * @return Response - */ - protected function httpFoundationResponse(array $content = null): Response + /** Return a HttpFoundation response with the provided content. */ + protected function httpFoundationResponse(?array $content = null): Response { return new Response( $content ? json_encode($content, JSON_THROW_ON_ERROR) : '', @@ -39,12 +32,8 @@ protected function httpFoundationResponse(array $content = null): Response ); } - /** - * Return a PSR-7 response with the provided content. - * - * @return ResponseInterface - */ - protected function psr7Response(array $content = null): ResponseInterface + /** Return a PSR-7 response with the provided content. */ + protected function psr7Response(?array $content = null): ResponseInterface { $response = $this->createMock(ResponseInterface::class); @@ -60,12 +49,8 @@ protected function psr7Response(array $content = null): ResponseInterface return $response; } - /** - * Return a HttpFoundation request with the provided content. - * - * @return Request - */ - protected function httpFoundationRequest(string $uri, string $method, array $content = null): Request + /** Return a HttpFoundation request with the provided content. */ + protected function httpFoundationRequest(string $uri, string $method, ?array $content = null): Request { return Request::create( self::BASE_URI . $uri, @@ -78,20 +63,16 @@ protected function httpFoundationRequest(string $uri, string $method, array $con ); } - /** - * Return a PSR-7 request with the provided content. - * - * @return ServerRequestInterface - */ + /** Return a PSR-7 request with the provided content. */ protected function psr7Request( string $uri, string $method, - array $content = null + ?array $content = null ): ServerRequestInterface { $psr17Factory = new Psr17Factory(); - $uri = $psr17Factory->createUri(self::BASE_URI . $uri); - $stream = $psr17Factory->createStream(json_encode($content, JSON_THROW_ON_ERROR)); - $request = $psr17Factory->createServerRequest($method, $uri); + $uri = $psr17Factory->createUri(self::BASE_URI . $uri); + $stream = $psr17Factory->createStream(json_encode($content, JSON_THROW_ON_ERROR)); + $request = $psr17Factory->createServerRequest($method, $uri); if ($content) { $request = $request->withHeader('Content-Type', 'application/json'); diff --git a/tests/ValidatorBuilderTest.php b/tests/ValidatorBuilderTest.php index 45cc36d..2737acf 100644 --- a/tests/ValidatorBuilderTest.php +++ b/tests/ValidatorBuilderTest.php @@ -6,7 +6,6 @@ use InvalidArgumentException; use Osteel\OpenApi\Testing\Adapters\AdapterInterface; -use Osteel\OpenApi\Testing\Tests\TestCase; use Osteel\OpenApi\Testing\Validator; use Osteel\OpenApi\Testing\ValidatorBuilder; @@ -26,16 +25,14 @@ public function definitionProvider(): array ]; } - /** - * @dataProvider definitionProvider - */ - public function testItBuildsAValidator(string $method, string $definition) + /** @dataProvider definitionProvider */ + public function test_it_builds_a_validator(string $method, string $definition) { $result = ValidatorBuilder::$method($definition)->getValidator(); $this->assertInstanceOf(Validator::class, $result); - $request = $this->httpFoundationRequest(static::PATH, 'get', ['foo' => 'bar']); + $request = $this->httpFoundationRequest(static::PATH, 'get', ['foo' => 'bar']); $response = $this->httpFoundationResponse(['foo' => 'bar']); // Validate a request and a response to make sure the definition was correctly parsed. @@ -43,7 +40,7 @@ public function testItBuildsAValidator(string $method, string $definition) $this->assertTrue($result->get($response, static::PATH)); } - public function testItDoesNotSetTheAdapterBecauseItsTypeIsInvalid() + public function test_it_does_not_set_the_adapter_because_its_type_is_invalid() { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage(sprintf( @@ -55,7 +52,7 @@ public function testItDoesNotSetTheAdapterBecauseItsTypeIsInvalid() ValidatorBuilder::fromYaml(self::$yamlDefinition)->setAdapter(InvalidArgumentException::class); } - public function testItSetsTheAdapter() + public function test_it_sets_the_adapter() { ValidatorBuilder::fromYaml(self::$yamlDefinition) ->setAdapter($this->createMock(AdapterInterface::class)::class); diff --git a/tests/ValidatorTest.php b/tests/ValidatorTest.php index 9eaa7f7..6b8c164 100644 --- a/tests/ValidatorTest.php +++ b/tests/ValidatorTest.php @@ -5,7 +5,6 @@ namespace Osteel\OpenApi\Testing\Tests; use Osteel\OpenApi\Testing\Exceptions\ValidationException; -use Osteel\OpenApi\Testing\Tests\TestCase; use Osteel\OpenApi\Testing\Validator; use Osteel\OpenApi\Testing\ValidatorBuilder; @@ -24,7 +23,7 @@ protected function setUp(): void |-------------------------------------------------------------------------- | Requests |-------------------------------------------------------------------------- - */ + */ public function requestTypeProvider(): array { @@ -34,50 +33,42 @@ public function requestTypeProvider(): array ]; } - /** - * @dataProvider requestTypeProvider - */ - public function testItDoesNotValidateTheRequestWithoutPayload(string $method) + /** @dataProvider requestTypeProvider */ + public function test_it_does_not_validate_the_request_without_payload(string $method) { $this->expectException(ValidationException::class); $this->expectExceptionMessage('OpenAPI spec contains no such operation [/test,foo]'); - $request = $this->$method(static::PATH, 'delete'); + $request = $this->{$method}(static::PATH, 'delete'); $this->sut->validate($request, static::PATH, 'foo'); } - /** - * @dataProvider requestTypeProvider - */ - public function testItValidatesTheRequestWithoutPayload(string $method) + /** @dataProvider requestTypeProvider */ + public function test_it_validates_the_request_without_payload(string $method) { - $request = $this->$method(static::PATH, $method); - $result = $this->sut->validate($request, static::PATH, 'delete'); + $request = $this->{$method}(static::PATH, $method); + $result = $this->sut->validate($request, static::PATH, 'delete'); $this->assertTrue($result); } - /** - * @dataProvider requestTypeProvider - */ - public function testItDoesNotValidateTheRequestWithPayload(string $method) + /** @dataProvider requestTypeProvider */ + public function test_it_does_not_validate_the_request_with_payload(string $method) { $this->expectException(ValidationException::class); $this->expectExceptionMessage('Body does not match schema for content-type "application/json" for Request [post /test]: Keyword validation failed: Required property \'foo\' must be present in the object Field: foo'); - $request = $this->$method(static::PATH, 'post', ['baz' => 'bar']); + $request = $this->{$method}(static::PATH, 'post', ['baz' => 'bar']); $this->sut->validate($request, static::PATH, 'post'); } - /** - * @dataProvider requestTypeProvider - */ - public function testItValidatesTheRequestWithPayload(string $method) + /** @dataProvider requestTypeProvider */ + public function test_it_validates_the_request_with_payload(string $method) { - $request = $this->$method(static::PATH, 'post', ['foo' => 'bar']); - $result = $this->sut->validate($request, static::PATH, 'post'); + $request = $this->{$method}(static::PATH, 'post', ['foo' => 'bar']); + $result = $this->sut->validate($request, static::PATH, 'post'); $this->assertTrue($result); } @@ -93,13 +84,11 @@ public function bodylessRequestMethodProvider(): array ]; } - /** - * @dataProvider bodylessRequestMethodProvider - */ - public function testItValidatesTheRequestWithoutPayloadUsingMethodShortcuts(string $method) + /** @dataProvider bodylessRequestMethodProvider */ + public function test_it_validates_the_request_without_payload_using_method_shortcuts(string $method) { $request = $this->httpFoundationRequest(static::PATH, $method); - $result = $this->sut->validate($request, static::PATH, $method); + $result = $this->sut->validate($request, static::PATH, $method); $this->assertTrue($result); } @@ -113,13 +102,11 @@ public function requestMethodProvider(): array ]; } - /** - * @dataProvider requestMethodProvider - */ - public function testItValidatesTheRequestWithPaylodUsingShortcuts(string $method) + /** @dataProvider requestMethodProvider */ + public function test_it_validates_the_request_with_paylod_using_shortcuts(string $method) { $request = $this->httpFoundationRequest(static::PATH, $method, ['foo' => 'bar']); - $result = $this->sut->validate($request, static::PATH, $method); + $result = $this->sut->validate($request, static::PATH, $method); $this->assertTrue($result); } @@ -128,7 +115,7 @@ public function testItValidatesTheRequestWithPaylodUsingShortcuts(string $method |-------------------------------------------------------------------------- | Responses |-------------------------------------------------------------------------- - */ + */ public function responseTypeProvider(): array { @@ -138,26 +125,22 @@ public function responseTypeProvider(): array ]; } - /** - * @dataProvider responseTypeProvider - */ - public function testItDoesNotValidateTheResponse(string $method) + /** @dataProvider responseTypeProvider */ + public function test_it_does_not_validate_the_response(string $method) { $this->expectException(ValidationException::class); $this->expectExceptionMessage('Body does not match schema for content-type "application/json" for Response [get /test 200]: Keyword validation failed: Required property \'foo\' must be present in the object Field: foo'); - $response = $this->$method(['baz' => 'bar']); + $response = $this->{$method}(['baz' => 'bar']); $this->sut->validate($response, static::PATH, 'get'); } - /** - * @dataProvider responseTypeProvider - */ - public function testItValidatesTheResponse(string $method) + /** @dataProvider responseTypeProvider */ + public function test_it_validates_the_response(string $method) { - $response = $this->$method(['foo' => 'bar']); - $result = $this->sut->validate($response, static::PATH, 'get'); + $response = $this->{$method}(['foo' => 'bar']); + $result = $this->sut->validate($response, static::PATH, 'get'); $this->assertTrue($result); } @@ -175,12 +158,10 @@ public function responseMethodProvider(): array ]; } - /** - * @dataProvider responseMethodProvider - */ - public function testItValidatesTheResponseUsingMethodShortcuts(string $method) + /** @dataProvider responseMethodProvider */ + public function test_it_validates_the_response_using_method_shortcuts(string $method) { - $result = $this->sut->$method($this->httpFoundationResponse(), static::PATH); + $result = $this->sut->{$method}($this->httpFoundationResponse(), static::PATH); $this->assertTrue($result); } @@ -189,7 +170,7 @@ public function testItValidatesTheResponseUsingMethodShortcuts(string $method) |-------------------------------------------------------------------------- | Misc |-------------------------------------------------------------------------- - */ + */ public function pathProvider(): array { @@ -199,13 +180,11 @@ public function pathProvider(): array ]; } - /** - * @dataProvider pathProvider - */ - public function testItFixesThePath(string $path) + /** @dataProvider pathProvider */ + public function test_it_fixes_the_path(string $path) { $response = $this->httpFoundationResponse(['foo' => 'bar']); - $result = $this->sut->validate($response, $path, 'get'); + $result = $this->sut->validate($response, $path, 'get'); $this->assertTrue($result); }