diff options
Diffstat (limited to 'apps/files_sharing/tests/External')
-rw-r--r-- | apps/files_sharing/tests/External/CacheTest.php | 59 | ||||
-rw-r--r-- | apps/files_sharing/tests/External/ManagerTest.php | 695 | ||||
-rw-r--r-- | apps/files_sharing/tests/External/ScannerTest.php | 53 |
3 files changed, 572 insertions, 235 deletions
diff --git a/apps/files_sharing/tests/External/CacheTest.php b/apps/files_sharing/tests/External/CacheTest.php index b86cf55af80..39e2057a24c 100644 --- a/apps/files_sharing/tests/External/CacheTest.php +++ b/apps/files_sharing/tests/External/CacheTest.php @@ -1,37 +1,23 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ - namespace OCA\Files_Sharing\Tests\External; use OC\Federation\CloudIdManager; +use OC\Files\Storage\Storage; +use OCA\Files_Sharing\External\Cache; use OCA\Files_Sharing\Tests\TestCase; use OCP\Contacts\IManager; +use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudIdManager; +use OCP\Files\Cache\ICacheEntry; +use OCP\ICacheFactory; +use OCP\IURLGenerator; +use OCP\IUserManager; /** * Class Cache @@ -45,12 +31,12 @@ class CacheTest extends TestCase { protected $contactsManager; /** - * @var \OC\Files\Storage\Storage + * @var Storage **/ private $storage; /** - * @var \OCA\Files_Sharing\External\Cache + * @var Cache */ private $cache; @@ -59,7 +45,7 @@ class CacheTest extends TestCase { */ private $remoteUser; - /** @var ICloudIdManager */ + /** @var ICloudIdManager */ private $cloudIdManager; protected function setUp(): void { @@ -67,7 +53,13 @@ class CacheTest extends TestCase { $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->remoteUser = $this->getUniqueID('remoteuser'); $this->storage = $this->getMockBuilder('\OCA\Files_Sharing\External\Storage') @@ -82,10 +74,11 @@ class CacheTest extends TestCase { ->method('search') ->willReturn([]); - $this->cache = new \OCA\Files_Sharing\External\Cache( + $this->cache = new Cache( $this->storage, $this->cloudIdManager->getCloudId($this->remoteUser, 'http://example.com/owncloud') ); + $this->cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); $this->cache->put( 'test.txt', [ @@ -103,7 +96,7 @@ class CacheTest extends TestCase { parent::tearDown(); } - public function testGetInjectsOwnerDisplayName() { + public function testGetInjectsOwnerDisplayName(): void { $info = $this->cache->get('test.txt'); $this->assertEquals( $this->remoteUser . '@example.com/owncloud', @@ -111,12 +104,12 @@ class CacheTest extends TestCase { ); } - public function testGetReturnsFalseIfNotFound() { + public function testGetReturnsFalseIfNotFound(): void { $info = $this->cache->get('unexisting-entry.txt'); $this->assertFalse($info); } - public function testGetFolderPopulatesOwner() { + public function testGetFolderPopulatesOwner(): void { $dirId = $this->cache->put( 'subdir', [ diff --git a/apps/files_sharing/tests/External/ManagerTest.php b/apps/files_sharing/tests/External/ManagerTest.php index e35d734f04e..14c6afec4d8 100644 --- a/apps/files_sharing/tests/External/ManagerTest.php +++ b/apps/files_sharing/tests/External/ManagerTest.php @@ -1,38 +1,17 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Joas Schilling <coding@schilljs.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ - namespace OCA\Files_Sharing\Tests\External; use OC\Federation\CloudIdManager; +use OC\Files\Mount\MountPoint; +use OC\Files\SetupManagerFactory; use OC\Files\Storage\StorageFactory; +use OC\Files\Storage\Temporary; use OCA\Files_Sharing\External\Manager; use OCA\Files_Sharing\External\MountProvider; use OCA\Files_Sharing\Tests\TestCase; @@ -40,11 +19,23 @@ use OCP\Contacts\IManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudFederationFactory; use OCP\Federation\ICloudFederationProviderManager; +use OCP\Files\NotFoundException; +use OCP\Http\Client\IClient; use OCP\Http\Client\IClientService; use OCP\Http\Client\IResponse; +use OCP\ICacheFactory; +use OCP\IDBConnection; +use OCP\IGroup; use OCP\IGroupManager; +use OCP\IURLGenerator; +use OCP\IUser; use OCP\IUserManager; +use OCP\IUserSession; +use OCP\OCS\IDiscoveryService; +use OCP\Server; use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; use Test\Traits\UserTrait; /** @@ -57,47 +48,26 @@ use Test\Traits\UserTrait; class ManagerTest extends TestCase { use UserTrait; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - protected $contactsManager; - - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject **/ - private $manager; - - /** @var \OC\Files\Mount\Manager */ - private $mountManager; - - /** @var IClientService|\PHPUnit\Framework\MockObject\MockObject */ - private $clientService; - - /** @var ICloudFederationProviderManager|\PHPUnit\Framework\MockObject\MockObject */ - private $cloudFederationProviderManager; - - /** @var ICloudFederationFactory|\PHPUnit\Framework\MockObject\MockObject */ - private $cloudFederationFactory; - - /** @var \PHPUnit\Framework\MockObject\MockObject|IGroupManager */ - private $groupManager; - - /** @var \PHPUnit\Framework\MockObject\MockObject|IUserManager */ - private $userManager; - - private $uid; - - /** - * @var \OCP\IUser - */ - private $user; - private $testMountProvider; - /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */ - private $eventDispatcher; + protected string $uid; + protected IUser $user; + protected MountProvider $testMountProvider; + protected IEventDispatcher&MockObject $eventDispatcher; + protected LoggerInterface&MockObject $logger; + protected \OC\Files\Mount\Manager $mountManager; + protected IManager&MockObject $contactsManager; + protected Manager&MockObject $manager; + protected IClientService&MockObject $clientService; + protected ICloudFederationProviderManager&MockObject $cloudFederationProviderManager; + protected ICloudFederationFactory&MockObject $cloudFederationFactory; + protected IGroupManager&MockObject $groupManager; + protected IUserManager&MockObject $userManager; protected function setUp(): void { parent::setUp(); $this->uid = $this->getUniqueID('user'); - $this->createUser($this->uid, ''); - $this->user = \OC::$server->getUserManager()->get($this->uid); - $this->mountManager = new \OC\Files\Mount\Manager(); + $this->user = $this->createUser($this->uid, ''); + $this->mountManager = new \OC\Files\Mount\Manager($this->createMock(SetupManagerFactory::class)); $this->clientService = $this->getMockBuilder(IClientService::class) ->disableOriginalConstructor()->getMock(); $this->cloudFederationProviderManager = $this->createMock(ICloudFederationProviderManager::class); @@ -112,38 +82,90 @@ class ManagerTest extends TestCase { ->method('search') ->willReturn([]); - $this->manager = $this->getMockBuilder(Manager::class) + $this->logger = $this->createMock(LoggerInterface::class); + $this->logger->expects($this->never())->method('emergency'); + + $this->manager = $this->createManagerForUser($this->uid); + + $this->testMountProvider = new MountProvider(Server::get(IDBConnection::class), function () { + return $this->manager; + }, new CloudIdManager( + $this->createMock(ICacheFactory::class), + $this->createMock(IEventDispatcher::class), + $this->contactsManager, + $this->createMock(IURLGenerator::class), + $this->userManager, + )); + + $group1 = $this->createMock(IGroup::class); + $group1->expects($this->any())->method('getGID')->willReturn('group1'); + $group1->expects($this->any())->method('inGroup')->with($this->user)->willReturn(true); + + $group2 = $this->createMock(IGroup::class); + $group2->expects($this->any())->method('getGID')->willReturn('group2'); + $group2->expects($this->any())->method('inGroup')->with($this->user)->willReturn(true); + + $this->userManager->expects($this->any())->method('get')->willReturn($this->user); + $this->groupManager->expects($this->any())->method(('getUserGroups'))->willReturn([$group1, $group2]); + $this->groupManager->expects($this->any())->method(('get')) + ->willReturnMap([ + ['group1', $group1], + ['group2', $group2], + ]); + } + + protected function tearDown(): void { + // clear the share external table to avoid side effects + $query = Server::get(IDBConnection::class)->prepare('DELETE FROM `*PREFIX*share_external`'); + $result = $query->execute(); + $result->closeCursor(); + + parent::tearDown(); + } + + private function createManagerForUser($userId) { + $user = $this->createMock(IUser::class); + $user->method('getUID') + ->willReturn($userId); + $userSession = $this->createMock(IUserSession::class); + $userSession->method('getUser') + ->willReturn($user); + + return $this->getMockBuilder(Manager::class) ->setConstructorArgs( [ - \OC::$server->getDatabaseConnection(), + Server::get(IDBConnection::class), $this->mountManager, new StorageFactory(), $this->clientService, - \OC::$server->getNotificationManager(), - \OC::$server->query(\OCP\OCS\IDiscoveryService::class), + Server::get(\OCP\Notification\IManager::class), + Server::get(IDiscoveryService::class), $this->cloudFederationProviderManager, $this->cloudFederationFactory, $this->groupManager, $this->userManager, - $this->uid, + $userSession, $this->eventDispatcher, + $this->logger, ] - )->setMethods(['tryOCMEndPoint'])->getMock(); - - $this->testMountProvider = new MountProvider(\OC::$server->getDatabaseConnection(), function () { - return $this->manager; - }, new CloudIdManager($this->contactsManager)); + )->onlyMethods(['tryOCMEndPoint'])->getMock(); } private function setupMounts() { + $this->clearMounts(); $mounts = $this->testMountProvider->getMountsForUser($this->user, new StorageFactory()); foreach ($mounts as $mount) { $this->mountManager->addMount($mount); } } - public function testAddShare() { - $shareData1 = [ + private function clearMounts() { + $this->mountManager->clear(); + $this->mountManager->addMount(new MountPoint(Temporary::class, '', [])); + } + + public function testAddUserShare(): void { + $this->doTestAddShare([ 'remote' => 'http://localhost', 'token' => 'token1', 'password' => '', @@ -153,23 +175,45 @@ class ManagerTest extends TestCase { 'accepted' => false, 'user' => $this->uid, 'remoteId' => '2342' - ]; + ], false); + } + + public function testAddGroupShare(): void { + $this->doTestAddShare([ + 'remote' => 'http://localhost', + 'token' => 'token1', + 'password' => '', + 'name' => '/SharedFolder', + 'owner' => 'foobar', + 'shareType' => IShare::TYPE_GROUP, + 'accepted' => false, + 'user' => 'group1', + 'remoteId' => '2342' + ], true); + } + + public function doTestAddShare($shareData1, $isGroup = false) { $shareData2 = $shareData1; $shareData2['token'] = 'token2'; $shareData3 = $shareData1; $shareData3['token'] = 'token3'; - $this->userManager->expects($this->any())->method('get')->willReturn($this->user); - $this->groupManager->expects($this->any())->method(('getUserGroups'))->willReturn([]); - - $this->manager->expects($this->at(0))->method('tryOCMEndPoint')->with('http://localhost', 'token1', '2342', 'accept')->willReturn(false); - $this->manager->expects($this->at(1))->method('tryOCMEndPoint')->with('http://localhost', 'token3', '2342', 'decline')->willReturn(false); + if ($isGroup) { + $this->manager->expects($this->never())->method('tryOCMEndPoint'); + } else { + $this->manager->expects(self::atLeast(2)) + ->method('tryOCMEndPoint') + ->willReturnMap([ + ['http://localhost', 'token1', '2342', 'accept', false], + ['http://localhost', 'token3', '2342', 'decline', false], + ]); + } // Add a share for "user" $this->assertSame(null, call_user_func_array([$this->manager, 'addShare'], $shareData1)); $openShares = $this->manager->getOpenShares(); $this->assertCount(1, $openShares); - $this->assertExternalShareEntry($shareData1, $openShares[0], 1, '{{TemporaryMountPointName#' . $shareData1['name'] . '}}'); + $this->assertExternalShareEntry($shareData1, $openShares[0], 1, '{{TemporaryMountPointName#' . $shareData1['name'] . '}}', $shareData1['user']); $this->setupMounts(); $this->assertNotMount('SharedFolder'); @@ -179,46 +223,54 @@ class ManagerTest extends TestCase { $this->assertSame(null, call_user_func_array([$this->manager, 'addShare'], $shareData2)); $openShares = $this->manager->getOpenShares(); $this->assertCount(2, $openShares); - $this->assertExternalShareEntry($shareData1, $openShares[0], 1, '{{TemporaryMountPointName#' . $shareData1['name'] . '}}'); + $this->assertExternalShareEntry($shareData1, $openShares[0], 1, '{{TemporaryMountPointName#' . $shareData1['name'] . '}}', $shareData1['user']); // New share falls back to "-1" appendix, because the name is already taken - $this->assertExternalShareEntry($shareData2, $openShares[1], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1'); + $this->assertExternalShareEntry($shareData2, $openShares[1], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1', $shareData2['user']); $this->setupMounts(); $this->assertNotMount('SharedFolder'); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}'); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1'); - $client = $this->getMockBuilder('OCP\Http\Client\IClient') - ->disableOriginalConstructor()->getMock(); - $this->clientService->expects($this->at(0)) + $newClientCalls = []; + $this->clientService ->method('newClient') - ->willReturn($client); - $response = $this->createMock(IResponse::class); - $response->method('getBody') - ->willReturn(json_encode([ - 'ocs' => [ - 'meta' => [ - 'statuscode' => 200, + ->willReturnCallback(function () use (&$newClientCalls): IClient { + if (!empty($newClientCalls)) { + return array_shift($newClientCalls); + } + return $this->createMock(IClient::class); + }); + if (!$isGroup) { + $client = $this->createMock(IClient::class); + $newClientCalls[] = $client; + $response = $this->createMock(IResponse::class); + $response->method('getBody') + ->willReturn(json_encode([ + 'ocs' => [ + 'meta' => [ + 'statuscode' => 200, + ] ] - ] - ])); - $client->expects($this->once()) - ->method('post') - ->with($this->stringStartsWith('http://localhost/ocs/v2.php/cloud/shares/' . $openShares[0]['remote_id']), $this->anything()) - ->willReturn($response); + ])); + $client->expects($this->once()) + ->method('post') + ->with($this->stringStartsWith('http://localhost/ocs/v2.php/cloud/shares/' . $openShares[0]['remote_id']), $this->anything()) + ->willReturn($response); + } // Accept the first share - $this->manager->acceptShare($openShares[0]['id']); + $this->assertTrue($this->manager->acceptShare($openShares[0]['id'])); // Check remaining shares - Accepted $acceptedShares = self::invokePrivate($this->manager, 'getShares', [true]); $this->assertCount(1, $acceptedShares); $shareData1['accepted'] = true; - $this->assertExternalShareEntry($shareData1, $acceptedShares[0], 1, $shareData1['name']); + $this->assertExternalShareEntry($shareData1, $acceptedShares[0], 1, $shareData1['name'], $this->uid); // Check remaining shares - Open $openShares = $this->manager->getOpenShares(); $this->assertCount(1, $openShares); - $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1'); + $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1', $shareData2['user']); $this->setupMounts(); $this->assertMount($shareData1['name']); @@ -229,36 +281,39 @@ class ManagerTest extends TestCase { $this->assertSame(null, call_user_func_array([$this->manager, 'addShare'], $shareData3)); $openShares = $this->manager->getOpenShares(); $this->assertCount(2, $openShares); - $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1'); - // New share falls back to the original name (no "-\d", because the name is not taken) - $this->assertExternalShareEntry($shareData3, $openShares[1], 3, '{{TemporaryMountPointName#' . $shareData3['name'] . '}}'); + $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1', $shareData2['user']); + if (!$isGroup) { + // New share falls back to the original name (no "-\d", because the name is not taken) + $this->assertExternalShareEntry($shareData3, $openShares[1], 3, '{{TemporaryMountPointName#' . $shareData3['name'] . '}}', $shareData3['user']); + } else { + $this->assertExternalShareEntry($shareData3, $openShares[1], 3, '{{TemporaryMountPointName#' . $shareData3['name'] . '}}-2', $shareData3['user']); + } $this->setupMounts(); $this->assertMount($shareData1['name']); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}'); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1'); - $client = $this->getMockBuilder('OCP\Http\Client\IClient') - ->disableOriginalConstructor()->getMock(); - $this->clientService->expects($this->at(0)) - ->method('newClient') - ->willReturn($client); - $response = $this->createMock(IResponse::class); - $response->method('getBody') - ->willReturn(json_encode([ - 'ocs' => [ - 'meta' => [ - 'statuscode' => 200, + if (!$isGroup) { + $client = $this->createMock(IClient::class); + $newClientCalls[] = $client; + $response = $this->createMock(IResponse::class); + $response->method('getBody') + ->willReturn(json_encode([ + 'ocs' => [ + 'meta' => [ + 'statuscode' => 200, + ] ] - ] - ])); - $client->expects($this->once()) - ->method('post') - ->with($this->stringStartsWith('http://localhost/ocs/v2.php/cloud/shares/' . $openShares[1]['remote_id'] . '/decline'), $this->anything()) - ->willReturn($response); + ])); + $client->expects($this->once()) + ->method('post') + ->with($this->stringStartsWith('http://localhost/ocs/v2.php/cloud/shares/' . $openShares[1]['remote_id'] . '/decline'), $this->anything()) + ->willReturn($response); + } // Decline the third share - $this->manager->declineShare($openShares[1]['id']); + $this->assertTrue($this->manager->declineShare($openShares[1]['id'])); $this->setupMounts(); $this->assertMount($shareData1['name']); @@ -269,68 +324,382 @@ class ManagerTest extends TestCase { $acceptedShares = self::invokePrivate($this->manager, 'getShares', [true]); $this->assertCount(1, $acceptedShares); $shareData1['accepted'] = true; - $this->assertExternalShareEntry($shareData1, $acceptedShares[0], 1, $shareData1['name']); + $this->assertExternalShareEntry($shareData1, $acceptedShares[0], 1, $shareData1['name'], $this->uid); // Check remaining shares - Open $openShares = $this->manager->getOpenShares(); - $this->assertCount(1, $openShares); - $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1'); + if ($isGroup) { + // declining a group share adds it back to pending instead of deleting it + $this->assertCount(2, $openShares); + // this is a group share that is still open + $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1', $shareData2['user']); + // this is the user share sub-entry matching the group share which got declined + $this->assertExternalShareEntry($shareData3, $openShares[1], 2, '{{TemporaryMountPointName#' . $shareData3['name'] . '}}-2', $this->uid); + } else { + $this->assertCount(1, $openShares); + $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1', $this->uid); + } $this->setupMounts(); $this->assertMount($shareData1['name']); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}'); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1'); - $client1 = $this->getMockBuilder('OCP\Http\Client\IClient') - ->disableOriginalConstructor()->getMock(); - $client2 = $this->getMockBuilder('OCP\Http\Client\IClient') - ->disableOriginalConstructor()->getMock(); - $this->clientService->expects($this->at(0)) - ->method('newClient') - ->willReturn($client1); - $this->clientService->expects($this->at(1)) - ->method('newClient') - ->willReturn($client2); - $response = $this->createMock(IResponse::class); - $response->method('getBody') - ->willReturn(json_encode([ - 'ocs' => [ - 'meta' => [ - 'statuscode' => 200, + if ($isGroup) { + // no http requests here + $this->manager->removeGroupShares('group1'); + } else { + $client1 = $this->createMock(IClient::class); + $client2 = $this->createMock(IClient::class); + $newClientCalls[] = $client1; + $newClientCalls[] = $client2; + $response = $this->createMock(IResponse::class); + $response->method('getBody') + ->willReturn(json_encode([ + 'ocs' => [ + 'meta' => [ + 'statuscode' => 200, + ] ] - ] - ])); - $client1->expects($this->once()) - ->method('post') - ->with($this->stringStartsWith('http://localhost/ocs/v2.php/cloud/shares/' . $openShares[0]['remote_id'] . '/decline'), $this->anything()) - ->willReturn($response); - $client2->expects($this->once()) - ->method('post') - ->with($this->stringStartsWith('http://localhost/ocs/v2.php/cloud/shares/' . $acceptedShares[0]['remote_id'] . '/decline'), $this->anything()) - ->willReturn($response); + ])); + + $client1->expects($this->once()) + ->method('post') + ->with($this->stringStartsWith('http://localhost/ocs/v2.php/cloud/shares/' . $openShares[0]['remote_id'] . '/decline'), $this->anything()) + ->willReturn($response); + $client2->expects($this->once()) + ->method('post') + ->with($this->stringStartsWith('http://localhost/ocs/v2.php/cloud/shares/' . $acceptedShares[0]['remote_id'] . '/decline'), $this->anything()) + ->willReturn($response); + + $this->manager->removeUserShares($this->uid); + } - $this->manager->removeUserShares($this->uid); $this->assertEmpty(self::invokePrivate($this->manager, 'getShares', [null]), 'Asserting all shares for the user have been deleted'); - $this->mountManager->clear(); + $this->clearMounts(); self::invokePrivate($this->manager, 'setupMounts'); $this->assertNotMount($shareData1['name']); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}'); $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1'); } + private function verifyAcceptedGroupShare($shareData) { + $openShares = $this->manager->getOpenShares(); + $this->assertCount(0, $openShares); + $acceptedShares = self::invokePrivate($this->manager, 'getShares', [true]); + $this->assertCount(1, $acceptedShares); + $shareData['accepted'] = true; + $this->assertExternalShareEntry($shareData, $acceptedShares[0], 0, $shareData['name'], $this->uid); + $this->setupMounts(); + $this->assertMount($shareData['name']); + } + + private function verifyDeclinedGroupShare($shareData, $tempMount = null) { + if ($tempMount === null) { + $tempMount = '{{TemporaryMountPointName#/SharedFolder}}'; + } + $openShares = $this->manager->getOpenShares(); + $this->assertCount(1, $openShares); + $acceptedShares = self::invokePrivate($this->manager, 'getShares', [true]); + $this->assertCount(0, $acceptedShares); + $this->assertExternalShareEntry($shareData, $openShares[0], 0, $tempMount, $this->uid); + $this->setupMounts(); + $this->assertNotMount($shareData['name']); + $this->assertNotMount($tempMount); + } + + private function createTestUserShare($userId = 'user1') { + $shareData = [ + 'remote' => 'http://localhost', + 'token' => 'token1', + 'password' => '', + 'name' => '/SharedFolder', + 'owner' => 'foobar', + 'shareType' => IShare::TYPE_USER, + 'accepted' => false, + 'user' => $userId, + 'remoteId' => '2342' + ]; + + $this->assertSame(null, call_user_func_array([$this->manager, 'addShare'], $shareData)); + + return $shareData; + } + private function createTestGroupShare($groupId = 'group1') { + $shareData = [ + 'remote' => 'http://localhost', + 'token' => 'token1', + 'password' => '', + 'name' => '/SharedFolder', + 'owner' => 'foobar', + 'shareType' => IShare::TYPE_GROUP, + 'accepted' => false, + 'user' => $groupId, + 'remoteId' => '2342' + ]; + + $this->assertSame(null, call_user_func_array([$this->manager, 'addShare'], $shareData)); + + $allShares = self::invokePrivate($this->manager, 'getShares', [null]); + foreach ($allShares as $share) { + if ($share['user'] === $groupId) { + // this will hold the main group entry + $groupShare = $share; + break; + } + } + + return [$shareData, $groupShare]; + } + + public function testAcceptOriginalGroupShare(): void { + [$shareData, $groupShare] = $this->createTestGroupShare(); + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData); + + // a second time + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData); + } + + public function testAcceptGroupShareAgainThroughGroupShare(): void { + [$shareData, $groupShare] = $this->createTestGroupShare(); + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData); + + // decline again, this keeps the sub-share + $this->assertTrue($this->manager->declineShare($groupShare['id'])); + $this->verifyDeclinedGroupShare($shareData, '/SharedFolder'); + + // this will return sub-entries + $openShares = $this->manager->getOpenShares(); + $this->assertCount(1, $openShares); + + // accept through group share + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData, '/SharedFolder'); + + // accept a second time + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData, '/SharedFolder'); + } + + public function testAcceptGroupShareAgainThroughSubShare(): void { + [$shareData, $groupShare] = $this->createTestGroupShare(); + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData); + + // decline again, this keeps the sub-share + $this->assertTrue($this->manager->declineShare($groupShare['id'])); + $this->verifyDeclinedGroupShare($shareData, '/SharedFolder'); + + // this will return sub-entries + $openShares = $this->manager->getOpenShares(); + $this->assertCount(1, $openShares); + + // accept through sub-share + $this->assertTrue($this->manager->acceptShare($openShares[0]['id'])); + $this->verifyAcceptedGroupShare($shareData); + + // accept a second time + $this->assertTrue($this->manager->acceptShare($openShares[0]['id'])); + $this->verifyAcceptedGroupShare($shareData); + } + + public function testDeclineOriginalGroupShare(): void { + [$shareData, $groupShare] = $this->createTestGroupShare(); + $this->assertTrue($this->manager->declineShare($groupShare['id'])); + $this->verifyDeclinedGroupShare($shareData); + + // a second time + $this->assertTrue($this->manager->declineShare($groupShare['id'])); + $this->verifyDeclinedGroupShare($shareData); + } + + public function testDeclineGroupShareAgainThroughGroupShare(): void { + [$shareData, $groupShare] = $this->createTestGroupShare(); + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData); + + // decline again, this keeps the sub-share + $this->assertTrue($this->manager->declineShare($groupShare['id'])); + $this->verifyDeclinedGroupShare($shareData, '/SharedFolder'); + + // a second time + $this->assertTrue($this->manager->declineShare($groupShare['id'])); + $this->verifyDeclinedGroupShare($shareData, '/SharedFolder'); + } + + public function testDeclineGroupShareAgainThroughSubshare(): void { + [$shareData, $groupShare] = $this->createTestGroupShare(); + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData); + + // this will return sub-entries + $allShares = self::invokePrivate($this->manager, 'getShares', [null]); + $this->assertCount(1, $allShares); + + // decline again through sub-share + $this->assertTrue($this->manager->declineShare($allShares[0]['id'])); + $this->verifyDeclinedGroupShare($shareData, '/SharedFolder'); + + // a second time + $this->assertTrue($this->manager->declineShare($allShares[0]['id'])); + $this->verifyDeclinedGroupShare($shareData, '/SharedFolder'); + } + + public function testDeclineGroupShareAgainThroughMountPoint(): void { + [$shareData, $groupShare] = $this->createTestGroupShare(); + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData); + + // decline through mount point name + $this->assertTrue($this->manager->removeShare($this->uid . '/files/' . $shareData['name'])); + $this->verifyDeclinedGroupShare($shareData, '/SharedFolder'); + + // second time must fail as the mount point is gone + $this->assertFalse($this->manager->removeShare($this->uid . '/files/' . $shareData['name'])); + } + + public function testDeclineThenAcceptGroupShareAgainThroughGroupShare(): void { + [$shareData, $groupShare] = $this->createTestGroupShare(); + // decline, this creates a declined sub-share + $this->assertTrue($this->manager->declineShare($groupShare['id'])); + $this->verifyDeclinedGroupShare($shareData); + + // this will return sub-entries + $openShares = $this->manager->getOpenShares(); + + // accept through sub-share + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData, '/SharedFolder'); + + // accept a second time + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + $this->verifyAcceptedGroupShare($shareData, '/SharedFolder'); + } + + public function testDeclineThenAcceptGroupShareAgainThroughSubShare(): void { + [$shareData, $groupShare] = $this->createTestGroupShare(); + // decline, this creates a declined sub-share + $this->assertTrue($this->manager->declineShare($groupShare['id'])); + $this->verifyDeclinedGroupShare($shareData); + + // this will return sub-entries + $openShares = $this->manager->getOpenShares(); + + // accept through sub-share + $this->assertTrue($this->manager->acceptShare($openShares[0]['id'])); + $this->verifyAcceptedGroupShare($shareData); + + // accept a second time + $this->assertTrue($this->manager->acceptShare($openShares[0]['id'])); + $this->verifyAcceptedGroupShare($shareData); + } + + public function testDeleteUserShares(): void { + // user 1 shares + + $shareData = $this->createTestUserShare($this->uid); + + [$shareData, $groupShare] = $this->createTestGroupShare(); + + $shares = $this->manager->getOpenShares(); + $this->assertCount(2, $shares); + + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + + // user 2 shares + $manager2 = $this->createManagerForUser('user2'); + $shareData2 = [ + 'remote' => 'http://localhost', + 'token' => 'token1', + 'password' => '', + 'name' => '/SharedFolder', + 'owner' => 'foobar', + 'shareType' => IShare::TYPE_USER, + 'accepted' => false, + 'user' => 'user2', + 'remoteId' => '2342' + ]; + + $this->assertCount(1, $manager2->getOpenShares()); + $this->assertSame(null, call_user_func_array([$manager2, 'addShare'], $shareData2)); + $this->assertCount(2, $manager2->getOpenShares()); + + $this->manager->expects($this->once())->method('tryOCMEndPoint')->with('http://localhost', 'token1', '2342', 'decline')->willReturn([]); + $this->manager->removeUserShares($this->uid); + + $user1Shares = $this->manager->getOpenShares(); + // user share is gone, group is still there + $this->assertCount(1, $user1Shares); + $this->assertEquals($user1Shares[0]['share_type'], IShare::TYPE_GROUP); + + // user 2 shares untouched + $user2Shares = $manager2->getOpenShares(); + $this->assertCount(2, $user2Shares); + $this->assertEquals($user2Shares[0]['share_type'], IShare::TYPE_GROUP); + $this->assertEquals($user2Shares[0]['user'], 'group1'); + $this->assertEquals($user2Shares[1]['share_type'], IShare::TYPE_USER); + $this->assertEquals($user2Shares[1]['user'], 'user2'); + } + + public function testDeleteGroupShares(): void { + $shareData = $this->createTestUserShare($this->uid); + + [$shareData, $groupShare] = $this->createTestGroupShare(); + + $shares = $this->manager->getOpenShares(); + $this->assertCount(2, $shares); + + $this->assertTrue($this->manager->acceptShare($groupShare['id'])); + + // user 2 shares + $manager2 = $this->createManagerForUser('user2'); + $shareData2 = [ + 'remote' => 'http://localhost', + 'token' => 'token1', + 'password' => '', + 'name' => '/SharedFolder', + 'owner' => 'foobar', + 'shareType' => IShare::TYPE_USER, + 'accepted' => false, + 'user' => 'user2', + 'remoteId' => '2342' + ]; + + $this->assertCount(1, $manager2->getOpenShares()); + $this->assertSame(null, call_user_func_array([$manager2, 'addShare'], $shareData2)); + $this->assertCount(2, $manager2->getOpenShares()); + + $this->manager->expects($this->never())->method('tryOCMEndPoint'); + $this->manager->removeGroupShares('group1'); + + $user1Shares = $this->manager->getOpenShares(); + // user share is gone, group is still there + $this->assertCount(1, $user1Shares); + $this->assertEquals($user1Shares[0]['share_type'], IShare::TYPE_USER); + + // user 2 shares untouched + $user2Shares = $manager2->getOpenShares(); + $this->assertCount(1, $user2Shares); + $this->assertEquals($user2Shares[0]['share_type'], IShare::TYPE_USER); + $this->assertEquals($user2Shares[0]['user'], 'user2'); + } + /** * @param array $expected * @param array $actual * @param int $share * @param string $mountPoint */ - protected function assertExternalShareEntry($expected, $actual, $share, $mountPoint) { + protected function assertExternalShareEntry($expected, $actual, $share, $mountPoint, $targetEntity) { $this->assertEquals($expected['remote'], $actual['remote'], 'Asserting remote of a share #' . $share); $this->assertEquals($expected['token'], $actual['share_token'], 'Asserting token of a share #' . $share); $this->assertEquals($expected['name'], $actual['name'], 'Asserting name of a share #' . $share); $this->assertEquals($expected['owner'], $actual['owner'], 'Asserting owner of a share #' . $share); - $this->assertEquals($expected['accepted'], (int) $actual['accepted'], 'Asserting accept of a share #' . $share); - $this->assertEquals($expected['user'], $actual['user'], 'Asserting user of a share #' . $share); + $this->assertEquals($expected['accepted'], (int)$actual['accepted'], 'Asserting accept of a share #' . $share); + $this->assertEquals($targetEntity, $actual['user'], 'Asserting user of a share #' . $share); $this->assertEquals($mountPoint, $actual['mountpoint'], 'Asserting mountpoint of a share #' . $share); } @@ -346,12 +715,12 @@ class ManagerTest extends TestCase { private function assertNotMount($mountPoint) { $mountPoint = rtrim($mountPoint, '/'); - $mount = $this->mountManager->find($this->getFullPath($mountPoint)); - if ($mount) { + try { + $mount = $this->mountManager->find($this->getFullPath($mountPoint)); $this->assertInstanceOf('\OCP\Files\Mount\IMountPoint', $mount); $this->assertNotEquals($this->getFullPath($mountPoint), rtrim($mount->getMountPoint(), '/')); - } else { - $this->assertNull($mount); + } catch (NotFoundException $e) { + } } diff --git a/apps/files_sharing/tests/External/ScannerTest.php b/apps/files_sharing/tests/External/ScannerTest.php index 843f106af81..8b44d47f2b1 100644 --- a/apps/files_sharing/tests/External/ScannerTest.php +++ b/apps/files_sharing/tests/External/ScannerTest.php @@ -1,38 +1,25 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ - namespace OCA\Files_Sharing\Tests\External; +use OC\Files\Cache\Cache; use OCA\Files_Sharing\External\Scanner; +use OCA\Files_Sharing\External\Storage; use Test\TestCase; +/** + * @group DB + */ class ScannerTest extends TestCase { - /** @var \OCA\Files_Sharing\External\Scanner */ - protected $scanner; - /** @var \OCA\Files_Sharing\External\Storage|\PHPUnit\Framework\MockObject\MockObject */ + protected Scanner $scanner; + /** @var Storage|\PHPUnit\Framework\MockObject\MockObject */ protected $storage; - /** @var \OC\Files\Cache\Cache|\PHPUnit\Framework\MockObject\MockObject */ + /** @var Cache|\PHPUnit\Framework\MockObject\MockObject */ protected $cache; protected function setUp(): void { @@ -51,19 +38,7 @@ class ScannerTest extends TestCase { $this->scanner = new Scanner($this->storage); } - public function testScanAll() { - $this->storage->expects($this->any()) - ->method('getShareInfo') - ->willReturn(['status' => 'success', 'data' => []]); - - // FIXME add real tests, we are currently only checking for - // Declaration of OCA\Files_Sharing\External\Scanner::*() should be - // compatible with OC\Files\Cache\Scanner::*() - $this->scanner->scanAll(); - $this->addToAssertionCount(1); - } - - public function testScan() { + public function testScan(): void { $this->storage->expects($this->any()) ->method('getShareInfo') ->willReturn(['status' => 'success', 'data' => []]); @@ -75,7 +50,7 @@ class ScannerTest extends TestCase { $this->addToAssertionCount(1); } - public function testScanFile() { + public function testScanFile(): void { // FIXME add real tests, we are currently only checking for // Declaration of OCA\Files_Sharing\External\Scanner::*() should be // compatible with OC\Files\Cache\Scanner::*() |