diff options
author | blizzz <blizzz@arthur-schiwon.de> | 2017-10-04 15:43:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-04 15:43:44 +0200 |
commit | 2d62f97f1bf1e7848e23ff0417915c3ab9e03e9a (patch) | |
tree | f1a67d6f764999fa802aa7034711321af684ddb9 /tests | |
parent | 5412c239f2ca128760c8d12de3bcd01384ddfd3f (diff) | |
parent | a579f8aa375bf02f9763892ce725713f08526a1a (diff) | |
download | nextcloud-server-2d62f97f1bf1e7848e23ff0417915c3ab9e03e9a.tar.gz nextcloud-server-2d62f97f1bf1e7848e23ff0417915c3ab9e03e9a.zip |
Merge pull request #6328 from nextcloud/split-sharees-api-logic
Splits off the logic from sharees endpoint thus making it available from within Nc/via PHP.
Diffstat (limited to 'tests')
6 files changed, 2059 insertions, 0 deletions
diff --git a/tests/lib/Collaboration/Collaborators/GroupPluginTest.php b/tests/lib/Collaboration/Collaborators/GroupPluginTest.php new file mode 100644 index 00000000000..9849bdb874a --- /dev/null +++ b/tests/lib/Collaboration/Collaborators/GroupPluginTest.php @@ -0,0 +1,491 @@ +<?php +/** + * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @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\Collaboration\Collaborators; + + +use OC\Collaboration\Collaborators\GroupPlugin; +use OC\Collaboration\Collaborators\SearchResult; +use OCP\Collaboration\Collaborators\ISearchResult; +use OCP\IConfig; +use OCP\IGroup; +use OCP\IGroupManager; +use OCP\IUser; +use OCP\IUserSession; +use OCP\Share; +use Test\TestCase; + +class GroupPluginTest extends TestCase { + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + protected $config; + + /** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $groupManager; + + /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */ + protected $session; + + /** @var ISearchResult */ + protected $searchResult; + + /** @var GroupPlugin */ + protected $plugin; + + /** @var int */ + protected $limit = 2; + + /** @var int */ + protected $offset = 0; + + /** @var IUser|\PHPUnit_Framework_MockObject_MockObject */ + protected $user; + + public function setUp() { + parent::setUp(); + + $this->config = $this->createMock(IConfig::class); + + $this->groupManager = $this->createMock(IGroupManager::class); + + $this->session = $this->createMock(IUserSession::class); + + $this->searchResult = new SearchResult(); + + $this->user = $this->getUserMock('admin', 'Administrator'); + } + + public function instantiatePlugin() { + // cannot be done within setUp, because dependent mocks needs to be set + // up with configuration etc. first + $this->plugin = new GroupPlugin( + $this->config, + $this->groupManager, + $this->session + ); + } + + public function getUserMock($uid, $displayName) { + $user = $this->createMock(IUser::class); + + $user->expects($this->any()) + ->method('getUID') + ->willReturn($uid); + + $user->expects($this->any()) + ->method('getDisplayName') + ->willReturn($displayName); + + return $user; + } + + /** + * @param string $gid + * @param null $displayName + * @return IGroup|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getGroupMock($gid, $displayName = null) { + $group = $this->createMock(IGroup::class); + + $group->expects($this->any()) + ->method('getGID') + ->willReturn($gid); + + if (is_null($displayName)) { + // note: this is how the Group class behaves + $displayName = $gid; + } + + $group->expects($this->any()) + ->method('getDisplayName') + ->willReturn($displayName); + + return $group; + } + + public function dataGetGroups() { + return [ + ['test', false, true, [], [], [], [], true, false], + ['test', false, false, [], [], [], [], true, false], + // group without display name + [ + 'test', false, true, + [$this->getGroupMock('test1')], + [], + [], + [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]], + true, + false, + ], + // group with display name, search by id + [ + 'test', false, true, + [$this->getGroupMock('test1', 'Test One')], + [], + [], + [['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]], + true, + false, + ], + // group with display name, search by display name + [ + 'one', false, true, + [$this->getGroupMock('test1', 'Test One')], + [], + [], + [['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]], + true, + false, + ], + // group with display name, search by display name, exact expected + [ + 'Test One', false, true, + [$this->getGroupMock('test1', 'Test One')], + [], + [['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]], + [], + true, + false, + ], + [ + 'test', false, false, + [$this->getGroupMock('test1')], + [], + [], + [], + true, + false, + ], + [ + 'test', false, true, + [ + $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, false, + [ + $this->getGroupMock('test'), + $this->getGroupMock('test1'), + ], + [], + [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]], + [], + true, + false, + ], + [ + 'test', false, true, + [ + $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, false, + [ + $this->getGroupMock('test0'), + $this->getGroupMock('test1'), + ], + [], + [], + [], + true, + null, + ], + [ + 'test', false, true, + [ + $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', false, false, + [ + $this->getGroupMock('test0'), + $this->getGroupMock('test1'), + ], + [], + [ + ['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']], + ], + [], + true, + $this->getGroupMock('test'), + ], + ['test', true, true, [], [], [], [], true, false], + ['test', true, false, [], [], [], [], true, false], + [ + 'test', true, true, + [ + $this->getGroupMock('test1'), + $this->getGroupMock('test2'), + ], + [$this->getGroupMock('test1')], + [], + [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]], + false, + false, + ], + [ + 'test', true, false, + [ + $this->getGroupMock('test1'), + $this->getGroupMock('test2'), + ], + [$this->getGroupMock('test1')], + [], + [], + true, + false, + ], + [ + 'test', true, true, + [ + $this->getGroupMock('test'), + $this->getGroupMock('test1'), + ], + [$this->getGroupMock('test')], + [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]], + [], + false, + false, + ], + [ + 'test', true, false, + [ + $this->getGroupMock('test'), + $this->getGroupMock('test1'), + ], + [$this->getGroupMock('test')], + [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]], + [], + true, + false, + ], + [ + 'test', true, true, + [ + $this->getGroupMock('test'), + $this->getGroupMock('test1'), + ], + [$this->getGroupMock('test1')], + [], + [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]], + false, + false, + ], + [ + 'test', true, false, + [ + $this->getGroupMock('test'), + $this->getGroupMock('test1'), + ], + [$this->getGroupMock('test1')], + [], + [], + true, + false, + ], + [ + 'test', true, 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, false, + [ + $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']]], + [], + true, + false, + ], + [ + 'test', true, 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, false, + [ + $this->getGroupMock('test0'), + $this->getGroupMock('test1'), + ], + [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')], + [], + [], + true, + null, + ], + [ + 'test', true, 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'), + ], + [ + 'test', true, false, + [ + $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']], + ], + [], + true, + $this->getGroupMock('test'), + ], + ]; + } + + /** + * @dataProvider dataGetGroups + * + * @param string $searchTerm + * @param bool $shareWithGroupOnly + * @param bool $shareeEnumeration + * @param array $groupResponse + * @param array $userGroupsResponse + * @param array $exactExpected + * @param array $expected + * @param bool $reachedEnd + * @param bool|IGroup $singleGroup + */ + public function testSearch( + $searchTerm, + $shareWithGroupOnly, + $shareeEnumeration, + array $groupResponse, + array $userGroupsResponse, + array $exactExpected, + array $expected, + $reachedEnd, + $singleGroup + ) { + $this->config->expects($this->any()) + ->method('getAppValue') + ->willReturnCallback( + function($appName, $key, $default) + use ($shareWithGroupOnly, $shareeEnumeration) + { + if ($appName === 'core' && $key === 'shareapi_only_share_with_group_members') { + return $shareWithGroupOnly ? 'yes' : 'no'; + } else if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') { + return $shareeEnumeration ? 'yes' : 'no'; + } + return $default; + } + ); + + $this->instantiatePlugin(); + + $this->groupManager->expects($this->once()) + ->method('search') + ->with($searchTerm, $this->limit, $this->offset) + ->willReturn($groupResponse); + + if ($singleGroup !== false) { + $this->groupManager->expects($this->once()) + ->method('get') + ->with($searchTerm) + ->willReturn($singleGroup); + } + + if ($shareWithGroupOnly) { + $this->session->expects($this->any()) + ->method('getUser') + ->willReturn($this->user); + + $numGetUserGroupsCalls = empty($groupResponse) ? 0 : 1; + $this->groupManager->expects($this->exactly($numGetUserGroupsCalls)) + ->method('getUserGroups') + ->with($this->user) + ->willReturn($userGroupsResponse); + } + + $moreResults = $this->plugin->search($searchTerm, $this->limit, $this->offset, $this->searchResult); + $result = $this->searchResult->asArray(); + + $this->assertEquals($exactExpected, $result['exact']['groups']); + $this->assertEquals($expected, $result['groups']); + $this->assertSame($reachedEnd, $moreResults); + } +} diff --git a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php new file mode 100644 index 00000000000..83d366cf467 --- /dev/null +++ b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php @@ -0,0 +1,180 @@ +<?php +/** + * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @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\Collaboration\Collaborators; + + +use OC\Collaboration\Collaborators\LookupPlugin; +use OCP\Collaboration\Collaborators\ISearchResult; +use OCP\Collaboration\Collaborators\SearchResultType; +use OCP\Http\Client\IClient; +use OCP\Http\Client\IClientService; +use OCP\Http\Client\IResponse; +use OCP\IConfig; +use OCP\Share; +use Test\TestCase; + +class LookupPluginTest extends TestCase { + + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + protected $config; + /** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */ + protected $clientService; + /** @var LookupPlugin */ + protected $plugin; + + public function setUp() { + parent::setUp(); + + $this->config = $this->createMock(IConfig::class); + $this->clientService = $this->createMock(IClientService::class); + + $this->plugin = new LookupPlugin($this->config, $this->clientService); + } + + /** + * @dataProvider searchDataProvider + * @param array $searchParams + */ + public function testSearch(array $searchParams) { + $type = new SearchResultType('lookup'); + + /** @var ISearchResult|\PHPUnit_Framework_MockObject_MockObject $searchResult */ + $searchResult = $this->createMock(ISearchResult::class); + $searchResult->expects($this->once()) + ->method('addResultSet') + ->with($type, $searchParams['expectedResult'], []); + + $this->config->expects($this->once()) + ->method('getAppValue') + ->with('files_sharing', 'lookupServerEnabled', 'no') + ->willReturn('yes'); + $this->config->expects($this->once()) + ->method('getSystemValue') + ->with('lookup_server', 'https://lookup.nextcloud.com') + ->willReturn($searchParams['server']); + + $response = $this->createMock(IResponse::class); + $response->expects($this->once()) + ->method('getBody') + ->willReturn(json_encode($searchParams['resultBody'])); + + $client = $this->createMock(IClient::class); + $client->expects($this->once()) + ->method('get') + ->willReturnCallback(function($url) use ($searchParams, $response) { + $this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0); + $this->assertNotFalse(strpos($url, urlencode($searchParams['search']))); + return $response; + }); + + $this->clientService->expects($this->once()) + ->method('newClient') + ->willReturn($client); + + $moreResults = $this->plugin->search( + $searchParams['search'], + $searchParams['limit'], + $searchParams['offset'], + $searchResult + ); + + + + $this->assertFalse($moreResults); + } + + public function testSearchLookupServerDisabled() { + $this->config->expects($this->once()) + ->method('getAppValue') + ->with('files_sharing', 'lookupServerEnabled', 'no') + ->willReturn('no'); + + /** @var ISearchResult|\PHPUnit_Framework_MockObject_MockObject $searchResult */ + $searchResult = $this->createMock(ISearchResult::class); + $searchResult->expects($this->never()) + ->method('addResultSet'); + $searchResult->expects($this->never()) + ->method('markExactIdMatch'); + + $this->assertFalse($this->plugin->search('irr', 10, 0, $searchResult)); + } + + public function searchDataProvider() { + $fedIDs = [ + 'foo@enceladus.moon', + 'foobar@enceladus.moon', + 'foongus@enceladus.moon', + ]; + + return [ + // #0, standard search with results + [[ + 'search' => 'foo', + 'limit' => 10, + 'offset' => 0, + 'server' => 'https://lookup.example.io', + 'resultBody' => [ + [ 'federationId' => $fedIDs[0] ], + [ 'federationId' => $fedIDs[1] ], + [ 'federationId' => $fedIDs[2] ], + ], + 'expectedResult' => [ + [ + 'label' => $fedIDs[0], + 'value' => [ + 'shareType' => Share::SHARE_TYPE_REMOTE, + 'shareWith' => $fedIDs[0] + ], + 'extra' => ['federationId' => $fedIDs[0]], + ], + [ + 'label' => $fedIDs[1], + 'value' => [ + 'shareType' => Share::SHARE_TYPE_REMOTE, + 'shareWith' => $fedIDs[1] + ], + 'extra' => ['federationId' => $fedIDs[1]], + ], + [ + 'label' => $fedIDs[2], + 'value' => [ + 'shareType' => Share::SHARE_TYPE_REMOTE, + 'shareWith' => $fedIDs[2] + ], + 'extra' => ['federationId' => $fedIDs[2]], + ], + ] + ]], + // #1, search without results + [[ + 'search' => 'foo', + 'limit' => 10, + 'offset' => 0, + 'server' => 'https://lookup.example.io', + 'resultBody' => [], + 'expectedResult' => [], + ]], + ]; + } +} diff --git a/tests/lib/Collaboration/Collaborators/MailPluginTest.php b/tests/lib/Collaboration/Collaborators/MailPluginTest.php new file mode 100644 index 00000000000..9c9d9cff909 --- /dev/null +++ b/tests/lib/Collaboration/Collaborators/MailPluginTest.php @@ -0,0 +1,336 @@ +<?php +/** + * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @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\Collaboration\Collaborators; + + +use OC\Collaboration\Collaborators\MailPlugin; +use OC\Collaboration\Collaborators\SearchResult; +use OC\Federation\CloudIdManager; +use OCP\Collaboration\Collaborators\SearchResultType; +use OCP\Contacts\IManager; +use OCP\Federation\ICloudIdManager; +use OCP\IConfig; +use OCP\Share; +use Test\TestCase; + +class MailPluginTest extends TestCase { + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + protected $config; + + /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $contactsManager; + + /** @var ICloudIdManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $cloudIdManager; + + /** @var MailPlugin */ + protected $plugin; + + /** @var SearchResult */ + protected $searchResult; + + public function setUp() { + parent::setUp(); + + $this->config = $this->createMock(IConfig::class); + $this->contactsManager = $this->createMock(IManager::class); + $this->cloudIdManager = new CloudIdManager(); + $this->searchResult = new SearchResult(); + } + + public function instantiatePlugin() { + $this->plugin = new MailPlugin($this->contactsManager, $this->cloudIdManager, $this->config); + } + + /** + * @dataProvider dataGetEmail + * + * @param string $searchTerm + * @param array $contacts + * @param bool $shareeEnumeration + * @param array $expected + * @param bool $reachedEnd + */ + public function testSearch($searchTerm, $contacts, $shareeEnumeration, $expected, $exactIdMatch, $reachedEnd) { + $this->config->expects($this->any()) + ->method('getAppValue') + ->willReturnCallback( + function($appName, $key, $default) + use ($shareeEnumeration) + { + if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') { + return $shareeEnumeration ? 'yes' : 'no'; + } + return $default; + } + ); + + $this->instantiatePlugin(); + + $this->contactsManager->expects($this->any()) + ->method('search') + ->with($searchTerm, ['EMAIL', 'FN']) + ->willReturn($contacts); + + $moreResults = $this->plugin->search($searchTerm, 0, 0, $this->searchResult); + $result = $this->searchResult->asArray(); + + $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails'))); + $this->assertEquals($expected, $result); + $this->assertSame($reachedEnd, $moreResults); + } + + public function dataGetEmail() { + return [ + ['test', [], true, ['emails' => [], 'exact' => ['emails' => []]], false, true], + ['test', [], false, ['emails' => [], 'exact' => ['emails' => []]], false, true], + [ + 'test@remote.com', + [], + true, + ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + false, + true, + ], + [ // no valid email address + 'test@remote', + [], + true, + ['emails' => [], 'exact' => ['emails' => []]], + false, + true, + ], + [ + 'test@remote.com', + [], + false, + ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + false, + true, + ], + [ + 'test', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost', + ], + ], + ], + true, + ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => []]], + false, + true, + ], + [ + 'test', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost', + ], + ], + ], + false, + ['emails' => [], 'exact' => ['emails' => []]], + false, + true, + ], + [ + 'test@remote.com', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost', + ], + ], + ], + true, + ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + false, + true, + ], + [ + 'test@remote.com', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost', + ], + ], + ], + false, + ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + false, + true, + ], + [ + 'username@localhost', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost', + ], + ], + ], + true, + ['emails' => [], 'exact' => ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], + true, + true, + ], + [ + 'username@localhost', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost', + ], + ], + ], + false, + ['emails' => [], 'exact' => ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], + true, + true, + ], + // contact with space + [ + 'user name@localhost', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User Name @ Localhost', + 'EMAIL' => [ + 'user name@localhost', + ], + ], + ], + false, + ['emails' => [], 'exact' => ['emails' => [['label' => 'User Name @ Localhost (user name@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'user name@localhost']]]]], + true, + true, + ], + // remote with space, no contact + [ + 'user space@remote.com', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost', + ], + ], + ], + false, + ['emails' => [], 'exact' => ['emails' => []]], + false, + true, + ], + // Local user found by email + [ + 'test@example.com', + [ + [ + 'FN' => 'User', + 'EMAIL' => ['test@example.com'], + 'CLOUD' => ['test@localhost'], + 'isLocalSystemBook' => true, + ] + ], + false, + ['users' => [], 'exact' => ['users' => [['label' => 'User (test@example.com)','value' => ['shareType' => 0, 'shareWith' => 'test'],]]]], + true, + false, + ] + ]; + } +} diff --git a/tests/lib/Collaboration/Collaborators/RemotePluginTest.php b/tests/lib/Collaboration/Collaborators/RemotePluginTest.php new file mode 100644 index 00000000000..5c4b3af5e70 --- /dev/null +++ b/tests/lib/Collaboration/Collaborators/RemotePluginTest.php @@ -0,0 +1,388 @@ +<?php +/** + * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @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\Collaboration\Collaborators; + + +use OC\Collaboration\Collaborators\RemotePlugin; +use OC\Collaboration\Collaborators\SearchResult; +use OC\Federation\CloudIdManager; +use OCP\Collaboration\Collaborators\SearchResultType; +use OCP\Contacts\IManager; +use OCP\Federation\ICloudIdManager; +use OCP\IConfig; +use OCP\Share; +use Test\TestCase; + +class RemotePluginTest extends TestCase { + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + protected $config; + + /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $contactsManager; + + /** @var ICloudIdManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $cloudIdManager; + + /** @var RemotePlugin */ + protected $plugin; + + /** @var SearchResult */ + protected $searchResult; + + public function setUp() { + parent::setUp(); + + $this->config = $this->createMock(IConfig::class); + $this->contactsManager = $this->createMock(IManager::class); + $this->cloudIdManager = new CloudIdManager(); + $this->searchResult = new SearchResult(); + } + + public function instantiatePlugin() { + $this->plugin = new RemotePlugin($this->contactsManager, $this->cloudIdManager, $this->config); + } + + /** + * @dataProvider dataGetRemote + * + * @param string $searchTerm + * @param array $contacts + * @param bool $shareeEnumeration + * @param array $expected + * @param bool $exactIdMatch + * @param bool $reachedEnd + */ + public function testSearch($searchTerm, array $contacts, $shareeEnumeration, array $expected, $exactIdMatch, $reachedEnd) { + $this->config->expects($this->any()) + ->method('getAppValue') + ->willReturnCallback( + function($appName, $key, $default) + use ($shareeEnumeration) + { + if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') { + return $shareeEnumeration ? 'yes' : 'no'; + } + return $default; + } + ); + + $this->instantiatePlugin(); + + $this->contactsManager->expects($this->any()) + ->method('search') + ->with($searchTerm, ['CLOUD', 'FN']) + ->willReturn($contacts); + + $moreResults = $this->plugin->search($searchTerm, 0, 0, $this->searchResult); + $result = $this->searchResult->asArray(); + + $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('remotes'))); + $this->assertEquals($expected, $result); + $this->assertSame($reachedEnd, $moreResults); + } + + /** + * @dataProvider dataTestSplitUserRemote + * + * @param string $remote + * @param string $expectedUser + * @param string $expectedUrl + */ + public function testSplitUserRemote($remote, $expectedUser, $expectedUrl) { + $this->instantiatePlugin(); + + list($remoteUser, $remoteUrl) = $this->plugin->splitUserRemote($remote); + $this->assertSame($expectedUser, $remoteUser); + $this->assertSame($expectedUrl, $remoteUrl); + } + + /** + * @dataProvider dataTestSplitUserRemoteError + * + * @param string $id + * @expectedException \Exception + */ + public function testSplitUserRemoteError($id) { + $this->instantiatePlugin(); + $this->plugin->splitUserRemote($id); + } + + public function dataGetRemote() { + return [ + ['test', [], true, ['remotes' => [], 'exact' => ['remotes' => []]], false, true], + ['test', [], false, ['remotes' => [], 'exact' => ['remotes' => []]], false, true], + [ + 'test@remote', + [], + true, + ['remotes' => [], 'exact' => ['remotes' => [['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']]]]], + false, + true, + ], + [ + 'test@remote', + [], + false, + ['remotes' => [], 'exact' => ['remotes' => [['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']]]]], + false, + true, + ], + [ + 'test', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'CLOUD' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'CLOUD' => [ + 'username@localhost', + ], + ], + ], + true, + ['remotes' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => []]], + false, + true, + ], + [ + 'test', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'CLOUD' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'CLOUD' => [ + 'username@localhost', + ], + ], + ], + false, + ['remotes' => [], 'exact' => ['remotes' => []]], + false, + true, + ], + [ + 'test@remote', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'CLOUD' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'CLOUD' => [ + 'username@localhost', + ], + ], + ], + true, + ['remotes' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => [['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']]]]], + false, + true, + ], + [ + 'test@remote', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'CLOUD' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'CLOUD' => [ + 'username@localhost', + ], + ], + ], + false, + ['remotes' => [], 'exact' => ['remotes' => [['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']]]]], + false, + true, + ], + [ + 'username@localhost', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'CLOUD' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'CLOUD' => [ + 'username@localhost', + ], + ], + ], + true, + ['remotes' => [], 'exact' => ['remotes' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]], + true, + true, + ], + [ + 'username@localhost', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'CLOUD' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'CLOUD' => [ + 'username@localhost', + ], + ], + ], + false, + ['remotes' => [], 'exact' => ['remotes' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]], + true, + true, + ], + // contact with space + [ + 'user name@localhost', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'CLOUD' => [ + ], + ], + [ + 'FN' => 'User Name @ Localhost', + 'CLOUD' => [ + 'user name@localhost', + ], + ], + ], + false, + ['remotes' => [], 'exact' => ['remotes' => [['label' => 'User Name @ Localhost (user name@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'user name@localhost', 'server' => 'localhost']]]]], + true, + true, + ], + // remote with space, no contact + [ + 'user space@remote', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'CLOUD' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'CLOUD' => [ + 'username@localhost', + ], + ], + ], + false, + ['remotes' => [], 'exact' => ['remotes' => [['label' => 'user space@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'user space@remote']]]]], + false, + true, + ], + ]; + } + + public function dataTestSplitUserRemote() { + $userPrefix = ['user@name', 'username']; + $protocols = ['', 'http://', 'https://']; + $remotes = [ + 'localhost', + 'local.host', + 'dev.local.host', + 'dev.local.host/path', + 'dev.local.host/at@inpath', + '127.0.0.1', + '::1', + '::192.0.2.128', + '::192.0.2.128/at@inpath', + ]; + + $testCases = []; + foreach ($userPrefix as $user) { + foreach ($remotes as $remote) { + foreach ($protocols as $protocol) { + $baseUrl = $user . '@' . $protocol . $remote; + + $testCases[] = [$baseUrl, $user, $protocol . $remote]; + $testCases[] = [$baseUrl . '/', $user, $protocol . $remote]; + $testCases[] = [$baseUrl . '/index.php', $user, $protocol . $remote]; + $testCases[] = [$baseUrl . '/index.php/s/token', $user, $protocol . $remote]; + } + } + } + return $testCases; + } + + public function dataTestSplitUserRemoteError() { + return array( + // Invalid path + array('user@'), + + // Invalid user + array('@server'), + array('us/er@server'), + array('us:er@server'), + + // Invalid splitting + array('user'), + array(''), + array('us/erserver'), + array('us:erserver'), + ); + } +} diff --git a/tests/lib/Collaboration/Collaborators/SearchTest.php b/tests/lib/Collaboration/Collaborators/SearchTest.php new file mode 100644 index 00000000000..80e6c7f0beb --- /dev/null +++ b/tests/lib/Collaboration/Collaborators/SearchTest.php @@ -0,0 +1,219 @@ +<?php +/** + * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @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\Collaboration\Collaborators; + + +use OC\Collaboration\Collaborators\Search; +use OC\Collaboration\Collaborators\SearchResult; +use OCP\Collaboration\Collaborators\ISearch; +use OCP\Collaboration\Collaborators\ISearchPlugin; +use OCP\Collaboration\Collaborators\SearchResultType; +use OCP\IContainer; +use OCP\Share; +use Test\TestCase; + +class SearchTest extends TestCase { + /** @var IContainer|\PHPUnit_Framework_MockObject_MockObject */ + protected $container; + /** @var ISearch */ + protected $search; + + public function setUp() { + parent::setUp(); + + $this->container = $this->createMock(IContainer::class); + + $this->search = new Search($this->container); + } + + /** + * @dataProvider dataSearchSharees + * + * @param string $searchTerm + * @param array $shareTypes + * @param int $page + * @param int $perPage + * @param array $mockedUserResult + * @param array $mockedGroupsResult + * @param array $mockedRemotesResult + * @param array $expected + * @param bool $expectedMoreResults + */ + public function testSearch( + $searchTerm, + array $shareTypes, + $page, + $perPage, + array $mockedUserResult, + array $mockedGroupsResult, + array $mockedRemotesResult, + array $expected, + $expectedMoreResults + ) { + $searchResult = new SearchResult(); + + $userPlugin = $this->createMock(ISearchPlugin::class); + $userPlugin->expects($this->any()) + ->method('search') + ->willReturnCallback(function() use ($searchResult, $mockedUserResult, $expectedMoreResults) { + $type = new SearchResultType('users'); + $searchResult->addResultSet($type, $mockedUserResult); + return $expectedMoreResults; + }); + + $groupPlugin = $this->createMock(ISearchPlugin::class); + $groupPlugin->expects($this->any()) + ->method('search') + ->willReturnCallback(function() use ($searchResult, $mockedGroupsResult, $expectedMoreResults) { + $type = new SearchResultType('groups'); + $searchResult->addResultSet($type, $mockedGroupsResult); + return $expectedMoreResults; + }); + + $remotePlugin = $this->createMock(ISearchPlugin::class); + $remotePlugin->expects($this->any()) + ->method('search') + ->willReturnCallback(function() use ($searchResult, $mockedRemotesResult, $expectedMoreResults) { + if($mockedRemotesResult !== null) { + $type = new SearchResultType('remotes'); + $searchResult->addResultSet($type, $mockedRemotesResult['results'], $mockedRemotesResult['exact']); + if($mockedRemotesResult['exactIdMatch'] === true) { + $searchResult->markExactIdMatch($type); + } + } + return $expectedMoreResults; + }); + + $this->container->expects($this->any()) + ->method('resolve') + ->willReturnCallback(function($class) use ($searchResult, $userPlugin, $groupPlugin, $remotePlugin) { + if($class === SearchResult::class) { + return $searchResult; + } elseif ($class === $userPlugin) { + return $userPlugin; + } elseif ($class === $groupPlugin) { + return $groupPlugin; + } elseif ($class === $remotePlugin) { + return $remotePlugin; + } + return null; + }); + + $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => $userPlugin]); + $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_GROUP', 'class' => $groupPlugin]); + $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE', 'class' => $remotePlugin]); + + list($results, $moreResults) = $this->search->search($searchTerm, $shareTypes, false, $perPage, $perPage * ($page - 1)); + + $this->assertEquals($expected, $results); + $this->assertSame($expectedMoreResults, $moreResults); + } + + public function dataSearchSharees() { + return [ + [ + 'test', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false], + [ + 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], + 'users' => [], + 'groups' => [], + 'remotes' => [], + ], false + ], + [ + 'test', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false], + [ + 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], + 'users' => [], + 'groups' => [], + 'remotes' => [], + ], false + ], + [ + 'test', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, [ + ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], + ], [ + ['label' => 'testgroup1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'testgroup1']], + ], [ + 'results' => [['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false, + ], + [ + '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', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_REMOTE], 1, 2, [ + ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], + ], [], [ + 'results' => [['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false + ], + [ + 'exact' => ['users' => [], 'remotes' => []], + 'users' => [ + ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], + ], + 'remotes' => [ + ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']], + ], + ], false, + ], + // Share type restricted to user - Only one user + [ + 'test', [Share::SHARE_TYPE_USER], 1, 2, [ + ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], + ], [], [], + [ + 'exact' => ['users' => []], + 'users' => [ + ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], + ], + ], false, + ], + // Share type restricted to user - Multipage result + [ + 'test', [Share::SHARE_TYPE_USER], 1, 2, [ + ['label' => 'test 1', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], + ['label' => 'test 2', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']], + ], [], [], + [ + 'exact' => ['users' => []], + 'users' => [ + ['label' => 'test 1', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], + ['label' => 'test 2', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']], + ], + ], true, + ], + ]; + } +} diff --git a/tests/lib/Collaboration/Collaborators/UserPluginTest.php b/tests/lib/Collaboration/Collaborators/UserPluginTest.php new file mode 100644 index 00000000000..7d6d9c645a0 --- /dev/null +++ b/tests/lib/Collaboration/Collaborators/UserPluginTest.php @@ -0,0 +1,445 @@ +<?php +/** + * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @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\Collaboration\Collaborators; + +use OC\Collaboration\Collaborators\SearchResult; +use OC\Collaboration\Collaborators\UserPlugin; +use OCP\Collaboration\Collaborators\ISearchResult; +use OCP\IConfig; +use OCP\IGroupManager; +use OCP\IUser; +use OCP\IUserManager; +use OCP\IUserSession; +use OCP\Share; +use Test\TestCase; + +class UserPluginTest extends TestCase { + /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ + protected $config; + + /** @var IUserManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $userManager; + + /** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */ + protected $groupManager; + + /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */ + protected $session; + + /** @var UserPlugin */ + protected $plugin; + + /** @var ISearchResult */ + protected $searchResult; + + /** @var int */ + protected $limit = 2; + + /** @var int */ + protected $offset = 0; + + /** @var IUser|\PHPUnit_Framework_MockObject_MockObject */ + protected $user; + + public function setUp() { + parent::setUp(); + + $this->config = $this->createMock(IConfig::class); + + $this->userManager = $this->createMock(IUserManager::class); + + $this->groupManager = $this->createMock(IGroupManager::class); + + $this->session = $this->createMock(IUserSession::class); + + $this->searchResult = new SearchResult(); + + $this->user = $this->getUserMock('admin', 'Administrator'); + } + + public function instantiatePlugin() { + // cannot be done within setUp, because dependent mocks needs to be set + // up with configuration etc. first + $this->plugin = new UserPlugin( + $this->config, + $this->userManager, + $this->groupManager, + $this->session + ); + } + + public function getUserMock($uid, $displayName) { + $user = $this->createMock(IUser::class); + + $user->expects($this->any()) + ->method('getUID') + ->willReturn($uid); + + $user->expects($this->any()) + ->method('getDisplayName') + ->willReturn($displayName); + + return $user; + } + + public function dataGetUsers() { + return [ + ['test', false, true, [], [], [], [], true, false], + ['test', false, false, [], [], [], [], true, false], + ['test', true, true, [], [], [], [], true, false], + ['test', true, false, [], [], [], [], true, false], + [ + 'test', false, true, [], [], + [ + ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']], + ], [], true, $this->getUserMock('test', 'Test') + ], + [ + 'test', false, false, [], [], + [ + ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']], + ], [], true, $this->getUserMock('test', 'Test') + ], + [ + 'test', true, true, [], [], + [], [], true, $this->getUserMock('test', 'Test') + ], + [ + 'test', true, false, [], [], + [], [], true, $this->getUserMock('test', 'Test') + ], + [ + 'test', true, true, ['test-group'], [['test-group', 'test', 2, 0, []]], + [ + ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']], + ], [], true, $this->getUserMock('test', 'Test') + ], + [ + 'test', true, false, ['test-group'], [['test-group', 'test', 2, 0, []]], + [ + ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']], + ], [], true, $this->getUserMock('test', 'Test') + ], + [ + 'test', + false, + true, + [], + [ + $this->getUserMock('test1', 'Test One'), + ], + [], + [ + ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], + ], + true, + false, + ], + [ + 'test', + false, + false, + [], + [ + $this->getUserMock('test1', 'Test One'), + ], + [], + [], + true, + false, + ], + [ + 'test', + false, + true, + [], + [ + $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, + false, + [], + [ + $this->getUserMock('test1', 'Test One'), + $this->getUserMock('test2', 'Test Two'), + ], + [], + [], + true, + false, + ], + [ + 'test', + false, + true, + [], + [ + $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', + false, + 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']], + ], + [], + true, + false, + ], + [ + 'test', + true, + 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, + false, + ['abc', 'xyz'], + [ + ['abc', 'test', 2, 0, ['test1' => 'Test One']], + ['xyz', 'test', 2, 0, []], + ], + [], + [], + true, + false, + ], + [ + 'test', + true, + 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, + false, + ['abc', 'xyz'], + [ + ['abc', 'test', 2, 0, [ + 'test1' => 'Test One', + 'test2' => 'Test Two', + ]], + ['xyz', 'test', 2, 0, [ + 'test1' => 'Test One', + 'test2' => 'Test Two', + ]], + ], + [], + [], + true, + false, + ], + [ + 'test', + true, + 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, + ], + [ + 'test', + true, + false, + ['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']], + ], + [], + true, + false, + ], + ]; + } + + /** + * @dataProvider dataGetUsers + * + * @param string $searchTerm + * @param bool $shareWithGroupOnly + * @param bool $shareeEnumeration + * @param array $groupResponse + * @param array $userResponse + * @param array $exactExpected + * @param array $expected + * @param bool $reachedEnd + * @param bool|IUser $singleUser + */ + public function testSearch( + $searchTerm, + $shareWithGroupOnly, + $shareeEnumeration, + array $groupResponse, + array $userResponse, + array $exactExpected, + array $expected, + $reachedEnd, + $singleUser + ) { + $this->config->expects($this->any()) + ->method('getAppValue') + ->willReturnCallback( + function($appName, $key, $default) + use ($shareWithGroupOnly, $shareeEnumeration) + { + if ($appName === 'core' && $key === 'shareapi_only_share_with_group_members') { + return $shareWithGroupOnly ? 'yes' : 'no'; + } else if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') { + return $shareeEnumeration ? 'yes' : 'no'; + } + return $default; + } + ); + + $this->instantiatePlugin(); + + $this->session->expects($this->any()) + ->method('getUser') + ->willReturn($this->user); + + if(!$shareWithGroupOnly) { + $this->userManager->expects($this->once()) + ->method('searchDisplayName') + ->with($searchTerm, $this->limit, $this->offset) + ->willReturn($userResponse); + } else { + if ($singleUser !== false) { + $this->groupManager->expects($this->exactly(2)) + ->method('getUserGroupIds') + ->withConsecutive( + $this->user, + $singleUser + ) + ->willReturn($groupResponse); + } else { + $this->groupManager->expects($this->once()) + ->method('getUserGroupIds') + ->with($this->user) + ->willReturn($groupResponse); + } + + $this->groupManager->expects($this->exactly(sizeof($groupResponse))) + ->method('displayNamesInGroup') + ->with($this->anything(), $searchTerm, $this->limit, $this->offset) + ->willReturnMap($userResponse); + } + + if ($singleUser !== false) { + $this->userManager->expects($this->once()) + ->method('get') + ->with($searchTerm) + ->willReturn($singleUser); + } + + + $moreResults = $this->plugin->search($searchTerm, $this->limit, $this->offset, $this->searchResult); + $result = $this->searchResult->asArray(); + + $this->assertEquals($exactExpected, $result['exact']['users']); + $this->assertEquals($expected, $result['users']); + $this->assertSame($reachedEnd, $moreResults); + } +} |