Skip to content
Snippets Groups Projects
Commit 8be0434c authored by Grzegorz Rola's avatar Grzegorz Rola
Browse files

Merge branch 'feature/first-release' into 'master'

Feature/first release

See merge request !1
parents 5a7d23b1 d87320de
No related branches found
No related tags found
1 merge request!1Feature/first release
Pipeline #4889 failed with stages
in 2 minutes and 23 seconds
Showing
with 756 additions and 4 deletions
tests/ export-ignore
vendor/ export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.git/ export-ignore
.gitlab-ci.yml export-ignore
.idea export-ignore
apigen.neon export-ignore
build-coverage/ export-ignore
docs/ export-ignore
LICENSE.md export-ignore
phpcs.xml.dist export-ignore
phpunit-integration.xml export-ignore
phpunit-unit.xml export-ignore
/vendor/
.idea
composer.lock
build-coverage
swagger
\ No newline at end of file
variables:
DISABLE_ACCEPTANCE: "1"
DISABLE_FUNCTIONAL: "1"
include: 'https://gitlab.com/wpdesk/gitlab-ci/raw/master/gitlab-ci-1.2.yml'
# wp-http-client [![pipeline status](https://gitlab.com/wpdesk/wp-http-client/badges/master/pipeline.svg)](https://gitlab.com/wpdesk/wp-http-client/commits/master)
Integration: [![coverage report](https://gitlab.com/wpdesk/wp-http-client/badges/master/coverage.svg?job=integration+test+lastest+coverage)](https://gitlab.com/wpdesk/wp-http-client/commits/master)
Unit: [![coverage report](https://gitlab.com/wpdesk/wp-http-client/badges/master/coverage.svg?job=unit+test+lastest+coverage)](https://gitlab.com/wpdesk/wp-http-client/commits/master)
HTTP Client
===========
= 1.0 - 2019-01-31 =
* First release
...@@ -9,9 +9,7 @@ ...@@ -9,9 +9,7 @@
"require": { "require": {
"php": ">=5.5", "php": ">=5.5",
"ext-curl": "*", "ext-curl": "*",
"ext-json": "*", "ext-json": "*"
"psr/log": "^1.0.1",
"psr/simple-cache": "^1.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "<7", "phpunit/phpunit": "<7",
......
<phpunit bootstrap="tests/integration/bootstrap.php"
backupGlobals="false"
>
<testsuites>
<testsuite>
<directory prefix="Test" suffix=".php">./tests/integration</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<logging>
<log type="junit" target="build-coverage/report.junit.xml"/>
<log type="coverage-html" target="build-coverage/coverage" charset="UTF-8" yui="true" highlight="true"/>
<log type="coverage-text" target="build-coverage/coverage.txt"/>
<log type="coverage-clover" target="build-coverage/clover.xml"/>
</logging>
<php>
<env name="WP_DEVELOP_DIR" value="/tmp/wordpress-develop"/>
<env name="WC_DEVELOP_DIR" value="/tmp/woocommerce"/>
</php>
</phpunit>
\ No newline at end of file
<phpunit bootstrap="tests/unit/bootstrap.php">
<testsuites>
<testsuite>
<directory prefix="Test" suffix=".php">./tests/unit/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<logging>
<log type="junit" target="build-coverage/report.junit.xml"/>
<log type="coverage-html" target="build-coverage/coverage" charset="UTF-8" yui="true" highlight="true"/>
<log type="coverage-text" target="build-coverage/coverage.txt"/>
<log type="coverage-clover" target="build-coverage/clover.xml"/>
</logging>
</phpunit>
<?php
namespace WPDesk\HttpClient\Curl;
use WPDesk\HttpClient\HttpClient;
use WPDesk\HttpClient\HttpClientResponse;
use WPDesk\HttpClient\HttpClientRequestException;
class CurlClient implements HttpClient
{
/** @var resource */
private $curlResource;
/** @var string|null|boolean */
private $rawResponse;
/** @var int */
private $httpResponseCode;
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function get($url, $body, array $headers, $timeOut)
{
return $this->send($url, 'GET', $body, $headers, $timeOut);
}
/**
* @param string $url
* @param string $method
* @param string $body
* @param array $headers
* @param int $timeOut
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function send($url, $method, $body, array $headers, $timeOut)
{
$this->initResource();
try {
$this->prepareConnection($url, $method, $body, $headers, $timeOut);
$this->sendRequest();
$this->throwExceptionIfError();
$this->closeConnection();
return $this->prepareResponse();
} catch (\Exception $e) {
$this->closeConnection();
if ($e instanceof HttpClientRequestException) {
throw $e;
}
throw CurlExceptionFactory::createDefaultException($e->getMessage(), $e->getCode(), $e);
}
}
private function initResource()
{
$this->curlResource = curl_init();
}
/**
* Opens a new curl connection.
*
* @param string $url The endpoint to send the request to.
* @param string $method The request method.
* @param string $body The body of the request.
* @param array $headers The request headers.
* @param int $timeOut The timeout in seconds for the request.
*/
private function prepareConnection($url, $method, $body, array $headers, $timeOut)
{
$options = [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $this->compileRequestHeaders($headers),
CURLOPT_URL => $url,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => $timeOut,
CURLOPT_RETURNTRANSFER => true, // Return response as string
CURLOPT_HEADER => true, // Enable header processing
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_SSL_VERIFYPEER => true,
//CURLOPT_CAINFO => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem',
];
if ($method !== "GET") {
$options[CURLOPT_POSTFIELDS] = $body;
}
curl_setopt_array($this->curlResource, $options);
}
/**
* Compiles the request headers into a curl-friendly format.
*
* @param array $headers The request headers.
*
* @return array
*/
private function compileRequestHeaders(array $headers)
{
$return = [];
foreach ($headers as $key => $value) {
$return[] = $key . ': ' . $value;
}
return $return;
}
/**
* Send the request and get the raw response from curl
*/
private function sendRequest()
{
$this->rawResponse = curl_exec($this->curlResource);
$this->httpResponseCode = $this->getHttpResponseCode();
}
/** @return int */
private function getHttpResponseCode()
{
return intval(curl_getinfo($this->curlResource, CURLINFO_HTTP_CODE));
}
private function throwExceptionIfError()
{
$errorNumber = curl_errno($this->curlResource);
if ($errorNumber === 0) {
return;
}
$errorMessage = curl_error($this->curlResource);
throw CurlExceptionFactory::createCurlException($errorMessage, $errorNumber);
}
/**
* Closes an existing curl connection
*/
private function closeConnection()
{
curl_close($this->curlResource);
$this->curlResource = null;
}
private function prepareResponse()
{
list($rawHeaders, $rawBody) = $this->extractResponseHeadersAndBody();
return new HttpClientResponse($rawHeaders, $rawBody, $this->httpResponseCode);
}
/**
* Extracts the headers and the body into a two-part array
*
* @return array
*/
private function extractResponseHeadersAndBody()
{
$parts = explode("\r\n\r\n", $this->rawResponse);
$rawBody = array_pop($parts);
$rawHeaders = implode("\r\n\r\n", $parts);
return [trim($rawHeaders), trim($rawBody)];
}
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function post($url, $body, array $headers, $timeOut)
{
return $this->send($url, 'POST', $body, $headers, $timeOut);
}
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function delete($url, $body, array $headers, $timeOut)
{
return $this->send($url, 'DELETE', $body, $headers, $timeOut);
}
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @return HttpClientResponse
* @throws HttpClientRequestException
*/
public function put($url, $body, array $headers, $timeOut)
{
return $this->send($url, 'PUT', $body, $headers, $timeOut);
}
}
\ No newline at end of file
<?php
namespace WPDesk\HttpClient\Curl;
use WPDesk\HttpClient\Curl\Exception\CurlException;
use WPDesk\HttpClient\Curl\Exception\CurlTimedOutException;
class CurlExceptionFactory
{
/**
* Convert curl code to appropriate exception class.
*
* @param int $curlCode Code from https://curl.haxx.se/libcurl/c/libcurl-errors.html
* @param string $curlMessage
* @return CurlException
*/
public static function createCurlException($curlCode, $curlMessage) {
switch ($curlCode) {
case CURLE_OPERATION_TIMEDOUT:
return new CurlTimedOutException($curlMessage, $curlCode);
default:
return self::createDefaultException($curlMessage, $curlCode);
}
}
/**
* Creates default Curl exception
*
* @param $code
* @param $message
* @param \Exception|null $prev
* @return CurlException
*/
public static function createDefaultException($code, $message, \Exception $prev = null) {
return new CurlException('Default exception: ' . $message, $code, $prev);
}
}
\ No newline at end of file
<?php
namespace WPDesk\HttpClient\Curl\Exception;
use WPDesk\HttpClient\HttpClientRequestException;
/**
* Base class for all curl exceptions.
*
* @package WPDesk\HttpClient\Curl\Exception
*/
class CurlException extends \RuntimeException implements HttpClientRequestException
{
}
\ No newline at end of file
<?php
namespace WPDesk\HttpClient\Curl\Exception;
class CurlTimedOutException extends CurlException
{
}
\ No newline at end of file
<?php
namespace WPDesk\HttpClient;
interface HttpClient
{
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function put($url, $body, array $headers, $timeOut);
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function get($url, $body, array $headers, $timeOut);
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function post($url, $body, array $headers, $timeOut);
/**
* @param string $url
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function delete($url, $body, array $headers, $timeOut);
/**
* @param string $url
* @param string $method
* @param string $body
* @param array $headers
* @param int $timeOut
* @throw HttpClientRequestException
* @return HttpClientResponse
*/
public function send($url, $method, $body, array $headers, $timeOut);
}
\ No newline at end of file
<?php
namespace WPDesk\HttpClient;
class HttpClientFactory
{
/**
* @param HttpClientOptions $options
* @return HttpClient
*/
public function createClient(HttpClientOptions $options)
{
$className = $options->getHttpClientClass();
return new $className;
}
}
\ No newline at end of file
<?php
namespace WPDesk\HttpClient;
interface HttpClientOptions
{
/**
* @return string
*/
public function getHttpClientClass();
}
\ No newline at end of file
<?php
namespace WPDesk\HttpClient;
/**
* Interface for all exceptions that can be thrown by HttpClient
*
* @package WPDesk\HttpClient
*/
interface HttpClientRequestException
{
}
\ No newline at end of file
<?php
namespace WPDesk\HttpClient;
class HttpClientResponse
{
/** @var string */
private $headers;
/** @var string */
private $body;
/** @var int */
private $code;
/**
* HttpClientResponse constructor.
* @param string $headers
* @param string $body
* @param int $code
*/
public function __construct($headers, $body, $code)
{
$this->headers = $headers;
$this->body = $body;
$this->code = $code;
}
/**
* @return array
*/
public function getHeaders()
{
$headers = array();
$headers_rows = explode("\r\n", $this->headers);
foreach ($headers_rows as $headers_row) {
$header = explode(": ", $headers_row);
$headers[$header[0]] = isset($header[1])?$header[1]:$header[0];
}
return $headers;
}
/**
* @return string
*/
public function getBody()
{
return $this->body;
}
/**
* @return int
*/
public function getResponseCode()
{
return $this->code;
}
}
\ No newline at end of file
version: '2.0'
services:
wordpress:
image: wpdesknet/phpunit-woocommerce:0-0
volumes:
- .././:/opt/project
depends_on:
- mysql0
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql0
wordpress-0-1:
image: wpdesknet/phpunit-woocommerce:0-1
volumes:
- .././:/opt/project
depends_on:
- mysql1
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql1
wordpress-0-2:
image: wpdesknet/phpunit-woocommerce:0-2
volumes:
- .././:/opt/project
depends_on:
- mysql2
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql2
wordpress-0-3:
image: wpdesknet/phpunit-woocommerce:0-3
volumes:
- .././:/opt/project
depends_on:
- mysql3
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql3
wordpress-0-4:
image: wpdesknet/phpunit-woocommerce:0-4
volumes:
- .././:/opt/project
depends_on:
- mysql4
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql4
wordpress-0-5:
image: wpdesknet/phpunit-woocommerce:0-5
volumes:
- .././:/opt/project
depends_on:
- mysql5
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql5
wordpress-1-0:
image: wpdesknet/phpunit-woocommerce:1-0
volumes:
- .././:/opt/project
depends_on:
- mysql0
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql0
wordpress-2-0:
image: wpdesknet/phpunit-woocommerce:2-0
volumes:
- .././:/opt/project
depends_on:
- mysql0
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql0
wordpress-3-0:
image: wpdesknet/phpunit-woocommerce:3-0
volumes:
- .././:/opt/project
depends_on:
- mysql0
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql0
wordpress-4-0:
image: wpdesknet/phpunit-woocommerce:4-0
volumes:
- .././:/opt/project
depends_on:
- mysql0
environment:
WORDPRESS_DB_NAME: wptest
WORDPRESS_DB_USER: mysql
WORDPRESS_DB_PASSWORD: mysql
WORDPRESS_DB_HOST: mysql0
mysql0:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: mysql
MYSQL_DATABASE: wptest
MYSQL_USER: mysql
MYSQL_PASSWORD: mysql
mysql1:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: mysql
MYSQL_DATABASE: wptest
MYSQL_USER: mysql
MYSQL_PASSWORD: mysql
mysql2:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: mysql
MYSQL_DATABASE: wptest
MYSQL_USER: mysql
MYSQL_PASSWORD: mysql
mysql3:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: mysql
MYSQL_DATABASE: wptest
MYSQL_USER: mysql
MYSQL_PASSWORD: mysql
mysql4:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: mysql
MYSQL_DATABASE: wptest
MYSQL_USER: mysql
MYSQL_PASSWORD: mysql
mysql5:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: mysql
MYSQL_DATABASE: wptest
MYSQL_USER: mysql
MYSQL_PASSWORD: mysql
<?php
ini_set('error_reporting', E_ALL); // or error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
require_once __DIR__ . '/../../vendor/autoload.php';
// disable xdebug backtrace
if ( function_exists( 'xdebug_disable' ) ) {
xdebug_disable();
}
if ( getenv( 'PLUGIN_PATH' ) !== false ) {
define( 'PLUGIN_PATH', getenv( 'PLUGIN_PATH' ) );
} else {
define( 'PLUGIN_PATH', __DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR );
}
require_once( getenv( 'WP_DEVELOP_DIR' ) . '/tests/phpunit/includes/functions.php' );
tests_add_filter( 'muplugins_loaded', function () {
}, 100 );
putenv('WP_TESTS_DIR=' . getenv( 'WP_DEVELOP_DIR' ) . '/tests/phpunit');
require_once( getenv( 'WC_DEVELOP_DIR' ) . '/tests/bootstrap.php' );
do_action('plugins_loaded');
\ No newline at end of file
<?php
class TestCurlClient extends \PHPUnit\Framework\TestCase
{
/**
* Test get method.
*/
public function testGet()
{
$client = new \WPDesk\HttpClient\Curl\CurlClient();
$response = $client->get('https://www.google.com', '', array(), 15);
$this->assertInstanceOf(\WPDesk\HttpClient\HttpClientResponse::class, $response);
$this->assertEquals(200, $response->getResponseCode());
}
/**
* Test post method.
*/
public function testPost()
{
$client = new \WPDesk\HttpClient\Curl\CurlClient();
$response = $client->post('https://www.google.com', '', array(), 15);
$this->assertInstanceOf(\WPDesk\HttpClient\HttpClientResponse::class, $response);
$this->assertEquals(405, $response->getResponseCode());
}
/**
* Test put method.
*/
public function testPut()
{
$client = new \WPDesk\HttpClient\Curl\CurlClient();
$response = $client->put('https://www.google.com', '', array(), 15);
$this->assertInstanceOf(\WPDesk\HttpClient\HttpClientResponse::class, $response);
$this->assertEquals(405, $response->getResponseCode());
}
/**
* Test delete method.
*/
public function testDelete()
{
$client = new \WPDesk\HttpClient\Curl\CurlClient();
$response = $client->put('https://www.google.com', '', array(), 15);
$this->assertInstanceOf(\WPDesk\HttpClient\HttpClientResponse::class, $response);
$this->assertEquals(405, $response->getResponseCode());
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment