diff --git a/README.markdown b/README.markdown index 3f82fffeda6..73e2f196d9c 100755 --- a/README.markdown +++ b/README.markdown @@ -15,7 +15,7 @@ Uses [GitHub API v3](http://developer.github.com/v3/). The object API is very si ## Requirements * PHP >= 5.3.2 with [cURL](http://php.net/manual/en/book.curl.php) extension, -* [Buzz](https://github.com/kriswallsmith/Buzz) library, +* [Guzzle](https://github.com/guzzle/guzzle) library, * (optional) PHPUnit to run tests. ## Autoload diff --git a/composer.json b/composer.json index 1f0c1c9f266..a9dbf2d1538 100644 --- a/composer.json +++ b/composer.json @@ -17,16 +17,19 @@ } ], "require": { - "php": ">=5.3.2", - "ext-curl": "*", - "kriswallsmith/buzz": ">=0.7" + "php": ">=5.3.2", + "ext-curl": "*", + "guzzle/guzzle": ">=3.7" + }, + "require-dev": { + "phpunit/phpunit": ">=3.7" }, "autoload": { "psr-0": { "Github\\": "lib/" } }, "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.3.x-dev" } } } diff --git a/lib/Github/Api/AbstractApi.php b/lib/Github/Api/AbstractApi.php index 727f4e51824..7ea594e3bf5 100644 --- a/lib/Github/Api/AbstractApi.php +++ b/lib/Github/Api/AbstractApi.php @@ -3,6 +3,7 @@ namespace Github\Api; use Github\Client; +use Github\HttpClient\Message\ResponseMediator; /** * Abstract class for Api classes @@ -65,7 +66,7 @@ protected function get($path, array $parameters = array(), $requestHeaders = arr } $response = $this->client->getHttpClient()->get($path, $parameters, $requestHeaders); - return $response->getContent(); + return ResponseMediator::getContent($response); } /** @@ -75,7 +76,7 @@ protected function post($path, array $parameters = array(), $requestHeaders = ar { $response = $this->client->getHttpClient()->post($path, $parameters, $requestHeaders); - return $response->getContent(); + return ResponseMediator::getContent($response); } /** @@ -85,7 +86,7 @@ protected function patch($path, array $parameters = array(), $requestHeaders = a { $response = $this->client->getHttpClient()->patch($path, $parameters, $requestHeaders); - return $response->getContent(); + return ResponseMediator::getContent($response); } /** @@ -95,7 +96,7 @@ protected function put($path, array $parameters = array(), $requestHeaders = arr { $response = $this->client->getHttpClient()->put($path, $parameters, $requestHeaders); - return $response->getContent(); + return ResponseMediator::getContent($response); } /** @@ -105,6 +106,6 @@ protected function delete($path, array $parameters = array(), $requestHeaders = { $response = $this->client->getHttpClient()->delete($path, $parameters, $requestHeaders); - return $response->getContent(); + return ResponseMediator::getContent($response); } } diff --git a/lib/Github/Api/ApiInterface.php b/lib/Github/Api/ApiInterface.php index 06a95047f28..c5928637ac7 100644 --- a/lib/Github/Api/ApiInterface.php +++ b/lib/Github/Api/ApiInterface.php @@ -2,6 +2,8 @@ namespace Github\Api; +use Github\Client; + /** * Api interface * @@ -9,4 +11,9 @@ */ interface ApiInterface { + public function __construct(Client $client); + + public function getPerPage(); + + public function setPerPage($perPage); } diff --git a/lib/Github/HttpClient/Cache/CacheInterface.php b/lib/Github/HttpClient/Cache/CacheInterface.php index b1ada0e53d9..50fedd6e25b 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 Guzzle\Http\Message\Response; /** * Caches github api responses diff --git a/lib/Github/HttpClient/Cache/FilesystemCache.php b/lib/Github/HttpClient/Cache/FilesystemCache.php index ad1f90821cf..e7c7588cd03 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 Guzzle\Http\Message\Response; class FilesystemCache implements CacheInterface { diff --git a/lib/Github/HttpClient/CachedHttpClient.php b/lib/Github/HttpClient/CachedHttpClient.php index f28f54bd9e2..cd847581762 100644 --- a/lib/Github/HttpClient/CachedHttpClient.php +++ b/lib/Github/HttpClient/CachedHttpClient.php @@ -61,15 +61,18 @@ public function request($path, array $parameters = array(), $httpMethod = 'GET', * * {@inheritdoc} */ - protected function createRequest($httpMethod, $url) + protected function createRequest($httpMethod, $path, $requestBody, array $headers = array()) { - $request = parent::createRequest($httpMethod, $url); + $request = parent::createRequest($httpMethod, $path, $requestBody, $headers = array()); - if ($modifiedAt = $this->getCache()->getModifiedSince($url)) { + if ($modifiedAt = $this->getCache()->getModifiedSince($path)) { $modifiedAt = new \DateTime('@'.$modifiedAt); $modifiedAt->setTimezone(new \DateTimeZone('GMT')); - $request->addHeader(sprintf('If-Modified-Since: %s GMT', $modifiedAt->format('l, d-M-y H:i:s'))); + $request->addHeader( + 'If-Modified-Since', + sprintf('%s GMT', $modifiedAt->format('l, d-M-y H:i:s')) + ); } return $request; diff --git a/lib/Github/HttpClient/HttpClient.php b/lib/Github/HttpClient/HttpClient.php index 3538f102589..f8833b43d14 100644 --- a/lib/Github/HttpClient/HttpClient.php +++ b/lib/Github/HttpClient/HttpClient.php @@ -2,16 +2,15 @@ namespace Github\HttpClient; -use Buzz\Client\ClientInterface; -use Buzz\Listener\ListenerInterface; +use Guzzle\Http\Client as GuzzleClient; +use Guzzle\Http\ClientInterface; +use Guzzle\Http\Message\Request; +use Guzzle\Http\Message\Response; use Github\Exception\ErrorException; use Github\Exception\RuntimeException; use Github\HttpClient\Listener\AuthListener; use Github\HttpClient\Listener\ErrorListener; -use Github\HttpClient\Message\Request; -use Github\HttpClient\Message\Response; -use Buzz\Client\Curl; /** * Performs requests on GitHub API. API documentation should be self-explanatory. @@ -20,9 +19,6 @@ */ class HttpClient implements HttpClientInterface { - /** - * @var array - */ protected $options = array( 'base_url' => 'https://api.github.com/', @@ -30,17 +26,11 @@ class HttpClient implements HttpClientInterface 'timeout' => 10, 'api_limit' => 5000, - 'api_version' => 'beta', + 'api_version' => 'v3', 'cache_dir' => null ); - /** - * @var array - */ - protected $listeners = array(); - /** - * @var array - */ + protected $headers = array(); private $lastResponse; @@ -52,32 +42,14 @@ class HttpClient implements HttpClientInterface */ public function __construct(array $options = array(), ClientInterface $client = null) { - $client = $client ?: new Curl(); - $timeout = isset($options['timeout']) ? $options['timeout'] : $this->options['timeout']; - $client->setTimeout($timeout); - $client->setVerifyPeer(false); - $this->options = array_merge($this->options, $options); + $client = $client ?: new GuzzleClient($options['base_url'], $this->options); $this->client = $client; - $this->addListener(new ErrorListener($this->options)); - + $this->addListener('request.error', array(new ErrorListener($this->options), 'onRequestError')); $this->clearHeaders(); } - public function authenticate($tokenOrLogin, $password, $authMethod) - { - $this->addListener( - new AuthListener( - $authMethod, - array( - 'tokenOrLogin' => $tokenOrLogin, - 'password' => $password - ) - ) - ); - } - /** * {@inheritDoc} */ @@ -105,12 +77,9 @@ public function clearHeaders() ); } - /** - * @param ListenerInterface $listener - */ - public function addListener(ListenerInterface $listener) + public function addListener($eventName, $listener) { - $this->listeners[get_class($listener)] = $listener; + $this->client->getEventDispatcher()->addListener($eventName, $listener); } /** @@ -118,11 +87,7 @@ public function addListener(ListenerInterface $listener) */ 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); + return $this->request($path, $parameters, 'GET', $headers); } /** @@ -162,27 +127,15 @@ public function put($path, array $parameters = array(), array $headers = array() */ public function request($path, array $parameters = array(), $httpMethod = 'GET', array $headers = array()) { - if (!empty($this->options['base_url']) && 0 !== strpos($path, $this->options['base_url'])) { - $path = trim($this->options['base_url'].$path, '/'); - } + $requestBody = count($parameters) === 0 + ? null : json_encode($parameters, empty($parameters) ? JSON_FORCE_OBJECT : 0) + ; - $request = $this->createRequest($httpMethod, $path); + $request = $this->createRequest($httpMethod, $path, $requestBody, $headers); $request->addHeaders($headers); - if (count($parameters) > 0) { - $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); - } - } - - $response = $this->createResponse(); try { - $this->client->send($request, $response); + $response = $this->client->send($request); } catch (\LogicException $e) { throw new ErrorException($e->getMessage()); } catch (\RuntimeException $e) { @@ -192,15 +145,19 @@ public function request($path, array $parameters = array(), $httpMethod = 'GET', $this->lastRequest = $request; $this->lastResponse = $response; - if ($hasListeners) { - foreach ($this->listeners as $listener) { - $listener->postSend($request, $response); - } - } - return $response; } + /** + * {@inheritDoc} + */ + public function authenticate($tokenOrLogin, $password = null, $method) + { + $this->addListener('request.before_send', array( + new AuthListener($tokenOrLogin, $password, $method), 'onRequestBeforeSend' + )); + } + /** * @return Request */ @@ -217,26 +174,8 @@ public function getLastResponse() return $this->lastResponse; } - /** - * @param string $httpMethod - * @param string $url - * - * @return Request - */ - protected function createRequest($httpMethod, $url) - { - $request = new Request($httpMethod); - $request->setHeaders($this->headers); - $request->fromUrl($url); - - return $request; - } - - /** - * @return Response - */ - protected function createResponse() + protected function createRequest($httpMethod, $path, $requestBody, array $headers = array()) { - return new Response(); + return $this->client->createRequest($httpMethod, $path, array_merge($this->headers, $headers), $requestBody); } } diff --git a/lib/Github/HttpClient/Listener/AuthListener.php b/lib/Github/HttpClient/Listener/AuthListener.php index 1f5e9e64b2f..41ad42e4642 100644 --- a/lib/Github/HttpClient/Listener/AuthListener.php +++ b/lib/Github/HttpClient/Listener/AuthListener.php @@ -2,44 +2,24 @@ namespace Github\HttpClient\Listener; +use Guzzle\Common\Event; use Github\Client; -use Github\Exception\InvalidArgumentException; +use Github\Exception\RuntimeException; -use Buzz\Listener\ListenerInterface; -use Buzz\Message\MessageInterface; -use Buzz\Message\RequestInterface; -use Buzz\Util\Url; - -/** - * @author Joseph Bielawski - */ -class AuthListener implements ListenerInterface +class AuthListener { - /** - * @var string - */ + private $tokenOrLogin; + private $password; private $method; - /** - * @var array - */ - private $options; - /** - * @param string $method - * @param array $options - */ - public function __construct($method, array $options) + public function __construct($tokenOrLogin, $password = null, $method) { - $this->method = $method; - $this->options = $options; + $this->tokenOrLogin = $tokenOrLogin; + $this->password = $password; + $this->method = $method; } - /** - * {@inheritDoc} - * - * @throws InvalidArgumentException - */ - public function preSend(RequestInterface $request) + public function onRequestBeforeSend(Event $event) { // Skip by default if (null === $this->method) { @@ -48,71 +28,41 @@ public function preSend(RequestInterface $request) switch ($this->method) { case Client::AUTH_HTTP_PASSWORD: - if (!isset($this->options['tokenOrLogin'], $this->options['password'])) { - throw new InvalidArgumentException('You need to set username with password!'); - } - - $request->addHeader('Authorization: Basic '. base64_encode($this->options['tokenOrLogin'] .':'. $this->options['password'])); + $event['request']->setHeader( + 'Authorization', + sprintf('Basic %s', base64_encode($this->tokenOrLogin . ':' . $this->password)) + ); break; case Client::AUTH_HTTP_TOKEN: - if (!isset($this->options['tokenOrLogin'])) { - throw new InvalidArgumentException('You need to set OAuth token!'); - } - - $request->addHeader('Authorization: token '. $this->options['tokenOrLogin']); + $event['request']->setHeader('Authorization', sprintf('token %s', $this->tokenOrLogin)); break; case Client::AUTH_URL_CLIENT_ID: - if (!isset($this->options['tokenOrLogin'], $this->options['password'])) { - throw new InvalidArgumentException('You need to set client_id and client_secret!'); - } + $url = $event['request']->getUrl(); - $this->setRequestUrl( - $request, - array( - 'client_id' => $this->options['tokenOrLogin'], - 'client_secret' => $this->options['password'], - ) + $parameters = array( + 'client_id' => $this->tokenOrLogin, + 'client_secret' => $this->password, ); + + $url .= (false === strpos($url, '?') ? '?' : '&'); + $url .= utf8_encode(http_build_query($parameters, '', '&')); + + $event['request']->setUrl($url); break; case Client::AUTH_URL_TOKEN: - if (!isset($this->options['tokenOrLogin'])) { - throw new InvalidArgumentException('You need to set OAuth token!'); - } + $url = $event['request']->getUrl(); + $url .= (false === strpos($url, '?') ? '?' : '&'); + $url .= utf8_encode(http_build_query(array('access_token' => $this->tokenOrLogin), '', '&')); - $this->setRequestUrl( - $request, - array( - 'access_token' => $this->options['tokenOrLogin'], - ) - ); + $event['request']->setUrl($url); break; default: - throw new InvalidArgumentException(sprintf('Unknown method called "%s".', $this->method)); + throw new RuntimeException(sprintf('%s not yet implemented', $this->method)); + break; } } - - /** - * {@inheritDoc} - */ - public function postSend(RequestInterface $request, MessageInterface $response) - { - } - - /** - * @param RequestInterface $request - * @param array $parameters - * - * @return Url - */ - private function setRequestUrl(RequestInterface $request, array $parameters = array()) - { - $url = $request->getUrl(); - $url .= (false === strpos($url, '?') ? '?' : '&').utf8_encode(http_build_query($parameters, '', '&')); - - $request->fromUrl(new Url($url)); - } } diff --git a/lib/Github/HttpClient/Listener/ErrorListener.php b/lib/Github/HttpClient/Listener/ErrorListener.php index 3f2963fc995..2294cfbad35 100644 --- a/lib/Github/HttpClient/Listener/ErrorListener.php +++ b/lib/Github/HttpClient/Listener/ErrorListener.php @@ -2,9 +2,10 @@ namespace Github\HttpClient\Listener; -use Buzz\Listener\ListenerInterface; -use Buzz\Message\MessageInterface; -use Buzz\Message\RequestInterface; +use Github\HttpClient\Message\ResponseMediator; +use Guzzle\Common\Event; +use Guzzle\Http\Message\Response; + use Github\Exception\ApiLimitExceedException; use Github\Exception\ErrorException; use Github\Exception\RuntimeException; @@ -13,7 +14,7 @@ /** * @author Joseph Bielawski */ -class ErrorListener implements ListenerInterface +class ErrorListener { /** * @var array @@ -31,24 +32,20 @@ public function __construct(array $options) /** * {@inheritDoc} */ - public function preSend(RequestInterface $request) + public function onRequestError(Event $event) { - } + /** @var $request \Guzzle\Http\Message\Request */ + $request = $event['request']; + $response = $request->getResponse(); - /** - * {@inheritDoc} - */ - public function postSend(RequestInterface $request, MessageInterface $response) - { - /** @var $response \Github\HttpClient\Message\Response */ if ($response->isClientError() || $response->isServerError()) { - $remaining = $response->getHeader('X-RateLimit-Remaining'); + $remaining = (string) $response->getHeader('X-RateLimit-Remaining'); if (null !== $remaining && 1 > $remaining && 'rate_limit' !== substr($request->getResource(), 1, 10)) { throw new ApiLimitExceedException($this->options['api_limit']); } - $content = $response->getContent(); + $content = ResponseMediator::getContent($response); if (is_array($content) && isset($content['message'])) { if (400 == $response->getStatusCode()) { throw new ErrorException($content['message'], 400); @@ -84,6 +81,6 @@ public function postSend(RequestInterface $request, MessageInterface $response) } throw new RuntimeException(isset($content['message']) ? $content['message'] : $content, $response->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/Message/ResponseMediator.php b/lib/Github/HttpClient/Message/ResponseMediator.php new file mode 100644 index 00000000000..72fe7c7129e --- /dev/null +++ b/lib/Github/HttpClient/Message/ResponseMediator.php @@ -0,0 +1,50 @@ +getBody(true); + $content = json_decode($body, true); + + if (JSON_ERROR_NONE !== json_last_error()) { + return $body; + } + + return $content; + } + + public static function getPagination(Response $response) + { + $header = $response->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; + } + + public static function getApiLimit(Response $response) + { + $remainingCalls = $response->getHeader('X-RateLimit-Remaining'); + + if (null !== $remainingCalls && 1 > $remainingCalls) { + throw new ApiLimitExceedException($remainingCalls); + } + } +} diff --git a/lib/Github/ResultPager.php b/lib/Github/ResultPager.php index 83f2692a29a..7483194ba3b 100644 --- a/lib/Github/ResultPager.php +++ b/lib/Github/ResultPager.php @@ -3,7 +3,7 @@ namespace Github; use Github\Api\ApiInterface; -use Github\HttpClient\HttpClient; +use Github\HttpClient\Message\ResponseMediator; /** * Pager class for supporting pagination in github classes @@ -14,7 +14,7 @@ class ResultPager implements ResultPagerInterface { /** - * @var Github\Client client + * @var \Github\Client client */ protected $client; @@ -89,7 +89,7 @@ public function fetchAll(ApiInterface $api, $method, array $parameters = array() */ public function postFetch() { - $this->pagination = $this->client->getHttpClient()->getLastResponse()->getPagination(); + $this->pagination = ResponseMediator::getPagination($this->client->getHttpClient()->getLastResponse()); } /** @@ -157,7 +157,7 @@ protected function get($key) $result = $this->client->getHttpClient()->get($this->pagination[$key]); $this->postFetch(); - return $result->getContent(); + return ResponseMediator::getContent($result); } } } diff --git a/test/Github/Tests/Api/AbstractApiTest.php b/test/Github/Tests/Api/AbstractApiTest.php index 40d8c2c3436..a48b28775f1 100644 --- a/test/Github/Tests/Api/AbstractApiTest.php +++ b/test/Github/Tests/Api/AbstractApiTest.php @@ -134,15 +134,7 @@ protected function getHttpMock() protected function getHttpClientMock() { - $mock = $this->getMock('Buzz\Client\ClientInterface', array('setTimeout', 'setVerifyPeer', 'send')); - $mock - ->expects($this->any()) - ->method('setTimeout') - ->with(10); - $mock - ->expects($this->any()) - ->method('setVerifyPeer') - ->with(false); + $mock = $this->getMock('Guzzle\Http\Client', array('send')); $mock ->expects($this->any()) ->method('send'); diff --git a/test/Github/Tests/Api/TestCase.php b/test/Github/Tests/Api/TestCase.php index 5bae9b02972..81e7635939f 100644 --- a/test/Github/Tests/Api/TestCase.php +++ b/test/Github/Tests/Api/TestCase.php @@ -8,15 +8,7 @@ abstract protected function getApiClass(); protected function getApiMock() { - $httpClient = $this->getMock('Buzz\Client\ClientInterface', array('setTimeout', 'setVerifyPeer', 'send')); - $httpClient - ->expects($this->any()) - ->method('setTimeout') - ->with(10); - $httpClient - ->expects($this->any()) - ->method('setVerifyPeer') - ->with(false); + $httpClient = $this->getMock('Guzzle\Http\Client', array('send')); $httpClient ->expects($this->any()) ->method('send'); diff --git a/test/Github/Tests/Functional/UserTest.php b/test/Github/Tests/Functional/UserTest.php index cdcdedde021..8cef6d7a88a 100644 --- a/test/Github/Tests/Functional/UserTest.php +++ b/test/Github/Tests/Functional/UserTest.php @@ -5,7 +5,7 @@ /** * @group functional */ -class UsetTest extends TestCase +class UserTest extends TestCase { /** * @test @@ -58,7 +58,7 @@ public function shouldGetUsersWhoUserIsFollowing() */ public function shouldGetFollowersUsers() { - $username = 'KnpLabs'; + $username = 'cursedcoder'; $users = $this->client->api('user')->followers($username); $user = array_pop($users); diff --git a/test/Github/Tests/HttpClient/Cache/FilesystemCacheTest.php b/test/Github/Tests/HttpClient/Cache/FilesystemCacheTest.php index 841f38f690b..54efdd49ba4 100644 --- a/test/Github/Tests/HttpClient/Cache/FilesystemCacheTest.php +++ b/test/Github/Tests/HttpClient/Cache/FilesystemCacheTest.php @@ -2,7 +2,7 @@ namespace Github\Tests\HttpClient\Cache; -use Github\HttpClient\Message\Response; +use Guzzle\Http\Message\Response; use Github\HttpClient\Cache\FilesystemCache; class FilesystemCacheTest extends \PHPUnit_Framework_TestCase @@ -14,7 +14,7 @@ public function shouldStoreAResponseForAGivenKey() { $cache = new FilesystemCache('/tmp/github-api-test'); - $cache->set('test', new Response); + $cache->set('test', new Response(200)); $this->assertNotNull($cache->get('test')); } @@ -26,7 +26,7 @@ public function shouldGetATimestampForExistingFile() { $cache = new FilesystemCache('/tmp/github-api-test'); - $cache->set('test', new Response); + $cache->set('test', new Response(200)); $this->assertInternalType('int', $cache->getModifiedSince('test')); } diff --git a/test/Github/Tests/HttpClient/CachedHttpClientTest.php b/test/Github/Tests/HttpClient/CachedHttpClientTest.php index 5a5e29dfde9..477b3e2eab3 100644 --- a/test/Github/Tests/HttpClient/CachedHttpClientTest.php +++ b/test/Github/Tests/HttpClient/CachedHttpClientTest.php @@ -3,7 +3,7 @@ namespace Github\Tests\HttpClient; use Github\HttpClient\CachedHttpClient; -use Github\HttpClient\Message\Response; +use Guzzle\Http\Message\Response; class CachedHttpClientTest extends HttpClientTest { @@ -13,15 +13,17 @@ class CachedHttpClientTest extends HttpClientTest public function shouldCacheResponseAtFirstTime() { $cache = $this->getCacheMock(); + $response = new Response(200); - $httpClient = new TestCachedHttpClient( - array('base_url' => ''), - $this->getMock('Buzz\Client\ClientInterface', array('setTimeout', 'setVerifyPeer', 'send')) - ); - $httpClient->setCache($cache); + $client = $this->getBrowserMock(); + $client->expects($this->once()) + ->method('send') + ->will($this->returnValue($response)); - $cache->expects($this->once())->method('set')->with('test', new Response); + $httpClient = new CachedHttpClient(array('base_url' => ''), $client); + $httpClient->setCache($cache); + $cache->expects($this->once())->method('set')->with('test', $response); $httpClient->get('test'); } @@ -30,18 +32,15 @@ public function shouldCacheResponseAtFirstTime() */ public function shouldGetCachedResponseWhileResourceNotModified() { - $client = $this->getMock('Buzz\Client\ClientInterface', array('setTimeout', 'setVerifyPeer', 'send')); - $client->expects($this->once())->method('send'); - $cache = $this->getCacheMock(); + $response = new Response(304); - $response = new Response; - $response->addHeader('HTTP/1.1 304 Not Modified'); + $client = $this->getBrowserMock(); + $client->expects($this->once()) + ->method('send') + ->will($this->returnValue($response)); - $httpClient = new TestCachedHttpClient( - array('base_url' => ''), - $client - ); + $httpClient = new CachedHttpClient(array('base_url' => ''), $client); $httpClient->setCache($cache); $httpClient->fakeResponse = $response; @@ -55,20 +54,16 @@ public function shouldGetCachedResponseWhileResourceNotModified() */ public function shouldRenewCacheWhenResourceHasChanged() { - $client = $this->getMock('Buzz\Client\ClientInterface', array('setTimeout', 'setVerifyPeer', 'send')); - $client->expects($this->once())->method('send'); - $cache = $this->getCacheMock(); + $response = new Response(200); - $response = new Response; - $response->addHeader('HTTP/1.1 200 OK'); + $client = $this->getBrowserMock(); + $client->expects($this->once()) + ->method('send') + ->will($this->returnValue($response)); - $httpClient = new TestCachedHttpClient( - array('base_url' => ''), - $client - ); + $httpClient = new CachedHttpClient(array('base_url' => ''), $client); $httpClient->setCache($cache); - $httpClient->fakeResponse = $response; $cache->expects($this->once())->method('set')->with('test', $response); $cache->expects($this->once())->method('getModifiedSince')->with('test')->will($this->returnValue(1256953732)); @@ -81,13 +76,3 @@ public function getCacheMock() return $this->getMock('Github\HttpClient\Cache\CacheInterface'); } } - -class TestCachedHttpClient extends CachedHttpClient -{ - public $fakeResponse; - - protected function createResponse() - { - return $this->fakeResponse ?: new Response(); - } -} diff --git a/test/Github/Tests/HttpClient/HttpClientTest.php b/test/Github/Tests/HttpClient/HttpClientTest.php index 4fc44717537..85e20a2eb98 100644 --- a/test/Github/Tests/HttpClient/HttpClientTest.php +++ b/test/Github/Tests/HttpClient/HttpClientTest.php @@ -4,8 +4,10 @@ use Github\Client; use Github\HttpClient\HttpClient; -use Github\HttpClient\Message\Request; -use Github\HttpClient\Message\Response; +use Github\HttpClient\Message\ResponseMediator; +use Guzzle\Http\Message\Response; +use Guzzle\Plugin\Mock\MockPlugin; +use Guzzle\Http\Client as GuzzleClient; class HttpClientTest extends \PHPUnit_Framework_TestCase { @@ -39,11 +41,18 @@ public function shouldBeAbleToSetOption() */ public function shouldAuthenticateUsingAllGivenParameters($login, $password, $method) { - $client = new TestHttpClient(); - $client->authenticate($login, $password, $method); + $client = new GuzzleClient(); + $listeners = $client->getEventDispatcher()->getListeners('request.before_send'); + $this->assertCount(1, $listeners); - $this->assertCount(2, $client->listeners); - $this->assertInstanceOf('Github\HttpClient\Listener\AuthListener', $client->listeners['Github\HttpClient\Listener\AuthListener']); + $httpClient = new TestHttpClient(array(), $client); + $httpClient->authenticate($login, $password, $method); + + $listeners = $client->getEventDispatcher()->getListeners('request.before_send'); + $this->assertCount(2, $listeners); + + $authListener = $listeners[1][0]; + $this->assertInstanceOf('Github\HttpClient\Listener\AuthListener', $authListener); } public function getAuthenticationFullData() @@ -81,11 +90,12 @@ public function shouldDoPOSTRequest() $headers = array('c' => 'd'); $client = $this->getBrowserMock(); + $client->expects($this->once()) + ->method('createRequest') + ->with('POST', $path, $this->isType('array'), '{"a":"b"}'); $httpClient = new HttpClient(array(), $client); $httpClient->post($path, $parameters, $headers); - - $this->assertEquals('{"a":"b"}', $httpClient->getLastRequest()->getContent()); } /** @@ -96,11 +106,12 @@ public function shouldDoPOSTRequestWithoutContent() $path = '/some/path'; $client = $this->getBrowserMock(); + $client->expects($this->once()) + ->method('createRequest') + ->with('POST', $path, $this->isType('array')); $httpClient = new HttpClient(array(), $client); $httpClient->post($path); - - $this->assertEmpty($httpClient->getLastRequest()->getContent()); } /** @@ -171,15 +182,15 @@ 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(200); + $response->addHeader('Link', "; rel=\"page2\", \n; rel=\"page4\""); $client = $this->getBrowserMock(); $httpClient = new HttpClient(array(), $client); $httpClient->request($path, $parameters, 'HEAD', $headers); - $this->assertEquals(array('page2' => 'page1', 'page4' => 'page3'), $response->getPagination()); + $this->assertEquals(array('page2' => 'page1', 'page4' => 'page3'), ResponseMediator::getPagination($response)); } /** @@ -191,20 +202,21 @@ public function shouldAllowToReturnRawContent() $parameters = array('a' => 'b'); $headers = array('c' => 'd'); - $message = $this->getMock('Github\HttpClient\Message\Response'); + $message = $this->getMock('Guzzle\Http\Message\Response', array(), array(200)); $message->expects($this->once()) - ->method('getContent') + ->method('getBody') ->will($this->returnValue('Just raw context')); $client = $this->getBrowserMock(); + $client->expects($this->once()) + ->method('send') + ->will($this->returnValue($message)); $httpClient = new TestHttpClient(array(), $client); - $httpClient->fakeResponse = $message; - $response = $httpClient->get($path, $parameters, $headers); - $this->assertEquals("Just raw context", $response->getContent()); - $this->assertInstanceOf('Buzz\Message\MessageInterface', $response); + $this->assertEquals("Just raw context", $response->getBody()); + $this->assertInstanceOf('Guzzle\Http\Message\MessageInterface', $response); } /** @@ -217,62 +229,48 @@ 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(403); + $response->addHeader('X-RateLimit-Remaining', 0); - $httpClient = new TestHttpClient(array(), $this->getBrowserMock()); - $httpClient->fakeResponse = $response; + $mockPlugin = new MockPlugin(); + $mockPlugin->addResponse($response); + + $client = new GuzzleClient('http://123.com/'); + $client->addSubscriber($mockPlugin); + $httpClient = new TestHttpClient(array(), $client); $httpClient->get($path, $parameters, $headers); } protected function getBrowserMock(array $methods = array()) { - return $this->getMock( - 'Buzz\Client\ClientInterface', + $mock = $this->getMock( + 'Guzzle\Http\Client', array_merge( - array('setTimeout', 'setVerifyPeer', 'send'), + array('send', 'createRequest'), $methods ) ); + + $mock->expects($this->any()) + ->method('createRequest') + ->will($this->returnValue($this->getMock('Guzzle\Http\Message\Request', array(), array('GET', 'some')))); + + return $mock; } } class TestHttpClient extends HttpClient { - public $fakeResponse; - public $listeners; - public function getOption($name, $default = null) { return isset($this->options[$name]) ? $this->options[$name] : $default; } - public function clearHeaders() - { - } - public function request($path, array $parameters = array(), $httpMethod = 'GET', array $headers = array()) { - $request = $this->createRequest($httpMethod, $path); - $response = $this->createResponse(); - if (0 < count($this->listeners)) { - foreach ($this->listeners as $listener) { - $listener->postSend($request, $response); - } - } - - return $response; - } + $request = $this->client->createRequest($httpMethod, $path); - protected function createRequest($httpMethod, $url) - { - return new Request($httpMethod); - } - - protected function createResponse() - { - return $this->fakeResponse ?: new Response(); + return $this->client->send($request, $headers, $parameters); } } diff --git a/test/Github/Tests/HttpClient/Listener/AuthListenerTest.php b/test/Github/Tests/HttpClient/Listener/AuthListenerTest.php index cfd741c7a0c..d071687488d 100644 --- a/test/Github/Tests/HttpClient/Listener/AuthListenerTest.php +++ b/test/Github/Tests/HttpClient/Listener/AuthListenerTest.php @@ -2,61 +2,21 @@ namespace Github\Tests\HttpClient; +use Guzzle\Http\Message\Request; + use Github\Client; -use Github\Exception\InvalidArgumentException; use Github\HttpClient\Listener\AuthListener; -use Github\HttpClient\Message\Request; class AuthListenerTest extends \PHPUnit_Framework_TestCase { /** * @test - * @expectedException InvalidArgumentException + * @expectedException \RuntimeException */ public function shouldHaveKnownMethodName() { - $listener = new AuthListener('unknown', array('tokenOrLogin' => 'test')); - $listener->preSend($this->getMock('Buzz\Message\RequestInterface')); - } - - /** - * @test - * @expectedException InvalidArgumentException - */ - public function shouldHaveLoginAndPasswordForAuthPassMethod() - { - $listener = new AuthListener(Client::AUTH_HTTP_PASSWORD, array('tokenOrLogin' => 'test')); - $listener->preSend($this->getMock('Buzz\Message\RequestInterface')); - } - - /** - * @test - * @expectedException InvalidArgumentException - */ - public function shouldHaveTokenForHttpTokenMethod() - { - $listener = new AuthListener(Client::AUTH_HTTP_TOKEN, array('password' => 'pass')); - $listener->preSend($this->getMock('Buzz\Message\RequestInterface')); - } - - /** - * @test - * @expectedException InvalidArgumentException - */ - public function shouldHaveTokenForUrlTokenMethod() - { - $listener = new AuthListener(Client::AUTH_URL_TOKEN, array('password' => 'login')); - $listener->preSend($this->getMock('Buzz\Message\RequestInterface')); - } - - /** - * @test - * @expectedException InvalidArgumentException - */ - public function shouldHaveClientIdAndSecretForUrlClientIdMethod() - { - $listener = new AuthListener(Client::AUTH_URL_CLIENT_ID, array('password' => 'login')); - $listener->preSend($this->getMock('Buzz\Message\RequestInterface')); + $listener = new AuthListener('test', null, 'unknown'); + $listener->onRequestBeforeSend($this->getEventMock()); } /** @@ -64,7 +24,7 @@ public function shouldHaveClientIdAndSecretForUrlClientIdMethod() */ public function shouldDoNothingForHaveNullMethod() { - $request = $this->getMock('Buzz\Message\RequestInterface'); + $request = $this->getMock('Guzzle\Http\Message\RequestInterface'); $request->expects($this->never()) ->method('addHeader'); $request->expects($this->never()) @@ -72,8 +32,8 @@ public function shouldDoNothingForHaveNullMethod() $request->expects($this->never()) ->method('getUrl'); - $listener = new AuthListener(null, array('password' => 'pass', 'tokenOrLogin' => 'test')); - $listener->preSend($request); + $listener = new AuthListener('test', 'pass', null); + $listener->onRequestBeforeSend($this->getEventMock($request)); } /** @@ -81,7 +41,7 @@ public function shouldDoNothingForHaveNullMethod() */ public function shouldDoNothingForPostSend() { - $request = $this->getMock('Buzz\Message\RequestInterface'); + $request = $this->getMock('Guzzle\Http\Message\RequestInterface'); $request->expects($this->never()) ->method('addHeader'); $request->expects($this->never()) @@ -89,22 +49,8 @@ public function shouldDoNothingForPostSend() $request->expects($this->never()) ->method('getUrl'); - $response = $this->getMock('Buzz\Message\MessageInterface'); - $response->expects($this->never()) - ->method('addHeader'); - $response->expects($this->never()) - ->method('setContent'); - $response->expects($this->never()) - ->method('setHeaders'); - $response->expects($this->never()) - ->method('getContent'); - $response->expects($this->never()) - ->method('__toString'); - $response->expects($this->never()) - ->method('getHeader'); - - $listener = new AuthListener(Client::AUTH_HTTP_PASSWORD, array('tokenOrLogin' => 'login', 'password' => 'mypasswd')); - $listener->postSend($request, $response); + $listener = new AuthListener('login', 'somepassphrase', Client::AUTH_HTTP_PASSWORD); + $listener->onRequestBeforeSend($this->getEventMock($request)); } /** @@ -112,19 +58,19 @@ public function shouldDoNothingForPostSend() */ public function shouldSetAuthBasicHeaderForAuthPassMethod() { - $expected = 'Basic '.base64_encode('login:mypasswd'); + $expected = 'Basic '.base64_encode('login2:pass42323'); - $request = $this->getMock('Buzz\Message\RequestInterface'); + $request = $this->getMock('Guzzle\Http\Message\RequestInterface'); $request->expects($this->once()) - ->method('addHeader') - ->with('Authorization: '.$expected); + ->method('setHeader') + ->with('Authorization', $expected); $request->expects($this->once()) ->method('getHeader') ->with('Authorization') ->will($this->returnValue($expected)); - $listener = new AuthListener(Client::AUTH_HTTP_PASSWORD, array('tokenOrLogin' => 'login', 'password' => 'mypasswd')); - $listener->preSend($request); + $listener = new AuthListener('login2', 'pass42323', Client::AUTH_HTTP_PASSWORD); + $listener->onRequestBeforeSend($this->getEventMock($request)); $this->assertEquals($expected, $request->getHeader('Authorization')); } @@ -136,17 +82,17 @@ public function shouldSetAuthTokenHeaderForAuthPassMethod() { $expected = 'token test'; - $request = $this->getMock('Buzz\Message\RequestInterface'); + $request = $this->getMock('Guzzle\Http\Message\RequestInterface'); $request->expects($this->once()) - ->method('addHeader') - ->with('Authorization: '.$expected); + ->method('setHeader') + ->with('Authorization', $expected); $request->expects($this->once()) ->method('getHeader') ->with('Authorization') ->will($this->returnValue($expected)); - $listener = new AuthListener(Client::AUTH_HTTP_TOKEN, array('tokenOrLogin' => 'test')); - $listener->preSend($request); + $listener = new AuthListener('test', null, Client::AUTH_HTTP_TOKEN); + $listener->onRequestBeforeSend($this->getEventMock($request)); $this->assertEquals($expected, $request->getHeader('Authorization')); } @@ -156,10 +102,10 @@ public function shouldSetAuthTokenHeaderForAuthPassMethod() */ public function shouldSetTokenInUrlForAuthUrlMethod() { - $request = new Request(Request::METHOD_GET, '/res'); + $request = new Request('GET', '/res'); - $listener = new AuthListener(Client::AUTH_URL_TOKEN, array('tokenOrLogin' => 'test')); - $listener->preSend($request); + $listener = new AuthListener('test', null, Client::AUTH_URL_TOKEN); + $listener->onRequestBeforeSend($this->getEventMock($request)); $this->assertEquals('/res?access_token=test', $request->getUrl()); } @@ -169,11 +115,24 @@ public function shouldSetTokenInUrlForAuthUrlMethod() */ public function shouldSetClientDetailsInUrlForAuthUrlMethod() { - $request = new Request(Request::METHOD_GET, '/res'); + $request = new Request('GET', '/res'); + + $listener = new AuthListener('clientId', 'clientSecret', Client::AUTH_URL_CLIENT_ID); + $listener->onRequestBeforeSend($this->getEventMock($request)); + + $this->assertEquals('/res?client_id=clientId&client_secret=clientSecret', $request->getUrl()); + } + + private function getEventMock($request = null) + { + $mock = $this->getMockBuilder('Guzzle\Common\Event')->getMock(); - $listener = new AuthListener(Client::AUTH_URL_CLIENT_ID, array('tokenOrLogin' => 'clientId', 'password' => 'clientSsecret')); - $listener->preSend($request); + if ($request) { + $mock->expects($this->any()) + ->method('offsetGet') + ->will($this->returnValue($request)); + } - $this->assertEquals('/res?client_id=clientId&client_secret=clientSsecret', $request->getUrl()); + return $mock; } } diff --git a/test/Github/Tests/HttpClient/Listener/ErrorListenerTest.php b/test/Github/Tests/HttpClient/Listener/ErrorListenerTest.php index 3a539343370..8bb0bfa177f 100644 --- a/test/Github/Tests/HttpClient/Listener/ErrorListenerTest.php +++ b/test/Github/Tests/HttpClient/Listener/ErrorListenerTest.php @@ -11,13 +11,13 @@ class ErrorListenerTest extends \PHPUnit_Framework_TestCase */ public function shouldPassIfResponseNotHaveErrorStatus() { - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMockBuilder('Guzzle\Http\Message\Response')->disableOriginalConstructor()->getMock(); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(false)); $listener = new ErrorListener(array('api_limit' => 5000)); - $listener->postSend($this->getMock('Buzz\Message\RequestInterface'), $response); + $listener->onRequestError($this->getEventMock($response)); } /** @@ -26,7 +26,7 @@ public function shouldPassIfResponseNotHaveErrorStatus() */ public function shouldFailWhenApiLimitWasExceed() { - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMockBuilder('Guzzle\Http\Message\Response')->disableOriginalConstructor()->getMock(); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); @@ -36,7 +36,7 @@ public function shouldFailWhenApiLimitWasExceed() ->will($this->returnValue(0)); $listener = new ErrorListener(array('api_limit' => 5000)); - $listener->postSend($this->getMock('Buzz\Message\RequestInterface'), $response); + $listener->onRequestError($this->getEventMock($response)); } /** @@ -45,7 +45,7 @@ public function shouldFailWhenApiLimitWasExceed() */ public function shouldNotPassWhenContentWasNotValidJson() { - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMockBuilder('Guzzle\Http\Message\Response')->disableOriginalConstructor()->getMock(); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); @@ -54,11 +54,11 @@ public function shouldNotPassWhenContentWasNotValidJson() ->with('X-RateLimit-Remaining') ->will($this->returnValue(5000)); $response->expects($this->once()) - ->method('getContent') + ->method('getBody') ->will($this->returnValue('fail')); $listener = new ErrorListener(array('api_limit' => 5000)); - $listener->postSend($this->getMock('Buzz\Message\RequestInterface'), $response); + $listener->onRequestError($this->getEventMock($response)); } /** @@ -67,7 +67,7 @@ public function shouldNotPassWhenContentWasNotValidJson() */ public function shouldNotPassWhenContentWasValidJsonButStatusIsNotCovered() { - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMockBuilder('Guzzle\Http\Message\Response')->disableOriginalConstructor()->getMock(); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); @@ -76,14 +76,14 @@ public function shouldNotPassWhenContentWasValidJsonButStatusIsNotCovered() ->with('X-RateLimit-Remaining') ->will($this->returnValue(5000)); $response->expects($this->once()) - ->method('getContent') - ->will($this->returnValue(array('message' => 'test'))); + ->method('getBody') + ->will($this->returnValue(json_encode(array('message' => 'test')))); $response->expects($this->any()) ->method('getStatusCode') ->will($this->returnValue(404)); $listener = new ErrorListener(array('api_limit' => 5000)); - $listener->postSend($this->getMock('Buzz\Message\RequestInterface'), $response); + $listener->onRequestError($this->getEventMock($response)); } /** @@ -92,7 +92,7 @@ public function shouldNotPassWhenContentWasValidJsonButStatusIsNotCovered() */ public function shouldNotPassWhen400IsSent() { - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMockBuilder('Guzzle\Http\Message\Response')->disableOriginalConstructor()->getMock(); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); @@ -101,14 +101,14 @@ public function shouldNotPassWhen400IsSent() ->with('X-RateLimit-Remaining') ->will($this->returnValue(5000)); $response->expects($this->once()) - ->method('getContent') - ->will($this->returnValue(array('message' => 'test'))); + ->method('getBody') + ->will($this->returnValue(json_encode(array('message' => 'test')))); $response->expects($this->any()) ->method('getStatusCode') ->will($this->returnValue(400)); $listener = new ErrorListener(array('api_limit' => 5000)); - $listener->postSend($this->getMock('Buzz\Message\RequestInterface'), $response); + $listener->onRequestError($this->getEventMock($response)); } /** @@ -118,7 +118,7 @@ public function shouldNotPassWhen400IsSent() */ public function shouldNotPassWhen422IsSentWithErrorCode($errorCode) { - $content = array( + $content = json_encode(array( 'message' => 'Validation Failed', 'errors' => array( array( @@ -128,9 +128,9 @@ public function shouldNotPassWhen422IsSentWithErrorCode($errorCode) 'resource' => 'fake' ) ) - ); + )); - $response = $this->getMock('Github\HttpClient\Message\Response'); + $response = $this->getMockBuilder('Guzzle\Http\Message\Response')->disableOriginalConstructor()->getMock(); $response->expects($this->once()) ->method('isClientError') ->will($this->returnValue(true)); @@ -139,14 +139,14 @@ public function shouldNotPassWhen422IsSentWithErrorCode($errorCode) ->with('X-RateLimit-Remaining') ->will($this->returnValue(5000)); $response->expects($this->once()) - ->method('getContent') + ->method('getBody') ->will($this->returnValue($content)); $response->expects($this->any()) ->method('getStatusCode') ->will($this->returnValue(422)); $listener = new ErrorListener(array('api_limit' => 5000)); - $listener->postSend($this->getMock('Buzz\Message\RequestInterface'), $response); + $listener->onRequestError($this->getEventMock($response)); } public function getErrorCodesProvider() @@ -158,4 +158,21 @@ public function getErrorCodesProvider() array('already_exists'), ); } + + private function getEventMock($response) + { + $mock = $this->getMockBuilder('Guzzle\Common\Event')->getMock(); + + $request = $this->getMockBuilder('Guzzle\Http\Message\Request')->disableOriginalConstructor()->getMock(); + + $request->expects($this->any()) + ->method('getResponse') + ->will($this->returnValue($response)); + + $mock->expects($this->any()) + ->method('offsetGet') + ->will($this->returnValue($request)); + + return $mock; + } } diff --git a/test/Github/Tests/Mock/TestResponse.php b/test/Github/Tests/Mock/TestResponse.php index 3cac1212d70..9d102844138 100644 --- a/test/Github/Tests/Mock/TestResponse.php +++ b/test/Github/Tests/Mock/TestResponse.php @@ -2,13 +2,15 @@ namespace Github\Tests\Mock; -class TestResponse +use Guzzle\Http\Message\Response; + +class TestResponse extends Response { protected $loopCount; protected $content; - public function __construct( $loopCount, array $content = array() ) + public function __construct($loopCount, array $content = array()) { $this->loopCount = $loopCount; $this->content = $content; @@ -17,28 +19,21 @@ public function __construct( $loopCount, array $content = array() ) /** * {@inheritDoc} */ - public function getContent() + public function getBody($asString = false) { - return $this->content; + return json_encode($this->content); } - /** - * @return array|null - */ - public function getPagination() + public function getHeader($header = null) { if ($this->loopCount) { - $returnArray = array( - 'next' => 'http://github.com/' . $this->loopCount - ); + $header = sprintf('; rel="next"', $this->loopCount); } else { - $returnArray = array( - 'prev' => 'http://github.com/prev' - ); + $header = '; rel="prev"'; } $this->loopCount--; - return $returnArray; + return $header; } } diff --git a/test/Github/Tests/ResultPagerTest.php b/test/Github/Tests/ResultPagerTest.php index 7d37bb4a957..df7f0e11c85 100644 --- a/test/Github/Tests/ResultPagerTest.php +++ b/test/Github/Tests/ResultPagerTest.php @@ -60,10 +60,10 @@ public function shouldGetAllResults() */ public function shouldGetSomeResults() { - $pagination = array('next' => 'http://github.com/next'); - $resultContent = 'organization test'; + $pagination = array('next' => 'http://github.com/next'); + $resultContent = 'organization test'; - $responseMock = $this->getResponseMock($pagination); + $responseMock = $this->getResponseMock('; rel="next"'); $httpClient = $this->getHttpClientMock($responseMock); $client = $this->getClientMock($httpClient); @@ -89,6 +89,13 @@ public function shouldGetSomeResults() */ public function postFetch() { + $header = <<; rel="first", +; rel="next", +; rel="prev", +; rel="last", +TEXT; + $pagination = array( 'first' => 'http://github.com', 'next' => 'http://github.com', @@ -97,11 +104,12 @@ public function postFetch() ); // response mock - $responseMock = $this->getMock('Github\HttpClient\Message\Response'); + $responseMock = $this->getMock('Guzzle\Http\Message\Response', array(), array(200)); $responseMock ->expects($this->any()) - ->method('getPagination') - ->will($this->returnValue($pagination)); + ->method('getHeader') + ->with('Link') + ->will($this->returnValue($header)); $httpClient = $this->getHttpClientMock($responseMock); $client = $this->getClientMock($httpClient); @@ -119,18 +127,20 @@ public function postFetch() */ public function fetchNext() { + $header = '; rel="next"'; $pagination = array('next' => 'http://github.com/next'); $resultContent = 'fetch test'; - $responseMock = $this->getResponseMock($pagination); + $responseMock = $this->getResponseMock($header); $responseMock ->expects($this->once()) - ->method('getContent') + ->method('getBody') ->will($this->returnValue($resultContent)); // Expected 2 times, 1 for setup and 1 for the actual test $responseMock ->expects($this->exactly(2)) - ->method('getPagination'); + ->method('getHeader') + ->with('Link'); $httpClient = $this->getHttpClientMock($responseMock); @@ -155,7 +165,7 @@ public function fetchNext() */ public function shouldHaveNext() { - $responseMock = $this->getResponseMock(array('next' => 'http://github.com/next')); + $responseMock = $this->getResponseMock('; rel="next"'); $httpClient = $this->getHttpClientMock($responseMock); $client = $this->getClientMock($httpClient); @@ -173,7 +183,7 @@ public function shouldHaveNext() */ public function shouldHavePrevious() { - $responseMock = $this->getResponseMock(array('prev' => 'http://github.com/previous')); + $responseMock = $this->getResponseMock('; rel="prev"'); $httpClient = $this->getHttpClientMock($responseMock); $client = $this->getClientMock($httpClient); @@ -184,14 +194,15 @@ public function shouldHavePrevious() $this->assertEquals($paginator->hasNext(), false); } - protected function getResponseMock(array $pagination) + protected function getResponseMock($header) { // response mock - $responseMock = $this->getMock('Github\HttpClient\Message\Response'); + $responseMock = $this->getMock('Guzzle\Http\Message\Response', array(), array(200)); $responseMock ->expects($this->any()) - ->method('getPagination') - ->will($this->returnValue($pagination)); + ->method('getHeader') + ->with('Link') + ->will($this->returnValue($header)); return $responseMock; } @@ -212,15 +223,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 = $this->getMock('Guzzle\Http\Client', array('send')); $clientInterfaceMock ->expects($this->any()) ->method('send');