Add some more tests for ocs remote api
Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
parent
f1eb55fad7
commit
5ce69e7c42
|
@ -43,7 +43,7 @@ class OCS extends ApiBase implements ICapabilitiesApi, IUserApi {
|
||||||
*/
|
*/
|
||||||
protected function request($method, $url, array $body = [], array $query = [], array $headers = []) {
|
protected function request($method, $url, array $body = [], array $query = [], array $headers = []) {
|
||||||
try {
|
try {
|
||||||
$response = json_decode(parent::request($method, '/ocs/v2.php/' . $url, $body, $query, $headers), true);
|
$response = json_decode(parent::request($method, 'ocs/v2.php/' . $url, $body, $query, $headers), true);
|
||||||
} catch (ClientException $e) {
|
} catch (ClientException $e) {
|
||||||
if ($e->getResponse()->getStatusCode() === 404) {
|
if ($e->getResponse()->getStatusCode() === 404) {
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
|
@ -69,14 +69,23 @@ class OCS extends ApiBase implements ICapabilitiesApi, IUserApi {
|
||||||
return $response['ocs']['data'];
|
return $response['ocs']['data'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param string $type
|
||||||
|
* @param string[] $keys
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
private function checkResponseArray(array $data, $type, array $keys) {
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (!array_key_exists($key, $data)) {
|
||||||
|
throw new \Exception('Invalid ' . $type . ' response, expected field ' . $key . ' not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getUser($userId) {
|
public function getUser($userId) {
|
||||||
$result = $this->request('get', 'cloud/users/' . $userId);
|
$result = $this->request('get', 'cloud/users/' . $userId);
|
||||||
$keys = ['id', 'email', 'displayname', 'phone', 'address', 'website', 'groups', 'language', 'quota'];
|
$this->checkResponseArray($result, 'user', User::EXPECTED_KEYS);
|
||||||
foreach ($keys as $key) {
|
|
||||||
if (!isset($result[$key])) {
|
|
||||||
throw new \Exception('Invalid user response, expected field ' . $key . ' not found');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new User($result);
|
return new User($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,18 @@ namespace OC\Remote;
|
||||||
use OCP\Remote\IUser;
|
use OCP\Remote\IUser;
|
||||||
|
|
||||||
class User implements IUser {
|
class User implements IUser {
|
||||||
|
const EXPECTED_KEYS = [
|
||||||
|
'id',
|
||||||
|
'email',
|
||||||
|
'displayname',
|
||||||
|
'phone',
|
||||||
|
'address',
|
||||||
|
'website',
|
||||||
|
'groups',
|
||||||
|
'language',
|
||||||
|
'quota'
|
||||||
|
];
|
||||||
|
|
||||||
/** @var array */
|
/** @var array */
|
||||||
private $data;
|
private $data;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Test\Remote\Api;
|
||||||
|
|
||||||
|
use OC\Memcache\ArrayCache;
|
||||||
|
use OC\Remote\Api\OCS;
|
||||||
|
use OC\Remote\Credentials;
|
||||||
|
use OC\Remote\InstanceFactory;
|
||||||
|
use OCP\Remote\IInstanceFactory;
|
||||||
|
use Test\TestCase;
|
||||||
|
use Test\Traits\ClientServiceTrait;
|
||||||
|
|
||||||
|
class OCSTest extends TestCase {
|
||||||
|
use ClientServiceTrait;
|
||||||
|
|
||||||
|
/** @var IInstanceFactory */
|
||||||
|
private $instanceFactory;
|
||||||
|
|
||||||
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->instanceFactory = new InstanceFactory(new ArrayCache(), $this->getClientService());
|
||||||
|
$this->expectGetRequest('https://example.com/status.php',
|
||||||
|
'{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getOCSClient() {
|
||||||
|
return new OCS(
|
||||||
|
$this->instanceFactory->getInstance('example.com'),
|
||||||
|
new Credentials('user', 'pass'),
|
||||||
|
$this->getClientService()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getOCSUrl($url) {
|
||||||
|
return 'https://example.com/ocs/v2.php/' . $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetUser() {
|
||||||
|
$client = $this->getOCSClient();
|
||||||
|
|
||||||
|
$this->expectGetRequest($this->getOCSUrl('cloud/users/user'),
|
||||||
|
'{"ocs":{"meta":{"status":"ok","statuscode":200,"message":"OK"},
|
||||||
|
"data":{"id":"user","quota":{"free":5366379387,"used":2329733,"total":5368709120,"relative":0.040000000000000001,"quota":5368709120},
|
||||||
|
"email":null,"displayname":"test","phone":"","address":"","website":"","twitter":"","groups":["Test","Test1"],"language":"en"}}}');
|
||||||
|
|
||||||
|
$user = $client->getUser('user');
|
||||||
|
$this->assertEquals('user', $user->getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Exception
|
||||||
|
* @expectedExceptionMessage Invalid user response, expected field email not found
|
||||||
|
*/
|
||||||
|
public function testGetUserInvalidResponse() {
|
||||||
|
$client = $this->getOCSClient();
|
||||||
|
|
||||||
|
$this->expectGetRequest($this->getOCSUrl('cloud/users/user'),
|
||||||
|
'{"ocs":{"meta":{"status":"ok","statuscode":200,"message":"OK"},
|
||||||
|
"data":{"id":"user"}}}');
|
||||||
|
|
||||||
|
$client->getUser('user');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \OC\ForbiddenException
|
||||||
|
*/
|
||||||
|
public function testInvalidPassword() {
|
||||||
|
$client = $this->getOCSClient();
|
||||||
|
|
||||||
|
$this->expectGetRequest($this->getOCSUrl('cloud/users/user'),
|
||||||
|
'{"ocs":{"meta":{"status":"failure","statuscode":997,"message":"Current user is not logged in"},"data":[]}}');
|
||||||
|
|
||||||
|
$client->getUser('user');
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,62 +24,25 @@ namespace Test\Remote;
|
||||||
|
|
||||||
use OC\Memcache\ArrayCache;
|
use OC\Memcache\ArrayCache;
|
||||||
use OC\Remote\Instance;
|
use OC\Remote\Instance;
|
||||||
use OCP\Http\Client\IClient;
|
|
||||||
use OCP\Http\Client\IClientService;
|
|
||||||
use OCP\Http\Client\IResponse;
|
|
||||||
use OCP\ICache;
|
use OCP\ICache;
|
||||||
use Test\TestCase;
|
use Test\TestCase;
|
||||||
|
use Test\Traits\ClientServiceTrait;
|
||||||
|
|
||||||
class InstanceTest extends TestCase {
|
class InstanceTest extends TestCase {
|
||||||
/** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */
|
use ClientServiceTrait;
|
||||||
private $clientService;
|
|
||||||
/** @var IClient|\PHPUnit_Framework_MockObject_MockObject */
|
|
||||||
private $client;
|
|
||||||
/** @var ICache */
|
/** @var ICache */
|
||||||
private $cache;
|
private $cache;
|
||||||
private $expectedRequests = [];
|
|
||||||
|
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->cache = new ArrayCache();
|
$this->cache = new ArrayCache();
|
||||||
|
|
||||||
$this->clientService = $this->createMock(IClientService::class);
|
|
||||||
$this->client = $this->createMock(IClient::class);
|
|
||||||
$this->clientService->expects($this->any())
|
|
||||||
->method('newClient')
|
|
||||||
->willReturn($this->client);
|
|
||||||
$this->client->expects($this->any())
|
|
||||||
->method('get')
|
|
||||||
->willReturnCallback(function ($url) {
|
|
||||||
if (!isset($this->expectedRequests[$url])) {
|
|
||||||
throw new \Exception('unexpected request');
|
|
||||||
}
|
|
||||||
$result = $this->expectedRequests[$url];
|
|
||||||
|
|
||||||
if ($result instanceof \Exception) {
|
|
||||||
throw $result;
|
|
||||||
} else {
|
|
||||||
$response = $this->createMock(IResponse::class);
|
|
||||||
$response->expects($this->any())
|
|
||||||
->method('getBody')
|
|
||||||
->willReturn($result);
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $url
|
|
||||||
* @param string|\Exception $result
|
|
||||||
*/
|
|
||||||
protected function expectRequest($url, $result) {
|
|
||||||
$this->expectedRequests[$url] = $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBasicStatus() {
|
public function testBasicStatus() {
|
||||||
$instance = new Instance('example.com', $this->cache, $this->clientService);
|
$instance = new Instance('example.com', $this->cache, $this->getClientService());
|
||||||
$this->expectRequest('https://example.com/status.php', '{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
$this->expectGetRequest('https://example.com/status.php', '{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
||||||
|
|
||||||
$this->assertEquals(true, $instance->isActive());
|
$this->assertEquals(true, $instance->isActive());
|
||||||
$this->assertEquals('13.0.0.5', $instance->getVersion());
|
$this->assertEquals('13.0.0.5', $instance->getVersion());
|
||||||
|
@ -88,24 +51,24 @@ class InstanceTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testHttpFallback() {
|
public function testHttpFallback() {
|
||||||
$instance = new Instance('example.com', $this->cache, $this->clientService);
|
$instance = new Instance('example.com', $this->cache, $this->getClientService());
|
||||||
$this->expectRequest('https://example.com/status.php', new \Exception());
|
$this->expectGetRequest('https://example.com/status.php', new \Exception());
|
||||||
$this->expectRequest('http://example.com/status.php', '{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
$this->expectGetRequest('http://example.com/status.php', '{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
||||||
|
|
||||||
$this->assertEquals('http', $instance->getProtocol());
|
$this->assertEquals('http', $instance->getProtocol());
|
||||||
$this->assertEquals('http://example.com', $instance->getFullUrl());
|
$this->assertEquals('http://example.com', $instance->getFullUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRerequestHttps() {
|
public function testRerequestHttps() {
|
||||||
$instance = new Instance('example.com', $this->cache, $this->clientService);
|
$instance = new Instance('example.com', $this->cache, $this->getClientService());
|
||||||
$this->expectRequest('https://example.com/status.php', '{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
$this->expectGetRequest('https://example.com/status.php', '{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
||||||
|
|
||||||
$this->assertEquals('https', $instance->getProtocol());
|
$this->assertEquals('https', $instance->getProtocol());
|
||||||
$this->assertEquals(true, $instance->isActive());
|
$this->assertEquals(true, $instance->isActive());
|
||||||
|
|
||||||
$this->cache->remove('remote/example.com/status');
|
$this->cache->remove('remote/example.com/status');
|
||||||
$this->expectRequest('https://example.com/status.php', '{"installed":true,"maintenance":true,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
$this->expectGetRequest('https://example.com/status.php', '{"installed":true,"maintenance":true,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
||||||
$instance2 = new Instance('example.com', $this->cache, $this->clientService);
|
$instance2 = new Instance('example.com', $this->cache, $this->getClientService());
|
||||||
$this->assertEquals('https', $instance2->getProtocol());
|
$this->assertEquals('https', $instance2->getProtocol());
|
||||||
$this->assertEquals(false, $instance2->isActive());
|
$this->assertEquals(false, $instance2->isActive());
|
||||||
}
|
}
|
||||||
|
@ -115,14 +78,14 @@ class InstanceTest extends TestCase {
|
||||||
* @expectedExceptionMessage refusing to connect to remote instance(example.com) over http that was previously accessible over https
|
* @expectedExceptionMessage refusing to connect to remote instance(example.com) over http that was previously accessible over https
|
||||||
*/
|
*/
|
||||||
public function testPreventDowngradeAttach() {
|
public function testPreventDowngradeAttach() {
|
||||||
$instance = new Instance('example.com', $this->cache, $this->clientService);
|
$instance = new Instance('example.com', $this->cache, $this->getClientService());
|
||||||
$this->expectRequest('https://example.com/status.php', '{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
$this->expectGetRequest('https://example.com/status.php', '{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"13.0.0.5","versionstring":"13.0.0 alpha","edition":"","productname":"Nextcloud"}');
|
||||||
|
|
||||||
$this->assertEquals('https', $instance->getProtocol());
|
$this->assertEquals('https', $instance->getProtocol());
|
||||||
|
|
||||||
$this->expectRequest('https://example.com/status.php', new \Exception());
|
$this->expectGetRequest('https://example.com/status.php', new \Exception());
|
||||||
$this->cache->remove('remote/example.com/status');
|
$this->cache->remove('remote/example.com/status');
|
||||||
$instance2 = new Instance('example.com', $this->cache, $this->clientService);
|
$instance2 = new Instance('example.com', $this->cache, $this->getClientService());
|
||||||
$instance2->getProtocol();
|
$instance2->getProtocol();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Test\Traits;
|
||||||
|
|
||||||
|
|
||||||
|
use OCP\Http\Client\IClient;
|
||||||
|
use OCP\Http\Client\IClientService;
|
||||||
|
use OCP\Http\Client\IResponse;
|
||||||
|
|
||||||
|
trait ClientServiceTrait {
|
||||||
|
/** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $clientService;
|
||||||
|
/** @var IClient|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $client;
|
||||||
|
private $expectedGetRequests = [];
|
||||||
|
private $expectedPostRequests = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper to be forward compatible to phpunit 5.4+
|
||||||
|
*
|
||||||
|
* @param string $originalClassName
|
||||||
|
* @return \PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
abstract protected function createMock($originalClassName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a matcher that matches when the method is executed
|
||||||
|
* zero or more times.
|
||||||
|
*
|
||||||
|
* @return \PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount
|
||||||
|
*
|
||||||
|
* @since Method available since Release 3.0.0
|
||||||
|
*/
|
||||||
|
abstract public function any();
|
||||||
|
|
||||||
|
protected function setUpClientServiceTrait() {
|
||||||
|
$this->clientService = $this->createMock(IClientService::class);
|
||||||
|
$this->client = $this->createMock(IClient::class);
|
||||||
|
$this->clientService->expects($this->any())
|
||||||
|
->method('newClient')
|
||||||
|
->willReturn($this->client);
|
||||||
|
$this->client->expects($this->any())
|
||||||
|
->method('get')
|
||||||
|
->willReturnCallback(function ($url) {
|
||||||
|
if (!isset($this->expectedGetRequests[$url])) {
|
||||||
|
throw new \Exception('unexpected request: ' . $url);
|
||||||
|
}
|
||||||
|
$result = $this->expectedGetRequests[$url];
|
||||||
|
|
||||||
|
if ($result instanceof \Exception) {
|
||||||
|
throw $result;
|
||||||
|
} else {
|
||||||
|
$response = $this->createMock(IResponse::class);
|
||||||
|
$response->expects($this->any())
|
||||||
|
->method('getBody')
|
||||||
|
->willReturn($result);
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$this->client->expects($this->any())
|
||||||
|
->method('post')
|
||||||
|
->willReturnCallback(function ($url) {
|
||||||
|
if (!isset($this->expectedPostRequests[$url])) {
|
||||||
|
throw new \Exception('unexpected request: ' . $url);
|
||||||
|
}
|
||||||
|
$result = $this->expectedPostRequests[$url];
|
||||||
|
|
||||||
|
if ($result instanceof \Exception) {
|
||||||
|
throw $result;
|
||||||
|
} else {
|
||||||
|
$response = $this->createMock(IResponse::class);
|
||||||
|
$response->expects($this->any())
|
||||||
|
->method('getBody')
|
||||||
|
->willReturn($result);
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $url
|
||||||
|
* @param string|\Exception $result
|
||||||
|
*/
|
||||||
|
protected function expectGetRequest($url, $result) {
|
||||||
|
$this->expectedGetRequests[$url] = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $url
|
||||||
|
* @param string|\Exception $result
|
||||||
|
*/
|
||||||
|
protected function expectPostRequest($url, $result) {
|
||||||
|
$this->expectedPostRequests[$url] = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IClientService|\PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
protected function getClientService() {
|
||||||
|
return $this->clientService;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue