diff --git a/composer.json b/composer.json index 5b226cc70bb..e5a0e106c83 100644 --- a/composer.json +++ b/composer.json @@ -24,17 +24,21 @@ "php-http/discovery": "^1.0", "php-http/client-implementation": "^1.0", "php-http/client-common": "^1.3", - "php-http/cache-plugin": "^1.3" + "php-http/cache-plugin": "^1.4" }, "require-dev": { "phpunit/phpunit": "^4.0 || ^5.5", "php-http/guzzle6-adapter": "^1.0", + "php-http/mock-client": "^1.0", "guzzlehttp/psr7": "^1.2", - "sllh/php-cs-fixer-styleci-bridge": "^1.3" + "sllh/php-cs-fixer-styleci-bridge": "^1.3", + "cache/array-adapter": "^0.4" }, "autoload": { "psr-4": { "Github\\": "lib/Github/" } }, + "minimum-stability": "dev", + "prefer-stable": true, "extra": { "branch-alias": { "dev-master": "2.3.x-dev" diff --git a/lib/Github/HttpClient/Builder.php b/lib/Github/HttpClient/Builder.php index e42a5efe22e..d87a021c076 100644 --- a/lib/Github/HttpClient/Builder.php +++ b/lib/Github/HttpClient/Builder.php @@ -13,6 +13,7 @@ use Http\Message\RequestFactory; use Http\Message\StreamFactory; use Psr\Cache\CacheItemPoolInterface; +use Http\Client\Common\Plugin\Cache\Generator\HeaderCacheKeyGenerator; /** * A builder that builds the API client. @@ -181,6 +182,9 @@ public function addHeaderValue($header, $headerValue) */ public function addCache(CacheItemPoolInterface $cachePool, array $config = []) { + if (!isset($config['cache_key_generator'])) { + $config['cache_key_generator'] = new HeaderCacheKeyGenerator(['Authorization', 'Cookie', 'Accept', 'Content-type']); + } $this->cachePlugin = Plugin\CachePlugin::clientCache($cachePool, $this->streamFactory, $config); $this->httpClientModified = true; } diff --git a/test/Github/Tests/Functional/CacheTest.php b/test/Github/Tests/Functional/CacheTest.php new file mode 100644 index 00000000000..31c6f5a4f5d --- /dev/null +++ b/test/Github/Tests/Functional/CacheTest.php @@ -0,0 +1,68 @@ + + */ +class CacheTest extends \PHPUnit_Framework_TestCase +{ + /** + * @test + */ + public function shouldServeCachedResponse() + { + $mockClient = new \Http\Mock\Client(); + $mockClient->addResponse($this->getCurrentUserResponse('nyholm')); + $mockClient->addResponse($this->getCurrentUserResponse('octocat')); + + $github = Client::createWithHttpClient($mockClient); + $github->addCache(new ArrayCachePool(), ['default_ttl'=>600]); + + $github->authenticate('fake_token_aaa', Client::AUTH_HTTP_TOKEN); + $userA = $github->currentUser()->show(); + $this->assertEquals('nyholm', $userA['login']); + + $userB = $github->currentUser()->show(); + $this->assertEquals('nyholm', $userB['login'], 'Two request following each other should be cached.'); + } + /** + * @test + */ + public function shouldVaryOnAuthorization() + { + $mockClient = new \Http\Mock\Client(); + $mockClient->addResponse($this->getCurrentUserResponse('nyholm')); + $mockClient->addResponse($this->getCurrentUserResponse('octocat')); + + $github = Client::createWithHttpClient($mockClient); + $github->addCache(new ArrayCachePool(), ['default_ttl'=>600]); + + $github->authenticate('fake_token_aaa', Client::AUTH_HTTP_TOKEN); + $userA = $github->currentUser()->show(); + $this->assertEquals('nyholm', $userA['login']); + + $github->authenticate('fake_token_bbb', Client::AUTH_HTTP_TOKEN); + $userB = $github->currentUser()->show(); + $this->assertEquals('octocat', $userB['login'], 'We must vary on the Authorization header.'); + } + + private function getCurrentUserResponse($username) + { + $headers = [ + 'Content-Type' => 'application/json', + ]; + + $body = \GuzzleHttp\Psr7\stream_for(json_encode([ + 'login' => $username, + ])); + + return new Response(200, $headers, $body); + } +}