summaryrefslogtreecommitdiff
path: root/server/vendor/php-opencloud/common/tests/unit
diff options
context:
space:
mode:
authormanzerbredes <loic.guegan_secondary@yahoo.fr>2016-03-15 16:17:39 +0100
committermanzerbredes <loic.guegan_secondary@yahoo.fr>2016-03-15 16:17:39 +0100
commit26d10bc0fa4befbac54453228ae1ce89021bdec2 (patch)
tree029d7240ecf7416205e5f76cf9107a6b5bdf8ca3 /server/vendor/php-opencloud/common/tests/unit
parent8ad216dedf017f3d6de047a25d08db3b98e16361 (diff)
parent03ef74d0cfe675a6e18a91f039182ca1b248d8f5 (diff)
Merge branch 'develop' into loic
Diffstat (limited to 'server/vendor/php-opencloud/common/tests/unit')
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Api/OperationTest.php74
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Api/OperatorTest.php137
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Api/ParameterTest.php203
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Api/fixtures/headers.php25
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Api/fixtures/jsonBody.php27
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/ArrayAccessTraitTest.php59
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Auth/AuthHandlerTest.php59
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/DateTime.php16
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Error/BadResponseErrorTest.php34
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Error/BuilderTest.php117
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/HydratorStrategyTraitTes.php52
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/JsonPathTest.php70
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/Fixtures/jsonPatchTests.json231
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/JsonPatchTest.php28
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/SchemaTest.php102
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Resource/AbstractResourceTest.php161
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-empty.resp6
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-page1.resp77
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-page2.resp77
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Service/BuilderTest.php164
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Transport/HandlerStackTest.php15
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Transport/JsonSerializerTest.php85
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Transport/MiddlewareTest.php59
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Transport/RequestSerializerTest.php112
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Common/Transport/UtilsTest.php30
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Fixtures/ComputeV2Api.php107
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Fixtures/IdentityV2Api.php36
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/Fixtures/IdentityV3Api.php75
-rw-r--r--server/vendor/php-opencloud/common/tests/unit/TestCase.php99
29 files changed, 2337 insertions, 0 deletions
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Api/OperationTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Api/OperationTest.php
new file mode 100644
index 0000000..ea0f7c8
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Api/OperationTest.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace OpenCloud\Test\Common\Api;
+
+use OpenCloud\Common\Api\Operation;
+use OpenCloud\Common\Api\Parameter;
+use OpenCloud\Test\Fixtures\ComputeV2Api;
+
+class OperationTest extends \PHPUnit_Framework_TestCase
+{
+ private $operation;
+
+ public function setUp()
+ {
+ $def = (new ComputeV2Api())->postServer();
+
+ $this->operation = new Operation($def);
+ }
+
+ public function test_it_reveals_whether_params_are_set_or_not()
+ {
+ $this->assertFalse($this->operation->hasParam('foo'));
+ $this->assertTrue($this->operation->hasParam('name'));
+ }
+
+ public function test_it_gets_params()
+ {
+ $this->assertInstanceOf(Parameter::class, $this->operation->getParam('name'));
+ }
+
+ public function test_it_validates_params()
+ {
+ $this->assertTrue($this->operation->validate([
+ 'name' => 'foo',
+ 'imageId' => 'bar',
+ 'flavorId' => 'baz',
+ ]));
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function test_exceptions_are_propagated()
+ {
+ $this->assertFalse($this->operation->validate([
+ 'name' => true,
+ 'imageId' => 'bar',
+ 'flavorId' => 'baz',
+ ]));
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function test_an_exception_is_thrown_when_user_does_not_provide_required_options()
+ {
+ $this->operation->validate([]);
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function test_it_throws_exception_when_user_provides_undefined_options()
+ {
+ $userData = ['name' => 'new_server', 'undefined_opt' => 'bah'];
+
+ $this->operation->validate($userData);
+ }
+
+ public function test_it_gets_json_key()
+ {
+ $this->assertEquals('server', $this->operation->getJsonKey());
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Api/OperatorTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Api/OperatorTest.php
new file mode 100644
index 0000000..43c5804
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Api/OperatorTest.php
@@ -0,0 +1,137 @@
+<?php
+
+namespace OpenCloud\Test\Common\Api;
+
+use function GuzzleHttp\Psr7\uri_for;
+use GuzzleHttp\Promise\Promise;
+use GuzzleHttp\Psr7\Request;
+use GuzzleHttp\Psr7\Response;
+use GuzzleHttp\Psr7\Uri;
+use OpenCloud\Common\Api\Operator;
+use OpenCloud\Common\Resource\AbstractResource;
+use OpenCloud\Common\Resource\ResourceInterface;
+use OpenCloud\Compute\v2\Models\Server;
+use OpenCloud\Test\Fixtures\ComputeV2Api;
+use OpenCloud\Test\TestCase;
+use Prophecy\Argument;
+
+class OperatorTest extends TestCase
+{
+ private $operator;
+ private $def;
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->rootFixturesDir = __DIR__;
+
+ $this->def = [
+ 'method' => 'GET',
+ 'path' => 'test',
+ 'params' => [],
+ ];
+
+ $this->operator = new TestOperator($this->client->reveal(), new ComputeV2Api());
+ }
+
+ public function test_it_returns_operations()
+ {
+ $this->assertInstanceOf(
+ 'OpenCloud\Common\Api\Operation',
+ $this->operator->getOperation($this->def, [])
+ );
+ }
+
+ public function test_it_sends_a_request_when_operations_are_executed()
+ {
+ $this->client->request('GET', 'test', ['headers' => []])->willReturn(new Request('GET', 'test'));
+
+ $this->operator->execute($this->def, []);
+ }
+
+ public function test_it_sends_a_request_when_async_operations_are_executed()
+ {
+ $this->client->requestAsync('GET', 'test', ['headers' => []])->willReturn(new Promise());
+
+ $this->operator->executeAsync($this->def, []);
+ }
+
+ public function test_it_returns_a_model_instance()
+ {
+ $this->assertInstanceOf(ResourceInterface::class, $this->operator->model(TestResource::class));
+ }
+
+ public function test_it_populates_models_from_response()
+ {
+ $this->assertInstanceOf(ResourceInterface::class, $this->operator->model(TestResource::class, new Response(200)));
+ }
+
+ public function test_it_populates_models_from_arrays()
+ {
+ $data = ['flavor' => [], 'image' => []];
+ $this->assertInstanceOf(ResourceInterface::class, $this->operator->model(TestResource::class, $data));
+ }
+
+ public function test_it_wraps_sequential_ops_in_promise_when_async_is_appended_to_method_name()
+ {
+ $promise = $this->operator->createAsync('something');
+
+ $this->assertInstanceOf(Promise::class, $promise);
+
+ $promise->then(function ($val) {
+ $this->assertEquals('Created something', $val);
+ });
+
+ $promise->wait();
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function test_it_throws_exception_when_async_is_called_on_a_non_existent_method()
+ {
+ $this->operator->fooAsync();
+ }
+
+ public function test_it_retrieves_base_http_url()
+ {
+ $returnedUri = uri_for('http://foo.com');
+
+ $this->client->getConfig('base_uri')->shouldBeCalled()->willReturn($returnedUri);
+
+ $uri = $this->operator->testBaseUri();
+
+ $this->assertInstanceOf(Uri::class, $uri);
+ $this->assertEquals($returnedUri, $uri);
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function test_undefined_methods_result_in_error()
+ {
+ $this->operator->foo();
+ }
+}
+
+class TestResource extends AbstractResource
+{
+}
+
+class TestOperator extends Operator
+{
+ public function testBaseUri()
+ {
+ return $this->getHttpBaseUrl();
+ }
+
+ public function create($str)
+ {
+ return 'Created ' . $str;
+ }
+
+ public function fail()
+ {
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Api/ParameterTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Api/ParameterTest.php
new file mode 100644
index 0000000..65d4760
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Api/ParameterTest.php
@@ -0,0 +1,203 @@
+<?php
+
+namespace OpenCloud\Test\Common\Api;
+
+use OpenCloud\Common\Api\Parameter;
+use OpenCloud\Test\Fixtures\ComputeV2Api;
+
+class ParameterTest extends \PHPUnit_Framework_TestCase
+{
+ const PARAMETER_CLASS = 'OpenCloud\Common\Api\Parameter';
+
+ private $param;
+ private $data;
+ private $api;
+
+ public function setUp()
+ {
+ $this->api = new ComputeV2Api();
+
+ $this->data = $this->api->postServer()['params']['name'] + ['name' => 'name'];
+ $this->param = new Parameter($this->data);
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function test_exception_is_thrown_for_invalid_locations()
+ {
+ $data = $this->data;
+ $data['location'] = 'foo';
+ new Parameter($data);
+ }
+
+ public function test_it_should_provide_access_to_a_name()
+ {
+ $this->assertEquals($this->data['name'], $this->param->getName());
+ }
+
+ public function test_it_should_use_sentAs_alias_for_name_if_one_is_set()
+ {
+ $data = $this->data + ['sentAs' => 'foo'];
+ $param = new Parameter($data);
+
+ $this->assertEquals($data['sentAs'], $param->getName());
+ }
+
+ public function test_it_indicates_whether_it_is_required_or_not()
+ {
+ $this->assertTrue($this->param->isRequired());
+ }
+
+ public function test_it_indicates_its_item_schema()
+ {
+ $data = $this->api->postServer()['params']['networks'] + ['name' => 'networks'];
+ $param = new Parameter($data);
+
+ $this->assertInstanceOf(self::PARAMETER_CLASS, $param->getItemSchema());
+ }
+
+ public function test_it_allows_property_retrieval()
+ {
+ $definition = $this->api->postServer()['params']['networks']['items'] + ['name' => 'network'];
+ $param = new Parameter($definition);
+
+ $this->assertInstanceOf(self::PARAMETER_CLASS, $param->getProperty('uuid'));
+ }
+
+ public function test_it_indicates_its_path()
+ {
+ $path = 'foo.bar.baz';
+ $param = new Parameter($this->data + ['path' => $path]);
+
+ $this->assertEquals($path, $param->getPath());
+ }
+
+ public function test_it_verifies_a_given_location_with_a_boolean()
+ {
+ $this->assertFalse($this->param->hasLocation('foo'));
+ $this->assertTrue($this->param->hasLocation('json'));
+ }
+
+ public function test_it_should_return_true_when_required_attributes_are_provided_and_match_their_definitions()
+ {
+ $this->assertTrue($this->param->validate('TestName'));
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function test_it_throws_exception_when_values_do_not_match_their_definition_types()
+ {
+ $data = $this->api->postServer()['params']['networks'] + ['name' => 'networks'];
+ $param = new Parameter($data);
+
+ $param->validate('a_network!'); // should be an array
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function test_it_throws_exception_when_deeply_nested_values_have_wrong_types()
+ {
+ $data = $this->api->postServer()['params']['networks'] + ['name' => 'networks'];
+
+ $param = new Parameter($data);
+ $param->validate(['name' => false]); // value should be a string, not bool
+ }
+
+ public function test_metadata_properties_are_handled_differently()
+ {
+ $params = [
+ 'name' => 'metadata',
+ 'type' => 'object',
+ 'properties' => [
+ 'type' => 'string',
+ ],
+ ];
+
+ $userValues = ['some' => 'value'];
+
+ $param = new Parameter($params);
+ $this->assertTrue($param->validate($userValues));
+ }
+
+ public function test_it_passes_validation_when_array_values_pass()
+ {
+ $params = [
+ 'name' => 'foo',
+ 'type' => 'array',
+ 'items' => ['type' => 'string'],
+ ];
+
+ $userVals = ['1', '2', '3'];
+
+ $param = new Parameter($params);
+ $this->assertTrue($param->validate($userVals));
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function test_an_exception_is_thrown_when_an_undefined_property_is_provided()
+ {
+ $params = ['type' => 'object', 'properties' => ['foo' => ['type' => 'string']]];
+ $userVals = ['bar' => 'baz'];
+
+ $param = new Parameter($params);
+ $param->validate($userVals);
+ }
+
+ public function test_it_passes_validation_when_all_subproperties_pass()
+ {
+ $params = ['type' => 'object', 'properties' => ['foo' => ['type' => 'string']]];
+ $userVals = ['foo' => 'baz'];
+
+ $param = new Parameter($params);
+ $this->assertTrue($param->validate($userVals));
+ }
+
+ public function test_it_sets_name()
+ {
+ $this->param->setName('foo');
+ $this->assertEquals($this->param->getName(), 'foo');
+ }
+
+ public function test_it_gets_property()
+ {
+ $property = new Parameter([
+ 'name' => 'metadata',
+ 'properties' => [
+ 'type' => 'string',
+ 'prefix' => 'foo',
+ ],
+ ]);
+
+ $prop = $property->getProperty('metadata');
+
+ $this->assertInstanceOf(Parameter::class, $prop);
+ $this->assertEquals('foo', $prop->getPrefix());
+ }
+
+ public function test_it_gets_prefixed_name()
+ {
+ $property = new Parameter([
+ 'name' => 'metadata',
+ 'prefix' => 'foo-',
+ ]);
+
+ $this->assertEquals('foo-metadata', $property->getPrefixedName());
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function test_exception_is_thrown_when_value_is_not_in_enum_list()
+ {
+ $data = $this->data;
+ $data['enum'] = ['foo'];
+
+ $param = new Parameter($data);
+ $param->validate('blah');
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Api/fixtures/headers.php b/server/vendor/php-opencloud/common/tests/unit/Common/Api/fixtures/headers.php
new file mode 100644
index 0000000..f428992
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Api/fixtures/headers.php
@@ -0,0 +1,25 @@
+<?php
+
+return [
+ 'method' => 'POST',
+ 'path' => 'something',
+ 'params' => [
+ 'name' => [
+ 'type' => 'string',
+ 'location' => 'header',
+ 'sentAs' => 'X-Foo-Name'
+ ],
+ 'age' => [
+ 'type' => 'integer',
+ 'location' => 'header'
+ ],
+ 'metadata' => [
+ 'type' => 'object',
+ 'location' => 'header',
+ 'items' => [
+ 'prefix' => 'X-Meta-'
+ ]
+ ],
+ 'other' => ['type' => 'string'] // should not be a header
+ ],
+];
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Api/fixtures/jsonBody.php b/server/vendor/php-opencloud/common/tests/unit/Common/Api/fixtures/jsonBody.php
new file mode 100644
index 0000000..350affd
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Api/fixtures/jsonBody.php
@@ -0,0 +1,27 @@
+<?php
+
+return [
+ 'method' => 'POST',
+ 'path' => 'something',
+ 'params' => [
+ 'name' => [
+ 'type' => 'string',
+ 'sentAs' => 'server_name',
+ ],
+ 'other' => [
+ 'type' => 'array',
+ 'sentAs' => 'other_params',
+ 'items' => [
+ 'type' => 'string'
+ ]
+ ],
+ 'etc' => [
+ 'type' => 'object',
+ 'sentAs' => 'etcetc',
+ 'properties' => [
+ 'dob' => ['type' => 'string'],
+ 'age' => ['type' => 'integer', 'sentAs' => 'current_age'],
+ ]
+ ],
+ ],
+];
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/ArrayAccessTraitTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/ArrayAccessTraitTest.php
new file mode 100644
index 0000000..f5d1fdb
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/ArrayAccessTraitTest.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace OpenCloud\Test\Common;
+
+use OpenCloud\Common\ArrayAccessTrait;
+use OpenCloud\Test\TestCase;
+
+class ArrayAccessTraitTest extends TestCase
+{
+ private $aa;
+
+ public function setUp()
+ {
+ $this->aa = new ArrayAccess();
+ }
+
+ public function test_offset_is_set()
+ {
+ $this->aa->offsetSet('foo', 'bar');
+ $this->assertEquals(['foo' => 'bar'], $this->aa->getElements());
+ }
+
+ public function test_it_appends_if_no_key_is_set()
+ {
+ $this->aa->offsetSet(null, 'bar');
+ $this->assertEquals(['bar'], $this->aa->getElements());
+ }
+
+ public function test_if_checks_if_offset_exists()
+ {
+ $this->aa->offsetSet('bar', 'foo');
+ $this->assertTrue($this->aa->offsetExists('bar'));
+ $this->assertFalse($this->aa->offsetExists('baz'));
+ }
+
+ public function test_if_gets_offset()
+ {
+ $this->aa->offsetSet('bar', 'foo');
+ $this->assertEquals('foo', $this->aa->offsetGet('bar'));
+ $this->assertNull($this->aa->offsetGet('baz'));
+ }
+
+ public function test_it_unsets_offset()
+ {
+ $this->aa->offsetSet('bar', 'foo');
+ $this->aa->offsetUnset('bar');
+ $this->assertNull($this->aa->offsetGet('bar'));
+ }
+}
+
+class ArrayAccess
+{
+ use ArrayAccessTrait;
+
+ public function getElements()
+ {
+ return $this->internalState;
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Auth/AuthHandlerTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Auth/AuthHandlerTest.php
new file mode 100644
index 0000000..3c77dde
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Auth/AuthHandlerTest.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace OpenCloud\Test\Common\Auth;
+
+use GuzzleHttp\Psr7\Request;
+use OpenCloud\Common\Auth\AuthHandler;
+use OpenCloud\Common\Auth\Token;
+use OpenCloud\Test\TestCase;
+use Psr\Http\Message\RequestInterface;
+
+class AuthHandlerTest extends TestCase
+{
+ const TOKEN_ID = 'tokenId';
+
+ private $generator;
+ private $handler;
+
+ public function setUp()
+ {
+ $this->generator = function () {
+ $token = $this->prophesize(FakeToken::class);
+ $token->getId()->shouldBeCalled()->willReturn(self::TOKEN_ID);
+ return $token->reveal();
+ };
+
+ $this->handler = function (RequestInterface $r) {
+ return $r;
+ };
+
+ $this->handler = new AuthHandler($this->handler, $this->generator);
+ }
+
+ public function test_it_should_bypass_auth_http_requests()
+ {
+ // Fake a Keystone request
+ $request = new Request('POST', 'https://my-openstack.org:5000/v2.0/tokens');
+
+ $this->assertEquals($request, call_user_func_array($this->handler, [$request, []]));
+ }
+
+ public function test_it_should_generate_a_new_token_if_the_current_token_is_either_expired_or_not_set()
+ {
+ $token = $this->prophesize(Token::class);
+
+ // force the mock token to indicate that its expired
+ $token->getId()->willReturn('');
+ $token->hasExpired()->willReturn(true);
+
+ $request = new Request('GET', '');
+
+ $handler = new AuthHandler($this->handler, $this->generator, $token->reveal());
+ $handler($request, []);
+ }
+}
+
+class FakeToken implements Token {
+ public function getId() {}
+ public function hasExpired() {}
+} \ No newline at end of file
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/DateTime.php b/server/vendor/php-opencloud/common/tests/unit/Common/DateTime.php
new file mode 100644
index 0000000..512ba30
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/DateTime.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace OpenCloud\Test\Common;
+
+class DateTime extends \DateTime
+{
+ public static function factory($time)
+ {
+ return new static($time);
+ }
+
+ public function toIso8601()
+ {
+ return $this->format(self::ISO8601);
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Error/BadResponseErrorTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Error/BadResponseErrorTest.php
new file mode 100644
index 0000000..7aa4bf1
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Error/BadResponseErrorTest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace OpenCloud\Test\Common\Error;
+
+use GuzzleHttp\Psr7\Request;
+use GuzzleHttp\Psr7\Response;
+use OpenCloud\Common\Error\BadResponseError;
+use OpenCloud\Test\TestCase;
+
+class BadResponseErrorTest extends TestCase
+{
+ private $e;
+
+ public function setUp()
+ {
+ $this->e = new BadResponseError();
+ }
+
+ public function test_it_gets_request()
+ {
+ $r = new Request('GET', '');
+
+ $this->e->setRequest($r);
+ $this->assertEquals($this->e->getRequest(), $r);
+ }
+
+ public function test_it_gets_response()
+ {
+ $r = new Response(500);
+
+ $this->e->setResponse($r);
+ $this->assertEquals($this->e->getResponse(), $r);
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Error/BuilderTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Error/BuilderTest.php
new file mode 100644
index 0000000..e23806d
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Error/BuilderTest.php
@@ -0,0 +1,117 @@
+<?php
+
+namespace OpenCloud\Test\Common\Error;
+
+use function GuzzleHttp\Psr7\{stream_for,str};
+
+use GuzzleHttp\ClientInterface;
+use GuzzleHttp\Exception\ClientException;
+use GuzzleHttp\Psr7\{Request,Response};
+use OpenCloud\Common\Error\{BadResponseError,Builder,UserInputError};
+
+class BuilderTest extends \PHPUnit_Framework_TestCase
+{
+ private $builder;
+ private $client;
+
+ public function __construct()
+ {
+ $this->client = $this->prophesize(ClientInterface::class);
+ $this->builder = new Builder($this->client->reveal());
+ }
+
+ public function test_it_injects_client()
+ {
+ $this->assertInstanceOf(Builder::class, new Builder($this->client->reveal()));
+ }
+
+ public function test_it_builds_http_errors()
+ {
+ $request = new Request('POST', '/servers');
+ $response = new Response(400, [], stream_for('Invalid parameters'));
+
+ $requestStr = trim($this->builder->str($request));
+ $responseStr = trim($this->builder->str($response));
+
+ $errorMessage = <<<EOT
+HTTP Error
+~~~~~~~~~~
+The remote server returned a "400 Bad Request" error for the following transaction:
+
+Request
+~~~~~~~
+$requestStr
+
+Response
+~~~~~~~~
+$responseStr
+
+Further information
+~~~~~~~~~~~~~~~~~~~
+Please ensure that your input values are valid and well-formed. Visit http://docs.php-opencloud.com/en/latest/http-codes for more information about debugging HTTP status codes, or file a support issue on https://github.com/php-opencloud/openstack/issues.
+EOT;
+
+ $e = new BadResponseError($errorMessage);
+ $e->setRequest($request);
+ $e->setResponse($response);
+
+ $this->assertEquals($e, $this->builder->httpError($request, $response));
+ }
+
+ public function test_it_builds_user_input_errors()
+ {
+ $expected = 'A well-formed string';
+ $value = ['foo' => true];
+ $link = 'http://docs.php-opencloud.com/en/latest/index.html';
+
+ $errorMessage = <<<EOT
+User Input Error
+~~~~~~~~~~~~~~~~
+A well-formed string was expected, but the following value was passed in:
+
+Array
+(
+ [foo] => 1
+)
+
+Please ensure that the value adheres to the expectation above. Visit $link for more information about input arguments. If you run into trouble, please open a support issue on https://github.com/php-opencloud/openstack/issues.
+EOT;
+
+ $this->client
+ ->request('HEAD', $link)
+ ->shouldBeCalled()
+ ->willReturn(new Response(200));
+
+ $e = new UserInputError($errorMessage);
+
+ $this->assertEquals($e, $this->builder->userInputError($expected, $value, 'index.html'));
+ }
+
+ public function test_dead_links_are_ignored()
+ {
+ $expected = 'A well-formed string';
+ $value = ['foo' => true];
+
+ $errorMessage = <<<EOT
+User Input Error
+~~~~~~~~~~~~~~~~
+A well-formed string was expected, but the following value was passed in:
+
+Array
+(
+ [foo] => 1
+)
+
+Please ensure that the value adheres to the expectation above. If you run into trouble, please open a support issue on https://github.com/php-opencloud/openstack/issues.
+EOT;
+
+ $this->client
+ ->request('HEAD', 'http://docs.php-opencloud.com/en/latest/sdffsda')
+ ->shouldBeCalled()
+ ->willThrow(ClientException::class);
+
+ $e = new UserInputError($errorMessage);
+
+ $this->assertEquals($e, $this->builder->userInputError($expected, $value, 'sdffsda'));
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/HydratorStrategyTraitTes.php b/server/vendor/php-opencloud/common/tests/unit/Common/HydratorStrategyTraitTes.php
new file mode 100644
index 0000000..6841002
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/HydratorStrategyTraitTes.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace OpenCloud\Test\Common;
+
+use OpenCloud\Common\HydratorStrategyTrait;
+use OpenCloud\Test\TestCase;
+
+class HydratorStrategyTraitTest extends TestCase
+{
+ private $fixture;
+
+ public function setUp()
+ {
+ $this->fixture = new Fixture();
+ }
+
+ public function test_it_hydrates()
+ {
+ $data = ['foo' => 1, 'bar' => 2, 'baz' => 3, 'boo' => 4];
+
+ $this->fixture->hydrate($data);
+
+ $this->assertEquals(1, $this->fixture->foo);
+ $this->assertEquals(2, $this->fixture->getBar());
+ $this->assertEquals(3, $this->fixture->getBaz());
+ }
+
+ public function test_it_hydrates_aliases()
+ {
+ $this->fixture->hydrate(['FOO!' => 1], ['FOO!' => 'foo']);
+
+ $this->assertEquals(1, $this->fixture->foo);
+ }
+}
+
+class Fixture
+{
+ public $foo;
+ protected $bar;
+ private $baz;
+
+ use HydratorStrategyTrait;
+
+ public function getBar()
+ {
+ return $this->bar;
+ }
+ public function getBaz()
+ {
+ return $this->baz;
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/JsonPathTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/JsonPathTest.php
new file mode 100644
index 0000000..1410076
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/JsonPathTest.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace OpenCloud\Test\Common;
+
+use OpenCloud\Common\JsonPath;
+
+class JsonPathTest extends \PHPUnit_Framework_TestCase
+{
+ private $jsonPath;
+
+ public function setUp()
+ {
+ $this->jsonPath = new JsonPath([]);
+ }
+
+ public function test_it_sets_values_according_to_paths()
+ {
+ $this->jsonPath->set('foo.bar.baz', 'VALUE');
+
+ $expected = [
+ 'foo' => [
+ 'bar' => [
+ 'baz' => 'VALUE',
+ ]
+ ]
+ ];
+
+ $this->assertEquals($expected, $this->jsonPath->getStructure());
+ }
+
+ public function test_it_sets_arrays_according_to_paths()
+ {
+ $jsonPath = new JsonPath([
+ 'foo' => [
+ 'bar' => [
+ 'value' => 'VALUE',
+ ]
+ ]
+ ]);
+
+ $jsonPath->set('foo.bar.items', ['item_1', 'item_2']);
+
+ $expected = [
+ 'foo' => [
+ 'bar' => [
+ 'value' => 'VALUE',
+ 'items' => ['item_1', 'item_2'],
+ ]
+ ]
+ ];
+
+ $this->assertEquals($expected, $jsonPath->getStructure());
+ }
+
+ public function test_it_gets_values_according_to_paths()
+ {
+ $jsonPath = new JsonPath([
+ 'foo' => [
+ 'bar' => [
+ 'baz' => 'VALUE_1',
+ 'lol' => 'VALUE_2',
+ ]
+ ]
+ ]);
+
+ $this->assertEquals('VALUE_1', $jsonPath->get('foo.bar.baz'));
+ $this->assertEquals('VALUE_2', $jsonPath->get('foo.bar.lol'));
+ $this->assertNull($jsonPath->get('foo.bar.boo'));
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/Fixtures/jsonPatchTests.json b/server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/Fixtures/jsonPatchTests.json
new file mode 100644
index 0000000..e7f3579
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/Fixtures/jsonPatchTests.json
@@ -0,0 +1,231 @@
+[
+ { "comment": "empty list, empty docs",
+ "doc": {},
+ "patch": [],
+ "expected": {} },
+
+ { "comment": "empty patch list",
+ "doc": {"foo": 1},
+ "patch": [],
+ "expected": {"foo": 1} },
+
+ { "comment": "rearrangements OK?",
+ "doc": {"foo": 1, "bar": 2},
+ "patch": [],
+ "expected": {"bar":2, "foo": 1} },
+
+ { "comment": "rearrangements OK? How about one level down ... array",
+ "doc": [{"foo": 1, "bar": 2}],
+ "patch": [],
+ "expected": [{"bar":2, "foo": 1}] },
+
+ { "comment": "rearrangements OK? How about one level down...",
+ "doc": {"foo":{"foo": 1, "bar": 2}},
+ "patch": [],
+ "expected": {"foo":{"bar":2, "foo": 1}} },
+
+ { "comment": "toplevel array",
+ "doc": [],
+ "patch": [{"op": "add", "path": "/0", "value": "foo"}],
+ "expected": ["foo"] },
+
+ { "comment": "toplevel array, no change",
+ "doc": ["foo"],
+ "patch": [],
+ "expected": ["foo"] },
+
+ { "comment": "toplevel object, numeric string",
+ "doc": {},
+ "patch": [{"op": "add", "path": "/foo", "value": "1"}],
+ "expected": {"foo":"1"} },
+
+ { "comment": "toplevel object, integer",
+ "doc": {},
+ "patch": [{"op": "add", "path": "/foo", "value": 1}],
+ "expected": {"foo":1} },
+
+ { "comment": "Toplevel scalar values OK?",
+ "doc": "foo",
+ "patch": [{"op": "replace", "path": "", "value": "bar"}],
+ "expected": "bar",
+ "disabled": true },
+
+ { "comment": "Add, / target",
+ "doc": {},
+ "patch": [ {"op": "add", "path": "/", "value":1 } ],
+ "expected": {"":1} },
+
+ { "comment": "Add composite value at top level",
+ "doc": {"foo": 1},
+ "patch": [{"op": "add", "path": "/bar", "value": [1, 2]}],
+ "expected": {"foo": 1, "bar": [1, 2]} },
+
+ { "comment": "Add into composite value",
+ "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
+ "patch": [{"op": "add", "path": "/baz/0/foo", "value": "world"}],
+ "expected": {"foo": 1, "baz": [{"qux": "hello", "foo": "world"}]} },
+
+ { "doc": {"bar": [1, 2]},
+ "patch": [{"op": "add", "path": "/bar/8", "value": "5"}],
+ "error": "Out of bounds (upper)" },
+
+ { "doc": {"bar": [1, 2]},
+ "patch": [{"op": "add", "path": "/bar/-1", "value": "5"}],
+ "error": "Out of bounds (lower)" },
+
+ { "doc": {"foo": 1},
+ "patch": [{"op": "add", "path": "/bar", "value": true}],
+ "expected": {"foo": 1, "bar": true} },
+
+ { "doc": {"foo": 1},
+ "patch": [{"op": "add", "path": "/bar", "value": false}],
+ "expected": {"foo": 1, "bar": false} },
+
+ { "doc": {"foo": 1},
+ "patch": [{"op": "add", "path": "/bar", "value": null}],
+ "expected": {"foo": 1, "bar": null} },
+
+ { "comment": "0 can be an array index or object element name",
+ "doc": {"foo": 1},
+ "patch": [{"op": "add", "path": "/0", "value": "bar"}],
+ "expected": {"foo": 1, "0": "bar" } },
+
+ { "doc": ["foo"],
+ "patch": [{"op": "add", "path": "/1", "value": "bar"}],
+ "expected": ["foo", "bar"] },
+
+ { "doc": ["foo", "sil"],
+ "patch": [{"op": "add", "path": "/1", "value": "bar"}],
+ "expected": ["foo", "bar", "sil"] },
+
+ { "doc": ["foo", "sil"],
+ "patch": [{"op": "add", "path": "/0", "value": "bar"}],
+ "expected": ["bar", "foo", "sil"] },
+
+ { "comment": "push item to array via last index + 1",
+ "doc": ["foo", "sil"],
+ "patch": [{"op":"add", "path": "/2", "value": "bar"}],
+ "expected": ["foo", "sil", "bar"] },
+
+ { "comment": "add item to array at index > length should fail",
+ "doc": ["foo", "sil"],
+ "patch": [{"op":"add", "path": "/3", "value": "bar"}],
+ "error": "index is greater than number of items in array" },
+
+ { "doc": ["foo", "sil"],
+ "patch": [{"op": "add", "path": "/bar", "value": 42}],
+ "error": "Object operation on array target" },
+
+ { "doc": ["foo", "sil"],
+ "patch": [{"op": "add", "path": "/1", "value": ["bar", "baz"]}],
+ "expected": ["foo", ["bar", "baz"], "sil"],
+ "comment": "value in array add not flattened" },
+
+ { "doc": {"foo": 1, "bar": [1, 2, 3, 4]},
+ "patch": [{"op": "remove", "path": "/bar"}],
+ "expected": {"foo": 1} },
+
+ { "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
+ "patch": [{"op": "remove", "path": "/baz/0/qux"}],
+ "expected": {"foo": 1, "baz": [{}]} },
+
+ { "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
+ "patch": [{"op": "replace", "path": "/foo", "value": [1, 2, 3, 4]}],
+ "expected": {"foo": [1, 2, 3, 4], "baz": [{"qux": "hello"}]} },
+
+ { "doc": {"foo": [1, 2, 3, 4], "baz": [{"qux": "hello"}]},
+ "patch": [{"op": "replace", "path": "/baz/0/qux", "value": "world"}],
+ "expected": {"foo": [1, 2, 3, 4], "baz": [{"qux": "world"}]} },
+
+ { "doc": ["foo"],
+ "patch": [{"op": "replace", "path": "/0", "value": "bar"}],
+ "expected": ["bar"] },
+
+ { "doc": [""],
+ "patch": [{"op": "replace", "path": "/0", "value": 0}],
+ "expected": [0] },
+
+ { "doc": [""],
+ "patch": [{"op": "replace", "path": "/0", "value": true}],
+ "expected": [true] },
+
+ { "doc": [""],
+ "patch": [{"op": "replace", "path": "/0", "value": false}],
+ "expected": [false] },
+
+ { "doc": [""],
+ "patch": [{"op": "replace", "path": "/0", "value": null}],
+ "expected": [null] },
+
+ { "doc": ["foo", "sil"],
+ "patch": [{"op": "replace", "path": "/1", "value": ["bar", "baz"]}],
+ "expected": ["foo", ["bar", "baz"]],
+ "comment": "value in array replace not flattened" },
+
+ { "comment": "replace whole document",
+ "disabled": true,
+ "doc": {"foo": "bar"},
+ "patch": [{"op": "replace", "path": "", "value": {"baz": "qux"}}],
+ "expected": {"baz": "qux"} },
+
+ { "doc": {"foo": null},
+ "patch": [{"op": "replace", "path": "/foo", "value": "truthy"}],
+ "expected": {"foo": "truthy"},
+ "comment": "null value should be valid obj property to be replaced with something truthy" },
+
+ { "doc": {"foo": null},
+ "patch": [{"op": "remove", "path": "/foo"}],
+ "expected": {},
+ "comment": "null value should be valid obj property to be removed" },
+
+ { "doc": {"foo": "bar"},
+ "patch": [{"op": "replace", "path": "/foo", "value": null}],
+ "expected": {"foo": null},
+ "comment": "null value should still be valid obj property replace other value" },
+
+ { "comment": "test remove with bad number should fail",
+ "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
+ "patch": [{"op": "remove", "path": "/baz/1e0/qux"}],
+ "error": "remove op shouldn't remove from array with bad number" },
+
+ { "comment": "test remove on array",
+ "doc": [1, 2, 3, 4],
+ "patch": [{"op": "remove", "path": "/0"}],
+ "expected": [2, 3, 4] },
+
+ { "comment": "test repeated removes",
+ "doc": [1, 2, 3, 4],
+ "patch": [{ "op": "remove", "path": "/1" },
+ { "op": "remove", "path": "/3" }],
+ "expected": [1, 3] },
+
+ { "comment": "test remove with bad index should fail",
+ "doc": [1, 2, 3, 4],
+ "patch": [{"op": "remove", "path": "/1e0"}],
+ "error": "remove op shouldn't remove from array with bad number" },
+
+ { "comment": "test replace with bad number should fail",
+ "doc": [""],
+ "patch": [{"op": "replace", "path": "/1e0", "value": false}],
+ "error": "replace op shouldn't replace in array with bad number" },
+
+ { "comment": "test add with bad number should fail",
+ "doc": ["foo", "sil"],
+ "patch": [{"op": "add", "path": "/1e0", "value": "bar"}],
+ "error": "add op shouldn't add to array with bad number" },
+
+ { "comment": "missing 'value' parameter to add",
+ "doc": [ 1 ],
+ "patch": [ { "op": "add", "path": "/-" } ],
+ "error": "missing 'value' parameter" },
+
+ { "comment": "missing 'value' parameter to replace",
+ "doc": [ 1 ],
+ "patch": [ { "op": "replace", "path": "/0" } ],
+ "error": "missing 'value' parameter" },
+
+ { "comment": "unrecognized op should fail",
+ "doc": {"foo": 1},
+ "patch": [{"op": "spam", "path": "/foo", "value": 1}],
+ "error": "Unrecognized op 'spam'" }
+] \ No newline at end of file
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/JsonPatchTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/JsonPatchTest.php
new file mode 100644
index 0000000..ee7db9e
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/JsonPatchTest.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace OpenCloud\Test\Common\JsonSchema;
+
+use OpenCloud\Common\JsonSchema\JsonPatch;
+use OpenCloud\Test\TestCase;
+
+class JsonPatchTest extends TestCase
+{
+ public function testAll()
+ {
+ $fixtures = json_decode(file_get_contents(__DIR__ . '/Fixtures/jsonPatchTests.json'));
+
+ foreach ($fixtures as $fixture) {
+ if (isset($fixture->disabled) || !isset($fixture->expected)) {
+ continue;
+ }
+
+ $actual = JsonPatch::diff($fixture->doc, $fixture->expected);
+
+ $this->assertEquals(
+ json_encode($fixture->patch, JSON_UNESCAPED_SLASHES),
+ json_encode($actual, JSON_UNESCAPED_SLASHES),
+ isset($fixture->comment) ? sprintf("Failed asserting test: %s\n", $fixture->comment) : ''
+ );
+ }
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/SchemaTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/SchemaTest.php
new file mode 100644
index 0000000..22663ef
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/JsonSchema/SchemaTest.php
@@ -0,0 +1,102 @@
+<?php
+
+namespace OpenCloud\Test\Common\JsonSchema;
+
+use JsonSchema\Validator;
+use OpenCloud\Common\JsonSchema\Schema;
+use OpenCloud\Test\TestCase;
+
+class SchemaTest extends TestCase
+{
+ /** @var Schema */
+ private $schema;
+
+ /** @var Validator */
+ private $validator;
+ private $body;
+
+ public function setUp()
+ {
+ $this->body = [
+ 'properties' => [
+ 'foo' => (object)[],
+ 'bar' => (object)[],
+ 'baz' => (object)['readOnly' => true],
+ ],
+ ];
+
+ $this->validator = $this->prophesize(Validator::class);
+ $this->schema = new Schema($this->body, $this->validator->reveal());
+ }
+
+ public function test_it_gets_errors()
+ {
+ $this->validator->getErrors()
+ ->shouldBeCalled()
+ ->willReturn([]);
+
+ $this->assertEquals([], $this->schema->getErrors());
+ }
+
+ public function test_it_gets_error_string()
+ {
+ $this->validator->getErrors()
+ ->shouldBeCalled()
+ ->willReturn([['property' => 'foo', 'message' => 'bar']]);
+
+ $errorMsg = sprintf("Provided values do not validate. Errors:\n[foo] bar\n");
+
+ $this->assertEquals($errorMsg, $this->schema->getErrorString());
+ }
+
+ public function test_it_gets_property_paths()
+ {
+ $this->assertEquals(['/foo', '/bar', '/baz'], $this->schema->getPropertyPaths());
+ }
+
+ public function test_it_ignores_readOnly_attrs()
+ {
+ $expected = (object)[
+ 'foo' => true,
+ 'bar' => false,
+ ];
+
+ $subject = (object)[
+ 'foo' => true,
+ 'bar' => false,
+ 'baz' => true,
+ ];
+
+ $this->assertEquals((object)$expected, $this->schema->normalizeObject((object)$subject, []));
+ }
+
+ public function test_it_stocks_aliases()
+ {
+ $subject = (object)[
+ 'fooAlias' => true,
+ 'bar' => false,
+ 'other' => true,
+ ];
+
+ $expected = (object)[
+ 'foo' => true,
+ 'bar' => false,
+ ];
+
+ $this->assertEquals($expected, $this->schema->normalizeObject($subject, ['foo' => 'fooAlias', 'bar' => 'lol']));
+ }
+
+ public function test_it_validates()
+ {
+ $this->validator->check([], (object) $this->body)->shouldBeCalled();
+
+ $this->schema->validate([]);
+ }
+
+ public function test_it_checks_validity()
+ {
+ $this->validator->isValid()->shouldBeCalled();
+
+ $this->schema->isValid();
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Resource/AbstractResourceTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Resource/AbstractResourceTest.php
new file mode 100644
index 0000000..f334292
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Resource/AbstractResourceTest.php
@@ -0,0 +1,161 @@
+<?php
+
+namespace OpenCloud\Test\Common\Resource;
+
+use function GuzzleHttp\Psr7\stream_for;
+use GuzzleHttp\Psr7\Response;
+use OpenCloud\Common\Resource\AbstractResource;
+use OpenCloud\Common\Resource\Generator;
+use OpenCloud\Test\Fixtures\ComputeV2Api;
+use OpenCloud\Test\TestCase;
+use Prophecy\Argument;
+
+class AbstractResourceTest extends TestCase
+{
+ private $resource;
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->rootFixturesDir = __DIR__;
+ $this->resource = new TestResource($this->client->reveal(), new ComputeV2Api());
+ }
+
+ public function test_it_populates_from_response()
+ {
+ $response = new Response(200, ['Content-Type' => 'application/json'], stream_for(
+ json_encode(['foo' => ['bar' => '1']])
+ ));
+
+ $this->resource->populateFromResponse($response);
+
+ $this->assertEquals('1', $this->resource->bar);
+ }
+
+ public function test_it_populates_datetimes_from_arrays()
+ {
+ $dt = new \DateTimeImmutable('2015');
+
+ $this->resource->populateFromArray(['created' => '2015']);
+
+ $this->assertEquals($this->resource->created, $dt);
+ }
+
+ public function test_it_populates_arrays_from_arrays()
+ {
+ $this->resource->populateFromArray(['children' => [$this->resource, $this->resource]]);
+
+ $this->assertInstanceOf(TestResource::class, $this->resource->children[0]);
+ }
+
+ public function test_it_gets_attrs()
+ {
+ $this->resource->bar = 'foo';
+
+ $this->assertEquals(['bar' => 'foo'], $this->resource->getAttrs(['bar']));
+ }
+
+ public function test_it_executes_with_state()
+ {
+ $this->resource->id = 'foo';
+ $this->resource->bar = 'bar';
+
+ $expectedJson = ['id' => 'foo', 'bar' => 'bar'];
+
+ $this->setupMock('GET', 'foo', $expectedJson, [], new Response(204));
+
+ $this->resource->executeWithState((new ComputeV2Api())->test());
+ }
+
+ public function test_it_executes_operations_until_a_204_is_received()
+ {
+ $this->client
+ ->request('GET', 'servers', ['headers' => []])
+ ->shouldBeCalled()
+ ->willReturn($this->getFixture('servers-page1'));
+
+ $this->client
+ ->request('GET', 'servers', ['query' => ['marker' => '5'], 'headers' => []])
+ ->shouldBeCalled()
+ ->willReturn(new Response(204));
+
+ $count = 0;
+
+ $api = new ComputeV2Api();
+
+ foreach ($this->resource->enumerate($api->getServers()) as $item) {
+ $count++;
+ $this->assertInstanceOf(TestResource::class, $item);
+ }
+
+ $this->assertEquals(5, $count);
+ }
+
+ public function test_it_invokes_function_if_provided()
+ {
+ $this->client
+ ->request('GET', 'servers', ['headers' => []])
+ ->shouldBeCalled()
+ ->willReturn($this->getFixture('servers-page1'));
+
+ $this->client
+ ->request('GET', 'servers', ['query' => ['marker' => '5'], 'headers' => []])
+ ->shouldBeCalled()
+ ->willReturn(new Response(204));
+
+ $api = new ComputeV2Api();
+
+ $count = 0;
+
+ $fn = function () use (&$count) {
+ $count++;
+ };
+
+ foreach ($this->resource->enumerate($api->getServers(), [], $fn) as $item) {
+ }
+
+ $this->assertEquals(5, $count);
+ }
+
+ public function test_it_halts_when_user_provided_limit_is_reached()
+ {
+ $this->client
+ ->request('GET', 'servers', ['query' => ['limit' => 2], 'headers' => []])
+ ->shouldBeCalled()
+ ->willReturn($this->getFixture('servers-page1'));
+
+ $count = 0;
+
+ $api = new ComputeV2Api();
+
+ foreach ($this->resource->enumerate($api->getServers(), ['limit' => 2]) as $item) {
+ $count++;
+ }
+
+ $this->assertEquals(2, $count);
+ }
+}
+
+class TestResource extends AbstractResource
+{
+ protected $resourceKey = 'foo';
+ protected $resourcesKey = 'servers';
+ protected $markerKey = 'id';
+
+ /** @var string */
+ public $bar;
+
+ public $id;
+
+ /** @var \DateTimeImmutable */
+ public $created;
+
+ /** @var []TestResource */
+ public $children;
+
+ public function getAttrs(array $keys)
+ {
+ return parent::getAttrs($keys);
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-empty.resp b/server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-empty.resp
new file mode 100644
index 0000000..655a35b
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-empty.resp
@@ -0,0 +1,6 @@
+HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+ "servers": []
+} \ No newline at end of file
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-page1.resp b/server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-page1.resp
new file mode 100644
index 0000000..adebcaf
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-page1.resp
@@ -0,0 +1,77 @@
+HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+ "servers": [
+ {
+ "id": "1",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server1"
+ },
+ {
+ "id": "2",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server2"
+ },
+ {
+ "id": "3",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server3"
+ },
+ {
+ "id": "4",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server4"
+ },
+ {
+ "id": "5",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server5"
+ }
+ ]
+} \ No newline at end of file
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-page2.resp b/server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-page2.resp
new file mode 100644
index 0000000..6be6b04
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Resource/Fixtures/servers-page2.resp
@@ -0,0 +1,77 @@
+HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+ "servers": [
+ {
+ "id": "6",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server6"
+ },
+ {
+ "id": "7",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server7"
+ },
+ {
+ "id": "8",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server8"
+ },
+ {
+ "id": "9",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server9"
+ },
+ {
+ "id": "10",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": "server10"
+ }
+ ]
+} \ No newline at end of file
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Service/BuilderTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Service/BuilderTest.php
new file mode 100644
index 0000000..09e9918
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Service/BuilderTest.php
@@ -0,0 +1,164 @@
+<?php
+
+namespace OpenCloud\Test\Common\Service;
+
+use GuzzleHttp\ClientInterface;
+use OpenCloud\Common\Service\Builder;
+use OpenCloud\Identity\v2\Models\Token;
+use OpenCloud\Identity\v2\Service as IdentityV2;
+use OpenCloud\Identity\v3\Service as IdentityV3;
+use OpenCloud\Compute\v2\Service as ComputeV2;
+use OpenCloud\Test\Common\Auth\FakeToken;
+use OpenCloud\Test\TestCase;
+use Prophecy\Argument;
+
+class BuilderTest extends TestCase
+{
+ private $builder;
+ private $opts;
+
+ public function setUp()
+ {
+ $this->builder = new Builder([]);
+
+ $this->opts = [
+ 'username' => '1',
+ 'password' => '2',
+ 'tenantId' => '3',
+ 'authUrl' => '4',
+ 'region' => '5',
+ 'catalogName' => '6',
+ 'catalogType' => '7',
+ ];
+ }
+
+ /**
+ * @expectedException \Exception
+ */
+ public function test_it_throws_exception_if_username_is_missing()
+ {
+ $this->builder->createService('Compute', 2, []);
+ }
+
+ /**
+ * @expectedException \Throwable
+ */
+ public function test_it_throws_exception_if_password_is_missing()
+ {
+ $this->builder->createService('Compute', 2, ['username' => 1]);
+ }
+
+ /**
+ * @expectedException \Throwable
+ */
+ public function test_it_throws_exception_if_both_tenantId_and_tenantName_is_missing()
+ {
+ $this->builder->createService('Compute', 2, [
+ 'username' => 1, 'password' => 2, 'authUrl' => 4, 'region' => 5, 'catalogName' => 6, 'catalogType' => 7,
+ ]);
+ }
+
+ /**
+ * @expectedException \Throwable
+ */
+ public function test_it_throws_exception_if_authUrl_is_missing()
+ {
+ $this->builder->createService('Compute', 2, ['username' => 1, 'password' => 2, 'tenantId' => 3]);
+ }
+
+ /**
+ * @expectedException \Throwable
+ */
+ public function test_it_throws_exception_if_region_is_missing()
+ {
+ $this->builder->createService('Compute', 2, [
+ 'username' => 1, 'password' => 2, 'tenantId' => 3, 'authUrl' => 4,
+ ]);
+ }
+
+ /**
+ * @expectedException \Throwable
+ */
+ public function test_it_throws_exception_if_catalogName_is_missing()
+ {
+ $this->builder->createService('Compute', 2, [
+ 'username' => 1, 'password' => 2, 'tenantId' => 3, 'authUrl' => 4,
+ ]);
+ }
+
+ /**
+ * @expectedException \Throwable
+ */
+ public function test_it_throws_exception_if_catalogType_is_missing()
+ {
+ $this->builder->createService('Compute', 2, [
+ 'username' => 1, 'password' => 2, 'tenantId' => 3, 'authUrl' => 4, 'region' => 5, 'catalogName' => 6,
+ ]);
+ }
+
+// public function test_it_builds_services_with_custom_identity_service()
+// {
+// $this->rootFixturesDir = dirname(dirname(__DIR__)) . '/Identity/v2/';
+//
+// $token = $this->prophesize(FakeToken::class)->reveal();
+// $service = $this->prophesize(IdentityService::class);
+// $service->authenticate(Argument::type('array'))->shouldBeCalled()->willReturn([$token, '']);
+//
+// $this->opts += [
+// 'identityService' => $service->reveal(),
+// 'catalogName' => 'nova',
+// 'catalogType' => 'compute',
+// 'region' => 'RegionOne',
+// ];
+//
+// $service = $this->builder->createService('Compute', 2, $this->opts);
+// $this->assertInstanceOf(ComputeV2::class, $service);
+// }
+
+ private function setupHttpClient()
+ {
+ $this->rootFixturesDir = dirname(dirname(__DIR__)) . '/Identity/v3/';
+
+ $response = $this->getFixture('token-get');
+
+ $expectedJson = [
+ 'auth' => [
+ 'identity' => [
+ 'methods' => ['password'],
+ 'password' => ['user' => ['id' => '0ca8f6', 'password' => 'secretsecret']]
+ ]
+ ]
+ ];
+
+ $httpClient = $this->prophesize(ClientInterface::class);
+ $httpClient->request('POST', 'tokens', ['json' => $expectedJson])->shouldBeCalled()->willReturn($response);
+
+ return $httpClient;
+ }
+
+ public function it_builds_services_with_default_identity()
+ {
+ $httpClient = $this->setupHttpClient();
+
+ $options = [
+ 'httpClient' => $httpClient->reveal(),
+ 'catalogName' => 'nova',
+ 'catalogType' => 'compute',
+ 'region' => 'RegionOne',
+ 'user' => [
+ 'id' => '0ca8f6',
+ 'password' => 'secretsecret',
+ ]
+ ];
+
+ $service = $this->builder->createService('Compute', 2, $options);
+ $this->assertInstanceOf(ComputeV2::class, $service);
+ }
+
+// public function test_it_does_not_authenticate_when_creating_identity_services()
+// {
+// $this->assertInstanceOf(IdentityV3::class, $this->builder->createService('Identity', 3, [
+// 'authUrl' => 'foo.com',
+// ]));
+// }
+} \ No newline at end of file
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Transport/HandlerStackTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/HandlerStackTest.php
new file mode 100644
index 0000000..ec1cf85
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/HandlerStackTest.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace OpenCloud\Test\Common\Transport;
+
+use GuzzleHttp\Handler\MockHandler;
+use OpenCloud\Common\Transport\HandlerStack;
+use OpenCloud\Test\TestCase;
+
+class HandlerStackTest extends TestCase
+{
+ public function test_it_is_created()
+ {
+ $this->assertInstanceOf(HandlerStack::class, HandlerStack::create(new MockHandler()));
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Transport/JsonSerializerTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/JsonSerializerTest.php
new file mode 100644
index 0000000..9075594
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/JsonSerializerTest.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace OpenCloud\Test\Common\Transport;
+
+use OpenCloud\Common\Api\Parameter;
+use OpenCloud\Common\Transport\JsonSerializer;
+
+class JsonSerializerTest extends \PHPUnit_Framework_TestCase
+{
+ private $serializer;
+
+ public function setUp()
+ {
+ $this->serializer = new JsonSerializer();
+ }
+
+ public function test_it_embeds_params_according_to_path()
+ {
+ $param = $this->prophesize(Parameter::class);
+ $param->isArray()->shouldBeCalled()->willReturn(false);
+ $param->isObject()->shouldBeCalled()->willReturn(false);
+ $param->getName()->shouldBeCalled()->willReturn('username');
+ $param->getPath()->shouldBeCalled()->willReturn('auth.passwordCredentials');
+
+ $userValue = 'fooBar';
+
+ $expected = [
+ 'auth' => [
+ 'passwordCredentials' => [
+ 'username' => $userValue,
+ ],
+ ],
+ ];
+
+ $actual = $this->serializer->stockJson($param->reveal(), $userValue, []);
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function test_it_serializes_arrays()
+ {
+ $param = $this->prophesize(Parameter::class);
+ $param->isArray()->shouldBeCalled()->willReturn(true);
+ $param->getName()->shouldBeCalled()->willReturn('fooBar');
+ $param->getPath()->shouldBeCalled()->willReturn(false);
+
+ $itemSchema = $this->prophesize(Parameter::class);
+ $itemSchema->isArray()->shouldBeCalled()->willReturn(false);
+ $itemSchema->isObject()->shouldBeCalled()->willReturn(false);
+ $itemSchema->getName()->shouldBeCalled()->willReturn(null);
+ $itemSchema->getPath()->shouldBeCalled()->willReturn(null);
+
+ $param->getItemSchema()->shouldBeCalled()->willReturn($itemSchema);
+
+ $userValues = ['1', '2', '3'];
+
+ $expected = ['fooBar' => $userValues];
+
+ $actual = $this->serializer->stockJson($param->reveal(), $userValues, []);
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function test_it_serializes_objects()
+ {
+ $prop = $this->prophesize(Parameter::class);
+ $prop->isArray()->shouldBeCalled()->willReturn(false);
+ $prop->isObject()->shouldBeCalled()->willReturn(false);
+ $prop->getName()->shouldBeCalled()->willReturn('foo');
+ $prop->getPath()->shouldBeCalled()->willReturn(null);
+
+ $param = $this->prophesize(Parameter::class);
+ $param->isArray()->shouldBeCalled()->willReturn(false);
+ $param->isObject()->shouldBeCalled()->willReturn(true);
+ $param->getName()->shouldBeCalled()->willReturn('topLevel');
+ $param->getPath()->shouldBeCalled()->willReturn(false);
+ $param->getProperty('foo')->shouldBeCalled()->willReturn($prop);
+
+ $expected = ['topLevel' => ['foo' => true]];
+
+ $json = $this->serializer->stockJson($param->reveal(), ['foo' => true], []);
+
+ $this->assertEquals($expected, $json);
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Transport/MiddlewareTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/MiddlewareTest.php
new file mode 100644
index 0000000..c445783
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/MiddlewareTest.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace unit\Common\Transport;
+
+use GuzzleHttp\Handler\MockHandler;
+use GuzzleHttp\Psr7\Request;
+use GuzzleHttp\Psr7\Response;
+use OpenCloud\Common\Transport\Middleware;
+use OpenCloud\Test\TestCase;
+use OpenCloud\Common\Auth\AuthHandler;
+
+class MiddlewareTest extends TestCase
+{
+ /**
+ * @expectedException \OpenCloud\Common\Error\BadResponseError
+ */
+ public function test_exception_is_thrown_for_4xx_statuses()
+ {
+ $middleware = Middleware::httpErrors();
+
+ $handler = new MockHandler([new Response(404)]);
+ $fn = $middleware($handler);
+
+ $promise = $fn(new Request('GET', 'http://foo.com'), []);
+ $this->assertEquals('pending', $promise->getState());
+
+ $promise->wait();
+ $this->assertEquals('rejected', $promise->getState());
+ }
+
+ public function test_responses_are_left_alone_when_status_under_400()
+ {
+ $middleware = Middleware::httpErrors();
+
+ $response = new Response(204);
+ $handler = new MockHandler([$response]);
+ $fn = $middleware($handler);
+
+ $promise = $fn(new Request('GET', 'http://foo.com'), []);
+
+ $promise->then(function ($val) use ($response) {
+ $this->assertEquals($val, $response);
+ });
+
+ $promise->wait();
+ }
+
+ public function test_auth_handler_is_returned()
+ {
+ $generator = function () {};
+
+ $middleware = Middleware::authHandler($generator);
+
+ $handler = new MockHandler([new Response(204)]);
+ $fn = $middleware($handler);
+
+ $this->assertInstanceOf(AuthHandler::class, $fn);
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Transport/RequestSerializerTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/RequestSerializerTest.php
new file mode 100644
index 0000000..cf06220
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/RequestSerializerTest.php
@@ -0,0 +1,112 @@
+<?php
+
+namespace OpenCloud\Test\Common\Transport;
+
+use OpenCloud\Common\Api\Operation;
+use OpenCloud\Common\Api\Parameter;
+use OpenCloud\Common\Transport\JsonSerializer;
+use OpenCloud\Common\Transport\RequestSerializer;
+use OpenCloud\Test\TestCase;
+
+class RequestSerializerTest extends TestCase
+{
+ private $rs;
+ private $js;
+
+ public function setUp()
+ {
+ $this->js = $this->prophesize(JsonSerializer::class);
+
+ $this->rs = new RequestSerializer($this->js->reveal());
+ }
+
+ public function test_it_ignores_undefined_params()
+ {
+ $op = $this->prophesize(Operation::class);
+ $op->getParam('foo')->shouldBeCalled()->willReturn(null);
+
+ $this->assertEquals(['headers' => []], $this->rs->serializeOptions($op->reveal(), ['foo' => 'bar']));
+ }
+
+ public function test_it_serializes_queries()
+ {
+ $sch = $this->prophesize(Parameter::class);
+ $sch->getName()->shouldBeCalled()->willReturn('fooAlias');
+ $sch->getLocation()->shouldBeCalled()->willReturn('query');
+
+ $op = $this->prophesize(Operation::class);
+ $op->getParam('foo')->shouldBeCalled()->willReturn($sch);
+
+ $actual = $this->rs->serializeOptions($op->reveal(), ['foo' => 'bar']);
+ $expected = ['query' => ['fooAlias' => 'bar'], 'headers' => []];
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function test_it_serializes_headers()
+ {
+ $sch = $this->prophesize(Parameter::class);
+ $sch->getLocation()->shouldBeCalled()->willReturn('header');
+ $sch->getName()->shouldBeCalled()->willReturn('fooAlias');
+ $sch->getPrefixedName()->shouldBeCalled()->willReturn('prefix-fooAlias');
+
+ $op = $this->prophesize(Operation::class);
+ $op->getParam('foo')->shouldBeCalled()->willReturn($sch);
+
+ $actual = $this->rs->serializeOptions($op->reveal(), ['foo' => 'bar']);
+ $expected = ['headers' => ['prefix-fooAlias' => 'bar']];
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function test_it_serializes_metadata_headers()
+ {
+ $itemSch = $this->prophesize(Parameter::class);
+ $itemSch->getName()->shouldBeCalled()->willReturn('foo');
+ $itemSch->getPrefixedName()->shouldBeCalled()->willReturn('prefix-foo');
+
+ $sch = $this->prophesize(Parameter::class);
+ $sch->getItemSchema()->shouldBeCalled()->willReturn($itemSch);
+ $sch->getLocation()->shouldBeCalled()->willReturn('header');
+ $sch->getName()->shouldBeCalled()->willReturn('metadata');
+
+ $op = $this->prophesize(Operation::class);
+ $op->getParam('metadata')->shouldBeCalled()->willReturn($sch);
+
+ $actual = $this->rs->serializeOptions($op->reveal(), ['metadata' => ['foo' => 'bar']]);
+ $expected = ['headers' => ['prefix-foo' => 'bar']];
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function test_it_serializes_json()
+ {
+ $sch = $this->prophesize(Parameter::class);
+ $sch->getLocation()->shouldBeCalled()->willReturn('json');
+
+ $op = $this->prophesize(Operation::class);
+ $op->getParam('foo')->shouldBeCalled()->willReturn($sch);
+ $op->getJsonKey()->shouldBeCalled()->willReturn('jsonKey');
+
+ $this->js->stockJson($sch, 'bar', [])->shouldBeCalled()->willReturn(['foo' => 'bar']);
+
+ $actual = $this->rs->serializeOptions($op->reveal(), ['foo' => 'bar']);
+ $expected = ['json' => ['jsonKey' => ['foo' => 'bar']], 'headers' => []];
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function test_it_serializes_raw_vals()
+ {
+ $sch = $this->prophesize(Parameter::class);
+ $sch->getLocation()->shouldBeCalled()->willReturn('raw');
+
+ $op = $this->prophesize(Operation::class);
+ $op->getParam('foo')->shouldBeCalled()->willReturn($sch);
+
+ $actual = $this->rs->serializeOptions($op->reveal(), ['foo' => 'bar']);
+ $expected = ['body' => 'bar', 'headers' => []];
+
+ $this->assertEquals($expected, $actual);
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Common/Transport/UtilsTest.php b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/UtilsTest.php
new file mode 100644
index 0000000..3103ad4
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Common/Transport/UtilsTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace OpenCloud\Test\Common\Transport;
+
+use GuzzleHttp\Psr7\Response;
+use function GuzzleHttp\Psr7\uri_for;
+use GuzzleHttp\Psr7\Uri;
+use OpenCloud\Common\Transport\Utils;
+use OpenCloud\Test\TestCase;
+
+class UtilsTest extends TestCase
+{
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function test_decoding_malformed_json_throws_error()
+ {
+ $response = new Response(200, [], \GuzzleHttp\Psr7\stream_for('{'));
+
+ Utils::jsonDecode($response);
+ }
+
+ public function test_it_adds_paths()
+ {
+ $uri = Utils::addPaths(uri_for('http://openstack.org/foo'), 'bar', 'baz', '1', '2');
+
+ $this->assertInstanceOf(Uri::class, $uri);
+ $this->assertEquals(uri_for('http://openstack.org/foo/bar/baz/1/2'), $uri);
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Fixtures/ComputeV2Api.php b/server/vendor/php-opencloud/common/tests/unit/Fixtures/ComputeV2Api.php
new file mode 100644
index 0000000..d395d10
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Fixtures/ComputeV2Api.php
@@ -0,0 +1,107 @@
+<?php
+
+namespace OpenCloud\Test\Fixtures;
+
+use OpenCloud\Common\Api\ApiInterface;
+
+class ComputeV2Api implements ApiInterface
+{
+ private $idParam = ['type' => 'string', 'required' => true, 'location' => 'url'];
+
+ public function getImage()
+ {
+ return [
+ 'method' => 'GET',
+ 'path' => 'images/{id}',
+ 'params' => [self::$idParam]
+ ];
+ }
+
+ public function postServer()
+ {
+ return [
+ 'path' => 'servers',
+ 'method' => 'POST',
+ 'jsonKey' => 'server',
+ 'params' => [
+ 'removeMetadata' => [
+ 'type' => 'object',
+ 'properties' => ['type' => 'string'],
+ ],
+ 'securityGroups' => [
+ 'type' => 'array',
+ 'items' => [
+ 'type' => 'object',
+ 'properties' => [
+ 'name' => ['type' => 'string']
+ ]
+ ],
+ 'sentAs' => 'security_groups',
+ ],
+ 'userData' => ['type' => 'string', 'sentAs' => 'user_data'],
+ 'availabilityZone' => ['type' => 'string', 'sentAs' => 'availability_zone'],
+ 'imageId' => ['type' => 'string', 'required' => true, 'sentAs' => 'imageRef'],
+ 'flavorId' => ['type' => 'string', 'required' => true, 'sentAs' => 'flavorRef'],
+ 'networks' => [
+ 'type' => 'array',
+ 'items' => [
+ 'type' => 'object',
+ 'properties' => [
+ 'uuid' => ['type' => 'string'],
+ 'port' => ['type' => 'string'],
+ ]
+ ]
+ ],
+ 'name' => ['type' => 'string', 'required' => true],
+ 'metadata' => ['type' => 'object', 'location' => 'json'],
+ 'personality' => ['type' => 'string'],
+ 'blockDeviceMapping' => [
+ 'type' => 'array',
+ 'sentAs' => 'block_device_mapping_v2',
+ 'items' => [
+ 'type' => 'object',
+ 'properties' => [
+ 'configDrive' => ['type' => 'string', 'sentAs' => 'config_drive'],
+ 'bootIndex' => ['type' => 'string', 'sentAs' => 'boot_index'],
+ 'deleteOnTermination' => ['type' => 'boolean', 'sentAs' => 'delete_on_termination'],
+ 'guestFormat' => ['type' => 'string', 'sentAs' => 'guest_format'],
+ 'destinationType' => ['type' => 'string', 'sentAs' => 'destination_type'],
+ 'sourceType' => ['type' => 'string', 'sentAs' => 'source_type'],
+ 'deviceName' => ['type' => 'string', 'sentAs' => 'device_name'],
+ ]
+ ],
+ ],
+ ]
+ ];
+ }
+
+ public function test()
+ {
+ return [
+ 'method' => 'GET',
+ 'path' => 'foo',
+ 'params' => [
+ 'id' => ['type' => 'string', 'location' => 'json'],
+ 'bar' => ['type' => 'string', 'location' => 'json'],
+ ]
+ ];
+ }
+
+ public function getServers()
+ {
+ return [
+ 'method' => 'GET',
+ 'path' => 'servers',
+ 'params' => [
+ 'changesSince' => ['sentAs' => 'changes-since', 'type' => 'string', 'location' => 'query'],
+ 'imageId' => ['sentAs' => 'image', 'type' => 'string', 'location' => 'query'],
+ 'flavorId' => ['sentAs' => 'flavor', 'type' => 'string', 'location' => 'query'],
+ 'name' => ['type' => 'string', 'location' => 'query'],
+ 'marker' => ['type' => 'string', 'location' => 'query'],
+ 'limit' => ['type' => 'integer', 'location' => 'query'],
+ 'status' => ['type' => 'string', 'location' => 'query'],
+ 'host' => ['type' => 'string', 'location' => 'query']
+ ],
+ ];
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Fixtures/IdentityV2Api.php b/server/vendor/php-opencloud/common/tests/unit/Fixtures/IdentityV2Api.php
new file mode 100644
index 0000000..4cc66b5
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Fixtures/IdentityV2Api.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace OpenCloud\Test\Fixtures;
+
+use OpenCloud\Common\Api\ApiInterface;
+
+class IdentityV2Api implements ApiInterface
+{
+ public function postToken()
+ {
+ return [
+ 'method' => 'POST',
+ 'path' => 'tokens',
+ 'params' => [
+ 'username' => [
+ 'type' => 'string',
+ 'required' => true,
+ 'path' => 'auth.passwordCredentials'
+ ],
+ 'password' => [
+ 'type' => 'string',
+ 'required' => true,
+ 'path' => 'auth.passwordCredentials'
+ ],
+ 'tenantId' => [
+ 'type' => 'string',
+ 'path' => 'auth',
+ ],
+ 'tenantName' => [
+ 'type' => 'string',
+ 'path' => 'auth',
+ ]
+ ],
+ ];
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/Fixtures/IdentityV3Api.php b/server/vendor/php-opencloud/common/tests/unit/Fixtures/IdentityV3Api.php
new file mode 100644
index 0000000..2fc922f
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/Fixtures/IdentityV3Api.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace OpenCloud\Test\Fixtures;
+
+class IdentityV3Api
+{
+ private function domainParam()
+ {
+ return [
+ 'type' => 'object',
+ 'params' => [
+ 'id' => ['type' => 'string'],
+ 'name' => ['type' => 'string']
+ ]
+ ];
+ }
+
+ private function projectParam()
+ {
+ return [
+ 'type' => 'object',
+ 'params' => [
+ 'id' => ['type' => 'string'],
+ 'name' => ['type' => 'string'],
+ 'domain' => $this->domainParam(),
+ ]
+ ];
+ }
+
+ public function postTokens()
+ {
+ return [
+ 'method' => 'POST',
+ 'path' => 'tokens',
+ 'params' => [
+ 'methods' => [
+ 'type' => 'array',
+ 'path' => 'auth.identity',
+ 'items' => [
+ 'type' => 'string'
+ ]
+ ],
+ 'user' => [
+ 'path' => 'auth.identity.password',
+ 'type' => 'object',
+ 'properties' => [
+ 'id' => [
+ 'type' => 'string',
+ ],
+ 'name' => [
+ 'type' => 'string',
+ ],
+ 'password' => [
+ 'type' => 'string',
+ ],
+ 'domain' => $this->domainParam()
+ ]
+ ],
+ 'tokenId' => [
+ 'type' => 'string',
+ 'path' => 'auth.identity.token',
+ 'sentAs' => 'id',
+ ],
+ 'scope' => [
+ 'type' => 'object',
+ 'path' => 'auth',
+ 'properties' => [
+ 'project' => $this->projectParam(),
+ 'domain' => $this->domainParam()
+ ]
+ ]
+ ]
+ ];
+ }
+}
diff --git a/server/vendor/php-opencloud/common/tests/unit/TestCase.php b/server/vendor/php-opencloud/common/tests/unit/TestCase.php
new file mode 100644
index 0000000..610d88a
--- /dev/null
+++ b/server/vendor/php-opencloud/common/tests/unit/TestCase.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace OpenCloud\Test;
+
+use function GuzzleHttp\Psr7\stream_for;
+use function GuzzleHttp\Psr7\parse_response;
+use GuzzleHttp\ClientInterface;
+use GuzzleHttp\Psr7\Response;
+use Prophecy\Argument;
+
+abstract class TestCase extends \PHPUnit_Framework_TestCase
+{
+ /** @var \Prophecy\Prophecy\ObjectProphecy */
+ protected $client;
+
+ /** @var string */
+ protected $rootFixturesDir;
+
+ protected $api;
+
+ protected function setUp()
+ {
+ $this->client = $this->prophesize(ClientInterface::class);
+ }
+
+ protected function createResponse($status, array $headers, array $json)
+ {
+ return new Response($status, $headers, stream_for(json_encode($json)));
+ }
+
+ protected function getFixture($file)
+ {
+ if (!$this->rootFixturesDir) {
+ throw new \RuntimeException('Root fixtures dir not set');
+ }
+
+ $path = $this->rootFixturesDir . '/Fixtures/' . $file . '.resp';
+
+ if (!file_exists($path)) {
+ throw new \RuntimeException(sprintf("%s does not exist", $path));
+ }
+
+ return parse_response(file_get_contents($path));
+ }
+
+ protected function setupMock($method, $path, $body = null, array $headers = [], $response)
+ {
+ $options = ['headers' => $headers];
+
+ if (!empty($body)) {
+ $options[is_array($body) ? 'json' : 'body'] = $body;
+ }
+
+ if (is_string($response)) {
+ $response = $this->getFixture($response);
+ }
+
+ $this->client
+ ->request($method, $path, $options)
+ ->shouldBeCalled()
+ ->willReturn($response);
+ }
+
+ protected function createFn($receiver, $method, $args)
+ {
+ return function () use ($receiver, $method, $args) {
+ return $receiver->$method($args);
+ };
+ }
+
+ protected function listTest(callable $call, $urlPath, $modelName = null, $responseFile = null)
+ {
+ $modelName = $modelName ?: $urlPath;
+ $responseFile = $responseFile ?: $urlPath;
+
+ $this->setupMock('GET', $urlPath, null, [], $responseFile);
+
+ $resources = call_user_func($call);
+
+ $this->assertInstanceOf('\Generator', $resources);
+
+ $count = 0;
+
+ foreach ($resources as $resource) {
+ $this->assertInstanceOf('OpenStack\Identity\v3\Models\\' . ucfirst($modelName), $resource);
+ ++$count;
+ }
+
+ $this->assertEquals(2, $count);
+ }
+
+ protected function getTest(callable $call, $modelName)
+ {
+ $resource = call_user_func($call);
+
+ $this->assertInstanceOf('OpenStack\Identity\v3\Models\\' . ucfirst($modelName), $resource);
+ $this->assertEquals('id', $resource->id);
+ }
+}