summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorBjörn Schießle <bjoern@schiessle.org>2015-09-01 17:09:57 +0200
committerBjörn Schießle <bjoern@schiessle.org>2015-09-01 17:09:57 +0200
commit39bd4ea8f202cb71f94d885901ba40872dfa5176 (patch)
tree5236452ce684d7231e00b07661372070c97ce1b3 /apps
parent87b3e28f06bc96c28fab65d8b297753f686ba58b (diff)
parent199d1dc239a55f9be25b8779122420537f34ecf8 (diff)
downloadnextcloud-server-39bd4ea8f202cb71f94d885901ba40872dfa5176.tar.gz
nextcloud-server-39bd4ea8f202cb71f94d885901ba40872dfa5176.zip
Merge pull request #18234 from owncloud/ocs_api_for_sharees_list
Add OCS API for sharees list
Diffstat (limited to 'apps')
-rw-r--r--apps/files_sharing/api/sharees.php409
-rw-r--r--apps/files_sharing/appinfo/routes.php13
-rw-r--r--apps/files_sharing/tests/api/shareestest.php995
3 files changed, 1417 insertions, 0 deletions
diff --git a/apps/files_sharing/api/sharees.php b/apps/files_sharing/api/sharees.php
new file mode 100644
index 00000000000..d7eabb9a550
--- /dev/null
+++ b/apps/files_sharing/api/sharees.php
@@ -0,0 +1,409 @@
+<?php
+/**
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+namespace OCA\Files_Sharing\API;
+
+use OCP\Contacts\IManager;
+use OCP\IGroup;
+use OCP\IGroupManager;
+use OCP\ILogger;
+use OCP\IRequest;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\IConfig;
+use OCP\IUserSession;
+use OCP\IURLGenerator;
+use OCP\Share;
+
+class Sharees {
+
+ /** @var IGroupManager */
+ protected $groupManager;
+
+ /** @var IUserManager */
+ protected $userManager;
+
+ /** @var IManager */
+ protected $contactsManager;
+
+ /** @var IConfig */
+ protected $config;
+
+ /** @var IUserSession */
+ protected $userSession;
+
+ /** @var IRequest */
+ protected $request;
+
+ /** @var IURLGenerator */
+ protected $urlGenerator;
+
+ /** @var ILogger */
+ protected $logger;
+
+ /** @var bool */
+ protected $shareWithGroupOnly = false;
+
+ /** @var int */
+ protected $offset = 0;
+
+ /** @var int */
+ protected $limit = 10;
+
+ /** @var array */
+ protected $result = [
+ 'exact' => [
+ 'users' => [],
+ 'groups' => [],
+ 'remotes' => [],
+ ],
+ 'users' => [],
+ 'groups' => [],
+ 'remotes' => [],
+ ];
+
+ protected $reachedEndFor = [];
+
+ /**
+ * @param IGroupManager $groupManager
+ * @param IUserManager $userManager
+ * @param IManager $contactsManager
+ * @param IConfig $config
+ * @param IUserSession $userSession
+ * @param IURLGenerator $urlGenerator
+ * @param IRequest $request
+ * @param ILogger $logger
+ */
+ public function __construct(IGroupManager $groupManager,
+ IUserManager $userManager,
+ IManager $contactsManager,
+ IConfig $config,
+ IUserSession $userSession,
+ IURLGenerator $urlGenerator,
+ IRequest $request,
+ ILogger $logger) {
+ $this->groupManager = $groupManager;
+ $this->userManager = $userManager;
+ $this->contactsManager = $contactsManager;
+ $this->config = $config;
+ $this->userSession = $userSession;
+ $this->urlGenerator = $urlGenerator;
+ $this->request = $request;
+ $this->logger = $logger;
+ }
+
+ /**
+ * @param string $search
+ */
+ protected function getUsers($search) {
+ $this->result['users'] = $this->result['exact']['users'] = $users = [];
+
+ if ($this->shareWithGroupOnly) {
+ // Search in all the groups this user is part of
+ $userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
+ foreach ($userGroups as $userGroup) {
+ $usersTmp = $this->groupManager->displayNamesInGroup($userGroup, $search, $this->limit, $this->offset);
+ foreach ($usersTmp as $uid => $userDisplayName) {
+ $users[$uid] = $userDisplayName;
+ }
+ }
+ } else {
+ // Search in all users
+ $usersTmp = $this->userManager->searchDisplayName($search, $this->limit, $this->offset);
+
+ foreach ($usersTmp as $user) {
+ $users[$user->getUID()] = $user->getDisplayName();
+ }
+ }
+
+ if (sizeof($users) < $this->limit) {
+ $this->reachedEndFor[] = 'users';
+ }
+
+ $foundUserById = false;
+ foreach ($users as $uid => $userDisplayName) {
+ if (strtolower($uid) === $search || strtolower($userDisplayName) === $search) {
+ if (strtolower($uid) === $search) {
+ $foundUserById = true;
+ }
+ $this->result['exact']['users'][] = [
+ 'label' => $userDisplayName,
+ 'value' => [
+ 'shareType' => Share::SHARE_TYPE_USER,
+ 'shareWith' => $uid,
+ ],
+ ];
+ } else {
+ $this->result['users'][] = [
+ 'label' => $userDisplayName,
+ 'value' => [
+ 'shareType' => Share::SHARE_TYPE_USER,
+ 'shareWith' => $uid,
+ ],
+ ];
+ }
+ }
+
+ if ($this->offset === 0 && !$foundUserById) {
+ // On page one we try if the search result has a direct hit on the
+ // user id and if so, we add that to the exact match list
+ $user = $this->userManager->get($search);
+ if ($user instanceof IUser) {
+ array_push($this->result['exact']['users'], [
+ 'label' => $user->getDisplayName(),
+ 'value' => [
+ 'shareType' => Share::SHARE_TYPE_USER,
+ 'shareWith' => $user->getUID(),
+ ],
+ ]);
+ }
+ }
+ }
+
+ /**
+ * @param string $search
+ */
+ protected function getGroups($search) {
+ $this->result['groups'] = $this->result['exact']['groups'] = [];
+
+ $groups = $this->groupManager->search($search, $this->limit, $this->offset);
+ $groups = array_map(function (IGroup $group) { return $group->getGID(); }, $groups);
+
+ if (sizeof($groups) < $this->limit) {
+ $this->reachedEndFor[] = 'groups';
+ }
+
+ $userGroups = [];
+ if (!empty($groups) && $this->shareWithGroupOnly) {
+ // Intersect all the groups that match with the groups this user is a member of
+ $userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
+ $userGroups = array_map(function (IGroup $group) { return $group->getGID(); }, $userGroups);
+ $groups = array_intersect($groups, $userGroups);
+ }
+
+ foreach ($groups as $gid) {
+ if (strtolower($gid) === $search) {
+ $this->result['exact']['groups'][] = [
+ 'label' => $search,
+ 'value' => [
+ 'shareType' => Share::SHARE_TYPE_GROUP,
+ 'shareWith' => $search,
+ ],
+ ];
+ } else {
+ $this->result['groups'][] = [
+ 'label' => $gid,
+ 'value' => [
+ 'shareType' => Share::SHARE_TYPE_GROUP,
+ 'shareWith' => $gid,
+ ],
+ ];
+ }
+ }
+
+ if ($this->offset === 0 && empty($this->result['exact']['groups'])) {
+ // On page one we try if the search result has a direct hit on the
+ // user id and if so, we add that to the exact match list
+ $group = $this->groupManager->get($search);
+ if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
+ array_push($this->result['exact']['groups'], [
+ 'label' => $group->getGID(),
+ 'value' => [
+ 'shareType' => Share::SHARE_TYPE_GROUP,
+ 'shareWith' => $group->getGID(),
+ ],
+ ]);
+ }
+ }
+ }
+
+ /**
+ * @param string $search
+ * @return array possible sharees
+ */
+ protected function getRemote($search) {
+ $this->result['remotes'] = [];
+
+ // Search in contacts
+ //@todo Pagination missing
+ $addressBookContacts = $this->contactsManager->search($search, ['CLOUD', 'FN']);
+ $foundRemoteById = false;
+ foreach ($addressBookContacts as $contact) {
+ if (isset($contact['CLOUD'])) {
+ foreach ($contact['CLOUD'] as $cloudId) {
+ if (strtolower($contact['FN']) === $search || strtolower($cloudId) === $search) {
+ if (strtolower($cloudId) === $search) {
+ $foundRemoteById = true;
+ }
+ $this->result['exact']['remotes'][] = [
+ 'label' => $contact['FN'],
+ 'value' => [
+ 'shareType' => Share::SHARE_TYPE_REMOTE,
+ 'shareWith' => $cloudId,
+ ],
+ ];
+ } else {
+ $this->result['remotes'][] = [
+ 'label' => $contact['FN'],
+ 'value' => [
+ 'shareType' => Share::SHARE_TYPE_REMOTE,
+ 'shareWith' => $cloudId,
+ ],
+ ];
+ }
+ }
+ }
+ }
+
+ if (!$foundRemoteById && substr_count($search, '@') >= 1 && substr_count($search, ' ') === 0 && $this->offset === 0) {
+ $this->result['exact']['remotes'][] = [
+ 'label' => $search,
+ 'value' => [
+ 'shareType' => Share::SHARE_TYPE_REMOTE,
+ 'shareWith' => $search,
+ ],
+ ];
+ }
+
+ $this->reachedEndFor[] = 'remotes';
+ }
+
+ /**
+ * @return \OC_OCS_Result
+ */
+ public function search() {
+ $search = isset($_GET['search']) ? (string) $_GET['search'] : '';
+ $itemType = isset($_GET['itemType']) ? (string) $_GET['itemType'] : null;
+ $page = !empty($_GET['page']) ? max(1, (int) $_GET['page']) : 1;
+ $perPage = !empty($_GET['limit']) ? max(1, (int) $_GET['limit']) : 200;
+
+ $shareTypes = [
+ Share::SHARE_TYPE_USER,
+ Share::SHARE_TYPE_GROUP,
+ Share::SHARE_TYPE_REMOTE,
+ ];
+ if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
+ $shareTypes = array_intersect($shareTypes, $_GET['shareType']);
+ sort($shareTypes);
+
+ } else if (isset($_GET['shareType']) && is_numeric($_GET['shareType'])) {
+ $shareTypes = array_intersect($shareTypes, [(int) $_GET['shareType']]);
+ sort($shareTypes);
+ }
+
+ if (in_array(Share::SHARE_TYPE_REMOTE, $shareTypes) && !$this->isRemoteSharingAllowed($itemType)) {
+ // Remove remote shares from type array, because it is not allowed.
+ $shareTypes = array_diff($shareTypes, [Share::SHARE_TYPE_REMOTE]);
+ }
+
+ $this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
+ $this->limit = (int) $perPage;
+ $this->offset = $perPage * ($page - 1);
+
+ return $this->searchSharees(strtolower($search), $itemType, $shareTypes, $page, $perPage);
+ }
+
+ /**
+ * Method to get out the static call for better testing
+ *
+ * @param string $itemType
+ * @return bool
+ */
+ protected function isRemoteSharingAllowed($itemType) {
+ try {
+ $backend = Share::getBackend($itemType);
+ return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE);
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Testable search function that does not need globals
+ *
+ * @param string $search
+ * @param string $itemType
+ * @param array $shareTypes
+ * @param int $page
+ * @param int $perPage
+ * @return \OC_OCS_Result
+ */
+ protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage) {
+ // Verify arguments
+ if ($itemType === null) {
+ return new \OC_OCS_Result(null, 400, 'missing itemType');
+ }
+
+ // Get users
+ if (in_array(Share::SHARE_TYPE_USER, $shareTypes)) {
+ $this->getUsers($search);
+ }
+
+ // Get groups
+ if (in_array(Share::SHARE_TYPE_GROUP, $shareTypes)) {
+ $this->getGroups($search);
+ }
+
+ // Get remote
+ if (in_array(Share::SHARE_TYPE_REMOTE, $shareTypes)) {
+ $this->getRemote($search);
+ }
+
+ $response = new \OC_OCS_Result($this->result);
+ $response->setItemsPerPage($perPage);
+
+ if (sizeof($this->reachedEndFor) < 3) {
+ $response->addHeader('Link', $this->getPaginationLink($page, [
+ 'search' => $search,
+ 'itemType' => $itemType,
+ 'shareType' => $shareTypes,
+ 'limit' => $perPage,
+ ]));
+ }
+
+ return $response;
+ }
+
+ /**
+ * Generates a bunch of pagination links for the current page
+ *
+ * @param int $page Current page
+ * @param array $params Parameters for the URL
+ * @return string
+ */
+ protected function getPaginationLink($page, array $params) {
+ if ($this->isV2()) {
+ $url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
+ } else {
+ $url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
+ }
+ $params['page'] = $page + 1;
+ $link = '<' . $url . http_build_query($params) . '>; rel="next"';
+
+ return $link;
+ }
+
+ /**
+ * @return bool
+ */
+ protected function isV2() {
+ return $this->request->getScriptName() === '/ocs/v2.php';
+ }
+}
diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php
index 184ad29bba4..375124cb730 100644
--- a/apps/files_sharing/appinfo/routes.php
+++ b/apps/files_sharing/appinfo/routes.php
@@ -102,3 +102,16 @@ API::register('delete',
array('\OCA\Files_Sharing\API\Remote', 'declineShare'),
'files_sharing');
+$sharees = new \OCA\Files_Sharing\API\Sharees(\OC::$server->getGroupManager(),
+ \OC::$server->getUserManager(),
+ \OC::$server->getContactsManager(),
+ \OC::$server->getConfig(),
+ \OC::$server->getUserSession(),
+ \OC::$server->getURLGenerator(),
+ \OC::$server->getRequest(),
+ \OC::$server->getLogger());
+
+API::register('get',
+ '/apps/files_sharing/api/v1/sharees',
+ [$sharees, 'search'],
+ 'files_sharing', API::USER_AUTH);
diff --git a/apps/files_sharing/tests/api/shareestest.php b/apps/files_sharing/tests/api/shareestest.php
new file mode 100644
index 00000000000..1e4438acd88
--- /dev/null
+++ b/apps/files_sharing/tests/api/shareestest.php
@@ -0,0 +1,995 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_Sharing\Tests\API;
+
+use Doctrine\DBAL\Connection;
+use OC\Share\Constants;
+use OCA\Files_Sharing\API\Sharees;
+use OCA\Files_sharing\Tests\TestCase;
+use OCP\Share;
+
+class ShareesTest extends TestCase {
+ /** @var Sharees */
+ protected $sharees;
+
+ /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $userManager;
+
+ /** @var \OCP\IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $groupManager;
+
+ /** @var \OCP\Contacts\IManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $contactsManager;
+
+ /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */
+ protected $session;
+
+ /** @var \OCP\IRequest|\PHPUnit_Framework_MockObject_MockObject */
+ protected $request;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->userManager = $this->getMockBuilder('OCP\IUserManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->groupManager = $this->getMockBuilder('OCP\IGroupManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->contactsManager = $this->getMockBuilder('OCP\Contacts\IManager')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->session = $this->getMockBuilder('OCP\IUserSession')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->request = $this->getMockBuilder('OCP\IRequest')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->sharees = new Sharees(
+ $this->groupManager,
+ $this->userManager,
+ $this->contactsManager,
+ $this->getMockBuilder('OCP\IConfig')->disableOriginalConstructor()->getMock(),
+ $this->session,
+ $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
+ $this->request,
+ $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock()
+ );
+ }
+
+ protected function getUserMock($uid, $displayName) {
+ $user = $this->getMockBuilder('OCP\IUser')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn($uid);
+
+ $user->expects($this->any())
+ ->method('getDisplayName')
+ ->willReturn($displayName);
+
+ return $user;
+ }
+
+ protected function getGroupMock($gid) {
+ $group = $this->getMockBuilder('OCP\IGroup')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $group->expects($this->any())
+ ->method('getGID')
+ ->willReturn($gid);
+
+ return $group;
+ }
+
+ public function dataGetUsers() {
+ return [
+ ['test', false, [], [], [], [], true, false],
+ ['test', true, [], [], [], [], true, false],
+ [
+ 'test', false, [], [],
+ [
+ ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']],
+ ], [], true, $this->getUserMock('test', 'Test')
+ ],
+ [
+ 'test', true, [], [],
+ [
+ ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']],
+ ], [], true, $this->getUserMock('test', 'Test')
+ ],
+ [
+ 'test',
+ false,
+ [],
+ [
+ $this->getUserMock('test1', 'Test One'),
+ ],
+ [],
+ [
+ ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ],
+ true,
+ false,
+ ],
+ [
+ 'test',
+ false,
+ [],
+ [
+ $this->getUserMock('test1', 'Test One'),
+ $this->getUserMock('test2', 'Test Two'),
+ ],
+ [],
+ [
+ ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ['label' => 'Test Two', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
+ ],
+ false,
+ false,
+ ],
+ [
+ 'test',
+ false,
+ [],
+ [
+ $this->getUserMock('test0', 'Test'),
+ $this->getUserMock('test1', 'Test One'),
+ $this->getUserMock('test2', 'Test Two'),
+ ],
+ [
+ ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test0']],
+ ],
+ [
+ ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ['label' => 'Test Two', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
+ ],
+ false,
+ false,
+ ],
+ [
+ 'test',
+ true,
+ ['abc', 'xyz'],
+ [
+ ['abc', 'test', 2, 0, ['test1' => 'Test One']],
+ ['xyz', 'test', 2, 0, []],
+ ],
+ [],
+ [
+ ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ],
+ true,
+ false,
+ ],
+ [
+ 'test',
+ true,
+ ['abc', 'xyz'],
+ [
+ ['abc', 'test', 2, 0, [
+ 'test1' => 'Test One',
+ 'test2' => 'Test Two',
+ ]],
+ ['xyz', 'test', 2, 0, [
+ 'test1' => 'Test One',
+ 'test2' => 'Test Two',
+ ]],
+ ],
+ [],
+ [
+ ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ['label' => 'Test Two', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
+ ],
+ false,
+ false,
+ ],
+ [
+ 'test',
+ true,
+ ['abc', 'xyz'],
+ [
+ ['abc', 'test', 2, 0, [
+ 'test' => 'Test One',
+ ]],
+ ['xyz', 'test', 2, 0, [
+ 'test2' => 'Test Two',
+ ]],
+ ],
+ [
+ ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']],
+ ],
+ [
+ ['label' => 'Test Two', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
+ ],
+ false,
+ false,
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGetUsers
+ *
+ * @param string $searchTerm
+ * @param bool $shareWithGroupOnly
+ * @param array $groupResponse
+ * @param array $userResponse
+ * @param array $exactExpected
+ * @param array $expected
+ * @param bool $reachedEnd
+ * @param mixed $singleUser
+ */
+ public function testGetUsers($searchTerm, $shareWithGroupOnly, $groupResponse, $userResponse, $exactExpected, $expected, $reachedEnd, $singleUser) {
+ $this->invokePrivate($this->sharees, 'limit', [2]);
+ $this->invokePrivate($this->sharees, 'offset', [0]);
+ $this->invokePrivate($this->sharees, 'shareWithGroupOnly', [$shareWithGroupOnly]);
+
+ $user = $this->getUserMock('admin', 'Administrator');
+ $this->session->expects($this->any())
+ ->method('getUser')
+ ->willReturn($user);
+
+ if (!$shareWithGroupOnly) {
+ $this->userManager->expects($this->once())
+ ->method('searchDisplayName')
+ ->with($searchTerm, $this->invokePrivate($this->sharees, 'limit'), $this->invokePrivate($this->sharees, 'offset'))
+ ->willReturn($userResponse);
+ } else {
+ $this->groupManager->expects($this->once())
+ ->method('getUserGroupIds')
+ ->with($user)
+ ->willReturn($groupResponse);
+
+ $this->groupManager->expects($this->exactly(sizeof($groupResponse)))
+ ->method('displayNamesInGroup')
+ ->with($this->anything(), $searchTerm, $this->invokePrivate($this->sharees, 'limit'), $this->invokePrivate($this->sharees, 'offset'))
+ ->willReturnMap($userResponse);
+ }
+
+ if ($singleUser !== false) {
+ $this->userManager->expects($this->once())
+ ->method('get')
+ ->with($searchTerm)
+ ->willReturn($singleUser);
+ }
+
+ $this->invokePrivate($this->sharees, 'getUsers', [$searchTerm]);
+ $result = $this->invokePrivate($this->sharees, 'result');
+
+ $this->assertEquals($exactExpected, $result['exact']['users']);
+ $this->assertEquals($expected, $result['users']);
+ $this->assertCount((int) $reachedEnd, $this->invokePrivate($this->sharees, 'reachedEndFor'));
+ }
+
+ public function dataGetGroups() {
+ return [
+ ['test', false, [], [], [], [], true, false],
+ [
+ 'test', false,
+ [$this->getGroupMock('test1')],
+ [],
+ [],
+ [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
+ true,
+ false,
+ ],
+ [
+ 'test', false,
+ [
+ $this->getGroupMock('test'),
+ $this->getGroupMock('test1'),
+ ],
+ [],
+ [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]],
+ [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
+ false,
+ false,
+ ],
+ [
+ 'test', false,
+ [
+ $this->getGroupMock('test0'),
+ $this->getGroupMock('test1'),
+ ],
+ [],
+ [],
+ [
+ ['label' => 'test0', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test0']],
+ ['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']],
+ ],
+ false,
+ null,
+ ],
+ [
+ 'test', false,
+ [
+ $this->getGroupMock('test0'),
+ $this->getGroupMock('test1'),
+ ],
+ [],
+ [
+ ['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']],
+ ],
+ [
+ ['label' => 'test0', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test0']],
+ ['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']],
+ ],
+ false,
+ $this->getGroupMock('test'),
+ ],
+ ['test', true, [], [], [], [], true, false],
+ [
+ 'test', true,
+ [
+ $this->getGroupMock('test1'),
+ $this->getGroupMock('test2'),
+ ],
+ [$this->getGroupMock('test1')],
+ [],
+ [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
+ false,
+ false,
+ ],
+ [
+ 'test', true,
+ [
+ $this->getGroupMock('test'),
+ $this->getGroupMock('test1'),
+ ],
+ [$this->getGroupMock('test')],
+ [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]],
+ [],
+ false,
+ false,
+ ],
+ [
+ 'test', true,
+ [
+ $this->getGroupMock('test'),
+ $this->getGroupMock('test1'),
+ ],
+ [$this->getGroupMock('test1')],
+ [],
+ [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
+ false,
+ false,
+ ],
+ [
+ 'test', true,
+ [
+ $this->getGroupMock('test'),
+ $this->getGroupMock('test1'),
+ ],
+ [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
+ [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]],
+ [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
+ false,
+ false,
+ ],
+ [
+ 'test', true,
+ [
+ $this->getGroupMock('test0'),
+ $this->getGroupMock('test1'),
+ ],
+ [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
+ [],
+ [
+ ['label' => 'test0', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test0']],
+ ['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']],
+ ],
+ false,
+ null,
+ ],
+ [
+ 'test', true,
+ [
+ $this->getGroupMock('test0'),
+ $this->getGroupMock('test1'),
+ ],
+ [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
+ [
+ ['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']],
+ ],
+ [
+ ['label' => 'test0', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test0']],
+ ['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']],
+ ],
+ false,
+ $this->getGroupMock('test'),
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGetGroups
+ *
+ * @param string $searchTerm
+ * @param bool $shareWithGroupOnly
+ * @param array $groupResponse
+ * @param array $userGroupsResponse
+ * @param array $exactExpected
+ * @param array $expected
+ * @param bool $reachedEnd
+ * @param mixed $singleGroup
+ */
+ public function testGetGroups($searchTerm, $shareWithGroupOnly, $groupResponse, $userGroupsResponse, $exactExpected, $expected, $reachedEnd, $singleGroup) {
+ $this->invokePrivate($this->sharees, 'limit', [2]);
+ $this->invokePrivate($this->sharees, 'offset', [0]);
+ $this->invokePrivate($this->sharees, 'shareWithGroupOnly', [$shareWithGroupOnly]);
+
+ $this->groupManager->expects($this->once())
+ ->method('search')
+ ->with($searchTerm, $this->invokePrivate($this->sharees, 'limit'), $this->invokePrivate($this->sharees, 'offset'))
+ ->willReturn($groupResponse);
+
+ if ($singleGroup !== false) {
+ $this->groupManager->expects($this->once())
+ ->method('get')
+ ->with($searchTerm)
+ ->willReturn($singleGroup);
+ }
+
+ if ($shareWithGroupOnly) {
+ $user = $this->getUserMock('admin', 'Administrator');
+ $this->session->expects($this->any())
+ ->method('getUser')
+ ->willReturn($user);
+
+ $numGetUserGroupsCalls = empty($groupResponse) ? 0 : 1;
+ $this->groupManager->expects($this->exactly($numGetUserGroupsCalls))
+ ->method('getUserGroups')
+ ->with($user)
+ ->willReturn($userGroupsResponse);
+ }
+
+ $this->invokePrivate($this->sharees, 'getGroups', [$searchTerm]);
+ $result = $this->invokePrivate($this->sharees, 'result');
+
+ $this->assertEquals($exactExpected, $result['exact']['groups']);
+ $this->assertEquals($expected, $result['groups']);
+ $this->assertCount((int) $reachedEnd, $this->invokePrivate($this->sharees, 'reachedEndFor'));
+ }
+
+ public function dataGetRemote() {
+ return [
+ ['test', [], [], [], true],
+ [
+ 'test@remote',
+ [],
+ [
+ ['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']],
+ ],
+ [],
+ true,
+ ],
+ [
+ 'test',
+ [
+ [
+ 'FN' => 'User3 @ Localhost',
+ ],
+ [
+ 'FN' => 'User2 @ Localhost',
+ 'CLOUD' => [
+ ],
+ ],
+ [
+ 'FN' => 'User @ Localhost',
+ 'CLOUD' => [
+ 'username@localhost',
+ ],
+ ],
+ ],
+ [],
+ [
+ ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost']],
+ ],
+ true,
+ ],
+ [
+ 'test@remote',
+ [
+ [
+ 'FN' => 'User3 @ Localhost',
+ ],
+ [
+ 'FN' => 'User2 @ Localhost',
+ 'CLOUD' => [
+ ],
+ ],
+ [
+ 'FN' => 'User @ Localhost',
+ 'CLOUD' => [
+ 'username@localhost',
+ ],
+ ],
+ ],
+ [
+ ['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']],
+ ],
+ [
+ ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost']],
+ ],
+ true,
+ ],
+ [
+ 'username@localhost',
+ [
+ [
+ 'FN' => 'User3 @ Localhost',
+ ],
+ [
+ 'FN' => 'User2 @ Localhost',
+ 'CLOUD' => [
+ ],
+ ],
+ [
+ 'FN' => 'User @ Localhost',
+ 'CLOUD' => [
+ 'username@localhost',
+ ],
+ ],
+ ],
+ [
+ ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost']],
+ ],
+ [
+ ],
+ true,
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGetRemote
+ *
+ * @param string $searchTerm
+ * @param array $contacts
+ * @param array $exactExpected
+ * @param array $expected
+ * @param bool $reachedEnd
+ */
+ public function testGetRemote($searchTerm, $contacts, $exactExpected, $expected, $reachedEnd) {
+ $this->contactsManager->expects($this->any())
+ ->method('search')
+ ->with($searchTerm, ['CLOUD', 'FN'])
+ ->willReturn($contacts);
+
+ $this->invokePrivate($this->sharees, 'getRemote', [$searchTerm]);
+ $result = $this->invokePrivate($this->sharees, 'result');
+
+ $this->assertEquals($exactExpected, $result['exact']['remotes']);
+ $this->assertEquals($expected, $result['remotes']);
+ $this->assertCount((int) $reachedEnd, $this->invokePrivate($this->sharees, 'reachedEndFor'));
+ }
+
+ public function dataSearch() {
+ $allTypes = [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE];
+
+ return [
+ [[], '', true, '', null, $allTypes, 1, 200, false],
+
+ // Test itemType
+ [[
+ 'search' => '',
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'search' => 'foobar',
+ ], '', true, 'foobar', null, $allTypes, 1, 200, false],
+ [[
+ 'search' => 0,
+ ], '', true, '0', null, $allTypes, 1, 200, false],
+
+ // Test itemType
+ [[
+ 'itemType' => '',
+ ], '', true, '', '', $allTypes, 1, 200, false],
+ [[
+ 'itemType' => 'folder',
+ ], '', true, '', 'folder', $allTypes, 1, 200, false],
+ [[
+ 'itemType' => 0,
+ ], '', true, '', '0', $allTypes, 1, 200, false],
+
+ // Test shareType
+ [[
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'shareType' => 0,
+ ], '', true, '', null, [0], 1, 200, false],
+ [[
+ 'shareType' => '0',
+ ], '', true, '', null, [0], 1, 200, false],
+ [[
+ 'shareType' => 1,
+ ], '', true, '', null, [1], 1, 200, false],
+ [[
+ 'shareType' => 12,
+ ], '', true, '', null, [], 1, 200, false],
+ [[
+ 'shareType' => 'foobar',
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'shareType' => [0, 1, 2],
+ ], '', true, '', null, [0, 1], 1, 200, false],
+ [[
+ 'shareType' => [0, 1],
+ ], '', true, '', null, [0, 1], 1, 200, false],
+ [[
+ 'shareType' => $allTypes,
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'shareType' => $allTypes,
+ ], '', false, '', null, [0, 1], 1, 200, false],
+
+ // Test pagination
+ [[
+ 'page' => 0,
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'page' => '0',
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'page' => -1,
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'page' => 1,
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'page' => 10,
+ ], '', true, '', null, $allTypes, 10, 200, false],
+
+ // Test limit
+ [[
+ 'limit' => 0,
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'limit' => '0',
+ ], '', true, '', null, $allTypes, 1, 200, false],
+ [[
+ 'limit' => -1,
+ ], '', true, '', null, $allTypes, 1, 1, false],
+ [[
+ 'limit' => 1,
+ ], '', true, '', null, $allTypes, 1, 1, false],
+ [[
+ 'limit' => 10,
+ ], '', true, '', null, $allTypes, 1, 10, false],
+
+ // Test $shareWithGroupOnly setting
+ [[], 'no', true, '', null, $allTypes, 1, 200, false],
+ [[], 'yes', true, '', null, $allTypes, 1, 200, true],
+
+ ];
+ }
+
+ /**
+ * @dataProvider dataSearch
+ *
+ * @param array $getData
+ * @param string $apiSetting
+ * @param bool $remoteSharingEnabled
+ * @param string $search
+ * @param string $itemType
+ * @param array $shareTypes
+ * @param int $page
+ * @param int $perPage
+ * @param bool $shareWithGroupOnly
+ */
+ public function testSearch($getData, $apiSetting, $remoteSharingEnabled, $search, $itemType, $shareTypes, $page, $perPage, $shareWithGroupOnly) {
+ $oldGet = $_GET;
+ $_GET = $getData;
+
+ $config = $this->getMockBuilder('OCP\IConfig')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $config->expects($this->once())
+ ->method('getAppValue')
+ ->with('core', 'shareapi_only_share_with_group_members', 'no')
+ ->willReturn($apiSetting);
+
+ $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees')
+ ->setConstructorArgs([
+ $this->groupManager,
+ $this->userManager,
+ $this->contactsManager,
+ $config,
+ $this->session,
+ $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
+ $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(),
+ $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock()
+ ])
+ ->setMethods(array('searchSharees', 'isRemoteSharingAllowed'))
+ ->getMock();
+ $sharees->expects($this->once())
+ ->method('searchSharees')
+ ->with($search, $itemType, $shareTypes, $page, $perPage)
+ ->willReturnCallback(function
+ ($isearch, $iitemType, $ishareTypes, $ipage, $iperPage)
+ use ($search, $itemType, $shareTypes, $page, $perPage) {
+
+ // We are doing strict comparisons here, so we can differ 0/'' and null on shareType/itemType
+ $this->assertSame($search, $isearch);
+ $this->assertSame($itemType, $iitemType);
+ $this->assertSame($shareTypes, $ishareTypes);
+ $this->assertSame($page, $ipage);
+ $this->assertSame($perPage, $iperPage);
+ return new \OC_OCS_Result([]);
+ });
+ $sharees->expects($this->any())
+ ->method('isRemoteSharingAllowed')
+ ->with($itemType)
+ ->willReturn($remoteSharingEnabled);
+
+ /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\API\Sharees $sharees */
+ $this->assertInstanceOf('\OC_OCS_Result', $sharees->search());
+
+ $this->assertSame($shareWithGroupOnly, $this->invokePrivate($sharees, 'shareWithGroupOnly'));
+
+ $_GET = $oldGet;
+ }
+
+ public function dataIsRemoteSharingAllowed() {
+ return [
+ ['file', true],
+ ['folder', true],
+ ['', false],
+ ['contacts', false],
+ ];
+ }
+
+ /**
+ * @dataProvider dataIsRemoteSharingAllowed
+ *
+ * @param string $itemType
+ * @param bool $expected
+ */
+ public function testIsRemoteSharingAllowed($itemType, $expected) {
+ $this->assertSame($expected, $this->invokePrivate($this->sharees, 'isRemoteSharingAllowed', [$itemType]));
+ }
+
+ public function dataSearchSharees() {
+ return [
+ ['test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, false, [], [], [],
+ [
+ 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
+ 'users' => [],
+ 'groups' => [],
+ 'remotes' => [],
+ ], false],
+ ['test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, false, [], [], [],
+ [
+ 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
+ 'users' => [],
+ 'groups' => [],
+ 'remotes' => [],
+ ], false],
+ [
+ 'test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, false, [
+ ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ], [
+ ['label' => 'testgroup1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'testgroup1']],
+ ], [
+ ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']],
+ ],
+ [
+ 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
+ 'users' => [
+ ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ],
+ 'groups' => [
+ ['label' => 'testgroup1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'testgroup1']],
+ ],
+ 'remotes' => [
+ ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']],
+ ],
+ ], true,
+ ],
+ // No groups requested
+ [
+ 'test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_REMOTE], 1, 2, false, [
+ ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ], null, [
+ ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']],
+ ],
+ [
+ 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
+ 'users' => [
+ ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ],
+ 'groups' => [],
+ 'remotes' => [
+ ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']],
+ ],
+ ], false,
+ ],
+ // Share type restricted to user - Only one user
+ [
+ 'test', 'folder', [Share::SHARE_TYPE_USER], 1, 2, false, [
+ ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ], null, null,
+ [
+ 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
+ 'users' => [
+ ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ],
+ 'groups' => [],
+ 'remotes' => [],
+ ], false,
+ ],
+ // Share type restricted to user - Multipage result
+ [
+ 'test', 'folder', [Share::SHARE_TYPE_USER], 1, 2, false, [
+ ['label' => 'test 1', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ['label' => 'test 2', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
+ ], null, null,
+ [
+ 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
+ 'users' => [
+ ['label' => 'test 1', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
+ ['label' => 'test 2', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
+ ],
+ 'groups' => [],
+ 'remotes' => [],
+ ], true,
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider dataSearchSharees
+ *
+ * @param string $searchTerm
+ * @param string $itemType
+ * @param array $shareTypes
+ * @param int $page
+ * @param int $perPage
+ * @param bool $shareWithGroupOnly
+ * @param array $mockedUserResult
+ * @param array $mockedGroupsResult
+ * @param array $mockedRemotesResult
+ * @param array $expected
+ * @param bool $nextLink
+ */
+ public function testSearchSharees($searchTerm, $itemType, array $shareTypes, $page, $perPage, $shareWithGroupOnly,
+ $mockedUserResult, $mockedGroupsResult, $mockedRemotesResult, $expected, $nextLink) {
+ /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\API\Sharees $sharees */
+ $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees')
+ ->setConstructorArgs([
+ $this->groupManager,
+ $this->userManager,
+ $this->contactsManager,
+ $this->getMockBuilder('OCP\IConfig')->disableOriginalConstructor()->getMock(),
+ $this->session,
+ $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
+ $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(),
+ $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock()
+ ])
+ ->setMethods(array('getShareesForShareIds', 'getUsers', 'getGroups', 'getRemote'))
+ ->getMock();
+ $sharees->expects(($mockedUserResult === null) ? $this->never() : $this->once())
+ ->method('getUsers')
+ ->with($searchTerm)
+ ->willReturnCallback(function() use ($sharees, $mockedUserResult) {
+ $result = $this->invokePrivate($sharees, 'result');
+ $result['users'] = $mockedUserResult;
+ $this->invokePrivate($sharees, 'result', [$result]);
+ });
+ $sharees->expects(($mockedGroupsResult === null) ? $this->never() : $this->once())
+ ->method('getGroups')
+ ->with($searchTerm)
+ ->willReturnCallback(function() use ($sharees, $mockedGroupsResult) {
+ $result = $this->invokePrivate($sharees, 'result');
+ $result['groups'] = $mockedGroupsResult;
+ $this->invokePrivate($sharees, 'result', [$result]);
+ });
+ $sharees->expects(($mockedRemotesResult === null) ? $this->never() : $this->once())
+ ->method('getRemote')
+ ->with($searchTerm)
+ ->willReturnCallback(function() use ($sharees, $mockedRemotesResult) {
+ $result = $this->invokePrivate($sharees, 'result');
+ $result['remotes'] = $mockedRemotesResult;
+ $this->invokePrivate($sharees, 'result', [$result]);
+ });
+
+ /** @var \OC_OCS_Result $ocs */
+ $ocs = $this->invokePrivate($sharees, 'searchSharees', [$searchTerm, $itemType, $shareTypes, $page, $perPage, $shareWithGroupOnly]);
+ $this->assertInstanceOf('\OC_OCS_Result', $ocs);
+ $this->assertEquals($expected, $ocs->getData());
+
+ // Check if next link is set
+ if ($nextLink) {
+ $headers = $ocs->getHeaders();
+ $this->assertArrayHasKey('Link', $headers);
+ $this->assertStringStartsWith('<', $headers['Link']);
+ $this->assertStringEndsWith('>; rel="next"', $headers['Link']);
+ }
+ }
+
+ public function testSearchShareesNoItemType() {
+ /** @var \OC_OCS_Result $ocs */
+ $ocs = $this->invokePrivate($this->sharees, 'searchSharees', ['', null, [], [], 0, 0, false]);
+ $this->assertInstanceOf('\OC_OCS_Result', $ocs);
+
+ $this->assertSame(400, $ocs->getStatusCode(), 'Expected status code 400');
+ $this->assertSame([], $ocs->getData(), 'Expected that no data is send');
+
+ $meta = $ocs->getMeta();
+ $this->assertNotEmpty($meta);
+ $this->assertArrayHasKey('message', $meta);
+ $this->assertSame('missing itemType', $meta['message']);
+ }
+
+ public function dataGetPaginationLink() {
+ return [
+ [1, '/ocs/v1.php', ['limit' => 2], '<?limit=2&page=2>; rel="next"'],
+ [10, '/ocs/v2.php', ['limit' => 2], '<?limit=2&page=11>; rel="next"'],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGetPaginationLink
+ *
+ * @param int $page
+ * @param string $scriptName
+ * @param array $params
+ * @param array $expected
+ */
+ public function testGetPaginationLink($page, $scriptName, $params, $expected) {
+ $this->request->expects($this->once())
+ ->method('getScriptName')
+ ->willReturn($scriptName);
+
+ $this->assertEquals($expected, $this->invokePrivate($this->sharees, 'getPaginationLink', [$page, $params]));
+ }
+
+ public function dataIsV2() {
+ return [
+ ['/ocs/v1.php', false],
+ ['/ocs/v2.php', true],
+ ];
+ }
+
+ /**
+ * @dataProvider dataIsV2
+ *
+ * @param string $scriptName
+ * @param bool $expected
+ */
+ public function testIsV2($scriptName, $expected) {
+ $this->request->expects($this->once())
+ ->method('getScriptName')
+ ->willReturn($scriptName);
+
+ $this->assertEquals($expected, $this->invokePrivate($this->sharees, 'isV2'));
+ }
+}