summaryrefslogtreecommitdiff
path: root/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin')
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Async/AsyncPluginTest.php93
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/AbstractBackoffStrategyTest.php86
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/BackoffLoggerTest.php110
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/BackoffPluginTest.php297
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/CallbackBackoffStrategyTest.php31
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ConstantBackoffStrategyTest.php20
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/CurlBackoffStrategyTest.php36
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ExponentialBackoffStrategyTest.php23
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/HttpBackoffStrategyTest.php47
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/LinearBackoffStrategyTest.php21
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ReasonPhraseBackoffStrategyTest.php32
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/TruncatedBackoffStrategyTest.php30
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CachePluginTest.php441
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CallbackCanCacheStrategyTest.php72
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultCacheStorageTest.php193
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultCanCacheStrategyTest.php40
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultRevalidationTest.php248
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DenyRevalidationTest.php19
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/SkipRevalidationTest.php19
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieJar/ArrayCookieJarTest.php385
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieJar/FileCookieJarTest.php63
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookiePluginTest.php134
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieTest.php223
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/CurlAuth/CurlAuthPluginTest.php39
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/ErrorResponse/ErrorResponsePluginTest.php137
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/History/HistoryPluginTest.php140
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Log/LogPluginTest.php95
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Md5/CommandContentMd5PluginTest.php97
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Md5/Md5ValidatorPluginTest.php120
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Mock/MockPluginTest.php199
-rw-r--r--vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Oauth/OauthPluginTest.php345
31 files changed, 3835 insertions, 0 deletions
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Async/AsyncPluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Async/AsyncPluginTest.php
new file mode 100644
index 0000000..16990a5
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Async/AsyncPluginTest.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Async;
+
+use Guzzle\Plugin\Async\AsyncPlugin;
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Http\Message\RequestFactory;
+use Guzzle\Http\Curl\CurlHandle;
+use Guzzle\Http\Exception\CurlException;
+use Guzzle\Common\Event;
+use Guzzle\Http\Client;
+
+/**
+ * @covers Guzzle\Plugin\Async\AsyncPlugin
+ */
+class AsyncPluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testSubscribesToEvents()
+ {
+ $events = AsyncPlugin::getSubscribedEvents();
+ $this->assertArrayHasKey('request.before_send', $events);
+ $this->assertArrayHasKey('request.exception', $events);
+ $this->assertArrayHasKey('curl.callback.progress', $events);
+ }
+
+ public function testEnablesProgressCallbacks()
+ {
+ $p = new AsyncPlugin();
+ $request = RequestFactory::getInstance()->create('PUT', 'http://www.example.com');
+ $event = new Event(array(
+ 'request' => $request
+ ));
+ $p->onBeforeSend($event);
+ $this->assertEquals(true, $request->getCurlOptions()->get('progress'));
+ }
+
+ public function testAddsTimesOutAfterSending()
+ {
+ $p = new AsyncPlugin();
+ $request = RequestFactory::getInstance()->create('PUT', 'http://www.example.com');
+ $handle = CurlHandle::factory($request);
+ $event = new Event(array(
+ 'request' => $request,
+ 'handle' => $handle->getHandle(),
+ 'uploaded' => 10,
+ 'upload_size' => 10,
+ 'downloaded' => 0
+ ));
+ $p->onCurlProgress($event);
+ }
+
+ public function testEnsuresRequestIsSet()
+ {
+ $p = new AsyncPlugin();
+ $event = new Event(array(
+ 'uploaded' => 10,
+ 'upload_size' => 10,
+ 'downloaded' => 0
+ ));
+ $p->onCurlProgress($event);
+ }
+
+ public function testMasksCurlExceptions()
+ {
+ $p = new AsyncPlugin();
+ $request = RequestFactory::getInstance()->create('PUT', 'http://www.example.com');
+ $e = new CurlException('Error');
+ $event = new Event(array(
+ 'request' => $request,
+ 'exception' => $e
+ ));
+ $p->onRequestTimeout($event);
+ $this->assertEquals(RequestInterface::STATE_COMPLETE, $request->getState());
+ $this->assertEquals(200, $request->getResponse()->getStatusCode());
+ $this->assertTrue($request->getResponse()->hasHeader('X-Guzzle-Async'));
+ }
+
+ public function testEnsuresIntegration()
+ {
+ $this->getServer()->flush();
+ $this->getServer()->enqueue("HTTP/1.1 204 FOO\r\nContent-Length: 4\r\n\r\ntest");
+ $client = new Client($this->getServer()->getUrl());
+ $request = $client->post('/', null, array(
+ 'foo' => 'bar'
+ ));
+ $request->getEventDispatcher()->addSubscriber(new AsyncPlugin());
+ $request->send();
+ $this->assertEquals('', $request->getResponse()->getBody(true));
+ $this->assertTrue($request->getResponse()->hasHeader('X-Guzzle-Async'));
+ $received = $this->getServer()->getReceivedRequests(true);
+ $this->assertEquals('POST', $received[0]->getMethod());
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/AbstractBackoffStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/AbstractBackoffStrategyTest.php
new file mode 100644
index 0000000..72af263
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/AbstractBackoffStrategyTest.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Http\Message\Request;
+use Guzzle\Plugin\Backoff\TruncatedBackoffStrategy;
+use Guzzle\Plugin\Backoff\CallbackBackoffStrategy;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\AbstractBackoffStrategy
+ */
+class AbstractBackoffStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ protected function getMockStrategy()
+ {
+ return $this->getMockBuilder('Guzzle\Plugin\Backoff\AbstractBackoffStrategy')
+ ->setMethods(array('getDelay', 'makesDecision'))
+ ->getMockForAbstractClass();
+ }
+
+ public function testReturnsZeroWhenNoNextAndGotNull()
+ {
+ $request = new Request('GET', 'http://www.foo.com');
+ $mock = $this->getMockStrategy();
+ $mock->expects($this->atLeastOnce())->method('getDelay')->will($this->returnValue(null));
+ $this->assertEquals(0, $mock->getBackoffPeriod(0, $request));
+ }
+
+ public function testReturnsFalse()
+ {
+ $request = new Request('GET', 'http://www.foo.com');
+ $mock = $this->getMockStrategy();
+ $mock->expects($this->atLeastOnce())->method('getDelay')->will($this->returnValue(false));
+ $this->assertEquals(false, $mock->getBackoffPeriod(0, $request));
+ }
+
+ public function testReturnsNextValueWhenNullOrTrue()
+ {
+ $request = new Request('GET', 'http://www.foo.com');
+ $mock = $this->getMockStrategy();
+ $mock->expects($this->atLeastOnce())->method('getDelay')->will($this->returnValue(null));
+ $mock->expects($this->any())->method('makesDecision')->will($this->returnValue(false));
+
+ $mock2 = $this->getMockStrategy();
+ $mock2->expects($this->atLeastOnce())->method('getDelay')->will($this->returnValue(10));
+ $mock2->expects($this->atLeastOnce())->method('makesDecision')->will($this->returnValue(true));
+ $mock->setNext($mock2);
+
+ $this->assertEquals(10, $mock->getBackoffPeriod(0, $request));
+ }
+
+ public function testReturnsFalseWhenNullAndNoNext()
+ {
+ $request = new Request('GET', 'http://www.foo.com');
+ $s = new TruncatedBackoffStrategy(2);
+ $this->assertFalse($s->getBackoffPeriod(0, $request));
+ }
+
+ public function testHasNext()
+ {
+ $a = new TruncatedBackoffStrategy(2);
+ $b = new TruncatedBackoffStrategy(2);
+ $a->setNext($b);
+ $this->assertSame($b, $a->getNext());
+ }
+
+ public function testSkipsOtherDecisionsInChainWhenOneReturnsTrue()
+ {
+ $a = new CallbackBackoffStrategy(function () { return null; }, true);
+ $b = new CallbackBackoffStrategy(function () { return true; }, true);
+ $c = new CallbackBackoffStrategy(function () { return null; }, true);
+ $d = new CallbackBackoffStrategy(function () { return 10; }, false);
+ $a->setNext($b);
+ $b->setNext($c);
+ $c->setNext($d);
+ $this->assertEquals(10, $a->getBackoffPeriod(2, new Request('GET', 'http://www.foo.com')));
+ }
+
+ public function testReturnsZeroWhenDecisionMakerReturnsTrueButNoFurtherStrategiesAreInTheChain()
+ {
+ $a = new CallbackBackoffStrategy(function () { return null; }, true);
+ $b = new CallbackBackoffStrategy(function () { return true; }, true);
+ $a->setNext($b);
+ $this->assertSame(0, $a->getBackoffPeriod(2, new Request('GET', 'http://www.foo.com')));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/BackoffLoggerTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/BackoffLoggerTest.php
new file mode 100644
index 0000000..a64dd82
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/BackoffLoggerTest.php
@@ -0,0 +1,110 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Common\Event;
+use Guzzle\Log\ClosureLogAdapter;
+use Guzzle\Http\Curl\CurlHandle;
+use Guzzle\Plugin\Backoff\BackoffLogger;
+use Guzzle\Http\Message\Response;
+use Guzzle\Http\Message\RequestFactory;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\BackoffLogger
+ */
+class BackoffLoggerTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public $message;
+
+ public function setUp()
+ {
+ $this->message = '';
+ }
+
+ public function testHasEventList()
+ {
+ $this->assertEquals(1, count(BackoffLogger::getSubscribedEvents()));
+ }
+
+ public function testLogsEvents()
+ {
+ list($logPlugin, $request, $response) = $this->getMocks();
+
+ $response = $this->getMockBuilder('Guzzle\Http\Message\Response')
+ ->setConstructorArgs(array(503))
+ ->setMethods(array('getInfo'))
+ ->getMock();
+
+ $response->expects($this->any())
+ ->method('getInfo')
+ ->will($this->returnValue(2));
+
+ $handle = $this->getMockHandle();
+
+ $event = new Event(array(
+ 'request' => $request,
+ 'response' => $response,
+ 'retries' => 1,
+ 'delay' => 3,
+ 'handle' => $handle
+ ));
+
+ $logPlugin->onRequestRetry($event);
+ $this->assertContains(
+ '] PUT http://www.example.com - 503 Service Unavailable - Retries: 1, Delay: 3, Time: 2, 2, cURL: 30 Foo',
+ $this->message
+ );
+ }
+
+ public function testCanSetTemplate()
+ {
+ $l = new BackoffLogger(new ClosureLogAdapter(function () {}));
+ $l->setTemplate('foo');
+ $t = $this->readAttribute($l, 'formatter');
+ $this->assertEquals('foo', $this->readAttribute($t, 'template'));
+ }
+
+ /**
+ * @return array
+ */
+ protected function getMocks()
+ {
+ $that = $this;
+ $logger = new ClosureLogAdapter(function ($message) use ($that) {
+ $that->message .= $message . "\n";
+ });
+ $logPlugin = new BackoffLogger($logger);
+ $response = new Response(503);
+ $request = RequestFactory::getInstance()->create('PUT', 'http://www.example.com', array(
+ 'Content-Length' => 3,
+ 'Foo' => 'Bar'
+ ));
+
+ return array($logPlugin, $request, $response);
+ }
+
+ /**
+ * @return CurlHandle
+ */
+ protected function getMockHandle()
+ {
+ $handle = $this->getMockBuilder('Guzzle\Http\Curl\CurlHandle')
+ ->disableOriginalConstructor()
+ ->setMethods(array('getError', 'getErrorNo', 'getInfo'))
+ ->getMock();
+
+ $handle->expects($this->once())
+ ->method('getError')
+ ->will($this->returnValue('Foo'));
+
+ $handle->expects($this->once())
+ ->method('getErrorNo')
+ ->will($this->returnValue(30));
+
+ $handle->expects($this->any())
+ ->method('getInfo')
+ ->will($this->returnValue(2));
+
+ return $handle;
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/BackoffPluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/BackoffPluginTest.php
new file mode 100644
index 0000000..496e49e
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/BackoffPluginTest.php
@@ -0,0 +1,297 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Common\Event;
+use Guzzle\Http\Exception\CurlException;
+use Guzzle\Http\Client;
+use Guzzle\Plugin\Backoff\BackoffPlugin;
+use Guzzle\Http\Message\RequestInterface;
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\EntityEnclosingRequest;
+use Guzzle\Http\Message\Response;
+use Guzzle\Http\Curl\CurlMulti;
+use Guzzle\Http\Curl\CurlMultiInterface;
+use Guzzle\Plugin\Backoff\ConstantBackoffStrategy;
+use Guzzle\Plugin\Backoff\CurlBackoffStrategy;
+use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
+use Guzzle\Plugin\Backoff\TruncatedBackoffStrategy;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * @group server
+ * @covers Guzzle\Plugin\Backoff\BackoffPlugin
+ */
+class BackoffPluginTest extends \Guzzle\Tests\GuzzleTestCase implements EventSubscriberInterface
+{
+ protected $retried;
+
+ public function setUp()
+ {
+ $this->retried = false;
+ }
+
+ public static function getSubscribedEvents()
+ {
+ return array(BackoffPlugin::RETRY_EVENT => 'onRequestRetry');
+ }
+
+ public function onRequestRetry(Event $event)
+ {
+ $this->retried = $event;
+ }
+
+ public function testHasEventList()
+ {
+ $this->assertEquals(1, count(BackoffPlugin::getAllEvents()));
+ }
+
+ public function testCreatesDefaultExponentialBackoffPlugin()
+ {
+ $plugin = BackoffPlugin::getExponentialBackoff(3, array(204), array(10));
+ $this->assertInstanceOf('Guzzle\Plugin\Backoff\BackoffPlugin', $plugin);
+ $strategy = $this->readAttribute($plugin, 'strategy');
+ $this->assertInstanceOf('Guzzle\Plugin\Backoff\TruncatedBackoffStrategy', $strategy);
+ $this->assertEquals(3, $this->readAttribute($strategy, 'max'));
+ $strategy = $this->readAttribute($strategy, 'next');
+ $this->assertInstanceOf('Guzzle\Plugin\Backoff\HttpBackoffStrategy', $strategy);
+ $this->assertEquals(array(204 => true), $this->readAttribute($strategy, 'errorCodes'));
+ $strategy = $this->readAttribute($strategy, 'next');
+ $this->assertInstanceOf('Guzzle\Plugin\Backoff\CurlBackoffStrategy', $strategy);
+ $this->assertEquals(array(10 => true), $this->readAttribute($strategy, 'errorCodes'));
+ $strategy = $this->readAttribute($strategy, 'next');
+ $this->assertInstanceOf('Guzzle\Plugin\Backoff\ExponentialBackoffStrategy', $strategy);
+ }
+
+ public function testDoesNotRetryUnlessStrategyReturnsNumber()
+ {
+ $request = new Request('GET', 'http://www.example.com');
+ $request->setState('transfer');
+
+ $mock = $this->getMockBuilder('Guzzle\Plugin\Backoff\BackoffStrategyInterface')
+ ->setMethods(array('getBackoffPeriod'))
+ ->getMockForAbstractClass();
+
+ $mock->expects($this->once())
+ ->method('getBackoffPeriod')
+ ->will($this->returnValue(false));
+
+ $plugin = new BackoffPlugin($mock);
+ $plugin->addSubscriber($this);
+ $plugin->onRequestSent(new Event(array('request' => $request)));
+ $this->assertFalse($this->retried);
+ }
+
+ public function testUpdatesRequestForRetry()
+ {
+ $request = new Request('GET', 'http://www.example.com');
+ $request->setState('transfer');
+ $response = new Response(500);
+ $handle = $this->getMockBuilder('Guzzle\Http\Curl\CurlHandle')->disableOriginalConstructor()->getMock();
+ $e = new CurlException();
+ $e->setCurlHandle($handle);
+
+ $plugin = new BackoffPlugin(new ConstantBackoffStrategy(10));
+ $plugin->addSubscriber($this);
+
+ $event = new Event(array(
+ 'request' => $request,
+ 'response' => $response,
+ 'exception' => $e
+ ));
+
+ $plugin->onRequestSent($event);
+ $this->assertEquals(array(
+ 'request' => $request,
+ 'response' => $response,
+ 'handle' => $handle,
+ 'retries' => 1,
+ 'delay' => 10
+ ), $this->readAttribute($this->retried, 'context'));
+
+ $plugin->onRequestSent($event);
+ $this->assertEquals(array(
+ 'request' => $request,
+ 'response' => $response,
+ 'handle' => $handle,
+ 'retries' => 2,
+ 'delay' => 10
+ ), $this->readAttribute($this->retried, 'context'));
+ }
+
+ public function testDoesNothingWhenNotRetryingAndPollingRequest()
+ {
+ $request = new Request('GET', 'http://www.foo.com');
+ $plugin = new BackoffPlugin(new ConstantBackoffStrategy(10));
+ $plugin->onRequestPoll(new Event(array('request' => $request)));
+ }
+
+ public function testRetriesRequests()
+ {
+ // Create a script to return several 500 and 503 response codes
+ $this->getServer()->flush();
+ $this->getServer()->enqueue(array(
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata"
+ ));
+
+ $plugin = new BackoffPlugin(
+ new TruncatedBackoffStrategy(3,
+ new HttpBackoffStrategy(null,
+ new CurlBackoffStrategy(null,
+ new ConstantBackoffStrategy(0.05)
+ )
+ )
+ )
+ );
+
+ $client = new Client($this->getServer()->getUrl());
+ $client->getEventDispatcher()->addSubscriber($plugin);
+ $request = $client->get();
+ $request->send();
+
+ // Make sure it eventually completed successfully
+ $this->assertEquals(200, $request->getResponse()->getStatusCode());
+ $this->assertEquals('data', $request->getResponse()->getBody(true));
+
+ // Check that three requests were made to retry this request
+ $this->assertEquals(3, count($this->getServer()->getReceivedRequests(false)));
+ $this->assertEquals(2, $request->getParams()->get(BackoffPlugin::RETRY_PARAM));
+ }
+
+ /**
+ * @expectedException \Guzzle\Http\Exception\ServerErrorResponseException
+ */
+ public function testFailsOnTruncation()
+ {
+ $this->getServer()->flush();
+ $this->getServer()->enqueue(array(
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n"
+ ));
+
+ $plugin = new BackoffPlugin(
+ new TruncatedBackoffStrategy(2,
+ new HttpBackoffStrategy(null,
+ new ConstantBackoffStrategy(0.05)
+ )
+ )
+ );
+
+ $client = new Client($this->getServer()->getUrl());
+ $client->addSubscriber($plugin);
+ $client->get()->send();
+ }
+
+ public function testRetriesRequestsWhenInParallel()
+ {
+ // Create a script to return several 500 and 503 response codes
+ $this->getServer()->flush();
+ $this->getServer()->enqueue(array(
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata",
+ "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata",
+ "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata",
+ "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata",
+ "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata"
+ ));
+
+ $plugin = new BackoffPlugin(
+ new HttpBackoffStrategy(null,
+ new TruncatedBackoffStrategy(3,
+ new CurlBackoffStrategy(null,
+ new ConstantBackoffStrategy(0.1)
+ )
+ )
+ )
+ );
+ $client = new Client($this->getServer()->getUrl());
+ $client->getEventDispatcher()->addSubscriber($plugin);
+ $requests = array();
+ for ($i = 0; $i < 5; $i++) {
+ $requests[] = $client->get();
+ }
+ $client->send($requests);
+
+ $this->assertEquals(15, count($this->getServer()->getReceivedRequests(false)));
+ }
+
+ /**
+ * @covers Guzzle\Plugin\Backoff\BackoffPlugin
+ * @covers Guzzle\Http\Curl\CurlMulti
+ */
+ public function testRetriesPooledRequestsUsingDelayAndPollingEvent()
+ {
+ $this->getServer()->flush();
+ $this->getServer()->enqueue(array(
+ "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
+ "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata"
+ ));
+ // Need to sleep for some time ensure that the polling works correctly in the observer
+ $plugin = new BackoffPlugin(new HttpBackoffStrategy(null,
+ new TruncatedBackoffStrategy(1,
+ new ConstantBackoffStrategy(0.5))));
+
+ $client = new Client($this->getServer()->getUrl());
+ $client->getEventDispatcher()->addSubscriber($plugin);
+ $request = $client->get();
+ $request->send();
+ // Make sure it eventually completed successfully
+ $this->assertEquals('data', $request->getResponse()->getBody(true));
+ // Check that two requests were made to retry this request
+ $this->assertEquals(2, count($this->getServer()->getReceivedRequests(false)));
+ }
+
+ public function testSeeksToBeginningOfRequestBodyWhenRetrying()
+ {
+ // Create a request with a body
+ $request = new EntityEnclosingRequest('PUT', 'http://www.example.com');
+ $request->setBody('abc');
+ // Set the retry time to be something that will be retried always
+ $request->getParams()->set(BackoffPlugin::DELAY_PARAM, 2);
+ // Seek to the end of the stream
+ $request->getBody()->seek(3);
+ $this->assertEquals('', $request->getBody()->read(1));
+ // Create a plugin that does not delay when retrying
+ $plugin = new BackoffPlugin(new ConstantBackoffStrategy(0));
+ $plugin->onRequestPoll($this->getMockEvent($request));
+ // Ensure that the stream was seeked to 0
+ $this->assertEquals('a', $request->getBody()->read(1));
+ }
+
+ public function testDoesNotSeekOnRequestsWithNoBodyWhenRetrying()
+ {
+ // Create a request with a body
+ $request = new EntityEnclosingRequest('PUT', 'http://www.example.com');
+ $request->getParams()->set(BackoffPlugin::DELAY_PARAM, 2);
+ $plugin = new BackoffPlugin(new ConstantBackoffStrategy(0));
+ $plugin->onRequestPoll($this->getMockEvent($request));
+ }
+
+ protected function getMockEvent(RequestInterface $request)
+ {
+ // Create a mock curl multi object
+ $multi = $this->getMockBuilder('Guzzle\Http\Curl\CurlMulti')
+ ->setMethods(array('remove', 'add'))
+ ->getMock();
+
+ // Create an event that is expected for the Poll event
+ $event = new Event(array(
+ 'request' => $request,
+ 'curl_multi' => $multi
+ ));
+ $event->setName(CurlMultiInterface::POLLING_REQUEST);
+
+ return $event;
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/CallbackBackoffStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/CallbackBackoffStrategyTest.php
new file mode 100644
index 0000000..c0ce10d
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/CallbackBackoffStrategyTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Plugin\Backoff\CallbackBackoffStrategy;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\CallbackBackoffStrategy
+ */
+class CallbackBackoffStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ /**
+ * @expectedException Guzzle\Common\Exception\InvalidArgumentException
+ */
+ public function testEnsuresIsCallable()
+ {
+ $strategy = new CallbackBackoffStrategy(new \stdClass(), true);
+ }
+
+ public function testRetriesWithCallable()
+ {
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $strategy = new CallbackBackoffStrategy(function () { return 10; }, true);
+ $this->assertTrue($strategy->makesDecision());
+ $this->assertEquals(10, $strategy->getBackoffPeriod(0, $request));
+ // Ensure it chains correctly when null is returned
+ $strategy = new CallbackBackoffStrategy(function () { return null; }, false);
+ $this->assertFalse($strategy->makesDecision());
+ $this->assertFalse($strategy->getBackoffPeriod(0, $request));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ConstantBackoffStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ConstantBackoffStrategyTest.php
new file mode 100644
index 0000000..703eb4a
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ConstantBackoffStrategyTest.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Plugin\Backoff\ConstantBackoffStrategy;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\ConstantBackoffStrategy
+ */
+class ConstantBackoffStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testRetriesWithConstantDelay()
+ {
+ $strategy = new ConstantBackoffStrategy(3.5);
+ $this->assertFalse($strategy->makesDecision());
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $this->assertEquals(3.5, $strategy->getBackoffPeriod(0, $request));
+ $this->assertEquals(3.5, $strategy->getBackoffPeriod(1, $request));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/CurlBackoffStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/CurlBackoffStrategyTest.php
new file mode 100644
index 0000000..0a5c3e2
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/CurlBackoffStrategyTest.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Backoff\CurlBackoffStrategy;
+use Guzzle\Http\Exception\CurlException;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\CurlBackoffStrategy
+ * @covers Guzzle\Plugin\Backoff\AbstractErrorCodeBackoffStrategy
+ */
+class CurlBackoffStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testRetriesWithExponentialDelay()
+ {
+ $this->assertNotEmpty(CurlBackoffStrategy::getDefaultFailureCodes());
+ $strategy = new CurlBackoffStrategy();
+ $this->assertTrue($strategy->makesDecision());
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $e = new CurlException();
+ $e->setError('foo', CURLE_BAD_CALLING_ORDER);
+ $this->assertEquals(false, $strategy->getBackoffPeriod(0, $request, null, $e));
+
+ foreach (CurlBackoffStrategy::getDefaultFailureCodes() as $code) {
+ $this->assertEquals(0, $strategy->getBackoffPeriod(0, $request, null, $e->setError('foo', $code)));
+ }
+ }
+
+ public function testIgnoresNonErrors()
+ {
+ $strategy = new CurlBackoffStrategy();
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $this->assertEquals(false, $strategy->getBackoffPeriod(0, $request, new Response(200)));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ExponentialBackoffStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ExponentialBackoffStrategyTest.php
new file mode 100644
index 0000000..09965bc
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ExponentialBackoffStrategyTest.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Plugin\Backoff\ExponentialBackoffStrategy;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\ExponentialBackoffStrategy
+ */
+class ExponentialBackoffStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testRetriesWithExponentialDelay()
+ {
+ $strategy = new ExponentialBackoffStrategy();
+ $this->assertFalse($strategy->makesDecision());
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $this->assertEquals(1, $strategy->getBackoffPeriod(0, $request));
+ $this->assertEquals(2, $strategy->getBackoffPeriod(1, $request));
+ $this->assertEquals(4, $strategy->getBackoffPeriod(2, $request));
+ $this->assertEquals(8, $strategy->getBackoffPeriod(3, $request));
+ $this->assertEquals(16, $strategy->getBackoffPeriod(4, $request));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/HttpBackoffStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/HttpBackoffStrategyTest.php
new file mode 100644
index 0000000..ae68a4e
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/HttpBackoffStrategyTest.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
+use Guzzle\Http\Message\Response;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\HttpBackoffStrategy
+ * @covers Guzzle\Plugin\Backoff\AbstractErrorCodeBackoffStrategy
+ */
+class HttpBackoffStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testRetriesWhenCodeMatches()
+ {
+ $this->assertNotEmpty(HttpBackoffStrategy::getDefaultFailureCodes());
+ $strategy = new HttpBackoffStrategy();
+ $this->assertTrue($strategy->makesDecision());
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+
+ $response = new Response(200);
+ $this->assertEquals(false, $strategy->getBackoffPeriod(0, $request, $response));
+ $response->setStatus(400);
+ $this->assertEquals(false, $strategy->getBackoffPeriod(0, $request, $response));
+
+ foreach (HttpBackoffStrategy::getDefaultFailureCodes() as $code) {
+ $this->assertEquals(0, $strategy->getBackoffPeriod(0, $request, $response->setStatus($code)));
+ }
+ }
+
+ public function testAllowsCustomCodes()
+ {
+ $strategy = new HttpBackoffStrategy(array(204));
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $response = new Response(204);
+ $this->assertEquals(0, $strategy->getBackoffPeriod(0, $request, $response));
+ $response->setStatus(500);
+ $this->assertEquals(false, $strategy->getBackoffPeriod(0, $request, $response));
+ }
+
+ public function testIgnoresNonErrors()
+ {
+ $strategy = new HttpBackoffStrategy();
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $this->assertEquals(false, $strategy->getBackoffPeriod(0, $request));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/LinearBackoffStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/LinearBackoffStrategyTest.php
new file mode 100644
index 0000000..b4ce8e4
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/LinearBackoffStrategyTest.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Plugin\Backoff\LinearBackoffStrategy;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\LinearBackoffStrategy
+ */
+class LinearBackoffStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testRetriesWithLinearDelay()
+ {
+ $strategy = new LinearBackoffStrategy(5);
+ $this->assertFalse($strategy->makesDecision());
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $this->assertEquals(0, $strategy->getBackoffPeriod(0, $request));
+ $this->assertEquals(5, $strategy->getBackoffPeriod(1, $request));
+ $this->assertEquals(10, $strategy->getBackoffPeriod(2, $request));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ReasonPhraseBackoffStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ReasonPhraseBackoffStrategyTest.php
new file mode 100644
index 0000000..dea5a68
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/ReasonPhraseBackoffStrategyTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Plugin\Backoff\ReasonPhraseBackoffStrategy;
+use Guzzle\Http\Message\Response;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\ReasonPhraseBackoffStrategy
+ * @covers Guzzle\Plugin\Backoff\AbstractErrorCodeBackoffStrategy
+ */
+class ReasonPhraseBackoffStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testRetriesWhenCodeMatches()
+ {
+ $this->assertEmpty(ReasonPhraseBackoffStrategy::getDefaultFailureCodes());
+ $strategy = new ReasonPhraseBackoffStrategy(array('Foo', 'Internal Server Error'));
+ $this->assertTrue($strategy->makesDecision());
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $response = new Response(200);
+ $this->assertEquals(false, $strategy->getBackoffPeriod(0, $request, $response));
+ $response->setStatus(200, 'Foo');
+ $this->assertEquals(0, $strategy->getBackoffPeriod(0, $request, $response));
+ }
+
+ public function testIgnoresNonErrors()
+ {
+ $strategy = new ReasonPhraseBackoffStrategy();
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $this->assertEquals(false, $strategy->getBackoffPeriod(0, $request));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/TruncatedBackoffStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/TruncatedBackoffStrategyTest.php
new file mode 100644
index 0000000..5590dfb
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Backoff/TruncatedBackoffStrategyTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Backoff;
+
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Backoff\TruncatedBackoffStrategy;
+use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
+use Guzzle\Plugin\Backoff\ConstantBackoffStrategy;
+
+/**
+ * @covers Guzzle\Plugin\Backoff\TruncatedBackoffStrategy
+ */
+class TruncatedBackoffStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testRetriesWhenLessThanMax()
+ {
+ $strategy = new TruncatedBackoffStrategy(2);
+ $this->assertTrue($strategy->makesDecision());
+ $request = $this->getMock('Guzzle\Http\Message\Request', array(), array(), '', false);
+ $this->assertFalse($strategy->getBackoffPeriod(0, $request));
+ $this->assertFalse($strategy->getBackoffPeriod(1, $request));
+ $this->assertFalse($strategy->getBackoffPeriod(2, $request));
+
+ $response = new Response(500);
+ $strategy->setNext(new HttpBackoffStrategy(null, new ConstantBackoffStrategy(10)));
+ $this->assertEquals(10, $strategy->getBackoffPeriod(0, $request, $response));
+ $this->assertEquals(10, $strategy->getBackoffPeriod(1, $request, $response));
+ $this->assertFalse($strategy->getBackoffPeriod(2, $request, $response));
+ }
+}
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 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cache;
+
+use Guzzle\Common\Event;
+use Guzzle\Common\Version;
+use Guzzle\Cache\DoctrineCacheAdapter;
+use Guzzle\Http\Client;
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Cache\CachePlugin;
+use Guzzle\Plugin\Cache\DefaultCacheStorage;
+use Guzzle\Plugin\Cache\CallbackCanCacheStrategy;
+use Doctrine\Common\Cache\ArrayCache;
+
+/**
+ * @group server
+ * @covers Guzzle\Plugin\Cache\CachePlugin
+ * @covers Guzzle\Plugin\Cache\DefaultRevalidation
+ */
+class CachePluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testAddsDefaultStorage()
+ {
+ $plugin = new CachePlugin();
+ $this->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();
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CallbackCanCacheStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CallbackCanCacheStrategyTest.php
new file mode 100644
index 0000000..f3d9baf
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/CallbackCanCacheStrategyTest.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cache;
+
+use Doctrine\Common\Cache\ArrayCache;
+use Guzzle\Cache\DoctrineCacheAdapter;
+use Guzzle\Common\Event;
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Cache\CachePlugin;
+use Guzzle\Plugin\Cache\CallbackCanCacheStrategy;
+
+/**
+ * @covers Guzzle\Plugin\Cache\CallbackCanCacheStrategy
+ */
+class CallbackCanCacheStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ /**
+ * @expectedException \Guzzle\Common\Exception\InvalidArgumentException
+ */
+ public function testConstructorEnsuresCallbackIsCallable()
+ {
+ $p = new CallbackCanCacheStrategy(new \stdClass());
+ }
+
+ public function testUsesCallback()
+ {
+ $c = new CallbackCanCacheStrategy(function ($request) { return true; });
+ $this->assertTrue($c->canCacheRequest(new Request('DELETE', 'http://www.foo.com')));
+ }
+
+ /**
+ * The following is a bit of an integration test to ensure that the CachePlugin honors a
+ * custom can cache strategy.
+ */
+ public function testIntegrationWithCachePlugin()
+ {
+ $c = new CallbackCanCacheStrategy(
+ function ($request) { return true; },
+ function ($response) { return true; }
+ );
+
+ // Make a request and response that have no business being cached
+ $request = new Request('DELETE', 'http://www.foo.com');
+ $response = Response::fromMessage(
+ "HTTP/1.1 200 OK\r\n"
+ . "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n"
+ . "Last-Modified: Wed, 09 Jan 2013 08:48:53 GMT\r\n"
+ . "Content-Length: 2\r\n"
+ . "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n\r\n"
+ . "hi"
+ );
+
+ $this->assertTrue($c->canCacheRequest($request));
+ $this->assertTrue($c->canCacheResponse($response));
+
+ $s = $this->getMockBuilder('Guzzle\Plugin\Cache\DefaultCacheStorage')
+ ->setConstructorArgs(array(new DoctrineCacheAdapter(new ArrayCache())))
+ ->setMethods(array('fetch'))
+ ->getMockForAbstractClass();
+
+ $s->expects($this->once())
+ ->method('fetch')
+ ->will($this->returnValue($response));
+
+ $plugin = new CachePlugin(array('can_cache' => $c, 'storage' => $s));
+ $plugin->onRequestBeforeSend(new Event(array('request' => $request)));
+
+ $this->assertEquals(200, $request->getResponse()->getStatusCode());
+ $this->assertEquals('hi', $request->getResponse()->getBody(true));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultCacheStorageTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultCacheStorageTest.php
new file mode 100644
index 0000000..701a015
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultCacheStorageTest.php
@@ -0,0 +1,193 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cache;
+
+use Guzzle\Cache\DoctrineCacheAdapter;
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\RequestFactory;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Cache\DefaultCacheStorage;
+use Doctrine\Common\Cache\ArrayCache;
+
+/**
+ * @covers Guzzle\Plugin\Cache\DefaultCacheStorage
+ */
+class DefaultCacheStorageTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ protected function getCache()
+ {
+ $a = new ArrayCache();
+ $c = new DoctrineCacheAdapter($a);
+ $s = new DefaultCacheStorage($c);
+ $request = new Request('GET', 'http://foo.com', array('Accept' => 'application/json'));
+ $response = new Response(200, array(
+ 'Content-Type' => 'application/json',
+ 'Connection' => 'close',
+ 'X-Foo' => 'Bar',
+ 'Vary' => 'Accept'
+ ), 'test');
+ $s->cache($request, $response);
+ $data = $this->readAttribute($a, 'data');
+
+ return array(
+ 'cache' => $a,
+ 'adapter' => $c,
+ 'storage' => $s,
+ 'request' => $request,
+ 'response' => $response,
+ 'serialized' => end($data)
+ );
+ }
+
+ public function testReturnsNullForCacheMiss()
+ {
+ $cache = $this->getCache();
+ $this->assertNull($cache['storage']->fetch(new Request('GET', 'http://test.com')));
+ }
+
+ public function testCachesRequests()
+ {
+ $cache = $this->getCache();
+ $foundRequest = $foundBody = $bodyKey = false;
+ foreach ($this->readAttribute($cache['cache'], 'data') as $key => $v) {
+ if (strpos($v, 'foo.com')) {
+ $foundRequest = true;
+ $data = unserialize($v);
+ $bodyKey = $data[0][3];
+ $this->assertInternalType('integer', $data[0][4]);
+ $this->assertFalse(isset($data[0][0]['connection']));
+ $this->assertEquals('foo.com', $data[0][0]['host']);
+ } elseif ($v == 'test') {
+ $foundBody = $key;
+ }
+ }
+ $this->assertContains($bodyKey, $foundBody);
+ $this->assertTrue($foundRequest);
+ }
+
+ public function testFetchesResponse()
+ {
+ $cache = $this->getCache();
+ $response = $cache['storage']->fetch($cache['request']);
+ $this->assertEquals(200, $response->getStatusCode());
+ $this->assertFalse($response->hasHeader('Connection'));
+ $this->assertEquals('Bar', (string) $response->getHeader('X-Foo'));
+ $this->assertEquals('test', (string) $response->getBody());
+ $this->assertTrue(in_array($cache['serialized'], $this->readAttribute($cache['cache'], 'data')));
+ }
+
+ public function testDeletesRequestItemsAndBody()
+ {
+ $cache = $this->getCache();
+ $cache['storage']->delete($cache['request']);
+ $this->assertFalse(in_array('test', $this->readAttribute($cache['cache'], 'data')));
+ $this->assertFalse(in_array($cache['serialized'], $this->readAttribute($cache['cache'], 'data')));
+ }
+
+ public function testCachesMultipleRequestsWithVary()
+ {
+ $cache = $this->getCache();
+ $cache['request']->setHeader('Accept', 'application/xml');
+ $response = $cache['response']->setHeader('Content-Type', 'application/xml');
+ $response->setBody('123');
+ $cache['storage']->cache($cache['request'], $response);
+ $data = $this->readAttribute($cache['cache'], 'data');
+ foreach ($data as $v) {
+ if (strpos($v, 'foo.com')) {
+ $u = unserialize($v);
+ $this->assertEquals(2, count($u));
+ $this->assertEquals($u[0][0]['accept'], 'application/xml');
+ $this->assertEquals($u[0][1]['content-type'], 'application/xml');
+ $this->assertEquals($u[1][0]['accept'], 'application/json');
+ $this->assertEquals($u[1][1]['content-type'], 'application/json');
+ $this->assertNotSame($u[0][3], $u[1][3]);
+ break;
+ }
+ }
+ }
+
+ public function testPurgeRemovesAllMethodCaches()
+ {
+ $cache = $this->getCache();
+ foreach (array('HEAD', 'POST', 'PUT', 'DELETE') as $method) {
+ $request = RequestFactory::getInstance()->cloneRequestWithMethod($cache['request'], $method);
+ $cache['storage']->cache($request, $cache['response']);
+ }
+ $cache['storage']->purge('http://foo.com');
+ $this->assertFalse(in_array('test', $this->readAttribute($cache['cache'], 'data')));
+ $this->assertFalse(in_array($cache['serialized'], $this->readAttribute($cache['cache'], 'data')));
+ $this->assertEquals(
+ array('DoctrineNamespaceCacheKey[]'),
+ array_keys($this->readAttribute($cache['cache'], 'data'))
+ );
+ }
+
+ public function testRemovesExpiredResponses()
+ {
+ $cache = $this->getCache();
+ $request = new Request('GET', 'http://xyz.com');
+ $response = new Response(200, array('Age' => 1000, 'Cache-Control' => 'max-age=-10000'));
+ $cache['storage']->cache($request, $response);
+ $this->assertNull($cache['storage']->fetch($request));
+ $data = $this->readAttribute($cache['cache'], 'data');
+ $this->assertFalse(in_array('xyz.com', $data));
+ $this->assertTrue(in_array($cache['serialized'], $data));
+ }
+
+ public function testUsesVaryToDetermineResult()
+ {
+ $cache = $this->getCache();
+ $this->assertInstanceOf('Guzzle\Http\Message\Response', $cache['storage']->fetch($cache['request']));
+ $request = new Request('GET', 'http://foo.com', array('Accept' => 'application/xml'));
+ $this->assertNull($cache['storage']->fetch($request));
+ }
+
+ public function testEnsuresResponseIsStillPresent()
+ {
+ $cache = $this->getCache();
+ $data = $this->readAttribute($cache['cache'], 'data');
+ $key = array_search('test', $data);
+ $cache['cache']->delete(substr($key, 1, -4));
+ $this->assertNull($cache['storage']->fetch($cache['request']));
+ }
+
+ public function staleProvider()
+ {
+ return array(
+ array(
+ new Request('GET', 'http://foo.com', array('Accept' => 'foo')),
+ new Response(200, array('Cache-Control' => 'stale-if-error=100', 'Vary' => 'Accept'))
+ ),
+ array(
+ new Request('GET', 'http://foo.com', array('Accept' => 'foo')),
+ new Response(200, array('Cache-Control' => 'stale-if-error', 'Vary' => 'Accept'))
+ )
+ );
+ }
+
+ /**
+ * @dataProvider staleProvider
+ */
+ public function testUsesStaleTimeDirectiveForTtd($request, $response)
+ {
+ $cache = $this->getCache();
+ $cache['storage']->cache($request, $response);
+ $data = $this->readAttribute($cache['cache'], 'data');
+ foreach ($data as $v) {
+ if (strpos($v, 'foo.com')) {
+ $u = unserialize($v);
+ $this->assertGreaterThan($u[1][4], $u[0][4]);
+ break;
+ }
+ }
+ }
+
+ public function testCanFilterCacheKeys()
+ {
+ $cache = $this->getCache();
+ $cache['request']->getQuery()->set('auth', 'foo');
+ $this->assertNull($cache['storage']->fetch($cache['request']));
+ $cache['request']->getParams()->set('cache.key_filter', 'auth');
+ $this->assertNotNull($cache['storage']->fetch($cache['request']));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultCanCacheStrategyTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultCanCacheStrategyTest.php
new file mode 100644
index 0000000..de4d182
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultCanCacheStrategyTest.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cache;
+
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Cache\DefaultCanCacheStrategy;
+
+/**
+ * @covers Guzzle\Plugin\Cache\DefaultCanCacheStrategy
+ */
+class DefaultCanCacheStrategyTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testReturnsRequestcanCacheRequest()
+ {
+ $strategy = new DefaultCanCacheStrategy();
+ $request = new Request('GET', 'http://foo.com');
+ $this->assertTrue($strategy->canCacheRequest($request));
+ }
+
+ public function testDoesNotCacheNoStore()
+ {
+ $strategy = new DefaultCanCacheStrategy();
+ $request = new Request('GET', 'http://foo.com', array('cache-control' => 'no-store'));
+ $this->assertFalse($strategy->canCacheRequest($request));
+ }
+
+ public function testCanCacheResponse()
+ {
+ $response = $this->getMockBuilder('Guzzle\Http\Message\Response')
+ ->setMethods(array('canCache'))
+ ->setConstructorArgs(array(200))
+ ->getMock();
+ $response->expects($this->once())
+ ->method('canCache')
+ ->will($this->returnValue(true));
+ $strategy = new DefaultCanCacheStrategy();
+ $this->assertTrue($strategy->canCacheResponse($response));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultRevalidationTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultRevalidationTest.php
new file mode 100644
index 0000000..0699cb2
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultRevalidationTest.php
@@ -0,0 +1,248 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cache;
+
+use Guzzle\Http\Client;
+use Guzzle\Http\ClientInterface;
+use Guzzle\Http\Exception\BadResponseException;
+use Guzzle\Http\Exception\CurlException;
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\Response;
+use Guzzle\Http\Message\RequestFactory;
+use Guzzle\Plugin\Cache\CachePlugin;
+use Guzzle\Cache\DoctrineCacheAdapter;
+use Doctrine\Common\Cache\ArrayCache;
+use Guzzle\Plugin\Cache\DefaultCacheStorage;
+use Guzzle\Plugin\Mock\MockPlugin;
+use Guzzle\Tests\Http\Server;
+
+/**
+ * @covers Guzzle\Plugin\Cache\DefaultRevalidation
+ * @group server
+ */
+class DefaultRevalidationTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ protected function getHttpDate($time)
+ {
+ return gmdate(ClientInterface::HTTP_DATE, strtotime($time));
+ }
+
+ /**
+ * Data provider to test cache revalidation
+ *
+ * @return array
+ */
+ public function cacheRevalidationDataProvider()
+ {
+ return array(
+ // Forces revalidation that passes
+ array(
+ true,
+ "Pragma: no-cache\r\n\r\n",
+ "HTTP/1.1 200 OK\r\nDate: " . $this->getHttpDate('-100 hours') . "\r\nContent-Length: 4\r\n\r\nData",
+ "HTTP/1.1 304 NOT MODIFIED\r\nCache-Control: max-age=2000000\r\nContent-Length: 0\r\n\r\n",
+ ),
+ // Forces revalidation that overwrites what is in cache
+ array(
+ false,
+ "\r\n",
+ "HTTP/1.1 200 OK\r\nCache-Control: must-revalidate, no-cache\r\nDate: " . $this->getHttpDate('-10 hours') . "\r\nContent-Length: 4\r\n\r\nData",
+ "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nDatas",
+ "HTTP/1.1 200 OK\r\nContent-Length: 5\r\nDate: " . $this->getHttpDate('now') . "\r\n\r\nDatas"
+ ),
+ // Throws an exception during revalidation
+ array(
+ false,
+ "\r\n",
+ "HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nDate: " . $this->getHttpDate('-3 hours') . "\r\n\r\nData",
+ "HTTP/1.1 500 INTERNAL SERVER ERROR\r\nContent-Length: 0\r\n\r\n"
+ ),
+ // ETag mismatch
+ array(
+ false,
+ "\r\n",
+ "HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nETag: \"123\"\r\nDate: " . $this->getHttpDate('-10 hours') . "\r\n\r\nData",
+ "HTTP/1.1 304 NOT MODIFIED\r\nETag: \"123456\"\r\n\r\n",
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider cacheRevalidationDataProvider
+ */
+ public function testRevalidatesResponsesAgainstOriginServer($can, $request, $response, $validate = null, $result = null)
+ {
+ // Send some responses to the test server for cache validation
+ $server = $this->getServer();
+ $server->flush();
+
+ if ($validate) {
+ $server->enqueue($validate);
+ }
+
+ $request = RequestFactory::getInstance()->fromMessage("GET / HTTP/1.1\r\nHost: 127.0.0.1:" . $server->getPort() . "\r\n" . $request);
+ $response = Response::fromMessage($response);
+ $request->setClient(new Client());
+
+ $plugin = new CachePlugin(new DoctrineCacheAdapter(new ArrayCache()));
+ $this->assertEquals(
+ $can,
+ $plugin->canResponseSatisfyRequest($request, $response),
+ '-> ' . $request . "\n" . $response
+ );
+
+ if ($result) {
+ $result = Response::fromMessage($result);
+ $result->removeHeader('Date');
+ $request->getResponse()->removeHeader('Date');
+ $request->getResponse()->removeHeader('Connection');
+ // Get rid of dates
+ $this->assertEquals((string) $result, (string) $request->getResponse());
+ }
+
+ if ($validate) {
+ $this->assertEquals(1, count($server->getReceivedRequests()));
+ }
+ }
+
+ public function testHandles404RevalidationResponses()
+ {
+ $request = new Request('GET', 'http://foo.com');
+ $request->setClient(new Client());
+ $badResponse = new Response(404, array(), 'Oh no!');
+ $badRequest = clone $request;
+ $badRequest->setResponse($badResponse, true);
+ $response = new Response(200, array(), 'foo');
+
+ // Seed the cache
+ $s = new DefaultCacheStorage(new DoctrineCacheAdapter(new ArrayCache()));
+ $s->cache($request, $response);
+ $this->assertNotNull($s->fetch($request));
+
+ $rev = $this->getMockBuilder('Guzzle\Plugin\Cache\DefaultRevalidation')
+ ->setConstructorArgs(array($s))
+ ->setMethods(array('createRevalidationRequest'))
+ ->getMock();
+
+ $rev->expects($this->once())
+ ->method('createRevalidationRequest')
+ ->will($this->returnValue($badRequest));
+
+ try {
+ $rev->revalidate($request, $response);
+ $this->fail('Should have thrown an exception');
+ } catch (BadResponseException $e) {
+ $this->assertSame($badResponse, $e->getResponse());
+ $this->assertNull($s->fetch($request));
+ }
+ }
+
+ public function testCanRevalidateWithPlugin()
+ {
+ $this->getServer()->flush();
+ $this->getServer()->enqueue(array(
+ "HTTP/1.1 200 OK\r\n" .
+ "Date: Mon, 12 Nov 2012 03:06:37 GMT\r\n" .
+ "Cache-Control: private, s-maxage=0, max-age=0, must-revalidate\r\n" .
+ "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
+ "Content-Length: 2\r\n\r\nhi",
+ "HTTP/1.0 304 Not Modified\r\n" .
+ "Date: Mon, 12 Nov 2012 03:06:38 GMT\r\n" .
+ "Content-Type: text/html; charset=UTF-8\r\n" .
+ "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
+ "Age: 6302\r\n\r\n",
+ "HTTP/1.0 304 Not Modified\r\n" .
+ "Date: Mon, 12 Nov 2012 03:06:38 GMT\r\n" .
+ "Content-Type: text/html; charset=UTF-8\r\n" .
+ "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
+ "Age: 6302\r\n\r\n",
+ ));
+ $client = new Client($this->getServer()->getUrl());
+ $client->addSubscriber(new CachePlugin());
+ $this->assertEquals(200, $client->get()->send()->getStatusCode());
+ $this->assertEquals(200, $client->get()->send()->getStatusCode());
+ $this->assertEquals(200, $client->get()->send()->getStatusCode());
+ $this->assertEquals(3, count($this->getServer()->getReceivedRequests()));
+ }
+
+ public function testCanHandleRevalidationFailures()
+ {
+ $client = new Client($this->getServer()->getUrl());
+ $lm = gmdate('c', time() - 60);
+ $mock = new MockPlugin(array(
+ new Response(200, array(
+ 'Date' => $lm,
+ 'Cache-Control' => 'max-age=100, must-revalidate, stale-if-error=9999',
+ 'Last-Modified' => $lm,
+ 'Content-Length' => 2
+ ), 'hi'),
+ new CurlException('Bleh'),
+ new CurlException('Bleh')
+ ));
+ $client->addSubscriber(new CachePlugin());
+ $client->addSubscriber($mock);
+ $client->get()->send();
+ $response = $client->get()->send();
+ $this->assertEquals(200, $response->getStatusCode());
+ $this->assertEquals('hi', $response->getBody(true));
+ $this->assertEquals(3, count($mock->getReceivedRequests()));
+ $this->assertEquals(0, count($mock->getQueue()));
+ }
+
+ public function testCanHandleStaleIfErrorWhenRevalidating()
+ {
+ $lm = gmdate('c', time() - 60);
+ $mock = new MockPlugin(array(
+ new Response(200, array(
+ 'Date' => $lm,
+ 'Cache-Control' => 'must-revalidate, max-age=0, stale-if-error=1200',
+ 'Last-Modified' => $lm,
+ 'Content-Length' => 2
+ ), 'hi'),
+ new CurlException('Oh no!'),
+ new CurlException('Oh no!')
+ ));
+ $cache = new CachePlugin();
+ $client = new Client('http://www.example.com');
+ $client->addSubscriber($cache);
+ $client->addSubscriber($mock);
+ $this->assertEquals(200, $client->get()->send()->getStatusCode());
+ $response = $client->get()->send();
+ $this->assertEquals(200, $response->getStatusCode());
+ $this->assertCount(0, $mock);
+ $this->assertEquals('HIT from GuzzleCache', (string) $response->getHeader('X-Cache-Lookup'));
+ $this->assertEquals('HIT_ERROR from GuzzleCache', (string) $response->getHeader('X-Cache'));
+ }
+
+ /**
+ * @group issue-437
+ */
+ public function testDoesNotTouchClosureListeners()
+ {
+ $this->getServer()->flush();
+ $this->getServer()->enqueue(array(
+ "HTTP/1.1 200 OK\r\n" .
+ "Date: Mon, 12 Nov 2012 03:06:37 GMT\r\n" .
+ "Cache-Control: private, s-maxage=0, max-age=0, must-revalidate\r\n" .
+ "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
+ "Content-Length: 2\r\n\r\nhi",
+ "HTTP/1.0 304 Not Modified\r\n" .
+ "Date: Mon, 12 Nov 2012 03:06:38 GMT\r\n" .
+ "Content-Type: text/html; charset=UTF-8\r\n" .
+ "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
+ "Age: 6302\r\n\r\n",
+ "HTTP/1.0 304 Not Modified\r\n" .
+ "Date: Mon, 12 Nov 2012 03:06:38 GMT\r\n" .
+ "Content-Type: text/html; charset=UTF-8\r\n" .
+ "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
+ "Age: 6302\r\n\r\n",
+ ));
+ $client = new Client($this->getServer()->getUrl());
+ $client->addSubscriber(new CachePlugin());
+ $client->getEventDispatcher()->addListener('command.after_send', function(){});
+ $this->assertEquals(200, $client->get()->send()->getStatusCode());
+ $this->assertEquals(200, $client->get()->send()->getStatusCode());
+ $this->assertEquals(200, $client->get()->send()->getStatusCode());
+ }
+
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DenyRevalidationTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DenyRevalidationTest.php
new file mode 100644
index 0000000..9af80f2
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DenyRevalidationTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cache;
+
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Cache\DenyRevalidation;
+
+/**
+ * @covers Guzzle\Plugin\Cache\DenyRevalidation
+ */
+class DenyRevalidationTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testDeniesRequestRevalidation()
+ {
+ $deny = new DenyRevalidation();
+ $this->assertFalse($deny->revalidate(new Request('GET', 'http://foo.com'), new Response(200)));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/SkipRevalidationTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/SkipRevalidationTest.php
new file mode 100644
index 0000000..4bcc04b
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/SkipRevalidationTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cache;
+
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Cache\SkipRevalidation;
+
+/**
+ * @covers Guzzle\Plugin\Cache\SkipRevalidation
+ */
+class SkipRevalidationTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testSkipsRequestRevalidation()
+ {
+ $skip = new SkipRevalidation();
+ $this->assertTrue($skip->revalidate(new Request('GET', 'http://foo.com'), new Response(200)));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieJar/ArrayCookieJarTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieJar/ArrayCookieJarTest.php
new file mode 100644
index 0000000..5d0f668
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieJar/ArrayCookieJarTest.php
@@ -0,0 +1,385 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cookie\CookieJar;
+
+use Guzzle\Plugin\Cookie\Cookie;
+use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
+use Guzzle\Http\Message\Response;
+use Guzzle\Http\Message\Request;
+
+/**
+ * @covers Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar
+ */
+class ArrayCookieJarTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ /**
+ * @var ArrayCookieJar
+ */
+ private $jar;
+
+ public function setUp()
+ {
+ $this->jar = new ArrayCookieJar();
+ }
+
+ protected function getTestCookies()
+ {
+ return array(
+ new Cookie(array('name' => 'foo', 'value' => 'bar', 'domain' => 'foo.com', 'path' => '/', 'discard' => true)),
+ new Cookie(array('name' => 'test', 'value' => '123', 'domain' => 'baz.com', 'path' => '/foo', 'expires' => 2)),
+ new Cookie(array('name' => 'you', 'value' => '123', 'domain' => 'bar.com', 'path' => '/boo', 'expires' => time() + 1000))
+ );
+ }
+
+ /**
+ * Provides test data for cookie cookieJar retrieval
+ */
+ public function getCookiesDataProvider()
+ {
+ return array(
+ array(array('foo', 'baz', 'test', 'muppet', 'googoo'), '', '', '', false),
+ array(array('foo', 'baz', 'muppet', 'googoo'), '', '', '', true),
+ array(array('googoo'), 'www.example.com', '', '', false),
+ array(array('muppet', 'googoo'), 'test.y.example.com', '', '', false),
+ array(array('foo', 'baz'), 'example.com', '', '', false),
+ array(array('muppet'), 'x.y.example.com', '/acme/', '', false),
+ array(array('muppet'), 'x.y.example.com', '/acme/test/', '', false),
+ array(array('googoo'), 'x.y.example.com', '/test/acme/test/', '', false),
+ array(array('foo', 'baz'), 'example.com', '', '', false),
+ array(array('baz'), 'example.com', '', 'baz', false),
+ );
+ }
+
+ public function testStoresAndRetrievesCookies()
+ {
+ $cookies = $this->getTestCookies();
+ foreach ($cookies as $cookie) {
+ $this->assertTrue($this->jar->add($cookie));
+ }
+
+ $this->assertEquals(3, count($this->jar));
+ $this->assertEquals(3, count($this->jar->getIterator()));
+ $this->assertEquals($cookies, $this->jar->all(null, null, null, false, false));
+ }
+
+ public function testRemovesExpiredCookies()
+ {
+ $cookies = $this->getTestCookies();
+ foreach ($this->getTestCookies() as $cookie) {
+ $this->jar->add($cookie);
+ }
+ $this->jar->removeExpired();
+ $this->assertEquals(array($cookies[0], $cookies[2]), $this->jar->all());
+ }
+
+ public function testRemovesTemporaryCookies()
+ {
+ $cookies = $this->getTestCookies();
+ foreach ($this->getTestCookies() as $cookie) {
+ $this->jar->add($cookie);
+ }
+ $this->jar->removeTemporary();
+ $this->assertEquals(array($cookies[2]), $this->jar->all());
+ }
+
+ public function testIsSerializable()
+ {
+ $this->assertEquals('[]', $this->jar->serialize());
+ $this->jar->unserialize('[]');
+ $this->assertEquals(array(), $this->jar->all());
+
+ $cookies = $this->getTestCookies();
+ foreach ($this->getTestCookies() as $cookie) {
+ $this->jar->add($cookie);
+ }
+
+ // Remove discard and expired cookies
+ $serialized = $this->jar->serialize();
+ $data = json_decode($serialized, true);
+ $this->assertEquals(1, count($data));
+
+ $a = new ArrayCookieJar();
+ $a->unserialize($serialized);
+ $this->assertEquals(1, count($a));
+ }
+
+ public function testRemovesSelectively()
+ {
+ $cookies = $this->getTestCookies();
+ foreach ($this->getTestCookies() as $cookie) {
+ $this->jar->add($cookie);
+ }
+
+ // Remove foo.com cookies
+ $this->jar->remove('foo.com');
+ $this->assertEquals(2, count($this->jar));
+ // Try again, removing no further cookies
+ $this->jar->remove('foo.com');
+ $this->assertEquals(2, count($this->jar));
+
+ // Remove bar.com cookies with path of /boo
+ $this->jar->remove('bar.com', '/boo');
+ $this->assertEquals(1, count($this->jar));
+
+ // Remove cookie by name
+ $this->jar->remove(null, null, 'test');
+ $this->assertEquals(0, count($this->jar));
+ }
+
+ public function testDoesNotAddIncompleteCookies()
+ {
+ $this->assertEquals(false, $this->jar->add(new Cookie()));
+ $this->assertFalse($this->jar->add(new Cookie(array(
+ 'name' => 'foo'
+ ))));
+ $this->assertFalse($this->jar->add(new Cookie(array(
+ 'name' => false
+ ))));
+ $this->assertFalse($this->jar->add(new Cookie(array(
+ 'name' => true
+ ))));
+ $this->assertFalse($this->jar->add(new Cookie(array(
+ 'name' => 'foo',
+ 'domain' => 'foo.com'
+ ))));
+ }
+
+ public function testDoesAddValidCookies()
+ {
+ $this->assertTrue($this->jar->add(new Cookie(array(
+ 'name' => 'foo',
+ 'domain' => 'foo.com',
+ 'value' => 0
+ ))));
+ $this->assertTrue($this->jar->add(new Cookie(array(
+ 'name' => 'foo',
+ 'domain' => 'foo.com',
+ 'value' => 0.0
+ ))));
+ $this->assertTrue($this->jar->add(new Cookie(array(
+ 'name' => 'foo',
+ 'domain' => 'foo.com',
+ 'value' => '0'
+ ))));
+ }
+
+ public function testOverwritesCookiesThatAreOlderOrDiscardable()
+ {
+ $t = time() + 1000;
+ $data = array(
+ 'name' => 'foo',
+ 'value' => 'bar',
+ 'domain' => '.example.com',
+ 'path' => '/',
+ 'max_age' => '86400',
+ 'port' => array(80, 8080),
+ 'version' => '1',
+ 'secure' => true,
+ 'discard' => true,
+ 'expires' => $t
+ );
+
+ // Make sure that the discard cookie is overridden with the non-discard
+ $this->assertTrue($this->jar->add(new Cookie($data)));
+
+ unset($data['discard']);
+ $this->assertTrue($this->jar->add(new Cookie($data)));
+ $this->assertEquals(1, count($this->jar));
+
+ $c = $this->jar->all();
+ $this->assertEquals(false, $c[0]->getDiscard());
+
+ // Make sure it doesn't duplicate the cookie
+ $this->jar->add(new Cookie($data));
+ $this->assertEquals(1, count($this->jar));
+
+ // Make sure the more future-ful expiration date supersede the other
+ $data['expires'] = time() + 2000;
+ $this->assertTrue($this->jar->add(new Cookie($data)));
+ $this->assertEquals(1, count($this->jar));
+ $c = $this->jar->all();
+ $this->assertNotEquals($t, $c[0]->getExpires());
+ }
+
+ public function testOverwritesCookiesThatHaveChanged()
+ {
+ $t = time() + 1000;
+ $data = array(
+ 'name' => 'foo',
+ 'value' => 'bar',
+ 'domain' => '.example.com',
+ 'path' => '/',
+ 'max_age' => '86400',
+ 'port' => array(80, 8080),
+ 'version' => '1',
+ 'secure' => true,
+ 'discard' => true,
+ 'expires' => $t
+ );
+
+ // Make sure that the discard cookie is overridden with the non-discard
+ $this->assertTrue($this->jar->add(new Cookie($data)));
+
+ $data['value'] = 'boo';
+ $this->assertTrue($this->jar->add(new Cookie($data)));
+ $this->assertEquals(1, count($this->jar));
+
+ // Changing the value plus a parameter also must overwrite the existing one
+ $data['value'] = 'zoo';
+ $data['secure'] = false;
+ $this->assertTrue($this->jar->add(new Cookie($data)));
+ $this->assertEquals(1, count($this->jar));
+
+ $c = $this->jar->all();
+ $this->assertEquals('zoo', $c[0]->getValue());
+ }
+
+ public function testAddsCookiesFromResponseWithNoRequest()
+ {
+ $response = new Response(200, array(
+ 'Set-Cookie' => array(
+ "fpc=d=.Hm.yh4.1XmJWjJfs4orLQzKzPImxklQoxXSHOZATHUSEFciRueW_7704iYUtsXNEXq0M92Px2glMdWypmJ7HIQl6XIUvrZimWjQ3vIdeuRbI.FNQMAfcxu_XN1zSx7l.AcPdKL6guHc2V7hIQFhnjRW0rxm2oHY1P4bGQxFNz7f.tHm12ZD3DbdMDiDy7TBXsuP4DM-&v=2; expires=Fri, 02-Mar-2019 02:17:40 GMT; path=/; domain=127.0.0.1",
+ "FPCK3=AgBNbvoQAGpGEABZLRAAbFsQAF1tEABkDhAAeO0=; expires=Sat, 02-Apr-2019 02:17:40 GMT; path=/; domain=127.0.0.1",
+ "CH=deleted; expires=Wed, 03-Mar-2010 02:17:39 GMT; path=/; domain=127.0.0.1",
+ "CH=AgBNbvoQAAEcEAApuhAAMJcQADQvEAAvGxAALe0QAD6uEAATwhAAC1AQAC8t; expires=Sat, 02-Apr-2019 02:17:40 GMT; path=/; domain=127.0.0.1"
+ )
+ ));
+
+ $this->jar->addCookiesFromResponse($response);
+ $this->assertEquals(3, count($this->jar));
+ $this->assertEquals(1, count($this->jar->all(null, null, 'fpc')));
+ $this->assertEquals(1, count($this->jar->all(null, null, 'FPCK3')));
+ $this->assertEquals(1, count($this->jar->all(null, null, 'CH')));
+ }
+
+ public function testAddsCookiesFromResponseWithRequest()
+ {
+ $response = new Response(200, array(
+ 'Set-Cookie' => "fpc=d=.Hm.yh4.1XmJWjJfs4orLQzKzPImxklQoxXSHOZATHUSEFciRueW_7704iYUtsXNEXq0M92Px2glMdWypmJ7HIQl6XIUvrZimWjQ3vIdeuRbI.FNQMAfcxu_XN1zSx7l.AcPdKL6guHc2V7hIQFhnjRW0rxm2oHY1P4bGQxFNz7f.tHm12ZD3DbdMDiDy7TBXsuP4DM-&v=2; expires=Fri, 02-Mar-2019 02:17:40 GMT;"
+ ));
+ $request = new Request('GET', 'http://www.example.com');
+ $this->jar->addCookiesFromResponse($response, $request);
+ $this->assertEquals(1, count($this->jar));
+ }
+
+ public function getMatchingCookiesDataProvider()
+ {
+ return array(
+ array('https://example.com', array(0)),
+ array('http://example.com', array()),
+ array('https://example.com:8912', array()),
+ array('https://foo.example.com', array(0)),
+ array('http://foo.example.com/test/acme/', array(4))
+ );
+ }
+
+ /**
+ * @dataProvider getMatchingCookiesDataProvider
+ */
+ public function testReturnsCookiesMatchingRequests($url, $cookies)
+ {
+ $bag = array(
+ new Cookie(array(
+ 'name' => 'foo',
+ 'value' => 'bar',
+ 'domain' => 'example.com',
+ 'path' => '/',
+ 'max_age' => '86400',
+ 'port' => array(443, 8080),
+ 'version' => '1',
+ 'secure' => true
+ )),
+ new Cookie(array(
+ 'name' => 'baz',
+ 'value' => 'foobar',
+ 'domain' => 'example.com',
+ 'path' => '/',
+ 'max_age' => '86400',
+ 'port' => array(80, 8080),
+ 'version' => '1',
+ 'secure' => true
+ )),
+ new Cookie(array(
+ 'name' => 'test',
+ 'value' => '123',
+ 'domain' => 'www.foobar.com',
+ 'path' => '/path/',
+ 'discard' => true
+ )),
+ new Cookie(array(
+ 'name' => 'muppet',
+ 'value' => 'cookie_monster',
+ 'domain' => '.y.example.com',
+ 'path' => '/acme/',
+ 'comment' => 'Comment goes here...',
+ 'expires' => time() + 86400
+ )),
+ new Cookie(array(
+ 'name' => 'googoo',
+ 'value' => 'gaga',
+ 'domain' => '.example.com',
+ 'path' => '/test/acme/',
+ 'max_age' => 1500,
+ 'version' => 2
+ ))
+ );
+
+ foreach ($bag as $cookie) {
+ $this->jar->add($cookie);
+ }
+
+ $request = new Request('GET', $url);
+ $results = $this->jar->getMatchingCookies($request);
+ $this->assertEquals(count($cookies), count($results));
+ foreach ($cookies as $i) {
+ $this->assertContains($bag[$i], $results);
+ }
+ }
+
+ /**
+ * @expectedException \Guzzle\Plugin\Cookie\Exception\InvalidCookieException
+ * @expectedExceptionMessage The cookie name must not contain invalid characters: abc:@123
+ */
+ public function testThrowsExceptionWithStrictMode()
+ {
+ $a = new ArrayCookieJar();
+ $a->setStrictMode(true);
+ $a->add(new Cookie(array(
+ 'name' => 'abc:@123',
+ 'value' => 'foo',
+ 'domain' => 'bar'
+ )));
+ }
+
+ public function testRemoveExistingCookieIfEmpty()
+ {
+ // Add a cookie that should not be affected
+ $a = new Cookie(array(
+ 'name' => 'foo',
+ 'value' => 'nope',
+ 'domain' => 'foo.com',
+ 'path' => '/abc'
+ ));
+ $this->jar->add($a);
+
+ $data = array(
+ 'name' => 'foo',
+ 'value' => 'bar',
+ 'domain' => 'foo.com',
+ 'path' => '/'
+ );
+
+ $b = new Cookie($data);
+ $this->assertTrue($this->jar->add($b));
+ $this->assertEquals(2, count($this->jar));
+
+ // Try to re-set the same cookie with no value: assert that cookie is not added
+ $data['value'] = null;
+ $this->assertFalse($this->jar->add(new Cookie($data)));
+ // assert that original cookie has been deleted
+ $cookies = $this->jar->all('foo.com');
+ $this->assertTrue(in_array($a, $cookies, true));
+ $this->assertFalse(in_array($b, $cookies, true));
+ $this->assertEquals(1, count($this->jar));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieJar/FileCookieJarTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieJar/FileCookieJarTest.php
new file mode 100644
index 0000000..ac9471f
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieJar/FileCookieJarTest.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cookie\CookieJar;
+
+use Guzzle\Plugin\Cookie\Cookie;
+use Guzzle\Plugin\Cookie\CookieJar\FileCookieJar;
+
+/**
+ * @covers Guzzle\Plugin\Cookie\CookieJar\FileCookieJar
+ */
+class FileCookieJarTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ private $file;
+
+ public function setUp()
+ {
+ $this->file = tempnam('/tmp', 'file-cookies');
+ }
+
+ public function testLoadsFromFileFile()
+ {
+ $jar = new FileCookieJar($this->file);
+ $this->assertEquals(array(), $jar->all());
+ unlink($this->file);
+ }
+
+ public function testPersistsToFileFile()
+ {
+ $jar = new FileCookieJar($this->file);
+ $jar->add(new Cookie(array(
+ 'name' => 'foo',
+ 'value' => 'bar',
+ 'domain' => 'foo.com',
+ 'expires' => time() + 1000
+ )));
+ $jar->add(new Cookie(array(
+ 'name' => 'baz',
+ 'value' => 'bar',
+ 'domain' => 'foo.com',
+ 'expires' => time() + 1000
+ )));
+ $jar->add(new Cookie(array(
+ 'name' => 'boo',
+ 'value' => 'bar',
+ 'domain' => 'foo.com',
+ )));
+
+ $this->assertEquals(3, count($jar));
+ unset($jar);
+
+ // Make sure it wrote to the file
+ $contents = file_get_contents($this->file);
+ $this->assertNotEmpty($contents);
+
+ // Load the cookieJar from the file
+ $jar = new FileCookieJar($this->file);
+
+ // Weeds out temporary and session cookies
+ $this->assertEquals(2, count($jar));
+ unset($jar);
+ unlink($this->file);
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookiePluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookiePluginTest.php
new file mode 100644
index 0000000..f8c175c
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookiePluginTest.php
@@ -0,0 +1,134 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cookie;
+
+use Guzzle\Common\Event;
+use Guzzle\Plugin\Cookie\Cookie;
+use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
+use Guzzle\Http\Client;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Cookie\CookiePlugin;
+
+/**
+ * @group server
+ * @covers Guzzle\Plugin\Cookie\CookiePlugin
+ */
+class CookiePluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testExtractsAndStoresCookies()
+ {
+ $response = new Response(200);
+ $mock = $this->getMockBuilder('Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar')
+ ->setMethods(array('addCookiesFromResponse'))
+ ->getMock();
+
+ $mock->expects($this->exactly(1))
+ ->method('addCookiesFromResponse')
+ ->with($response);
+
+ $plugin = new CookiePlugin($mock);
+ $plugin->onRequestSent(new Event(array(
+ 'response' => $response
+ )));
+ }
+
+ public function testAddsCookiesToRequests()
+ {
+ $cookie = new Cookie(array(
+ 'name' => 'foo',
+ 'value' => 'bar'
+ ));
+
+ $mock = $this->getMockBuilder('Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar')
+ ->setMethods(array('getMatchingCookies'))
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('getMatchingCookies')
+ ->will($this->returnValue(array($cookie)));
+
+ $plugin = new CookiePlugin($mock);
+
+ $client = new Client();
+ $client->getEventDispatcher()->addSubscriber($plugin);
+
+ $request = $client->get('http://www.example.com');
+ $plugin->onRequestBeforeSend(new Event(array(
+ 'request' => $request
+ )));
+
+ $this->assertEquals('bar', $request->getCookie('foo'));
+ }
+
+ public function testCookiesAreExtractedFromRedirectResponses()
+ {
+ $plugin = new CookiePlugin(new ArrayCookieJar());
+ $this->getServer()->flush();
+ $this->getServer()->enqueue(array(
+ "HTTP/1.1 302 Moved Temporarily\r\n" .
+ "Set-Cookie: test=583551; expires=Wednesday, 23-Mar-2050 19:49:45 GMT; path=/\r\n" .
+ "Location: /redirect\r\n\r\n",
+ "HTTP/1.1 200 OK\r\n" .
+ "Content-Length: 0\r\n\r\n",
+ "HTTP/1.1 200 OK\r\n" .
+ "Content-Length: 0\r\n\r\n"
+ ));
+
+ $client = new Client($this->getServer()->getUrl());
+ $client->getEventDispatcher()->addSubscriber($plugin);
+
+ $client->get()->send();
+ $request = $client->get();
+ $request->send();
+ $this->assertEquals('test=583551', $request->getHeader('Cookie'));
+
+ $requests = $this->getServer()->getReceivedRequests(true);
+ // Confirm subsequent requests have the cookie.
+ $this->assertEquals('test=583551', $requests[2]->getHeader('Cookie'));
+ // Confirm the redirected request has the cookie.
+ $this->assertEquals('test=583551', $requests[1]->getHeader('Cookie'));
+ }
+
+ public function testCookiesAreNotAddedWhenParamIsSet()
+ {
+ $jar = new ArrayCookieJar();
+ $plugin = new CookiePlugin($jar);
+
+ $jar->add(new Cookie(array(
+ 'domain' => 'example.com',
+ 'path' => '/',
+ 'name' => 'test',
+ 'value' => 'hi',
+ 'expires' => time() + 3600
+ )));
+
+ $client = new Client('http://example.com');
+ $client->getEventDispatcher()->addSubscriber($plugin);
+
+ // Ensure that it is normally added
+ $request = $client->get();
+ $request->setResponse(new Response(200), true);
+ $request->send();
+ $this->assertEquals('hi', $request->getCookie('test'));
+
+ // Now ensure that it is not added
+ $request = $client->get();
+ $request->getParams()->set('cookies.disable', true);
+ $request->setResponse(new Response(200), true);
+ $request->send();
+ $this->assertNull($request->getCookie('test'));
+ }
+
+ public function testProvidesCookieJar()
+ {
+ $jar = new ArrayCookieJar();
+ $plugin = new CookiePlugin($jar);
+ $this->assertSame($jar, $plugin->getCookieJar());
+ }
+
+ public function testEscapesCookieDomains()
+ {
+ $cookie = new Cookie(array('domain' => '/foo/^$[A-Z]+/'));
+ $this->assertFalse($cookie->matchesDomain('foo'));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieTest.php
new file mode 100644
index 0000000..9fb0b43
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cookie/CookieTest.php
@@ -0,0 +1,223 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Cookie;
+
+use Guzzle\Plugin\Cookie\Cookie;
+
+/**
+ * @covers Guzzle\Plugin\Cookie\Cookie
+ */
+class CookieTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testInitializesDefaultValues()
+ {
+ $cookie = new Cookie();
+ $this->assertEquals('/', $cookie->getPath());
+ $this->assertEquals(array(), $cookie->getPorts());
+ }
+
+ public function testConvertsDateTimeMaxAgeToUnixTimestamp()
+ {
+ $cookie = new Cookie(array(
+ 'expires' => 'November 20, 1984'
+ ));
+ $this->assertTrue(is_numeric($cookie->getExpires()));
+ }
+
+ public function testAddsExpiresBasedOnMaxAge()
+ {
+ $t = time();
+ $cookie = new Cookie(array(
+ 'max_age' => 100
+ ));
+ $this->assertEquals($t + 100, $cookie->getExpires());
+ }
+
+ public function testHoldsValues()
+ {
+ $t = time();
+ $data = array(
+ 'name' => 'foo',
+ 'value' => 'baz',
+ 'path' => '/bar',
+ 'domain' => 'baz.com',
+ 'expires' => $t,
+ 'max_age' => 100,
+ 'comment' => 'Hi',
+ 'comment_url' => 'foo.com',
+ 'port' => array(1, 2),
+ 'version' => 2,
+ 'secure' => true,
+ 'discard' => true,
+ 'http_only' => true,
+ 'data' => array(
+ 'foo' => 'baz',
+ 'bar' => 'bam'
+ )
+ );
+
+ $cookie = new Cookie($data);
+ $this->assertEquals($data, $cookie->toArray());
+
+ $this->assertEquals('foo', $cookie->getName());
+ $this->assertEquals('baz', $cookie->getValue());
+ $this->assertEquals('baz.com', $cookie->getDomain());
+ $this->assertEquals('/bar', $cookie->getPath());
+ $this->assertEquals($t, $cookie->getExpires());
+ $this->assertEquals(100, $cookie->getMaxAge());
+ $this->assertEquals('Hi', $cookie->getComment());
+ $this->assertEquals('foo.com', $cookie->getCommentUrl());
+ $this->assertEquals(array(1, 2), $cookie->getPorts());
+ $this->assertEquals(2, $cookie->getVersion());
+ $this->assertTrue($cookie->getSecure());
+ $this->assertTrue($cookie->getDiscard());
+ $this->assertTrue($cookie->getHttpOnly());
+ $this->assertEquals('baz', $cookie->getAttribute('foo'));
+ $this->assertEquals('bam', $cookie->getAttribute('bar'));
+ $this->assertEquals(array(
+ 'foo' => 'baz',
+ 'bar' => 'bam'
+ ), $cookie->getAttributes());
+
+ $cookie->setName('a')
+ ->setValue('b')
+ ->setPath('c')
+ ->setDomain('bar.com')
+ ->setExpires(10)
+ ->setMaxAge(200)
+ ->setComment('e')
+ ->setCommentUrl('f')
+ ->setPorts(array(80))
+ ->setVersion(3)
+ ->setSecure(false)
+ ->setHttpOnly(false)
+ ->setDiscard(false)
+ ->setAttribute('snoop', 'dog');
+
+ $this->assertEquals('a', $cookie->getName());
+ $this->assertEquals('b', $cookie->getValue());
+ $this->assertEquals('c', $cookie->getPath());
+ $this->assertEquals('bar.com', $cookie->getDomain());
+ $this->assertEquals(10, $cookie->getExpires());
+ $this->assertEquals(200, $cookie->getMaxAge());
+ $this->assertEquals('e', $cookie->getComment());
+ $this->assertEquals('f', $cookie->getCommentUrl());
+ $this->assertEquals(array(80), $cookie->getPorts());
+ $this->assertEquals(3, $cookie->getVersion());
+ $this->assertFalse($cookie->getSecure());
+ $this->assertFalse($cookie->getDiscard());
+ $this->assertFalse($cookie->getHttpOnly());
+ $this->assertEquals('dog', $cookie->getAttribute('snoop'));
+ }
+
+ public function testDeterminesIfExpired()
+ {
+ $c = new Cookie();
+ $c->setExpires(10);
+ $this->assertTrue($c->isExpired());
+ $c->setExpires(time() + 10000);
+ $this->assertFalse($c->isExpired());
+ }
+
+ public function testMatchesPorts()
+ {
+ $cookie = new Cookie();
+ // Always matches when nothing is set
+ $this->assertTrue($cookie->matchesPort(2));
+
+ $cookie->setPorts(array(1, 2));
+ $this->assertTrue($cookie->matchesPort(2));
+ $this->assertFalse($cookie->matchesPort(100));
+ }
+
+ public function testMatchesDomain()
+ {
+ $cookie = new Cookie();
+ $this->assertTrue($cookie->matchesDomain('baz.com'));
+
+ $cookie->setDomain('baz.com');
+ $this->assertTrue($cookie->matchesDomain('baz.com'));
+ $this->assertFalse($cookie->matchesDomain('bar.com'));
+
+ $cookie->setDomain('.baz.com');
+ $this->assertTrue($cookie->matchesDomain('.baz.com'));
+ $this->assertTrue($cookie->matchesDomain('foo.baz.com'));
+ $this->assertFalse($cookie->matchesDomain('baz.bar.com'));
+ $this->assertTrue($cookie->matchesDomain('baz.com'));
+
+ $cookie->setDomain('.127.0.0.1');
+ $this->assertTrue($cookie->matchesDomain('127.0.0.1'));
+
+ $cookie->setDomain('127.0.0.1');
+ $this->assertTrue($cookie->matchesDomain('127.0.0.1'));
+
+ $cookie->setDomain('.com.');
+ $this->assertFalse($cookie->matchesDomain('baz.com'));
+
+ $cookie->setDomain('.local');
+ $this->assertTrue($cookie->matchesDomain('example.local'));
+ }
+
+ public function testMatchesPath()
+ {
+ $cookie = new Cookie();
+ $this->assertTrue($cookie->matchesPath('/foo'));
+
+ $cookie->setPath('/foo');
+
+ // o The cookie-path and the request-path are identical.
+ $this->assertTrue($cookie->matchesPath('/foo'));
+ $this->assertFalse($cookie->matchesPath('/bar'));
+
+ // o The cookie-path is a prefix of the request-path, and the first
+ // character of the request-path that is not included in the cookie-
+ // path is a %x2F ("/") character.
+ $this->assertTrue($cookie->matchesPath('/foo/bar'));
+ $this->assertFalse($cookie->matchesPath('/fooBar'));
+
+ // o The cookie-path is a prefix of the request-path, and the last
+ // character of the cookie-path is %x2F ("/").
+ $cookie->setPath('/foo/');
+ $this->assertTrue($cookie->matchesPath('/foo/bar'));
+ $this->assertFalse($cookie->matchesPath('/fooBaz'));
+ $this->assertFalse($cookie->matchesPath('/foo'));
+
+ }
+
+ public function cookieValidateProvider()
+ {
+ return array(
+ array('foo', 'baz', 'bar', true),
+ array('0', '0', '0', true),
+ array('', 'baz', 'bar', 'The cookie name must not be empty'),
+ array('foo', '', 'bar', 'The cookie value must not be empty'),
+ array('foo', 'baz', '', 'The cookie domain must not be empty'),
+ array('foo\\', 'baz', '0', 'The cookie name must not contain invalid characters: foo\\'),
+ );
+ }
+
+ /**
+ * @dataProvider cookieValidateProvider
+ */
+ public function testValidatesCookies($name, $value, $domain, $result)
+ {
+ $cookie = new Cookie(array(
+ 'name' => $name,
+ 'value' => $value,
+ 'domain' => $domain
+ ));
+ $this->assertSame($result, $cookie->validate());
+ }
+
+ public function testCreatesInvalidCharacterString()
+ {
+ $m = new \ReflectionMethod('Guzzle\Plugin\Cookie\Cookie', 'getInvalidCharacters');
+ $m->setAccessible(true);
+ $p = new \ReflectionProperty('Guzzle\Plugin\Cookie\Cookie', 'invalidCharString');
+ $p->setAccessible(true);
+ $p->setValue('');
+ // Expects a string containing 51 invalid characters
+ $this->assertEquals(51, strlen($m->invoke($m)));
+ $this->assertContains('@', $m->invoke($m));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/CurlAuth/CurlAuthPluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/CurlAuth/CurlAuthPluginTest.php
new file mode 100644
index 0000000..2a4b49e
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/CurlAuth/CurlAuthPluginTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\CurlAuth;
+
+use Guzzle\Common\Version;
+use Guzzle\Plugin\CurlAuth\CurlAuthPlugin;
+use Guzzle\Http\Client;
+
+/**
+ * @covers Guzzle\Plugin\CurlAuth\CurlAuthPlugin
+ */
+class CurlAuthPluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testAddsBasicAuthentication()
+ {
+ Version::$emitWarnings = false;
+ $plugin = new CurlAuthPlugin('michael', 'test');
+ $client = new Client('http://www.test.com/');
+ $client->getEventDispatcher()->addSubscriber($plugin);
+ $request = $client->get('/');
+ $this->assertEquals('michael', $request->getUsername());
+ $this->assertEquals('test', $request->getPassword());
+ Version::$emitWarnings = true;
+ }
+
+ public function testAddsDigestAuthentication()
+ {
+ Version::$emitWarnings = false;
+ $plugin = new CurlAuthPlugin('julian', 'test', CURLAUTH_DIGEST);
+ $client = new Client('http://www.test.com/');
+ $client->getEventDispatcher()->addSubscriber($plugin);
+ $request = $client->get('/');
+ $this->assertEquals('julian', $request->getUsername());
+ $this->assertEquals('test', $request->getPassword());
+ $this->assertEquals('julian:test', $request->getCurlOptions()->get(CURLOPT_USERPWD));
+ $this->assertEquals(CURLAUTH_DIGEST, $request->getCurlOptions()->get(CURLOPT_HTTPAUTH));
+ Version::$emitWarnings = true;
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/ErrorResponse/ErrorResponsePluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/ErrorResponse/ErrorResponsePluginTest.php
new file mode 100644
index 0000000..6f94186
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/ErrorResponse/ErrorResponsePluginTest.php
@@ -0,0 +1,137 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\ErrorResponse;
+
+use Guzzle\Service\Client;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\ErrorResponse\ErrorResponsePlugin;
+use Guzzle\Service\Description\ServiceDescription;
+use Guzzle\Tests\Mock\ErrorResponseMock;
+
+/**
+ * @covers \Guzzle\Plugin\ErrorResponse\ErrorResponsePlugin
+ */
+class ErrorResponsePluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ protected $client;
+
+ public static function tearDownAfterClass()
+ {
+ self::getServer()->flush();
+ }
+
+ public function setUp()
+ {
+ $mockError = 'Guzzle\Tests\Mock\ErrorResponseMock';
+ $description = ServiceDescription::factory(array(
+ 'operations' => array(
+ 'works' => array(
+ 'httpMethod' => 'GET',
+ 'errorResponses' => array(
+ array('code' => 500, 'class' => $mockError),
+ array('code' => 503, 'reason' => 'foo', 'class' => $mockError),
+ array('code' => 200, 'reason' => 'Error!', 'class' => $mockError)
+ )
+ ),
+ 'bad_class' => array(
+ 'httpMethod' => 'GET',
+ 'errorResponses' => array(
+ array('code' => 500, 'class' => 'Does\\Not\\Exist')
+ )
+ ),
+ 'does_not_implement' => array(
+ 'httpMethod' => 'GET',
+ 'errorResponses' => array(
+ array('code' => 500, 'class' => __CLASS__)
+ )
+ ),
+ 'no_errors' => array('httpMethod' => 'GET'),
+ 'no_class' => array(
+ 'httpMethod' => 'GET',
+ 'errorResponses' => array(
+ array('code' => 500)
+ )
+ ),
+ )
+ ));
+ $this->client = new Client($this->getServer()->getUrl());
+ $this->client->setDescription($description);
+ }
+
+ /**
+ * @expectedException \Guzzle\Http\Exception\ServerErrorResponseException
+ */
+ public function testSkipsWhenErrorResponsesIsNotSet()
+ {
+ $this->getServer()->enqueue("HTTP/1.1 500 Foo\r\nContent-Length: 0\r\n\r\n");
+ $this->client->addSubscriber(new ErrorResponsePlugin());
+ $this->client->getCommand('no_errors')->execute();
+ }
+
+ public function testSkipsWhenErrorResponsesIsNotSetAndAllowsSuccess()
+ {
+ $this->getServer()->enqueue("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
+ $this->client->addSubscriber(new ErrorResponsePlugin());
+ $this->client->getCommand('no_errors')->execute();
+ }
+
+ /**
+ * @expectedException \Guzzle\Plugin\ErrorResponse\Exception\ErrorResponseException
+ * @expectedExceptionMessage Does\Not\Exist does not exist
+ */
+ public function testEnsuresErrorResponseExists()
+ {
+ $this->getServer()->enqueue("HTTP/1.1 500 Foo\r\nContent-Length: 0\r\n\r\n");
+ $this->client->addSubscriber(new ErrorResponsePlugin());
+ $this->client->getCommand('bad_class')->execute();
+ }
+
+ /**
+ * @expectedException \Guzzle\Plugin\ErrorResponse\Exception\ErrorResponseException
+ * @expectedExceptionMessage must implement Guzzle\Plugin\ErrorResponse\ErrorResponseExceptionInterface
+ */
+ public function testEnsuresErrorResponseImplementsInterface()
+ {
+ $this->getServer()->enqueue("HTTP/1.1 500 Foo\r\nContent-Length: 0\r\n\r\n");
+ $this->client->addSubscriber(new ErrorResponsePlugin());
+ $this->client->getCommand('does_not_implement')->execute();
+ }
+
+ public function testThrowsSpecificErrorResponseOnMatch()
+ {
+ try {
+ $this->getServer()->enqueue("HTTP/1.1 500 Foo\r\nContent-Length: 0\r\n\r\n");
+ $this->client->addSubscriber(new ErrorResponsePlugin());
+ $command = $this->client->getCommand('works');
+ $command->execute();
+ $this->fail('Exception not thrown');
+ } catch (ErrorResponseMock $e) {
+ $this->assertSame($command, $e->command);
+ $this->assertEquals(500, $e->response->getStatusCode());
+ }
+ }
+
+ /**
+ * @expectedException \Guzzle\Tests\Mock\ErrorResponseMock
+ */
+ public function testThrowsWhenCodeAndPhraseMatch()
+ {
+ $this->getServer()->enqueue("HTTP/1.1 200 Error!\r\nContent-Length: 0\r\n\r\n");
+ $this->client->addSubscriber(new ErrorResponsePlugin());
+ $this->client->getCommand('works')->execute();
+ }
+
+ public function testSkipsWhenReasonDoesNotMatch()
+ {
+ $this->getServer()->enqueue("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
+ $this->client->addSubscriber(new ErrorResponsePlugin());
+ $this->client->getCommand('works')->execute();
+ }
+
+ public function testSkipsWhenNoClassIsSet()
+ {
+ $this->getServer()->enqueue("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
+ $this->client->addSubscriber(new ErrorResponsePlugin());
+ $this->client->getCommand('no_class')->execute();
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/History/HistoryPluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/History/HistoryPluginTest.php
new file mode 100644
index 0000000..41aa673
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/History/HistoryPluginTest.php
@@ -0,0 +1,140 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\History;
+
+use Guzzle\Http\Client;
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\History\HistoryPlugin;
+use Guzzle\Plugin\Mock\MockPlugin;
+
+/**
+ * @covers Guzzle\Plugin\History\HistoryPlugin
+ */
+class HistoryPluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ /**
+ * Adds multiple requests to a plugin
+ *
+ * @param HistoryPlugin $h Plugin
+ * @param int $num Number of requests to add
+ *
+ * @return array
+ */
+ protected function addRequests(HistoryPlugin $h, $num)
+ {
+ $requests = array();
+ $client = new Client('http://127.0.0.1/');
+ for ($i = 0; $i < $num; $i++) {
+ $requests[$i] = $client->get();
+ $requests[$i]->setResponse(new Response(200), true);
+ $requests[$i]->send();
+ $h->add($requests[$i]);
+ }
+
+ return $requests;
+ }
+
+ public function testDescribesSubscribedEvents()
+ {
+ $this->assertInternalType('array', HistoryPlugin::getSubscribedEvents());
+ }
+
+ public function testMaintainsLimitValue()
+ {
+ $h = new HistoryPlugin();
+ $this->assertSame($h, $h->setLimit(10));
+ $this->assertEquals(10, $h->getLimit());
+ }
+
+ public function testAddsRequests()
+ {
+ $h = new HistoryPlugin();
+ $requests = $this->addRequests($h, 1);
+ $this->assertEquals(1, count($h));
+ $i = $h->getIterator();
+ $this->assertEquals(1, count($i));
+ $this->assertEquals($requests[0], $i[0]);
+ }
+
+ /**
+ * @depends testAddsRequests
+ */
+ public function testMaintainsLimit()
+ {
+ $h = new HistoryPlugin();
+ $h->setLimit(2);
+ $requests = $this->addRequests($h, 3);
+ $this->assertEquals(2, count($h));
+ $i = 0;
+ foreach ($h as $request) {
+ if ($i > 0) {
+ $this->assertSame($requests[$i], $request);
+ }
+ }
+ }
+
+ public function testReturnsLastRequest()
+ {
+ $h = new HistoryPlugin();
+ $requests = $this->addRequests($h, 5);
+ $this->assertSame(end($requests), $h->getLastRequest());
+ }
+
+ public function testReturnsLastResponse()
+ {
+ $h = new HistoryPlugin();
+ $requests = $this->addRequests($h, 5);
+ $this->assertSame(end($requests)->getResponse(), $h->getLastResponse());
+ }
+
+ public function testClearsHistory()
+ {
+ $h = new HistoryPlugin();
+ $requests = $this->addRequests($h, 5);
+ $this->assertEquals(5, count($h));
+ $h->clear();
+ $this->assertEquals(0, count($h));
+ }
+
+ /**
+ * @depends testAddsRequests
+ */
+ public function testUpdatesAddRequests()
+ {
+ $h = new HistoryPlugin();
+ $client = new Client('http://127.0.0.1/');
+ $client->getEventDispatcher()->addSubscriber($h);
+
+ $request = $client->get();
+ $request->setResponse(new Response(200), true);
+ $request->send();
+
+ $this->assertSame($request, $h->getLastRequest());
+ }
+
+ public function testCanCastToString()
+ {
+ $client = new Client('http://127.0.0.1/');
+ $h = new HistoryPlugin();
+ $client->getEventDispatcher()->addSubscriber($h);
+
+ $mock = new MockPlugin(array(
+ new Response(301, array('Location' => '/redirect1', 'Content-Length' => 0)),
+ new Response(307, array('Location' => '/redirect2', 'Content-Length' => 0)),
+ new Response(200, array('Content-Length' => '2'), 'HI')
+ ));
+
+ $client->getEventDispatcher()->addSubscriber($mock);
+ $request = $client->get();
+ $request->send();
+ $this->assertEquals(3, count($h));
+ $this->assertEquals(3, count($mock->getReceivedRequests()));
+
+ $h = str_replace("\r", '', $h);
+ $this->assertContains("> GET / HTTP/1.1\nHost: 127.0.0.1\nUser-Agent:", $h);
+ $this->assertContains("< HTTP/1.1 301 Moved Permanently\nLocation: /redirect1", $h);
+ $this->assertContains("< HTTP/1.1 307 Temporary Redirect\nLocation: /redirect2", $h);
+ $this->assertContains("< HTTP/1.1 200 OK\nContent-Length: 2\n\nHI", $h);
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Log/LogPluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Log/LogPluginTest.php
new file mode 100644
index 0000000..ad663a5
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Log/LogPluginTest.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Log;
+
+use Guzzle\Log\ClosureLogAdapter;
+use Guzzle\Http\Client;
+use Guzzle\Http\EntityBody;
+use Guzzle\Http\Message\Request;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Log\LogPlugin;
+use Guzzle\Common\Event;
+
+/**
+ * @group server
+ * @covers Guzzle\Plugin\Log\LogPlugin
+ */
+class LogPluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ protected $adapter;
+
+ public function setUp()
+ {
+ $this->adapter = new ClosureLogAdapter(function ($message) {
+ echo $message;
+ });
+ }
+
+ public function testIgnoresCurlEventsWhenNotWiringBodies()
+ {
+ $p = new LogPlugin($this->adapter);
+ $this->assertNotEmpty($p->getSubscribedEvents());
+ $event = new Event(array('request' => new Request('GET', 'http://foo.com')));
+ $p->onCurlRead($event);
+ $p->onCurlWrite($event);
+ $p->onRequestBeforeSend($event);
+ }
+
+ public function testLogsWhenComplete()
+ {
+ $output = '';
+ $p = new LogPlugin(new ClosureLogAdapter(function ($message) use (&$output) {
+ $output = $message;
+ }), '{method} {resource} | {code} {res_body}');
+
+ $p->onRequestSent(new Event(array(
+ 'request' => new Request('GET', 'http://foo.com'),
+ 'response' => new Response(200, array(), 'Foo')
+ )));
+
+ $this->assertEquals('GET / | 200 Foo', $output);
+ }
+
+ public function testWiresBodiesWhenNeeded()
+ {
+ $client = new Client($this->getServer()->getUrl());
+ $plugin = new LogPlugin($this->adapter, '{req_body} | {res_body}', true);
+ $client->getEventDispatcher()->addSubscriber($plugin);
+ $request = $client->put();
+
+ // Send the response from the dummy server as the request body
+ $this->getServer()->enqueue("HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\nsend");
+ $stream = fopen($this->getServer()->getUrl(), 'r');
+ $request->setBody(EntityBody::factory($stream, 4));
+
+ $tmpFile = tempnam(sys_get_temp_dir(), 'non_repeatable');
+ $request->setResponseBody(EntityBody::factory(fopen($tmpFile, 'w')));
+
+ $this->getServer()->enqueue("HTTP/1.1 200 OK\r\nContent-Length: 8\r\n\r\nresponse");
+
+ ob_start();
+ $request->send();
+ $message = ob_get_clean();
+
+ unlink($tmpFile);
+ $this->assertContains("send", $message);
+ $this->assertContains("response", $message);
+ }
+
+ public function testHasHelpfulStaticFactoryMethod()
+ {
+ $s = fopen('php://temp', 'r+');
+ $client = new Client();
+ $client->addSubscriber(LogPlugin::getDebugPlugin(true, $s));
+ $request = $client->put('http://foo.com', array('Content-Type' => 'Foo'), 'Bar');
+ $request->setresponse(new Response(200), true);
+ $request->send();
+ rewind($s);
+ $contents = stream_get_contents($s);
+ $this->assertContains('# Request:', $contents);
+ $this->assertContainsIns('PUT / HTTP/1.1', $contents);
+ $this->assertContains('# Response:', $contents);
+ $this->assertContainsIns('HTTP/1.1 200 OK', $contents);
+ $this->assertContains('# Errors:', $contents);
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Md5/CommandContentMd5PluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Md5/CommandContentMd5PluginTest.php
new file mode 100644
index 0000000..4bd4111
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Md5/CommandContentMd5PluginTest.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Md5;
+
+use Guzzle\Common\Event;
+use Guzzle\Plugin\Md5\CommandContentMd5Plugin;
+use Guzzle\Service\Description\ServiceDescription;
+use Guzzle\Service\Client;
+
+/**
+ * @covers Guzzle\Plugin\Md5\CommandContentMd5Plugin
+ */
+class CommandContentMd5PluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ protected function getClient()
+ {
+ $description = new ServiceDescription(array(
+ 'operations' => array(
+ 'test' => array(
+ 'httpMethod' => 'PUT',
+ 'parameters' => array(
+ 'ContentMD5' => array(),
+ 'Body' => array(
+ 'location' => 'body'
+ )
+ )
+ )
+ )
+ ));
+
+ $client = new Client();
+ $client->setDescription($description);
+
+ return $client;
+ }
+
+ public function testHasEvents()
+ {
+ $this->assertNotEmpty(CommandContentMd5Plugin::getSubscribedEvents());
+ }
+
+ public function testValidatesMd5WhenParamExists()
+ {
+ $client = $this->getClient();
+ $command = $client->getCommand('test', array(
+ 'Body' => 'Foo',
+ 'ContentMD5' => true
+ ));
+ $event = new Event(array('command' => $command));
+ $request = $command->prepare();
+ $plugin = new CommandContentMd5Plugin();
+ $plugin->onCommandBeforeSend($event);
+ $this->assertEquals('E1bGfXrRY42Ba/uCLdLCXQ==', (string) $request->getHeader('Content-MD5'));
+ }
+
+ public function testDoesNothingWhenNoPayloadExists()
+ {
+ $client = $this->getClient();
+ $client->getDescription()->getOperation('test')->setHttpMethod('GET');
+ $command = $client->getCommand('test');
+ $event = new Event(array('command' => $command));
+ $request = $command->prepare();
+ $plugin = new CommandContentMd5Plugin();
+ $plugin->onCommandBeforeSend($event);
+ $this->assertNull($request->getHeader('Content-MD5'));
+ }
+
+ public function testAddsValidationToResponsesOfContentMd5()
+ {
+ $client = $this->getClient();
+ $client->getDescription()->getOperation('test')->setHttpMethod('GET');
+ $command = $client->getCommand('test', array(
+ 'ValidateMD5' => true
+ ));
+ $event = new Event(array('command' => $command));
+ $request = $command->prepare();
+ $plugin = new CommandContentMd5Plugin();
+ $plugin->onCommandBeforeSend($event);
+ $listeners = $request->getEventDispatcher()->getListeners('request.complete');
+ $this->assertNotEmpty($listeners);
+ }
+
+ public function testIgnoresValidationWhenDisabled()
+ {
+ $client = $this->getClient();
+ $client->getDescription()->getOperation('test')->setHttpMethod('GET');
+ $command = $client->getCommand('test', array(
+ 'ValidateMD5' => false
+ ));
+ $event = new Event(array('command' => $command));
+ $request = $command->prepare();
+ $plugin = new CommandContentMd5Plugin();
+ $plugin->onCommandBeforeSend($event);
+ $listeners = $request->getEventDispatcher()->getListeners('request.complete');
+ $this->assertEmpty($listeners);
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Md5/Md5ValidatorPluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Md5/Md5ValidatorPluginTest.php
new file mode 100644
index 0000000..482e92b
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Md5/Md5ValidatorPluginTest.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Md5;
+
+use Guzzle\Http\EntityBody;
+use Guzzle\Http\Message\RequestFactory;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Md5\Md5ValidatorPlugin;
+
+/**
+ * @covers Guzzle\Plugin\Md5\Md5ValidatorPlugin
+ */
+class Md5ValidatorPluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testValidatesMd5()
+ {
+ $plugin = new Md5ValidatorPlugin();
+ $request = RequestFactory::getInstance()->create('GET', 'http://www.test.com/');
+ $request->getEventDispatcher()->addSubscriber($plugin);
+
+ $body = 'abc';
+ $hash = md5($body);
+ $response = new Response(200, array(
+ 'Content-MD5' => $hash,
+ 'Content-Length' => 3
+ ), 'abc');
+
+ $request->dispatch('request.complete', array(
+ 'response' => $response
+ ));
+
+ // Try again with no Content-MD5
+ $response->removeHeader('Content-MD5');
+ $request->dispatch('request.complete', array(
+ 'response' => $response
+ ));
+ }
+
+ /**
+ * @expectedException UnexpectedValueException
+ */
+ public function testThrowsExceptionOnInvalidMd5()
+ {
+ $plugin = new Md5ValidatorPlugin();
+ $request = RequestFactory::getInstance()->create('GET', 'http://www.test.com/');
+ $request->getEventDispatcher()->addSubscriber($plugin);
+
+ $request->dispatch('request.complete', array(
+ 'response' => new Response(200, array(
+ 'Content-MD5' => 'foobar',
+ 'Content-Length' => 3
+ ), 'abc')
+ ));
+ }
+
+ public function testSkipsWhenContentLengthIsTooLarge()
+ {
+ $plugin = new Md5ValidatorPlugin(false, 1);
+ $request = RequestFactory::getInstance()->create('GET', 'http://www.test.com/');
+ $request->getEventDispatcher()->addSubscriber($plugin);
+
+ $request->dispatch('request.complete', array(
+ 'response' => new Response(200, array(
+ 'Content-MD5' => 'foobar',
+ 'Content-Length' => 3
+ ), 'abc')
+ ));
+ }
+
+ public function testProperlyValidatesWhenUsingContentEncoding()
+ {
+ $plugin = new Md5ValidatorPlugin(true);
+ $request = RequestFactory::getInstance()->create('GET', 'http://www.test.com/');
+ $request->getEventDispatcher()->addSubscriber($plugin);
+
+ // Content-MD5 is the MD5 hash of the canonical content after all
+ // content-encoding has been applied. Because cURL will automatically
+ // decompress entity bodies, we need to re-compress it to calculate.
+ $body = EntityBody::factory('abc');
+ $body->compress();
+ $hash = $body->getContentMd5();
+ $body->uncompress();
+
+ $response = new Response(200, array(
+ 'Content-MD5' => $hash,
+ 'Content-Encoding' => 'gzip'
+ ), 'abc');
+ $request->dispatch('request.complete', array(
+ 'response' => $response
+ ));
+ $this->assertEquals('abc', $response->getBody(true));
+
+ // Try again with an unknown encoding
+ $response = new Response(200, array(
+ 'Content-MD5' => $hash,
+ 'Content-Encoding' => 'foobar'
+ ), 'abc');
+ $request->dispatch('request.complete', array(
+ 'response' => $response
+ ));
+
+ // Try again with compress
+ $body->compress('bzip2.compress');
+ $response = new Response(200, array(
+ 'Content-MD5' => $body->getContentMd5(),
+ 'Content-Encoding' => 'compress'
+ ), 'abc');
+ $request->dispatch('request.complete', array(
+ 'response' => $response
+ ));
+
+ // Try again with encoding and disabled content-encoding checks
+ $request->getEventDispatcher()->removeSubscriber($plugin);
+ $plugin = new Md5ValidatorPlugin(false);
+ $request->getEventDispatcher()->addSubscriber($plugin);
+ $request->dispatch('request.complete', array(
+ 'response' => $response
+ ));
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Mock/MockPluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Mock/MockPluginTest.php
new file mode 100644
index 0000000..3af8fef
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Mock/MockPluginTest.php
@@ -0,0 +1,199 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Mock;
+
+use Guzzle\Common\Event;
+use Guzzle\Http\EntityBody;
+use Guzzle\Http\Message\Response;
+use Guzzle\Plugin\Mock\MockPlugin;
+use Guzzle\Http\Client;
+use Guzzle\Http\Exception\CurlException;
+
+/**
+ * @covers Guzzle\Plugin\Mock\MockPlugin
+ */
+class MockPluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ public function testDescribesSubscribedEvents()
+ {
+ $this->assertInternalType('array', MockPlugin::getSubscribedEvents());
+ }
+
+ public function testDescribesEvents()
+ {
+ $this->assertInternalType('array', MockPlugin::getAllEvents());
+ }
+
+ public function testCanBeTemporary()
+ {
+ $plugin = new MockPlugin();
+ $this->assertFalse($plugin->isTemporary());
+ $plugin = new MockPlugin(null, true);
+ $this->assertTrue($plugin->isTemporary());
+ }
+
+ public function testIsCountable()
+ {
+ $plugin = new MockPlugin();
+ $plugin->addResponse(Response::fromMessage("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"));
+ $this->assertEquals(1, count($plugin));
+ }
+
+ /**
+ * @depends testIsCountable
+ */
+ public function testCanClearQueue()
+ {
+ $plugin = new MockPlugin();
+ $plugin->addResponse(Response::fromMessage("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"));
+ $plugin->clearQueue();
+ $this->assertEquals(0, count($plugin));
+ }
+
+ public function testCanInspectQueue()
+ {
+ $plugin = new MockPlugin();
+ $this->assertInternalType('array', $plugin->getQueue());
+ $plugin->addResponse(Response::fromMessage("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"));
+ $queue = $plugin->getQueue();
+ $this->assertInternalType('array', $queue);
+ $this->assertEquals(1, count($queue));
+ }
+
+ public function testRetrievesResponsesFromFiles()
+ {
+ $response = MockPlugin::getMockFile(__DIR__ . '/../../TestData/mock_response');
+ $this->assertInstanceOf('Guzzle\\Http\\Message\\Response', $response);
+ $this->assertEquals(200, $response->getStatusCode());
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testThrowsExceptionWhenResponseFileIsNotFound()
+ {
+ MockPlugin::getMockFile('missing/filename');
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testInvalidResponsesThrowAnException()
+ {
+ $p = new MockPlugin();
+ $p->addResponse($this);
+ }
+
+ public function testAddsResponseObjectsToQueue()
+ {
+ $p = new MockPlugin();
+ $response = Response::fromMessage("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
+ $p->addResponse($response);
+ $this->assertEquals(array($response), $p->getQueue());
+ }
+
+ public function testAddsResponseFilesToQueue()
+ {
+ $p = new MockPlugin();
+ $p->addResponse(__DIR__ . '/../../TestData/mock_response');
+ $this->assertEquals(1, count($p));
+ }
+
+ /**
+ * @depends testAddsResponseFilesToQueue
+ */
+ public function testAddsMockResponseToRequestFromClient()
+ {
+ $p = new MockPlugin();
+ $response = MockPlugin::getMockFile(__DIR__ . '/../../TestData/mock_response');
+ $p->addResponse($response);
+
+ $client = new Client('http://127.0.0.1:123/');
+ $client->getEventDispatcher()->addSubscriber($p, 9999);
+ $request = $client->get();
+ $request->send();
+
+ $this->assertSame($response, $request->getResponse());
+ $this->assertEquals(0, count($p));
+ }
+
+ /**
+ * @depends testAddsResponseFilesToQueue
+ * @expectedException \OutOfBoundsException
+ */
+ public function testUpdateThrowsExceptionWhenEmpty()
+ {
+ $p = new MockPlugin();
+ $p->onRequestBeforeSend(new Event());
+ }
+
+ /**
+ * @depends testAddsMockResponseToRequestFromClient
+ */
+ public function testDetachesTemporaryWhenEmpty()
+ {
+ $p = new MockPlugin(null, true);
+ $p->addResponse(MockPlugin::getMockFile(__DIR__ . '/../../TestData/mock_response'));
+ $client = new Client('http://127.0.0.1:123/');
+ $client->getEventDispatcher()->addSubscriber($p, 9999);
+ $request = $client->get();
+ $request->send();
+
+ $this->assertFalse($this->hasSubscriber($client, $p));
+ }
+
+ public function testLoadsResponsesFromConstructor()
+ {
+ $p = new MockPlugin(array(new Response(200)));
+ $this->assertEquals(1, $p->count());
+ }
+
+ public function testStoresMockedRequests()
+ {
+ $p = new MockPlugin(array(new Response(200), new Response(200)));
+ $client = new Client('http://127.0.0.1:123/');
+ $client->getEventDispatcher()->addSubscriber($p, 9999);
+
+ $request1 = $client->get();
+ $request1->send();
+ $this->assertEquals(array($request1), $p->getReceivedRequests());
+
+ $request2 = $client->get();
+ $request2->send();
+ $this->assertEquals(array($request1, $request2), $p->getReceivedRequests());
+
+ $p->flush();
+ $this->assertEquals(array(), $p->getReceivedRequests());
+ }
+
+ public function testReadsBodiesFromMockedRequests()
+ {
+ $p = new MockPlugin(array(new Response(200)));
+ $p->readBodies(true);
+ $client = new Client('http://127.0.0.1:123/');
+ $client->getEventDispatcher()->addSubscriber($p, 9999);
+
+ $body = EntityBody::factory('foo');
+ $request = $client->put();
+ $request->setBody($body);
+ $request->send();
+ $this->assertEquals(3, $body->ftell());
+ }
+
+ public function testCanMockBadRequestExceptions()
+ {
+ $client = new Client('http://127.0.0.1:123/');
+ $ex = new CurlException('Foo');
+ $mock = new MockPlugin(array($ex));
+ $client->addSubscriber($mock);
+ $request = $client->get('foo');
+
+ try {
+ $request->send();
+ $this->fail('Did not dequeue an exception');
+ } catch (CurlException $e) {
+ $this->assertSame($e, $ex);
+ $this->assertSame($request, $ex->getRequest());
+ }
+ }
+}
diff --git a/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Oauth/OauthPluginTest.php b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Oauth/OauthPluginTest.php
new file mode 100644
index 0000000..3892fb6
--- /dev/null
+++ b/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Oauth/OauthPluginTest.php
@@ -0,0 +1,345 @@
+<?php
+
+namespace Guzzle\Tests\Plugin\Oauth;
+
+use Guzzle\Http\Message\RequestFactory;
+use Guzzle\Http\QueryAggregator\CommaAggregator;
+use Guzzle\Plugin\Oauth\OauthPlugin;
+use Guzzle\Common\Event;
+
+/**
+ * @covers Guzzle\Plugin\Oauth\OauthPlugin
+ */
+class OauthPluginTest extends \Guzzle\Tests\GuzzleTestCase
+{
+ const TIMESTAMP = '1327274290';
+ const NONCE = 'e7aa11195ca58349bec8b5ebe351d3497eb9e603';
+
+ protected $config = array(
+ 'consumer_key' => 'foo',
+ 'consumer_secret' => 'bar',
+ 'token' => 'count',
+ 'token_secret' => 'dracula'
+ );
+
+ protected function getRequest()
+ {
+ return RequestFactory::getInstance()->create('POST', 'http://www.test.com/path?a=b&c=d', null, array(
+ 'e' => 'f'
+ ));
+ }
+
+ public function testSubscribesToEvents()
+ {
+ $events = OauthPlugin::getSubscribedEvents();
+ $this->assertArrayHasKey('request.before_send', $events);
+ }
+
+ public function testAcceptsConfigurationData()
+ {
+ $p = new OauthPlugin($this->config);
+
+ // Access the config object
+ $class = new \ReflectionClass($p);
+ $property = $class->getProperty('config');
+ $property->setAccessible(true);
+ $config = $property->getValue($p);
+
+ $this->assertEquals('foo', $config['consumer_key']);
+ $this->assertEquals('bar', $config['consumer_secret']);
+ $this->assertEquals('count', $config['token']);
+ $this->assertEquals('dracula', $config['token_secret']);
+ $this->assertEquals('1.0', $config['version']);
+ $this->assertEquals('HMAC-SHA1', $config['signature_method']);
+ $this->assertEquals('header', $config['request_method']);
+ }
+
+ public function testCreatesStringToSignFromPostRequest()
+ {
+ $p = new OauthPlugin($this->config);
+ $request = $this->getRequest();
+ $signString = $p->getStringToSign($request, self::TIMESTAMP, self::NONCE);
+
+ $this->assertContains('&e=f', rawurldecode($signString));
+
+ $expectedSignString =
+ // Method and URL
+ 'POST&http%3A%2F%2Fwww.test.com%2Fpath' .
+ // Sorted parameters from query string and body
+ '&a%3Db%26c%3Dd%26e%3Df%26oauth_consumer_key%3Dfoo' .
+ '%26oauth_nonce%3De7aa11195ca58349bec8b5ebe351d3497eb9e603%26' .
+ 'oauth_signature_method%3DHMAC-SHA1' .
+ '%26oauth_timestamp%3D' . self::TIMESTAMP . '%26oauth_token%3Dcount%26oauth_version%3D1.0';
+
+ $this->assertEquals($expectedSignString, $signString);
+ }
+
+ public function testCreatesStringToSignIgnoringPostFields()
+ {
+ $config = $this->config;
+ $config['disable_post_params'] = true;
+ $p = new OauthPlugin($config);
+ $request = $this->getRequest();
+ $sts = rawurldecode($p->getStringToSign($request, self::TIMESTAMP, self::NONCE));
+ $this->assertNotContains('&e=f', $sts);
+ }
+
+ public function testCreatesStringToSignFromPostRequestWithCustomContentType()
+ {
+ $p = new OauthPlugin($this->config);
+ $request = $this->getRequest();
+ $request->setHeader('Content-Type', 'Foo');
+ $this->assertEquals(
+ // Method and URL
+ 'POST&http%3A%2F%2Fwww.test.com%2Fpath' .
+ // Sorted parameters from query string and body
+ '&a%3Db%26c%3Dd%26oauth_consumer_key%3Dfoo' .
+ '%26oauth_nonce%3D'. self::NONCE .'%26' .
+ 'oauth_signature_method%3DHMAC-SHA1' .
+ '%26oauth_timestamp%3D' . self::TIMESTAMP . '%26oauth_token%3Dcount%26oauth_version%3D1.0',
+ $p->getStringToSign($request, self::TIMESTAMP, self::NONCE)
+ );
+ }
+
+ /**
+ * @depends testCreatesStringToSignFromPostRequest
+ */
+ public function testConvertsBooleansToStrings()
+ {
+ $p = new OauthPlugin($this->config);
+ $request = $this->getRequest();
+ $request->getQuery()->set('a', true);
+ $request->getQuery()->set('c', false);
+ $this->assertContains('&a%3Dtrue%26c%3Dfalse', $p->getStringToSign($request, self::TIMESTAMP, self::NONCE));
+ }
+
+ public function testCreatesStringToSignFromPostRequestWithNullValues()
+ {
+ $config = array(
+ 'consumer_key' => 'foo',
+ 'consumer_secret' => 'bar',
+ 'token' => null,
+ 'token_secret' => 'dracula'
+ );
+
+ $p = new OauthPlugin($config);
+ $request = $this->getRequest();
+ $signString = $p->getStringToSign($request, self::TIMESTAMP, self::NONCE);
+
+ $this->assertContains('&e=f', rawurldecode($signString));
+
+ $expectedSignString = // Method and URL
+ 'POST&http%3A%2F%2Fwww.test.com%2Fpath' .
+ // Sorted parameters from query string and body
+ '&a%3Db%26c%3Dd%26e%3Df%26oauth_consumer_key%3Dfoo' .
+ '%26oauth_nonce%3De7aa11195ca58349bec8b5ebe351d3497eb9e603%26' .
+ 'oauth_signature_method%3DHMAC-SHA1' .
+ '%26oauth_timestamp%3D' . self::TIMESTAMP . '%26oauth_version%3D1.0';
+
+ $this->assertEquals($expectedSignString, $signString);
+ }
+
+ /**
+ * @depends testCreatesStringToSignFromPostRequest
+ */
+ public function testMultiDimensionalArray()
+ {
+ $p = new OauthPlugin($this->config);
+ $request = $this->getRequest();
+ $request->getQuery()->set('a', array('b' => array('e' => 'f', 'c' => 'd')));
+ $this->assertContains('a%255Bb%255D%255Bc%255D%3Dd%26a%255Bb%255D%255Be%255D%3Df%26c%3Dd%26e%3Df%26', $p->getStringToSign($request, self::TIMESTAMP, self::NONCE));
+ }
+
+ /**
+ * @depends testMultiDimensionalArray
+ */
+ public function testMultiDimensionalArrayWithNonDefaultQueryAggregator()
+ {
+ $p = new OauthPlugin($this->config);
+ $request = $this->getRequest();
+ $aggregator = new CommaAggregator();
+ $query = $request->getQuery()->setAggregator($aggregator)
+ ->set('g', array('h', 'i', 'j'))
+ ->set('k', array('l'))
+ ->set('m', array('n', 'o'));
+ $this->assertContains('a%3Db%26c%3Dd%26e%3Df%26g%3Dh%2Ci%2Cj%26k%3Dl%26m%3Dn%2Co', $p->getStringToSign($request, self::TIMESTAMP, self::NONCE));
+ }
+
+ /**
+ * @depends testCreatesStringToSignFromPostRequest
+ */
+ public function testSignsStrings()
+ {
+ $p = new OauthPlugin(array_merge($this->config, array(
+ 'signature_callback' => function($string, $key) {
+ return "_{$string}|{$key}_";
+ }
+ )));
+ $request = $this->getRequest();
+ $sig = $p->getSignature($request, self::TIMESTAMP, self::NONCE);
+ $this->assertEquals(
+ '_POST&http%3A%2F%2Fwww.test.com%2Fpath&a%3Db%26c%3Dd%26e%3Df%26oauth_consumer_key%3Dfoo' .
+ '%26oauth_nonce%3D'. self::NONCE .'%26oauth_signature_method%3DHMAC-SHA1' .
+ '%26oauth_timestamp%3D' . self::TIMESTAMP . '%26oauth_token%3Dcount%26oauth_version%3D1.0|' .
+ 'bar&dracula_',
+ base64_decode($sig)
+ );
+ }
+
+ /**
+ * Test that the Oauth is signed correctly and that extra strings haven't been added
+ * to the authorization header.
+ */
+ public function testSignsOauthRequests()
+ {
+ $p = new OauthPlugin($this->config);
+ $event = new Event(array(
+ 'request' => $this->getRequest(),
+ 'timestamp' => self::TIMESTAMP
+ ));
+ $params = $p->onRequestBeforeSend($event);
+
+ $this->assertTrue($event['request']->hasHeader('Authorization'));
+
+ $authorizationHeader = (string)$event['request']->getHeader('Authorization');
+
+ $this->assertStringStartsWith('OAuth ', $authorizationHeader);
+
+ $stringsToCheck = array(
+ 'oauth_consumer_key="foo"',
+ 'oauth_nonce="'.urlencode($params['oauth_nonce']).'"',
+ 'oauth_signature="'.urlencode($params['oauth_signature']).'"',
+ 'oauth_signature_method="HMAC-SHA1"',
+ 'oauth_timestamp="' . self::TIMESTAMP . '"',
+ 'oauth_token="count"',
+ 'oauth_version="1.0"',
+ );
+
+ $totalLength = strlen('OAuth ');
+
+ //Separator is not used before first parameter.
+ $separator = '';
+
+ foreach ($stringsToCheck as $stringToCheck) {
+ $this->assertContains($stringToCheck, $authorizationHeader);
+ $totalLength += strlen($separator);
+ $totalLength += strlen($stringToCheck);
+ $separator = ', ';
+ }
+
+ // Technically this test is not universally valid. It would be allowable to have extra \n characters
+ // in the Authorization header. However Guzzle does not do this, so we just perform a simple check
+ // on length to validate the Authorization header is composed of only the strings above.
+ $this->assertEquals($totalLength, strlen($authorizationHeader), 'Authorization has extra characters i.e. contains extra elements compared to stringsToCheck.');
+ }
+
+ public function testSignsOauthQueryStringRequest()
+ {
+ $config = array_merge(
+ $this->config,
+ array('request_method' => OauthPlugin::REQUEST_METHOD_QUERY)
+ );
+
+ $p = new OauthPlugin($config);
+ $event = new Event(array(
+ 'request' => $this->getRequest(),
+ 'timestamp' => self::TIMESTAMP
+ ));
+ $params = $p->onRequestBeforeSend($event);
+
+ $this->assertFalse($event['request']->hasHeader('Authorization'));
+
+ $stringsToCheck = array(
+ 'a=b',
+ 'c=d',
+ 'oauth_consumer_key=foo',
+ 'oauth_nonce='.urlencode($params['oauth_nonce']),
+ 'oauth_signature='.urlencode($params['oauth_signature']),
+ 'oauth_signature_method=HMAC-SHA1',
+ 'oauth_timestamp='.self::TIMESTAMP,
+ 'oauth_token=count',
+ 'oauth_version=1.0',
+ );
+
+ $queryString = (string) $event['request']->getQuery();
+
+ $totalLength = strlen('?');
+
+ //Separator is not used before first parameter.
+ $separator = '';
+
+ foreach ($stringsToCheck as $stringToCheck) {
+ $this->assertContains($stringToCheck, $queryString);
+ $totalLength += strlen($separator);
+ $totalLength += strlen($stringToCheck);
+ $separator = '&';
+ }
+
+ // Removes the last query string separator '&'
+ $totalLength -= 1;
+
+ $this->assertEquals($totalLength, strlen($queryString), 'Query string has extra characters i.e. contains extra elements compared to stringsToCheck.');
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testInvalidArgumentExceptionOnMethodError()
+ {
+ $config = array_merge(
+ $this->config,
+ array('request_method' => 'FakeMethod')
+ );
+
+ $p = new OauthPlugin($config);
+ $event = new Event(array(
+ 'request' => $this->getRequest(),
+ 'timestamp' => self::TIMESTAMP
+ ));
+
+ $p->onRequestBeforeSend($event);
+ }
+
+ public function testDoesNotAddFalseyValuesToAuthorization()
+ {
+ unset($this->config['token']);
+ $p = new OauthPlugin($this->config);
+ $event = new Event(array('request' => $this->getRequest(), 'timestamp' => self::TIMESTAMP));
+ $p->onRequestBeforeSend($event);
+ $this->assertTrue($event['request']->hasHeader('Authorization'));
+ $this->assertNotContains('oauth_token=', (string) $event['request']->getHeader('Authorization'));
+ }
+
+ public function testOptionalOauthParametersAreNotAutomaticallyAdded()
+ {
+ // The only required Oauth parameters are the consumer key and secret. That is enough credentials
+ // for signing oauth requests.
+ $config = array(
+ 'consumer_key' => 'foo',
+ 'consumer_secret' => 'bar',
+ );
+
+ $plugin = new OauthPlugin($config);
+ $event = new Event(array(
+ 'request' => $this->getRequest(),
+ 'timestamp' => self::TIMESTAMP
+ ));
+
+ $timestamp = $plugin->getTimestamp($event);
+ $request = $event['request'];
+ $nonce = $plugin->generateNonce($request);
+
+ $paramsToSign = $plugin->getParamsToSign($request, $timestamp, $nonce);
+
+ $optionalParams = array(
+ 'callback' => 'oauth_callback',
+ 'token' => 'oauth_token',
+ 'verifier' => 'oauth_verifier',
+ 'token_secret' => 'token_secret'
+ );
+
+ foreach ($optionalParams as $optionName => $oauthName) {
+ $this->assertArrayNotHasKey($oauthName, $paramsToSign, "Optional Oauth param '$oauthName' was not set via config variable '$optionName', but it is listed in getParamsToSign().");
+ }
+ }
+}