From dc988f00d0637f3947765dba8d784807b957d4a0 Mon Sep 17 00:00:00 2001 From: gpolverini Date: Tue, 17 Jul 2018 13:15:24 -0300 Subject: [PATCH 1/6] + Add Client interface.- + Add enums (HTTP Method, Schemes and Status Code).- + TDD.- --- composer.json | 2 +- phpunit.xml | 2 +- src/AbstractMessage.php | 310 ++++++ src/Client.php | 163 ++- src/ClientInterface.php | 77 ++ src/Enum.php | 110 ++ src/HttpMethod.php | 40 + src/HttpStatusCode.php | 174 +++ src/Request.php | 280 +---- src/Response.php | 265 +---- src/Scheme.php | 39 + src/Uri.php | 66 +- tests/ClientTest.php | 102 +- tests/HttpMethodTest.php | 329 ++++++ tests/HttpStatusCodeTest.php | 1980 ++++++++++++++++++++++++++++++++++ tests/RequestTest.php | 351 +++++- tests/ResponseTest.php | 258 ++++- tests/SchemeTest.php | 149 +++ tests/UriTest.php | 237 +++- 19 files changed, 4415 insertions(+), 519 deletions(-) create mode 100644 src/AbstractMessage.php create mode 100644 src/ClientInterface.php create mode 100644 src/Enum.php create mode 100644 src/HttpMethod.php create mode 100644 src/HttpStatusCode.php create mode 100644 src/Scheme.php create mode 100644 tests/HttpMethodTest.php create mode 100644 tests/HttpStatusCodeTest.php create mode 100644 tests/SchemeTest.php diff --git a/composer.json b/composer.json index 8b0c032..0d818c9 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "library", "keywords": ["http", "client", "psr7", "curl", "wrapper"], "require": { - "php": ">=5.4.0", + "php": ">=5.5.0", "psr/http-message": "^1.0" }, "require-dev": { diff --git a/phpunit.xml b/phpunit.xml index 14c613f..56bd4ed 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -26,7 +26,7 @@ diff --git a/src/AbstractMessage.php b/src/AbstractMessage.php new file mode 100644 index 0000000..27b0163 --- /dev/null +++ b/src/AbstractMessage.php @@ -0,0 +1,310 @@ + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +namespace Matricali\Http; + +use Psr\Http\Message\MessageInterface; +use Psr\Http\Message\StreamInterface; + +abstract class AbstractMessage implements MessageInterface +{ + protected $protocolVersion; + protected $headers; + protected $body; + + /** + * AbstractMessage constructor. + * + * @param string $protocolVersion. + * @param array $headers Header value(s). + * @param string $body. + * @throws \InvalidArgumentException for invalid HTTP methods. + */ + public function __construct($protocolVersion = '1.1', array $headers = array(), $body = null) + { + if ($body !== null && !is_string($body)) { + throw new \InvalidArgumentException('The body parameter must be of the string type'); + } + $this->protocolVersion = $protocolVersion; + $this->headers = []; + if ($headers !== null) { + foreach ($headers as $k => $v) { + if (!is_array($v)) { + $this->headers[$k] = array_map('trim', explode(',', $v)); + continue; + } + $this->headers[$k] = $v; + } + } + $this->body = $body; + } + + /** + * Retrieves the index if a header exists by the given case-insensitive name. + * + * @param string $name Case-insensitive header field name. + * @return mixed Returns integer if any header names match the given header + * name using a case-insensitive string comparison. Returns false if + * no matching header name is found in the message. + */ + protected function searchHeader($name) + { + $keysHeader = array_keys($this->headers); + $index = array_search(strtolower($name), array_map('strtolower', $keysHeader)); + return $index !== false ? $keysHeader[$index] : $index; + } + + /** + * Retrieves the HTTP protocol version as a string. + * + * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0"). + * + * @return string HTTP protocol version. + */ + public function getProtocolVersion() + { + return $this->protocolVersion; + } + + /** + * Return an instance with the specified HTTP protocol version. + * + * The version string MUST contain only the HTTP version number (e.g., + * "1.1", "1.0"). + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * new protocol version. + * + * @param string $version HTTP protocol version + * @return static + */ + public function withProtocolVersion($version) + { + $clone = clone $this; + $clone->protocolVersion = $version; + return $clone; + } + + /** + * Retrieves all message header values. + * + * The keys represent the header name as it will be sent over the wire, and + * each value is an array of strings associated with the header. + * + * // Represent the headers as a string + * foreach ($message->getHeaders() as $name => $values) { + * echo $name . ": " . implode(", ", $values); + * } + * + * // Emit headers iteratively: + * foreach ($message->getHeaders() as $name => $values) { + * foreach ($values as $value) { + * header(sprintf('%s: %s', $name, $value), false); + * } + * } + * + * While header names are not case-sensitive, getHeaders() will preserve the + * exact case in which headers were originally specified. + * + * @return string[][] Returns an associative array of the message's headers. Each + * key MUST be a header name, and each value MUST be an array of strings + * for that header. + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Checks if a header exists by the given case-insensitive name. + * + * @param string $name Case-insensitive header field name. + * @return bool Returns true if any header names match the given header + * name using a case-insensitive string comparison. Returns false if + * no matching header name is found in the message. + */ + public function hasHeader($name) + { + return $this->searchHeader($name) !== false; + } + + /** + * Retrieves a message header value by the given case-insensitive name. + * + * This method returns an array of all the header values of the given + * case-insensitive header name. + * + * If the header does not appear in the message, this method MUST return an + * empty array. + * + * @param string $name Case-insensitive header field name. + * @return string[] An array of string values as provided for the given + * header. If the header does not appear in the message, this method MUST + * return an empty array. + */ + public function getHeader($name) + { + $key = $this->searchHeader($name); + if ($key !== false) { + return $this->headers[$key]; + } + return []; + } + + /** + * Retrieves a comma-separated string of the values for a single header. + * + * This method returns all of the header values of the given + * case-insensitive header name as a string concatenated together using + * a comma. + * + * NOTE: Not all header values may be appropriately represented using + * comma concatenation. For such headers, use getHeader() instead + * and supply your own delimiter when concatenating. + * + * If the header does not appear in the message, this method MUST return + * an empty string. + * + * @param string $name Case-insensitive header field name. + * @return string A string of values as provided for the given header + * concatenated together using a comma. If the header does not appear in + * the message, this method MUST return an empty string. + */ + public function getHeaderLine($name) + { + $key = $this->searchHeader($name); + if ($key !== false) { + return implode(', ', $this->headers[$key]); + } + return ''; + } + + /** + * Return an instance with the provided value replacing the specified header. + * + * While header names are case-insensitive, the casing of the header will + * be preserved by this function, and returned from getHeaders(). + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * new and/or updated header and value. + * + * @param string $name Case-insensitive header field name. + * @param string|string[] $value Header value(s). + * @return static + * @throws \InvalidArgumentException for invalid header names or values. + */ + public function withHeader($name, $value) + { + $key = $this->searchHeader($name); + $value = is_array($value) ? $value : [$value]; + if ($key !== false) { + $name = $key; + } + $clone = clone $this; + $clone->headers[$name] = $value; + return $clone; + } + + /** + * Return an instance with the specified header appended with the given value. + * + * Existing values for the specified header will be maintained. The new + * value(s) will be appended to the existing list. If the header did not + * exist previously, it will be added. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * new header and/or value. + * + * @param string $name Case-insensitive header field name to add. + * @param string|string[] $value Header value(s). + * @return static + * @throws \InvalidArgumentException for invalid header names or values. + */ + public function withAddedHeader($name, $value) + { + $key = $this->searchHeader($name); + $value = is_array($value) ? $value : [$value]; + if ($key !== false) { + $name = $key; + $value = array_merge($this->headers[$key], $value); + } + $clone = clone $this; + $clone->headers[$name] = $value; + return $clone; + } + + /** + * Return an instance without the specified header. + * + * Header resolution MUST be done without case-sensitivity. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that removes + * the named header. + * + * @param string $name Case-insensitive header field name to remove. + * @return static + */ + public function withoutHeader($name) + { + $clone = clone $this; + $key = $this->searchHeader($name); + if ($key !== false) { + unset($clone->headers[$key]); + } + return $clone; + } + + /** + * Gets the body of the message. + * + * @return StreamInterface Returns the body as a stream. + */ + public function getBody() + { + return $this->body; + } + + /** + * Return an instance with the specified message body. + * + * The body MUST be a StreamInterface object. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return a new instance that has the + * new body stream. + * + * @param StreamInterface $body Body. + * @return static + * @throws \InvalidArgumentException When the body is not valid. + */ + public function withBody(StreamInterface $body) + { + $clone = clone $this; + $clone->body = $body->__toString(); + return $clone; + } +} diff --git a/src/Client.php b/src/Client.php index 9c805d0..296cdcd 100644 --- a/src/Client.php +++ b/src/Client.php @@ -24,11 +24,9 @@ namespace Matricali\Http; use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; - use Matricali\Http\Client\Exception as ClientException; -class Client +class Client implements ClientInterface { const VERSION = '1.1'; @@ -38,6 +36,11 @@ class Client protected $statusCode; protected $version; + /** + * Client constructor. + * + * @throws ClientException + */ public function __construct() { $this->handle = curl_init(); @@ -46,7 +49,7 @@ public function __construct() throw new ClientException(curl_error($this->handle), 'curl'); } - curl_setopt_array($this->handle, [ + $this->setOptions([ CURLOPT_RETURNTRANSFER => true, CURLOPT_AUTOREFERER => true, CURLOPT_FOLLOWLOCATION => true, @@ -65,12 +68,25 @@ public function __destruct() curl_close($this->handle); } + /** + * headerFunction. + * + * @param $handler + * @param $line + * @return int + */ public function headerFunction($handler, $line) { $this->responseHeader .= $line; return strlen($line); } + /** + * __clone. + * + * @return Client + * @throws ClientException + */ public function __clone() { $client = new self; @@ -78,9 +94,26 @@ public function __clone() return $client; } - protected function parseHeaders($lines) + /** + * setOptions. + * + * @param array $options + */ + public function setOptions(array $options) { + if (is_array($options) && count($options) > 0) { + curl_setopt_array($this->handle, $options); + } + } + /** + * parseHeaders. + * + * @param $lines + * @return array|bool + */ + protected function parseHeaders($lines) + { if (empty($lines)) { return []; } @@ -106,28 +139,34 @@ protected function parseHeaders($lines) $this->responseHeaders[$field[0]] = $field[1]; } } + return $this->responseHeaders; } + /** + * sendRequest. + * + * @param RequestInterface $request + * @return Response + * @throws ClientException + */ public function sendRequest(RequestInterface $request) { curl_setopt($this->handle, CURLOPT_URL, (string) $request->getUri()); curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, [$this, 'headerFunction']); - if ($request->getMethod() == 'HEAD') { - curl_setopt($this->handle, CURLOPT_NOBODY, true); - } + $method = $request->getMethod(); - if ($request->getMethod() == 'POST') { + if ($method == HttpMethod::HEAD) { + curl_setopt($this->handle, CURLOPT_NOBODY, true); + } elseif ($method == HttpMethod::POST) { curl_setopt($this->handle, CURLOPT_POST, true); $body = $request->getBody(); if (!empty($body)) { curl_setopt($this->handle, CURLOPT_POSTFIELDS, $body); } - } - - if (in_array($request->getMethod(), ['PUT', 'PATCH', 'DELETE'])) { - curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $request->getMethod()); + } elseif (in_array($method, [HttpMethod::PUT, HttpMethod::PATCH, HttpMethod::DELETE])) { + curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $method); } $ret = curl_exec($this->handle); @@ -138,26 +177,100 @@ public function sendRequest(RequestInterface $request) $this->parseHeaders($this->responseHeader); - $response = new Response($ret, $this->statusCode, $this->responseHeaders, $this->version); - return $response; + return new Response($ret, $this->statusCode, $this->responseHeaders, $this->version); + } + + /** + * Create a GET request for the client + * + * @param string $uri Resource URI.- + * @param array $headers HTTP headers.- + * @param array $options Options to apply to the request.- + * @return Response + * @throws ClientException + */ + public function get($uri, array $headers = array(), array $options = array()) + { + $this->setOptions($options); + return $this->sendRequest(new Request(HttpMethod::GET, $uri, $headers)); + } + + /** + * Create a HEAD request for the client + * + * @param string $uri Resource URI.- + * @param array $headers HTTP headers.- + * @param array $options Options to apply to the request.- + * @return Response + * @throws ClientException + */ + public function head($uri, array $headers = array(), array $options = array()) + { + $this->setOptions($options); + return $this->sendRequest(new Request(HttpMethod::HEAD, $uri, $headers)); + } + + /** + * Create a POST request for the client + * + * @param string $uri Resource URI.- + * @param string $body Body to send in the request.- + * @param array $headers HTTP headers.- + * @param array $options Options to apply to the request.- + * @return Response + * @throws ClientException + */ + public function post($uri, $body = '', array $headers = array(), array $options = array()) + { + $this->setOptions($options); + return $this->sendRequest(new Request(HttpMethod::POST, $uri, $headers, $body)); } - public function get($uri, $headers = []) + /** + * Create a PUT request for the client + * + * @param string $uri Resource URI.- + * @param string $body Body to send in the request.- + * @param array $headers HTTP headers.- + * @param array $options Options to apply to the request.- + * @return Response + * @throws ClientException + */ + public function put($uri, $body = '', array $headers = array(), array $options = array()) { - $request = new Request('GET', $uri, $headers); - return $this->sendRequest($request); + $this->setOptions($options); + return $this->sendRequest(new Request(HttpMethod::PUT, $uri, $headers, $body)); } - public function head($uri, $headers = []) + /** + * Create a DELETE request for the client + * + * @param string $uri Resource URI.- + * @param string $body Body to send in the request.- + * @param array $headers HTTP headers.- + * @param array $options Options to apply to the request.- + * @return Response + * @throws ClientException + */ + public function delete($uri, $body = '', array $headers = array(), array $options = array()) { - $request = new Request('HEAD', $uri, $headers); - return $this->sendRequest($request); + $this->setOptions($options); + return $this->sendRequest(new Request(HttpMethod::DELETE, $uri, $headers, $body)); } - public function post($uri, $body = '', $headers = []) + /** + * Create a PATCH request for the client + * + * @param string $uri Resource URI.- + * @param string $body Body to send in the request.- + * @param array $headers HTTP headers.- + * @param array $options Options to apply to the request.- + * @return Response + * @throws ClientException + */ + public function patch($uri, $body = '', array $headers = array(), array $options = array()) { - $request = new Request('POST', $uri, $headers); - $request->setBody($body); - return $this->sendRequest($request); + $this->setOptions($options); + return $this->sendRequest(new Request(HttpMethod::PATCH, $uri, $headers, $body)); } } diff --git a/src/ClientInterface.php b/src/ClientInterface.php new file mode 100644 index 0000000..30e105d --- /dev/null +++ b/src/ClientInterface.php @@ -0,0 +1,77 @@ + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +namespace Matricali\Http; + +use ReflectionClass; + +/** + * Enumerador basico. + * + * @author Jorge Matricali + */ +abstract class Enum +{ + private static $constCache = null; + + /** + * Obtiene una lista con las constantes definidas. + * + * @throws \ReflectionException + * + * @return mixed + */ + protected static function getConstants() + { + if (self::$constCache == null) { + self::$constCache = []; + } + $calledClass = get_called_class(); + if (!array_key_exists($calledClass, self::$constCache)) { + $reflect = new ReflectionClass($calledClass); + self::$constCache[$calledClass] = $reflect->getConstants(); + } + return self::$constCache[$calledClass]; + } + + /** + * Comprueba si el nombre dado corresponde a un elemento enumerado. + * + * @param string $name + * @param bool $strict + * + * @throws \ReflectionException + * + * @return bool + */ + public static function isValidName($name, $strict = false) + { + $constants = self::getConstants(); + if ($strict) { + return array_key_exists($name, $constants); + } + $keys = array_map('strtolower', array_keys($constants)); + + return in_array(strtolower($name), $keys); + } + + /** + * Comprueba si el valor dado corresponde a un elemento enumerado. + * + * @param string $value + * + * @throws \ReflectionException + * + * @return bool + */ + public static function isValidValue($value) + { + $values = array_values(self::getConstants()); + + return in_array($value, $values, true); + } + + /** + * Obtiene un valor en base a un nombre dado. + * + * @param string $name + * + * @throws \ReflectionException + * + * @return mixed + */ + public static function getByName($name) + { + $name = strtoupper($name); + $values = self::getConstants(); + + return in_array($name, array_keys($values)) ? $values[$name] : null; + } +} diff --git a/src/HttpMethod.php b/src/HttpMethod.php new file mode 100644 index 0000000..8d4e998 --- /dev/null +++ b/src/HttpMethod.php @@ -0,0 +1,40 @@ + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +namespace Matricali\Http; + +/** + * @author Gabriel Polverini + */ +abstract class HttpMethod extends Enum +{ + const GET = 'GET'; + const POST = 'POST'; + const PUT = 'PUT'; + const HEAD = 'HEAD'; + const DELETE = 'DELETE'; + const PATCH = 'PATCH'; + const CONNECT = 'CONNECT'; + const OPTIONS = 'OPTIONS'; + const TRACE = 'TRACE'; +} diff --git a/src/HttpStatusCode.php b/src/HttpStatusCode.php new file mode 100644 index 0000000..ff62bca --- /dev/null +++ b/src/HttpStatusCode.php @@ -0,0 +1,174 @@ + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +namespace Matricali\Http; + +/** + * @author Gabriel Polverini + */ +abstract class HttpStatusCode extends Enum +{ + const HTTP_CONTINUE = 100; + const HTTP_SWITCHING_PROTOCOLS = 101; + const HTTP_PROCESSING = 102; + const HTTP_EARLY_HINTS = 103; + const HTTP_OK = 200; + const HTTP_CREATED = 201; + const HTTP_ACCEPTED = 202; + const HTTP_NON_AUTHORITATIVE_INFORMATION = 203; + const HTTP_NO_CONTENT = 204; + const HTTP_RESET_CONTENT = 205; + const HTTP_PARTIAL_CONTENT = 206; + const HTTP_MULTI_STATUS = 207; + const HTTP_ALREADY_REPORTED = 208; + const HTTP_IM_USED = 226; + const HTTP_MULTIPLE_CHOICES = 300; + const HTTP_MOVED_PERMANENTLY = 301; + const HTTP_FOUND = 302; + const HTTP_SEE_OTHER = 303; + const HTTP_NOT_MODIFIED = 304; + const HTTP_USE_PROXY = 305; + const HTTP_RESERVED = 306; + const HTTP_TEMPORARY_REDIRECT = 307; + const HTTP_PERMANENTLY_REDIRECT = 308; + const HTTP_BAD_REQUEST = 400; + const HTTP_UNAUTHORIZED = 401; + const HTTP_PAYMENT_REQUIRED = 402; + const HTTP_FORBIDDEN = 403; + const HTTP_NOT_FOUND = 404; + const HTTP_METHOD_NOT_ALLOWED = 405; + const HTTP_NOT_ACCEPTABLE = 406; + const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; + const HTTP_REQUEST_TIMEOUT = 408; + const HTTP_CONFLICT = 409; + const HTTP_GONE = 410; + const HTTP_LENGTH_REQUIRED = 411; + const HTTP_PRECONDITION_FAILED = 412; + const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; + const HTTP_REQUEST_URI_TOO_LONG = 414; + const HTTP_UNSUPPORTED_MEDIA_TYPE = 415; + const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + const HTTP_EXPECTATION_FAILED = 417; + const HTTP_I_AM_A_TEAPOT = 418; + const HTTP_MISDIRECTED_REQUEST = 421; + const HTTP_UNPROCESSABLE_ENTITY = 422; + const HTTP_LOCKED = 423; + const HTTP_FAILED_DEPENDENCY = 424; + /** + * @deprecated + */ + const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; + const HTTP_TOO_EARLY = 425; + const HTTP_UPGRADE_REQUIRED = 426; + const HTTP_PRECONDITION_REQUIRED = 428; + const HTTP_TOO_MANY_REQUESTS = 429; + const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; + const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451; + const HTTP_INTERNAL_SERVER_ERROR = 500; + const HTTP_NOT_IMPLEMENTED = 501; + const HTTP_BAD_GATEWAY = 502; + const HTTP_SERVICE_UNAVAILABLE = 503; + const HTTP_GATEWAY_TIMEOUT = 504; + const HTTP_VERSION_NOT_SUPPORTED = 505; + const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; + const HTTP_INSUFFICIENT_STORAGE = 507; + const HTTP_LOOP_DETECTED = 508; + const HTTP_NOT_EXTENDED = 510; + const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; + + /** + * Status codes translation table. + * + * The list of codes is complete according to the + * {@link http://www.iana.org/assignments/http-status-codes/ Hypertext Transfer Protocol (HTTP) Status Code Registry} + * (last updated 2016-03-01). + * + * Unless otherwise noted, the status code is defined in RFC2616. + * + * @var array + */ + public static $statusTexts = array( + self::HTTP_CONTINUE => 'Continue', + self::HTTP_SWITCHING_PROTOCOLS => 'Switching Protocols', + self::HTTP_PROCESSING => 'Processing', + self::HTTP_EARLY_HINTS => 'Early Hints', + self::HTTP_OK => 'OK', + self::HTTP_CREATED => 'Created', + self::HTTP_ACCEPTED => 'Accepted', + self::HTTP_NON_AUTHORITATIVE_INFORMATION => 'Non-Authoritative Information', + self::HTTP_NO_CONTENT => 'No Content', + self::HTTP_RESET_CONTENT => 'Reset Content', + self::HTTP_PARTIAL_CONTENT => 'Partial Content', + self::HTTP_MULTI_STATUS => 'Multi-Status', + self::HTTP_ALREADY_REPORTED => 'Already Reported', + self::HTTP_IM_USED => 'IM Used', + self::HTTP_MULTIPLE_CHOICES => 'Multiple Choices', + self::HTTP_MOVED_PERMANENTLY => 'Moved Permanently', + self::HTTP_FOUND => 'Found', + self::HTTP_SEE_OTHER => 'See Other', + self::HTTP_NOT_MODIFIED => 'Not Modified', + self::HTTP_USE_PROXY => 'Use Proxy', + self::HTTP_TEMPORARY_REDIRECT => 'Temporary Redirect', + self::HTTP_PERMANENTLY_REDIRECT => 'Permanent Redirect', + self::HTTP_BAD_REQUEST => 'Bad Request', + self::HTTP_UNAUTHORIZED => 'Unauthorized', + self::HTTP_PAYMENT_REQUIRED => 'Payment Required', + self::HTTP_FORBIDDEN => 'Forbidden', + self::HTTP_NOT_FOUND => 'Not Found', + self::HTTP_METHOD_NOT_ALLOWED => 'Method Not Allowed', + self::HTTP_NOT_ACCEPTABLE => 'Not Acceptable', + self::HTTP_PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required', + self::HTTP_REQUEST_TIMEOUT => 'Request Timeout', + self::HTTP_CONFLICT => 'Conflict', + self::HTTP_GONE => 'Gone', + self::HTTP_LENGTH_REQUIRED => 'Length Required', + self::HTTP_PRECONDITION_FAILED => 'Precondition Failed', + self::HTTP_REQUEST_ENTITY_TOO_LARGE => 'Payload Too Large', + self::HTTP_REQUEST_URI_TOO_LONG => 'URI Too Long', + self::HTTP_UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type', + self::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE => 'Range Not Satisfiable', + self::HTTP_EXPECTATION_FAILED => 'Expectation Failed', + self::HTTP_I_AM_A_TEAPOT => 'I\'m a teapot', + self::HTTP_MISDIRECTED_REQUEST => 'Misdirected Request', + self::HTTP_UNPROCESSABLE_ENTITY => 'Unprocessable Entity', + self::HTTP_LOCKED => 'Locked', + self::HTTP_FAILED_DEPENDENCY => 'Failed Dependency', + self::HTTP_TOO_EARLY => 'Too Early', + self::HTTP_UPGRADE_REQUIRED => 'Upgrade Required', + self::HTTP_PRECONDITION_REQUIRED => 'Precondition Required', + self::HTTP_TOO_MANY_REQUESTS => 'Too Many Requests', + self::HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large', + self::HTTP_UNAVAILABLE_FOR_LEGAL_REASONS => 'Unavailable For Legal Reasons', + self::HTTP_INTERNAL_SERVER_ERROR => 'Internal Server Error', + self::HTTP_NOT_IMPLEMENTED => 'Not Implemented', + self::HTTP_BAD_GATEWAY => 'Bad Gateway', + self::HTTP_SERVICE_UNAVAILABLE => 'Service Unavailable', + self::HTTP_GATEWAY_TIMEOUT => 'Gateway Timeout', + self::HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version Not Supported', + self::HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL => 'Variant Also Negotiates', + self::HTTP_INSUFFICIENT_STORAGE => 'Insufficient Storage', + self::HTTP_LOOP_DETECTED => 'Loop Detected', + self::HTTP_NOT_EXTENDED => 'Not Extended', + self::HTTP_NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required', + ); +} diff --git a/src/Request.php b/src/Request.php index 269e809..dca033b 100644 --- a/src/Request.php +++ b/src/Request.php @@ -24,35 +24,64 @@ namespace Matricali\Http; use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\UriInterface; -use Psr\Http\Message\StreamInterface; -class Request implements RequestInterface +class Request extends AbstractMessage implements RequestInterface { - protected $method = 'GET'; + protected $method; protected $uri; - protected $protocolVersion = '1.1'; - protected $headers = []; - protected $body; - public function __construct($method = 'GET', $uri = '', $headers = []) + /** + * Request constructor. + * + * While HTTP method names are typically all uppercase characters, HTTP + * method names are case-sensitive and thus implementations SHOULD NOT + * modify the given string. + * + * @param string $method Case-sensitive method. + * @param string $uri Resource URI.- + * @param array $headers Header value(s). + * @param string $body Body to send in the request.- + * @throws \InvalidArgumentException for invalid HTTP methods. + */ + public function __construct($method = HttpMethod::GET, $uri = '', array $headers = array(), $body = null) { + $this->validateMethod($method); + parent::__construct('1.1', $headers, $body); $this->method = $method; - foreach ($headers as $k => $v) { - if (!is_array($v)) { - $this->headers[$k][] = $v; - continue; - } - $this->headers[$k] = $v; - } - if (is_string($uri)) { $this->uri = new Uri($uri); } } + /** + * __clone. + * + * @return Request + */ + public function __clone() + { + return new self; + } + + /** + * Validate HTTP method + * + * While HTTP method names are typically all uppercase characters, HTTP + * method names are case-sensitive and thus implementations SHOULD NOT + * modify the given string. + * + * @param string $method Case-sensitive method. + * @throws \InvalidArgumentException for invalid HTTP methods. + */ + protected function validateMethod($method) + { + if (!HttpMethod::isValidValue($method)) { + throw new \InvalidArgumentException(sprintf('The HTTP method "%s" is not valid.', $method)); + } + } + /** * Retrieves the message's request target. * @@ -97,7 +126,8 @@ public function getRequestTarget() */ public function withRequestTarget($requestTarget) { - + $clone = clone $this; + return $clone; } /** @@ -127,7 +157,10 @@ public function getMethod() */ public function withMethod($method) { - + $this->validateMethod($method); + $clone = clone $this; + $clone->method = $method; + return $clone; } /** @@ -176,213 +209,8 @@ public function getUri() */ public function withUri(UriInterface $uri, $preserveHost = false) { - - } - - // ----------------- - - /** - * Retrieves the HTTP protocol version as a string. - * - * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0"). - * - * @return string HTTP protocol version. - */ - public function getProtocolVersion() - { - return $this->protocolVersion; - } - /** - * Return an instance with the specified HTTP protocol version. - * - * The version string MUST contain only the HTTP version number (e.g., - * "1.1", "1.0"). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new protocol version. - * - * @param string $version HTTP protocol version - * @return static - */ - public function withProtocolVersion($version) - { - - } - /** - * Retrieves all message header values. - * - * The keys represent the header name as it will be sent over the wire, and - * each value is an array of strings associated with the header. - * - * // Represent the headers as a string - * foreach ($message->getHeaders() as $name => $values) { - * echo $name . ": " . implode(", ", $values); - * } - * - * // Emit headers iteratively: - * foreach ($message->getHeaders() as $name => $values) { - * foreach ($values as $value) { - * header(sprintf('%s: %s', $name, $value), false); - * } - * } - * - * While header names are not case-sensitive, getHeaders() will preserve the - * exact case in which headers were originally specified. - * - * @return string[][] Returns an associative array of the message's headers. Each - * key MUST be a header name, and each value MUST be an array of strings - * for that header. - */ - public function getHeaders() - { - return $this->headers; - } - /** - * Checks if a header exists by the given case-insensitive name. - * - * @param string $name Case-insensitive header field name. - * @return bool Returns true if any header names match the given header - * name using a case-insensitive string comparison. Returns false if - * no matching header name is found in the message. - */ - public function hasHeader($name) - { - return array_key_exists($name, $this->headers); - } - /** - * Retrieves a message header value by the given case-insensitive name. - * - * This method returns an array of all the header values of the given - * case-insensitive header name. - * - * If the header does not appear in the message, this method MUST return an - * empty array. - * - * @param string $name Case-insensitive header field name. - * @return string[] An array of string values as provided for the given - * header. If the header does not appear in the message, this method MUST - * return an empty array. - */ - public function getHeader($name) - { - if (array_key_exists($name, $this->headers)) { - return $this->headers[$name]; - } - return []; - } - /** - * Retrieves a comma-separated string of the values for a single header. - * - * This method returns all of the header values of the given - * case-insensitive header name as a string concatenated together using - * a comma. - * - * NOTE: Not all header values may be appropriately represented using - * comma concatenation. For such headers, use getHeader() instead - * and supply your own delimiter when concatenating. - * - * If the header does not appear in the message, this method MUST return - * an empty string. - * - * @param string $name Case-insensitive header field name. - * @return string A string of values as provided for the given header - * concatenated together using a comma. If the header does not appear in - * the message, this method MUST return an empty string. - */ - public function getHeaderLine($name) - { - if (array_key_exists($name, $this->headers)) { - return implode(',', $this->headers[$name]); - } - return ''; - } - /** - * Return an instance with the provided value replacing the specified header. - * - * While header names are case-insensitive, the casing of the header will - * be preserved by this function, and returned from getHeaders(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new and/or updated header and value. - * - * @param string $name Case-insensitive header field name. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withHeader($name, $value) - { - - } - /** - * Return an instance with the specified header appended with the given value. - * - * Existing values for the specified header will be maintained. The new - * value(s) will be appended to the existing list. If the header did not - * exist previously, it will be added. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new header and/or value. - * - * @param string $name Case-insensitive header field name to add. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withAddedHeader($name, $value) - { - - } - /** - * Return an instance without the specified header. - * - * Header resolution MUST be done without case-sensitivity. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that removes - * the named header. - * - * @param string $name Case-insensitive header field name to remove. - * @return static - */ - public function withoutHeader($name) - { - - } - /** - * Gets the body of the message. - * - * @return StreamInterface Returns the body as a stream. - */ - public function getBody() - { - return $this->body; - } - - public function setBody($body) - { - $this->body = $body; - return $this; - } - - /** - * Return an instance with the specified message body. - * - * The body MUST be a StreamInterface object. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return a new instance that has the - * new body stream. - * - * @param StreamInterface $body Body. - * @return static - * @throws \InvalidArgumentException When the body is not valid. - */ - public function withBody(StreamInterface $body) - { - + $clone = clone $this; + $clone->uri = $uri; + return $clone; } } diff --git a/src/Response.php b/src/Response.php index 2965fad..bb374d0 100644 --- a/src/Response.php +++ b/src/Response.php @@ -23,9 +23,7 @@ namespace Matricali\Http; -use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamInterface; /** * Representation of an outgoing, server-side response. @@ -42,19 +40,52 @@ * be implemented such that they retain the internal state of the current * message and return an instance that contains the changed state. */ -class Response implements ResponseInterface +class Response extends AbstractMessage implements ResponseInterface { protected $statusCode; - protected $protocolVersion; - protected $headers; - protected $body; + protected $reasonPhrase; - public function __construct($body, $statusCode = 200, $headers = [], $protocolVersion = '1.1') + /** + * Response constructor. + * + * @param string $body Body to return in the response.- + * @param int $statusCode. + * @param array $headers Header value(s). + * @param string $protocolVersion HTTP protocol version + * @throws \InvalidArgumentException for invalid HTTP methods. + */ + public function __construct($body = '', $statusCode = 200, array $headers = array(), $protocolVersion = '1.1') { - $this->protocolVersion = $protocolVersion; - $this->body = $body; + $this->validateStatusCode($statusCode); + parent::__construct($protocolVersion, $headers, $body); $this->statusCode = $statusCode; - $this->headers = $headers; + $this->reasonPhrase = ''; + } + + /** + * __clone. + * + * @return Response + */ + public function __clone() + { + return new self; + } + + /** + * Validate the response status code. + * + * The status code is a 3-digit integer result code of the server's attempt + * to understand and satisfy the request. + * + * @param int $statusCode. + * @throws \InvalidArgumentException for invalid HTTP methods. + */ + protected function validateStatusCode($statusCode) + { + if (!HttpStatusCode::isValidValue($statusCode)) { + throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $statusCode)); + } } /** @@ -92,7 +123,17 @@ public function getStatusCode() */ public function withStatus($code, $reasonPhrase = '') { - + $this->validateStatusCode($code); + + $clone = clone $this; + $clone->statusCode = $code; + $clone->reasonPhrase = 'unknown status'; + if (!empty($reasonPhrase)) { + $clone->reasonPhrase = $reasonPhrase; + } elseif (isset(HttpStatusCode::$statusTexts[$code])) { + $clone->reasonPhrase = HttpStatusCode::$statusTexts[$code]; + } + return $clone; } /** @@ -110,206 +151,6 @@ public function withStatus($code, $reasonPhrase = '') */ public function getReasonPhrase() { - - } - - // ---------- - - /** - * Retrieves the HTTP protocol version as a string. - * - * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0"). - * - * @return string HTTP protocol version. - */ - public function getProtocolVersion() - { - return $this->protocolVersion; - } - /** - * Return an instance with the specified HTTP protocol version. - * - * The version string MUST contain only the HTTP version number (e.g., - * "1.1", "1.0"). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new protocol version. - * - * @param string $version HTTP protocol version - * @return static - */ - public function withProtocolVersion($version) - { - - } - /** - * Retrieves all message header values. - * - * The keys represent the header name as it will be sent over the wire, and - * each value is an array of strings associated with the header. - * - * // Represent the headers as a string - * foreach ($message->getHeaders() as $name => $values) { - * echo $name . ": " . implode(", ", $values); - * } - * - * // Emit headers iteratively: - * foreach ($message->getHeaders() as $name => $values) { - * foreach ($values as $value) { - * header(sprintf('%s: %s', $name, $value), false); - * } - * } - * - * While header names are not case-sensitive, getHeaders() will preserve the - * exact case in which headers were originally specified. - * - * @return string[][] Returns an associative array of the message's headers. Each - * key MUST be a header name, and each value MUST be an array of strings - * for that header. - */ - public function getHeaders() - { - return $this->headers; - } - /** - * Checks if a header exists by the given case-insensitive name. - * - * @param string $name Case-insensitive header field name. - * @return bool Returns true if any header names match the given header - * name using a case-insensitive string comparison. Returns false if - * no matching header name is found in the message. - */ - public function hasHeader($name) - { - return array_key_exists($name, $this->headers); - } - /** - * Retrieves a message header value by the given case-insensitive name. - * - * This method returns an array of all the header values of the given - * case-insensitive header name. - * - * If the header does not appear in the message, this method MUST return an - * empty array. - * - * @param string $name Case-insensitive header field name. - * @return string[] An array of string values as provided for the given - * header. If the header does not appear in the message, this method MUST - * return an empty array. - */ - public function getHeader($name) - { - if (array_key_exists($name, $this->headers)) { - return $this->headers[$name]; - } - return []; - } - /** - * Retrieves a comma-separated string of the values for a single header. - * - * This method returns all of the header values of the given - * case-insensitive header name as a string concatenated together using - * a comma. - * - * NOTE: Not all header values may be appropriately represented using - * comma concatenation. For such headers, use getHeader() instead - * and supply your own delimiter when concatenating. - * - * If the header does not appear in the message, this method MUST return - * an empty string. - * - * @param string $name Case-insensitive header field name. - * @return string A string of values as provided for the given header - * concatenated together using a comma. If the header does not appear in - * the message, this method MUST return an empty string. - */ - public function getHeaderLine($name) - { - if (in_array($this->headers[$name])) { - return implode(',', $this->headers[$name]); - } - return ''; - } - /** - * Return an instance with the provided value replacing the specified header. - * - * While header names are case-insensitive, the casing of the header will - * be preserved by this function, and returned from getHeaders(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new and/or updated header and value. - * - * @param string $name Case-insensitive header field name. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withHeader($name, $value) - { - - } - /** - * Return an instance with the specified header appended with the given value. - * - * Existing values for the specified header will be maintained. The new - * value(s) will be appended to the existing list. If the header did not - * exist previously, it will be added. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new header and/or value. - * - * @param string $name Case-insensitive header field name to add. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withAddedHeader($name, $value) - { - - } - /** - * Return an instance without the specified header. - * - * Header resolution MUST be done without case-sensitivity. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that removes - * the named header. - * - * @param string $name Case-insensitive header field name to remove. - * @return static - */ - public function withoutHeader($name) - { - - } - /** - * Gets the body of the message. - * - * @return StreamInterface Returns the body as a stream. - */ - public function getBody() - { - return $this->body; - } - /** - * Return an instance with the specified message body. - * - * The body MUST be a StreamInterface object. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return a new instance that has the - * new body stream. - * - * @param StreamInterface $body Body. - * @return static - * @throws \InvalidArgumentException When the body is not valid. - */ - public function withBody(StreamInterface $body) - { - + return $this->reasonPhrase; } } diff --git a/src/Scheme.php b/src/Scheme.php new file mode 100644 index 0000000..717d553 --- /dev/null +++ b/src/Scheme.php @@ -0,0 +1,39 @@ + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +namespace Matricali\Http; + +/** + * @author Gabriel Polverini + */ +abstract class Scheme extends Enum +{ + const HTTP = 'http'; + const HTTPS = 'https'; + const FTP = 'ftp'; + + public static $defaultPort = array( + self::HTTP => 80, + self::HTTPS => 443, + ); +} diff --git a/src/Uri.php b/src/Uri.php index 49e7d34..3039faa 100644 --- a/src/Uri.php +++ b/src/Uri.php @@ -94,6 +94,17 @@ public function __construct($url = '') $this->fragment = $url['fragment']; } } + + /** + * __clone. + * + * @return Uri + */ + public function __clone() + { + return new self; + } + /** * Retrieve the scheme component of the URI. * @@ -312,7 +323,12 @@ public function getFragment() */ public function withScheme($scheme) { - + if (!Scheme::isValidValue($scheme)) { + throw new \InvalidArgumentException(sprintf('The scheme "%s" is not valid.', $scheme)); + } + $clone = clone $this; + $clone->scheme = $scheme; + return $clone; } /** @@ -331,7 +347,10 @@ public function withScheme($scheme) */ public function withUserInfo($user, $password = null) { - + $clone = clone $this; + $clone->user = $user; + $clone->pass = $password; + return $clone; } /** @@ -348,7 +367,12 @@ public function withUserInfo($user, $password = null) */ public function withHost($host) { - + if ($host !== null && !is_string($host)) { + throw new \InvalidArgumentException(sprintf('The host "%s" is not valid.', $host)); + } + $clone = clone $this; + $clone->host = $host; + return $clone; } /** @@ -370,7 +394,12 @@ public function withHost($host) */ public function withPort($port) { - + if ($port != null && !is_int($port)) { + throw new \InvalidArgumentException(sprintf('The port "%s" is not valid.', $port)); + } + $clone = clone $this; + $clone->port = $port; + return $clone; } /** @@ -397,7 +426,12 @@ public function withPort($port) */ public function withPath($path) { - + if ($path !== null && !is_string($path)) { + throw new \InvalidArgumentException(sprintf('The path "%s" is not valid.', $path)); + } + $clone = clone $this; + $clone->path = $path; + return $clone; } /** @@ -417,7 +451,12 @@ public function withPath($path) */ public function withQuery($query) { - + if ($query !== null && !is_string($query)) { + throw new \InvalidArgumentException(sprintf('The query "%s" is not valid.', $query)); + } + $clone = clone $this; + $clone->query = $query; + return $clone; } /** @@ -436,7 +475,12 @@ public function withQuery($query) */ public function withFragment($fragment) { - + if ($fragment !== null && !is_string($fragment)) { + throw new \InvalidArgumentException(sprintf('The fragment "%s" is not valid.', $fragment)); + } + $clone = clone $this; + $clone->fragment = $fragment; + return $clone; } /** @@ -490,12 +534,6 @@ public function __toString() private function getDefaultPort($scheme) { - switch ($scheme) { - case 'http': - return 80; - case 'https': - return 443; - } - return null; + return isset(Scheme::$defaultPort[$scheme]) ? Scheme::$defaultPort[$scheme] : null; } } diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 141a384..ae34b14 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -24,12 +24,33 @@ namespace Matricali\Http; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; +use Psr\Http\Message\RequestInterface; /** - * @covers Matricali\Http\Client + * @author Gabriel Polverini + * + * @group Client */ class ClientTest extends TestCase { + /** + * @test + * + * @expectedException Matricali\Http\Client\Exception + */ + public function testSendRequest() + { + $client = new Client(); + $request = $this->prophesize(RequestInterface::class); + $request->getUri()->willReturn('http://404.php.net/'); + $request->getMethod()->willReturn(HttpMethod::GET); + $client->sendRequest($request->reveal()); + } + + /** + * @test + */ public function testBasicGet() { $client = new Client(); @@ -40,6 +61,9 @@ public function testBasicGet() $this->assertNotEmpty($response->getBody()); } + /** + * @test + */ public function testBasicHead() { $client = new Client(); @@ -50,13 +74,87 @@ public function testBasicHead() $this->assertEmpty($response->getBody()); } + /** + * @test + */ public function testBasicPost() { $client = new Client(); $response = $client->post('http://www.google.com/', 'test=test&a=b'); $this->assertEquals(405, $response->getStatusCode()); - // $this->assertContains('private', $response->getHeader('Cache-Control')); $this->assertEquals('1.1', $response->getProtocolVersion()); $this->assertNotEmpty($response->getBody()); } + + /** + * @test + */ + public function testBasicPut() + { + $client = new Client(); + $response = $client->put('http://www.google.com/', 'test=test&a=b'); + $this->assertEquals(411, $response->getStatusCode()); + $this->assertEquals('1.0', $response->getProtocolVersion()); + $this->assertNotEmpty($response->getBody()); + } + + /** + * @test + */ + public function testBasicDelete() + { + $client = new Client(); + $response = $client->delete('http://www.google.com/', 'test=test&a=b'); + $this->assertEquals(405, $response->getStatusCode()); + $this->assertEquals('1.1', $response->getProtocolVersion()); + $this->assertNotEmpty($response->getBody()); + } + + /** + * @test + */ + public function testBasicPatch() + { + $client = new Client(); + $response = $client->patch('http://www.google.com/', 'test=test&a=b'); + $this->assertEquals(405, $response->getStatusCode()); + $this->assertEquals('1.1', $response->getProtocolVersion()); + $this->assertNotEmpty($response->getBody()); + } + + /** + * @test + */ + public function testClone() + { + $client = new Client(); + $clientCloned = clone $client; + $this->assertEquals($client, $clientCloned); + } + + /** + * @test + */ + public function testParseHeaderEmpty() + { + $client = new Client(); + $reflection = new \ReflectionClass($client); + $method = $reflection->getMethod('parseHeaders'); + $method->setAccessible(true); + + $this->assertEquals([], $method->invoke($client, '')); + } + + /** + * @test + */ + public function testParseHeaderNotArray() + { + $client = new Client(); + $reflection = new \ReflectionClass($client); + $method = $reflection->getMethod('parseHeaders'); + $method->setAccessible(true); + + $this->assertFalse($method->invoke($client, 123)); + } } diff --git a/tests/HttpMethodTest.php b/tests/HttpMethodTest.php new file mode 100644 index 0000000..43d2078 --- /dev/null +++ b/tests/HttpMethodTest.php @@ -0,0 +1,329 @@ + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +namespace Matricali\Http; + +use PHPUnit\Framework\TestCase; + +/** + * @author Gabriel Polverini + * + * @group Enums + */ +class HttpMethodTest extends TestCase +{ + const NAME_GET = 'GET'; + const NAME_POST = 'POST'; + const NAME_PUT = 'PUT'; + const NAME_HEAD = 'HEAD'; + const NAME_DELETE = 'DELETE'; + const NAME_PATCH = 'PATCH'; + const NAME_CONNECT = 'CONNECT'; + const NAME_OPTIONS = 'OPTIONS'; + const NAME_TRACE = 'TRACE'; + const NAME_NOTEXIST = ''; + + protected $httpMethod; + + public function setUp() + { + $this->httpMethod = $this->getMockForAbstractClass(HttpMethod::class); + } + + /** + * @test + */ + public function testIsValidNameGet() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_GET)); + } + + /** + * @test + */ + public function testGetByNameGet() + { + $value = $this->httpMethod->getByName(self::NAME_GET); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameGet + * + * @param string $value + */ + public function testIsValidValueGet($value) + { + $this->assertTrue($this->httpMethod->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNamePost() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_POST)); + } + + /** + * @test + */ + public function testGetByNamePost() + { + $value = $this->httpMethod->getByName(self::NAME_POST); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNamePost + * + * @param string $value + */ + public function testIsValidValuePost($value) + { + $this->assertTrue($this->httpMethod->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNamePut() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_PUT)); + } + + /** + * @test + */ + public function testGetByNamePut() + { + $value = $this->httpMethod->getByName(self::NAME_PUT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNamePut + * + * @param string $value + */ + public function testIsValidValuePut($value) + { + $this->assertTrue($this->httpMethod->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHead() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_HEAD)); + } + + /** + * @test + */ + public function testGetByNameHead() + { + $value = $this->httpMethod->getByName(self::NAME_HEAD); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHead + * + * @param string $value + */ + public function testIsValidValueHead($value) + { + $this->assertTrue($this->httpMethod->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameDelete() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_DELETE)); + } + + /** + * @test + */ + public function testGetByNameDelete() + { + $value = $this->httpMethod->getByName(self::NAME_DELETE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameDelete + * + * @param string $value + */ + public function testIsValidValueDelete($value) + { + $this->assertTrue($this->httpMethod->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNamePatch() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_PATCH)); + } + + /** + * @test + */ + public function testGetByNamePatch() + { + $value = $this->httpMethod->getByName(self::NAME_PATCH); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNamePatch + * + * @param string $value + */ + public function testIsValidValuePatch($value) + { + $this->assertTrue($this->httpMethod->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameConnect() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_CONNECT)); + } + + /** + * @test + */ + public function testGetByNameConnect() + { + $value = $this->httpMethod->getByName(self::NAME_CONNECT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameConnect + * + * @param string $value + */ + public function testIsValidValueConnect($value) + { + $this->assertTrue($this->httpMethod->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameOptions() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_OPTIONS)); + } + + /** + * @test + */ + public function testGetByNameOptions() + { + $value = $this->httpMethod->getByName(self::NAME_OPTIONS); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameOptions + * + * @param string $value + */ + public function testIsValidValueOptions($value) + { + $this->assertTrue($this->httpMethod->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameTrace() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_TRACE)); + } + + /** + * @test + */ + public function testGetByNameTrace() + { + $value = $this->httpMethod->getByName(self::NAME_TRACE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameTrace + * + * @param string $value + */ + public function testIsValidValueTrace($value) + { + $this->assertTrue($this->httpMethod->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameStrictTrue() + { + $this->assertTrue($this->httpMethod->isValidName(self::NAME_GET, true)); + } + + /** + * @test + */ + public function testGetByNameNotExist() + { + $this->assertNull($this->httpMethod->getByName(self::NAME_NOTEXIST)); + } +} \ No newline at end of file diff --git a/tests/HttpStatusCodeTest.php b/tests/HttpStatusCodeTest.php new file mode 100644 index 0000000..4018d85 --- /dev/null +++ b/tests/HttpStatusCodeTest.php @@ -0,0 +1,1980 @@ + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +namespace Matricali\Http; + +use PHPUnit\Framework\TestCase; + +/** + * @author Gabriel Polverini + * + * @group Enums + */ +class HttpStatusCodeTest extends TestCase +{ + const NAME_HTTP_CONTINUE = 'HTTP_CONTINUE'; + const NAME_HTTP_SWITCHING_PROTOCOLS = 'HTTP_SWITCHING_PROTOCOLS'; + const NAME_HTTP_PROCESSING = 'HTTP_PROCESSING'; + const NAME_HTTP_EARLY_HINTS = 'HTTP_EARLY_HINTS'; + const NAME_HTTP_OK = 'HTTP_OK'; + const NAME_HTTP_CREATED = 'HTTP_CREATED'; + const NAME_HTTP_ACCEPTED = 'HTTP_ACCEPTED'; + const NAME_HTTP_NON_AUTHORITATIVE_INFORMATION = 'HTTP_NON_AUTHORITATIVE_INFORMATION'; + const NAME_HTTP_NO_CONTENT = 'HTTP_NO_CONTENT'; + const NAME_HTTP_RESET_CONTENT = 'HTTP_RESET_CONTENT'; + const NAME_HTTP_PARTIAL_CONTENT = 'HTTP_PARTIAL_CONTENT'; + const NAME_HTTP_MULTI_STATUS = 'HTTP_MULTI_STATUS'; + const NAME_HTTP_ALREADY_REPORTED = 'HTTP_ALREADY_REPORTED'; + const NAME_HTTP_IM_USED = 'HTTP_IM_USED'; + const NAME_HTTP_MULTIPLE_CHOICES = 'HTTP_MULTIPLE_CHOICES'; + const NAME_HTTP_MOVED_PERMANENTLY = 'HTTP_MOVED_PERMANENTLY'; + const NAME_HTTP_FOUND = 'HTTP_FOUND'; + const NAME_HTTP_SEE_OTHER = 'HTTP_SEE_OTHER'; + const NAME_HTTP_NOT_MODIFIED = 'HTTP_NOT_MODIFIED'; + const NAME_HTTP_USE_PROXY = 'HTTP_USE_PROXY'; + const NAME_HTTP_RESERVED = 'HTTP_RESERVED'; + const NAME_HTTP_TEMPORARY_REDIRECT = 'HTTP_TEMPORARY_REDIRECT'; + const NAME_HTTP_PERMANENTLY_REDIRECT = 'HTTP_PERMANENTLY_REDIRECT'; + const NAME_HTTP_BAD_REQUEST = 'HTTP_BAD_REQUEST'; + const NAME_HTTP_UNAUTHORIZED = 'HTTP_UNAUTHORIZED'; + const NAME_HTTP_PAYMENT_REQUIRED = 'HTTP_PAYMENT_REQUIRED'; + const NAME_HTTP_FORBIDDEN = 'HTTP_FORBIDDEN'; + const NAME_HTTP_NOT_FOUND = 'HTTP_NOT_FOUND'; + const NAME_HTTP_METHOD_NOT_ALLOWED = 'HTTP_METHOD_NOT_ALLOWED'; + const NAME_HTTP_NOT_ACCEPTABLE = 'HTTP_NOT_ACCEPTABLE'; + const NAME_HTTP_PROXY_AUTHENTICATION_REQUIRED = 'HTTP_PROXY_AUTHENTICATION_REQUIRED'; + const NAME_HTTP_REQUEST_TIMEOUT = 'HTTP_REQUEST_TIMEOUT'; + const NAME_HTTP_CONFLICT = 'HTTP_CONFLICT'; + const NAME_HTTP_GONE = 'HTTP_GONE'; + const NAME_HTTP_LENGTH_REQUIRED = 'HTTP_LENGTH_REQUIRED'; + const NAME_HTTP_PRECONDITION_FAILED = 'HTTP_PRECONDITION_FAILED'; + const NAME_HTTP_REQUEST_ENTITY_TOO_LARGE = 'HTTP_REQUEST_ENTITY_TOO_LARGE'; + const NAME_HTTP_REQUEST_URI_TOO_LONG = 'HTTP_REQUEST_URI_TOO_LONG'; + const NAME_HTTP_UNSUPPORTED_MEDIA_TYPE = 'HTTP_UNSUPPORTED_MEDIA_TYPE'; + const NAME_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 'HTTP_REQUESTED_RANGE_NOT_SATISFIABLE'; + const NAME_HTTP_EXPECTATION_FAILED = 'HTTP_EXPECTATION_FAILED'; + const NAME_HTTP_I_AM_A_TEAPOT = 'HTTP_I_AM_A_TEAPOT'; + const NAME_HTTP_MISDIRECTED_REQUEST = 'HTTP_MISDIRECTED_REQUEST'; + const NAME_HTTP_UNPROCESSABLE_ENTITY = 'HTTP_UNPROCESSABLE_ENTITY'; + const NAME_HTTP_LOCKED = 'HTTP_LOCKED'; + const NAME_HTTP_FAILED_DEPENDENCY = 'HTTP_FAILED_DEPENDENCY'; + const NAME_HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 'HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL'; + const NAME_HTTP_TOO_EARLY = 'HTTP_TOO_EARLY'; + const NAME_HTTP_UPGRADE_REQUIRED = 'HTTP_UPGRADE_REQUIRED'; + const NAME_HTTP_PRECONDITION_REQUIRED = 'HTTP_PRECONDITION_REQUIRED'; + const NAME_HTTP_TOO_MANY_REQUESTS = 'HTTP_TOO_MANY_REQUESTS'; + const NAME_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 'HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE'; + const NAME_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 'HTTP_UNAVAILABLE_FOR_LEGAL_REASONS'; + const NAME_HTTP_INTERNAL_SERVER_ERROR = 'HTTP_INTERNAL_SERVER_ERROR'; + const NAME_HTTP_NOT_IMPLEMENTED = 'HTTP_NOT_IMPLEMENTED'; + const NAME_HTTP_BAD_GATEWAY = 'HTTP_BAD_GATEWAY'; + const NAME_HTTP_SERVICE_UNAVAILABLE = 'HTTP_SERVICE_UNAVAILABLE'; + const NAME_HTTP_GATEWAY_TIMEOUT = 'HTTP_GATEWAY_TIMEOUT'; + const NAME_HTTP_VERSION_NOT_SUPPORTED = 'HTTP_VERSION_NOT_SUPPORTED'; + const NAME_HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 'HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL'; + const NAME_HTTP_INSUFFICIENT_STORAGE = 'HTTP_INSUFFICIENT_STORAGE'; + const NAME_HTTP_LOOP_DETECTED = 'HTTP_LOOP_DETECTED'; + const NAME_HTTP_NOT_EXTENDED = 'HTTP_NOT_EXTENDED'; + const NAME_HTTP_NETWORK_AUTHENTICATION_REQUIRED = 'HTTP_NETWORK_AUTHENTICATION_REQUIRED'; + const NAME_NOTEXIST = ''; + + protected $httpStatusCode; + + public function setUp() + { + $this->httpStatusCode = $this->getMockForAbstractClass(HttpStatusCode::class); + } + + /** + * @test + */ + public function testIsValidNameHttpContinue() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_CONTINUE)); + } + + /** + * @test + */ + public function testGetByNameHttpContinue() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_CONTINUE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpContinue + * + * @param string $value + */ + public function testIsValidValueHttpContinue($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpSwitchingProtocols() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_SWITCHING_PROTOCOLS)); + } + + /** + * @test + */ + public function testGetByNameHttpSwitchingProtocols() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_SWITCHING_PROTOCOLS); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpSwitchingProtocols + * + * @param string $value + */ + public function testIsValidValueHttpSwitchingProtocols($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpProcessing() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_PROCESSING)); + } + + /** + * @test + */ + public function testGetByNameHttpProcessing() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_PROCESSING); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpProcessing + * + * @param string $value + */ + public function testIsValidValueHttpProcessing($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpEarlyHints() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_EARLY_HINTS)); + } + + /** + * @test + */ + public function testGetByNameHttpEarlyHints() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_EARLY_HINTS); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpEarlyHints + * + * @param string $value + */ + public function testIsValidValueHttpEarlyHints($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpOk() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_OK)); + } + + /** + * @test + */ + public function testGetByNameHttpOk() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_OK); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpOk + * + * @param string $value + */ + public function testIsValidValueHttpOk($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpCreated() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_CREATED)); + } + + /** + * @test + */ + public function testGetByNameHttpCreated() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_CREATED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpCreated + * + * @param string $value + */ + public function testIsValidValueHttpCreated($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpAccepted() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_ACCEPTED)); + } + + /** + * @test + */ + public function testGetByNameHttpAccepted() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_ACCEPTED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpAccepted + * + * @param string $value + */ + public function testIsValidValueHttpAccepted($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpNonAuthoritativeInformation() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_NON_AUTHORITATIVE_INFORMATION)); + } + + /** + * @test + */ + public function testGetByNameHttpNonAuthoritativeInformation() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_NON_AUTHORITATIVE_INFORMATION); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpNonAuthoritativeInformation + * + * @param string $value + */ + public function testIsValidValueHttpNonAuthoritativeInformation($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpNoContent() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_NO_CONTENT)); + } + + /** + * @test + */ + public function testGetByNameHttpNoContent() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_NO_CONTENT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpNoContent + * + * @param string $value + */ + public function testIsValidValueHttpNoContent($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpResetContent() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_RESET_CONTENT)); + } + + /** + * @test + */ + public function testGetByNameHttpResetContent() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_RESET_CONTENT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpResetContent + * + * @param string $value + */ + public function testIsValidValueHttpResetContent($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttPartialContent() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_PARTIAL_CONTENT)); + } + + /** + * @test + */ + public function testGetByNameHttpPartialContent() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_PARTIAL_CONTENT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpPartialContent + * + * @param string $value + */ + public function testIsValidValueHttpPartialContent($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpMultiStatus() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_MULTI_STATUS)); + } + + /** + * @test + */ + public function testGetByNameHttpMultiStatus() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_MULTI_STATUS); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpMultiStatus + * + * @param string $value + */ + public function testIsValidValueHttpMultiStatus($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpAlreadyReported() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_ALREADY_REPORTED)); + } + + /** + * @test + */ + public function testGetByNameHttpAlreadyReported() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_ALREADY_REPORTED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpAlreadyReported + * + * @param string $value + */ + public function testIsValidValueHttpAlreadyReported($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpImUsed() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_IM_USED)); + } + + /** + * @test + */ + public function testGetByNameHttpImUsed() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_IM_USED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpImUsed + * + * @param string $value + */ + public function testIsValidValueHttpImUsed($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpMultipleChoices() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_MULTIPLE_CHOICES)); + } + + /** + * @test + */ + public function testGetByNameHttpMultipleChoices() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_MULTIPLE_CHOICES); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpMultipleChoices + * + * @param string $value + */ + public function testIsValidValueHttpMultipleChoices($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpMovedPermanently() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_MOVED_PERMANENTLY)); + } + + /** + * @test + */ + public function testGetByNameHttpMovedPermanently() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_MOVED_PERMANENTLY); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpMovedPermanently + * + * @param string $value + */ + public function testIsValidValueHttpMovedPermanently($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpFound() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_FOUND)); + } + + /** + * @test + */ + public function testGetByNameHttpFound() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_FOUND); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpFound + * + * @param string $value + */ + public function testIsValidValueHttpFound($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpSeeOther() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_SEE_OTHER)); + } + + /** + * @test + */ + public function testGetByNameHttpSeeOther() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_SEE_OTHER); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpSeeOther + * + * @param string $value + */ + public function testIsValidValueHttpSeeOther($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpNotModified() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_NOT_MODIFIED)); + } + + /** + * @test + */ + public function testGetByNameHttpNotModified() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_NOT_MODIFIED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpNotModified + * + * @param string $value + */ + public function testIsValidValueHttpNotModified($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpUseProxy() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_USE_PROXY)); + } + + /** + * @test + */ + public function testGetByNameHttpUseProxy() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_USE_PROXY); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpUseProxy + * + * @param string $value + */ + public function testIsValidValueHttpUseProxy($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpReserved() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_RESERVED)); + } + + /** + * @test + */ + public function testGetByNameHttpReserved() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_RESERVED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpReserved + * + * @param string $value + */ + public function testIsValidValueHttpReserved($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpTemporaryRedirect() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_TEMPORARY_REDIRECT)); + } + + /** + * @test + */ + public function testGetByNameHttpTemporaryRedirect() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_TEMPORARY_REDIRECT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpTemporaryRedirect + * + * @param string $value + */ + public function testIsValidValueHttpTemporaryRedirect($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpPermanentlyRedirect() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_PERMANENTLY_REDIRECT)); + } + + /** + * @test + */ + public function testGetByNameHttpPermanentlyRedirect() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_PERMANENTLY_REDIRECT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpPermanentlyRedirect + * + * @param string $value + */ + public function testIsValidValueHttpPermanentlyRedirect($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpBadRequest() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_BAD_REQUEST)); + } + + /** + * @test + */ + public function testGetByNameHttpBadRequest() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_BAD_REQUEST); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpBadRequest + * + * @param string $value + */ + public function testIsValidValueHttpBadRequest($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpUnauthorized() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_UNAUTHORIZED)); + } + + /** + * @test + */ + public function testGetByNameHttpUnauthorized() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_UNAUTHORIZED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpUnauthorized + * + * @param string $value + */ + public function testIsValidValueHttpUnauthorized($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpPaymentRequired() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_PAYMENT_REQUIRED)); + } + + /** + * @test + */ + public function testGetByNameHttpPaymentRequired() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_PAYMENT_REQUIRED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpPaymentRequired + * + * @param string $value + */ + public function testIsValidValueHttpPaymentRequired($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpForbidden() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_FORBIDDEN)); + } + + /** + * @test + */ + public function testGetByNameHttpForbidden() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_FORBIDDEN); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpForbidden + * + * @param string $value + */ + public function testIsValidValueHttpForbidden($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpNotFound() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_NOT_FOUND)); + } + + /** + * @test + */ + public function testGetByNameHttpNotFound() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_NOT_FOUND); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpNotFound + * + * @param string $value + */ + public function testIsValidValueHttpNotFound($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpMethodNotAllowed() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_METHOD_NOT_ALLOWED)); + } + + /** + * @test + */ + public function testGetByNameHttpMethodNotAllowed() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_METHOD_NOT_ALLOWED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpMethodNotAllowed + * + * @param string $value + */ + public function testIsValidValueHttpMethodNotAllowed($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpNotAcceptable() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_NOT_ACCEPTABLE)); + } + + /** + * @test + */ + public function testGetByNameHttpNotAcceptable() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_NOT_ACCEPTABLE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpNotAcceptable + * + * @param string $value + */ + public function testIsValidValueHttpNotAcceptable($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpProxyAuthenticationRequired() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_PROXY_AUTHENTICATION_REQUIRED)); + } + + /** + * @test + */ + public function testGetByNameHttpProxyAuthenticationRequired() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_PROXY_AUTHENTICATION_REQUIRED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpProxyAuthenticationRequired + * + * @param string $value + */ + public function testIsValidValueHttpProxyAuthenticationRequired($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpRequestTimeout() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_REQUEST_TIMEOUT)); + } + + /** + * @test + */ + public function testGetByNameHttpRequestTimeout() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_REQUEST_TIMEOUT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpRequestTimeout + * + * @param string $value + */ + public function testIsValidValueHttpRequestTimeout($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpConflict() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_CONFLICT)); + } + + /** + * @test + */ + public function testGetByNameHttpConflict() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_CONFLICT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpConflict + * + * @param string $value + */ + public function testIsValidValueHttpConflict($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpGone() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_GONE)); + } + + /** + * @test + */ + public function testGetByNameHttpGone() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_GONE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpGone + * + * @param string $value + */ + public function testIsValidValueHttpGone($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpLengthRequired() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_LENGTH_REQUIRED)); + } + + /** + * @test + */ + public function testGetByNameHttpLengthRequired() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_LENGTH_REQUIRED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpLengthRequired + * + * @param string $value + */ + public function testIsValidValueHttpLengthRequired($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpPreconditionFailed() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_PRECONDITION_FAILED)); + } + + /** + * @test + */ + public function testGetByNameHttpPreconditionFailed() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_PRECONDITION_FAILED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpPreconditionFailed + * + * @param string $value + */ + public function testIsValidValueHttpPreconditionFailed($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpRequestEntityTooLarge() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_REQUEST_ENTITY_TOO_LARGE)); + } + + /** + * @test + */ + public function testGetByNameHttpRequestEntityTooLarge() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_REQUEST_ENTITY_TOO_LARGE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpRequestEntityTooLarge + * + * @param string $value + */ + public function testIsValidValueHttpRequestEntityTooLarge($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpRequestUriTooLong() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_REQUEST_URI_TOO_LONG)); + } + + /** + * @test + */ + public function testGetByNameHttpRequestUriTooLong() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_REQUEST_URI_TOO_LONG); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpRequestUriTooLong + * + * @param string $value + */ + public function testIsValidValueHttpRequestUriTooLong($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpUnsupportedMediaType() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_UNSUPPORTED_MEDIA_TYPE)); + } + + /** + * @test + */ + public function testGetByNameHttpUnsupportedMediaType() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_UNSUPPORTED_MEDIA_TYPE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpUnsupportedMediaType + * + * @param string $value + */ + public function testIsValidValueHttpUnsupportedMediaType($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpRequestedRangeNotSatistiable() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE)); + } + + /** + * @test + */ + public function testGetByNameHttpRequestedRangeNotSatistiable() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_REQUESTED_RANGE_NOT_SATISFIABLE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpRequestedRangeNotSatistiable + * + * @param string $value + */ + public function testIsValidValueHttpRequestedRangeNotSatistiable($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpExpectationFailed() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_EXPECTATION_FAILED)); + } + + /** + * @test + */ + public function testGetByNameHttpExpectationFailed() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_EXPECTATION_FAILED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpExpectationFailed + * + * @param string $value + */ + public function testIsValidValueHttpExpectationFailed($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpIAmATeapot() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_I_AM_A_TEAPOT)); + } + + /** + * @test + */ + public function testGetByNameHttpIAmATeapot() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_I_AM_A_TEAPOT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpIAmATeapot + * + * @param string $value + */ + public function testIsValidValueHttpIAmATeapot($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpMisdirectedRequest() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_MISDIRECTED_REQUEST)); + } + + /** + * @test + */ + public function testGetByNameHttpMisdirectedRequest() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_MISDIRECTED_REQUEST); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpMisdirectedRequest + * + * @param string $value + */ + public function testIsValidValueHttpMisdirectedRequest($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpUnprocessableEntity() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_UNPROCESSABLE_ENTITY)); + } + + /** + * @test + */ + public function testGetByNameHttpUnprocessableEntity() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_UNPROCESSABLE_ENTITY); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpUnprocessableEntity + * + * @param string $value + */ + public function testIsValidValueHttpUnprocessableEntity($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpLocked() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_LOCKED)); + } + + /** + * @test + */ + public function testGetByNameHttpLocked() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_LOCKED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpLocked + * + * @param string $value + */ + public function testIsValidValueHttpLocked($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpFailedDependency() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_FAILED_DEPENDENCY)); + } + + /** + * @test + */ + public function testGetByNameHttpFailedDependency() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_FAILED_DEPENDENCY); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpFailedDependency + * + * @param string $value + */ + public function testIsValidValueHttpFailedDependency($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpReservedForWebdavAdvancedCollectionsExpiredProposal() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL)); + } + + /** + * @test + */ + public function testGetByNameHttpReservedForWebdavAdvancedCollectionsExpiredProposal() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpReservedForWebdavAdvancedCollectionsExpiredProposal + * + * @param string $value + */ + public function testIsValidValueHttpReservedForWebdavAdvancedCollectionsExpiredProposal($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpTooEarly() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_TOO_EARLY)); + } + + /** + * @test + */ + public function testGetByNameHttpTooEarly() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_TOO_EARLY); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpTooEarly + * + * @param string $value + */ + public function testIsValidValueHttpTooEarly($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpUpgradeRequired() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_UPGRADE_REQUIRED)); + } + + /** + * @test + */ + public function testGetByNameHttpUpgradeRequired() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_UPGRADE_REQUIRED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpUpgradeRequired + * + * @param string $value + */ + public function testIsValidValueHttpUpgradeRequired($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpPreconditionRequired() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_PRECONDITION_REQUIRED)); + } + + /** + * @test + */ + public function testGetByNameHttpPreconditionRequired() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_PRECONDITION_REQUIRED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpPreconditionRequired + * + * @param string $value + */ + public function testIsValidValueHttpPreconditionRequired($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpTooManyRequests() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_TOO_MANY_REQUESTS)); + } + + /** + * @test + */ + public function testGetByNameHttpTooManyRequests() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_TOO_MANY_REQUESTS); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpTooManyRequests + * + * @param string $value + */ + public function testIsValidValueHttpTooManyRequests($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpRequestHeaderFieldsTooLarge() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE)); + } + + /** + * @test + */ + public function testGetByNameHttpRequestHeaderFieldsTooLarge() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpRequestHeaderFieldsTooLarge + * + * @param string $value + */ + public function testIsValidValueHttpRequestHeaderFieldsTooLarge($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpUnavailableForLegalReasons() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)); + } + + /** + * @test + */ + public function testGetByNameHttpUnavailableForLegalReasons() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpUnavailableForLegalReasons + * + * @param string $value + */ + public function testIsValidValueHttpUnavailableForLegalReasons($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpInternalServerError() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_INTERNAL_SERVER_ERROR)); + } + + /** + * @test + */ + public function testGetByNameHttpInternalServerError() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_INTERNAL_SERVER_ERROR); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpInternalServerError + * + * @param string $value + */ + public function testIsValidValueHttpInternalServerError($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpNotImplemented() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_NOT_IMPLEMENTED)); + } + + /** + * @test + */ + public function testGetByNameHttpNotImplemented() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_NOT_IMPLEMENTED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpNotImplemented + * + * @param string $value + */ + public function testIsValidValueHttpNotImplemented($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpBadGateway() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_BAD_GATEWAY)); + } + + /** + * @test + */ + public function testGetByNameHttpBadGateway() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_BAD_GATEWAY); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpBadGateway + * + * @param string $value + */ + public function testIsValidValueHttpBadGateway($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpServiceUnavailable() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_SERVICE_UNAVAILABLE)); + } + + /** + * @test + */ + public function testGetByNameHttpServiceUnavailable() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_SERVICE_UNAVAILABLE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpServiceUnavailable + * + * @param string $value + */ + public function testIsValidValueHttpServiceUnavailable($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpGatewayTimeout() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_GATEWAY_TIMEOUT)); + } + + /** + * @test + */ + public function testGetByNameHttpGatewayTimeout() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_GATEWAY_TIMEOUT); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpGatewayTimeout + * + * @param string $value + */ + public function testIsValidValueHttpGatewayTimeout($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpVersionNotSupported() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_VERSION_NOT_SUPPORTED)); + } + + /** + * @test + */ + public function testGetByNameHttpVersionNotSupported() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_VERSION_NOT_SUPPORTED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpVersionNotSupported + * + * @param string $value + */ + public function testIsValidValueHttpVersionNotSupported($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpVariantAlsoNegotiatesExperimental() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL)); + } + + /** + * @test + */ + public function testGetByNameHttpVariantAlsoNegotiatesExperimental() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpVariantAlsoNegotiatesExperimental + * + * @param string $value + */ + public function testIsValidValueHttpVariantAlsoNegotiatesExperimental($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpInsufficientStorage() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_INSUFFICIENT_STORAGE)); + } + + /** + * @test + */ + public function testGetByNameHttpInsufficientStorage() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_INSUFFICIENT_STORAGE); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpInsufficientStorage + * + * @param string $value + */ + public function testIsValidValueHttpInsufficientStorage($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpLoopDetected() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_LOOP_DETECTED)); + } + + /** + * @test + */ + public function testGetByNameHttpLoopDetected() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_LOOP_DETECTED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpLoopDetected + * + * @param string $value + */ + public function testIsValidValueHttpLoopDetected($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttpNotExtended() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_NOT_EXTENDED)); + } + + /** + * @test + */ + public function testGetByNameHttpNotExtended() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_NOT_EXTENDED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpNotExtended + * + * @param string $value + */ + public function testIsValidValueHttpNotExtended($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + + /** + * @test + */ + public function testIsValidNameHttpNetworkAuthenticationRequired() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_NETWORK_AUTHENTICATION_REQUIRED)); + } + + /** + * @test + */ + public function testGetByNameHttpNetworkAuthenticationRequired() + { + $value = $this->httpStatusCode->getByName(self::NAME_HTTP_NETWORK_AUTHENTICATION_REQUIRED); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttpNetworkAuthenticationRequired + * + * @param string $value + */ + public function testIsValidValueHttpNetworkAuthenticationRequired($value) + { + $this->assertTrue($this->httpStatusCode->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameStrictTrue() + { + $this->assertTrue($this->httpStatusCode->isValidName(self::NAME_HTTP_CONTINUE, true)); + } + + /** + * @test + */ + public function testGetByNameNotExist() + { + $this->assertNull($this->httpStatusCode->getByName(self::NAME_NOTEXIST)); + } +} \ No newline at end of file diff --git a/tests/RequestTest.php b/tests/RequestTest.php index 9375bfc..caf85cc 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -24,52 +24,343 @@ namespace Matricali\Http; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; +use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UriInterface; /** - * @covers Matricali\Http\Request + * @author Gabriel Polverini + * + * @group Request */ class RequestTest extends TestCase { - public function testBasicTest() + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testInstanceInvalidMethodParam() { + new Request('NONE'); + } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testInstanceInvalidBodyParam() + { + new Request(HttpMethod::GET, '', [], 1); + } + + /** + * @test + * + * @throws \InvalidArgumentException + * @throws \ReflectionException + */ + public function testSearchHeader() + { + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', + ]; + $request = new Request(HttpMethod::GET, '', $headers); + + $reflection = new \ReflectionClass($request); + $method = $reflection->getMethod('searchHeader'); + $method->setAccessible(true); + $this->assertFalse($method->invoke($request, 'Content-Encoding')); + $this->assertFalse($method->invoke($request, 'content-encoding')); + $expected = 'Accept'; + $this->assertEquals($expected, $method->invoke($request, 'Accept')); + $this->assertEquals($expected, $method->invoke($request, 'accept')); + $expected = 'Content-Type'; + $this->assertEquals($expected, $method->invoke($request, 'Content-Type')); + $this->assertEquals($expected, $method->invoke($request, 'content-type')); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testGetRequestTarget() + { + $request = new Request(HttpMethod::GET, ''); + $this->assertEquals('/', $request->getRequestTarget()); + $uri = 'https://www.google.com/'; - $headers = []; - $request = new Request('GET', $uri, $headers); - $this->assertEquals($uri, (string) $request->getUri()); - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals($headers, $request->getHeaders()); - $this->assertEquals('1.1', $request->getProtocolVersion()); - $this->assertEquals('', $request->getBody()); + $request = new Request(HttpMethod::GET, $uri); $this->assertEquals($uri, $request->getRequestTarget()); + } - $request = new Request('HEAD', ''); - $this->assertEquals('HEAD', $request->getMethod()); - $this->assertEquals('/', $request->getRequestTarget()); + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testWithRequestTarget() + { + $headers = ['Accept' => ['application/json']]; + $request = new Request(HttpMethod::GET, '', $headers); + $this->assertEquals($request->getRequestTarget(), $request->withRequestTarget('')->getRequestTarget()); } - public function testHeaders() + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testGetMethod() + { + $method = HttpMethod::GET; + $request = new Request($method); + $this->assertEquals($method, $request->getMethod()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testWithMethod() + { + $request = new Request(); + $this->assertEquals($request->getMethod(), $request->withMethod(HttpMethod::GET)->getMethod()); + } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testWithInvalidMethod() + { + $request = new Request(); + $this->assertEquals($request->getMethod(), $request->withMethod('NONE')->getMethod()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testGetUri() { $uri = 'https://www.google.com/'; + $request = new Request(HttpMethod::GET, $uri); + $this->assertEquals($uri, $request->getUri()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testWithUri() + { + $uri = 'www.google.com'; + $uriInterface = $this->prophesize(UriInterface::class); + $uriInterface->__toString()->willReturn($uri); + $request = new Request(HttpMethod::GET, $uri); + $this->assertEquals($request->getUri(), (string) $request->withUri($uriInterface->reveal())->getUri()); + $uriInterface->__toString()->willReturn('www.example.com'); + $this->assertNotEquals($request->getUri(), (string) $request->withUri($uriInterface->reveal())->getUri()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testGetProtocolVersion() + { + $request = new Request(); + $this->assertEquals('1.1', $request->getProtocolVersion()); + $protocolVersion = '1.0'; + $this->assertEquals($protocolVersion, $request->withProtocolVersion($protocolVersion)->getProtocolVersion()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testWithProtocolVersion() + { + $request = new Request(); + $protocolVersion = $request->getProtocolVersion(); + $this->assertEquals($protocolVersion, $request->withProtocolVersion('1.1')->getProtocolVersion()); + $this->assertNotEquals($protocolVersion, $request->withProtocolVersion('1.0')->getProtocolVersion()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testGetHeaders() + { + $this->assertTrue(is_array((new Request())->getHeaders())); + $headers = [ - 'Accept' => 'application/json' + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', ]; - $headers2 = [ - 'Accept' => [ - 'application/json' - ] + $expected = [ + 'Accept' => ['application/json'], + 'Content-Type' => ['text/xml;charset=UTF-8'], + ]; + $this->assertEquals($expected, (new Request(HttpMethod::GET, '', $headers))->getHeaders()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testHasHeader() + { + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', ]; - $request = new Request('GET', $uri, $headers); - $this->assertEquals($uri, (string) $request->getUri()); - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals($headers2, $request->getHeaders()); + $request = new Request(HttpMethod::GET, '', $headers); + $this->assertFalse($request->hasHeader('Content-Encoding')); + $this->assertFalse($request->hasHeader('content-encoding')); $this->assertTrue($request->hasHeader('Accept')); - $this->assertFalse($request->hasHeader('Authorization')); - $this->assertEquals([$headers['Accept']], $request->getHeader('Accept')); - $this->assertEquals([], $request->getHeader('Authorization')); - $this->assertEquals($headers['Accept'], $request->getHeaderLine('Accept')); - $this->assertEquals('', $request->getHeaderLine('Authorization')); - - $request = new Request('GET', '', $headers2); - $this->assertEquals($headers2, $request->getHeaders()); + $this->assertTrue($request->hasHeader('accept')); + $this->assertTrue($request->hasHeader('Content-Type')); + $this->assertTrue($request->hasHeader('content-type')); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testGetHeader() + { + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', + ]; + $request = new Request(HttpMethod::GET, '', $headers); + $expected = []; + $this->assertEquals($expected, $request->getHeader('Content-Encoding')); + $this->assertEquals($expected, $request->getHeader('content-encoding')); + $expected = ['application/json']; + $this->assertEquals($expected, $request->getHeader('Accept')); + $this->assertEquals($expected, $request->getHeader('accept')); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testGetHeaderLine() + { + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', + 'Cache-Control' => [ + 'no-transform', + 'public', + 'max-age=2678400', + 's-maxage=2678400', + ], + ]; + $request = new Request(HttpMethod::GET, '', $headers); + $expected = ''; + $this->assertEquals($expected, $request->getHeaderLine('Content-Encoding')); + $this->assertEquals($expected, $request->getHeaderLine('content-encoding')); + $expected = 'application/json'; + $this->assertEquals($expected, $request->getHeaderLine('Accept')); + $this->assertEquals($expected, $request->getHeaderLine('accept')); + $expected = 'text/xml;charset=UTF-8'; + $this->assertEquals($expected, $request->getHeaderLine('Content-Type')); + $this->assertEquals($expected, $request->getHeaderLine('content-type')); + $expected = implode(', ', $headers['Cache-Control']); + $this->assertEquals($expected, $request->getHeaderLine('Cache-Control')); + $this->assertEquals($expected, $request->getHeaderLine('cache-control')); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testWithHeader() + { + $headers = ['Accept' => ['application/json']]; + $request = new Request(HttpMethod::GET, '', $headers); + $expected = array_merge($headers, ['Content-Encoding' => ['gzip']]); + $this->assertEquals($expected, $request->withHeader('Content-Encoding', 'gzip')->getHeaders()); + $this->assertEquals($expected, $request->withHeader('Content-Encoding', ['gzip'])->getHeaders()); + $expected = ['Accept' => ['application/xml']]; + $this->assertEquals($expected, $request->withHeader('Accept', 'application/xml')->getHeaders()); + $this->assertEquals($expected, $request->withHeader('Accept', ['application/xml'])->getHeaders()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testWithAddedHeader() + { + $headers = ['Accept' => ['application/json']]; + $request = new Request(HttpMethod::GET, '', $headers); + $expected = array_merge($headers, ['Content-Encoding' => ['gzip']]); + $this->assertEquals($expected, $request->withAddedHeader('Content-Encoding', 'gzip')->getHeaders()); + $this->assertEquals($expected, $request->withAddedHeader('Content-Encoding', ['gzip'])->getHeaders()); + $expected = ['Accept' => ['application/json', 'application/xml']]; + $this->assertEquals($expected, $request->withAddedHeader('Accept', 'application/xml')->getHeaders()); + $this->assertEquals($expected, $request->withAddedHeader('Accept', ['application/xml'])->getHeaders()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testWithoutHeader() + { + $headers = ['Accept' => ['application/json'], 'Content-Encoding' => ['gzip']]; + $request = new Request(HttpMethod::GET, '', $headers); + $expected = $headers; + $this->assertEquals($expected, $request->withoutHeader('Cache-Control')->getHeaders()); + $expected = ['Content-Encoding' => ['gzip']]; + $this->assertEquals($expected, $request->withoutHeader('Accept')->getHeaders()); + $this->assertEquals($expected, $request->withoutHeader('accept')->getHeaders()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testGetBody() + { + $body = '{"message":"text"}'; + $request = new Request(HttpMethod::GET, '', [], $body); + $this->assertEquals($body, $request->getBody()); + } + + /** + * @test + * + * @throws \InvalidArgumentException + */ + public function testWithBody() + { + $body = '{"message":"text"}'; + $stream = $this->prophesize(StreamInterface::class); + $stream->__toString()->willReturn($body); + $this->assertEquals($body, (new Request())->withBody($stream->reveal())->getBody()); } } diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index 3b38f77..ed48257 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -24,19 +24,263 @@ namespace Matricali\Http; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\StreamInterface; /** - * @covers Matricali\Http\Response + * @author Gabriel Polverini + * + * @group Response */ class ResponseTest extends TestCase { - public function testEmptyUri() + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testInstanceInvalidStatusCodeParam() { - $response = new Response('{"message":"text"}', 200, ['Content-Type' => 'application/json']); - $this->assertEquals('{"message":"text"}', $response->getBody()); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals(['Content-Type' => 'application/json'], $response->getHeaders()); - $this->assertEquals('application/json', $response->getHeader('Content-Type')); + new Response('', -1); + } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testInstanceInvalidBodyParam() + { + new Response(1); + } + + /** + * @test + */ + public function testSearchHeader() + { + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', + ]; + $response = new Response('', 200, $headers); + + $reflection = new \ReflectionClass($response); + $method = $reflection->getMethod('searchHeader'); + $method->setAccessible(true); + $this->assertFalse($method->invoke($response, 'Content-Encoding')); + $this->assertFalse($method->invoke($response, 'content-encoding')); + $expected = 'Accept'; + $this->assertEquals($expected, $method->invoke($response, 'Accept')); + $this->assertEquals($expected, $method->invoke($response, 'accept')); + $expected = 'Content-Type'; + $this->assertEquals($expected, $method->invoke($response, 'Content-Type')); + $this->assertEquals($expected, $method->invoke($response, 'content-type')); + } + + /** + * @test + */ + public function testGetProtocolVersion() + { + $response = new Response(''); + $this->assertEquals('1.1', $response->getProtocolVersion()); + $protocolVersion = '1.0'; + $this->assertEquals($protocolVersion, $response->withProtocolVersion($protocolVersion)->getProtocolVersion()); + } + + /** + * @test + */ + public function testWithProtocolVersion() + { + $response = new Response(''); + $protocolVersion = $response->getProtocolVersion(); + $this->assertEquals($protocolVersion, $response->withProtocolVersion('1.1')->getProtocolVersion()); + $this->assertNotEquals($protocolVersion, $response->withProtocolVersion('1.0')->getProtocolVersion()); + } + + /** + * @test + */ + public function testGetHeaders() + { + $body = ''; + $this->assertTrue(is_array((new Response($body))->getHeaders())); + + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', + ]; + $expected = [ + 'Accept' => ['application/json'], + 'Content-Type' => ['text/xml;charset=UTF-8'], + ]; + $this->assertEquals($expected, (new Response($body, 200, $headers))->getHeaders()); + } + + /** + * @test + */ + public function testHasHeader() + { + $body = ''; + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', + ]; + $response = new Response($body, 200, $headers); + $this->assertFalse($response->hasHeader('Content-Encoding')); + $this->assertFalse($response->hasHeader('content-encoding')); + $this->assertTrue($response->hasHeader('Accept')); + $this->assertTrue($response->hasHeader('accept')); $this->assertTrue($response->hasHeader('Content-Type')); + $this->assertTrue($response->hasHeader('content-type')); + } + + /** + * @test + */ + public function testGetHeader() + { + $body = ''; + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', + ]; + $response = new Response($body, 200, $headers); + $expected = []; + $this->assertEquals($expected, $response->getHeader('Content-Encoding')); + $this->assertEquals($expected, $response->getHeader('content-encoding')); + $expected = ['application/json']; + $this->assertEquals($expected, $response->getHeader('Accept')); + $this->assertEquals($expected, $response->getHeader('accept')); + } + + /** + * @test + */ + public function testGetHeaderLine() + { + $body = ''; + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'text/xml;charset=UTF-8', + 'Cache-Control' => [ + 'no-transform', + 'public', + 'max-age=2678400', + 's-maxage=2678400', + ], + ]; + $response = new Response($body, 200, $headers); + $expected = ''; + $this->assertEquals($expected, $response->getHeaderLine('Content-Encoding')); + $this->assertEquals($expected, $response->getHeaderLine('content-encoding')); + $expected = 'application/json'; + $this->assertEquals($expected, $response->getHeaderLine('Accept')); + $this->assertEquals($expected, $response->getHeaderLine('accept')); + $expected = 'text/xml;charset=UTF-8'; + $this->assertEquals($expected, $response->getHeaderLine('Content-Type')); + $this->assertEquals($expected, $response->getHeaderLine('content-type')); + $expected = implode(', ', $headers['Cache-Control']); + $this->assertEquals($expected, $response->getHeaderLine('Cache-Control')); + $this->assertEquals($expected, $response->getHeaderLine('cache-control')); + } + + /** + * @test + */ + public function testWithHeader() + { + $body = ''; + $headers = ['Accept' => ['application/json']]; + $response = new Response($body, 200, $headers); + $expected = array_merge($headers, ['Content-Encoding' => ['gzip']]); + $this->assertEquals($expected, $response->withHeader('Content-Encoding', 'gzip')->getHeaders()); + $this->assertEquals($expected, $response->withHeader('Content-Encoding', ['gzip'])->getHeaders()); + $expected = ['Accept' => ['application/xml']]; + $this->assertEquals($expected, $response->withHeader('Accept', 'application/xml')->getHeaders()); + $this->assertEquals($expected, $response->withHeader('Accept', ['application/xml'])->getHeaders()); + } + + /** + * @test + */ + public function testWithAddedHeader() + { + $body = ''; + $headers = ['Accept' => ['application/json']]; + $response = new Response($body, 200, $headers); + $expected = array_merge($headers, ['Content-Encoding' => ['gzip']]); + $this->assertEquals($expected, $response->withAddedHeader('Content-Encoding', 'gzip')->getHeaders()); + $this->assertEquals($expected, $response->withAddedHeader('Content-Encoding', ['gzip'])->getHeaders()); + $expected = ['Accept' => ['application/json', 'application/xml']]; + $this->assertEquals($expected, $response->withAddedHeader('Accept', 'application/xml')->getHeaders()); + $this->assertEquals($expected, $response->withAddedHeader('Accept', ['application/xml'])->getHeaders()); + } + + /** + * @test + */ + public function testWithoutHeader() + { + $body = ''; + $headers = ['Accept' => ['application/json'], 'Content-Encoding' => ['gzip']]; + $response = new Response($body, 200, $headers); + $expected = $headers; + $this->assertEquals($expected, $response->withoutHeader('Cache-Control')->getHeaders()); + $expected = ['Content-Encoding' => ['gzip']]; + $this->assertEquals($expected, $response->withoutHeader('Accept')->getHeaders()); + $this->assertEquals($expected, $response->withoutHeader('accept')->getHeaders()); + } + + /** + * @test + */ + public function testGetBody() + { + $body = ''; + $response = new Response($body); + $this->assertEquals($body, $response->getBody()); + } + + /** + * @test + */ + public function testWithBody() + { + $body = '{"message":"text"}'; + $stream = $this->prophesize(StreamInterface::class); + $stream->__toString()->willReturn($body); + $this->assertEquals($body, (new Response(''))->withBody($stream->reveal())->getBody()); + } + + /** + * @test + */ + public function testGetStatusCode() + { + $this->assertEquals(200, (new Response(''))->getStatusCode()); + $this->assertEquals(400, (new Response('', 400))->getStatusCode()); + } + + /** + * @test + */ + public function testWithStatus() + { + $statusCode = 200; + $response = (new Response(''))->withStatus($statusCode); + $this->assertTrue( + $statusCode === $response->getStatusCode() + && $response->getReasonPhrase() === HttpStatusCode::$statusTexts[$statusCode] + ); + + $reasonPhrase = 'value'; + $response = (new Response(''))->withStatus($statusCode, $reasonPhrase); + $this->assertTrue( + $statusCode === $response->getStatusCode() + && $reasonPhrase === $response->getReasonPhrase() + ); } } diff --git a/tests/SchemeTest.php b/tests/SchemeTest.php new file mode 100644 index 0000000..2733f19 --- /dev/null +++ b/tests/SchemeTest.php @@ -0,0 +1,149 @@ + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +namespace Matricali\Http; + +use PHPUnit\Framework\TestCase; + +/** + * @author Gabriel Polverini + * + * @group Enums + */ +class SchemeTest extends TestCase +{ + const NAME_HTTP = 'HTTP'; + const NAME_HTTPS = 'HTTPS'; + const NAME_FTP = 'FTP'; + const NAME_NOTEXIST = ''; + + protected $scheme; + + public function setUp() + { + $this->scheme = $this->getMockForAbstractClass(Scheme::class); + } + + /** + * @test + */ + public function testIsValidNameHttp() + { + $this->assertTrue($this->scheme->isValidName(self::NAME_HTTP)); + } + + /** + * @test + */ + public function testGetByNameHttp() + { + $value = $this->scheme->getByName(self::NAME_HTTP); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttp + * + * @param string $value + */ + public function testIsValidValueHttp($value) + { + $this->assertTrue($this->scheme->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameHttps() + { + $this->assertTrue($this->scheme->isValidName(self::NAME_HTTPS)); + } + + /** + * @test + */ + public function testGetByNameHttps() + { + $value = $this->scheme->getByName(self::NAME_HTTPS); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameHttps + * + * @param string $value + */ + public function testIsValidValueHttps($value) + { + $this->assertTrue($this->scheme->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameFtp() + { + $this->assertTrue($this->scheme->isValidName(self::NAME_FTP)); + } + + /** + * @test + */ + public function testGetByNameFtp() + { + $value = $this->scheme->getByName(self::NAME_FTP); + $this->assertNotNull($value); + return $value; + } + + /** + * @test + * @depends testGetByNameFtp + * + * @param string $value + */ + public function testIsValidValueFtp($value) + { + $this->assertTrue($this->scheme->isValidValue($value)); + } + + /** + * @test + */ + public function testIsValidNameStrictTrue() + { + $this->assertTrue($this->scheme->isValidName(self::NAME_HTTP, true)); + } + + /** + * @test + */ + public function testGetByNameNotExist() + { + $this->assertNull($this->scheme->getByName(self::NAME_NOTEXIST)); + } +} \ No newline at end of file diff --git a/tests/UriTest.php b/tests/UriTest.php index 3a28531..f8c9e4a 100644 --- a/tests/UriTest.php +++ b/tests/UriTest.php @@ -23,13 +23,19 @@ namespace Matricali\Http; +use MongoDB\BSON\ObjectId; use PHPUnit\Framework\TestCase; /** - * @covers Matricali\Http\Uri + * @author Gabriel Polverini + * + * @group Uri */ class UriTest extends TestCase { + /** + * @test + */ public function testEmptyUri() { $uri = new Uri(); @@ -44,6 +50,9 @@ public function testEmptyUri() $this->assertEquals('', $uri->getFragment()); } + /** + * @test + */ public function testBasicHttpUri() { $uri = new Uri('http://www.google.com/'); @@ -58,6 +67,9 @@ public function testBasicHttpUri() $this->assertEquals('', $uri->getFragment()); } + /** + * @test + */ public function testHttpUriWithUsername() { $uri = new Uri('http://user@www.google.com/'); @@ -72,6 +84,9 @@ public function testHttpUriWithUsername() $this->assertEquals('', $uri->getFragment()); } + /** + * @test + */ public function testHttpUriWithUsernameAndPassword() { $uri = new Uri('http://user:password@www.google.com/'); @@ -86,6 +101,9 @@ public function testHttpUriWithUsernameAndPassword() $this->assertEquals('', $uri->getFragment()); } + /** + * @test + */ public function testHttpUriWithPathQueryAndFragmentHttps() { $uri = new Uri('https://www.google.com:9000/ExampleResource?a=1&b=2#top'); @@ -100,6 +118,9 @@ public function testHttpUriWithPathQueryAndFragmentHttps() $this->assertEquals('top', $uri->getFragment()); } + /** + * @test + */ public function testHttpUriWithPathQueryAndFragmentHttp() { $uri = new Uri('http://www.example.com:8080/ExamplePage.html?#anchor'); @@ -114,6 +135,9 @@ public function testHttpUriWithPathQueryAndFragmentHttp() $this->assertEquals('anchor', $uri->getFragment()); } + /** + * @test + */ public function testFtpUri() { $uri = new Uri('ftp://username:password@ftp.example.com:21'); @@ -127,4 +151,215 @@ public function testFtpUri() $this->assertEquals('', $uri->getQuery()); $this->assertEquals('', $uri->getFragment()); } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testWithInvalidScheme() + { + (new Uri('http://www.example.com/'))->withScheme(1); + } + + /** + * @test + */ + public function testWithScheme() + { + $value = 'http://www.example.com/'; + $uri = new Uri($value); + + $uriCloned = $uri->withScheme(Scheme::HTTPS); + $this->assertEquals($uri->getPort(), $uriCloned->getPort()); + $this->assertEquals($uri->getAuthority(), $uriCloned->getAuthority()); + $this->assertEquals($uri->getUserInfo(), $uriCloned->getUserInfo()); + $this->assertEquals($uri->getHost(), $uriCloned->getHost()); + $this->assertEquals($uri->getPath(), $uriCloned->getPath()); + $this->assertEquals($uri->getQuery(), $uriCloned->getQuery()); + $this->assertEquals($uri->getFragment(), $uriCloned->getFragment()); + $this->assertNotEquals($value, (string) $uriCloned); + $this->assertNotEquals($uri->getScheme(), $uriCloned->getScheme()); + $this->assertEquals(Scheme::HTTPS, $uriCloned->getScheme()); + } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testWithInvalidHost() + { + (new Uri('http://www.example.com/'))->withHost(1); + } + + /** + * @test + */ + public function testWithHost() + { + $value = 'http://www.example.com/'; + $uri = new Uri($value); + + $host = 'www.clarovideo.com'; + $uriCloned = $uri->withHost($host); + $this->assertEquals($uri->getScheme(), $uriCloned->getScheme()); + $this->assertEquals($uri->getPort(), $uriCloned->getPort()); + $this->assertNotEquals($uri->getAuthority(), $uriCloned->getAuthority()); + $this->assertEquals($host, $uriCloned->getAuthority()); + $this->assertEquals($uri->getUserInfo(), $uriCloned->getUserInfo()); + $this->assertEquals($uri->getPath(), $uriCloned->getPath()); + $this->assertEquals($uri->getQuery(), $uriCloned->getQuery()); + $this->assertEquals($uri->getFragment(), $uriCloned->getFragment()); + $this->assertNotEquals($uri->getHost(), $uriCloned->getHost()); + $this->assertEquals($host, $uriCloned->getHost()); + } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testWithInvalidPort() + { + (new Uri('http://www.example.com/'))->withPort('value'); + } + + /** + * @test + */ + public function testWithPort() + { + $value = 'http://www.example.com/'; + $uri = new Uri($value); + + $port = 8084; + $uriCloned = $uri->withPort($port); + $this->assertEquals($uri->getScheme(), $uriCloned->getScheme()); + $this->assertEquals($uri->getAuthority().":$port", $uriCloned->getAuthority()); + $this->assertEquals($uri->getUserInfo(), $uriCloned->getUserInfo()); + $this->assertEquals($uri->getPath(), $uriCloned->getPath()); + $this->assertEquals($uri->getQuery(), $uriCloned->getQuery()); + $this->assertEquals($uri->getFragment(), $uriCloned->getFragment()); + $this->assertEquals($uri->getHost(), $uriCloned->getHost()); + $this->assertNotEquals($uri->getPort(), $uriCloned->getPort()); + $this->assertEquals($port, $uriCloned->getPort()); + } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testWithInvalidPath() + { + (new Uri('http://www.example.com/'))->withPath(1); + } + + /** + * @test + */ + public function testWithPath() + { + $value = 'http://www.example.com/'; + $uri = new Uri($value); + + $path = '/ExamplePage.html'; + $uriCloned = $uri->withPath($path); + $this->assertEquals($uri->getScheme(), $uriCloned->getScheme()); + $this->assertEquals($uri->getAuthority(), $uriCloned->getAuthority()); + $this->assertEquals($uri->getUserInfo(), $uriCloned->getUserInfo()); + $this->assertEquals($uri->getQuery(), $uriCloned->getQuery()); + $this->assertEquals($uri->getFragment(), $uriCloned->getFragment()); + $this->assertEquals($uri->getHost(), $uriCloned->getHost()); + $this->assertEquals($uri->getPort(), $uriCloned->getPort()); + $this->assertNotEquals($uri->getPath(), $uriCloned->getPath()); + $this->assertEquals($path, $uriCloned->getPath()); + } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testWithInvalidQuery() + { + (new Uri('http://www.example.com/'))->withQuery(1); + } + + /** + * @test + */ + public function testWithQuery() + { + $value = 'http://www.example.com/ExamplePage.html'; + $uri = new Uri($value); + + $query = 'a=1&b=2'; + $uriCloned = $uri->withQuery($query); + $this->assertEquals($uri->getScheme(), $uriCloned->getScheme()); + $this->assertEquals($uri->getAuthority(), $uriCloned->getAuthority()); + $this->assertEquals($uri->getUserInfo(), $uriCloned->getUserInfo()); + $this->assertEquals($uri->getFragment(), $uriCloned->getFragment()); + $this->assertEquals($uri->getHost(), $uriCloned->getHost()); + $this->assertEquals($uri->getPort(), $uriCloned->getPort()); + $this->assertEquals($uri->getPath(), $uriCloned->getPath()); + $this->assertNotEquals($uri->getQuery(), $uriCloned->getQuery()); + $this->assertEquals($query, $uriCloned->getQuery()); + } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function testWithInvalidFragment() + { + (new Uri('http://www.example.com/'))->withFragment(1); + } + + /** + * @test + */ + public function testWithFragment() + { + $value = 'http://www.example.com/ExamplePage.html'; + $uri = new Uri($value); + + $fragment = 'anchor'; + $uriCloned = $uri->withFragment($fragment); + $this->assertEquals($uri->getScheme(), $uriCloned->getScheme()); + $this->assertEquals($uri->getAuthority(), $uriCloned->getAuthority()); + $this->assertEquals($uri->getUserInfo(), $uriCloned->getUserInfo()); + $this->assertEquals($uri->getHost(), $uriCloned->getHost()); + $this->assertEquals($uri->getPort(), $uriCloned->getPort()); + $this->assertEquals($uri->getPath(), $uriCloned->getPath()); + $this->assertEquals($uri->getQuery(), $uriCloned->getQuery()); + $this->assertNotEquals($uri->getFragment(), $uriCloned->getFragment()); + $this->assertEquals($fragment, $uriCloned->getFragment()); + } + + /** + * @test + */ + public function testWithUserInfo() + { + $value = 'http://www.example.com/ExamplePage.html'; + $uri = new Uri($value); + + $user = 'user'; + $password = 'password'; + $uriCloned = $uri->withUserInfo($user, $password); + $this->assertEquals($uri->getScheme(), $uriCloned->getScheme()); + $this->assertEquals($uri->getHost(), $uriCloned->getHost()); + $this->assertEquals($uri->getPort(), $uriCloned->getPort()); + $this->assertEquals($uri->getPath(), $uriCloned->getPath()); + $this->assertEquals($uri->getQuery(), $uriCloned->getQuery()); + $this->assertEquals($uri->getFragment(), $uriCloned->getFragment()); + $this->assertNotEquals($uri->getUserInfo(), $uriCloned->getUserInfo()); + $this->assertNotEquals($uri->getAuthority(), $uriCloned->getAuthority()); + $this->assertEquals("$user:$password@www.example.com", $uriCloned->getAuthority()); + $this->assertEquals("$user:$password", $uriCloned->getUserInfo()); + + } } From 05eee5a2bbf07e1462aaf20f97395e87b9f207fc Mon Sep 17 00:00:00 2001 From: gpolverini Date: Tue, 17 Jul 2018 13:43:03 -0300 Subject: [PATCH 2/6] + Add FTP default port.- --- src/Scheme.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Scheme.php b/src/Scheme.php index 717d553..8e79260 100644 --- a/src/Scheme.php +++ b/src/Scheme.php @@ -35,5 +35,6 @@ abstract class Scheme extends Enum public static $defaultPort = array( self::HTTP => 80, self::HTTPS => 443, + self::FTP => 21 ); } From 1a8d11d91baefe28142840f6668350b56b887c1c Mon Sep 17 00:00:00 2001 From: gpolverini Date: Tue, 17 Jul 2018 13:49:29 -0300 Subject: [PATCH 3/6] + Fix TDD.- --- tests/UriTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/UriTest.php b/tests/UriTest.php index f8c9e4a..0b79b93 100644 --- a/tests/UriTest.php +++ b/tests/UriTest.php @@ -141,10 +141,10 @@ public function testHttpUriWithPathQueryAndFragmentHttp() public function testFtpUri() { $uri = new Uri('ftp://username:password@ftp.example.com:21'); - $this->assertEquals('ftp://username:password@ftp.example.com:21', (string) $uri); + $this->assertEquals('ftp://username:password@ftp.example.com', (string) $uri); $this->assertEquals('ftp', $uri->getScheme()); $this->assertEquals(21, $uri->getPort()); - $this->assertEquals('username:password@ftp.example.com:21', $uri->getAuthority()); + $this->assertEquals('username:password@ftp.example.com', $uri->getAuthority()); $this->assertEquals('username:password', $uri->getUserInfo()); $this->assertEquals('ftp.example.com', $uri->getHost()); $this->assertEquals('', $uri->getPath()); From bcbc00910a75f6f5355e471c4c3a0c0853dbce44 Mon Sep 17 00:00:00 2001 From: gpolverini Date: Tue, 17 Jul 2018 15:15:18 -0300 Subject: [PATCH 4/6] + BugFix destructor.- --- composer.json | 2 +- src/Client.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 0d818c9..8b0c032 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "library", "keywords": ["http", "client", "psr7", "curl", "wrapper"], "require": { - "php": ">=5.5.0", + "php": ">=5.4.0", "psr/http-message": "^1.0" }, "require-dev": { diff --git a/src/Client.php b/src/Client.php index 296cdcd..e06b30a 100644 --- a/src/Client.php +++ b/src/Client.php @@ -65,7 +65,9 @@ public function __construct() public function __destruct() { - curl_close($this->handle); + if (is_resource($this->handle)) { + curl_close($this->handle); + } } /** From c132aaaa3add117ddf99c56efe21f79bb3331eba Mon Sep 17 00:00:00 2001 From: gpolverini Date: Tue, 17 Jul 2018 15:29:51 -0300 Subject: [PATCH 5/6] + Fix TDD --- tests/ClientTest.php | 3 +-- tests/RequestTest.php | 6 ++---- tests/ResponseTest.php | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index ae34b14..de84ae1 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -25,7 +25,6 @@ use PHPUnit\Framework\TestCase; use Prophecy\Argument; -use Psr\Http\Message\RequestInterface; /** * @author Gabriel Polverini @@ -42,7 +41,7 @@ class ClientTest extends TestCase public function testSendRequest() { $client = new Client(); - $request = $this->prophesize(RequestInterface::class); + $request = $this->prophesize('Psr\Http\Message\RequestInterface'); $request->getUri()->willReturn('http://404.php.net/'); $request->getMethod()->willReturn(HttpMethod::GET); $client->sendRequest($request->reveal()); diff --git a/tests/RequestTest.php b/tests/RequestTest.php index caf85cc..5a38d46 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -25,8 +25,6 @@ use PHPUnit\Framework\TestCase; use Prophecy\Argument; -use Psr\Http\Message\StreamInterface; -use Psr\Http\Message\UriInterface; /** * @author Gabriel Polverini @@ -163,7 +161,7 @@ public function testGetUri() public function testWithUri() { $uri = 'www.google.com'; - $uriInterface = $this->prophesize(UriInterface::class); + $uriInterface = $this->prophesize('Psr\Http\Message\UriInterface'); $uriInterface->__toString()->willReturn($uri); $request = new Request(HttpMethod::GET, $uri); $this->assertEquals($request->getUri(), (string) $request->withUri($uriInterface->reveal())->getUri()); @@ -359,7 +357,7 @@ public function testGetBody() public function testWithBody() { $body = '{"message":"text"}'; - $stream = $this->prophesize(StreamInterface::class); + $stream = $this->prophesize('Psr\Http\Message\StreamInterface'); $stream->__toString()->willReturn($body); $this->assertEquals($body, (new Request())->withBody($stream->reveal())->getBody()); } diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php index ed48257..03a853c 100644 --- a/tests/ResponseTest.php +++ b/tests/ResponseTest.php @@ -24,7 +24,6 @@ namespace Matricali\Http; use PHPUnit\Framework\TestCase; -use Psr\Http\Message\StreamInterface; /** * @author Gabriel Polverini @@ -250,7 +249,7 @@ public function testGetBody() public function testWithBody() { $body = '{"message":"text"}'; - $stream = $this->prophesize(StreamInterface::class); + $stream = $this->prophesize('Psr\Http\Message\StreamInterface'); $stream->__toString()->willReturn($body); $this->assertEquals($body, (new Response(''))->withBody($stream->reveal())->getBody()); } From 50b19fb4f3e34b04581b6d33ce48a4ce312d860e Mon Sep 17 00:00:00 2001 From: gpolverini Date: Tue, 17 Jul 2018 15:44:19 -0300 Subject: [PATCH 6/6] + Fix TDD for getMockForAbstractClass.- --- tests/HttpMethodTest.php | 2 +- tests/HttpStatusCodeTest.php | 2 +- tests/SchemeTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/HttpMethodTest.php b/tests/HttpMethodTest.php index 43d2078..85234fa 100644 --- a/tests/HttpMethodTest.php +++ b/tests/HttpMethodTest.php @@ -47,7 +47,7 @@ class HttpMethodTest extends TestCase public function setUp() { - $this->httpMethod = $this->getMockForAbstractClass(HttpMethod::class); + $this->httpMethod = $this->getMockForAbstractClass('Matricali\Http\HttpMethod'); } /** diff --git a/tests/HttpStatusCodeTest.php b/tests/HttpStatusCodeTest.php index 4018d85..b024777 100644 --- a/tests/HttpStatusCodeTest.php +++ b/tests/HttpStatusCodeTest.php @@ -102,7 +102,7 @@ class HttpStatusCodeTest extends TestCase public function setUp() { - $this->httpStatusCode = $this->getMockForAbstractClass(HttpStatusCode::class); + $this->httpStatusCode = $this->getMockForAbstractClass('Matricali\Http\HttpStatusCode'); } /** diff --git a/tests/SchemeTest.php b/tests/SchemeTest.php index 2733f19..71a0913 100644 --- a/tests/SchemeTest.php +++ b/tests/SchemeTest.php @@ -41,7 +41,7 @@ class SchemeTest extends TestCase public function setUp() { - $this->scheme = $this->getMockForAbstractClass(Scheme::class); + $this->scheme = $this->getMockForAbstractClass('Matricali\Http\Scheme'); } /**