From 620e13057c1e169202ec876f554c54314d839cbc Mon Sep 17 00:00:00 2001 From: Michael Dowling Date: Wed, 23 Mar 2011 17:24:36 -0500 Subject: [PATCH] [Http] [Service] Adding more coverage to Url. Fixing CookiePlugintest. Allowing XML based commands to extend previously defined commands. --- library/Guzzle/Http/Curl/CurlHandle.php | 4 ++ library/Guzzle/Http/Url.php | 8 ++- .../Guzzle/Service/Description/ApiCommand.php | 6 +- .../Description/XmlDescriptionBuilder.php | 69 ++++++++++++++++--- .../Tests/Http/Plugin/CookiePluginTest.php | 2 +- tests/Guzzle/Tests/Http/UrlTest.php | 22 ++++++ .../Service/Description/ApiCommandTest.php | 6 +- .../Description/XmlDescriptionBuilderTest.php | 52 +++++++++++++- 8 files changed, 151 insertions(+), 18 deletions(-) diff --git a/library/Guzzle/Http/Curl/CurlHandle.php b/library/Guzzle/Http/Curl/CurlHandle.php index 0db7cf95..bf7829e5 100644 --- a/library/Guzzle/Http/Curl/CurlHandle.php +++ b/library/Guzzle/Http/Curl/CurlHandle.php @@ -93,9 +93,11 @@ class CurlHandle */ public function isAvailable() { + //@codeCoverageIgnoreStart if (!$this->handle) { return false; } + //@codeCoverageIgnoreEnd return false != @curl_getinfo($this->handle, CURLINFO_EFFECTIVE_URL); } @@ -346,6 +348,7 @@ class CurlHandle */ public function hasProblematicOption() { + //@codeCoverageIgnoreStart if (!self::$pollute) { self::$pollute = array( CURLOPT_RANGE, @@ -365,6 +368,7 @@ class CurlHandle self::$pollute[] = \CURLOPT_TIMEOUT_MS; } } + //@codeCoverageIgnoreEnd return count(array_intersect(self::$pollute, $this->options->getKeys())) > 0; } diff --git a/library/Guzzle/Http/Url.php b/library/Guzzle/Http/Url.php index 37163ef5..136b82ff 100644 --- a/library/Guzzle/Http/Url.php +++ b/library/Guzzle/Http/Url.php @@ -412,7 +412,13 @@ class Url */ public function setQuery($query) { - $this->query = $query; + if (is_string($query)) { + $output = null; + parse_str($query, $output); + $this->query = new QueryString($output); + } else { + $this->query = $query; + } return $this; } diff --git a/library/Guzzle/Service/Description/ApiCommand.php b/library/Guzzle/Service/Description/ApiCommand.php index 586bff85..522e5797 100644 --- a/library/Guzzle/Service/Description/ApiCommand.php +++ b/library/Guzzle/Service/Description/ApiCommand.php @@ -100,7 +100,11 @@ class ApiCommand if (isset($config['args']) && is_array($config['args'])) { $this->args = array(); foreach ($config['args'] as $argName => $arg) { - $this->args[$argName] = new Collection($arg); + if ($arg instanceof Collection) { + $this->args[$argName] = $arg; + } else { + $this->args[$argName] = new Collection($arg); + } } } } diff --git a/library/Guzzle/Service/Description/XmlDescriptionBuilder.php b/library/Guzzle/Service/Description/XmlDescriptionBuilder.php index b651e6fc..2e59c2ce 100644 --- a/library/Guzzle/Service/Description/XmlDescriptionBuilder.php +++ b/library/Guzzle/Service/Description/XmlDescriptionBuilder.php @@ -67,6 +67,56 @@ class XmlDescriptionBuilder implements DescriptionBuilderInterface // Parse the commands in the XML doc foreach ($xml->commands->command as $command) { $args = array(); + $parentData = array(); + $parentArgs = array(); + $attr = $command->attributes(); + $data = array( + 'name' => (string) $attr->name + ); + if ($v = (string) $command->doc) { + $data['doc'] = $v; + } + if ($v = (string) $attr->method) { + $data['method'] = $v; + } + if ($v = (string) $attr->path) { + $data['path'] = $v; + } + if ($v = (int) (string) $attr->min_args) { + $data['min_args'] = $v; + } + if ($v = (string) $attr->can_batch) { + $data['can_batch'] = $v == 'false' ? false : true; + } + if ($v = (string) $attr->class) { + $data['class'] = $v; + } + + $extends = (string) $attr->extends; + if ($extends) { + $match = false; + foreach ($commands as $cmd) { + if ($cmd->getName() == $extends) { + $match = $cmd; + } + } + if (!$match) { + throw new \RuntimeException((string) $attr->name + . 'is trying to extend non-existent command ' . $extends); + } else { + $parentArgs = $match->getArgs(); + $parentData = array( + 'name' => $match->getName(), + 'doc' => $match->getDoc(), + 'method' => $match->getMethod(), + 'path' => $match->getPath(), + 'min_args' => $match->getMinArgs(), + 'can_batch' => $match->canBatch(), + 'class' => $match->getConcreteClass() + ); + } + } + // Add the arguments to the command foreach ($command->param as $arg) { $row = array(); @@ -83,19 +133,16 @@ class XmlDescriptionBuilder implements DescriptionBuilderInterface $args[(string) $arg->attributes()->name] = $row; } - $attr = $command->attributes(); + $data = array_merge($parentData, $data); + $data['args'] = array_merge($parentArgs, $args); + if (!isset($data['class'])) { + $data['class'] = ServiceDescription::DEFAULT_COMMAND_CLASS; + } else { + $data['class'] = str_replace('.', '\\', $data['class']); + } // Create a new command using the parsed XML - $commands[] = new ApiCommand(array( - 'name' => (string) $attr->name, - 'doc' => (string) $command->doc, - 'method' => (string) $attr->method, - 'path' => (string) $attr->path, - 'min_args' => (int) (string) $attr->min_args, - 'can_batch' => (string) $attr->can_batch == 'false' ? false : true, - 'class' => (string) $attr->class ?: ServiceDescription::DEFAULT_COMMAND_CLASS, - 'args' => $args - )); + $commands[] = new ApiCommand($data); } return new ServiceDescription($commands); diff --git a/tests/Guzzle/Tests/Http/Plugin/CookiePluginTest.php b/tests/Guzzle/Tests/Http/Plugin/CookiePluginTest.php index f70b7b3b..5e441e58 100644 --- a/tests/Guzzle/Tests/Http/Plugin/CookiePluginTest.php +++ b/tests/Guzzle/Tests/Http/Plugin/CookiePluginTest.php @@ -540,7 +540,7 @@ class CookiePluginTest extends \Guzzle\Tests\GuzzleTestCase { $this->getServer()->enqueue(array( "HTTP/1.1 302 Moved Temporarily\r\n" . - "Set-Cookie: test=583551; expires=Wednesday, 23-Mar-2011 19:49:45 GMT; path=/\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" . diff --git a/tests/Guzzle/Tests/Http/UrlTest.php b/tests/Guzzle/Tests/Http/UrlTest.php index aca28a0b..561e43e4 100644 --- a/tests/Guzzle/Tests/Http/UrlTest.php +++ b/tests/Guzzle/Tests/Http/UrlTest.php @@ -6,6 +6,7 @@ namespace Guzzle\Tests\Http; +use Guzzle\Http\QueryString; use Guzzle\Http\Url; use Guzzle\Http\HttpException; @@ -181,4 +182,25 @@ class UrlTest extends \Guzzle\Tests\GuzzleTestCase { $this->assertEquals($c, (string) Url::factory($a)->combine($b)); } + + /** + * @covers Guzzle\Http\Url + */ + public function testHasGettersAndSetters() + { + $url = Url::factory('http://www.test.com/'); + $this->assertEquals('example.com', $url->setHost('example.com')->getHost()); + $this->assertEquals('8080', $url->setPort(8080)->getPort()); + $this->assertEquals('/foo/bar', $url->setPath(array('foo', 'bar'))->getPath()); + $this->assertEquals('a', $url->setPassword('a')->getPassword()); + $this->assertEquals('b', $url->setUsername('b')->getUsername()); + $this->assertEquals('abc', $url->setFragment('abc')->getFragment()); + $this->assertEquals('https', $url->setScheme('https')->getScheme()); + $this->assertEquals('?a=123', (string) $url->setQuery('a=123')->getQuery()); + $this->assertEquals('https://b:a@example.com:8080/foo/bar?a=123#abc', (string)$url); + $this->assertEquals('?b=boo', (string) $url->setQuery(new QueryString(array( + 'b' => 'boo' + )))->getQuery()); + $this->assertEquals('https://b:a@example.com:8080/foo/bar?b=boo#abc', (string)$url); + } } \ No newline at end of file diff --git a/tests/Guzzle/Tests/Service/Description/ApiCommandTest.php b/tests/Guzzle/Tests/Service/Description/ApiCommandTest.php index f80083d6..bbc6c0f9 100644 --- a/tests/Guzzle/Tests/Service/Description/ApiCommandTest.php +++ b/tests/Guzzle/Tests/Service/Description/ApiCommandTest.php @@ -84,7 +84,11 @@ class ApiCommandTest extends \Guzzle\Tests\GuzzleTestCase $c = new ApiCommand(array( 'name' => 'test', 'class' => 'Guzzle\\Service\\Command\ClosureCommand', - 'args' => array() + 'args' => array( + 'p' => new Collection(array( + 'name' => 'foo' + )) + ) )); $this->assertEquals('Guzzle\\Service\\Command\ClosureCommand', $c->getConcreteClass()); } diff --git a/tests/Guzzle/Tests/Service/Description/XmlDescriptionBuilderTest.php b/tests/Guzzle/Tests/Service/Description/XmlDescriptionBuilderTest.php index 01e7c56b..e011f96b 100644 --- a/tests/Guzzle/Tests/Service/Description/XmlDescriptionBuilderTest.php +++ b/tests/Guzzle/Tests/Service/Description/XmlDescriptionBuilderTest.php @@ -75,8 +75,16 @@ class XmlDescriptionBuilderTest extends \Guzzle\Tests\GuzzleTestCase - - + + + + + + + + + + @@ -84,7 +92,45 @@ EOT; $builder = new XmlDescriptionBuilder($xml); $service = $builder->build(); - $this->assertTrue($service->hasCommand('geo.id')); $this->arrayHasKey('slug', Inspector::getInstance()->getRegisteredFilters()); + $this->assertTrue($service->hasCommand('abstract')); + $this->assertTrue($service->hasCommand('test1')); + $this->assertTrue($service->hasCommand('test1')); + $this->assertTrue($service->hasCommand('test2')); + $this->assertTrue($service->hasCommand('test3')); + + $test1 = $service->getCommand('test1'); + $test2 = $service->getCommand('test2'); + $test3 = $service->getCommand('test3'); + + $this->assertEquals('GET', $test1->getMethod()); + $this->assertEquals('/path/{{def}}', $test1->getPath()); + $this->assertEquals('2', $test1->getMinArgs()); + $this->assertEquals('static', $test1->getArg('st')->get('static')); + $this->assertEquals('123', $test1->getArg('def')->get('default')); + + $this->assertEquals('DELETE', $test2->getMethod()); + $this->assertEquals('/path/{{def}}', $test1->getPath()); + $this->assertEquals('2', $test1->getMinArgs()); + $this->assertEquals('static', $test1->getArg('st')->get('static')); + $this->assertEquals('123', $test1->getArg('def')->get('default')); + $this->assertEquals('header:X-Hd', $test1->getArg('hd')->get('location')); + + $this->assertEquals('', $test3->getMethod()); + $this->assertEquals('Guzzle\Service\Command\ClosureCommand', $test3->getConcreteClass()); + } + + /** + * @covers Guzzle\Service\Description\XmlDescriptionBuilder + * @expectedException RuntimeException + */ + public function testvalidatesXmlExtensions() + { + $xml = << + +EOT; + $builder = new XmlDescriptionBuilder($xml); + $service = $builder->build(); } } \ No newline at end of file