From 8df3db566a3a937b45ebf11adb90d265e6f5e2d4 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 17 Nov 2019 20:45:02 +0100 Subject: initial checking of customized version 1.0rc9 --- .../Guzzle/Tests/Plugin/Cache/CachePluginTest.php | 441 +++++++++++++++++++++ 1 file changed, 441 insertions(+) create mode 100644 vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CachePluginTest.php (limited to 'vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CachePluginTest.php') diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CachePluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CachePluginTest.php new file mode 100644 index 0000000..69da60a --- /dev/null +++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CachePluginTest.php @@ -0,0 +1,441 @@ +assertInstanceOf('Guzzle\Plugin\Cache\CacheStorageInterface', $this->readAttribute($plugin, 'storage')); + } + + public function testAddsDefaultCollaborators() + { + $this->assertNotEmpty(CachePlugin::getSubscribedEvents()); + $plugin = new CachePlugin(array( + 'storage' => $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface')->getMockForAbstractClass() + )); + $this->assertInstanceOf('Guzzle\Plugin\Cache\CacheStorageInterface', $this->readAttribute($plugin, 'storage')); + $this->assertInstanceOf( + 'Guzzle\Plugin\Cache\CanCacheStrategyInterface', + $this->readAttribute($plugin, 'canCache') + ); + $this->assertInstanceOf( + 'Guzzle\Plugin\Cache\RevalidationInterface', + $this->readAttribute($plugin, 'revalidation') + ); + } + + public function testAddsCallbackCollaborators() + { + $this->assertNotEmpty(CachePlugin::getSubscribedEvents()); + $plugin = new CachePlugin(array('can_cache' => function () {})); + $this->assertInstanceOf( + 'Guzzle\Plugin\Cache\CallbackCanCacheStrategy', + $this->readAttribute($plugin, 'canCache') + ); + } + + public function testCanPassCacheAsOnlyArgumentToConstructor() + { + $p = new CachePlugin(new DoctrineCacheAdapter(new ArrayCache())); + $p = new CachePlugin(new DefaultCacheStorage(new DoctrineCacheAdapter(new ArrayCache()))); + } + + public function testUsesCreatedCacheStorage() + { + $plugin = new CachePlugin(array( + 'adapter' => $this->getMockBuilder('Guzzle\Cache\CacheAdapterInterface')->getMockForAbstractClass() + )); + $this->assertInstanceOf('Guzzle\Plugin\Cache\CacheStorageInterface', $this->readAttribute($plugin, 'storage')); + } + + public function testUsesProvidedOptions() + { + $can = $this->getMockBuilder('Guzzle\Plugin\Cache\CanCacheStrategyInterface')->getMockForAbstractClass(); + $revalidate = $this->getMockBuilder('Guzzle\Plugin\Cache\RevalidationInterface')->getMockForAbstractClass(); + $plugin = new CachePlugin(array( + 'storage' => $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface')->getMockForAbstractClass(), + 'can_cache' => $can, + 'revalidation' => $revalidate + )); + $this->assertSame($can, $this->readAttribute($plugin, 'canCache')); + $this->assertSame($revalidate, $this->readAttribute($plugin, 'revalidation')); + } + + public function satisfyProvider() + { + $req1 = new Request('GET', 'http://foo.com', array('Cache-Control' => 'no-cache')); + + return array( + // The response is too old to satisfy the request + array(new Request('GET', 'http://foo.com', array('Cache-Control' => 'max-age=20')), new Response(200, array('Age' => 100)), false, false), + // The response cannot satisfy the request because it is stale + array(new Request('GET', 'http://foo.com'), new Response(200, array('Cache-Control' => 'max-age=10', 'Age' => 100)), false, false), + // Allows the expired response to satisfy the request because of the max-stale + array(new Request('GET', 'http://foo.com', array('Cache-Control' => 'max-stale=15')), new Response(200, array('Cache-Control' => 'max-age=90', 'Age' => 100)), true, false), + // Max stale is > than the allowed staleness + array(new Request('GET', 'http://foo.com', array('Cache-Control' => 'max-stale=5')), new Response(200, array('Cache-Control' => 'max-age=90', 'Age' => 100)), false, false), + // Performs cache revalidation + array($req1, new Response(200), true, true), + // Performs revalidation due to ETag on the response and no cache-control on the request + array(new Request('GET', 'http://foo.com'), new Response(200, array( + 'ETag' => 'ABC', + 'Expires' => date('c', strtotime('+1 year')) + )), true, true), + ); + } + + /** + * @dataProvider satisfyProvider + */ + public function testChecksIfResponseCanSatisfyRequest($request, $response, $can, $revalidates) + { + $didRevalidate = false; + $storage = $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface')->getMockForAbstractClass(); + $revalidate = $this->getMockBuilder('Guzzle\Plugin\Cache\DefaultRevalidation') + ->setMethods(array('revalidate')) + ->setConstructorArgs(array($storage)) + ->getMockForAbstractClass(); + + $revalidate->expects($this->any()) + ->method('revalidate') + ->will($this->returnCallback(function () use (&$didRevalidate) { + $didRevalidate = true; + return true; + })); + + $plugin = new CachePlugin(array( + 'storage' => $storage, + 'revalidation' => $revalidate + )); + + $this->assertEquals($can, $plugin->canResponseSatisfyRequest($request, $response)); + $this->assertEquals($didRevalidate, $revalidates); + } + + public function satisfyFailedProvider() + { + return array( + // Neither has stale-if-error + array(new Request('GET', 'http://foo.com', array()), new Response(200, array('Age' => 100)), false), + // Request has stale-if-error + array(new Request('GET', 'http://foo.com', array('Cache-Control' => 'stale-if-error')), new Response(200, array('Age' => 100, 'Cache-Control' => 'max-age=50')), true), + // Request has valid stale-if-error + array(new Request('GET', 'http://foo.com', array('Cache-Control' => 'stale-if-error=50')), new Response(200, array('Age' => 100, 'Cache-Control' => 'max-age=50')), true), + // Request has expired stale-if-error + array(new Request('GET', 'http://foo.com', array('Cache-Control' => 'stale-if-error=20')), new Response(200, array('Age' => 100, 'Cache-Control' => 'max-age=50')), false), + // Response has permanent stale-if-error + array(new Request('GET', 'http://foo.com', array()), new Response(200, array('Age' => 100, 'Cache-Control' => 'max-age=50, stale-if-error', )), true), + // Response has valid stale-if-error + array(new Request('GET', 'http://foo.com', array()), new Response(200, array('Age' => 100, 'Cache-Control' => 'max-age=50, stale-if-error=50')), true), + // Response has expired stale-if-error + array(new Request('GET', 'http://foo.com', array()), new Response(200, array('Age' => 100, 'Cache-Control' => 'max-age=50, stale-if-error=20')), false), + // Request has valid stale-if-error but response does not + array(new Request('GET', 'http://foo.com', array('Cache-Control' => 'stale-if-error=50')), new Response(200, array('Age' => 100, 'Cache-Control' => 'max-age=50, stale-if-error=20')), false), + // Response has valid stale-if-error but request does not + array(new Request('GET', 'http://foo.com', array('Cache-Control' => 'stale-if-error=20')), new Response(200, array('Age' => 100, 'Cache-Control' => 'max-age=50, stale-if-error=50')), false), + ); + } + + /** + * @dataProvider satisfyFailedProvider + */ + public function testChecksIfResponseCanSatisfyFailedRequest($request, $response, $can) + { + $plugin = new CachePlugin(); + + $this->assertEquals($can, $plugin->canResponseSatisfyFailedRequest($request, $response)); + } + + public function testDoesNothingWhenRequestIsNotCacheable() + { + $storage = $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface') + ->setMethods(array('fetch')) + ->getMockForAbstractClass(); + $storage->expects($this->never())->method('fetch'); + + $plugin = new CachePlugin(array( + 'storage' => $storage, + 'can_cache' => new CallbackCanCacheStrategy(function () { return false; }) + )); + + $plugin->onRequestBeforeSend(new Event(array( + 'request' => new Request('GET', 'http://foo.com') + ))); + } + + public function satisfiableProvider() + { + $date = new \DateTime('-10 seconds'); + + return array( + // Fresh response + array(new Response(200, array(), 'foo')), + // Stale response + array(new Response(200, array('Date' => $date->format('c'), 'Cache-Control' => 'max-age=5'), 'foo')) + ); + } + + /** + * @dataProvider satisfiableProvider + */ + public function testInjectsSatisfiableResponses($response) + { + $storage = $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface') + ->setMethods(array('fetch')) + ->getMockForAbstractClass(); + + $storage->expects($this->once())->method('fetch')->will($this->returnValue($response)); + $plugin = new CachePlugin(array('storage' => $storage)); + $request = new Request('GET', 'http://foo.com', array('Cache-Control' => 'max-stale')); + $plugin->onRequestBeforeSend(new Event(array('request' => $request))); + $plugin->onRequestSent(new Event(array('request' => $request, 'response' => $request->getResponse()))); + $this->assertEquals($response->getStatusCode(), $request->getResponse()->getStatusCode()); + $this->assertEquals((string) $response->getBody(), (string) $request->getResponse()->getBody()); + $this->assertTrue($request->getResponse()->hasHeader('Age')); + if ($request->getResponse()->isFresh() === false) { + $this->assertContains('110', (string) $request->getResponse()->getHeader('Warning')); + } + $this->assertSame( + sprintf('%s GuzzleCache/%s', $request->getProtocolVersion(), Version::VERSION), + (string) $request->getHeader('Via') + ); + $this->assertSame( + sprintf('%s GuzzleCache/%s',$request->getProtocolVersion(), Version::VERSION), + (string) $request->getResponse()->getHeader('Via') + ); + $this->assertTrue($request->getParams()->get('cache.lookup')); + $this->assertTrue($request->getParams()->get('cache.hit')); + $this->assertTrue($request->getResponse()->hasHeader('X-Cache-Lookup')); + $this->assertTrue($request->getResponse()->hasHeader('X-Cache')); + $this->assertEquals('HIT from GuzzleCache', (string) $request->getResponse()->getHeader('X-Cache')); + $this->assertEquals('HIT from GuzzleCache', (string) $request->getResponse()->getHeader('X-Cache-Lookup')); + } + + public function satisfiableOnErrorProvider() + { + $date = new \DateTime('-10 seconds'); + return array( + array( + new Response(200, array( + 'Date' => $date->format('c'), + 'Cache-Control' => 'max-age=5, stale-if-error' + ), 'foo'), + ) + ); + } + + /** + * @dataProvider satisfiableOnErrorProvider + */ + public function testInjectsSatisfiableResponsesOnError($cacheResponse) + { + $storage = $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface') + ->setMethods(array('fetch')) + ->getMockForAbstractClass(); + $storage->expects($this->exactly(2))->method('fetch')->will($this->returnValue($cacheResponse)); + $plugin = new CachePlugin(array('storage' => $storage)); + $request = new Request('GET', 'http://foo.com', array('Cache-Control' => 'max-stale')); + $plugin->onRequestBeforeSend(new Event(array('request' => $request))); + $plugin->onRequestError( + $event = new Event(array( + 'request' => $request, + 'response' => $request->getResponse(), + )) + ); + $response = $event['response']; + $this->assertEquals($cacheResponse->getStatusCode(), $response->getStatusCode()); + $this->assertEquals((string) $cacheResponse->getBody(), (string) $response->getBody()); + $this->assertTrue($response->hasHeader('Age')); + if ($response->isFresh() === false) { + $this->assertContains('110', (string) $response->getHeader('Warning')); + } + $this->assertSame(sprintf('%s GuzzleCache/%s', $request->getProtocolVersion(), Version::VERSION), (string) $request->getHeader('Via')); + $this->assertSame(sprintf('%s GuzzleCache/%s', $request->getProtocolVersion(), Version::VERSION), (string) $response->getHeader('Via')); + $this->assertTrue($request->getParams()->get('cache.lookup')); + $this->assertSame('error', $request->getParams()->get('cache.hit')); + $this->assertTrue($response->hasHeader('X-Cache-Lookup')); + $this->assertTrue($response->hasHeader('X-Cache')); + $this->assertEquals('HIT from GuzzleCache', (string) $response->getHeader('X-Cache-Lookup')); + $this->assertEquals('HIT_ERROR from GuzzleCache', (string) $response->getHeader('X-Cache')); + } + + /** + * @dataProvider satisfiableOnErrorProvider + */ + public function testInjectsSatisfiableResponsesOnException($cacheResponse) + { + $storage = $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface') + ->setMethods(array('fetch')) + ->getMockForAbstractClass(); + $storage->expects($this->exactly(2))->method('fetch')->will($this->returnValue($cacheResponse)); + $plugin = new CachePlugin(array('storage' => $storage)); + $request = new Request('GET', 'http://foo.com', array('Cache-Control' => 'max-stale')); + $plugin->onRequestBeforeSend(new Event(array( + 'request' => $request + ))); + $plugin->onRequestException( + new Event(array( + 'request' => $request, + 'response' => $request->getResponse(), + 'exception' => $this->getMock('Guzzle\Http\Exception\CurlException'), + )) + ); + $plugin->onRequestSent( + new Event(array( + 'request' => $request, + 'response' => $response = $request->getResponse(), + )) + ); + $this->assertEquals($cacheResponse->getStatusCode(), $response->getStatusCode()); + $this->assertEquals((string) $cacheResponse->getBody(), (string) $response->getBody()); + $this->assertTrue($response->hasHeader('Age')); + if ($response->isFresh() === false) { + $this->assertContains('110', (string) $response->getHeader('Warning')); + } + $this->assertSame(sprintf('%s GuzzleCache/%s', $request->getProtocolVersion(), Version::VERSION), (string) $request->getHeader('Via')); + $this->assertSame(sprintf('%s GuzzleCache/%s', $request->getProtocolVersion(), Version::VERSION), (string) $response->getHeader('Via')); + $this->assertTrue($request->getParams()->get('cache.lookup')); + $this->assertSame('error', $request->getParams()->get('cache.hit')); + $this->assertTrue($response->hasHeader('X-Cache-Lookup')); + $this->assertTrue($response->hasHeader('X-Cache')); + $this->assertEquals('HIT from GuzzleCache', (string) $response->getHeader('X-Cache-Lookup')); + $this->assertEquals('HIT_ERROR from GuzzleCache', (string) $response->getHeader('X-Cache')); + } + + public function unsatisfiableOnErrorProvider() + { + $date = new \DateTime('-10 seconds'); + + return array( + // no-store on request + array( + false, + array('Cache-Control' => 'no-store'), + new Response(200, array('Date' => $date->format('D, d M Y H:i:s T'), 'Cache-Control' => 'max-age=5, stale-if-error'), 'foo'), + ), + // request expired + array( + true, + array('Cache-Control' => 'stale-if-error=4'), + new Response(200, array('Date' => $date->format('D, d M Y H:i:s T'), 'Cache-Control' => 'max-age=5, stale-if-error'), 'foo'), + ), + // response expired + array( + true, + array('Cache-Control' => 'stale-if-error'), + new Response(200, array('Date' => $date->format('D, d M Y H:i:s T'), 'Cache-Control' => 'max-age=5, stale-if-error=4'), 'foo'), + ), + ); + } + + /** + * @dataProvider unsatisfiableOnErrorProvider + */ + public function testDoesNotInjectUnsatisfiableResponsesOnError($requestCanCache, $requestHeaders, $cacheResponse) + { + $storage = $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface') + ->setMethods(array('fetch')) + ->getMockForAbstractClass(); + $storage->expects($this->exactly($requestCanCache ? 2 : 0))->method('fetch')->will($this->returnValue($cacheResponse)); + $plugin = new CachePlugin(array('storage' => $storage)); + $request = new Request('GET', 'http://foo.com', $requestHeaders); + $plugin->onRequestBeforeSend(new Event(array( + 'request' => $request + ))); + $plugin->onRequestError( + $event = new Event(array( + 'request' => $request, + 'response' => $response = $request->getResponse(), + )) + ); + + $this->assertSame($response, $event['response']); + } + + /** + * @dataProvider unsatisfiableOnErrorProvider + */ + public function testDoesNotInjectUnsatisfiableResponsesOnException($requestCanCache, $requestHeaders, $responseParts) + { + $storage = $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface') + ->setMethods(array('fetch')) + ->getMockForAbstractClass(); + $storage->expects($this->exactly($requestCanCache ? 2 : 0))->method('fetch')->will($this->returnValue($responseParts)); + $plugin = new CachePlugin(array('storage' => $storage)); + $request = new Request('GET', 'http://foo.com', $requestHeaders); + $plugin->onRequestBeforeSend(new Event(array( + 'request' => $request + ))); + $plugin->onRequestException( + $event = new Event(array( + 'request' => $request, + 'response' => $response = $request->getResponse(), + 'exception' => $this->getMock('Guzzle\Http\Exception\CurlException'), + )) + ); + + $this->assertSame($response, $request->getResponse()); + } + + public function testCachesResponsesWhenCacheable() + { + $cache = new ArrayCache(); + $plugin = new CachePlugin($cache); + + $request = new Request('GET', 'http://foo.com'); + $response = new Response(200, array(), 'Foo'); + $plugin->onRequestBeforeSend(new Event(array( + 'request' => $request + ))); + $plugin->onRequestSent(new Event(array( + 'request' => $request, + 'response' => $response + ))); + $data = $this->readAttribute($cache, 'data'); + $this->assertNotEmpty($data); + } + + public function testPurgesRequests() + { + $storage = $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface') + ->setMethods(array('purge')) + ->getMockForAbstractClass(); + $storage->expects($this->atLeastOnce())->method('purge'); + $plugin = new CachePlugin(array('storage' => $storage)); + $request = new Request('GET', 'http://foo.com', array('X-Foo' => 'Bar')); + $plugin->purge($request); + } + + public function testAutoPurgesRequests() + { + $storage = $this->getMockBuilder('Guzzle\Plugin\Cache\CacheStorageInterface') + ->setMethods(array('purge')) + ->getMockForAbstractClass(); + $storage->expects($this->atLeastOnce())->method('purge'); + $plugin = new CachePlugin(array('storage' => $storage, 'auto_purge' => true)); + $client = new Client(); + $request = $client->put('http://foo.com', array('X-Foo' => 'Bar')); + $request->addSubscriber($plugin); + $request->setResponse(new Response(200), true); + $request->send(); + } +} -- cgit v1.2.3-54-g00ecf