diff options
Diffstat (limited to 'tests/lib/Collaboration/Collaborators')
7 files changed, 629 insertions, 421 deletions
diff --git a/tests/lib/Collaboration/Collaborators/GroupPluginTest.php b/tests/lib/Collaboration/Collaborators/GroupPluginTest.php index 2f7cd1061e9..a4ecd598562 100644 --- a/tests/lib/Collaboration/Collaborators/GroupPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/GroupPluginTest.php @@ -1,24 +1,8 @@ <?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/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Collaboration\Collaborators; @@ -35,19 +19,19 @@ use OCP\Share\IShare; use Test\TestCase; class GroupPluginTest extends TestCase { - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ protected $config; - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ protected $groupManager; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ protected $session; - /** @var ISearchResult */ + /** @var ISearchResult */ protected $searchResult; - /** @var GroupPlugin */ + /** @var GroupPlugin */ protected $plugin; /** @var int */ @@ -56,7 +40,7 @@ class GroupPluginTest extends TestCase { /** @var int */ protected $offset = 0; - /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */ protected $user; protected function setUp(): void { @@ -125,13 +109,15 @@ class GroupPluginTest extends TestCase { return $group; } - public function dataGetGroups() { + public function dataGetGroups(): array { return [ - ['test', false, true, [], [], [], [], true, false], - ['test', false, false, [], [], [], [], true, false], + ['test', false, true, false, [], [], [], [], true, false], + ['test', false, false, false, [], [], [], [], true, false], + // group sharing disabled + ['test', false, true, true, [], [], [], [], false, false], // group without display name [ - 'test', false, true, + 'test', false, true, false, [$this->getGroupMock('test1')], [], [], @@ -141,7 +127,7 @@ class GroupPluginTest extends TestCase { ], // group with display name, search by id [ - 'test', false, true, + 'test', false, true, false, [$this->getGroupMock('test1', 'Test One')], [], [], @@ -151,7 +137,7 @@ class GroupPluginTest extends TestCase { ], // group with display name, search by display name [ - 'one', false, true, + 'one', false, true, false, [$this->getGroupMock('test1', 'Test One')], [], [], @@ -161,7 +147,7 @@ class GroupPluginTest extends TestCase { ], // group with display name, search by display name, exact expected [ - 'Test One', false, true, + 'Test One', false, true, false, [$this->getGroupMock('test1', 'Test One')], [], [['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'test1']]], @@ -170,7 +156,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', false, false, + 'test', false, false, false, [$this->getGroupMock('test1')], [], [], @@ -179,7 +165,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', false, true, + 'test', false, true, false, [ $this->getGroupMock('test'), $this->getGroupMock('test1'), @@ -191,7 +177,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', false, false, + 'test', false, false, false, [ $this->getGroupMock('test'), $this->getGroupMock('test1'), @@ -203,7 +189,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', false, true, + 'test', false, true, false, [ $this->getGroupMock('test0'), $this->getGroupMock('test1'), @@ -218,7 +204,7 @@ class GroupPluginTest extends TestCase { null, ], [ - 'test', false, false, + 'test', false, false, false, [ $this->getGroupMock('test0'), $this->getGroupMock('test1'), @@ -230,7 +216,7 @@ class GroupPluginTest extends TestCase { null, ], [ - 'test', false, true, + 'test', false, true, false, [ $this->getGroupMock('test0'), $this->getGroupMock('test1'), @@ -247,7 +233,7 @@ class GroupPluginTest extends TestCase { $this->getGroupMock('test'), ], [ - 'test', false, false, + 'test', false, false, false, [ $this->getGroupMock('test0'), $this->getGroupMock('test1'), @@ -260,10 +246,10 @@ class GroupPluginTest extends TestCase { true, $this->getGroupMock('test'), ], - ['test', true, true, [], [], [], [], true, false], - ['test', true, false, [], [], [], [], true, false], + ['test', true, true, false, [], [], [], [], true, false], + ['test', true, false, false, [], [], [], [], true, false], [ - 'test', true, true, + 'test', true, true, false, [ $this->getGroupMock('test1'), $this->getGroupMock('test2'), @@ -275,7 +261,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', true, false, + 'test', true, false, false, [ $this->getGroupMock('test1'), $this->getGroupMock('test2'), @@ -287,7 +273,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', true, true, + 'test', true, true, false, [ $this->getGroupMock('test'), $this->getGroupMock('test1'), @@ -299,7 +285,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', true, false, + 'test', true, false, false, [ $this->getGroupMock('test'), $this->getGroupMock('test1'), @@ -311,7 +297,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', true, true, + 'test', true, true, false, [ $this->getGroupMock('test'), $this->getGroupMock('test1'), @@ -323,7 +309,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', true, false, + 'test', true, false, false, [ $this->getGroupMock('test'), $this->getGroupMock('test1'), @@ -335,7 +321,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', true, true, + 'test', true, true, false, [ $this->getGroupMock('test'), $this->getGroupMock('test1'), @@ -347,7 +333,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', true, false, + 'test', true, false, false, [ $this->getGroupMock('test'), $this->getGroupMock('test1'), @@ -359,7 +345,7 @@ class GroupPluginTest extends TestCase { false, ], [ - 'test', true, true, + 'test', true, true, false, [ $this->getGroupMock('test0'), $this->getGroupMock('test1'), @@ -374,7 +360,7 @@ class GroupPluginTest extends TestCase { null, ], [ - 'test', true, false, + 'test', true, false, false, [ $this->getGroupMock('test0'), $this->getGroupMock('test1'), @@ -386,7 +372,7 @@ class GroupPluginTest extends TestCase { null, ], [ - 'test', true, true, + 'test', true, true, false, [ $this->getGroupMock('test0'), $this->getGroupMock('test1'), @@ -403,7 +389,7 @@ class GroupPluginTest extends TestCase { $this->getGroupMock('test'), ], [ - 'test', true, false, + 'test', true, false, false, [ $this->getGroupMock('test0'), $this->getGroupMock('test1'), @@ -417,7 +403,7 @@ class GroupPluginTest extends TestCase { $this->getGroupMock('test'), ], [ - 'test', false, false, + 'test', false, false, false, [ $this->getGroupMock('test', null, true), $this->getGroupMock('test1'), @@ -432,11 +418,11 @@ class GroupPluginTest extends TestCase { } /** - * @dataProvider dataGetGroups * * @param string $searchTerm * @param bool $shareWithGroupOnly * @param bool $shareeEnumeration + * @param bool $groupSharingDisabled * @param array $groupResponse * @param array $userGroupsResponse * @param array $exactExpected @@ -444,36 +430,47 @@ class GroupPluginTest extends TestCase { * @param bool $reachedEnd * @param bool|IGroup $singleGroup */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetGroups')] public function testSearch( - $searchTerm, - $shareWithGroupOnly, - $shareeEnumeration, + string $searchTerm, + bool $shareWithGroupOnly, + bool $shareeEnumeration, + bool $groupSharingDisabled, array $groupResponse, array $userGroupsResponse, array $exactExpected, array $expected, - $reachedEnd, - $singleGroup - ) { + bool $reachedEnd, + $singleGroup, + ): void { $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'; - } elseif ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') { - return $shareeEnumeration ? 'yes' : 'no'; + function ($appName, $key, $default) use ($shareWithGroupOnly, $shareeEnumeration, $groupSharingDisabled) { + if ($appName !== 'core') { + return $default; + } + switch ($key) { + case 'shareapi_only_share_with_group_members': + return $shareWithGroupOnly ? 'yes' : 'no'; + case 'shareapi_allow_share_dialog_user_enumeration': + return $shareeEnumeration ? 'yes' : 'no'; + case 'shareapi_allow_group_sharing': + return $groupSharingDisabled ? 'no' : 'yes'; + default: + return $default; } - return $default; } ); $this->instantiatePlugin(); - $this->groupManager->expects($this->once()) - ->method('search') - ->with($searchTerm, $this->limit, $this->offset) - ->willReturn($groupResponse); + if (!$groupSharingDisabled) { + $this->groupManager->expects($this->once()) + ->method('search') + ->with($searchTerm, $this->limit, $this->offset) + ->willReturn($groupResponse); + } if ($singleGroup !== false) { $this->groupManager->expects($this->once()) @@ -497,8 +494,10 @@ class GroupPluginTest extends TestCase { $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']); + if (!$groupSharingDisabled) { + $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 index 0a1febe33a5..ac9b196ea1e 100644 --- a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php @@ -1,24 +1,8 @@ <?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/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Collaboration\Collaborators; @@ -33,25 +17,25 @@ use OCP\Http\Client\IClient; use OCP\Http\Client\IClientService; use OCP\Http\Client\IResponse; use OCP\IConfig; -use OCP\ILogger; use OCP\IUser; use OCP\IUserSession; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; use Test\TestCase; class LookupPluginTest extends TestCase { - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IConfig|MockObject */ protected $config; - /** @var IClientService|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IClientService|MockObject */ protected $clientService; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserSession|MockObject */ protected $userSession; - /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var ICloudIdManager|MockObject */ protected $cloudIdManager; - /** @var LookupPlugin */ + /** @var LookupPlugin */ protected $plugin; - /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */ + /** @var LoggerInterface|MockObject */ protected $logger; protected function setUp(): void { @@ -60,7 +44,7 @@ class LookupPluginTest extends TestCase { $this->userSession = $this->createMock(IUserSession::class); $this->cloudIdManager = $this->createMock(ICloudIdManager::class); $this->config = $this->createMock(IConfig::class); - $this->logger = $this->createMock(ILogger::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->clientService = $this->createMock(IClientService::class); $cloudId = $this->createMock(ICloudId::class); $cloudId->expects($this->any())->method('getRemote')->willReturn('myNextcloud.net'); @@ -86,66 +70,61 @@ class LookupPluginTest extends TestCase { ); } - public function testSearchNoLookupServerURI() { + public function testSearchNoLookupServerURI(): void { $this->config->expects($this->once()) ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') + ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn('yes'); - $this->config->expects($this->at(0)) - ->method('getSystemValue') - ->with('gs.enabled', false) - ->willReturn(false); - - $this->config->expects($this->at(2)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - $this->config->expects($this->at(3)) - ->method('getSystemValue') + $this->config->expects($this->exactly(2)) + ->method('getSystemValueBool') + ->willReturnMap([ + ['gs.enabled', false, true], + ['has_internet_connection', true, true], + ]); + + $this->config->expects($this->once()) + ->method('getSystemValueString') ->with('lookup_server', 'https://lookup.nextcloud.com') ->willReturn(''); $this->clientService->expects($this->never()) ->method('newClient'); - /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */ + /** @var ISearchResult|MockObject $searchResult */ $searchResult = $this->createMock(ISearchResult::class); $this->plugin->search('foobar', 10, 0, $searchResult); } - public function testSearchNoInternet() { + public function testSearchNoInternet(): void { $this->config->expects($this->once()) ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') + ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn('yes'); - $this->config->expects($this->at(0)) - ->method('getSystemValue') - ->with('gs.enabled', false) - ->willReturn(false); - - $this->config->expects($this->at(2)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(false); + $this->config->expects($this->exactly(2)) + ->method('getSystemValueBool') + ->willReturnMap([ + ['gs.enabled', false, false], + ['has_internet_connection', true, false], + ]); $this->clientService->expects($this->never()) ->method('newClient'); - /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */ + /** @var ISearchResult|MockObject $searchResult */ $searchResult = $this->createMock(ISearchResult::class); $this->plugin->search('foobar', 10, 0, $searchResult); } /** - * @dataProvider searchDataProvider * @param array $searchParams */ - public function testSearch(array $searchParams) { + #[\PHPUnit\Framework\Attributes\DataProvider('searchDataProvider')] + public function testSearch(array $searchParams): void { $type = new SearchResultType('lookup'); - /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */ + /** @var ISearchResult|MockObject $searchResult */ $searchResult = $this->createMock(ISearchResult::class); $searchResult->expects($this->once()) ->method('addResultSet') @@ -153,19 +132,17 @@ class LookupPluginTest extends TestCase { $this->config->expects($this->once()) ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') + ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn('yes'); - $this->config->expects($this->at(0)) - ->method('getSystemValue') - ->with('gs.enabled', false) - ->willReturn(false); - - $this->config->expects($this->at(2)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - $this->config->expects($this->at(3)) - ->method('getSystemValue') + $this->config->expects($this->exactly(2)) + ->method('getSystemValueBool') + ->willReturnMap([ + ['gs.enabled', false, true], + ['has_internet_connection', true, true], + ]); + + $this->config->expects($this->once()) + ->method('getSystemValueString') ->with('lookup_server', 'https://lookup.nextcloud.com') ->willReturn($searchParams['server']); @@ -199,36 +176,34 @@ class LookupPluginTest extends TestCase { /** - * @dataProvider dataSearchEnableDisableLookupServer * @param array $searchParams * @param bool $GSEnabled * @param bool $LookupEnabled */ - public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnabled, $LookupEnabled) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataSearchEnableDisableLookupServer')] + public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnabled, $LookupEnabled): void { $type = new SearchResultType('lookup'); - /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */ + /** @var ISearchResult|MockObject $searchResult */ $searchResult = $this->createMock(ISearchResult::class); $this->config->expects($this->once()) ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') + ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn($LookupEnabled ? 'yes' : 'no'); - $this->config->expects($this->at(0)) - ->method('getSystemValue') - ->with('gs.enabled', false) - ->willReturn($GSEnabled); - if ($GSEnabled || $LookupEnabled) { + if ($GSEnabled) { $searchResult->expects($this->once()) ->method('addResultSet') ->with($type, $searchParams['expectedResult'], []); - $this->config->expects($this->at(2)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - $this->config->expects($this->at(3)) - ->method('getSystemValue') + $this->config->expects($this->exactly(2)) + ->method('getSystemValueBool') + ->willReturnMap([ + ['gs.enabled', false, $GSEnabled], + ['has_internet_connection', true, true], + ]); + $this->config->expects($this->once()) + ->method('getSystemValueString') ->with('lookup_server', 'https://lookup.nextcloud.com') ->willReturn($searchParams['server']); @@ -251,6 +226,12 @@ class LookupPluginTest extends TestCase { ->willReturn($client); } else { $searchResult->expects($this->never())->method('addResultSet'); + $this->config->expects($this->exactly(2)) + ->method('getSystemValueBool') + ->willReturnMap([ + ['gs.enabled', false, $GSEnabled], + ['has_internet_connection', true, true], + ]); } $moreResults = $this->plugin->search( $searchParams['search'], @@ -263,13 +244,15 @@ class LookupPluginTest extends TestCase { } - public function testSearchLookupServerDisabled() { - $this->config->expects($this->once()) - ->method('getAppValue') - ->with('files_sharing', 'lookupServerEnabled', 'yes') - ->willReturn('no'); + public function testSearchGSDisabled(): void { + $this->config->expects($this->atLeastOnce()) + ->method('getSystemValueBool') + ->willReturnMap([ + ['has_internet_connection', true, true], + ['gs.enabled', false, false], + ]); - /** @var ISearchResult|\PHPUnit\Framework\MockObject\MockObject $searchResult */ + /** @var ISearchResult|MockObject $searchResult */ $searchResult = $this->createMock(ISearchResult::class); $searchResult->expects($this->never()) ->method('addResultSet'); @@ -279,7 +262,7 @@ class LookupPluginTest extends TestCase { $this->assertFalse($this->plugin->search('irr', 10, 0, $searchResult)); } - public function dataSearchEnableDisableLookupServer() { + public static function dataSearchEnableDisableLookupServer(): array { $fedIDs = [ 'foo@enceladus.moon', 'foobar@enceladus.moon', @@ -302,6 +285,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[0], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, + 'globalScale' => true, 'shareWith' => $fedIDs[0] ], 'extra' => ['federationId' => $fedIDs[0]], @@ -310,6 +294,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[1], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, + 'globalScale' => true, 'shareWith' => $fedIDs[1] ], 'extra' => ['federationId' => $fedIDs[1]], @@ -318,6 +303,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[2], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, + 'globalScale' => true, 'shareWith' => $fedIDs[2] ], 'extra' => ['federationId' => $fedIDs[2]], @@ -341,6 +327,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[0], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, + 'globalScale' => true, 'shareWith' => $fedIDs[0] ], 'extra' => ['federationId' => $fedIDs[0]], @@ -349,6 +336,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[1], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, + 'globalScale' => true, 'shareWith' => $fedIDs[1] ], 'extra' => ['federationId' => $fedIDs[1]], @@ -357,6 +345,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[2], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, + 'globalScale' => true, 'shareWith' => $fedIDs[2] ], 'extra' => ['federationId' => $fedIDs[2]], @@ -446,7 +435,7 @@ class LookupPluginTest extends TestCase { ]; } - public function searchDataProvider() { + public static function searchDataProvider(): array { $fedIDs = [ 'foo@enceladus.moon', 'foobar@enceladus.moon', @@ -470,6 +459,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[0], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, + 'globalScale' => true, 'shareWith' => $fedIDs[0] ], 'extra' => ['federationId' => $fedIDs[0]], @@ -478,6 +468,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[1], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, + 'globalScale' => true, 'shareWith' => $fedIDs[1] ], 'extra' => ['federationId' => $fedIDs[1]], @@ -486,6 +477,7 @@ class LookupPluginTest extends TestCase { 'label' => $fedIDs[2], 'value' => [ 'shareType' => IShare::TYPE_REMOTE, + 'globalScale' => true, 'shareWith' => $fedIDs[2] ], 'extra' => ['federationId' => $fedIDs[2]], diff --git a/tests/lib/Collaboration/Collaborators/MailPluginTest.php b/tests/lib/Collaboration/Collaborators/MailPluginTest.php index 141d4b680b7..b38b961a512 100644 --- a/tests/lib/Collaboration/Collaborators/MailPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/MailPluginTest.php @@ -1,24 +1,8 @@ <?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/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Collaboration\Collaborators; @@ -26,56 +10,83 @@ namespace Test\Collaboration\Collaborators; use OC\Collaboration\Collaborators\MailPlugin; use OC\Collaboration\Collaborators\SearchResult; use OC\Federation\CloudIdManager; +use OC\KnownUser\KnownUserService; use OCP\Collaboration\Collaborators\SearchResultType; use OCP\Contacts\IManager; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudIdManager; +use OCP\ICacheFactory; use OCP\IConfig; use OCP\IGroupManager; +use OCP\IURLGenerator; use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; +use OCP\Mail\IMailer; use OCP\Share\IShare; use Test\TestCase; class MailPluginTest extends TestCase { - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ protected $config; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ protected $contactsManager; - /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */ protected $cloudIdManager; - /** @var MailPlugin */ + /** @var MailPlugin */ protected $plugin; - /** @var SearchResult */ + /** @var SearchResult */ protected $searchResult; - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ protected $groupManager; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ + /** @var KnownUserService|\PHPUnit\Framework\MockObject\MockObject */ + protected $knownUserService; + + /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ protected $userSession; + /** @var IMailer|\PHPUnit\Framework\MockObject\MockObject */ + protected $mailer; + protected function setUp(): void { parent::setUp(); $this->config = $this->createMock(IConfig::class); $this->contactsManager = $this->createMock(IManager::class); $this->groupManager = $this->createMock(IGroupManager::class); + $this->knownUserService = $this->createMock(KnownUserService::class); $this->userSession = $this->createMock(IUserSession::class); - $this->cloudIdManager = new CloudIdManager($this->contactsManager); + $this->mailer = $this->createMock(IMailer::class); + $this->cloudIdManager = new CloudIdManager( + $this->createMock(ICacheFactory::class), + $this->createMock(IEventDispatcher::class), + $this->contactsManager, + $this->createMock(IURLGenerator::class), + $this->createMock(IUserManager::class), + ); $this->searchResult = new SearchResult(); } public function instantiatePlugin() { - $this->plugin = new MailPlugin($this->contactsManager, $this->cloudIdManager, $this->config, $this->groupManager, $this->userSession); + $this->plugin = new MailPlugin( + $this->contactsManager, + $this->cloudIdManager, + $this->config, + $this->groupManager, + $this->knownUserService, + $this->userSession, + $this->mailer + ); } /** - * @dataProvider dataGetEmail * * @param string $searchTerm * @param array $contacts @@ -83,7 +94,8 @@ class MailPluginTest extends TestCase { * @param array $expected * @param bool $reachedEnd */ - public function testSearch($searchTerm, $contacts, $shareeEnumeration, $expected, $exactIdMatch, $reachedEnd) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetEmail')] + public function testSearch($searchTerm, $contacts, $shareeEnumeration, $expected, $exactIdMatch, $reachedEnd, $validEmail): void { $this->config->expects($this->any()) ->method('getAppValue') ->willReturnCallback( @@ -103,6 +115,9 @@ class MailPluginTest extends TestCase { $this->userSession->method('getUser') ->willReturn($currentUser); + $this->mailer->method('validateMailAddress') + ->willReturn($validEmail); + $this->contactsManager->expects($this->any()) ->method('search') ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) { @@ -120,12 +135,12 @@ class MailPluginTest extends TestCase { $this->assertSame($reachedEnd, $moreResults); } - public function dataGetEmail() { + public static function dataGetEmail(): array { return [ // data set 0 - ['test', [], true, ['emails' => [], 'exact' => ['emails' => []]], false, false], + ['test', [], true, ['emails' => [], 'exact' => ['emails' => []]], false, false, false], // data set 1 - ['test', [], false, ['emails' => [], 'exact' => ['emails' => []]], false, false], + ['test', [], false, ['emails' => [], 'exact' => ['emails' => []]], false, false, false], // data set 2 [ 'test@remote.com', @@ -134,6 +149,7 @@ class MailPluginTest extends TestCase { ['emails' => [], 'exact' => ['emails' => [['uuid' => 'test@remote.com', 'label' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], false, false, + true, ], // data set 3 [ // no valid email address @@ -143,6 +159,7 @@ class MailPluginTest extends TestCase { ['emails' => [], 'exact' => ['emails' => []]], false, false, + false, ], // data set 4 [ @@ -152,6 +169,7 @@ class MailPluginTest extends TestCase { ['emails' => [], 'exact' => ['emails' => [['uuid' => 'test@remote.com', 'label' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], false, false, + true, ], // data set 5 [ @@ -171,12 +189,13 @@ class MailPluginTest extends TestCase { 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ - 'username@localhost', + 'username@example.com', ], ], ], true, - ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => []]], + ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']]], 'exact' => ['emails' => []]], + false, false, false, ], @@ -195,6 +214,7 @@ class MailPluginTest extends TestCase { ], ], [ + 'isLocalSystemBook' => true, 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ @@ -206,6 +226,7 @@ class MailPluginTest extends TestCase { ['emails' => [], 'exact' => ['emails' => []]], false, false, + false, ], // data set 7 [ @@ -213,26 +234,27 @@ class MailPluginTest extends TestCase { [ [ 'UID' => 'uid3', - 'FN' => 'User3 @ Localhost', + 'FN' => 'User3 @ example.com', ], [ 'UID' => 'uid2', - 'FN' => 'User2 @ Localhost', + 'FN' => 'User2 @ example.com', 'EMAIL' => [ ], ], [ 'UID' => 'uid1', - 'FN' => 'User @ Localhost', + 'FN' => 'User @ example.com', 'EMAIL' => [ - 'username@localhost', + 'username@example.com', ], ], ], true, - ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => [['label' => 'test@remote.com', 'uuid' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], + ['emails' => [['uuid' => 'uid1', 'name' => 'User @ example.com', 'type' => '', 'label' => 'User @ example.com (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']]], 'exact' => ['emails' => [['label' => 'test@remote.com', 'uuid' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], false, false, + true, ], // data set 8 [ @@ -249,6 +271,7 @@ class MailPluginTest extends TestCase { ], ], [ + 'isLocalSystemBook' => true, 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ @@ -260,60 +283,63 @@ class MailPluginTest extends TestCase { ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'uuid' => 'test@remote.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]], false, false, + true, ], // data set 9 [ - 'username@localhost', + 'username@example.com', [ [ 'UID' => 'uid3', - 'FN' => 'User3 @ Localhost', + 'FN' => 'User3 @ example.com', ], [ 'UID' => 'uid2', - 'FN' => 'User2 @ Localhost', + 'FN' => 'User2 @ example.com', 'EMAIL' => [ ], ], [ 'UID' => 'uid1', - 'FN' => 'User @ Localhost', + 'FN' => 'User @ example.com', 'EMAIL' => [ - 'username@localhost', + 'username@example.com', ], ], ], true, - ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], + ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ example.com', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ example.com (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']]]]], true, false, + false, ], // data set 10 [ - 'username@localhost', + 'username@example.com', [ [ 'UID' => 'uid1', - 'FN' => 'User3 @ Localhost', + 'FN' => 'User3 @ example.com', ], [ 'UID' => 'uid2', - 'FN' => 'User2 @ Localhost', + 'FN' => 'User2 @ example.com', 'EMAIL' => [ ], ], [ 'UID' => 'uid1', - 'FN' => 'User @ Localhost', + 'FN' => 'User @ example.com', 'EMAIL' => [ - 'username@localhost', + 'username@example.com', ], ], ], false, - ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]], + ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ example.com', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ example.com (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']]]]], true, false, + false, ], // data set 11 // contact with space @@ -339,8 +365,9 @@ class MailPluginTest extends TestCase { ], ], false, - ['emails' => [], 'exact' => ['emails' => [['name' => 'User Name @ Localhost', 'uuid' => 'uid1', 'type' => '', 'label' => 'User Name @ Localhost (user name@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'user name@localhost']]]]], - true, + ['emails' => [], 'exact' => ['emails' => []]], + false, + false, false, ], // data set 12 @@ -359,6 +386,7 @@ class MailPluginTest extends TestCase { ], ], [ + 'isLocalSystemBook' => true, 'UID' => 'uid1', 'FN' => 'User @ Localhost', 'EMAIL' => [ @@ -370,6 +398,7 @@ class MailPluginTest extends TestCase { ['emails' => [], 'exact' => ['emails' => []]], false, false, + false, ], // data set 13 // Local user found by email @@ -388,6 +417,7 @@ class MailPluginTest extends TestCase { ['users' => [], 'exact' => ['users' => [['uuid' => 'uid1', 'name' => 'User', 'label' => 'User (test@example.com)','value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'shareWithDisplayNameUnique' => 'test@example.com']]]], true, false, + true, ], // data set 14 // Current local user found by email => no result @@ -406,6 +436,7 @@ class MailPluginTest extends TestCase { ['exact' => []], false, false, + true, ], // data set 15 // Pagination and "more results" for user matches byyyyyyy emails @@ -448,6 +479,7 @@ class MailPluginTest extends TestCase { ], 'emails' => [], 'exact' => ['users' => [], 'emails' => []]], false, true, + false, ], // data set 16 // Pagination and "more results" for normal emails @@ -486,6 +518,7 @@ class MailPluginTest extends TestCase { ], 'exact' => ['emails' => []]], false, true, + false, ], // data set 17 // multiple email addresses with type @@ -506,25 +539,36 @@ class MailPluginTest extends TestCase { 'UID' => 'uid1', 'FN' => 'User Name', 'EMAIL' => [ - ['type' => 'HOME', 'value' => 'username@localhost'], - ['type' => 'WORK', 'value' => 'username@other'], + ['type' => 'HOME', 'value' => 'username@example.com'], + ['type' => 'WORK', 'value' => 'other@example.com'], ], ], ], false, ['emails' => [ ], 'exact' => ['emails' => [ - ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'HOME', 'label' => 'User Name (username@localhost)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@localhost']], - ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'WORK', 'label' => 'User Name (username@other)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@other']] + ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'HOME', 'label' => 'User Name (username@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'username@example.com']], + ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'WORK', 'label' => 'User Name (other@example.com)', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'other@example.com']] ]]], false, false, + false, + ], + // data set 18 + // idn email + [ + 'test@lölölölölölölöl.com', + [], + true, + ['emails' => [], 'exact' => ['emails' => [['uuid' => 'test@lölölölölölölöl.com', 'label' => 'test@lölölölölölölöl.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@lölölölölölölöl.com']]]]], + false, + false, + true, ], ]; } /** - * @dataProvider dataGetEmailGroupsOnly * * @param string $searchTerm * @param array $contacts @@ -533,7 +577,8 @@ class MailPluginTest extends TestCase { * @param bool $reachedEnd * @param array groups */ - public function testSearchGroupsOnly($searchTerm, $contacts, $expected, $exactIdMatch, $reachedEnd, $userToGroupMapping) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetEmailGroupsOnly')] + public function testSearchGroupsOnly($searchTerm, $contacts, $expected, $exactIdMatch, $reachedEnd, $userToGroupMapping, $validEmail): void { $this->config->expects($this->any()) ->method('getAppValue') ->willReturnCallback( @@ -549,13 +594,16 @@ class MailPluginTest extends TestCase { $this->instantiatePlugin(); - /** @var \OCP\IUser | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */ $currentUser = $this->createMock('\OCP\IUser'); $currentUser->expects($this->any()) ->method('getUID') ->willReturn('currentUser'); + $this->mailer->method('validateMailAddress') + ->willReturn($validEmail); + $this->contactsManager->expects($this->any()) ->method('search') ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) { @@ -571,7 +619,7 @@ class MailPluginTest extends TestCase { $this->groupManager->expects($this->any()) ->method('getUserGroupIds') - ->willReturnCallback(function (\OCP\IUser $user) use ($userToGroupMapping) { + ->willReturnCallback(function (IUser $user) use ($userToGroupMapping) { return $userToGroupMapping[$user->getUID()]; }); @@ -589,7 +637,7 @@ class MailPluginTest extends TestCase { $this->assertSame($reachedEnd, $moreResults); } - public function dataGetEmailGroupsOnly() { + public static function dataGetEmailGroupsOnly(): array { return [ // The user `User` can share with the current user [ @@ -607,9 +655,10 @@ class MailPluginTest extends TestCase { false, false, [ - "currentUser" => ["group1"], - "User" => ["group1"] - ] + 'currentUser' => ['group1'], + 'User' => ['group1'] + ], + false, ], // The user `User` cannot share with the current user [ @@ -627,9 +676,10 @@ class MailPluginTest extends TestCase { false, false, [ - "currentUser" => ["group1"], - "User" => ["group2"] - ] + 'currentUser' => ['group1'], + 'User' => ['group2'] + ], + false, ], // The user `User` cannot share with the current user, but there is an exact match on the e-mail address -> share by e-mail [ @@ -647,9 +697,10 @@ class MailPluginTest extends TestCase { false, false, [ - "currentUser" => ["group1"], - "User" => ["group2"] - ] + 'currentUser' => ['group1'], + 'User' => ['group2'] + ], + true, ] ]; } diff --git a/tests/lib/Collaboration/Collaborators/RemotePluginTest.php b/tests/lib/Collaboration/Collaborators/RemotePluginTest.php index 1345df13379..a9a5e05dfe4 100644 --- a/tests/lib/Collaboration/Collaborators/RemotePluginTest.php +++ b/tests/lib/Collaboration/Collaborators/RemotePluginTest.php @@ -1,24 +1,8 @@ <?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/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Collaboration\Collaborators; @@ -28,8 +12,11 @@ use OC\Collaboration\Collaborators\SearchResult; use OC\Federation\CloudIdManager; use OCP\Collaboration\Collaborators\SearchResultType; use OCP\Contacts\IManager; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudIdManager; +use OCP\ICacheFactory; use OCP\IConfig; +use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; @@ -37,23 +24,22 @@ use OCP\Share\IShare; use Test\TestCase; class RemotePluginTest extends TestCase { - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ protected $userManager; - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ protected $config; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ protected $contactsManager; - /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */ protected $cloudIdManager; - /** @var RemotePlugin */ + /** @var RemotePlugin */ protected $plugin; - /** @var SearchResult */ + /** @var SearchResult */ protected $searchResult; protected function setUp(): void { @@ -62,7 +48,13 @@ class RemotePluginTest extends TestCase { $this->userManager = $this->createMock(IUserManager::class); $this->config = $this->createMock(IConfig::class); $this->contactsManager = $this->createMock(IManager::class); - $this->cloudIdManager = new CloudIdManager($this->contactsManager); + $this->cloudIdManager = new CloudIdManager( + $this->createMock(ICacheFactory::class), + $this->createMock(IEventDispatcher::class), + $this->contactsManager, + $this->createMock(IURLGenerator::class), + $this->createMock(IUserManager::class), + ); $this->searchResult = new SearchResult(); } @@ -79,7 +71,6 @@ class RemotePluginTest extends TestCase { } /** - * @dataProvider dataGetRemote * * @param string $searchTerm * @param array $contacts @@ -88,7 +79,8 @@ class RemotePluginTest extends TestCase { * @param bool $exactIdMatch * @param bool $reachedEnd */ - public function testSearch($searchTerm, array $contacts, $shareeEnumeration, array $expected, $exactIdMatch, $reachedEnd) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetRemote')] + public function testSearch($searchTerm, array $contacts, $shareeEnumeration, array $expected, $exactIdMatch, $reachedEnd): void { $this->config->expects($this->any()) ->method('getAppValue') ->willReturnCallback( @@ -120,37 +112,36 @@ class RemotePluginTest extends TestCase { } /** - * @dataProvider dataTestSplitUserRemote * * @param string $remote * @param string $expectedUser * @param string $expectedUrl */ - public function testSplitUserRemote($remote, $expectedUser, $expectedUrl) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestSplitUserRemote')] + public function testSplitUserRemote($remote, $expectedUser, $expectedUrl): void { $this->instantiatePlugin(); $this->contactsManager->expects($this->any()) ->method('search') ->willReturn([]); - list($remoteUser, $remoteUrl) = $this->plugin->splitUserRemote($remote); + [$remoteUser, $remoteUrl] = $this->plugin->splitUserRemote($remote); $this->assertSame($expectedUser, $remoteUser); $this->assertSame($expectedUrl, $remoteUrl); } /** - * @dataProvider dataTestSplitUserRemoteError - * * @param string $id */ - public function testSplitUserRemoteError($id) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestSplitUserRemoteError')] + public function testSplitUserRemoteError($id): void { $this->expectException(\Exception::class); $this->instantiatePlugin(); $this->plugin->splitUserRemote($id); } - public function dataGetRemote() { + public static function dataGetRemote() { return [ ['test', [], true, ['remotes' => [], 'exact' => ['remotes' => []]], false, true], ['test', [], false, ['remotes' => [], 'exact' => ['remotes' => []]], false, true], @@ -383,7 +374,7 @@ class RemotePluginTest extends TestCase { ]; } - public function dataTestSplitUserRemote() { + public static function dataTestSplitUserRemote(): array { $userPrefix = ['user@name', 'username']; $protocols = ['', 'http://', 'https://']; $remotes = [ @@ -404,6 +395,11 @@ class RemotePluginTest extends TestCase { foreach ($protocols as $protocol) { $baseUrl = $user . '@' . $protocol . $remote; + if ($protocol === 'https://') { + // https:// protocol is not expected in the final result + $protocol = ''; + } + $testCases[] = [$baseUrl, $user, $protocol . $remote]; $testCases[] = [$baseUrl . '/', $user, $protocol . $remote]; $testCases[] = [$baseUrl . '/index.php', $user, $protocol . $remote]; @@ -414,7 +410,7 @@ class RemotePluginTest extends TestCase { return $testCases; } - public function dataTestSplitUserRemoteError() { + public static function dataTestSplitUserRemoteError(): array { return [ // Invalid path ['user@'], diff --git a/tests/lib/Collaboration/Collaborators/SearchResultTest.php b/tests/lib/Collaboration/Collaborators/SearchResultTest.php index 98e454f2834..687901c47a6 100644 --- a/tests/lib/Collaboration/Collaborators/SearchResultTest.php +++ b/tests/lib/Collaboration/Collaborators/SearchResultTest.php @@ -1,24 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2017 Joas Schilling - * - * @author Joas Schilling <coding@schilljs.com> - * - * @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/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Collaboration\Collaborators; @@ -31,9 +15,9 @@ use OCP\IContainer; use Test\TestCase; class SearchResultTest extends TestCase { - /** @var IContainer|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IContainer|\PHPUnit\Framework\MockObject\MockObject */ protected $container; - /** @var ISearch */ + /** @var ISearch */ protected $search; protected function setUp(): void { @@ -44,7 +28,7 @@ class SearchResultTest extends TestCase { $this->search = new Search($this->container); } - public function dataAddResultSet() { + public static function dataAddResultSet(): array { return [ [[], ['exact' => []]], [['users' => ['exact' => null, 'loose' => []]], ['exact' => ['users' => []], 'users' => []]], @@ -54,11 +38,11 @@ class SearchResultTest extends TestCase { } /** - * @dataProvider dataAddResultSet * @param array $toAdd * @param array $expected */ - public function testAddResultSet(array $toAdd, array $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataAddResultSet')] + public function testAddResultSet(array $toAdd, array $expected): void { $result = new SearchResult(); foreach ($toAdd as $type => $results) { @@ -68,7 +52,7 @@ class SearchResultTest extends TestCase { $this->assertEquals($expected, $result->asArray()); } - public function dataHasResult() { + public static function dataHasResult(): array { $result = ['value' => ['shareWith' => 'l1']]; return [ [[],'users', 'n1', false], @@ -83,13 +67,13 @@ class SearchResultTest extends TestCase { } /** - * @dataProvider dataHasResult * @param array $toAdd * @param string $type * @param string $id * @param bool $expected */ - public function testHasResult(array $toAdd, $type, $id, $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataHasResult')] + public function testHasResult(array $toAdd, $type, $id, $expected): void { $result = new SearchResult(); foreach ($toAdd as $addType => $results) { diff --git a/tests/lib/Collaboration/Collaborators/SearchTest.php b/tests/lib/Collaboration/Collaborators/SearchTest.php index 0aebef72de0..ade995ea526 100644 --- a/tests/lib/Collaboration/Collaborators/SearchTest.php +++ b/tests/lib/Collaboration/Collaborators/SearchTest.php @@ -1,24 +1,8 @@ <?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/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Collaboration\Collaborators; @@ -33,9 +17,9 @@ use OCP\Share\IShare; use Test\TestCase; class SearchTest extends TestCase { - /** @var IContainer|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IContainer|\PHPUnit\Framework\MockObject\MockObject */ protected $container; - /** @var ISearch */ + /** @var ISearch */ protected $search; protected function setUp(): void { @@ -46,30 +30,19 @@ class SearchTest extends TestCase { $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 - */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataSearchSharees')] public function testSearch( - $searchTerm, + string $searchTerm, array $shareTypes, - $page, - $perPage, + int $page, + int $perPage, array $mockedUserResult, array $mockedGroupsResult, array $mockedRemotesResult, + array $mockedMailResult, array $expected, - $expectedMoreResults - ) { + bool $expectedMoreResults, + ): void { $searchResult = new SearchResult(); $userPlugin = $this->createMock(ISearchPlugin::class); @@ -104,9 +77,18 @@ class SearchTest extends TestCase { return $expectedMoreResults; }); + $mailPlugin = $this->createMock(ISearchPlugin::class); + $mailPlugin->expects($this->any()) + ->method('search') + ->willReturnCallback(function () use ($searchResult, $mockedMailResult, $expectedMoreResults) { + $type = new SearchResultType('emails'); + $searchResult->addResultSet($type, $mockedMailResult); + return $expectedMoreResults; + }); + $this->container->expects($this->any()) ->method('resolve') - ->willReturnCallback(function ($class) use ($searchResult, $userPlugin, $groupPlugin, $remotePlugin) { + ->willReturnCallback(function ($class) use ($searchResult, $userPlugin, $groupPlugin, $remotePlugin, $mailPlugin) { if ($class === SearchResult::class) { return $searchResult; } elseif ($class === $userPlugin) { @@ -115,6 +97,8 @@ class SearchTest extends TestCase { return $groupPlugin; } elseif ($class === $remotePlugin) { return $remotePlugin; + } elseif ($class === $mailPlugin) { + return $mailPlugin; } return null; }); @@ -122,33 +106,41 @@ class SearchTest extends TestCase { $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]); + $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_EMAIL', 'class' => $mailPlugin]); - list($results, $moreResults) = $this->search->search($searchTerm, $shareTypes, false, $perPage, $perPage * ($page - 1)); + [$results, $moreResults] = $this->search->search($searchTerm, $shareTypes, false, $perPage, $perPage * ($page - 1)); $this->assertEquals($expected, $results); $this->assertSame($expectedMoreResults, $moreResults); } - public function dataSearchSharees() { + public static function dataSearchSharees(): array { return [ + // #0 [ 'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false], + [], [ 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], 'users' => [], 'groups' => [], 'remotes' => [], - ], false + ], + false ], + // #1 [ 'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false], + [], [ 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], 'users' => [], 'groups' => [], 'remotes' => [], - ], false + ], + false ], + // #2 [ 'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [ ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']], @@ -157,6 +149,7 @@ class SearchTest extends TestCase { ], [ 'results' => [['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false, ], + [], [ 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], 'users' => [ @@ -170,13 +163,14 @@ class SearchTest extends TestCase { ], ], true, ], - // No groups requested + // #3 No groups requested [ 'test', [IShare::TYPE_USER, IShare::TYPE_REMOTE], 1, 2, [ ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']], ], [], [ 'results' => [['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false ], + [], [ 'exact' => ['users' => [], 'remotes' => []], 'users' => [ @@ -187,11 +181,11 @@ class SearchTest extends TestCase { ], ], false, ], - // Share type restricted to user - Only one user + // #4 Share type restricted to user - Only one user [ 'test', [IShare::TYPE_USER], 1, 2, [ ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']], - ], [], [], + ], [], [], [], [ 'exact' => ['users' => []], 'users' => [ @@ -199,12 +193,12 @@ class SearchTest extends TestCase { ], ], false, ], - // Share type restricted to user - Multipage result + // #5 Share type restricted to user - Multipage result [ 'test', [IShare::TYPE_USER], 1, 2, [ ['label' => 'test 1', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']], ['label' => 'test 2', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2']], - ], [], [], + ], [], [], [], [ 'exact' => ['users' => []], 'users' => [ @@ -213,6 +207,47 @@ class SearchTest extends TestCase { ], ], true, ], + // #6 Mail shares filtered out in favor of remote shares + [ + 'test', // search term + [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL], // plugins + 1, // page + 10, // per page + [ // user result + ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']], + ], + [ // group result + ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']], + ], + [ // remote result + 'results' => [ + ['label' => 'testz@remote.tld', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf','value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote.tld']] + ], + 'exact' => [], + 'exactIdMatch' => false, + ], + [ // mail result + ['label' => 'test Two', 'uuid' => 'b2321e9e-31af-43ac-a406-583fb26d1964', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test2@remote.tld']], + ['label' => 'test One', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'testz@remote.tld']], + ], + [ // expected result + 'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []], + 'users' => [ + ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']], + ], + 'groups' => [ + ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']], + ], + 'remotes' => [ + ['label' => 'testz@remote.tld', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote.tld']], + ], + 'emails' => [ + // one passes, another is filtered out + ['label' => 'test Two', 'uuid' => 'b2321e9e-31af-43ac-a406-583fb26d1964', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test2@remote.tld']] + ] + ], + false, // expected more results indicator + ], ]; } } diff --git a/tests/lib/Collaboration/Collaborators/UserPluginTest.php b/tests/lib/Collaboration/Collaborators/UserPluginTest.php index 2806540d00e..cb4949fb86d 100644 --- a/tests/lib/Collaboration/Collaborators/UserPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/UserPluginTest.php @@ -1,30 +1,15 @@ <?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/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Collaboration\Collaborators; use OC\Collaboration\Collaborators\SearchResult; use OC\Collaboration\Collaborators\UserPlugin; +use OC\KnownUser\KnownUserService; use OCP\Collaboration\Collaborators\ISearchResult; use OCP\IConfig; use OCP\IGroup; @@ -34,37 +19,39 @@ use OCP\IUserManager; use OCP\IUserSession; use OCP\Share\IShare; use OCP\UserStatus\IManager as IUserStatusManager; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class UserPluginTest extends TestCase { - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IConfig|MockObject */ protected $config; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserManager|MockObject */ protected $userManager; - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IGroupManager|MockObject */ protected $groupManager; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserSession|MockObject */ protected $session; - /** @var IUserStatusManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var KnownUserService|MockObject */ + protected $knownUserService; + + /** @var IUserStatusManager|MockObject */ protected $userStatusManager; - /** @var UserPlugin */ + /** @var UserPlugin */ protected $plugin; - /** @var ISearchResult */ + /** @var ISearchResult */ protected $searchResult; - /** @var int */ - protected $limit = 2; + protected int $limit = 2; - /** @var int */ - protected $offset = 0; + protected int $offset = 0; - /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUser|MockObject */ protected $user; protected function setUp(): void { @@ -78,6 +65,8 @@ class UserPluginTest extends TestCase { $this->session = $this->createMock(IUserSession::class); + $this->knownUserService = $this->createMock(KnownUserService::class); + $this->userStatusManager = $this->createMock(IUserStatusManager::class); $this->searchResult = new SearchResult(); @@ -93,23 +82,17 @@ class UserPluginTest extends TestCase { $this->userManager, $this->groupManager, $this->session, + $this->knownUserService, $this->userStatusManager ); } - public function mockConfig($shareWithGroupOnly, $shareeEnumeration, $shareeEnumerationLimitToGroup) { + public function mockConfig($mockedSettings) { $this->config->expects($this->any()) ->method('getAppValue') ->willReturnCallback( - function ($appName, $key, $default) use ($shareWithGroupOnly, $shareeEnumeration, $shareeEnumerationLimitToGroup) { - if ($appName === 'core' && $key === 'shareapi_only_share_with_group_members') { - return $shareWithGroupOnly ? 'yes' : 'no'; - } elseif ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') { - return $shareeEnumeration ? 'yes' : 'no'; - } elseif ($appName === 'core' && $key === 'shareapi_restrict_user_enumeration_to_group') { - return $shareeEnumerationLimitToGroup ? 'yes' : 'no'; - } - return $default; + function ($appName, $key, $default) use ($mockedSettings) { + return $mockedSettings[$appName][$key] ?? $default; } ); } @@ -142,7 +125,7 @@ class UserPluginTest extends TestCase { return $group; } - public function dataGetUsers() { + public function dataGetUsers(): array { return [ ['test', false, true, [], [], [], [], true, false], ['test', false, false, [], [], [], [], true, false], @@ -262,6 +245,28 @@ class UserPluginTest extends TestCase { [ 'test', false, + true, + [], + [ + $this->getUserMock('test0', 'Test'), + $this->getUserMock('test1', 'Test One'), + $this->getUserMock('test2', 'Test Two'), + ], + [ + ['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test0'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test0'], + ], + [ + ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'], + ['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'], + ], + false, + false, + [], + true, + ], + [ + 'test', + false, false, [], [ @@ -413,7 +418,6 @@ class UserPluginTest extends TestCase { } /** - * @dataProvider dataGetUsers * * @param string $searchTerm * @param bool $shareWithGroupOnly @@ -426,6 +430,7 @@ class UserPluginTest extends TestCase { * @param bool|IUser $singleUser * @param array $users */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetUsers')] public function testSearch( $searchTerm, $shareWithGroupOnly, @@ -436,9 +441,16 @@ class UserPluginTest extends TestCase { array $expected, $reachedEnd, $singleUser, - array $users = [] - ) { - $this->mockConfig($shareWithGroupOnly, $shareeEnumeration, false); + array $users = [], + $shareeEnumerationPhone = false, + ): void { + $this->mockConfig(['core' => [ + 'shareapi_only_share_with_group_members' => $shareWithGroupOnly ? 'yes' : 'no', + 'shareapi_allow_share_dialog_user_enumeration' => $shareeEnumeration? 'yes' : 'no', + 'shareapi_restrict_user_enumeration_to_group' => false ? 'yes' : 'no', + 'shareapi_restrict_user_enumeration_to_phone' => $shareeEnumerationPhone ? 'yes' : 'no', + ]]); + $this->instantiatePlugin(); $this->session->expects($this->any()) @@ -446,10 +458,24 @@ class UserPluginTest extends TestCase { ->willReturn($this->user); if (!$shareWithGroupOnly) { - $this->userManager->expects($this->once()) - ->method('searchDisplayName') - ->with($searchTerm, $this->limit, $this->offset) - ->willReturn($userResponse); + if ($shareeEnumerationPhone) { + $this->userManager->expects($this->once()) + ->method('searchKnownUsersByDisplayName') + ->with($this->user->getUID(), $searchTerm, $this->limit, $this->offset) + ->willReturn($userResponse); + + $this->knownUserService->method('isKnownToUser') + ->willReturnMap([ + [$this->user->getUID(), 'test0', true], + [$this->user->getUID(), 'test1', true], + [$this->user->getUID(), 'test2', true], + ]); + } else { + $this->userManager->expects($this->once()) + ->method('searchDisplayName') + ->with($searchTerm, $this->limit, $this->offset) + ->willReturn($userResponse); + } } else { $this->groupManager->method('getUserGroupIds') ->with($this->user) @@ -483,7 +509,7 @@ class UserPluginTest extends TestCase { $this->assertSame($reachedEnd, $moreResults); } - public function takeOutCurrentUserProvider() { + public static function takeOutCurrentUserProvider(): array { $inputUsers = [ 'alice' => 'Alice', 'bob' => 'Bob', @@ -509,12 +535,12 @@ class UserPluginTest extends TestCase { } /** - * @dataProvider takeOutCurrentUserProvider * @param array $users * @param array $expectedUIDs * @param $currentUserId */ - public function testTakeOutCurrentUser(array $users, array $expectedUIDs, $currentUserId) { + #[\PHPUnit\Framework\Attributes\DataProvider('takeOutCurrentUserProvider')] + public function testTakeOutCurrentUser(array $users, array $expectedUIDs, $currentUserId): void { $this->instantiatePlugin(); $this->session->expects($this->once()) @@ -530,7 +556,7 @@ class UserPluginTest extends TestCase { $this->assertSame($expectedUIDs, array_keys($users)); } - public function dataSearchEnumeration() { + public static function dataSearchEnumeration(): array { return [ [ 'test', @@ -540,6 +566,83 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB']], ], ['exact' => [], 'wide' => ['test1']], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], + ], + [ + 'test', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']], + ], + ['exact' => [], 'wide' => []], + ['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no']], + ], + [ + 'test1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']], + ], + ['exact' => ['test1'], 'wide' => []], + ['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no']], + ], + [ + 'test1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']], + ], + ['exact' => [], 'wide' => []], + [ + 'core' => [ + 'shareapi_allow_share_dialog_user_enumeration' => 'no', + 'shareapi_restrict_user_enumeration_full_match_userid' => 'no', + ], + ] + ], + [ + 'Test user 1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']], + ], + ['exact' => ['test1'], 'wide' => []], + [ + 'core' => [ + 'shareapi_allow_share_dialog_user_enumeration' => 'no', + 'shareapi_restrict_user_enumeration_full_match_userid' => 'no', + ], + ] + ], + [ + 'Test user 1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1 (Second displayName for user 1)', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2 (Second displayName for user 2)', 'groups' => ['groupA']], + ], + ['exact' => [], 'wide' => []], + ['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no'], + ] + ], + [ + 'Test user 1', + ['groupA'], + [ + ['uid' => 'test1', 'displayName' => 'Test user 1 (Second displayName for user 1)', 'groups' => ['groupA']], + ['uid' => 'test2', 'displayName' => 'Test user 2 (Second displayName for user 2)', 'groups' => ['groupA']], + ], + ['exact' => ['test1'], 'wide' => []], + [ + 'core' => [ + 'shareapi_allow_share_dialog_user_enumeration' => 'no', + 'shareapi_restrict_user_enumeration_full_match_ignore_second_dn' => 'yes', + ], + ] ], [ 'test1', @@ -549,6 +652,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB']], ], ['exact' => ['test1'], 'wide' => []], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -558,6 +662,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB', 'groupA']], ], ['exact' => [], 'wide' => ['test1', 'test2']], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -567,6 +672,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB', 'groupA']], ], ['exact' => [], 'wide' => ['test1', 'test2']], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -576,6 +682,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB', 'groupA']], ], ['exact' => [], 'wide' => ['test1', 'test2']], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -585,6 +692,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => ['groupB', 'groupA']], ], ['exact' => [], 'wide' => []], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -594,6 +702,7 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => []], ], ['exact' => [], 'wide' => []], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], [ 'test', @@ -603,40 +712,82 @@ class UserPluginTest extends TestCase { ['uid' => 'test2', 'groups' => []], ], ['exact' => [], 'wide' => []], + ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']], ], ]; } - /** - * @dataProvider dataSearchEnumeration - */ - public function testSearchEnumerationLimit($search, $userGroups, $matchingUsers, $result) { - $this->mockConfig(false, true, true); + #[\PHPUnit\Framework\Attributes\DataProvider('dataSearchEnumeration')] + public function testSearchEnumerationLimit($search, $userGroups, $matchingUsers, $result, $mockedSettings): void { + $this->mockConfig($mockedSettings); - $userResults = array_map(function ($user) { - return $this->getUserMock($user['uid'], $user['uid']); - }, $matchingUsers); + $userResults = []; + foreach ($matchingUsers as $user) { + $userResults[$user['uid']] = $user['uid']; + } - $mappedResultExact = array_map(function ($user) { - return ['label' => $user, 'value' => ['shareType' => 0, 'shareWith' => $user], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => $user]; + $usersById = []; + foreach ($matchingUsers as $user) { + $usersById[$user['uid']] = $user; + } + + $mappedResultExact = array_map(function ($user) use ($usersById, $search) { + return [ + 'label' => $search === $user ? $user : $usersById[$user]['displayName'], + 'value' => ['shareType' => 0, 'shareWith' => $user], + 'icon' => 'icon-user', + 'subline' => null, + 'status' => [], + 'shareWithDisplayNameUnique' => $user, + ]; }, $result['exact']); $mappedResultWide = array_map(function ($user) { - return ['label' => $user, 'value' => ['shareType' => 0, 'shareWith' => $user], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => $user]; + return [ + 'label' => $user, + 'value' => ['shareType' => 0, 'shareWith' => $user], + 'icon' => 'icon-user', + 'subline' => null, + 'status' => [], + 'shareWithDisplayNameUnique' => $user, + ]; }, $result['wide']); - $this->userManager->expects($this->once()) + $this->userManager + ->method('get') + ->willReturnCallback(function ($userId) use ($userResults) { + if (isset($userResults[$userId])) { + return $this->getUserMock($userId, $userId); + } + return null; + }); + $this->userManager ->method('searchDisplayName') + ->willReturnCallback(function ($search) use ($matchingUsers) { + $users = array_filter( + $matchingUsers, + fn ($user) => str_contains(strtolower($user['displayName']), strtolower($search)) + ); + return array_map( + fn ($user) => $this->getUserMock($user['uid'], $user['displayName']), + $users); + }); + + $this->groupManager->method('displayNamesInGroup') ->willReturn($userResults); + + $this->session->expects($this->any()) ->method('getUser') ->willReturn($this->getUserMock('test', 'foo')); - // current user - $this->groupManager->expects($this->at(0)) - ->method('getUserGroupIds') - ->willReturn($userGroups); $this->groupManager->expects($this->any()) ->method('getUserGroupIds') - ->willReturnCallback(function ($user) use ($matchingUsers) { + ->willReturnCallback(function ($user) use ($matchingUsers, $userGroups) { + static $firstCall = true; + if ($firstCall) { + $firstCall = false; + // current user + return $userGroups; + } $neededObject = array_filter( $matchingUsers, function ($e) use ($user) { |