From 8e8613cbe9ce375042500968fa5001c4f1d2331a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Guti=C3=A9rrez?= Date: Thu, 15 Feb 2018 22:34:00 +0100 Subject: [PATCH] http aware exceptions --- .coveralls.yml | 1 + .editorconfig | 27 ++++ .gitattributes | 14 ++ .gitignore | 8 ++ .php_cs | 130 ++++++++++++++++++ .scrutinizer.yml | 84 +++++++++++ .styleci.yml | 83 +++++++++++ .travis.yml | 48 +++++++ CONTRIBUTING.md | 21 +++ LICENSE | 27 ++++ README.md | 43 ++++++ composer.json | 111 +++++++++++++++ infection.json.dist | 11 ++ phpstan.neon | 2 + phpunit.xml.dist | 30 ++++ src/BadGatewayHttpException.php | 41 ++++++ src/BadRequestHttpException.php | 41 ++++++ src/ConflictHttpException.php | 41 ++++++ src/ForbiddenHttpException.php | 41 ++++++ src/GoneHttpException.php | 41 ++++++ src/HttpException.php | 94 +++++++++++++ src/InternalServerErrorHttpException.php | 41 ++++++ src/MethodNotAllowedHttpException.php | 72 ++++++++++ src/NotAcceptableHttpException.php | 41 ++++++ src/NotFoundHttpException.php | 41 ++++++ src/NotImplementedHttpException.php | 41 ++++++ src/TooManyRequestsHttpException.php | 41 ++++++ src/UnauthorizedHttpException.php | 41 ++++++ src/UnprocessableEntityHttpException.php | 41 ++++++ src/UnsupportedMediaTypeHttpException.php | 41 ++++++ .../BadGatewayHttpExceptionTest.php | 34 +++++ .../BadRequestHttpExceptionTest.php | 34 +++++ .../ConflictHttpExceptionTest.php | 34 +++++ .../ForbiddenHttpExceptionTest.php | 34 +++++ tests/HttpException/GoneHttpExceptionTest.php | 34 +++++ tests/HttpException/HttpExceptionTest.php | 38 +++++ .../InternalServerErrorHttpExceptionTest.php | 34 +++++ .../MethodNotAllowedHttpExceptionTest.php | 36 +++++ .../NotAcceptableHttpExceptionTest.php | 34 +++++ .../NotFoundHttpExceptionTest.php | 34 +++++ .../NotImplementedHttpExceptionTest.php | 34 +++++ .../HttpException/Stubs/HttpExceptionStub.php | 20 +++ .../TooManyRequestsHttpExceptionTest.php | 34 +++++ .../UnauthorizedHttpExceptionTest.php | 34 +++++ .../UnprocessableEntityHttpExceptionTest.php | 34 +++++ .../UnsupportedMediaTypeHttpExceptionTest.php | 34 +++++ tests/bootstrap.php | 14 ++ 47 files changed, 1889 insertions(+) create mode 100644 .coveralls.yml create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .php_cs create mode 100644 .scrutinizer.yml create mode 100644 .styleci.yml create mode 100644 .travis.yml create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 composer.json create mode 100644 infection.json.dist create mode 100644 phpstan.neon create mode 100644 phpunit.xml.dist create mode 100644 src/BadGatewayHttpException.php create mode 100644 src/BadRequestHttpException.php create mode 100644 src/ConflictHttpException.php create mode 100644 src/ForbiddenHttpException.php create mode 100644 src/GoneHttpException.php create mode 100644 src/HttpException.php create mode 100644 src/InternalServerErrorHttpException.php create mode 100644 src/MethodNotAllowedHttpException.php create mode 100644 src/NotAcceptableHttpException.php create mode 100644 src/NotFoundHttpException.php create mode 100644 src/NotImplementedHttpException.php create mode 100644 src/TooManyRequestsHttpException.php create mode 100644 src/UnauthorizedHttpException.php create mode 100644 src/UnprocessableEntityHttpException.php create mode 100644 src/UnsupportedMediaTypeHttpException.php create mode 100644 tests/HttpException/BadGatewayHttpExceptionTest.php create mode 100644 tests/HttpException/BadRequestHttpExceptionTest.php create mode 100644 tests/HttpException/ConflictHttpExceptionTest.php create mode 100644 tests/HttpException/ForbiddenHttpExceptionTest.php create mode 100644 tests/HttpException/GoneHttpExceptionTest.php create mode 100644 tests/HttpException/HttpExceptionTest.php create mode 100644 tests/HttpException/InternalServerErrorHttpExceptionTest.php create mode 100644 tests/HttpException/MethodNotAllowedHttpExceptionTest.php create mode 100644 tests/HttpException/NotAcceptableHttpExceptionTest.php create mode 100644 tests/HttpException/NotFoundHttpExceptionTest.php create mode 100644 tests/HttpException/NotImplementedHttpExceptionTest.php create mode 100644 tests/HttpException/Stubs/HttpExceptionStub.php create mode 100644 tests/HttpException/TooManyRequestsHttpExceptionTest.php create mode 100644 tests/HttpException/UnauthorizedHttpExceptionTest.php create mode 100644 tests/HttpException/UnprocessableEntityHttpExceptionTest.php create mode 100644 tests/HttpException/UnsupportedMediaTypeHttpExceptionTest.php create mode 100644 tests/bootstrap.php diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 0000000..9160059 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1 @@ +service_name: travis-ci diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c21d79c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,27 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.js] +indent_size = 2 + +[*.html] +indent_size = 2 + +[*.json] +indent_size = 2 + +[*.neon] +indent_size = 2 + +[*.yml] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..256c226 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +* text=auto + +.gitattributes export-ignore +.gitignore export-ignore +.editorconfig export-ignore +.php_cs export-ignore +.travis.yml export-ignore +.coveralls.yml export-ignore +.scrutinizer.yml export-ignore +.styleci.yml export-ignore +infection.json.dist export-ignore +README.md export-ignore +CONTRIBUTING.md export-ignore +phpunit.xml.dist export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c1dc421 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +!.gitignore +composer.lock +cghooks.lock +vendor/ +.yo-rc.json +*.cache +infection-log.* +build/ diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..5652658 --- /dev/null +++ b/.php_cs @@ -0,0 +1,130 @@ + + */ + +use PhpCsFixer\Config; +use PhpCsFixer\Finder; + +$header = <<<'HEADER' +http-exception (https://github.com/juliangut/http-exception). +HTTP aware exceptions. + +@license BSD-3-Clause +@link https://github.com/juliangut/http-exception +@author Julián Gutiérrez +HEADER; + +$finder = Finder::create() + ->exclude(['vendor', 'build']) + ->in(__DIR__); + +return Config::create() + ->setUsingCache(true) + ->setRiskyAllowed(true) + ->setRules([ + '@PSR2' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'binary_operator_spaces' => [ + 'align_double_arrow' => false, + 'align_equals' => false, + ], + 'blank_line_after_opening_tag' => true, + 'cast_spaces' => true, + 'class_attributes_separation' => true, + 'combine_consecutive_unsets' => true, + 'concat_space' => [ + 'spacing' => 'one' + ], + 'declare_equal_normalize' => true, + 'declare_strict_types' => true, + 'function_typehint_space' => true, + 'hash_to_slash_comment' => true, + 'header_comment' => [ + 'header' => $header, + 'location' => 'after_open', + ], + 'heredoc_to_nowdoc' => true, + 'include' => true, + 'linebreak_after_opening_tag' => true, + 'lowercase_cast' => true, + 'modernize_types_casting' => true, + 'native_function_casing' => true, + 'native_function_invocation' => true, + 'new_with_braces' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => true, + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_multiline_whitespace_before_semicolons' => true, + 'no_php4_constructor' => true, + 'no_short_bool_cast' => true, + 'no_short_echo_tag' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_around_offset' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unreachable_default_argument_value' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'normalize_index_brace' => true, + 'ordered_imports' => true, + 'php_unit_construct' => true, + 'php_unit_dedicate_assert' => true, + 'phpdoc_add_missing_param_annotation' => true, + 'phpdoc_align' => true, + 'phpdoc_annotation_without_dot' => true, + 'phpdoc_indent' => true, + 'phpdoc_inline_tag' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_alias_tag' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_order' => true, + 'phpdoc_return_self_reference' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_summary' => true, + 'phpdoc_to_comment' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'phpdoc_var_without_name' => true, + 'pow_to_exponentiation' => true, + 'random_api_migration' => true, + 'return_type_declaration' => [ + 'space_before' => 'none', + ], + 'self_accessor' => true, + 'short_scalar_cast' => true, + 'single_blank_line_before_namespace' => true, + 'single_quote' => true, + 'space_after_semicolon' => true, + 'standardize_not_equals' => true, + 'trailing_comma_in_multiline_array' => true, + 'ternary_operator_spaces' => true, + 'ternary_to_null_coalescing' => true, + 'trim_array_spaces' => true, + 'unary_operator_spaces' => true, + 'whitespace_after_comma_in_array' => true + ]) + ->setFinder($finder); diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 0000000..9a9bb96 --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,84 @@ +# language: php + +filter: + paths: [src/*] + excluded_paths: [tests/*, vendor/*] + +before_commands: + - 'composer self-update' + - 'composer update --prefer-stable --prefer-source --no-interaction --no-scripts --no-progress --no-suggest' + +coding_style: + php: + upper_lower_casing: + keywords: + general: lower + constants: + true_false_null: lower + spaces: + around_operators: + concatenation: true + negation: false + other: + after_type_cast: true + +tools: + php_code_coverage: false + php_code_sniffer: + enabled: true + config: + standard: 'PSR2' + filter: + paths: [src/*, tests/*] + php_mess_detector: + enabled: true + config: + ruleset: 'unusedcode,naming,design,controversial,codesize' + + php_cpd: true + php_loc: true + php_pdepend: true + php_analyzer: true + sensiolabs_security_checker: true + +checks: + php: + code_rating: true + duplication: true + uppercase_constants: true + properties_in_camelcaps: true + prefer_while_loop_over_for_loop: true + parameters_in_camelcaps: true + optional_parameters_at_the_end: true + no_short_variable_names: + minimum: '3' + no_short_method_names: + minimum: '3' + no_goto: true + newline_at_end_of_file: true + more_specific_types_in_doc_comments: true + line_length: + max_length: '120' + function_in_camel_caps: true + encourage_single_quotes: true + encourage_postdec_operator: true + classes_in_camel_caps: true + avoid_perl_style_comments: true + avoid_multiple_statements_on_same_line: true + parameter_doc_comments: true + use_self_instead_of_fqcn: true + simplify_boolean_return: true + avoid_fixme_comments: true + return_doc_comments: true + remove_extra_empty_lines: true + remove_php_closing_tag: true + remove_trailing_whitespace: true + fix_use_statements: + remove_unused: true + preserve_multiple: false + preserve_blanklines: true + order_alphabetically: true + fix_php_opening_tag: true + fix_linefeed: true + fix_line_ending: true + fix_identation_4spaces: true diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..2449f1c --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,83 @@ +preset: psr2 + +finder: + exclude: + - vendor + - build + +enabled: + - alpha_ordered_imports + - binary_operator_spaces + - blank_line_after_opening_tag + - blank_line_before_return + - cast_spaces + - concat_with_spaces + - declare_equal_normalize + - declare_strict_types + - function_typehint_space + - hash_to_slash_comment + - heredoc_to_nowdoc + - include + - linebreak_after_opening_tag + - lowercase_cast + - method_separation + - modernize_types_casting + - native_function_casing + - new_with_braces + - no_alias_functions + - no_blank_lines_after_class_opening + - no_blank_lines_after_phpdoc + - no_empty_comment + - no_empty_phpdoc + - no_empty_statement + - no_leading_import_slash + - no_leading_namespace_whitespace + - no_multiline_whitespace_around_double_arrow + - no_multiline_whitespace_before_semicolons + - no_php4_constructor + - no_short_bool_cast + - no_singleline_whitespace_before_semicolons + - no_spaces_inside_offset + - no_spaces_outside_offset + - no_trailing_comma_in_singleline_array + - no_unneeded_control_parentheses + - no_unreachable_default_argument_value + - no_unused_imports + - no_useless_else + - no_useless_return + - no_whitespace_before_comma_in_array + - no_whitespace_in_blank_line + - normalize_index_brace + - php_unit_construct + - php_unit_dedicate_assert + - phpdoc_align + - phpdoc_annotation_without_dot + - phpdoc_indent + - phpdoc_inline_tag + - phpdoc_no_access + - phpdoc_no_empty_return + - phpdoc_no_package + - phpdoc_order + - phpdoc_property + - phpdoc_scalar + - phpdoc_separation + - phpdoc_single_line_var_spacing + - phpdoc_summary + - phpdoc_to_comment + - phpdoc_trim + - phpdoc_types + - phpdoc_var_without_name + - print_to_echo + - return_type_declaration + - self_accessor + - short_array_syntax + - short_scalar_cast + - single_blank_line_before_namespace + - single_quote + - space_after_semicolon + - standardize_not_equals + - ternary_operator_spaces + - trailing_comma_in_multiline_array + - trim_array_spaces + - unary_operator_spaces + - whitespace_after_comma_in_array diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..612a87c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,48 @@ +language: php + +sudo: false + +git: + depth: 3 + +cache: + directories: + - $HOME/.composer/cache/files + +env: + - COMPOSER_FLAGS="--prefer-stable --prefer-dist" + +php: + - 7.1 + - 7.2 + - nightly + +matrix: + fast_finish: true + include: + - php: 7 + env: + - COMPOSER_FLAGS="--prefer-lowest --prefer-stable --prefer-dist" + - php: 7 + env: + - TEST_VERSION=true + - COMPOSER_FLAGS="--prefer-stable --prefer-dist" + allow_failures: + - php: nightly + +before_install: + - if [[ -z $TEST_VERSION && -f "/home/travis/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini" ]]; then phpenv config-rm xdebug.ini; fi + - composer global require hirak/prestissimo + - composer self-update --stable --no-progress + +install: + - travis_retry composer update $COMPOSER_FLAGS --no-interaction --no-scripts --no-progress + - if [[ $TEST_VERSION ]]; then travis_retry composer require php-coveralls/php-coveralls $COMPOSER_FLAGS --no-interaction --no-scripts --no-progress ; fi + +script: + - if [[ $TEST_VERSION ]]; then composer qa && composer phpunit-clover ; fi + + - if [[ -z $TEST_VERSION ]]; then composer phpunit ; fi + +after_script: + - if [[ $TEST_VERSION ]]; then travis_retry php vendor/bin/php-coveralls --verbose ; fi diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8cd4941 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,21 @@ +# Contributing + +First of all **thank you** for contributing! + +Make your contributions through Pull Requests + +Find here a few rules to follow in order to keep the code clean and easy to review and merge: + +- Follow **[PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** coding standard +- **Unit test everything** and run the test suite +- Try not to bring **code coverage** down +- Keep documentation **updated** +- Just **one pull request per feature** at a time +- Check that **[Travis CI](https://travis-ci.org/juliangut/http-exception)** build passed + +Composer scripts are provided to help you keep code quality and run the test suite: + +- `composer qa` will run quality assurance tools: PHP linting, [Editorconfig-checker](https://github.com/editorconfig-checker/editorconfig-checker.php) for editorconfig adherence, [PHP Code Sniffer](https://github.com/squizlabs/PHP_CodeSniffer) for coding style guidelines, [PHPMD](https://github.com/phpmd/phpmd) for code smells, [PHPMND](https://github.com/povils/phpmnd) for magic code detection, [PHPCPD](https://github.com/sebastianbergmann/phpcpd) for copy/paste detection, [PHPStan](https://github.com/phpstan/phpstan) for static code analysis +- `composer test` will run unit tests with [PHPUnit](https://github.com/sebastianbergmann/phpunit) for unit tests +- `composer fix` will run [Editorconfig-checker](https://github.com/editorconfig-checker/editorconfig-checker.php) and [PHP-CS-Fixer](https://github.com/FriendsOfPhp/PHP-CS-Fixer) for fixing style +- `composer security` will run [Composer](https://getcomposer.org) (>=1.1.0) for outdated dependencies diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d613674 --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2018, Julián Gutiérrez (juliangut@gmail.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f0729a6 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +[![PHP version](https://img.shields.io/badge/PHP-%3E%3D7-8892BF.svg?style=flat-square)](http://php.net) +[![Latest Version](https://img.shields.io/packagist/v/juliangut/http-exception.svg?style=flat-square)](https://packagist.org/packages/juliangut/http-exception) +[![License](https://img.shields.io/github/license/juliangut/http-exception.svg?style=flat-square)](https://github.com/juliangut/http-exception/blob/master/LICENSE) + +[![Build Status](https://img.shields.io/travis/juliangut/http-exception.svg?style=flat-square)](https://travis-ci.org/juliangut/http-exception) +[![Style Check](https://styleci.io/repos/121684874/shield)](https://styleci.io/repos/121684874) +[![Code Quality](https://img.shields.io/scrutinizer/g/juliangut/http-exception.svg?style=flat-square)](https://scrutinizer-ci.com/g/juliangut/http-exception) +[![Code Coverage](https://img.shields.io/coveralls/juliangut/http-exception.svg?style=flat-square)](https://coveralls.io/github/juliangut/http-exception) + +[![Total Downloads](https://img.shields.io/packagist/dt/juliangut/http-exception.svg?style=flat-square)](https://packagist.org/packages/juliangut/http-exception/stats) +[![Monthly Downloads](https://img.shields.io/packagist/dm/juliangut/http-exception.svg?style=flat-square)](https://packagist.org/packages/juliangut/http-exception/stats) + +# http-exception + +HTTP aware exceptions + +## Installation + +### Composer + +``` +composer require juliangut/http-exception +``` + +## Usage + +Require composer autoload file + +```php +require './vendor/autoload.php'; +``` + +> Usage instructions go here + +## Contributing + +Found a bug or have a feature request? [Please open a new issue](https://github.com/juliangut/http-exception/issues). Have a look at existing issues before. + +See file [CONTRIBUTING.md](https://github.com/juliangut/http-exception/blob/master/CONTRIBUTING.md) + +## License + +See file [LICENSE](https://github.com/juliangut/http-exception/blob/master/LICENSE) included with the source code for a copy of the license terms. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..3b245b7 --- /dev/null +++ b/composer.json @@ -0,0 +1,111 @@ +{ + "name": "juliangut/http-exception", + "description": "HTTP aware exceptions", + "keywords": [ + "HTTP", + "exception" + ], + "homepage": "https://github.com/juliangut/http-exception", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Julián Gutiérrez", + "email": "juliangut@gmail.com", + "homepage": "http://juliangut.com", + "role": "Developer" + } + ], + "support": { + "source": "https://github.com/juliangut/http-exception", + "issues": "https://github.com/juliangut/http-exception/issues" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "require": { + "php": "^7.0", + "fig/http-message-util": "^1.1", + "pascaldevink/shortuuid": "^1.0" + }, + "require-dev": { + "brainmaestro/composer-git-hooks": "^2.1", + "editorconfig-checker/editorconfig-checker": "^7.0", + "friendsofphp/php-cs-fixer": "^2.0", + "infection/infection": "^0.7.0", + "phpmd/phpmd": "^2.0", + "phpmetrics/phpmetrics": "^2.0", + "phpstan/phpstan": "^0.9", + "phpstan/phpstan-strict-rules": "0.9", + "phpunit/phpunit": "^5.7|^6.0", + "povils/phpmnd": "^1.1", + "roave/security-advisories": "dev-master", + "sebastian/phpcpd": "^2.0", + "squizlabs/php_codesniffer": "^2.0" + }, + "suggest": { + }, + "autoload": { + "psr-4": { + "Jgut\\HttpException\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Jgut\\HttpException\\Tests\\": "tests/HttpException/" + } + }, + "bin": [ + ], + "config": { + "preferred-install": "dist", + "sort-packages": true + }, + "scripts": { + "cghooks": "cghooks", + "post-install-cmd": "cghooks add --ignore-lock", + "post-update-cmd": "cghooks update", + "php-lint": "php -l src && php -l tests", + "editorconfig-lint": "editorconfig-checker src/* tests/*", + "editorconfig-fix": "editorconfig-checker --auto-fix src/* tests/*", + "phpcs": "phpcs --standard=PSR2 src tests", + "phpcs-lint": "php-cs-fixer fix --dry-run --verbose", + "phpcs-fix": "php-cs-fixer fix --verbose", + "phpcpd": "phpcpd src", + "phpmd": "phpmd src text unusedcode,naming,design,controversial,codesize", + "phpmnd": "phpmnd ./ --exclude=tests", + "phpmetrics-report": "phpmetrics --report-html=build/metrics --offline .", + "phpstan": "phpstan analyse --level max -c phpstan.neon src", + "phpunit": "phpunit", + "phpunit-coverage": "phpunit --coverage-html build/coverage", + "phpunit-clover": "phpunit --coverage-clover build/logs/clover.xml", + "infection": "infection", + "qa": [ + "@php-lint", + "@editorconfig-lint", + "@phpcs", + "@phpcs-lint", + "@phpcpd", + "@phpmd", + "@phpmnd", + "@phpstan" + ], + "reports": [ + "@phpmetrics-report", + "@phpunit-coverage" + ], + "fix": [ + "@editorconfig-fix", + "@phpcs-fix" + ], + "security": "composer outdated", + "test": [ + "@php-lint", + "@phpunit", + "@infection" + ] + }, + "extra": { + "hooks": { + "pre-commit": "composer qa && composer phpunit" + } + } +} diff --git a/infection.json.dist b/infection.json.dist new file mode 100644 index 0000000..e493b70 --- /dev/null +++ b/infection.json.dist @@ -0,0 +1,11 @@ +{ + "source": { + "directories": [ + "src" + ] + }, + "timeout": 10, + "logs": { + "text": "infection-log.txt", + } +} diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..236125c --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,2 @@ +includes: + - vendor/phpstan/phpstan-strict-rules/rules.neon diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..cb64673 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + tests/HttpException/ + + + + + + src/ + + + + + + + diff --git a/src/BadGatewayHttpException.php b/src/BadGatewayHttpException.php new file mode 100644 index 0000000..6dd4f9c --- /dev/null +++ b/src/BadGatewayHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 502 Bad Gateway exception class. + */ +class BadGatewayHttpException extends HttpException +{ + /** + * Bad Gateway Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Bad Gateway', + string $description = '', + int $code = StatusCodeInterface::STATUS_BAD_GATEWAY, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_BAD_GATEWAY; + } +} diff --git a/src/BadRequestHttpException.php b/src/BadRequestHttpException.php new file mode 100644 index 0000000..6095c70 --- /dev/null +++ b/src/BadRequestHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 400 Bad Request exception class. + */ +class BadRequestHttpException extends HttpException +{ + /** + * Bad Request Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Bad Request', + string $description = '', + int $code = StatusCodeInterface::STATUS_BAD_REQUEST, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_BAD_REQUEST; + } +} diff --git a/src/ConflictHttpException.php b/src/ConflictHttpException.php new file mode 100644 index 0000000..78a8fb4 --- /dev/null +++ b/src/ConflictHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 409 Conflict exception class. + */ +class ConflictHttpException extends HttpException +{ + /** + * Conflict Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Conflict', + string $description = '', + int $code = StatusCodeInterface::STATUS_CONFLICT, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_CONFLICT; + } +} diff --git a/src/ForbiddenHttpException.php b/src/ForbiddenHttpException.php new file mode 100644 index 0000000..7cd357c --- /dev/null +++ b/src/ForbiddenHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 403 Forbidden exception class. + */ +class ForbiddenHttpException extends HttpException +{ + /** + * Forbidden Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Forbidden', + string $description = '', + int $code = StatusCodeInterface::STATUS_FORBIDDEN, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_FORBIDDEN; + } +} diff --git a/src/GoneHttpException.php b/src/GoneHttpException.php new file mode 100644 index 0000000..5ce6326 --- /dev/null +++ b/src/GoneHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 410 Gone exception class. + */ +class GoneHttpException extends HttpException +{ + /** + * Gone Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Gone', + string $description = '', + int $code = StatusCodeInterface::STATUS_GONE, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_GONE; + } +} diff --git a/src/HttpException.php b/src/HttpException.php new file mode 100644 index 0000000..b494c4f --- /dev/null +++ b/src/HttpException.php @@ -0,0 +1,94 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; +use PascalDeVink\ShortUuid\ShortUuid; + +/** + * HTTP exception class. + */ +abstract class HttpException extends \DomainException +{ + /** + * Unique error identifier. + * + * @var string + */ + protected $identifier; + + /** + * Exception description. + * + * @var string + */ + protected $description; + + /** + * HTTP status code. + * + * @var int + */ + protected $statusCode = StatusCodeInterface::STATUS_BAD_REQUEST; + + /** + * HTTP Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message, + string $description, + int $code, + \Throwable $previous = null + ) { + parent::__construct(\trim($message), $code, $previous); + + $this->identifier = ShortUuid::uuid4(); + $this->description = \trim($description); + } + + /** + * Get exception unique identifier. + * + * @return string + */ + public function getIdentifier(): string + { + return $this->identifier; + } + + /** + * Get exception description. + * + * @return string + */ + public function getDescription(): string + { + return $this->description; + } + + /** + * Get HTTP status code. + * + * @return int + */ + public function getStatusCode(): int + { + return $this->statusCode; + } +} diff --git a/src/InternalServerErrorHttpException.php b/src/InternalServerErrorHttpException.php new file mode 100644 index 0000000..7339c96 --- /dev/null +++ b/src/InternalServerErrorHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 500 Internal Server Error Entity exception class. + */ +class InternalServerErrorHttpException extends HttpException +{ + /** + * InternalServerError Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Internal Server Error', + string $description = '', + int $code = StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR; + } +} diff --git a/src/MethodNotAllowedHttpException.php b/src/MethodNotAllowedHttpException.php new file mode 100644 index 0000000..5a7ace3 --- /dev/null +++ b/src/MethodNotAllowedHttpException.php @@ -0,0 +1,72 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 405 Method Not Allowed exception class. + */ +class MethodNotAllowedHttpException extends HttpException +{ + /** + * Valid HTTP methods. + * + * @var array + */ + protected $validMethods = []; + + /** + * Method Not Allowed Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Method Not Allowed', + string $description = '', + int $code = StatusCodeInterface::STATUS_METHOD_NOT_ALLOWED, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_METHOD_NOT_ALLOWED; + } + + /** + * Set valid HTTP methods. + * + * @param array $validMethods + * + * @return static + */ + public function setValidMethods(array $validMethods): self + { + $this->validMethods = $validMethods; + + return $this; + } + + /** + * Get valid HTTP methods. + * + * @return array + */ + public function getValidMethods(): array + { + return $this->validMethods; + } +} diff --git a/src/NotAcceptableHttpException.php b/src/NotAcceptableHttpException.php new file mode 100644 index 0000000..199d985 --- /dev/null +++ b/src/NotAcceptableHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 406 Not Acceptable exception class. + */ +class NotAcceptableHttpException extends HttpException +{ + /** + * Not Acceptable Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Not Acceptable', + string $description = '', + int $code = StatusCodeInterface::STATUS_NOT_ACCEPTABLE, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_NOT_ACCEPTABLE; + } +} diff --git a/src/NotFoundHttpException.php b/src/NotFoundHttpException.php new file mode 100644 index 0000000..f48097c --- /dev/null +++ b/src/NotFoundHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 404 Not Found exception class. + */ +class NotFoundHttpException extends HttpException +{ + /** + * Not Found Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Not Found', + string $description = '', + int $code = StatusCodeInterface::STATUS_NOT_FOUND, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_NOT_FOUND; + } +} diff --git a/src/NotImplementedHttpException.php b/src/NotImplementedHttpException.php new file mode 100644 index 0000000..8274112 --- /dev/null +++ b/src/NotImplementedHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 501 Not Implemented exception class. + */ +class NotImplementedHttpException extends HttpException +{ + /** + * Not Implemented Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Not Implemented', + string $description = '', + int $code = StatusCodeInterface::STATUS_NOT_IMPLEMENTED, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_NOT_IMPLEMENTED; + } +} diff --git a/src/TooManyRequestsHttpException.php b/src/TooManyRequestsHttpException.php new file mode 100644 index 0000000..bcd7411 --- /dev/null +++ b/src/TooManyRequestsHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 429 Too Many Requests Entity exception class. + */ +class TooManyRequestsHttpException extends HttpException +{ + /** + * Too Many Requests Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Too Many Requests', + string $description = '', + int $code = StatusCodeInterface::STATUS_TOO_MANY_REQUESTS, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_TOO_MANY_REQUESTS; + } +} diff --git a/src/UnauthorizedHttpException.php b/src/UnauthorizedHttpException.php new file mode 100644 index 0000000..e6b705c --- /dev/null +++ b/src/UnauthorizedHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 401 Unauthorized exception class. + */ +class UnauthorizedHttpException extends HttpException +{ + /** + * Unauthorized Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Unauthorized', + string $description = '', + int $code = StatusCodeInterface::STATUS_UNAUTHORIZED, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_UNAUTHORIZED; + } +} diff --git a/src/UnprocessableEntityHttpException.php b/src/UnprocessableEntityHttpException.php new file mode 100644 index 0000000..b6008ba --- /dev/null +++ b/src/UnprocessableEntityHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 422 Unprocessable Entity exception class. + */ +class UnprocessableEntityHttpException extends HttpException +{ + /** + * Unprocessable Entity Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Unprocessable Entity', + string $description = '', + int $code = StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY; + } +} diff --git a/src/UnsupportedMediaTypeHttpException.php b/src/UnsupportedMediaTypeHttpException.php new file mode 100644 index 0000000..2186e93 --- /dev/null +++ b/src/UnsupportedMediaTypeHttpException.php @@ -0,0 +1,41 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException; + +use Fig\Http\Message\StatusCodeInterface; + +/** + * HTTP 415 Unsupported Media Type exception class. + */ +class UnsupportedMediaTypeHttpException extends HttpException +{ + /** + * Unsupported Media Type Exception constructor. + * + * @param string $message + * @param string $description + * @param int $code + * @param \Throwable|null $previous + */ + public function __construct( + string $message = 'Unsupported Media Type', + string $description = '', + int $code = StatusCodeInterface::STATUS_UNSUPPORTED_MEDIA_TYPE, + \Throwable $previous = null + ) { + parent::__construct($message, $description, $code, $previous); + + $this->statusCode = StatusCodeInterface::STATUS_UNSUPPORTED_MEDIA_TYPE; + } +} diff --git a/tests/HttpException/BadGatewayHttpExceptionTest.php b/tests/HttpException/BadGatewayHttpExceptionTest.php new file mode 100644 index 0000000..2623cc6 --- /dev/null +++ b/tests/HttpException/BadGatewayHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\BadGatewayHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 502 Bad Gateway Exception tests. + */ +class BadGatewayHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new BadGatewayHttpException(); + + self::assertEquals('Bad Gateway', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_BAD_GATEWAY, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_BAD_GATEWAY, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/BadRequestHttpExceptionTest.php b/tests/HttpException/BadRequestHttpExceptionTest.php new file mode 100644 index 0000000..2fa811b --- /dev/null +++ b/tests/HttpException/BadRequestHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\BadRequestHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 400 Bad Request Exception tests. + */ +class BadRequestHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new BadRequestHttpException(); + + self::assertEquals('Bad Request', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_BAD_REQUEST, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_BAD_REQUEST, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/ConflictHttpExceptionTest.php b/tests/HttpException/ConflictHttpExceptionTest.php new file mode 100644 index 0000000..64c97f1 --- /dev/null +++ b/tests/HttpException/ConflictHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\ConflictHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 409 Conflict Exception tests. + */ +class ConflictHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new ConflictHttpException(); + + self::assertEquals('Conflict', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_CONFLICT, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_CONFLICT, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/ForbiddenHttpExceptionTest.php b/tests/HttpException/ForbiddenHttpExceptionTest.php new file mode 100644 index 0000000..98290dd --- /dev/null +++ b/tests/HttpException/ForbiddenHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\ForbiddenHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 403 Forbidden Exception tests. + */ +class ForbiddenHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new ForbiddenHttpException(); + + self::assertEquals('Forbidden', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_FORBIDDEN, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_FORBIDDEN, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/GoneHttpExceptionTest.php b/tests/HttpException/GoneHttpExceptionTest.php new file mode 100644 index 0000000..125881b --- /dev/null +++ b/tests/HttpException/GoneHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\GoneHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 410 Gone Exception tests. + */ +class GoneHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new GoneHttpException(); + + self::assertEquals('Gone', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_GONE, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_GONE, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/HttpExceptionTest.php b/tests/HttpException/HttpExceptionTest.php new file mode 100644 index 0000000..12f8973 --- /dev/null +++ b/tests/HttpException/HttpExceptionTest.php @@ -0,0 +1,38 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\Tests\Stubs\HttpExceptionStub; +use PHPUnit\Framework\TestCase; + +/** + * HTTP Exception tests. + */ +class HttpExceptionTest extends TestCase +{ + public function testException() + { + $previous = new \Exception('previous'); + + $exception = new HttpExceptionStub('message', 'description', 1000, $previous); + + self::assertNotNull($exception->getIdentifier()); + self::assertSame('message', $exception->getMessage()); + self::assertSame('description', $exception->getDescription()); + self::assertSame(1000, $exception->getCode()); + self::assertSame(StatusCodeInterface::STATUS_BAD_REQUEST, $exception->getStatusCode()); + self::assertSame($previous, $exception->getPrevious()); + } +} diff --git a/tests/HttpException/InternalServerErrorHttpExceptionTest.php b/tests/HttpException/InternalServerErrorHttpExceptionTest.php new file mode 100644 index 0000000..56a98b4 --- /dev/null +++ b/tests/HttpException/InternalServerErrorHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\InternalServerErrorHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 500 Internal Server Error Exception tests. + */ +class InternalServerErrorHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new InternalServerErrorHttpException(); + + self::assertEquals('Internal Server Error', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/MethodNotAllowedHttpExceptionTest.php b/tests/HttpException/MethodNotAllowedHttpExceptionTest.php new file mode 100644 index 0000000..982b792 --- /dev/null +++ b/tests/HttpException/MethodNotAllowedHttpExceptionTest.php @@ -0,0 +1,36 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\MethodNotAllowedHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 45 Method Not Allowed Exception tests. + */ +class MethodNotAllowedHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new MethodNotAllowedHttpException(); + $exception->setValidMethods(['GET', 'POST']); + + self::assertEquals('Method Not Allowed', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_METHOD_NOT_ALLOWED, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_METHOD_NOT_ALLOWED, $exception->getStatusCode()); + self::assertSame(['GET', 'POST'], $exception->getValidMethods()); + } +} diff --git a/tests/HttpException/NotAcceptableHttpExceptionTest.php b/tests/HttpException/NotAcceptableHttpExceptionTest.php new file mode 100644 index 0000000..42c7020 --- /dev/null +++ b/tests/HttpException/NotAcceptableHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\NotAcceptableHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 406 Not Acceptable Exception tests. + */ +class NotAcceptableHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new NotAcceptableHttpException(); + + self::assertEquals('Not Acceptable', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_NOT_ACCEPTABLE, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_NOT_ACCEPTABLE, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/NotFoundHttpExceptionTest.php b/tests/HttpException/NotFoundHttpExceptionTest.php new file mode 100644 index 0000000..26fbc5f --- /dev/null +++ b/tests/HttpException/NotFoundHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\NotFoundHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 404 Not Found Exception tests. + */ +class NotFoundHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new NotFoundHttpException(); + + self::assertEquals('Not Found', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_NOT_FOUND, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_NOT_FOUND, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/NotImplementedHttpExceptionTest.php b/tests/HttpException/NotImplementedHttpExceptionTest.php new file mode 100644 index 0000000..ee879a8 --- /dev/null +++ b/tests/HttpException/NotImplementedHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\NotImplementedHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 501 Not Implemented Exception tests. + */ +class NotImplementedHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new NotImplementedHttpException(); + + self::assertEquals('Not Implemented', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_NOT_IMPLEMENTED, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_NOT_IMPLEMENTED, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/Stubs/HttpExceptionStub.php b/tests/HttpException/Stubs/HttpExceptionStub.php new file mode 100644 index 0000000..5f3b467 --- /dev/null +++ b/tests/HttpException/Stubs/HttpExceptionStub.php @@ -0,0 +1,20 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests\Stubs; + +use Jgut\HttpException\HttpException; + +class HttpExceptionStub extends HttpException +{ +} diff --git a/tests/HttpException/TooManyRequestsHttpExceptionTest.php b/tests/HttpException/TooManyRequestsHttpExceptionTest.php new file mode 100644 index 0000000..9c186d2 --- /dev/null +++ b/tests/HttpException/TooManyRequestsHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\TooManyRequestsHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 429 Too Many Requests Exception tests. + */ +class TooManyRequestsHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new TooManyRequestsHttpException(); + + self::assertEquals('Too Many Requests', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_TOO_MANY_REQUESTS, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_TOO_MANY_REQUESTS, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/UnauthorizedHttpExceptionTest.php b/tests/HttpException/UnauthorizedHttpExceptionTest.php new file mode 100644 index 0000000..0b66218 --- /dev/null +++ b/tests/HttpException/UnauthorizedHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\UnauthorizedHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 401 Unauthorized Exception tests. + */ +class UnauthorizedHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new UnauthorizedHttpException(); + + self::assertEquals('Unauthorized', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_UNAUTHORIZED, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_UNAUTHORIZED, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/UnprocessableEntityHttpExceptionTest.php b/tests/HttpException/UnprocessableEntityHttpExceptionTest.php new file mode 100644 index 0000000..d6d1683 --- /dev/null +++ b/tests/HttpException/UnprocessableEntityHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\UnprocessableEntityHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 422 Unprocessable Entity Exception tests. + */ +class UnprocessableEntityHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new UnprocessableEntityHttpException(); + + self::assertEquals('Unprocessable Entity', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY, $exception->getStatusCode()); + } +} diff --git a/tests/HttpException/UnsupportedMediaTypeHttpExceptionTest.php b/tests/HttpException/UnsupportedMediaTypeHttpExceptionTest.php new file mode 100644 index 0000000..560f556 --- /dev/null +++ b/tests/HttpException/UnsupportedMediaTypeHttpExceptionTest.php @@ -0,0 +1,34 @@ + + */ + +declare(strict_types=1); + +namespace Jgut\HttpException\Tests; + +use Fig\Http\Message\StatusCodeInterface; +use Jgut\HttpException\UnsupportedMediaTypeHttpException; +use PHPUnit\Framework\TestCase; + +/** + * HTTP 415 Unsupported Media Type Exception tests. + */ +class UnsupportedMediaTypeHttpExceptionTest extends TestCase +{ + public function testException() + { + $exception = new UnsupportedMediaTypeHttpException(); + + self::assertEquals('Unsupported Media Type', $exception->getMessage()); + self::assertEquals('', $exception->getDescription()); + self::assertEquals(StatusCodeInterface::STATUS_UNSUPPORTED_MEDIA_TYPE, $exception->getCode()); + self::assertEquals(StatusCodeInterface::STATUS_UNSUPPORTED_MEDIA_TYPE, $exception->getStatusCode()); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..8bd6a17 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,14 @@ + + */ + +declare(strict_types=1); + +require __DIR__ . '/../vendor/autoload.php';