diff --git a/phpcs.xml b/phpcs.xml
index b0e3834..cae0cb7 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -6,7 +6,10 @@
+
+ */tests/*
+
src
tests
-
\ No newline at end of file
+
diff --git a/src/Api.php b/src/Api.php
index c5ec8e6..43219a2 100644
--- a/src/Api.php
+++ b/src/Api.php
@@ -211,6 +211,24 @@ class Api
return $response;
}
+ /**
+ * getTarget returns the URL to target given an endpoint and a path.
+ * If the path starts with `/v1` or `/v2`, then remove the trailing `/1.0` from the endpoint.
+ *
+ * @param string path to use prefix from
+ * @return string
+ */
+ protected function getTarget($path) : string
+ {
+ $endpoint = $this->endpoint;
+ if (substr($endpoint, -4) == '/1.0' && (
+ substr($path, 0, 3) == '/v1' ||
+ substr($path, 0, 3) == '/v2')) {
+ $endpoint = substr($endpoint, 0, strlen($endpoint)-4);
+ }
+ return $endpoint . $path;
+ }
+
/**
* This is the main method of this wrapper. It will
* sign a given query and return its result.
@@ -238,7 +256,7 @@ class Api
}
}
- $url = $this->endpoint . $path;
+ $url = $this->getTarget($path);
$request = new Request($method, $url);
if (isset($content) && $method === 'GET') {
$query_string = $request->getUri()->getQuery();
@@ -280,9 +298,8 @@ class Api
}
$headers['Content-Type'] = 'application/json; charset=utf-8';
+ $headers['X-Ovh-Application'] = $this->application_key ?? '';
if ($is_authenticated) {
- $headers['X-Ovh-Application'] = $this->application_key;
-
if (!isset($this->time_delta)) {
$this->calculateTimeDelta();
}
diff --git a/tests/ApiFunctionalTest.php b/tests/ApiFunctionalTest.php
index 97b692b..5c0de7c 100644
--- a/tests/ApiFunctionalTest.php
+++ b/tests/ApiFunctionalTest.php
@@ -86,6 +86,13 @@ class ApiFunctionalTest extends TestCase
*/
protected function setUp() :void
{
+ foreach (['APP_KEY', 'APP_SECRET', 'CONSUMER', 'ENDPOINT'] as $envName) {
+ if (!getenv($envName)) {
+ $this->markTestSkipped("Skip test due to missing $envName variable");
+ return;
+ }
+ }
+
$this->application_key = getenv('APP_KEY');
$this->application_secret = getenv('APP_SECRET');
$this->consumer_key = getenv('CONSUMER');
diff --git a/tests/ApiTest.php b/tests/ApiTest.php
index 20185ff..ec5c884 100644
--- a/tests/ApiTest.php
+++ b/tests/ApiTest.php
@@ -29,6 +29,8 @@ namespace Ovh\tests;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
+use GuzzleHttp\Handler\MockHandler;
+use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Response;
@@ -37,6 +39,29 @@ use Ovh\Api;
use Ovh\Exceptions\InvalidParameterException;
use PHPUnit\Framework\TestCase;
+# Mock values
+const MOCK_APPLICATION_KEY = "TDPKJdwZwAQPwKX2";
+const MOCK_APPLICATION_SECRET = "9ufkBmLaTQ9nz5yMUlg79taH0GNnzDjk";
+const MOCK_CONSUMER_KEY = "5mBuy6SUQcRw2ZUxg0cG68BoDKpED4KY";
+const MOCK_TIME = 1457018875;
+
+class MockClient extends Client
+{
+ public $calls = [];
+
+ public function __construct(...$responses)
+ {
+
+ $mock = new MockHandler($responses);
+ $history = Middleware::history($this->calls);
+
+ $handlerStack = HandlerStack::create($mock);
+ $handlerStack->push($history);
+
+ parent::__construct(['handler' => $handlerStack]);
+ }
+}
+
/**
* Test Api class
*
@@ -45,60 +70,6 @@ use PHPUnit\Framework\TestCase;
*/
class ApiTest extends TestCase
{
- /**
- * @var Client
- */
- private $client;
-
- /**
- * @var string
- */
- private $application_key;
-
- /**
- * @var string
- */
- private $consumer_key;
-
- /**
- * @var string
- */
- private $endpoint;
-
- /**
- * @var string
- */
- private $application_secret;
-
- /**
- * Define id to create object
- */
- protected function setUp() :void
- {
- $this->application_key = 'app_key';
- $this->application_secret = 'app_secret';
- $this->consumer_key = 'consumer';
- $this->endpoint = 'ovh-eu';
-
- $this->client = new Client();
- }
-
- /**
- * Get private and protected method to unit test it
- *
- * @param string $name
- *
- * @return \ReflectionMethod
- */
- protected static function getPrivateMethod($name)
- {
- $class = new \ReflectionClass('Ovh\Api');
- $method = $class->getMethod($name);
- $method->setAccessible(true);
-
- return $method;
- }
-
/**
* Get private and protected property to unit test it
*
@@ -121,7 +92,8 @@ class ApiTest extends TestCase
public function testMissingApplicationKey()
{
$this->expectException(InvalidParameterException::class);
- $api = new Api(null, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
+ $this->expectExceptionMessage('Application key parameter is empty');
+ $api = new Api(null, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, new MockClient());
$api->get('/me');
}
@@ -131,7 +103,8 @@ class ApiTest extends TestCase
public function testMissingApplicationSecret()
{
$this->expectException(InvalidParameterException::class);
- $api = new Api($this->application_key, null, $this->endpoint, $this->consumer_key, $this->client);
+ $this->expectExceptionMessage('Application secret parameter is empty');
+ $api = new Api(MOCK_APPLICATION_KEY, null, 'ovh-eu', MOCK_CONSUMER_KEY, new MockClient());
$api->get('/me');
}
@@ -140,25 +113,18 @@ class ApiTest extends TestCase
*/
public function testNoCheckAppKeyForUnauthCall()
{
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapRequest(function (Request $request) {
- if ($request->getUri()->getPath() == "/1.0/unauthcall") {
- return $request;
- }
+ $client = new MockClient(new Response(200, [], '{}'));
- return null;
- }));
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
- $body = Psr7\Utils::streamFor('{}');
+ $api = new Api(null, null, 'ovh-eu', null, $client);
+ $api->get("/me", null, null, false);
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
- $api = new Api(null, null, $this->endpoint, $this->consumer_key, $this->client);
- $api->get('/unauthcall', null, null, false);
- $this->assertEquals(1, 1);
+ $calls = $client->calls;
+ $this->assertEquals(1, count($calls));
+
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/me', $req->getUri()->__toString());
+ $this->assertEquals('', $req->getHeaderLine('X-Ovh-Application'));
}
/**
@@ -167,7 +133,8 @@ class ApiTest extends TestCase
public function testMissingApiEndpoint()
{
$this->expectException(InvalidParameterException::class);
- new Api($this->application_key, $this->application_secret, null, $this->consumer_key, $this->client);
+ $this->expectExceptionMessage('Endpoint parameter is empty');
+ new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, null, MOCK_CONSUMER_KEY, new MockClient());
}
/**
@@ -176,7 +143,8 @@ class ApiTest extends TestCase
public function testBadApiEndpoint()
{
$this->expectException(InvalidParameterException::class);
- new Api($this->application_key, $this->application_secret, 'i_am_invalid', $this->consumer_key, $this->client);
+ $this->expectExceptionMessage('Unknown provided endpoint');
+ new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'i_am_invalid', MOCK_CONSUMER_KEY, new MockClient());
}
/**
@@ -184,8 +152,7 @@ class ApiTest extends TestCase
*/
public function testClientCreation()
{
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key);
-
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY);
$this->assertInstanceOf('\\GuzzleHttp\\Client', $api->getHttpClient());
}
@@ -194,28 +161,28 @@ class ApiTest extends TestCase
*/
public function testTimeDeltaCompute()
{
- $delay = 10;
+ $client = new MockClient(
+ new Response(200, [], time() - 10),
+ new Response(200, [], '{}'),
+ );
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
+ $api->get("/me");
- $body = Psr7\Utils::streamFor(time() - 10);
-
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
-
- $invoker = self::getPrivateMethod('calculateTimeDelta');
$property = self::getPrivateProperty('time_delta');
-
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
- $invoker->invokeArgs($api, []);
-
$time_delta = $property->getValue($api);
- $this->assertNotNull($time_delta);
- $this->assertEquals($time_delta, $delay * -1);
+ $this->assertEquals($time_delta, -10);
+
+ $calls = $client->calls;
+ $this->assertEquals(2, count($calls));
+
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
+
+ $req = $calls[1]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/me', $req->getUri()->__toString());
}
/**
@@ -223,32 +190,30 @@ class ApiTest extends TestCase
*/
public function testIfConsumerKeyIsReplace()
{
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
+ $client = new MockClient(
+ new Response(200, [], MOCK_TIME),
+ new Response(
+ 200,
+ ['Content-Type' => 'application/json; charset=utf-8'],
+ '{"validationUrl":"https://api.ovh.com/login/?credentialToken=token","consumerKey":"consumer_remote","state":"pendingValidation"}'
+ ),
+ );
- $body = Psr7\Utils::streamFor('{"validationUrl":"https://api.ovh.com/login/?credentialToken=token","consumerKey":"consumer_remote","state":"pendingValidation"}');
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
+ $this->assertNotEquals('consumer_remote', $api->getConsumerKey());
+ $credentials = $api->requestCredentials(['method' => 'GET', 'path' => '/*']);
+ $this->assertEquals('consumer_remote', $api->getConsumerKey());
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
+ $calls = $client->calls;
+ $this->assertEquals(2, count($calls));
- $property = self::getPrivateProperty('consumer_key');
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
- $this->assertEquals('consumer', $this->consumer_key);
- $this->assertNotEquals('consumer_remote', $this->consumer_key);
-
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
- $accessRules = [json_decode(' { "method": "GET", "path": "/*" } ')];
-
- $credentials = $api->requestCredentials($accessRules);
-
- $consumer_key = $property->getValue($api);
-
- $this->assertEquals($consumer_key, $credentials["consumerKey"]);
- $this->assertEquals('consumer_remote', $credentials["consumerKey"]);
- $this->assertNotEquals($consumer_key, $this->consumer_key);
+ $req = $calls[1]['request'];
+ $this->assertEquals('POST', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/auth/credential', $req->getUri()->__toString());
}
/**
@@ -256,30 +221,15 @@ class ApiTest extends TestCase
*/
public function testInvalidApplicationKey()
{
-
+ $error = '{"class":"Client::Forbidden","message":"Invalid application key"}';
$this->expectException(ClientException::class);
+ $this->expectExceptionCode(403);
+ $this->expectExceptionMessage($error);
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
+ $client = new MockClient(new Response(403, ['Content-Type' => 'application/json; charset=utf-8'], $error));
- $body = Psr7\Utils::streamFor('{\"message\":\"Invalid application key\"}');
-
- return $response
- ->withStatus(401, 'POUET')
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withHeader('Content-Length', 37)
- ->withBody($body);
- }));
-
- $property = self::getPrivateProperty('consumer_key');
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
- $accessRules = [json_decode(' { "method": "GET", "path": "/*" } ')];
-
- $credentials = $api->requestCredentials($accessRules);
- $consumer_key = $property->getValue($api);
-
- $this->assertEquals($consumer_key, $credentials["consumerKey"]);
- $this->assertNotEquals($consumer_key, $this->consumer_key);
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
+ $api->requestCredentials(['method' => 'GET', 'path' => '/*']);
}
/**
@@ -287,30 +237,21 @@ class ApiTest extends TestCase
*/
public function testInvalidRight()
{
+ $error = '{"message": "Invalid credentials"}';
$this->expectException(ClientException::class);
+ $this->expectExceptionCode(403);
+ $this->expectExceptionMessage($error);
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
+ $client = new MockClient(new Response(403, ['Content-Type' => 'application/json; charset=utf-8'], $error));
- $body = Psr7\Utils::streamFor('{\"message\":\"Invalid credentials\"}');
-
- return $response
- ->withStatus(403)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withHeader('Content-Length', 37)
- ->withBody($body);
- }));
-
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
-
- $invoker = self::getPrivateMethod('rawCall');
- $invoker->invokeArgs($api, ['GET', '/me']);
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
+ $api->get('/me', null, null, false);
}
public function testGetConsumerKey()
{
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
- $this->assertEquals($this->consumer_key, $api->getConsumerKey());
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY);
+ $this->assertEquals(MOCK_CONSUMER_KEY, $api->getConsumerKey());
}
@@ -319,32 +260,17 @@ class ApiTest extends TestCase
*/
public function testGetQueryArgs()
{
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapRequest(function (Request $request) {
- if ($request->getUri()->getPath() == "/1.0/auth/time") {
- return $request;
- }
+ $client = new MockClient(new Response(200, [], '{}'));
- $query_string = $request->getUri()->getQuery();
- $this->assertEquals($query_string, 'applicationId=49&status=pendingValidation');
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
+ $api->get('/me/api/credential?applicationId=49', ['status' => 'pendingValidation'], null, false);
- $request = $request->withUri($request->getUri()
- ->withHost('httpbin.org')
- ->withPath('/')
- ->withQuery(''));
- return $request;
- }));
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
- $body = Psr7\Utils::streamFor('123456789991');
+ $calls = $client->calls;
+ $this->assertEquals(1, count($calls));
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
-
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
- $api->get('/me/api/credential?applicationId=49', ['status' => 'pendingValidation']);
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/me/api/credential?applicationId=49&status=pendingValidation', $req->getUri()->__toString());
}
/**
@@ -352,32 +278,17 @@ class ApiTest extends TestCase
*/
public function testGetOverlappingQueryArgs()
{
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapRequest(function (Request $request) {
- if ($request->getUri()->getPath() == "/1.0/auth/time") {
- return $request;
- }
+ $client = new MockClient(new Response(200, [], '{}'));
- $query_string = $request->getUri()->getQuery();
- $this->assertEquals($query_string, 'applicationId=49&status=expired&test=success');
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
+ $api->get('/me/api/credential?applicationId=49&status=pendingValidation', ['status' => 'expired', 'test' => "success"], null, false);
- $request = $request->withUri($request->getUri()
- ->withHost('httpbin.org')
- ->withPath('/')
- ->withQuery(''));
- return $request;
- }));
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
- $body = Psr7\Utils::streamFor('123456789991');
+ $calls = $client->calls;
+ $this->assertEquals(1, count($calls));
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
-
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
- $api->get('/me/api/credential?applicationId=49&status=pendingValidation', ['status' => 'expired', 'test' => "success"]);
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/me/api/credential?applicationId=49&status=expired&test=success', $req->getUri()->__toString());
}
/**
@@ -385,149 +296,41 @@ class ApiTest extends TestCase
*/
public function testGetBooleanQueryArgs()
{
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapRequest(function (Request $request) {
- if ($request->getUri()->getPath() == "/1.0/auth/time") {
- return $request;
- }
+ $client = new MockClient(new Response(200, [], '{}'));
- $query_string = $request->getUri()->getQuery();
- $this->assertEquals($query_string, 'dryRun=true¬DryRun=false');
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
+ $api->get('/me/api/credential', ['dryRun' => true, 'notDryRun' => false], null, false);
- $request = $request->withUri($request->getUri()
- ->withHost('httpbin.org')
- ->withPath('/')
- ->withQuery(''));
- return $request;
- }));
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
- $body = Psr7\Utils::streamFor('123456789991');
+ $calls = $client->calls;
+ $this->assertEquals(1, count($calls));
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
-
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
- $api->get('/me/api/credential', ['dryRun' => true, 'notDryRun' => false]);
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/me/api/credential?dryRun=true¬DryRun=false', $req->getUri()->__toString());
}
/**
- * Test valid predefined endpoint
+ * Test valid provided endpoint
*/
- public function testPredefinedEndPoint()
+ public function testProvidedUrl()
{
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapRequest(function (Request $request) {
- if ($request->getUri()->getPath() == "/1.0/auth/time") {
- return $request;
- }
+ foreach ([
+ ['endpoint' => 'http://api.ovh.com/1.0', 'expectedUrl' => 'http://api.ovh.com/1.0'],
+ ['endpoint' => 'https://api.ovh.com/1.0', 'expectedUrl' => 'https://api.ovh.com/1.0'],
+ ['endpoint' => 'ovh-eu', 'expectedUrl' => 'https://eu.api.ovh.com/1.0'],
+ ] as $test) {
+ $client = new MockClient(new Response(200, [], '{}'));
- $host = $request->getUri()->getHost();
- $this->assertEquals($host, 'ca.api.ovh.com');
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, $test['endpoint'], MOCK_CONSUMER_KEY, $client);
+ $api->get('/me/api/credential', null, null, false);
- $resource = $request->getUri()->getPath();
- $this->assertEquals($resource, '/1.0/me/api/credential');
+ $calls = $client->calls;
+ $this->assertEquals(1, count($calls));
- $resource = $request->getUri()->getScheme();
- $this->assertEquals($resource, 'https');
-
- $request = $request->withUri($request->getUri()
- ->withHost('httpbin.org')
- ->withPath('/')
- ->withQuery(''));
- return $request;
- }));
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
- $body = Psr7\Utils::streamFor('123456789991');
-
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
-
- $api = new Api($this->application_key, $this->application_secret, 'ovh-ca', $this->consumer_key, $this->client);
- $api->get('/me/api/credential');
- }
-
- /**
- * Test valid provided HTTP endpoint
- */
- public function testProvidedHttpEndPoint()
- {
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapRequest(function (Request $request) {
- if ($request->getUri()->getPath() == "/1.0/auth/time") {
- return $request;
- }
-
- $host = $request->getUri()->getHost();
- $this->assertEquals($host, 'api.ovh.com');
-
- $resource = $request->getUri()->getPath();
- $this->assertEquals($resource, '/1.0/me/api/credential');
-
- $resource = $request->getUri()->getScheme();
- $this->assertEquals($resource, 'http');
-
- $request = $request->withUri($request->getUri()
- ->withHost('httpbin.org')
- ->withPath('/')
- ->withQuery(''));
- return $request;
- }));
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
- $body = Psr7\Utils::streamFor('123456789991');
-
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
-
- $api = new Api($this->application_key, $this->application_secret, 'http://api.ovh.com/1.0', $this->consumer_key, $this->client);
- $api->get('/me/api/credential');
- }
-
- /**
- * Test valid provided HTTPS endpoint
- */
- public function testProvidedHttpsEndPoint()
- {
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapRequest(function (Request $request) {
- if ($request->getUri()->getPath() == "/1.0/auth/time") {
- return $request;
- }
-
- $host = $request->getUri()->getHost();
- $this->assertEquals($host, 'api.ovh.com');
-
- $resource = $request->getUri()->getPath();
- $this->assertEquals($resource, '/1.0/me/api/credential');
-
- $resource = $request->getUri()->getScheme();
- $this->assertEquals($resource, 'https');
-
- $request = $request->withUri($request->getUri()
- ->withHost('httpbin.org')
- ->withPath('/')
- ->withQuery(''));
- return $request;
- }));
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
- $body = Psr7\Utils::streamFor('123456789991');
-
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
-
- $api = new Api($this->application_key, $this->application_secret, 'https://api.ovh.com/1.0', $this->consumer_key, $this->client);
- $api->get('/me/api/credential');
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals($test['expectedUrl'] . '/me/api/credential', $req->getUri()->__toString());
+ }
}
/**
@@ -535,32 +338,128 @@ class ApiTest extends TestCase
*/
public function testMissingOvhApplicationHeaderOnRequestCredentials()
{
- $handlerStack = $this->client->getConfig('handler');
- $handlerStack->push(Middleware::mapRequest(function (Request $request) {
- if ($request->getUri()->getPath() == "/1.0/auth/time") {
- return $request;
- }
+ $client = new MockClient(
+ new Response(200, [], MOCK_TIME),
+ new Response(200, [], '{"validationUrl":"https://api.ovh.com/login/?credentialToken=token","consumerKey":"consumer_remote","state":"pendingValidation"}'),
+ );
- $ovhApplication = $request->getHeader('X-OVH-Application');
- $this->assertNotNull($ovhApplication);
- $this->assertEquals($ovhApplication, array($this->application_key));
-
- $request = $request->withUri($request->getUri()
- ->withHost('httpbin.org')
- ->withPath('/')
- ->withQuery(''));
- return $request;
- }));
- $handlerStack->push(Middleware::mapResponse(function (Response $response) {
- $body = Psr7\Utils::streamFor('{"validationUrl":"https://api.ovh.com/login/?credentialToken=token","consumerKey":"consumer_remote","state":"pendingValidation"}');
-
- return $response
- ->withStatus(200)
- ->withHeader('Content-Type', 'application/json; charset=utf-8')
- ->withBody($body);
- }));
-
- $api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$api->requestCredentials([]);
+
+ $calls = $client->calls;
+ $this->assertEquals(2, count($calls));
+
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
+
+ $req = $calls[1]['request'];
+ $this->assertEquals('POST', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/auth/credential', $req->getUri()->__toString());
+ $this->assertEquals(MOCK_APPLICATION_KEY, $req->getHeaderLine('X-Ovh-Application'));
+ $this->assertEquals(MOCK_CONSUMER_KEY, $req->getHeaderLine('X-Ovh-Consumer'));
+ $this->assertEquals(MOCK_TIME, $req->getHeaderLine('X-Ovh-Timestamp'));
+ }
+
+ public function testCallSignature()
+ {
+ // GET /auth/time
+ $mocks = [new Response(200, [], MOCK_TIME)];
+ // (GET,POST,PUT,DELETE) x (/auth,/unauth)
+ for ($i = 0; $i < 8; $i++) {
+ $mocks[] = new Response(200, [], '{}');
+ }
+ $client = new MockClient(...$mocks);
+
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
+ $body = ["a" => "b", "c" => "d"];
+
+ // Authenticated calls
+ $api->get('/auth');
+ $api->post('/auth', $body);
+ $api->put('/auth', $body);
+ $api->delete('/auth');
+
+ // Unauth calls
+ $api->get('/unauth', null, null, false);
+ $api->post('/unauth', $body, null, false);
+ $api->put('/unauth', $body, null, false);
+ $api->delete('/unauth', null, null, false);
+
+ $calls = $client->calls;
+ $this->assertEquals(9, count($calls));
+
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
+
+ foreach ([
+ 1 => ['method' => 'GET', 'sig' => '$1$e9556054b6309771395efa467c22e627407461ad'],
+ 2 => ['method' => 'POST', 'sig' => '$1$ec2fb5c7a81f64723c77d2e5b609ae6f58a84fc1'],
+ 3 => ['method' => 'PUT', 'sig' => '$1$8a75a9e7c8e7296c9dbeda6a2a735eb6bd58ec4b'],
+ 4 => ['method' => 'DELETE', 'sig' => '$1$a1eecd00b3b02b6cf5708b84b9ff42059a950d85'],
+ ] as $i => $test) {
+ $req = $calls[$i]['request'];
+ $this->assertEquals($test['method'], $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/auth', $req->getUri()->__toString());
+ $this->assertEquals(MOCK_APPLICATION_KEY, $req->getHeaderLine('X-Ovh-Application'));
+ $this->assertEquals(MOCK_CONSUMER_KEY, $req->getHeaderLine('X-Ovh-Consumer'));
+ $this->assertEquals(MOCK_TIME, $req->getHeaderLine('X-Ovh-Timestamp'));
+ $this->assertEquals($test['sig'], $req->getHeaderLine('X-Ovh-Signature'));
+ if ($test['method'] == 'POST' || $test['method'] == 'PUT') {
+ $this->assertEquals('application/json; charset=utf-8', $req->getHeaderLine('Content-Type'));
+ }
+ }
+
+ foreach (['GET', 'POST', 'PUT', 'DELETE'] as $i => $method) {
+ $req = $calls[$i + 5]['request'];
+ $this->assertEquals($method, $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/unauth', $req->getUri()->__toString());
+ $this->assertEquals(MOCK_APPLICATION_KEY, $req->getHeaderLine('X-Ovh-Application'));
+ $this->assertNotTrue($req->hasHeader('X-Ovh-Consumer'));
+ $this->assertNotTrue($req->hasHeader('X-Ovh-Timestamp'));
+ $this->assertNotTrue($req->hasHeader('X-Ovh-Signature'));
+ if ($method == 'POST' || $method == 'PUT') {
+ $this->assertEquals('application/json; charset=utf-8', $req->getHeaderLine('Content-Type'));
+ }
+ }
+ }
+
+ public function testVersionInUrl()
+ {
+ // GET /auth/time
+ $mocks = [new Response(200, [], MOCK_TIME)];
+ // GET) x (/1.0/call,/v1/call,/v2/call)
+ for ($i = 0; $i < 3; $i++) {
+ $mocks[] = new Response(200, [], '{}');
+ }
+ $client = new MockClient(...$mocks);
+
+ $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
+
+ $api->get('/call');
+ $api->get('/v1/call');
+ $api->get('/v2/call');
+
+ $calls = $client->calls;
+ $this->assertEquals(4, count($calls));
+
+ $req = $calls[0]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
+
+ foreach ([
+ 1 => ['path' => '1.0/call', 'sig' => '$1$7f2db49253edfc41891023fcd1a54cf61db05fbb'],
+ 2 => ['path' => 'v1/call', 'sig' => '$1$e6e7906d385eb28adcbfbe6b66c1528a42d741ad'],
+ 3 => ['path' => 'v2/call', 'sig' => '$1$bb63b132a6f84ad5433d0c534d48d3f7c3804285'],
+ ] as $i => $test) {
+ $req = $calls[$i]['request'];
+ $this->assertEquals('GET', $req->getMethod());
+ $this->assertEquals('https://eu.api.ovh.com/' . $test['path'], $req->getUri()->__toString());
+ $this->assertEquals(MOCK_APPLICATION_KEY, $req->getHeaderLine('X-Ovh-Application'));
+ $this->assertEquals(MOCK_CONSUMER_KEY, $req->getHeaderLine('X-Ovh-Consumer'));
+ $this->assertEquals(MOCK_TIME, $req->getHeaderLine('X-Ovh-Timestamp'));
+ $this->assertEquals($test['sig'], $req->getHeaderLine('X-Ovh-Signature'));
+ }
}
}