diff --git a/.travis.yml b/.travis.yml index 776d6a9b15b..e0797524fa6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ php: before_script: - composer install --dev --prefer-source + - composer require "kriswallsmith/buzz:>=0.7" script: - phpunit --coverage-text diff --git a/composer.json b/composer.json index d3471164d68..1feef413cb1 100644 --- a/composer.json +++ b/composer.json @@ -19,11 +19,14 @@ "require": { "php": ">=5.3.2", "ext-curl": "*", - "kriswallsmith/buzz": ">=0.7" + "guzzle/guzzle": "3.7.*" }, "require-dev": { "phpunit/phpunit": ">=3.6.0" }, + "suggests": { + "kriswallsmith/buzz": "You may use old Buzz(>=0.7) adapter for your project" + }, "autoload": { "psr-0": { "Github\\": "lib/" } }, diff --git a/doc/result_pager.md b/doc/result_pager.md index a802be1caa9..a7910f3c182 100644 --- a/doc/result_pager.md +++ b/doc/result_pager.md @@ -21,7 +21,7 @@ $client = new Github\Client(); $organizationApi = $client->api('organization'); -$paginator = new Github\ResultPager( $client ); +$paginator = new Github\ResultPager($client); $parameters = array('github'); $result = $paginator->fetch($organizationApi, 'repositories', $parameters); ``` diff --git a/lib/Github/Api/AbstractApi.php b/lib/Github/Api/AbstractApi.php index 727f4e51824..73cc4f1d09b 100644 --- a/lib/Github/Api/AbstractApi.php +++ b/lib/Github/Api/AbstractApi.php @@ -63,7 +63,7 @@ protected function get($path, array $parameters = array(), $requestHeaders = arr if (null !== $this->perPage && !isset($parameters['per_page'])) { $parameters['per_page'] = $this->perPage; } - $response = $this->client->getHttpClient()->get($path, $parameters, $requestHeaders); + $response = $this->client->executeRequest('GET', $path, $parameters, $requestHeaders); return $response->getContent(); } @@ -73,7 +73,7 @@ protected function get($path, array $parameters = array(), $requestHeaders = arr */ protected function post($path, array $parameters = array(), $requestHeaders = array()) { - $response = $this->client->getHttpClient()->post($path, $parameters, $requestHeaders); + $response = $this->client->executeRequest('POST', $path, $parameters, $requestHeaders); return $response->getContent(); } @@ -83,7 +83,7 @@ protected function post($path, array $parameters = array(), $requestHeaders = ar */ protected function patch($path, array $parameters = array(), $requestHeaders = array()) { - $response = $this->client->getHttpClient()->patch($path, $parameters, $requestHeaders); + $response = $this->client->executeRequest('PATCH', $path, $parameters, $requestHeaders); return $response->getContent(); } @@ -93,7 +93,7 @@ protected function patch($path, array $parameters = array(), $requestHeaders = a */ protected function put($path, array $parameters = array(), $requestHeaders = array()) { - $response = $this->client->getHttpClient()->put($path, $parameters, $requestHeaders); + $response = $this->client->executeRequest('PUT', $path, $parameters, $requestHeaders); return $response->getContent(); } @@ -103,7 +103,7 @@ protected function put($path, array $parameters = array(), $requestHeaders = arr */ protected function delete($path, array $parameters = array(), $requestHeaders = array()) { - $response = $this->client->getHttpClient()->delete($path, $parameters, $requestHeaders); + $response = $this->client->executeRequest('DELETE', $path, $parameters, $requestHeaders); return $response->getContent(); } diff --git a/lib/Github/Client.php b/lib/Github/Client.php index e50d5e94638..800158b713f 100644 --- a/lib/Github/Client.php +++ b/lib/Github/Client.php @@ -4,7 +4,7 @@ use Github\Api\ApiInterface; use Github\Exception\InvalidArgumentException; -use Github\HttpClient\HttpClient; +use Github\HttpClient\Adapter\Guzzle\HttpClient; use Github\HttpClient\HttpClientInterface; /** @@ -161,7 +161,35 @@ public function authenticate($tokenOrLogin, $password = null, $authMethod = null $password = null; } - $this->getHttpClient()->authenticate($tokenOrLogin, $password, $authMethod); + switch ($authMethod) { + case Client::AUTH_HTTP_PASSWORD: + if (!$tokenOrLogin || !$password) { + throw new InvalidArgumentException('You need to set username with password!'); + } + break; + case Client::AUTH_HTTP_TOKEN: + if (!$tokenOrLogin) { + throw new InvalidArgumentException('You need to set OAuth token!'); + } + break; + case Client::AUTH_URL_CLIENT_ID: + if (!$tokenOrLogin || !$password) { + throw new InvalidArgumentException('You need to set client_id and client_secret!'); + } + break; + case Client::AUTH_URL_TOKEN: + if (!$tokenOrLogin) { + throw new InvalidArgumentException('You need to set OAuth token!'); + } + break; + } + + $this->getHttpClient()->authenticate($authMethod, $tokenOrLogin, $password); + } + + public function executeRequest($method, $path, $parameters, $headers) + { + return $this->getHttpClient()->request($path, $parameters, $method, $headers)->getContent(); } /** diff --git a/lib/Github/Exception/InvalidJsonResponse.php b/lib/Github/Exception/InvalidJsonResponse.php new file mode 100644 index 00000000000..b0344086893 --- /dev/null +++ b/lib/Github/Exception/InvalidJsonResponse.php @@ -0,0 +1,19 @@ +body = $body; + parent::__construct('Invalid Json Response', $code, $previous); + } + + public function getBody() + { + return $this->body; + } +} diff --git a/lib/Github/HttpClient/AbstractAdapter.php b/lib/Github/HttpClient/AbstractAdapter.php new file mode 100644 index 00000000000..392aeda0d2f --- /dev/null +++ b/lib/Github/HttpClient/AbstractAdapter.php @@ -0,0 +1,100 @@ + 'https://api.github.com/', + 'user_agent' => 'php-github-api (http://github.com/KnpLabs/php-github-api)', + 'timeout' => 10, + 'api_version' => 'beta', + 'cache_dir' => null + ); + /** + * @var array + */ + protected $headers; + + /** + * {@inheritDoc} + */ + public function setOption($name, $value) + { + $this->options[$name] = $value; + } + + /** + * {@inheritDoc} + */ + public function setHeaders(array $headers) + { + $this->headers = array_merge($this->headers, $headers); + } + + /** + * {@inheritDoc} + */ + public function clearHeaders() + { + $this->headers = array( + sprintf('Accept: application/vnd.github.%s+json', $this->options['api_version']) + ); + } + + /** + * {@inheritDoc} + */ + public function getLastRequest() + { + return $this->lastRequest; + } + + /** + * {@inheritDoc} + */ + public function getLastResponse() + { + return $this->lastResponse; + } + + /** + * {@inheritDoc} + */ + public function getAPILimit() + { + if (!$this->getLastRequest()) { + $this->get('/rate_limit'); + } + + return (int) $this->getLastRequest()->getHeaderAsString('X-RateLimit-Limit'); + } + + /** + * {@inheritDoc} + */ + public function getAPIRemaining() + { + if (!$this->getLastRequest()) { + $this->get('/rate_limit'); + } + + return (int) $this->getLastRequest()->getHeaderAsString('X-RateLimit-Remaining'); + } +} diff --git a/lib/Github/HttpClient/CachedHttpClient.php b/lib/Github/HttpClient/Adapter/Buzz/CachedHttpClient.php similarity index 84% rename from lib/Github/HttpClient/CachedHttpClient.php rename to lib/Github/HttpClient/Adapter/Buzz/CachedHttpClient.php index f28f54bd9e2..395ebb9d767 100644 --- a/lib/Github/HttpClient/CachedHttpClient.php +++ b/lib/Github/HttpClient/Adapter/Buzz/CachedHttpClient.php @@ -1,9 +1,10 @@ options['base_url'].$path, '/'); - if (304 == $response->getStatusCode()) { + if (304 == $buzzResponse->getStatusCode()) { return $this->getCache()->get($key); } - $this->getCache()->set($key, $response); + $this->getCache()->set($key, new Response($buzzResponse)); - return $response; + return $buzzResponse; } /** diff --git a/lib/Github/HttpClient/HttpClient.php b/lib/Github/HttpClient/Adapter/Buzz/HttpClient.php similarity index 78% rename from lib/Github/HttpClient/HttpClient.php rename to lib/Github/HttpClient/Adapter/Buzz/HttpClient.php index 3538f102589..6b6f9009704 100644 --- a/lib/Github/HttpClient/HttpClient.php +++ b/lib/Github/HttpClient/Adapter/Buzz/HttpClient.php @@ -1,24 +1,26 @@ */ -class HttpClient implements HttpClientInterface +class HttpClient extends AbstractAdapter { /** * @var array @@ -43,8 +45,8 @@ class HttpClient implements HttpClientInterface */ protected $headers = array(); - private $lastResponse; - private $lastRequest; + protected $lastResponse; + protected $lastRequest; /** * @param array $options @@ -65,19 +67,6 @@ public function __construct(array $options = array(), ClientInterface $client = $this->clearHeaders(); } - public function authenticate($tokenOrLogin, $password, $authMethod) - { - $this->addListener( - new AuthListener( - $authMethod, - array( - 'tokenOrLogin' => $tokenOrLogin, - 'password' => $password - ) - ) - ); - } - /** * {@inheritDoc} */ @@ -113,6 +102,16 @@ public function addListener(ListenerInterface $listener) $this->listeners[get_class($listener)] = $listener; } + /** + * Returns listeners + * + * @return array + */ + public function getListeners() + { + return $this->listeners; + } + /** * {@inheritDoc} */ @@ -172,11 +171,8 @@ public function request($path, array $parameters = array(), $httpMethod = 'GET', $request->setContent(json_encode($parameters, empty($parameters) ? JSON_FORCE_OBJECT : 0)); } - $hasListeners = 0 < count($this->listeners); - if ($hasListeners) { - foreach ($this->listeners as $listener) { - $listener->preSend($request); - } + foreach ($this->listeners as $listener) { + $listener->preSend($request); } $response = $this->createResponse(); @@ -189,24 +185,30 @@ public function request($path, array $parameters = array(), $httpMethod = 'GET', throw new RuntimeException($e->getMessage()); } - $this->lastRequest = $request; - $this->lastResponse = $response; - - if ($hasListeners) { - foreach ($this->listeners as $listener) { - $listener->postSend($request, $response); - } + foreach ($this->listeners as $listener) { + $listener->postSend($request, $response); } + $this->lastRequest = new Request($request); + $this->lastResponse = new Response($response); + return $response; } /** - * @return Request + * {@inheritdoc} */ - public function getLastRequest() + public function authenticate($method, $tokenOrLogin, $password = null) { - return $this->lastRequest; + $this->addListener( + new AuthListener( + $method, + array( + 'tokenOrLogin' => $tokenOrLogin, + 'password' => $password + ) + ) + ); } /** @@ -221,11 +223,11 @@ public function getLastResponse() * @param string $httpMethod * @param string $url * - * @return Request + * @return BuzzRequest */ protected function createRequest($httpMethod, $url) { - $request = new Request($httpMethod); + $request = new BuzzRequest($httpMethod); $request->setHeaders($this->headers); $request->fromUrl($url); @@ -233,10 +235,10 @@ protected function createRequest($httpMethod, $url) } /** - * @return Response + * @return BuzzResponse */ protected function createResponse() { - return new Response(); + return new BuzzResponse(); } } diff --git a/lib/Github/HttpClient/Listener/AuthListener.php b/lib/Github/HttpClient/Adapter/Buzz/Listener/AuthListener.php similarity index 90% rename from lib/Github/HttpClient/Listener/AuthListener.php rename to lib/Github/HttpClient/Adapter/Buzz/Listener/AuthListener.php index 1f5e9e64b2f..7ea8ebceecc 100644 --- a/lib/Github/HttpClient/Listener/AuthListener.php +++ b/lib/Github/HttpClient/Adapter/Buzz/Listener/AuthListener.php @@ -1,6 +1,6 @@ options = $options; } + /** + * Returns authentication method + * + * @return string + */ + public function getMethod() + { + return $this->method; + } + + /** + * Returns Options + * + * @return array + */ + public function getOptions() + { + return $this->options; + } + /** * {@inheritDoc} * diff --git a/lib/Github/HttpClient/Listener/ErrorListener.php b/lib/Github/HttpClient/Adapter/Buzz/Listener/ErrorListener.php similarity index 96% rename from lib/Github/HttpClient/Listener/ErrorListener.php rename to lib/Github/HttpClient/Adapter/Buzz/Listener/ErrorListener.php index 3f2963fc995..792412928d9 100644 --- a/lib/Github/HttpClient/Listener/ErrorListener.php +++ b/lib/Github/HttpClient/Adapter/Buzz/Listener/ErrorListener.php @@ -1,6 +1,6 @@ isClientError() || $response->isServerError()) { $remaining = $response->getHeader('X-RateLimit-Remaining'); diff --git a/lib/Github/HttpClient/Adapter/Buzz/Message/Request.php b/lib/Github/HttpClient/Adapter/Buzz/Message/Request.php new file mode 100644 index 00000000000..60809beec70 --- /dev/null +++ b/lib/Github/HttpClient/Adapter/Buzz/Message/Request.php @@ -0,0 +1,21 @@ +request = $request; + } + + public function getAdapterRequest() + { + return $this->request; + } +} diff --git a/lib/Github/HttpClient/Adapter/Buzz/Message/Response.php b/lib/Github/HttpClient/Adapter/Buzz/Message/Response.php new file mode 100644 index 00000000000..7d10b004427 --- /dev/null +++ b/lib/Github/HttpClient/Adapter/Buzz/Message/Response.php @@ -0,0 +1,59 @@ +response = $response; + } + + /** + * {@inheritdoc} + */ + public function getStatusCode() + { + return $this->response->getStatusCode(); + } + + /** + * {@inheritdoc} + */ + public function getHeaderAsString($name) + { + return $this->response->getHeader($name); + } + + /** + * {@inheritdoc} + */ + public function isNotModified() + { + return 304 === $this->getStatusCode(); + } + + /** + * {@inheritdoc} + */ + public function getAdapterResponse() + { + return $this->response; + } + + /** + * {@inheritdoc} + * + * @return BuzzResponse + */ + public function getRawBody() + { + return $this->response->getContent(); + } +} diff --git a/lib/Github/HttpClient/Adapter/Guzzle/HttpClient.php b/lib/Github/HttpClient/Adapter/Guzzle/HttpClient.php new file mode 100644 index 00000000000..550b9e2bae4 --- /dev/null +++ b/lib/Github/HttpClient/Adapter/Guzzle/HttpClient.php @@ -0,0 +1,164 @@ +setBaseUrl($this->options['base_url']); + $client->setSslVerification(false); + + $opts = $client->getConfig(GuzzleClient::CURL_OPTIONS); + $opts[CURLOPT_TIMEOUT] = $this->options['timeout']; + + $client->getConfig()->set(GuzzleClient::CURL_OPTIONS, $opts); + + $this->options = array_merge($this->options, $options); + $this->client = $client; + +// $this->addListener(new ErrorListener($this->options)); + + $this->clearHeaders(); + } + + /** + * {@inheritDoc} + */ + public function get($path, array $parameters = array(), array $headers = array()) + { + if (0 < count($parameters)) { + $path .= (false === strpos($path, '?') ? '?' : '&') . http_build_query($parameters, '', '&'); + } + + return $this->request($path, array(), 'GET', $headers); + } + + /** + * {@inheritDoc} + */ + public function post($path, array $parameters = array(), array $headers = array()) + { + return $this->request($path, $parameters, 'POST', $headers); + } + + /** + * {@inheritDoc} + */ + public function patch($path, array $parameters = array(), array $headers = array()) + { + return $this->request($path, $parameters, 'PATCH', $headers); + } + + /** + * {@inheritDoc} + */ + public function delete($path, array $parameters = array(), array $headers = array()) + { + return $this->request($path, $parameters, 'DELETE', $headers); + } + + /** + * {@inheritDoc} + */ + public function put($path, array $parameters = array(), array $headers = array()) + { + return $this->request($path, $parameters, 'PUT', $headers); + } + + /** + * {@inheritDoc} + */ + public function request($path, array $parameters = array(), $httpMethod = 'GET', array $headers = array()) + { + $path = trim($path, '/'); + + $request = $this->client->createRequest($httpMethod, $path, $headers, json_encode($parameters)); + + try { + $response = new Response($request->send()); + } catch (GuzzleException $e) { + throw new RuntimeException($e->getMessage()); + } + + $this->lastRequest = $request; + $this->lastResponse = $response; + + return $response; + } + + /** + * {@inheritdoc} + */ + public function authenticate($method, $tokenOrLogin, $password = null) + { + switch ($method) { + case Client::AUTH_HTTP_PASSWORD: + $handler = function (Event $event) use ($tokenOrLogin, $password) { + $event['request']->setHeader( + 'Authorization', + sprintf('Basic ', base64_encode($tokenOrLogin . ':' . $password)) + ); + }; + break; + + case Client::AUTH_HTTP_TOKEN: + $handler = function (Event $event) use ($tokenOrLogin, $password) { + $event['request']->setHeader('Authorization', sprintf('token ', $tokenOrLogin)); + }; + break; + + case Client::AUTH_URL_CLIENT_ID: + $handler = function (Event $event) use ($tokenOrLogin, $password) { + $url = $event['request']->getUrl(); + + $parameters = array( + 'client_id' => $tokenOrLogin, + 'client_secret' => $password, + ); + + $url .= (false === strpos($url, '?') ? '?' : '&'); + $url .= utf8_encode(http_build_query($parameters, '', '&')); + + $event['request']->setUrl($url); + }; + break; + + case Client::AUTH_URL_TOKEN: + $handler = function (Event $event) use ($tokenOrLogin, $password) { + $url = $event['request']->getUrl(); + $url .= (false === strpos($url, '?') ? '?' : '&'); + $url .= utf8_encode(http_build_query(array('access_token' => $tokenOrLogin), '', '&')); + + $event['request']->setUrl($url); + }; + break; + + default: + throw new RuntimeException(sprintf('%s not yet implemented', $method)); + break; + } + + $this->client->getEventDispatcher()->addListener('request.create', $handler); + } +} diff --git a/lib/Github/HttpClient/Adapter/Guzzle/Message/Response.php b/lib/Github/HttpClient/Adapter/Guzzle/Message/Response.php new file mode 100644 index 00000000000..6f300baac84 --- /dev/null +++ b/lib/Github/HttpClient/Adapter/Guzzle/Message/Response.php @@ -0,0 +1,51 @@ +response = $response; + } + + /** + * {@inheritdoc} + */ + public function getRawBody() + { + return $this->response->getBody(true); + } + + /** + * {@inheritdoc} + */ + public function getStatusCode() + { + return $this->response->getStatusCode(); + } + + /** + * {@inheritdoc} + */ + public function getHeaderAsString($name) + { + return $this->response->getHeader($name, true); + } + + /** + * {@inheritdoc} + * + * @return GuzzleResponse + */ + public function getAdapterResponse() + { + return $this->response; + } +} diff --git a/lib/Github/HttpClient/Cache/CacheInterface.php b/lib/Github/HttpClient/Cache/CacheInterface.php index b1ada0e53d9..99a2ad67e81 100644 --- a/lib/Github/HttpClient/Cache/CacheInterface.php +++ b/lib/Github/HttpClient/Cache/CacheInterface.php @@ -2,7 +2,7 @@ namespace Github\HttpClient\Cache; -use Github\HttpClient\Message\Response; +use Github\HttpClient\ResponseInterface; /** * Caches github api responses @@ -21,17 +21,18 @@ public function getModifiedSince($id); /** * @param string $id The id of the cached resource * - * @return Response The cached response object + * @return ResponseInterface The cached response object * * @throws \InvalidArgumentException If cache data don't exists */ public function get($id); /** - * @param string $id The id of the cached resource - * @param Response $response The response to cache + * @param string $id The id of the cached resource + * @param ResponseInterface $response The response to cache * * @throws \InvalidArgumentException If cache data cannot be saved */ - public function set($id, Response $response); + public function set($id, ResponseInterface $response); } + diff --git a/lib/Github/HttpClient/Cache/FilesystemCache.php b/lib/Github/HttpClient/Cache/FilesystemCache.php index ad1f90821cf..ae0094af250 100644 --- a/lib/Github/HttpClient/Cache/FilesystemCache.php +++ b/lib/Github/HttpClient/Cache/FilesystemCache.php @@ -2,7 +2,7 @@ namespace Github\HttpClient\Cache; -use Github\HttpClient\Message\Response; +use Github\HttpClient\ResponseInterface; class FilesystemCache implements CacheInterface { @@ -34,7 +34,7 @@ public function get($id) /** * {@inheritdoc} */ - public function set($id, Response $response) + public function set($id, ResponseInterface $response) { if (!is_dir($this->path)) { @mkdir($this->path, 0777, true); diff --git a/lib/Github/HttpClient/HttpClientInterface.php b/lib/Github/HttpClient/HttpClientInterface.php index 09ee8d11708..ca8dccf4d04 100644 --- a/lib/Github/HttpClient/HttpClientInterface.php +++ b/lib/Github/HttpClient/HttpClientInterface.php @@ -97,13 +97,44 @@ public function setOption($name, $value); public function setHeaders(array $headers); /** - * Authenticate a user for all next requests + * Removes all headers previously set + */ + public function clearHeaders(); + + /** + * Authenticate HttpClient requests with parameters + * + * @param string $method + * @param string $tokenOrLogin + * @param string|null $password + */ + public function authenticate($method, $tokenOrLogin, $password = null); + + /** + * Return the last request that has been executed + * + * @return RequestInterface + */ + public function getLastRequest(); + + /** + * Return the last response that has been received * - * @param string $tokenOrLogin GitHub private token/username/client ID - * @param null|string $password GitHub password/secret (optionally can contain $authMethod) - * @param null|string $authMethod One of the AUTH_* class constants + * @return ResponseInterface + */ + public function getLastResponse(); + + /** + * Return the API Limit with the current authentication state + * + * @return Integer + */ + public function getAPILimit(); + + /** + * Return the API remaining request quantity with the current authentication state * - * @throws InvalidArgumentException If no authentication method was given + * @return Integer */ - public function authenticate($tokenOrLogin, $password, $authMethod); + public function getAPIRemaining(); } diff --git a/lib/Github/HttpClient/Message/AbstractResponse.php b/lib/Github/HttpClient/Message/AbstractResponse.php new file mode 100644 index 00000000000..069f3201886 --- /dev/null +++ b/lib/Github/HttpClient/Message/AbstractResponse.php @@ -0,0 +1,54 @@ +getRawBody(); + $content = json_decode($rawBody, true); + + if (JSON_ERROR_NONE !== json_last_error()) { + throw new InvalidJsonResponse($rawBody); + } + + return $content; + } + + /** + * {@inheritdoc} + */ + public function getPagination() + { + $header = $this->getHeaderAsString('Link'); + if (empty($header)) { + return null; + } + + $pagination = array(); + foreach (explode(',', $header) as $link) { + preg_match('/<(.*)>; rel="(.*)"/i', trim($link, ','), $match); + + if (3 === count($match)) { + $pagination[$match[2]] = $match[1]; + } + } + + return $pagination; + } + + /** + * {@inheritdoc} + */ + public function isNotModified() + { + return 304 === $this->getStatusCode(); + } +} diff --git a/lib/Github/HttpClient/Message/Request.php b/lib/Github/HttpClient/Message/Request.php deleted file mode 100644 index cbc206809de..00000000000 --- a/lib/Github/HttpClient/Message/Request.php +++ /dev/null @@ -1,10 +0,0 @@ -getHeader('Link'); - if (empty($header)) { - return null; - } - - $pagination = array(); - foreach (explode(',', $header) as $link) { - preg_match('/<(.*)>; rel="(.*)"/i', trim($link, ','), $match); - - if (3 === count($match)) { - $pagination[$match[2]] = $match[1]; - } - } - - return $pagination; - } - - /** - * {@inheritDoc} - */ - public function getApiLimit() - { - $header = $this->getHeader('X-RateLimit-Remaining'); - if (!empty($header)) { - $this->remainingCalls = $header; - } - - if (null !== $this->remainingCalls && 1 > $this->remainingCalls) { - throw new ApiLimitExceedException($this->getHeader('X-RateLimit-Limit')); - } - } -} diff --git a/lib/Github/HttpClient/RequestInterface.php b/lib/Github/HttpClient/RequestInterface.php new file mode 100644 index 00000000000..5a2131af0f8 --- /dev/null +++ b/lib/Github/HttpClient/RequestInterface.php @@ -0,0 +1,11 @@ +getResponseMock($expectedArray); $httpClient = $this->getHttpMock(); $httpClient - ->expects($this->any()) - ->method('get') - ->with('/path', array('param1' => 'param1value'), array('header1' => 'header1value')) - ->will($this->returnValue($expectedArray)); + ->expects($this->once()) + ->method('request') + ->with('/path', array('param1' => 'param1value'), 'GET', array('header1' => 'header1value')) + ->will($this->returnValue($response)); + $client = $this->getClientMock(); $client->setHttpClient($httpClient); @@ -37,9 +39,10 @@ public function shouldPassPOSTRequestToClient() $httpClient = $this->getHttpMock(); $httpClient ->expects($this->once()) - ->method('post') - ->with('/path', array('param1' => 'param1value'), array('option1' => 'option1value')) - ->will($this->returnValue($expectedArray)); + ->method('request') + ->with('/path', array('param1' => 'param1value'), 'POST', array('option1' => 'option1value')) + ->will($this->returnValue($this->getResponseMock($expectedArray))); + $client = $this->getClientMock(); $client->setHttpClient($httpClient); @@ -58,9 +61,9 @@ public function shouldPassPATCHRequestToClient() $httpClient = $this->getHttpMock(); $httpClient ->expects($this->once()) - ->method('patch') - ->with('/path', array('param1' => 'param1value'), array('option1' => 'option1value')) - ->will($this->returnValue($expectedArray)); + ->method('request') + ->with('/path', array('param1' => 'param1value'), 'PATCH', array('option1' => 'option1value')) + ->will($this->returnValue($this->getResponseMock($expectedArray))); $client = $this->getClientMock(); $client->setHttpClient($httpClient); @@ -79,9 +82,9 @@ public function shouldPassPUTRequestToClient() $httpClient = $this->getHttpMock(); $httpClient ->expects($this->once()) - ->method('put') - ->with('/path', array('param1' => 'param1value'), array('option1' => 'option1value')) - ->will($this->returnValue($expectedArray)); + ->method('request') + ->with('/path', array('param1' => 'param1value'), 'PUT', array('option1' => 'option1value')) + ->will($this->returnValue($this->getResponseMock($expectedArray))); $client = $this->getClientMock(); $client->setHttpClient($httpClient); @@ -100,9 +103,9 @@ public function shouldPassDELETERequestToClient() $httpClient = $this->getHttpMock(); $httpClient ->expects($this->once()) - ->method('delete') - ->with('/path', array('param1' => 'param1value'), array('option1' => 'option1value')) - ->will($this->returnValue($expectedArray)); + ->method('request') + ->with('/path', array('param1' => 'param1value'), 'DELETE', array('option1' => 'option1value')) + ->will($this->returnValue($this->getResponseMock($expectedArray))); $client = $this->getClientMock(); $client->setHttpClient($httpClient); @@ -129,12 +132,12 @@ protected function getClientMock() */ protected function getHttpMock() { - return $this->getMock('Github\HttpClient\HttpClient', array(), array(array(), $this->getHttpClientMock())); + return $this->getMock('Github\HttpClient\HttpClientInterface', array(), array(array(), $this->getHttpClientMock())); } protected function getHttpClientMock() { - $mock = $this->getMock('Buzz\Client\ClientInterface', array('setTimeout', 'setVerifyPeer', 'send')); + $mock = $this->getMock('Buzz\Client\ClientInterface', array('setTimeout', 'setVerifyPeer', 'send', 'request')); $mock ->expects($this->any()) ->method('setTimeout') @@ -149,6 +152,28 @@ protected function getHttpClientMock() return $mock; } + + protected function getResponseMock($expectedValue, $times = 1) + { + $mock = $this + ->getMockBuilder('Github\\HttpClient\\ResponseInterface') + ->setMethods(array( + 'getContent', 'getPagination', + 'isNotModified', 'getHeaderAsString', + 'getStatusCode', 'getRawBody', + 'getAdapterResponse' + )) + ->getMock() + ; + + $mock + ->expects($this->exactly($times)) + ->method('getContent') + ->will($this->returnValue($expectedValue)) + ; + + return $mock; + } } class AbstractApiTestInstance extends AbstractApi @@ -158,7 +183,7 @@ class AbstractApiTestInstance extends AbstractApi */ public function get($path, array $parameters = array(), $requestHeaders = array()) { - return $this->client->getHttpClient()->get($path, $parameters, $requestHeaders); + return $this->client->executeRequest('GET', $path, $parameters, $requestHeaders); } /** @@ -166,7 +191,7 @@ public function get($path, array $parameters = array(), $requestHeaders = array( */ public function post($path, array $parameters = array(), $requestHeaders = array()) { - return $this->client->getHttpClient()->post($path, $parameters, $requestHeaders); + return $this->client->executeRequest('POST', $path, $parameters, $requestHeaders); } /** @@ -174,7 +199,7 @@ public function post($path, array $parameters = array(), $requestHeaders = array */ public function patch($path, array $parameters = array(), $requestHeaders = array()) { - return $this->client->getHttpClient()->patch($path, $parameters, $requestHeaders); + return $this->client->executeRequest('PATCH', $path, $parameters, $requestHeaders); } /** @@ -182,7 +207,7 @@ public function patch($path, array $parameters = array(), $requestHeaders = arra */ public function put($path, array $parameters = array(), $requestHeaders = array()) { - return $this->client->getHttpClient()->put($path, $parameters, $requestHeaders); + return $this->client->executeRequest('PUT', $path, $parameters, $requestHeaders); } /** @@ -190,6 +215,6 @@ public function put($path, array $parameters = array(), $requestHeaders = array( */ public function delete($path, array $parameters = array(), $requestHeaders = array()) { - return $this->client->getHttpClient()->delete($path, $parameters, $requestHeaders); + return $this->client->executeRequest('DELETE', $path, $parameters, $requestHeaders); } } diff --git a/test/Github/Tests/Api/TestCase.php b/test/Github/Tests/Api/TestCase.php index 5bae9b02972..cd59a88aecb 100644 --- a/test/Github/Tests/Api/TestCase.php +++ b/test/Github/Tests/Api/TestCase.php @@ -21,7 +21,7 @@ protected function getApiMock() ->expects($this->any()) ->method('send'); - $mock = $this->getMock('Github\HttpClient\HttpClient', array(), array(array(), $httpClient)); + $mock = $this->getMock('Github\HttpClient\HttpClientInterface', array(), array(array(), $httpClient)); $client = new \Github\Client($mock); $client->setHttpClient($mock); diff --git a/test/Github/Tests/ClientTest.php b/test/Github/Tests/ClientTest.php index 29e926b246a..c1b89e8bda4 100644 --- a/test/Github/Tests/ClientTest.php +++ b/test/Github/Tests/ClientTest.php @@ -3,7 +3,7 @@ namespace Github\Tests; use Github\Client; -use Github\Exception\InvalidArgumentException; +use Github\HttpClient\Adapter\Buzz\Listener\AuthListener; class ClientTest extends \PHPUnit_Framework_TestCase { @@ -14,65 +14,18 @@ public function shouldNotHaveToPassHttpClientToConstructor() { $client = new Client(); - $this->assertInstanceOf('Github\HttpClient\HttpClient', $client->getHttpClient()); - } - - /** - * @test - */ - public function shouldPassHttpClientInterfaceToConstructor() - { - $client = new Client($this->getHttpClientMock()); - $this->assertInstanceOf('Github\HttpClient\HttpClientInterface', $client->getHttpClient()); } /** * @test - * @dataProvider getAuthenticationFullData */ - public function shouldAuthenticateUsingAllGivenParameters($login, $password, $method) - { - $httpClient = $this->getHttpClientMock(); - $httpClient->expects($this->once()) - ->method('authenticate') - ->with($login, $password, $method); - - $client = new Client($httpClient); - $client->authenticate($login, $password, $method); - } - - public function getAuthenticationFullData() - { - return array( - array('login', 'password', Client::AUTH_HTTP_PASSWORD), - array('token', null, Client::AUTH_HTTP_TOKEN), - array('token', null, Client::AUTH_URL_TOKEN), - array('client_id', 'client_secret', Client::AUTH_URL_CLIENT_ID), - ); - } - - /** - * @test - * @dataProvider getAuthenticationPartialData - */ - public function shouldAuthenticateUsingGivenParameters($token, $method) + public function shouldPassHttpClientInterfaceToConstructor() { $httpClient = $this->getHttpClientMock(); - $httpClient->expects($this->once()) - ->method('authenticate') - ->with($token, null, $method); - $client = new Client($httpClient); - $client->authenticate($token, $method); - } - public function getAuthenticationPartialData() - { - return array( - array('token', Client::AUTH_HTTP_TOKEN), - array('token', Client::AUTH_URL_TOKEN), - ); + $this->assertEquals($httpClient, $client->getHttpClient()); } /** @@ -92,7 +45,7 @@ public function shouldThrowExceptionWhenAuthenticatingWithoutMethodSet() */ public function shouldClearHeadersLazy() { - $httpClient = $this->getHttpClientMock(array('clearHeaders')); + $httpClient = $this->getHttpClientMock(); $httpClient->expects($this->once())->method('clearHeaders'); $client = new Client($httpClient); @@ -174,7 +127,11 @@ public function getApiClassesProvider() public function getHttpClientMock(array $methods = array()) { $methods = array_merge( - array('get', 'post', 'patch', 'put', 'delete', 'request', 'setOption', 'setHeaders', 'authenticate'), + array( + 'get', 'post', 'patch', 'put', 'delete', 'request', + 'setOption', 'setHeaders', 'clearHeaders', 'authenticate', + 'getLastRequest', 'getLastResponse', 'getAPILimit', 'getAPIRemaining' + ), $methods ); diff --git a/test/Github/Tests/HttpClient/CachedHttpClientTest.php b/test/Github/Tests/HttpClient/Adapter/Buzz/CachedHttpClientTest.php similarity index 84% rename from test/Github/Tests/HttpClient/CachedHttpClientTest.php rename to test/Github/Tests/HttpClient/Adapter/Buzz/CachedHttpClientTest.php index 5a5e29dfde9..61e6ff1e043 100644 --- a/test/Github/Tests/HttpClient/CachedHttpClientTest.php +++ b/test/Github/Tests/HttpClient/Adapter/Buzz/CachedHttpClientTest.php @@ -1,9 +1,10 @@ setCache($cache); - $cache->expects($this->once())->method('set')->with('test', new Response); + $cache->expects($this->once())->method('set')->with('test', new Response(new BuzzResponse())); $httpClient->get('test'); } @@ -35,7 +36,7 @@ public function shouldGetCachedResponseWhileResourceNotModified() $cache = $this->getCacheMock(); - $response = new Response; + $response = new BuzzResponse(); $response->addHeader('HTTP/1.1 304 Not Modified'); $httpClient = new TestCachedHttpClient( @@ -60,7 +61,7 @@ public function shouldRenewCacheWhenResourceHasChanged() $cache = $this->getCacheMock(); - $response = new Response; + $response = new BuzzResponse(); $response->addHeader('HTTP/1.1 200 OK'); $httpClient = new TestCachedHttpClient( @@ -70,7 +71,7 @@ public function shouldRenewCacheWhenResourceHasChanged() $httpClient->setCache($cache); $httpClient->fakeResponse = $response; - $cache->expects($this->once())->method('set')->with('test', $response); + $cache->expects($this->once())->method('set')->with('test', new Response($response)); $cache->expects($this->once())->method('getModifiedSince')->with('test')->will($this->returnValue(1256953732)); $httpClient->get('test'); @@ -88,6 +89,6 @@ class TestCachedHttpClient extends CachedHttpClient protected function createResponse() { - return $this->fakeResponse ?: new Response(); + return $this->fakeResponse ?: new BuzzResponse(); } } diff --git a/test/Github/Tests/HttpClient/HttpClientTest.php b/test/Github/Tests/HttpClient/Adapter/Buzz/HttpClientTest.php similarity index 68% rename from test/Github/Tests/HttpClient/HttpClientTest.php rename to test/Github/Tests/HttpClient/Adapter/Buzz/HttpClientTest.php index 4fc44717537..f9bf35169f9 100644 --- a/test/Github/Tests/HttpClient/HttpClientTest.php +++ b/test/Github/Tests/HttpClient/Adapter/Buzz/HttpClientTest.php @@ -1,11 +1,13 @@ assertEquals(666, $httpClient->getOption('timeout')); } - /** - * @test - * @dataProvider getAuthenticationFullData - */ - public function shouldAuthenticateUsingAllGivenParameters($login, $password, $method) - { - $client = new TestHttpClient(); - $client->authenticate($login, $password, $method); - - $this->assertCount(2, $client->listeners); - $this->assertInstanceOf('Github\HttpClient\Listener\AuthListener', $client->listeners['Github\HttpClient\Listener\AuthListener']); - } - - public function getAuthenticationFullData() - { - return array( - array('login', 'password', Client::AUTH_HTTP_PASSWORD), - array('token', null, Client::AUTH_HTTP_TOKEN), - array('token', null, Client::AUTH_URL_TOKEN), - array('client_id', 'client_secret', Client::AUTH_URL_CLIENT_ID), - ); - } - /** * @test */ @@ -84,8 +63,6 @@ public function shouldDoPOSTRequest() $httpClient = new HttpClient(array(), $client); $httpClient->post($path, $parameters, $headers); - - $this->assertEquals('{"a":"b"}', $httpClient->getLastRequest()->getContent()); } /** @@ -99,8 +76,6 @@ public function shouldDoPOSTRequestWithoutContent() $httpClient = new HttpClient(array(), $client); $httpClient->post($path); - - $this->assertEmpty($httpClient->getLastRequest()->getContent()); } /** @@ -171,8 +146,8 @@ public function shouldHandlePagination() $parameters = array('a' => 'b'); $headers = array('c' => 'd'); - $response = new Response(); - $response->addHeader("Link:; rel=\"page2\", \n; rel=\"page4\""); + $response = new Response(new BuzzResponse()); + $response->getAdapterResponse()->addHeader("Link:; rel=\"page2\", \n; rel=\"page4\""); $client = $this->getBrowserMock(); @@ -191,11 +166,31 @@ public function shouldAllowToReturnRawContent() $parameters = array('a' => 'b'); $headers = array('c' => 'd'); - $message = $this->getMock('Github\HttpClient\Message\Response'); + $buzzMessage = $this + ->getMockBuilder('Buzz\Message\Response') + ->getMock(); + + $buzzMessage->expects($this->once()) + ->method('isClientError') + ->will($this->returnValue(false)); + + $buzzMessage->expects($this->once()) + ->method('isServerError') + ->will($this->returnValue(false)); + + $message = $this + ->getMockBuilder('Github\HttpClient\Adapter\Buzz\Message\Response') + ->disableOriginalConstructor() + ->getMock(); + $message->expects($this->once()) ->method('getContent') ->will($this->returnValue('Just raw context')); + $message->expects($this->exactly(2)) + ->method('getAdapterResponse') + ->will($this->returnValue($buzzMessage)); + $client = $this->getBrowserMock(); $httpClient = new TestHttpClient(array(), $client); @@ -204,7 +199,7 @@ public function shouldAllowToReturnRawContent() $response = $httpClient->get($path, $parameters, $headers); $this->assertEquals("Just raw context", $response->getContent()); - $this->assertInstanceOf('Buzz\Message\MessageInterface', $response); + $this->assertInstanceOf('Buzz\Message\MessageInterface', $response->getAdapterResponse()); } /** @@ -217,9 +212,9 @@ public function shouldThrowExceptionWhenApiIsExceeded() $parameters = array('a' => 'b'); $headers = array('c' => 'd'); - $response = new Response(); - $response->addHeader('HTTP/1.1 403 Forbidden'); - $response->addHeader('X-RateLimit-Remaining: 0'); + $response = new Response(new BuzzResponse()); + $response->getAdapterResponse()->addHeader('HTTP/1.1 403 Forbidden'); + $response->getAdapterResponse()->addHeader('X-RateLimit-Remaining: 0'); $httpClient = new TestHttpClient(array(), $this->getBrowserMock()); $httpClient->fakeResponse = $response; @@ -227,6 +222,64 @@ public function shouldThrowExceptionWhenApiIsExceeded() $httpClient->get($path, $parameters, $headers); } + /** + * @test + * @dataProvider getAuthenticationFullData + */ + public function shouldAuthenticateUsingAllGivenParameters($login, $password, $method) + { + $httpClient = new HttpClient(); + + $n = count($httpClient->getListeners()); + + $httpClient->authenticate($method, $login, $password); + + $listeners = $httpClient->getListeners(); + $this->assertCount($n + 1, $listeners); + + $listener = array_pop($listeners); + $this->assertEquals($method, $listener->getMethod()); + $this->assertEquals(array('tokenOrLogin' => $login, 'password' => $password), $listener->getOptions()); + } + + public function getAuthenticationFullData() + { + return array( + array('login', 'password', Client::AUTH_HTTP_PASSWORD), + array('token', null, Client::AUTH_HTTP_TOKEN), + array('token', null, Client::AUTH_URL_TOKEN), + array('client_id', 'client_secret', Client::AUTH_URL_CLIENT_ID), + ); + } + + /** + * @test + * @dataProvider getAuthenticationPartialData + */ + public function shouldAuthenticateUsingGivenParameters($token, $method) + { + $httpClient = new HttpClient(); + + $n = count($httpClient->getListeners()); + + $httpClient->authenticate($method, $token); + + $listeners = $httpClient->getListeners(); + $this->assertCount($n + 1, $listeners); + + $listener = array_pop($listeners); + $this->assertEquals($method, $listener->getMethod()); + $this->assertEquals(array('tokenOrLogin' => $token, 'password' => null), $listener->getOptions()); + } + + public function getAuthenticationPartialData() + { + return array( + array('token', Client::AUTH_HTTP_TOKEN), + array('token', Client::AUTH_URL_TOKEN), + ); + } + protected function getBrowserMock(array $methods = array()) { return $this->getMock( @@ -259,7 +312,7 @@ public function request($path, array $parameters = array(), $httpMethod = 'GET', $response = $this->createResponse(); if (0 < count($this->listeners)) { foreach ($this->listeners as $listener) { - $listener->postSend($request, $response); + $listener->postSend($request->getAdapterRequest(), $response->getAdapterResponse()); } } @@ -268,11 +321,11 @@ public function request($path, array $parameters = array(), $httpMethod = 'GET', protected function createRequest($httpMethod, $url) { - return new Request($httpMethod); + return new Request(new BuzzRequest($httpMethod)); } protected function createResponse() { - return $this->fakeResponse ?: new Response(); + return $this->fakeResponse ?: new Response(new BuzzResponse()); } } diff --git a/test/Github/Tests/HttpClient/Listener/AuthListenerTest.php b/test/Github/Tests/HttpClient/Adapter/Buzz/Listener/AuthListenerTest.php similarity index 94% rename from test/Github/Tests/HttpClient/Listener/AuthListenerTest.php rename to test/Github/Tests/HttpClient/Adapter/Buzz/Listener/AuthListenerTest.php index cfd741c7a0c..b8bb006b385 100644 --- a/test/Github/Tests/HttpClient/Listener/AuthListenerTest.php +++ b/test/Github/Tests/HttpClient/Adapter/Buzz/Listener/AuthListenerTest.php @@ -1,11 +1,11 @@ 'test')); $listener->preSend($request); @@ -169,7 +169,7 @@ public function shouldSetTokenInUrlForAuthUrlMethod() */ public function shouldSetClientDetailsInUrlForAuthUrlMethod() { - $request = new Request(Request::METHOD_GET, '/res'); + $request = new BuzzRequest(BuzzRequest::METHOD_GET, '/res'); $listener = new AuthListener(Client::AUTH_URL_CLIENT_ID, array('tokenOrLogin' => 'clientId', 'password' => 'clientSsecret')); $listener->preSend($request); diff --git a/test/Github/Tests/HttpClient/Listener/ErrorListenerTest.php b/test/Github/Tests/HttpClient/Adapter/Buzz/Listener/ErrorListenerTest.php similarity index 89% rename from test/Github/Tests/HttpClient/Listener/ErrorListenerTest.php rename to test/Github/Tests/HttpClient/Adapter/Buzz/Listener/ErrorListenerTest.php index 3a539343370..1eb9bb13c54 100644 --- a/test/Github/Tests/HttpClient/Listener/ErrorListenerTest.php +++ b/test/Github/Tests/HttpClient/Adapter/Buzz/Listener/ErrorListenerTest.php @@ -1,17 +1,17 @@ getMock('Github\HttpClient\Message\Response'); + $response = $this->getMock('Buzz\Message\Response'); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(false)); @@ -26,7 +26,7 @@ public function shouldPassIfResponseNotHaveErrorStatus() */ public function shouldFailWhenApiLimitWasExceed() { - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMock('Buzz\Message\Response'); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); @@ -45,7 +45,7 @@ public function shouldFailWhenApiLimitWasExceed() */ public function shouldNotPassWhenContentWasNotValidJson() { - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMock('Buzz\Message\Response'); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); @@ -67,7 +67,7 @@ public function shouldNotPassWhenContentWasNotValidJson() */ public function shouldNotPassWhenContentWasValidJsonButStatusIsNotCovered() { - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMock('Buzz\Message\Response'); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); @@ -92,7 +92,7 @@ public function shouldNotPassWhenContentWasValidJsonButStatusIsNotCovered() */ public function shouldNotPassWhen400IsSent() { - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMock('Buzz\Message\Response'); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); @@ -130,7 +130,7 @@ public function shouldNotPassWhen422IsSentWithErrorCode($errorCode) ) ); - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMock('Buzz\Message\Response'); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); diff --git a/test/Github/Tests/HttpClient/Cache/FilesystemCacheTest.php b/test/Github/Tests/HttpClient/Cache/FilesystemCacheTest.php index 841f38f690b..c7f2b571cca 100644 --- a/test/Github/Tests/HttpClient/Cache/FilesystemCacheTest.php +++ b/test/Github/Tests/HttpClient/Cache/FilesystemCacheTest.php @@ -2,7 +2,6 @@ namespace Github\Tests\HttpClient\Cache; -use Github\HttpClient\Message\Response; use Github\HttpClient\Cache\FilesystemCache; class FilesystemCacheTest extends \PHPUnit_Framework_TestCase @@ -14,7 +13,7 @@ public function shouldStoreAResponseForAGivenKey() { $cache = new FilesystemCache('/tmp/github-api-test'); - $cache->set('test', new Response); + $cache->set('test', $this->getMock('Github\HttpClient\ResponseInterface')); $this->assertNotNull($cache->get('test')); } @@ -26,7 +25,7 @@ public function shouldGetATimestampForExistingFile() { $cache = new FilesystemCache('/tmp/github-api-test'); - $cache->set('test', new Response); + $cache->set('test', $this->getMock('Github\HttpClient\ResponseInterface')); $this->assertInternalType('int', $cache->getModifiedSince('test')); } diff --git a/test/Github/Tests/ResultPagerTest.php b/test/Github/Tests/ResultPagerTest.php index 7d37bb4a957..819023cb2e5 100644 --- a/test/Github/Tests/ResultPagerTest.php +++ b/test/Github/Tests/ResultPagerTest.php @@ -97,7 +97,7 @@ public function postFetch() ); // response mock - $responseMock = $this->getMock('Github\HttpClient\Message\Response'); + $responseMock = $this->getMock('Github\HttpClient\Message\AbstractResponse'); $responseMock ->expects($this->any()) ->method('getPagination') @@ -187,7 +187,7 @@ public function shouldHavePrevious() protected function getResponseMock(array $pagination) { // response mock - $responseMock = $this->getMock('Github\HttpClient\Message\Response'); + $responseMock = $this->getMock('Github\HttpClient\Message\AbstractResponse'); $responseMock ->expects($this->any()) ->method('getPagination') @@ -211,22 +211,7 @@ protected function getClientMock(HttpClientInterface $httpClient = null) protected function getHttpClientMock($responseMock = null) { - // mock the client interface - $clientInterfaceMock = $this->getMock('Buzz\Client\ClientInterface', array('setTimeout', 'setVerifyPeer', 'send')); - $clientInterfaceMock - ->expects($this->any()) - ->method('setTimeout') - ->with(10); - $clientInterfaceMock - ->expects($this->any()) - ->method('setVerifyPeer') - ->with(false); - $clientInterfaceMock - ->expects($this->any()) - ->method('send'); - - // create the httpClient mock - $httpClientMock = $this->getMock('Github\HttpClient\HttpClient', array(), array(array(), $clientInterfaceMock)); + $httpClientMock = $this->getMock('Github\HttpClient\AbstractAdapter', array()); if ($responseMock) { $httpClientMock