aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/tests
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_sharing/tests')
-rw-r--r--apps/files_sharing/tests/ApiTest.php1501
-rw-r--r--apps/files_sharing/tests/ApplicationTest.php206
-rw-r--r--apps/files_sharing/tests/CacheTest.php608
-rw-r--r--apps/files_sharing/tests/CapabilitiesTest.php360
-rw-r--r--apps/files_sharing/tests/Collaboration/ShareRecipientSorterTest.php234
-rw-r--r--apps/files_sharing/tests/Command/CleanupRemoteStoragesTest.php205
-rw-r--r--apps/files_sharing/tests/Command/FixShareOwnersTest.php117
-rw-r--r--apps/files_sharing/tests/Controller/ExternalShareControllerTest.php80
-rw-r--r--apps/files_sharing/tests/Controller/PublicPreviewControllerTest.php292
-rw-r--r--apps/files_sharing/tests/Controller/ShareAPIControllerTest.php5380
-rw-r--r--apps/files_sharing/tests/Controller/ShareControllerTest.php822
-rw-r--r--apps/files_sharing/tests/Controller/ShareInfoControllerTest.php277
-rw-r--r--apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php466
-rw-r--r--apps/files_sharing/tests/DeleteOrphanedSharesJobTest.php148
-rw-r--r--apps/files_sharing/tests/EncryptedSizePropagationTest.php44
-rw-r--r--apps/files_sharing/tests/EtagPropagationTest.php (renamed from apps/files_sharing/tests/etagpropagation.php)249
-rw-r--r--apps/files_sharing/tests/ExpireSharesJobTest.php (renamed from apps/files_sharing/tests/expiresharesjobtest.php)116
-rw-r--r--apps/files_sharing/tests/External/CacheTest.php137
-rw-r--r--apps/files_sharing/tests/External/ManagerTest.php730
-rw-r--r--apps/files_sharing/tests/External/ScannerTest.php60
-rw-r--r--apps/files_sharing/tests/ExternalStorageTest.php118
-rw-r--r--apps/files_sharing/tests/GroupEtagPropagationTest.php (renamed from apps/files_sharing/tests/groupetagpropagation.php)91
-rw-r--r--apps/files_sharing/tests/HelperTest.php37
-rw-r--r--apps/files_sharing/tests/Listener/LoadAdditionalListenerTest.php120
-rw-r--r--apps/files_sharing/tests/LockingTest.php (renamed from apps/files_sharing/tests/locking.php)68
-rw-r--r--apps/files_sharing/tests/Middleware/OCSShareAPIMiddlewareTest.php124
-rw-r--r--apps/files_sharing/tests/Middleware/ShareInfoMiddlewareTest.php140
-rw-r--r--apps/files_sharing/tests/Middleware/SharingCheckMiddlewareTest.php205
-rw-r--r--apps/files_sharing/tests/Migration/SetPasswordColumnTest.php108
-rw-r--r--apps/files_sharing/tests/MountProviderTest.php409
-rw-r--r--apps/files_sharing/tests/PropagationTestCase.php (renamed from apps/files_sharing/tests/propagationtestcase.php)41
-rw-r--r--apps/files_sharing/tests/ShareTest.php242
-rw-r--r--apps/files_sharing/tests/SharedMountTest.php436
-rw-r--r--apps/files_sharing/tests/SharedStorageTest.php612
-rw-r--r--apps/files_sharing/tests/SharesReminderJobTest.php193
-rw-r--r--apps/files_sharing/tests/SizePropagationTest.php108
-rw-r--r--apps/files_sharing/tests/TestCase.php247
-rw-r--r--apps/files_sharing/tests/UnshareChildrenTest.php96
-rw-r--r--apps/files_sharing/tests/UpdaterTest.php345
-rw-r--r--apps/files_sharing/tests/WatcherTest.php (renamed from apps/files_sharing/tests/watcher.php)101
-rw-r--r--apps/files_sharing/tests/activity.php80
-rw-r--r--apps/files_sharing/tests/api.php1586
-rw-r--r--apps/files_sharing/tests/api/share20ocstest.php1952
-rw-r--r--apps/files_sharing/tests/api/shareestest.php1553
-rw-r--r--apps/files_sharing/tests/backend.php111
-rw-r--r--apps/files_sharing/tests/cache.php508
-rw-r--r--apps/files_sharing/tests/capabilities.php282
-rw-r--r--apps/files_sharing/tests/controller/externalsharecontroller.php152
-rw-r--r--apps/files_sharing/tests/controller/sharecontroller.php437
-rw-r--r--apps/files_sharing/tests/deleteorphanedsharesjobtest.php171
-rw-r--r--apps/files_sharing/tests/external/cache.php124
-rw-r--r--apps/files_sharing/tests/external/managertest.php253
-rw-r--r--apps/files_sharing/tests/external/scannertest.php82
-rw-r--r--apps/files_sharing/tests/externalstorage.php95
-rw-r--r--apps/files_sharing/tests/helper.php49
-rw-r--r--apps/files_sharing/tests/js/appSpec.js148
-rw-r--r--apps/files_sharing/tests/js/externalSpec.js245
-rw-r--r--apps/files_sharing/tests/js/publicAppSpec.js122
-rw-r--r--apps/files_sharing/tests/js/shareSpec.js473
-rw-r--r--apps/files_sharing/tests/js/sharedfilelistSpec.js718
-rw-r--r--apps/files_sharing/tests/middleware/sharingcheckmiddleware.php287
-rw-r--r--apps/files_sharing/tests/migrationtest.php351
-rw-r--r--apps/files_sharing/tests/permissions.php161
-rw-r--r--apps/files_sharing/tests/server2server.php254
-rw-r--r--apps/files_sharing/tests/share.php478
-rw-r--r--apps/files_sharing/tests/sharedmount.php466
-rw-r--r--apps/files_sharing/tests/sharedstorage.php488
-rw-r--r--apps/files_sharing/tests/sizepropagation.php100
-rw-r--r--apps/files_sharing/tests/testcase.php204
-rw-r--r--apps/files_sharing/tests/unsharechildren.php108
-rw-r--r--apps/files_sharing/tests/updater.php218
71 files changed, 15582 insertions, 12547 deletions
diff --git a/apps/files_sharing/tests/ApiTest.php b/apps/files_sharing/tests/ApiTest.php
new file mode 100644
index 00000000000..960f29224bb
--- /dev/null
+++ b/apps/files_sharing/tests/ApiTest.php
@@ -0,0 +1,1501 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Core\AppInfo\ConfigLexicon;
+use OC\Files\Cache\Scanner;
+use OC\Files\FileInfo;
+use OC\Files\Filesystem;
+use OC\Files\Storage\Temporary;
+use OC\Files\View;
+use OCA\Federation\TrustedServers;
+use OCA\Files_Sharing\Controller\ShareAPIController;
+use OCP\App\IAppManager;
+use OCP\AppFramework\OCS\OCSBadRequestException;
+use OCP\AppFramework\OCS\OCSException;
+use OCP\AppFramework\OCS\OCSForbiddenException;
+use OCP\AppFramework\OCS\OCSNotFoundException;
+use OCP\Constants;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\IAppConfig;
+use OCP\IConfig;
+use OCP\IDateTimeZone;
+use OCP\IGroupManager;
+use OCP\IL10N;
+use OCP\IPreview;
+use OCP\IRequest;
+use OCP\ITagManager;
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\Mail\IMailer;
+use OCP\Server;
+use OCP\Share\IProviderFactory;
+use OCP\Share\IShare;
+use OCP\UserStatus\IManager as IUserStatusManager;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Container\ContainerInterface;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class ApiTest
+ *
+ * @group DB
+ * TODO: convert to real integration tests
+ */
+class ApiTest extends TestCase {
+ public const TEST_FOLDER_NAME = '/folder_share_api_test';
+ public const APP_NAME = 'files_sharing';
+
+ private static $tempStorage;
+
+ private Folder $userFolder;
+ private string $subsubfolder;
+ protected IAppConfig&MockObject $appConfig;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups', 'no');
+ Server::get(IConfig::class)->setAppValue('core', 'shareapi_expire_after_n_days', '7');
+
+ Filesystem::getLoader()->removeStorageWrapper('sharing_mask');
+
+ $this->folder = self::TEST_FOLDER_NAME;
+ $this->subfolder = '/subfolder_share_api_test';
+ $this->subsubfolder = '/subsubfolder_share_api_test';
+
+ $this->filename = '/share-api-test.txt';
+
+ // save file with content
+ $this->view->file_put_contents($this->filename, $this->data);
+ $this->view->mkdir($this->folder);
+ $this->view->mkdir($this->folder . $this->subfolder);
+ $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder);
+ $this->view->file_put_contents($this->folder . $this->filename, $this->data);
+ $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data);
+ $mount = $this->view->getMount($this->filename);
+ $mount->getStorage()->getScanner()->scan('', Scanner::SCAN_RECURSIVE);
+
+ $this->userFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+
+ $this->appConfig = $this->createMock(IAppConfig::class);
+ }
+
+ protected function tearDown(): void {
+ if ($this->view instanceof View) {
+ $this->view->unlink($this->filename);
+ $this->view->deleteAll($this->folder);
+ }
+
+ self::$tempStorage = null;
+
+ parent::tearDown();
+ }
+
+ /**
+ * @param string $userId The userId of the caller
+ * @return ShareAPIController
+ */
+ private function createOCS($userId) {
+ $l = $this->getMockBuilder(IL10N::class)->getMock();
+ $l->method('t')
+ ->willReturnCallback(function ($text, $parameters = []) {
+ return vsprintf($text, $parameters);
+ });
+ $config = $this->createMock(IConfig::class);
+ $appManager = $this->createMock(IAppManager::class);
+ $serverContainer = $this->createMock(ContainerInterface::class);
+ $userStatusManager = $this->createMock(IUserStatusManager::class);
+ $previewManager = $this->createMock(IPreview::class);
+ $dateTimeZone = $this->createMock(IDateTimeZone::class);
+ $logger = $this->createMock(LoggerInterface::class);
+ $providerFactory = $this->createMock(IProviderFactory::class);
+ $mailer = $this->createMock(IMailer::class);
+ $tagManager = $this->createMock(ITagManager::class);
+ $trustedServers = $this->createMock(TrustedServers::class);
+ $dateTimeZone->method('getTimeZone')->willReturn(new \DateTimeZone(date_default_timezone_get()));
+
+ return new ShareAPIController(
+ self::APP_NAME,
+ $this->getMockBuilder(IRequest::class)->getMock(),
+ $this->shareManager,
+ Server::get(IGroupManager::class),
+ Server::get(IUserManager::class),
+ Server::get(IRootFolder::class),
+ Server::get(IURLGenerator::class),
+ $l,
+ $config,
+ $this->appConfig,
+ $appManager,
+ $serverContainer,
+ $userStatusManager,
+ $previewManager,
+ $dateTimeZone,
+ $logger,
+ $providerFactory,
+ $mailer,
+ $tagManager,
+ $trustedServers,
+ $userId,
+ );
+ }
+
+ public function testCreateShareUserFile(): void {
+ $this->setUp(); // for some reasons phpunit refuses to do this for us only for this test
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertEquals(19, $data['permissions']);
+ $this->assertEmpty($data['expiration']);
+
+ $this->shareManager->getShareById('ocinternal:' . $data['id']);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($data['id']);
+
+ $ocs->cleanup();
+ }
+
+ public function testCreateShareUserFolder(): void {
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertEquals(31, $data['permissions']);
+ $this->assertEmpty($data['expiration']);
+
+ $this->shareManager->getShareById('ocinternal:' . $data['id']);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($data['id']);
+ $ocs->cleanup();
+ }
+
+
+ public function testCreateShareGroupFile(): void {
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_GROUP, self::TEST_FILES_SHARING_API_GROUP1);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertEquals(19, $data['permissions']);
+ $this->assertEmpty($data['expiration']);
+
+ $this->shareManager->getShareById('ocinternal:' . $data['id']);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($data['id']);
+ $ocs->cleanup();
+ }
+
+ public function testCreateShareGroupFolder(): void {
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_GROUP, self::TEST_FILES_SHARING_API_GROUP1);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertEquals(31, $data['permissions']);
+ $this->assertEmpty($data['expiration']);
+
+ $this->shareManager->getShareById('ocinternal:' . $data['id']);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($data['id']);
+ $ocs->cleanup();
+ }
+
+ /**
+ * @group RoutingWeirdness
+ */
+ public function testCreateShareLink(): void {
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertEquals(Constants::PERMISSION_ALL,
+ $data['permissions']);
+ $this->assertEmpty($data['expiration']);
+ $this->assertTrue(is_string($data['token']));
+
+ // check for correct link
+ $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']);
+ $this->assertEquals($url, $data['url']);
+
+ $this->shareManager->getShareById('ocinternal:' . $data['id']);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($data['id']);
+ $ocs->cleanup();
+ }
+
+ /**
+ * @group RoutingWeirdness
+ * @dataProvider dataAllowFederationOnPublicShares
+ */
+ public function testCreateShareLinkPublicUpload(array $appConfig, int $permissions): void {
+ $this->appConfig->method('getValueBool')
+ ->willReturnMap([$appConfig]);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true');
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertEquals(
+ Constants::PERMISSION_READ
+ | Constants::PERMISSION_CREATE
+ | Constants::PERMISSION_UPDATE
+ | Constants::PERMISSION_DELETE
+ | $permissions,
+ $data['permissions']
+ );
+ $this->assertEmpty($data['expiration']);
+ $this->assertTrue(is_string($data['token']));
+
+ // check for correct link
+ $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']);
+ $this->assertEquals($url, $data['url']);
+
+ $this->shareManager->getShareById('ocinternal:' . $data['id']);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($data['id']);
+ $ocs->cleanup();
+ }
+
+ public function testEnforceLinkPassword(): void {
+ $password = md5(time());
+ $config = Server::get(IConfig::class);
+ $config->setAppValue('core', 'shareapi_enforce_links_password', 'yes');
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ try {
+ $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK);
+ $this->fail();
+ } catch (OCSForbiddenException $e) {
+ }
+ $ocs->cleanup();
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ try {
+ $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '');
+ $this->fail();
+ } catch (OCSForbiddenException $e) {
+ }
+ $ocs->cleanup();
+
+ // share with password should succeed
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', $password);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+
+ // setting new password should succeed
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->updateShare($data['id'], null, $password);
+ $ocs->cleanup();
+
+ // removing password should fail
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ try {
+ $ocs->updateShare($data['id']);
+ $this->fail();
+ } catch (OCSBadRequestException $e) {
+ }
+ $ocs->cleanup();
+
+ // cleanup
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($data['id']);
+ $ocs->cleanup();
+
+ $config->setAppValue('core', 'shareapi_enforce_links_password', 'no');
+ $this->addToAssertionCount(1);
+ }
+
+ /**
+ * @medium
+ */
+ public function testSharePermissions(): void {
+ // sharing file to a user should work if shareapi_exclude_groups is set
+ // to no
+ Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups', 'no');
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+
+ $this->shareManager->getShareById('ocinternal:' . $data['id']);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($data['id']);
+ $ocs->cleanup();
+
+ // exclude groups, but not the group the user belongs to. Sharing should still work
+ Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups', 'yes');
+ Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups_list', 'admin,group1,group2');
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+
+ $this->shareManager->getShareById('ocinternal:' . $data['id']);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($data['id']);
+ $ocs->cleanup();
+
+ // now we exclude the group the user belongs to ('group'), sharing should fail now
+ Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups_list', 'admin,group');
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
+ $ocs->cleanup();
+
+ // cleanup
+ Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups', 'no');
+ Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups_list', '');
+
+ $this->addToAssertionCount(1);
+ }
+
+
+ /**
+ * @medium
+ */
+ public function testGetAllShares(): void {
+ $node = $this->userFolder->get($this->filename);
+
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+
+ $share = $this->shareManager->createShare($share);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ $this->assertTrue(count($result->getData()) === 1);
+
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testGetAllSharesWithMe(): void {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ $this->logout();
+
+ $node1 = $this->userFolder->get($this->filename);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+ $share1 = $this->shareManager->createShare($share1);
+ $share1->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share1);
+
+ $node2 = $this->userFolder->get($this->folder);
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(31);
+ $share2 = $this->shareManager->createShare($share2);
+ $share2->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share2);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $result = $ocs->getShares('true');
+ $ocs->cleanup();
+
+ $this->assertCount(2, $result->getData());
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ }
+
+ /**
+ * @medium
+ * @group RoutingWeirdness
+ */
+ public function testPublicLinkUrl(): void {
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+
+ // check if we have a token
+ $this->assertTrue(is_string($data['token']));
+ $id = $data['id'];
+
+ // check for correct link
+ $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']);
+ $this->assertEquals($url, $data['url']);
+
+ // check for link in getall shares
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertEquals($url, current($data)['url']);
+
+ // check for path
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertEquals($url, current($data)['url']);
+
+ // check in share id
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShare($id);
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertEquals($url, current($data)['url']);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($id);
+ $ocs->cleanup();
+ }
+
+ /**
+ * @medium
+ * @depends testCreateShareUserFile
+ * @depends testCreateShareLink
+ */
+ public function testGetShareFromSource(): void {
+ $node = $this->userFolder->get($this->filename);
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+ $share1 = $this->shareManager->createShare($share);
+
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share2 = $this->shareManager->createShare($share);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ // test should return one share created from testCreateShare()
+ $this->assertTrue(count($result->getData()) === 2);
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ }
+
+ /**
+ * @medium
+ * @depends testCreateShareUserFile
+ * @depends testCreateShareLink
+ */
+ public function testGetShareFromSourceWithReshares(): void {
+ $node = $this->userFolder->get($this->filename);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+ $share1 = $this->shareManager->createShare($share1);
+
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER3)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+ $share2 = $this->shareManager->createShare($share2);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ // test should return one share
+ $this->assertTrue(count($result->getData()) === 1);
+
+ // now also ask for the reshares
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares('false', 'true', 'false', $this->filename);
+ $ocs->cleanup();
+
+ // now we should get two shares, the initial share and the reshare
+ $this->assertCount(2, $result->getData());
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ }
+
+ /**
+ * @medium
+ * @depends testCreateShareUserFile
+ */
+ public function testGetShareFromId(): void {
+ $node = $this->userFolder->get($this->filename);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+ $share1 = $this->shareManager->createShare($share1);
+
+ // call getShare() with share ID
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShare($share1->getId());
+ $ocs->cleanup();
+
+ // test should return one share created from testCreateShare()
+ $this->assertEquals(1, count($result->getData()));
+
+ $this->shareManager->deleteShare($share1);
+ }
+
+ /**
+ * @medium
+ */
+ public function testGetShareFromFolder(): void {
+ $node1 = $this->userFolder->get($this->filename);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+ $share1 = $this->shareManager->createShare($share1);
+
+ $node2 = $this->userFolder->get($this->folder . '/' . $this->filename);
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share2 = $this->shareManager->createShare($share2);
+
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares('false', 'false', 'true', $this->folder);
+ $ocs->cleanup();
+
+ // test should return one share within $this->folder
+ $this->assertTrue(count($result->getData()) === 1);
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ }
+
+ public function testGetShareFromFolderWithFile(): void {
+ $node1 = $this->userFolder->get($this->filename);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+ $share1 = $this->shareManager->createShare($share1);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ try {
+ $ocs->getShares('false', 'false', 'true', $this->filename);
+ $this->fail();
+ } catch (OCSBadRequestException $e) {
+ $this->assertEquals('Not a directory', $e->getMessage());
+ }
+ $ocs->cleanup();
+
+ $this->shareManager->deleteShare($share1);
+ }
+
+ /**
+ * share a folder, than reshare a file within the shared folder and check if we construct the correct path
+ * @medium
+ */
+ public function testGetShareFromFolderReshares(): void {
+ $node1 = $this->userFolder->get($this->folder);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(31);
+ $share1 = $this->shareManager->createShare($share1);
+ $share1->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share1);
+
+ $node2 = $this->userFolder->get($this->folder . '/' . $this->filename);
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share2 = $this->shareManager->createShare($share2);
+ $share2->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share2);
+
+ $node3 = $this->userFolder->get($this->folder . '/' . $this->subfolder . '/' . $this->filename);
+ $share3 = $this->shareManager->newShare();
+ $share3->setNode($node3)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share3 = $this->shareManager->createShare($share3);
+ $share3->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share3);
+
+ $testValues = [
+ ['query' => $this->folder,
+ 'expectedResult' => $this->folder . $this->filename],
+ ['query' => $this->folder . $this->subfolder,
+ 'expectedResult' => $this->folder . $this->subfolder . $this->filename],
+ ];
+
+ foreach ($testValues as $value) {
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $result = $ocs->getShares('false', 'false', 'true', $value['query']);
+ $ocs->cleanup();
+
+ // test should return one share within $this->folder
+ $data = $result->getData();
+
+ $this->assertEquals($value['expectedResult'], $data[0]['path']);
+ }
+
+ // cleanup
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ $this->shareManager->deleteShare($share3);
+ }
+
+ /**
+ * reshare a sub folder and check if we get the correct path
+ * @medium
+ */
+ public function testGetShareFromSubFolderReShares(): void {
+ $node1 = $this->userFolder->get($this->folder . $this->subfolder);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(31);
+ $share1 = $this->shareManager->createShare($share1);
+ $share1->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share1);
+
+ $node2 = Server::get(IRootFolder::class)->getUserFolder(self::TEST_FILES_SHARING_API_USER2)->get($this->subfolder);
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share2 = $this->shareManager->createShare($share2);
+ $share2->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share2);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ // test should return one share within $this->folder
+ $data = $result->getData();
+
+ // we should get exactly one result
+ $this->assertCount(1, $data);
+
+ $this->assertEquals($this->subfolder, $data[0]['path']);
+
+ $this->shareManager->deleteShare($share2);
+ $this->shareManager->deleteShare($share1);
+ }
+
+ /**
+ * test re-re-share of folder if the path gets constructed correctly
+ * @medium
+ */
+ public function XtestGetShareFromFolderReReShares() {
+ $node1 = $this->userFolder->get($this->folder . $this->subfolder);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(31);
+ $share1 = $this->shareManager->createShare($share1);
+
+ $node2 = $this->userFolder->get($this->folder . $this->subfolder . $this->subsubfolder);
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER3)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(31);
+ $share2 = $this->shareManager->createShare($share2);
+
+ $share3 = $this->shareManager->newShare();
+ $share3->setNode($node2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER3)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share3 = $this->shareManager->createShare($share3);
+
+ /*
+ * Test as recipient
+ */
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER3);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ // test should return one share within $this->folder
+ $data = $result->getData();
+
+ // we should get exactly one result
+ $this->assertCount(1, $data);
+ $this->assertEquals($this->subsubfolder, $data[0]['path']);
+
+ /*
+ * Test for first owner/initiator
+ */
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ // test should return one share within $this->folder
+ $data = $result->getData();
+
+ // we should get exactly one result
+ $this->assertCount(1, $data);
+ $this->assertEquals($this->folder . $this->subfolder, $data[0]['path']);
+
+ /*
+ * Test for second initiator
+ */
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ // test should return one share within $this->folder
+ $data = $result->getData();
+
+ // we should get exactly one result
+ $this->assertCount(1, $data);
+ $this->assertEquals($this->subfolder . $this->subsubfolder, $data[0]['path']);
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ $this->shareManager->deleteShare($share3);
+ }
+
+ /**
+ * test multiple shared folder if the path gets constructed correctly
+ * @medium
+ */
+ public function testGetShareMultipleSharedFolder(): void {
+ $this->setUp();
+ $node1 = $this->userFolder->get($this->folder . $this->subfolder);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(31);
+ $share1 = $this->shareManager->createShare($share1);
+ $share1->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share1);
+
+ $node2 = $this->userFolder->get($this->folder);
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(31);
+ $share2 = $this->shareManager->createShare($share2);
+ $share2->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share2);
+
+ $share3 = $this->shareManager->newShare();
+ $share3->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share3 = $this->shareManager->createShare($share3);
+ $share3->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share3);
+
+ // $request = $this->createRequest(['path' => $this->subfolder]);
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $result1 = $ocs->getShares('false', 'false', 'false', $this->subfolder);
+ $ocs->cleanup();
+
+ // test should return one share within $this->folder
+ $data1 = $result1->getData();
+ $this->assertCount(1, $data1);
+ $s1 = reset($data1);
+
+ //$request = $this->createRequest(['path' => $this->folder.$this->subfolder]);
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $result2 = $ocs->getShares('false', 'false', 'false', $this->folder . $this->subfolder);
+ $ocs->cleanup();
+
+ // test should return one share within $this->folder
+ $data2 = $result2->getData();
+ $this->assertCount(1, $data2);
+ $s2 = reset($data2);
+
+ $this->assertEquals($this->subfolder, $s1['path']);
+ $this->assertEquals($this->folder . $this->subfolder, $s2['path']);
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ $this->shareManager->deleteShare($share3);
+ }
+
+ /**
+ * test re-re-share of folder if the path gets constructed correctly
+ * @medium
+ */
+ public function testGetShareFromFileReReShares(): void {
+ $node1 = $this->userFolder->get($this->folder . $this->subfolder);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(31);
+ $share1 = $this->shareManager->createShare($share1);
+ $share1->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share1);
+
+ $user2Folder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER2);
+ $node2 = $user2Folder->get($this->subfolder . $this->filename);
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER3)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+ $share2 = $this->shareManager->createShare($share2);
+ $share2->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share2);
+
+ $user3Folder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER3);
+ $node3 = $user3Folder->get($this->filename);
+ $share3 = $this->shareManager->newShare();
+ $share3->setNode($node3)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER3)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share3 = $this->shareManager->createShare($share3);
+ $share3->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share3);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER3);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ // test should return one share within $this->folder
+ $data = $result->getData();
+
+ // we should get exactly one result
+ $this->assertCount(1, $data);
+
+ $this->assertEquals($this->filename, $data[0]['path']);
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ $this->shareManager->deleteShare($share3);
+ }
+
+ /**
+ * @medium
+ */
+ public function testGetShareFromUnknownId(): void {
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER3);
+ try {
+ $ocs->getShare(0);
+ $this->fail();
+ } catch (OCSNotFoundException $e) {
+ $this->assertEquals('Wrong share ID, share does not exist', $e->getMessage());
+ }
+ $ocs->cleanup();
+ }
+
+ /**
+ * @medium
+ * @depends testCreateShareUserFile
+ * @depends testCreateShareLink
+ */
+ public function testUpdateShare(): void {
+ $password = md5(time());
+
+ $node1 = $this->userFolder->get($this->filename);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19)
+ ->setAttributes($this->shareManager->newShare()->newAttributes());
+
+ $this->assertNotNull($share1->getAttributes());
+ $share1 = $this->shareManager->createShare($share1);
+ $this->assertEquals(19, $share1->getPermissions());
+
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share2 = $this->shareManager->createShare($share2);
+ $this->assertEquals(1, $share2->getPermissions());
+
+ // update permissions
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->updateShare(
+ $share1->getId(), 1, null, null, null, null, null, null, null,
+ '[{"scope": "app1", "key": "attr1", "value": true}]'
+ );
+ $ocs->cleanup();
+
+ $share1 = $this->shareManager->getShareById('ocinternal:' . $share1->getId());
+ $this->assertEquals(1, $share1->getPermissions());
+ $this->assertEquals(true, $share1->getAttributes()->getAttribute('app1', 'attr1'));
+
+ // update password for link share
+ $this->assertNull($share2->getPassword());
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->updateShare($share2->getId(), null, $password);
+ $ocs->cleanup();
+
+ $share2 = $this->shareManager->getShareById('ocinternal:' . $share2->getId());
+ $this->assertNotNull($share2->getPassword());
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->updateShare($share2->getId(), null, '');
+ $ocs->cleanup();
+
+ $share2 = $this->shareManager->getShareById('ocinternal:' . $share2->getId());
+ $this->assertNull($share2->getPassword());
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ }
+
+ /**
+ * @medium
+ * @dataProvider dataAllowFederationOnPublicShares
+ */
+ public function testUpdateShareUpload(array $appConfig, int $permissions): void {
+ $this->appConfig->method('getValueBool')->willReturnMap([
+ $appConfig,
+ ]);
+
+ $node1 = $this->userFolder->get($this->folder);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share1 = $this->shareManager->createShare($share1);
+
+ // update public upload
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->updateShare($share1->getId(), null, null, null, 'true');
+ $ocs->cleanup();
+
+ $share1 = $this->shareManager->getShareById($share1->getFullId());
+ $this->assertEquals(
+ Constants::PERMISSION_READ
+ | Constants::PERMISSION_CREATE
+ | Constants::PERMISSION_UPDATE
+ | Constants::PERMISSION_DELETE
+ | $permissions,
+ $share1->getPermissions()
+ );
+
+ // cleanup
+ $this->shareManager->deleteShare($share1);
+ }
+
+ public static function dataAllowFederationOnPublicShares(): array {
+ return [
+ [['core', ConfigLexicon::SHAREAPI_ALLOW_FEDERATION_ON_PUBLIC_SHARES, false, false], 0],
+ [['core', ConfigLexicon::SHAREAPI_ALLOW_FEDERATION_ON_PUBLIC_SHARES, false, true], Constants::PERMISSION_SHARE],
+ ];
+ }
+
+ /**
+ * @medium
+ */
+ public function testUpdateShareExpireDate(): void {
+ $node1 = $this->userFolder->get($this->folder);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share1 = $this->shareManager->createShare($share1);
+ $share1->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share1);
+
+ $config = Server::get(IConfig::class);
+
+ // enforce expire date, by default 7 days after the file was shared
+ $config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
+ $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
+
+ $dateWithinRange = new \DateTime();
+ $dateWithinRange->add(new \DateInterval('P6D'));
+
+ $dateOutOfRange = new \DateTime();
+ $dateOutOfRange->add(new \DateInterval('P8D'));
+
+ // update expire date to a valid value
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->updateShare($share1->getId(), null, null, null, null, $dateWithinRange->format('Y-m-d'));
+ $ocs->cleanup();
+
+ $share1 = $this->shareManager->getShareById($share1->getFullId());
+
+ // date should be changed
+ $dateWithinRange->setTime(0, 0, 0);
+ $dateWithinRange->setTimezone(new \DateTimeZone(date_default_timezone_get()));
+ $this->assertEquals($dateWithinRange, $share1->getExpirationDate());
+
+ // update expire date to a value out of range
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ try {
+ $ocs->updateShare($share1->getId());
+ $this->fail();
+ } catch (OCSBadRequestException $e) {
+ }
+ $ocs->cleanup();
+
+ $share1 = $this->shareManager->getShareById($share1->getFullId());
+
+ // date shouldn't be changed
+ $this->assertEquals($dateWithinRange, $share1->getExpirationDate());
+
+ // Try to remove expire date
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ try {
+ $ocs->updateShare($share1->getId());
+ $this->fail();
+ } catch (OCSBadRequestException $e) {
+ }
+ $ocs->cleanup();
+
+ $share1 = $this->shareManager->getShareById($share1->getFullId());
+
+
+ // date shouldn't be changed
+ $this->assertEquals($dateWithinRange, $share1->getExpirationDate());
+ // cleanup
+ $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
+ $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+ $this->shareManager->deleteShare($share1);
+ }
+
+ /**
+ * @medium
+ * @depends testCreateShareUserFile
+ */
+ public function testDeleteShare(): void {
+ $node1 = $this->userFolder->get($this->filename);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(19);
+ $share1 = $this->shareManager->createShare($share1);
+
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share2 = $this->shareManager->createShare($share2);
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($share1->getId());
+ $ocs->cleanup();
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($share2->getId());
+ $ocs->cleanup();
+
+ $this->assertEmpty($this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER2, IShare::TYPE_USER));
+ $this->assertEmpty($this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER2, IShare::TYPE_LINK));
+ }
+
+ /**
+ * test unshare of a reshared file
+ */
+ public function testDeleteReshare(): void {
+ $node1 = $this->userFolder->get($this->folder);
+ $share1 = $this->shareManager->newShare();
+ $share1->setNode($node1)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(31);
+ $share1 = $this->shareManager->createShare($share1);
+ $share1->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share1);
+
+ $user2folder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER2);
+ $node2 = $user2folder->get($this->folder . '/' . $this->filename);
+ $share2 = $this->shareManager->newShare();
+ $share2->setNode($node2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(1);
+ $share2 = $this->shareManager->createShare($share2);
+ $share2->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share2);
+
+ // test if we can unshare the link again
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $ocs->deleteShare($share2->getId());
+ $ocs->cleanup();
+
+ $this->shareManager->deleteShare($share1);
+ $this->addToAssertionCount(1);
+ }
+
+ /**
+ * share a folder which contains a share mount point, should be forbidden
+ */
+ public function testShareFolderWithAMountPoint(): void {
+ // user 1 shares a folder with user2
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+
+ // user2 shares a file from the folder as link
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+ $view->mkdir('localDir');
+
+ // move mount point to the folder "localDir"
+ $result = $view->rename($this->folder, 'localDir/' . $this->folder);
+ $this->assertTrue($result !== false);
+
+ // try to share "localDir"
+ $fileInfo2 = $view->getFileInfo('localDir');
+
+ $this->assertTrue($fileInfo2 instanceof FileInfo);
+
+ $pass = true;
+ try {
+ $this->share(
+ IShare::TYPE_USER,
+ 'localDir',
+ self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3,
+ Constants::PERMISSION_ALL
+ );
+ } catch (\Exception $e) {
+ $pass = false;
+ }
+
+ $this->assertFalse($pass);
+
+ //cleanup
+
+ $result = $view->rename('localDir/' . $this->folder, $this->folder);
+ $this->assertTrue($result !== false);
+ $view->unlink('localDir');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $this->shareManager->deleteShare($share);
+ }
+
+ /**
+ * Post init mount points hook for mounting simulated ext storage
+ */
+ public static function initTestMountPointsHook($data) {
+ if ($data['user'] === self::TEST_FILES_SHARING_API_USER1) {
+ Filesystem::mount(self::$tempStorage, [], '/' . self::TEST_FILES_SHARING_API_USER1 . '/files' . self::TEST_FOLDER_NAME);
+ }
+ }
+
+ /**
+ * Tests mounting a folder that is an external storage mount point.
+ */
+ public function testShareStorageMountPoint(): void {
+ $tempStorage = new Temporary([]);
+ $tempStorage->file_put_contents('test.txt', 'abcdef');
+ $tempStorage->getScanner()->scan('');
+
+ $this->registerMount(self::TEST_FILES_SHARING_API_USER1, $tempStorage, self::TEST_FILES_SHARING_API_USER1 . '/files' . self::TEST_FOLDER_NAME);
+
+ // logging in will auto-mount the temp storage for user1 as well
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ // user 1 shares the mount point folder with user2
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+
+ // user2: check that mount point name appears correctly
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ $this->assertTrue($view->file_exists($this->folder));
+ $this->assertTrue($view->file_exists($this->folder . '/test.txt'));
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $this->shareManager->deleteShare($share);
+
+ \OC_Hook::clear('OC_Filesystem', 'post_initMountPoints');
+ \OC_Hook::clear('\OCA\Files_Sharing\Tests\ApiTest', 'initTestMountPointsHook');
+ }
+
+ public static function datesProvider() {
+ $date = new \DateTime();
+ $date->setTime(0, 0);
+ $date->add(new \DateInterval('P5D'));
+ $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
+
+ return [
+ [$date->format('Y-m-d H:i:s'), true],
+ ['abc', false],
+ [$date->format('Y-m-d H:i:s') . 'xyz', false],
+ ];
+ }
+
+ /**
+ * Make sure only ISO 8601 dates are accepted
+ *
+ * @group RoutingWeirdness
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('datesProvider')]
+ public function testPublicLinkExpireDate($date, $valid): void {
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+
+ try {
+ $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, $date);
+ $this->assertTrue($valid);
+ } catch (OCSNotFoundException $e) {
+ $this->assertFalse($valid);
+ $this->assertEquals('Invalid date. Format must be YYYY-MM-DD', $e->getMessage());
+ $ocs->cleanup();
+ return;
+ }
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertTrue(is_string($data['token']));
+ $this->assertEquals(substr($date, 0, 10), substr($data['expiration'], 0, 10));
+
+ // check for correct link
+ $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']);
+ $this->assertEquals($url, $data['url']);
+
+ $share = $this->shareManager->getShareById('ocinternal:' . $data['id']);
+
+ $this->assertEquals($date, $share->getExpirationDate()->format('Y-m-d H:i:s'));
+
+ $this->shareManager->deleteShare($share);
+ }
+
+ /**
+ * @group RoutingWeirdness
+ */
+ public function testCreatePublicLinkExpireDateValid(): void {
+ $config = Server::get(IConfig::class);
+
+ // enforce expire date, by default 7 days after the file was shared
+ $config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
+ $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
+
+ $date = new \DateTime();
+ $date->add(new \DateInterval('P5D'));
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, $date->format('Y-m-d'));
+ $ocs->cleanup();
+
+ $data = $result->getData();
+ $this->assertTrue(is_string($data['token']));
+ $this->assertEquals($date->format('Y-m-d 00:00:00'), $data['expiration']);
+
+ // check for correct link
+ $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']);
+ $this->assertEquals($url, $data['url']);
+
+ $share = $this->shareManager->getShareById('ocinternal:' . $data['id']);
+ $date->setTime(0, 0, 0);
+ $this->assertEquals($date, $share->getExpirationDate());
+
+ $this->shareManager->deleteShare($share);
+
+ $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
+ $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+ }
+
+ public function testCreatePublicLinkExpireDateInvalidFuture(): void {
+ $config = Server::get(IConfig::class);
+
+ // enforce expire date, by default 7 days after the file was shared
+ $config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
+ $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
+
+ $date = new \DateTime();
+ $date->add(new \DateInterval('P8D'));
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+
+ try {
+ $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, $date->format('Y-m-d'));
+ $this->fail();
+ } catch (OCSException $e) {
+ $this->assertEquals(404, $e->getCode());
+ $this->assertEquals('Cannot set expiration date more than 7 days in the future', $e->getMessage());
+ }
+ $ocs->cleanup();
+
+ $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
+ $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+ }
+
+ public function XtestCreatePublicLinkExpireDateInvalidPast() {
+ $config = Server::get(IConfig::class);
+
+ $date = new \DateTime();
+ $date->sub(new \DateInterval('P8D'));
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+
+ try {
+ $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, $date->format('Y-m-d'));
+ $this->fail();
+ } catch (OCSException $e) {
+ $this->assertEquals(404, $e->getCode());
+ $this->assertEquals('Expiration date is in the past', $e->getMessage());
+ }
+ $ocs->cleanup();
+
+ $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
+ $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+ }
+
+ /**
+ * test for no invisible shares
+ * See: https://github.com/owncloud/core/issues/22295
+ */
+ public function testInvisibleSharesUser(): void {
+ // simulate a post request
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
+ $ocs->cleanup();
+ $data = $result->getData();
+
+ $topId = $data['id'];
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $ocs->acceptShare($topId);
+ $ocs->cleanup();
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK);
+ $ocs->cleanup();
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($topId);
+ $ocs->cleanup();
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ $this->assertEmpty($result->getData());
+ }
+
+ /**
+ * test for no invisible shares
+ * See: https://github.com/owncloud/core/issues/22295
+ */
+ public function testInvisibleSharesGroup(): void {
+ // simulate a post request
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_GROUP, self::TEST_FILES_SHARING_API_GROUP1);
+ $ocs->cleanup();
+ $data = $result->getData();
+
+ $topId = $data['id'];
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $ocs->acceptShare($topId);
+ $ocs->cleanup();
+
+ \OC_Util::tearDownFS();
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2);
+ $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK);
+ $ocs->cleanup();
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $ocs->deleteShare($topId);
+ $ocs->cleanup();
+
+ $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
+ $result = $ocs->getShares();
+ $ocs->cleanup();
+
+ $this->assertEmpty($result->getData());
+ }
+}
diff --git a/apps/files_sharing/tests/ApplicationTest.php b/apps/files_sharing/tests/ApplicationTest.php
new file mode 100644
index 00000000000..84a3f4b372b
--- /dev/null
+++ b/apps/files_sharing/tests/ApplicationTest.php
@@ -0,0 +1,206 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Sharing\Tests;
+
+use OCA\Files_Sharing\AppInfo\Application;
+use OCA\Files_Sharing\Listener\BeforeDirectFileDownloadListener;
+use OCA\Files_Sharing\Listener\BeforeZipCreatedListener;
+use OCA\Files_Sharing\SharedStorage;
+use OCP\Files\Events\BeforeDirectFileDownloadEvent;
+use OCP\Files\Events\BeforeZipCreatedEvent;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Storage\IStorage;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\Share\IAttributes;
+use OCP\Share\IShare;
+use Test\TestCase;
+
+class ApplicationTest extends TestCase {
+ private Application $application;
+
+ /** @var IUserSession */
+ private $userSession;
+
+ /** @var IRootFolder */
+ private $rootFolder;
+
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->application = new Application([]);
+
+ $this->userSession = $this->createMock(IUserSession::class);
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ }
+
+ public function providesDataForCanGet(): array {
+ // normal file (sender) - can download directly
+ $senderFileStorage = $this->createMock(IStorage::class);
+ $senderFileStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(false);
+ $senderFile = $this->createMock(File::class);
+ $senderFile->method('getStorage')->willReturn($senderFileStorage);
+ $senderUserFolder = $this->createMock(Folder::class);
+ $senderUserFolder->method('get')->willReturn($senderFile);
+
+ $result[] = [ '/bar.txt', $senderUserFolder, true ];
+
+ // shared file (receiver) with attribute secure-view-enabled set false -
+ // can download directly
+ $receiverFileShareAttributes = $this->createMock(IAttributes::class);
+ $receiverFileShareAttributes->method('getAttribute')->with('permissions', 'download')->willReturn(true);
+ $receiverFileShare = $this->createMock(IShare::class);
+ $receiverFileShare->method('getAttributes')->willReturn($receiverFileShareAttributes);
+ $receiverFileStorage = $this->createMock(SharedStorage::class);
+ $receiverFileStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(true);
+ $receiverFileStorage->method('getShare')->willReturn($receiverFileShare);
+ $receiverFile = $this->createMock(File::class);
+ $receiverFile->method('getStorage')->willReturn($receiverFileStorage);
+ $receiverUserFolder = $this->createMock(Folder::class);
+ $receiverUserFolder->method('get')->willReturn($receiverFile);
+
+ $result[] = [ '/share-bar.txt', $receiverUserFolder, true ];
+
+ // shared file (receiver) with attribute secure-view-enabled set true -
+ // cannot download directly
+ $secureReceiverFileShareAttributes = $this->createMock(IAttributes::class);
+ $secureReceiverFileShareAttributes->method('getAttribute')->with('permissions', 'download')->willReturn(false);
+ $secureReceiverFileShare = $this->createMock(IShare::class);
+ $secureReceiverFileShare->method('getAttributes')->willReturn($secureReceiverFileShareAttributes);
+ $secureReceiverFileStorage = $this->createMock(SharedStorage::class);
+ $secureReceiverFileStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(true);
+ $secureReceiverFileStorage->method('getShare')->willReturn($secureReceiverFileShare);
+ $secureReceiverFile = $this->createMock(File::class);
+ $secureReceiverFile->method('getStorage')->willReturn($secureReceiverFileStorage);
+ $secureReceiverUserFolder = $this->createMock(Folder::class);
+ $secureReceiverUserFolder->method('get')->willReturn($secureReceiverFile);
+
+ $result[] = [ '/secure-share-bar.txt', $secureReceiverUserFolder, false ];
+
+ return $result;
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('providesDataForCanGet')]
+ public function testCheckDirectCanBeDownloaded(string $path, Folder $userFolder, bool $run): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')->willReturn('test');
+ $this->userSession->method('getUser')->willReturn($user);
+ $this->userSession->method('isLoggedIn')->willReturn(true);
+ $this->rootFolder->method('getUserFolder')->willReturn($userFolder);
+
+ // Simulate direct download of file
+ $event = new BeforeDirectFileDownloadEvent($path);
+ $listener = new BeforeDirectFileDownloadListener(
+ $this->userSession,
+ $this->rootFolder
+ );
+ $listener->handle($event);
+
+ $this->assertEquals($run, $event->isSuccessful());
+ }
+
+ public function providesDataForCanZip(): array {
+ // Mock: Normal file/folder storage
+ $nonSharedStorage = $this->createMock(IStorage::class);
+ $nonSharedStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(false);
+
+ // Mock: Secure-view file/folder shared storage
+ $secureReceiverFileShareAttributes = $this->createMock(IAttributes::class);
+ $secureReceiverFileShareAttributes->method('getAttribute')->with('permissions', 'download')->willReturn(false);
+ $secureReceiverFileShare = $this->createMock(IShare::class);
+ $secureReceiverFileShare->method('getAttributes')->willReturn($secureReceiverFileShareAttributes);
+ $secureSharedStorage = $this->createMock(SharedStorage::class);
+ $secureSharedStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(true);
+ $secureSharedStorage->method('getShare')->willReturn($secureReceiverFileShare);
+
+ // 1. can download zipped 2 non-shared files inside non-shared folder
+ // 2. can download zipped non-shared folder
+ $sender1File = $this->createMock(File::class);
+ $sender1File->method('getStorage')->willReturn($nonSharedStorage);
+ $sender1Folder = $this->createMock(Folder::class);
+ $sender1Folder->method('getStorage')->willReturn($nonSharedStorage);
+ $sender1Folder->method('getDirectoryListing')->willReturn([$sender1File, $sender1File]);
+ $sender1RootFolder = $this->createMock(Folder::class);
+ $sender1RootFolder->method('getStorage')->willReturn($nonSharedStorage);
+ $sender1RootFolder->method('getDirectoryListing')->willReturn([$sender1Folder]);
+ $sender1UserFolder = $this->createMock(Folder::class);
+ $sender1UserFolder->method('get')->willReturn($sender1RootFolder);
+
+ $return[] = [ '/folder', ['bar1.txt', 'bar2.txt'], $sender1UserFolder, true ];
+ $return[] = [ '/', ['folder'], $sender1UserFolder, true ];
+
+ // 3. cannot download zipped 1 non-shared file and 1 secure-shared inside non-shared folder
+ $receiver1File = $this->createMock(File::class);
+ $receiver1File->method('getStorage')->willReturn($nonSharedStorage);
+ $receiver1SecureFile = $this->createMock(File::class);
+ $receiver1SecureFile->method('getStorage')->willReturn($secureSharedStorage);
+ $receiver1Folder = $this->createMock(Folder::class);
+ $receiver1Folder->method('getStorage')->willReturn($nonSharedStorage);
+ $receiver1Folder->method('getDirectoryListing')->willReturn([$receiver1File, $receiver1SecureFile]);
+ $receiver1RootFolder = $this->createMock(Folder::class);
+ $receiver1RootFolder->method('getStorage')->willReturn($nonSharedStorage);
+ $receiver1RootFolder->method('getDirectoryListing')->willReturn([$receiver1Folder]);
+ $receiver1UserFolder = $this->createMock(Folder::class);
+ $receiver1UserFolder->method('get')->willReturn($receiver1RootFolder);
+
+ $return[] = [ '/folder', ['secured-bar1.txt', 'bar2.txt'], $receiver1UserFolder, false ];
+
+ // 4. cannot download zipped secure-shared folder
+ $receiver2Folder = $this->createMock(Folder::class);
+ $receiver2Folder->method('getStorage')->willReturn($secureSharedStorage);
+ $receiver2RootFolder = $this->createMock(Folder::class);
+ $receiver2RootFolder->method('getStorage')->willReturn($nonSharedStorage);
+ $receiver2RootFolder->method('getDirectoryListing')->willReturn([$receiver2Folder]);
+ $receiver2UserFolder = $this->createMock(Folder::class);
+ $receiver2UserFolder->method('get')->willReturn($receiver2RootFolder);
+
+ $return[] = [ '/', ['secured-folder'], $receiver2UserFolder, false ];
+
+ return $return;
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('providesDataForCanZip')]
+ public function testCheckZipCanBeDownloaded(string $dir, array $files, Folder $userFolder, bool $run): void {
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')->willReturn('test');
+ $this->userSession->method('getUser')->willReturn($user);
+ $this->userSession->method('isLoggedIn')->willReturn(true);
+
+ $this->rootFolder->method('getUserFolder')->with('test')->willReturn($userFolder);
+
+ // Simulate zip download of folder folder
+ $event = new BeforeZipCreatedEvent($dir, $files);
+ $listener = new BeforeZipCreatedListener(
+ $this->userSession,
+ $this->rootFolder
+ );
+ $listener->handle($event);
+
+
+ $this->assertEquals($run, $event->isSuccessful());
+ $this->assertEquals($run, $event->getErrorMessage() === null);
+ }
+
+ public function testCheckFileUserNotFound(): void {
+ $this->userSession->method('isLoggedIn')->willReturn(false);
+
+ // Simulate zip download of folder folder
+ $event = new BeforeZipCreatedEvent('/test', ['test.txt']);
+ $listener = new BeforeZipCreatedListener(
+ $this->userSession,
+ $this->rootFolder
+ );
+ $listener->handle($event);
+
+ // It should run as this would restrict e.g. share links otherwise
+ $this->assertTrue($event->isSuccessful());
+ $this->assertEquals(null, $event->getErrorMessage());
+ }
+}
diff --git a/apps/files_sharing/tests/CacheTest.php b/apps/files_sharing/tests/CacheTest.php
new file mode 100644
index 00000000000..e95d3d4f91a
--- /dev/null
+++ b/apps/files_sharing/tests/CacheTest.php
@@ -0,0 +1,608 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\Cache\Cache;
+use OC\Files\Filesystem;
+use OC\Files\Storage\Storage;
+use OC\Files\Storage\Temporary;
+use OC\Files\Storage\Wrapper\Jail;
+use OC\Files\View;
+use OCA\Files_Sharing\SharedStorage;
+use OCP\Constants;
+use OCP\Files\Cache\IWatcher;
+use OCP\IUserManager;
+use OCP\Server;
+use OCP\Share\IShare;
+
+/**
+ * Class CacheTest
+ *
+ * @group DB
+ */
+class CacheTest extends TestCase {
+
+ /**
+ * @var View
+ */
+ public $user2View;
+
+ /** @var Cache */
+ protected $ownerCache;
+
+ /** @var Cache */
+ protected $sharedCache;
+
+ /** @var Storage */
+ protected $ownerStorage;
+
+ /** @var Storage */
+ protected $sharedStorage;
+
+ /** @var \OCP\Share\IManager */
+ protected $shareManager;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->shareManager = Server::get(\OCP\Share\IManager::class);
+
+
+ $userManager = Server::get(IUserManager::class);
+ $userManager->get(self::TEST_FILES_SHARING_API_USER1)->setDisplayName('User One');
+ $userManager->get(self::TEST_FILES_SHARING_API_USER2)->setDisplayName('User Two');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $this->user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ // prepare user1's dir structure
+ $this->view->mkdir('container');
+ $this->view->mkdir('container/shareddir');
+ $this->view->mkdir('container/shareddir/subdir');
+ $this->view->mkdir('container/shareddir/emptydir');
+
+ $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ $this->view->file_put_contents('container/not shared.txt', $textData);
+ $this->view->file_put_contents('container/shared single file.txt', $textData);
+ $this->view->file_put_contents('container/shareddir/bar.txt', $textData);
+ $this->view->file_put_contents('container/shareddir/subdir/another.txt', $textData);
+ $this->view->file_put_contents('container/shareddir/subdir/another too.txt', $textData);
+ $this->view->file_put_contents('container/shareddir/subdir/not a text file.xml', '<xml></xml>');
+ $this->view->file_put_contents('simplefile.txt', $textData);
+
+ [$this->ownerStorage,] = $this->view->resolvePath('');
+ $this->ownerCache = $this->ownerStorage->getCache();
+ $this->ownerStorage->getScanner()->scan('');
+
+ // share "shareddir" with user2
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+
+ $node = $rootFolder->get('container/shareddir');
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+
+ $node = $rootFolder->get('container/shared single file.txt');
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL & ~(Constants::PERMISSION_CREATE | Constants::PERMISSION_DELETE));
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+
+ // login as user2
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ // retrieve the shared storage
+ $secondView = new View('/' . self::TEST_FILES_SHARING_API_USER2);
+ [$this->sharedStorage,] = $secondView->resolvePath('files/shareddir');
+ $this->sharedCache = $this->sharedStorage->getCache();
+ }
+
+ protected function tearDown(): void {
+ if ($this->sharedCache) {
+ $this->sharedCache->clear();
+ }
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $shares = $this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER1, IShare::TYPE_USER);
+ foreach ($shares as $share) {
+ $this->shareManager->deleteShare($share);
+ }
+
+ $this->view->deleteAll('container');
+
+ $this->ownerCache->clear();
+
+ parent::tearDown();
+ }
+
+ public function searchDataProvider() {
+ return [
+ ['%another%',
+ [
+ ['name' => 'another too.txt', 'path' => 'subdir/another too.txt'],
+ ['name' => 'another.txt', 'path' => 'subdir/another.txt'],
+ ]
+ ],
+ ['%Another%',
+ [
+ ['name' => 'another too.txt', 'path' => 'subdir/another too.txt'],
+ ['name' => 'another.txt', 'path' => 'subdir/another.txt'],
+ ]
+ ],
+ ['%dir%',
+ [
+ ['name' => 'emptydir', 'path' => 'emptydir'],
+ ['name' => 'subdir', 'path' => 'subdir'],
+ ['name' => 'shareddir', 'path' => ''],
+ ]
+ ],
+ ['%Dir%',
+ [
+ ['name' => 'emptydir', 'path' => 'emptydir'],
+ ['name' => 'subdir', 'path' => 'subdir'],
+ ['name' => 'shareddir', 'path' => ''],
+ ]
+ ],
+ ['%txt%',
+ [
+ ['name' => 'bar.txt', 'path' => 'bar.txt'],
+ ['name' => 'another too.txt', 'path' => 'subdir/another too.txt'],
+ ['name' => 'another.txt', 'path' => 'subdir/another.txt'],
+ ]
+ ],
+ ['%Txt%',
+ [
+ ['name' => 'bar.txt', 'path' => 'bar.txt'],
+ ['name' => 'another too.txt', 'path' => 'subdir/another too.txt'],
+ ['name' => 'another.txt', 'path' => 'subdir/another.txt'],
+ ]
+ ],
+ ['%',
+ [
+ ['name' => 'bar.txt', 'path' => 'bar.txt'],
+ ['name' => 'emptydir', 'path' => 'emptydir'],
+ ['name' => 'subdir', 'path' => 'subdir'],
+ ['name' => 'another too.txt', 'path' => 'subdir/another too.txt'],
+ ['name' => 'another.txt', 'path' => 'subdir/another.txt'],
+ ['name' => 'not a text file.xml', 'path' => 'subdir/not a text file.xml'],
+ ['name' => 'shareddir', 'path' => ''],
+ ]
+ ],
+ ['%nonexistent%',
+ [
+ ]
+ ],
+ ];
+ }
+
+ /**
+ * we cannot use a dataProvider because that would cause the stray hook detection to remove the hooks
+ * that were added in setUpBeforeClass.
+ */
+ public function testSearch(): void {
+ foreach ($this->searchDataProvider() as $data) {
+ [$pattern, $expectedFiles] = $data;
+
+ $results = $this->sharedStorage->getCache()->search($pattern);
+
+ $this->verifyFiles($expectedFiles, $results);
+ }
+ }
+ /**
+ * Test searching by mime type
+ */
+ public function testSearchByMime(): void {
+ $results = $this->sharedStorage->getCache()->searchByMime('text');
+ $check = [
+ [
+ 'name' => 'bar.txt',
+ 'path' => 'bar.txt'
+ ],
+ [
+ 'name' => 'another too.txt',
+ 'path' => 'subdir/another too.txt'
+ ],
+ [
+ 'name' => 'another.txt',
+ 'path' => 'subdir/another.txt'
+ ],
+ ];
+ $this->verifyFiles($check, $results);
+ }
+
+ public function testGetFolderContentsInRoot(): void {
+ $results = $this->user2View->getDirectoryContent('/');
+ $results = (array_filter($results, function ($file) {
+ return $file->getName() !== 'welcome.txt';
+ }));
+
+ // we should get the shared items "shareddir" and "shared single file.txt"
+ // additional root will always contain the example file "welcome.txt",
+ // so this will be part of the result
+ $this->verifyFiles(
+ [
+ [
+ 'name' => 'shareddir',
+ 'path' => 'files/shareddir',
+ 'mimetype' => 'httpd/unix-directory',
+ 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
+ 'displayname_owner' => 'User One',
+ ],
+ [
+ 'name' => 'shared single file.txt',
+ 'path' => 'files/shared single file.txt',
+ 'mimetype' => 'text/plain',
+ 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
+ 'displayname_owner' => 'User One',
+ ],
+ ],
+ $results
+ );
+ }
+
+ public function testGetFolderContentsInSubdir(): void {
+ $results = $this->user2View->getDirectoryContent('/shareddir');
+
+ $this->verifyFiles(
+ [
+ [
+ 'name' => 'bar.txt',
+ 'path' => 'bar.txt',
+ 'mimetype' => 'text/plain',
+ 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
+ 'displayname_owner' => 'User One',
+ ],
+ [
+ 'name' => 'emptydir',
+ 'path' => 'emptydir',
+ 'mimetype' => 'httpd/unix-directory',
+ 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
+ 'displayname_owner' => 'User One',
+ ],
+ [
+ 'name' => 'subdir',
+ 'path' => 'subdir',
+ 'mimetype' => 'httpd/unix-directory',
+ 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
+ 'displayname_owner' => 'User One',
+ ],
+ ],
+ $results
+ );
+ }
+
+ /**
+ * This covers a bug where the share owners name was propagated
+ * to the recipient in the recent files API response where the
+ * share recipient has a different target set
+ *
+ * https://github.com/nextcloud/server/issues/39879
+ */
+ public function testShareRenameOriginalFileInRecentResults(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+ $node = $rootFolder->get('simplefile.txt');
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER3)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_READ);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $node->move(self::TEST_FILES_SHARING_API_USER1 . '/files/simplefile2.txt');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER3);
+ $recents = $rootFolder->getRecent(10);
+ self::assertEquals([
+ 'welcome.txt',
+ 'simplefile.txt'
+ ], array_map(function ($node) {
+ return $node->getFileInfo()['name'];
+ }, $recents));
+ }
+
+ public function testGetFolderContentsWhenSubSubdirShared(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+ $node = $rootFolder->get('container/shareddir/subdir');
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER3)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
+
+ $thirdView = new View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files');
+ $results = $thirdView->getDirectoryContent('/subdir');
+
+ $this->verifyFiles(
+ [
+ [
+ 'name' => 'another too.txt',
+ 'path' => 'another too.txt',
+ 'mimetype' => 'text/plain',
+ 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
+ 'displayname_owner' => 'User One',
+ ],
+ [
+ 'name' => 'another.txt',
+ 'path' => 'another.txt',
+ 'mimetype' => 'text/plain',
+ 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
+ 'displayname_owner' => 'User One',
+ ],
+ [
+ 'name' => 'not a text file.xml',
+ 'path' => 'not a text file.xml',
+ 'mimetype' => 'application/xml',
+ 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
+ 'displayname_owner' => 'User One',
+ ],
+ ],
+ $results
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $this->shareManager->deleteShare($share);
+ }
+
+ /**
+ * Check if 'results' contains the expected 'examples' only.
+ *
+ * @param array $examples array of example files
+ * @param array $results array of files
+ */
+ private function verifyFiles($examples, $results) {
+ $this->assertEquals(count($examples), count($results));
+
+ foreach ($examples as $example) {
+ foreach ($results as $key => $result) {
+ if ($result['name'] === $example['name']) {
+ $this->verifyKeys($example, $result);
+ unset($results[$key]);
+ break;
+ }
+ }
+ }
+ $this->assertEquals([], $results);
+ }
+
+ /**
+ * verify if each value from the result matches the expected result
+ * @param array $example array with the expected results
+ * @param array $result array with the results
+ */
+ private function verifyKeys($example, $result) {
+ foreach ($example as $key => $value) {
+ $this->assertEquals($value, $result[$key]);
+ }
+ }
+
+ public function testGetPathByIdDirectShare(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::file_put_contents('test.txt', 'foo');
+ $info = Filesystem::getFileInfo('test.txt');
+
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+ $node = $rootFolder->get('test.txt');
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+
+ \OC_Util::tearDownFS();
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertTrue(Filesystem::file_exists('/test.txt'));
+ [$sharedStorage] = Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/test.txt');
+ /**
+ * @var SharedStorage $sharedStorage
+ */
+ $sharedCache = $sharedStorage->getCache();
+ $this->assertEquals('', $sharedCache->getPathById($info->getId()));
+ }
+
+ public function testGetPathByIdShareSubFolder(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::mkdir('foo');
+ Filesystem::mkdir('foo/bar');
+ Filesystem::touch('foo/bar/test.txt');
+ $folderInfo = Filesystem::getFileInfo('foo');
+ $fileInfo = Filesystem::getFileInfo('foo/bar/test.txt');
+
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+ $node = $rootFolder->get('foo');
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+ \OC_Util::tearDownFS();
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertTrue(Filesystem::file_exists('/foo'));
+ [$sharedStorage] = Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/foo');
+ /**
+ * @var SharedStorage $sharedStorage
+ */
+ $sharedCache = $sharedStorage->getCache();
+ $this->assertEquals('', $sharedCache->getPathById($folderInfo->getId()));
+ $this->assertEquals('bar/test.txt', $sharedCache->getPathById($fileInfo->getId()));
+ }
+
+ public function testNumericStorageId(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::mkdir('foo');
+
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+ $node = $rootFolder->get('foo');
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+ \OC_Util::tearDownFS();
+
+ [$sourceStorage] = Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER1 . '/files/foo');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertTrue(Filesystem::file_exists('/foo'));
+ /** @var SharedStorage $sharedStorage */
+ [$sharedStorage] = Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/foo');
+
+ $this->assertEquals($sourceStorage->getCache()->getNumericStorageId(), $sharedStorage->getCache()->getNumericStorageId());
+ }
+
+ public function testShareJailedStorage(): void {
+ $sourceStorage = new Temporary();
+ $sourceStorage->mkdir('jail');
+ $sourceStorage->mkdir('jail/sub');
+ $sourceStorage->file_put_contents('jail/sub/foo.txt', 'foo');
+ $jailedSource = new Jail([
+ 'storage' => $sourceStorage,
+ 'root' => 'jail'
+ ]);
+ $sourceStorage->getScanner()->scan('');
+ $this->registerMount(self::TEST_FILES_SHARING_API_USER1, $jailedSource, '/' . self::TEST_FILES_SHARING_API_USER1 . '/files/foo');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+ $node = $rootFolder->get('foo/sub');
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+ \OC_Util::tearDownFS();
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertEquals('foo', Filesystem::file_get_contents('/sub/foo.txt'));
+
+ Filesystem::file_put_contents('/sub/bar.txt', 'bar');
+ /** @var SharedStorage $sharedStorage */
+ [$sharedStorage] = Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/sub');
+
+ $this->assertTrue($sharedStorage->getCache()->inCache('bar.txt'));
+
+ $this->assertTrue($sourceStorage->getCache()->inCache('jail/sub/bar.txt'));
+ }
+
+ public function testSearchShareJailedStorage(): void {
+ $sourceStorage = new Temporary();
+ $sourceStorage->mkdir('jail');
+ $sourceStorage->mkdir('jail/sub');
+ $sourceStorage->file_put_contents('jail/sub/foo.txt', 'foo');
+ $jailedSource = new Jail([
+ 'storage' => $sourceStorage,
+ 'root' => 'jail'
+ ]);
+ $sourceStorage->getScanner()->scan('');
+ $this->registerMount(self::TEST_FILES_SHARING_API_USER1, $jailedSource, '/' . self::TEST_FILES_SHARING_API_USER1 . '/files/foo');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+ $node = $rootFolder->get('foo/sub');
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+ \OC_Util::tearDownFS();
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ /** @var SharedStorage $sharedStorage */
+ [$sharedStorage] = Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/sub');
+
+ $results = $sharedStorage->getCache()->search('foo.txt');
+ $this->assertCount(1, $results);
+ }
+
+ public function testWatcherRootChange() {
+ $sourceStorage = new Temporary();
+ $sourceStorage->mkdir('shared');
+ $sourceStorage->file_put_contents('shared/foo.txt', 'foo');
+ $sourceStorage->getScanner()->scan('');
+ $sourceStorage->getWatcher()->setPolicy(IWatcher::CHECK_ALWAYS);
+ $this->registerMount(self::TEST_FILES_SHARING_API_USER1, $sourceStorage, '/' . self::TEST_FILES_SHARING_API_USER1 . '/files/foo');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+ $node = $rootFolder->get('foo/shared');
+ $this->assertEquals(3, $node->getSize());
+
+ $share = $this->shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($share);
+ \OC_Util::tearDownFS();
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $view = Filesystem::getView();
+
+ $sourceStorage->rmdir('shared');
+
+ $this->assertFalse($view->getFileInfo('shared'));
+ }
+}
diff --git a/apps/files_sharing/tests/CapabilitiesTest.php b/apps/files_sharing/tests/CapabilitiesTest.php
new file mode 100644
index 00000000000..9a076d7a171
--- /dev/null
+++ b/apps/files_sharing/tests/CapabilitiesTest.php
@@ -0,0 +1,360 @@
+<?php
+
+/**
+ * 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;
+
+use OC\KnownUser\KnownUserService;
+use OC\Share20\Manager;
+use OC\Share20\ShareDisableChecker;
+use OCA\Files_Sharing\Capabilities;
+use OCP\App\IAppManager;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\IRootFolder;
+use OCP\Files\Mount\IMountManager;
+use OCP\IAppConfig;
+use OCP\IConfig;
+use OCP\IDateTimeZone;
+use OCP\IGroupManager;
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use OCP\L10N\IFactory;
+use OCP\Mail\IMailer;
+use OCP\Security\IHasher;
+use OCP\Security\ISecureRandom;
+use OCP\Share\IProviderFactory;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class CapabilitiesTest
+ *
+ * @group DB
+ */
+class CapabilitiesTest extends \Test\TestCase {
+
+ /**
+ * Test for the general part in each return statement and assert.
+ * Strip of the general part on the way.
+ *
+ * @param string[] $data Capabilities
+ * @return string[]
+ */
+ private function getFilesSharingPart(array $data) {
+ $this->assertArrayHasKey('files_sharing', $data);
+ return $data['files_sharing'];
+ }
+
+ /**
+ * Create a mock config object and insert the values in $map to the getAppValue
+ * function. Then obtain the capabilities and extract the first few
+ * levels in the array
+ *
+ * @param (string[])[] $map Map of arguments to return types for the getAppValue function in the mock
+ * @return string[]
+ */
+ private function getResults(array $map, array $typedMap = [], bool $federationEnabled = true) {
+ $config = $this->getMockBuilder(IConfig::class)->disableOriginalConstructor()->getMock();
+ $appManager = $this->getMockBuilder(IAppManager::class)->disableOriginalConstructor()->getMock();
+ $config->method('getAppValue')->willReturnMap($map);
+ $appManager->method('isEnabledForAnyone')->with('federation')->willReturn($federationEnabled);
+
+ if (empty($typedMap)) {
+ $appConfig = $this->createMock(IAppConfig::class);
+ } else {
+ // hack to help transition from old IConfig to new IAppConfig
+ $appConfig = $this->getMockBuilder(IAppConfig::class)->disableOriginalConstructor()->getMock();
+ $appConfig->expects($this->any())->method('getValueBool')->willReturnCallback(function (...$args) use ($typedMap): bool {
+ foreach ($typedMap as $entry) {
+ if ($entry[0] !== $args[0] || $entry[1] !== $args[1]) {
+ continue;
+ }
+
+ return $entry[2];
+ }
+
+ return false;
+ });
+ }
+
+ $shareManager = new Manager(
+ $this->createMock(LoggerInterface::class),
+ $config,
+ $this->createMock(ISecureRandom::class),
+ $this->createMock(IHasher::class),
+ $this->createMock(IMountManager::class),
+ $this->createMock(IGroupManager::class),
+ $this->createMock(IFactory::class),
+ $this->createMock(IProviderFactory::class),
+ $this->createMock(IUserManager::class),
+ $this->createMock(IRootFolder::class),
+ $this->createMock(IMailer::class),
+ $this->createMock(IURLGenerator::class),
+ $this->createMock(\OC_Defaults::class),
+ $this->createMock(IEventDispatcher::class),
+ $this->createMock(IUserSession::class),
+ $this->createMock(KnownUserService::class),
+ $this->createMock(ShareDisableChecker::class),
+ $this->createMock(IDateTimeZone::class),
+ $appConfig,
+ );
+
+ $cap = new Capabilities($config, $appConfig, $shareManager, $appManager);
+ $result = $this->getFilesSharingPart($cap->getCapabilities());
+ return $result;
+ }
+
+ public function testEnabledSharingAPI(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertTrue($result['api_enabled']);
+ $this->assertArrayHasKey('public', $result);
+ $this->assertArrayHasKey('user', $result);
+ $this->assertArrayHasKey('resharing', $result);
+ }
+
+ public function testDisabledSharingAPI(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'no'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertFalse($result['api_enabled']);
+ $this->assertFalse($result['public']['enabled']);
+ $this->assertFalse($result['user']['send_mail']);
+ $this->assertFalse($result['resharing']);
+ }
+
+ public function testNoLinkSharing(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'no'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertIsArray($result['public']);
+ $this->assertFalse($result['public']['enabled']);
+ }
+
+ public function testOnlyLinkSharing(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertIsArray($result['public']);
+ $this->assertTrue($result['public']['enabled']);
+ }
+
+ public function testLinkPassword(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $typedMap = [
+ ['core', 'shareapi_enforce_links_password', true],
+ ];
+ $result = $this->getResults($map, $typedMap);
+ $this->assertArrayHasKey('password', $result['public']);
+ $this->assertArrayHasKey('enforced', $result['public']['password']);
+ $this->assertTrue($result['public']['password']['enforced']);
+ }
+
+ public function testLinkNoPassword(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ['core', 'shareapi_enforce_links_password', 'no', 'no'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('password', $result['public']);
+ $this->assertArrayHasKey('enforced', $result['public']['password']);
+ $this->assertFalse($result['public']['password']['enforced']);
+ }
+
+ public function testLinkNoExpireDate(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_default_expire_date', 'no', 'no'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('expire_date', $result['public']);
+ $this->assertIsArray($result['public']['expire_date']);
+ $this->assertFalse($result['public']['expire_date']['enabled']);
+ }
+
+ public function testLinkExpireDate(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_default_expire_date', 'no', 'yes'],
+ ['core', 'shareapi_expire_after_n_days', '7', '7'],
+ ['core', 'shareapi_enforce_expire_date', 'no', 'no'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('expire_date', $result['public']);
+ $this->assertIsArray($result['public']['expire_date']);
+ $this->assertTrue($result['public']['expire_date']['enabled']);
+ $this->assertArrayHasKey('days', $result['public']['expire_date']);
+ $this->assertFalse($result['public']['expire_date']['enforced']);
+ }
+
+ public function testLinkExpireDateEnforced(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_default_expire_date', 'no', 'yes'],
+ ['core', 'shareapi_enforce_expire_date', 'no', 'yes'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('expire_date', $result['public']);
+ $this->assertIsArray($result['public']['expire_date']);
+ $this->assertTrue($result['public']['expire_date']['enforced']);
+ }
+
+ public function testLinkSendMail(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_allow_public_notification', 'no', 'yes'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertTrue($result['public']['send_mail']);
+ }
+
+ public function testLinkNoSendMail(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_allow_public_notification', 'no', 'no'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertFalse($result['public']['send_mail']);
+ }
+
+ public function testResharing(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_resharing', 'yes', 'yes'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertTrue($result['resharing']);
+ }
+
+ public function testNoResharing(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_resharing', 'yes', 'no'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertFalse($result['resharing']);
+ }
+
+ public function testLinkPublicUpload(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_allow_public_upload', 'yes', 'yes'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertTrue($result['public']['upload']);
+ $this->assertTrue($result['public']['upload_files_drop']);
+ }
+
+ public function testLinkNoPublicUpload(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_links', 'yes', 'yes'],
+ ['core', 'shareapi_allow_public_upload', 'yes', 'no'],
+ ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''],
+ ];
+ $result = $this->getResults($map);
+ $this->assertFalse($result['public']['upload']);
+ $this->assertFalse($result['public']['upload_files_drop']);
+ }
+
+ public function testNoGroupSharing(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_group_sharing', 'yes', 'no'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertFalse($result['group_sharing']);
+ }
+
+ public function testGroupSharing(): void {
+ $map = [
+ ['core', 'shareapi_enabled', 'yes', 'yes'],
+ ['core', 'shareapi_allow_group_sharing', 'yes', 'yes'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertTrue($result['group_sharing']);
+ }
+
+ public function testFederatedSharingIncoming(): void {
+ $map = [
+ ['files_sharing', 'incoming_server2server_share_enabled', 'yes', 'yes'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertTrue($result['federation']['incoming']);
+ }
+
+ public function testFederatedSharingNoIncoming(): void {
+ $map = [
+ ['files_sharing', 'incoming_server2server_share_enabled', 'yes', 'no'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertFalse($result['federation']['incoming']);
+ }
+
+ public function testFederatedSharingOutgoing(): void {
+ $map = [
+ ['files_sharing', 'outgoing_server2server_share_enabled', 'yes', 'yes'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertTrue($result['federation']['outgoing']);
+ }
+
+ public function testFederatedSharingNoOutgoing(): void {
+ $map = [
+ ['files_sharing', 'outgoing_server2server_share_enabled', 'yes', 'no'],
+ ];
+ $result = $this->getResults($map);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertFalse($result['federation']['outgoing']);
+ }
+
+ public function testFederatedSharingExpirationDate(): void {
+ $result = $this->getResults([]);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertEquals(['enabled' => true], $result['federation']['expire_date']);
+ $this->assertEquals(['enabled' => true], $result['federation']['expire_date_supported']);
+ }
+
+ public function testFederatedSharingDisabled(): void {
+ $result = $this->getResults([], federationEnabled: false);
+ $this->assertArrayHasKey('federation', $result);
+ $this->assertFalse($result['federation']['incoming']);
+ $this->assertFalse($result['federation']['outgoing']);
+ $this->assertEquals(['enabled' => false], $result['federation']['expire_date']);
+ $this->assertEquals(['enabled' => false], $result['federation']['expire_date_supported']);
+ }
+}
diff --git a/apps/files_sharing/tests/Collaboration/ShareRecipientSorterTest.php b/apps/files_sharing/tests/Collaboration/ShareRecipientSorterTest.php
new file mode 100644
index 00000000000..572463a9ebc
--- /dev/null
+++ b/apps/files_sharing/tests/Collaboration/ShareRecipientSorterTest.php
@@ -0,0 +1,234 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Sharing\Tests\Collaboration;
+
+use OCA\Files_Sharing\Collaboration\ShareRecipientSorter;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Node;
+use OCP\IUser;
+use OCP\IUserSession;
+use OCP\Share\IManager;
+use Test\TestCase;
+
+class ShareRecipientSorterTest extends TestCase {
+ /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
+ protected $shareManager;
+ /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */
+ protected $rootFolder;
+ /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
+ protected $userSession;
+ /** @var ShareRecipientSorter */
+ protected $sorter;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->shareManager = $this->createMock(IManager::class);
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->userSession = $this->createMock(IUserSession::class);
+
+ $this->sorter = new ShareRecipientSorter($this->shareManager, $this->rootFolder, $this->userSession);
+ }
+
+ /**
+ * @param $data
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('sortDataProvider')]
+ public function testSort($data): void {
+ $node = $this->createMock(Node::class);
+
+ /** @var Folder|\PHPUnit\Framework\MockObject\MockObject $folder */
+ $folder = $this->createMock(Folder::class);
+ $this->rootFolder->expects($this->any())
+ ->method('getUserFolder')
+ ->willReturn($folder);
+
+ $user = $this->createMock(IUser::class);
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn('yvonne');
+
+ $this->userSession->expects($this->once())
+ ->method('getUser')
+ ->willReturn($user);
+
+ if ($data['context']['itemType'] === 'files') {
+ $folder->expects($this->once())
+ ->method('getFirstNodeById')
+ ->with($data['context']['itemId'])
+ ->willReturn($node);
+
+ $this->shareManager->expects($this->once())
+ ->method('getAccessList')
+ ->with($node)
+ ->willReturn($data['accessList']);
+ } else {
+ $folder->expects($this->never())
+ ->method('getFirstNodeById');
+ $this->shareManager->expects($this->never())
+ ->method('getAccessList');
+ }
+
+ $workArray = $data['input'];
+ $this->sorter->sort($workArray, $data['context']);
+
+ $this->assertEquals($data['expected'], $workArray);
+ }
+
+ public function testSortNoNodes(): void {
+ /** @var Folder|\PHPUnit\Framework\MockObject\MockObject $folder */
+ $folder = $this->createMock(Folder::class);
+ $this->rootFolder->expects($this->any())
+ ->method('getUserFolder')
+ ->willReturn($folder);
+
+ $folder->expects($this->once())
+ ->method('getFirstNodeById')
+ ->willReturn(null);
+
+ $user = $this->createMock(IUser::class);
+ $user->expects($this->any())
+ ->method('getUID')
+ ->willReturn('yvonne');
+
+ $this->userSession->expects($this->once())
+ ->method('getUser')
+ ->willReturn($user);
+
+ $this->shareManager->expects($this->never())
+ ->method('getAccessList');
+
+ $originalArray = [
+ 'users' => [
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ]
+ ];
+ $workArray = $originalArray;
+ $this->sorter->sort($workArray, ['itemType' => 'files', 'itemId' => '404']);
+
+ $this->assertEquals($originalArray, $workArray);
+ }
+
+ public static function sortDataProvider() {
+ return [[
+ [
+ #0 – sort properly and otherwise keep existing order
+ 'context' => ['itemType' => 'files', 'itemId' => '42'],
+ 'accessList' => ['users' => ['celia', 'darius', 'faruk', 'gail'], 'bots' => ['r2-d2']],
+ 'input' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'elena']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'c-3po']],
+ ['value' => ['shareWith' => 'r2-d2']],
+ ]
+ ],
+ 'expected' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'elena']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'r2-d2']],
+ ['value' => ['shareWith' => 'c-3po']],
+ ]
+ ],
+ ],
+ [
+ #1 – no recipients
+ 'context' => ['itemType' => 'files', 'itemId' => '42'],
+ 'accessList' => ['users' => false],
+ 'input' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'elena']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'c-3po']],
+ ['value' => ['shareWith' => 'r2-d2']],
+ ]
+ ],
+ 'expected' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'elena']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'c-3po']],
+ ['value' => ['shareWith' => 'r2-d2']],
+ ]
+ ],
+ ],
+ [
+ #2 – unsupported item type
+ 'context' => ['itemType' => 'announcements', 'itemId' => '42'],
+ 'accessList' => null, // not needed
+ 'input' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'elena']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'c-3po']],
+ ['value' => ['shareWith' => 'r2-d2']],
+ ]
+ ],
+ 'expected' => [
+ 'users' => [
+ ['value' => ['shareWith' => 'alice']],
+ ['value' => ['shareWith' => 'bob']],
+ ['value' => ['shareWith' => 'celia']],
+ ['value' => ['shareWith' => 'darius']],
+ ['value' => ['shareWith' => 'elena']],
+ ['value' => ['shareWith' => 'faruk']],
+ ['value' => ['shareWith' => 'gail']],
+ ],
+ 'bots' => [
+ ['value' => ['shareWith' => 'c-3po']],
+ ['value' => ['shareWith' => 'r2-d2']],
+ ]
+ ],
+ ],
+ [
+ #3 – no nothing
+ 'context' => ['itemType' => 'files', 'itemId' => '42'],
+ 'accessList' => [],
+ 'input' => [],
+ 'expected' => [],
+ ],
+ ]];
+ }
+}
diff --git a/apps/files_sharing/tests/Command/CleanupRemoteStoragesTest.php b/apps/files_sharing/tests/Command/CleanupRemoteStoragesTest.php
new file mode 100644
index 00000000000..6f0960bf46c
--- /dev/null
+++ b/apps/files_sharing/tests/Command/CleanupRemoteStoragesTest.php
@@ -0,0 +1,205 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud GmbH.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Files_Sharing\Tests\Command;
+
+use OCA\Files_Sharing\Command\CleanupRemoteStorages;
+use OCP\Federation\ICloudId;
+use OCP\Federation\ICloudIdManager;
+use OCP\IDBConnection;
+use OCP\Server;
+use PHPUnit\Framework\MockObject\MockObject;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Test\TestCase;
+
+/**
+ * Class CleanupRemoteStoragesTest
+ *
+ * @group DB
+ *
+ * @package OCA\Files_Sharing\Tests\Command
+ */
+class CleanupRemoteStoragesTest extends TestCase {
+
+ protected IDBConnection $connection;
+ protected CleanupRemoteStorages $command;
+ private ICloudIdManager&MockObject $cloudIdManager;
+
+ private $storages = [
+ ['id' => 'shared::7b4a322b22f9d0047c38d77d471ce3cf', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e1', 'remote' => 'https://hostname.tld/owncloud1', 'user' => 'user1'],
+ ['id' => 'shared::efe3b456112c3780da6155d3a9b9141c', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e2', 'remote' => 'https://hostname.tld/owncloud2', 'user' => 'user2'],
+ ['notExistingId' => 'shared::33323d9f4ca416a9e3525b435354bc6f', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e3', 'remote' => 'https://hostname.tld/owncloud3', 'user' => 'user3'],
+ ['id' => 'shared::7fe41a07d3f517a923f4b2b599e72cbb', 'files_count' => 2],
+ ['id' => 'shared::de4aeb2f378d222b6d2c5fd8f4e42f8e', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e5', 'remote' => 'https://hostname.tld/owncloud5', 'user' => 'user5'],
+ ['id' => 'shared::af712293ab5eb9e6a1745a13818b99fe', 'files_count' => 3],
+ ['notExistingId' => 'shared::c34568c143cdac7d2f06e0800b5280f9', 'share_token' => 'f2c69dad1dc0649f26976fd210fc62e7', 'remote' => 'https://hostname.tld/owncloud7', 'user' => 'user7'],
+ ];
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->connection = Server::get(IDBConnection::class);
+
+ $storageQuery = Server::get(IDBConnection::class)->getQueryBuilder();
+ $storageQuery->insert('storages')
+ ->setValue('id', $storageQuery->createParameter('id'));
+
+ $shareExternalQuery = Server::get(IDBConnection::class)->getQueryBuilder();
+ $shareExternalQuery->insert('share_external')
+ ->setValue('share_token', $shareExternalQuery->createParameter('share_token'))
+ ->setValue('remote', $shareExternalQuery->createParameter('remote'))
+ ->setValue('name', $shareExternalQuery->createParameter('name'))
+ ->setValue('owner', $shareExternalQuery->createParameter('owner'))
+ ->setValue('user', $shareExternalQuery->createParameter('user'))
+ ->setValue('mountpoint', $shareExternalQuery->createParameter('mountpoint'))
+ ->setValue('mountpoint_hash', $shareExternalQuery->createParameter('mountpoint_hash'));
+
+ $filesQuery = Server::get(IDBConnection::class)->getQueryBuilder();
+ $filesQuery->insert('filecache')
+ ->setValue('storage', $filesQuery->createParameter('storage'))
+ ->setValue('path', $filesQuery->createParameter('path'))
+ ->setValue('path_hash', $filesQuery->createParameter('path_hash'));
+
+ foreach ($this->storages as &$storage) {
+ if (isset($storage['id'])) {
+ $storageQuery->setParameter('id', $storage['id']);
+ $storageQuery->executeStatement();
+ $storage['numeric_id'] = $storageQuery->getLastInsertId();
+ }
+
+ if (isset($storage['share_token'])) {
+ $shareExternalQuery
+ ->setParameter('share_token', $storage['share_token'])
+ ->setParameter('remote', $storage['remote'])
+ ->setParameter('name', 'irrelevant')
+ ->setParameter('owner', 'irrelevant')
+ ->setParameter('user', $storage['user'])
+ ->setParameter('mountpoint', 'irrelevant')
+ ->setParameter('mountpoint_hash', 'irrelevant');
+ $shareExternalQuery->executeStatement();
+ }
+
+ if (isset($storage['files_count'])) {
+ for ($i = 0; $i < $storage['files_count']; $i++) {
+ $filesQuery->setParameter('storage', $storage['numeric_id']);
+ $filesQuery->setParameter('path', 'file' . $i);
+ $filesQuery->setParameter('path_hash', md5('file' . $i));
+ $filesQuery->executeStatement();
+ }
+ }
+ }
+
+ $this->cloudIdManager = $this->createMock(ICloudIdManager::class);
+
+ $this->command = new CleanupRemoteStorages($this->connection, $this->cloudIdManager);
+ }
+
+ protected function tearDown(): void {
+ $storageQuery = Server::get(IDBConnection::class)->getQueryBuilder();
+ $storageQuery->delete('storages')
+ ->where($storageQuery->expr()->eq('id', $storageQuery->createParameter('id')));
+
+ $shareExternalQuery = Server::get(IDBConnection::class)->getQueryBuilder();
+ $shareExternalQuery->delete('share_external')
+ ->where($shareExternalQuery->expr()->eq('share_token', $shareExternalQuery->createParameter('share_token')))
+ ->andWhere($shareExternalQuery->expr()->eq('remote', $shareExternalQuery->createParameter('remote')));
+
+ foreach ($this->storages as $storage) {
+ if (isset($storage['id'])) {
+ $storageQuery->setParameter('id', $storage['id']);
+ $storageQuery->executeStatement();
+ }
+
+ if (isset($storage['share_token'])) {
+ $shareExternalQuery->setParameter('share_token', $storage['share_token']);
+ $shareExternalQuery->setParameter('remote', $storage['remote']);
+ $shareExternalQuery->executeStatement();
+ }
+ }
+
+ parent::tearDown();
+ }
+
+ private function doesStorageExist($numericId) {
+ $qb = Server::get(IDBConnection::class)->getQueryBuilder();
+ $qb->select('*')
+ ->from('storages')
+ ->where($qb->expr()->eq('numeric_id', $qb->createNamedParameter($numericId)));
+
+ $qResult = $qb->executeQuery();
+ $result = $qResult->fetch();
+ $qResult->closeCursor();
+ if (!empty($result)) {
+ return true;
+ }
+
+ $qb = Server::get(IDBConnection::class)->getQueryBuilder();
+ $qb->select('*')
+ ->from('filecache')
+ ->where($qb->expr()->eq('storage', $qb->createNamedParameter($numericId)));
+
+ $qResult = $qb->executeQuery();
+ $result = $qResult->fetch();
+ $qResult->closeCursor();
+ if (!empty($result)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Test cleanup of orphaned storages
+ */
+ public function testCleanup(): void {
+ $input = $this->getMockBuilder(InputInterface::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $output = $this->getMockBuilder(OutputInterface::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ // parent folder, `files`, ´test` and `welcome.txt` => 4 elements
+ $outputCalls = [];
+ $output
+ ->expects($this->any())
+ ->method('writeln')
+ ->willReturnCallback(function (string $text) use (&$outputCalls): void {
+ $outputCalls[] = $text;
+ });
+
+ $this->cloudIdManager
+ ->expects($this->any())
+ ->method('getCloudId')
+ ->willReturnCallback(function (string $user, string $remote) {
+ $cloudIdMock = $this->createMock(ICloudId::class);
+
+ // The remotes are already sanitized in the original data, so
+ // they can be directly returned.
+ $cloudIdMock
+ ->expects($this->any())
+ ->method('getRemote')
+ ->willReturn($remote);
+
+ return $cloudIdMock;
+ });
+
+ $this->command->execute($input, $output);
+
+ $this->assertTrue($this->doesStorageExist($this->storages[0]['numeric_id']));
+ $this->assertTrue($this->doesStorageExist($this->storages[1]['numeric_id']));
+ $this->assertFalse($this->doesStorageExist($this->storages[3]['numeric_id']));
+ $this->assertTrue($this->doesStorageExist($this->storages[4]['numeric_id']));
+ $this->assertFalse($this->doesStorageExist($this->storages[5]['numeric_id']));
+
+ $this->assertEquals([
+ '5 remote storage(s) need(s) to be checked',
+ '5 remote share(s) exist',
+ ], array_slice($outputCalls, 0, 2));
+ }
+}
diff --git a/apps/files_sharing/tests/Command/FixShareOwnersTest.php b/apps/files_sharing/tests/Command/FixShareOwnersTest.php
new file mode 100644
index 00000000000..0fde61895b1
--- /dev/null
+++ b/apps/files_sharing/tests/Command/FixShareOwnersTest.php
@@ -0,0 +1,117 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Files_Sharing\Tests\Command;
+
+use OCA\Files_Sharing\Command\FixShareOwners;
+use OCA\Files_Sharing\OrphanHelper;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Test\TestCase;
+
+/**
+ * Class FixShareOwnersTest
+ *
+ * @package OCA\Files_Sharing\Tests\Command
+ */
+class FixShareOwnersTest extends TestCase {
+ /**
+ * @var FixShareOwners
+ */
+ private $command;
+
+ /**
+ * @var OrphanHelper|\PHPUnit\Framework\MockObject\MockObject
+ */
+ private $orphanHelper;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->orphanHelper = $this->createMock(OrphanHelper::class);
+ $this->command = new FixShareOwners($this->orphanHelper);
+ }
+
+ public function testExecuteNoSharesDetected() {
+ $this->orphanHelper->expects($this->once())
+ ->method('getAllShares')
+ ->willReturn([
+ ['id' => 1, 'owner' => 'user1', 'fileid' => 1, 'target' => 'target1'],
+ ['id' => 2, 'owner' => 'user2', 'fileid' => 2, 'target' => 'target2'],
+ ]);
+ $this->orphanHelper->expects($this->exactly(2))
+ ->method('isShareValid')
+ ->willReturn(true);
+
+ $input = $this->createMock(InputInterface::class);
+ $output = $this->createMock(OutputInterface::class);
+
+ $output->expects($this->once())
+ ->method('writeln')
+ ->with('No broken shares detected');
+ $this->command->execute($input, $output);
+ }
+
+ public function testExecuteSharesDetected() {
+ $this->orphanHelper->expects($this->once())
+ ->method('getAllShares')
+ ->willReturn([
+ ['id' => 1, 'owner' => 'user1', 'fileid' => 1, 'target' => 'target1'],
+ ['id' => 2, 'owner' => 'user2', 'fileid' => 2, 'target' => 'target2'],
+ ]);
+ $this->orphanHelper->expects($this->exactly(2))
+ ->method('isShareValid')
+ ->willReturnOnConsecutiveCalls(true, false);
+ $this->orphanHelper->expects($this->once())
+ ->method('fileExists')
+ ->willReturn(true);
+ $this->orphanHelper->expects($this->once())
+ ->method('findOwner')
+ ->willReturn('newOwner');
+ $this->orphanHelper->expects($this->once())
+ ->method('updateShareOwner');
+
+ $input = $this->createMock(InputInterface::class);
+ $output = $this->createMock(OutputInterface::class);
+
+ $output->expects($this->once())
+ ->method('writeln')
+ ->with('Share with id <info>2</info> (target: <info>target2</info>) updated to owner <info>newOwner</info>');
+ $this->command->execute($input, $output);
+ }
+
+ public function testExecuteSharesDetectedDryRun() {
+ $this->orphanHelper->expects($this->once())
+ ->method('getAllShares')
+ ->willReturn([
+ ['id' => 1, 'owner' => 'user1', 'fileid' => 1, 'target' => 'target1'],
+ ['id' => 2, 'owner' => 'user2', 'fileid' => 2, 'target' => 'target2'],
+ ]);
+ $this->orphanHelper->expects($this->exactly(2))
+ ->method('isShareValid')
+ ->willReturnOnConsecutiveCalls(true, false);
+ $this->orphanHelper->expects($this->once())
+ ->method('fileExists')
+ ->willReturn(true);
+ $this->orphanHelper->expects($this->once())
+ ->method('findOwner')
+ ->willReturn('newOwner');
+ $this->orphanHelper->expects($this->never())
+ ->method('updateShareOwner');
+
+ $input = $this->createMock(InputInterface::class);
+ $output = $this->createMock(OutputInterface::class);
+
+ $output->expects($this->once())
+ ->method('writeln')
+ ->with('Share with id <info>2</info> (target: <info>target2</info>) can be updated to owner <info>newOwner</info>');
+ $input->expects($this->once())
+ ->method('getOption')
+ ->with('dry-run')
+ ->willReturn(true);
+ $this->command->execute($input, $output);
+ }
+}
diff --git a/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php b/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php
new file mode 100644
index 00000000000..7e054d9a6dc
--- /dev/null
+++ b/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Files_Sharing\Tests\Controllers;
+
+use OCA\Files_Sharing\Controller\ExternalSharesController;
+use OCA\Files_Sharing\External\Manager;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\Http\Client\IClientService;
+use OCP\IConfig;
+use OCP\IRequest;
+use PHPUnit\Framework\MockObject\MockObject;
+
+/**
+ * Class ExternalShareControllerTest
+ *
+ * @package OCA\Files_Sharing\Controllers
+ */
+class ExternalShareControllerTest extends \Test\TestCase {
+ /** @var IRequest */
+ private $request;
+ /** @var \OCA\Files_Sharing\External\Manager */
+ private $externalManager;
+ /** @var IConfig|MockObject */
+ private $config;
+ /** @var IClientService */
+ private $clientService;
+
+ protected function setUp(): void {
+ parent::setUp();
+ $this->request = $this->createMock(IRequest::class);
+ $this->externalManager = $this->createMock(Manager::class);
+ $this->clientService = $this->createMock(IClientService::class);
+ $this->config = $this->createMock(IConfig::class);
+ }
+
+ /**
+ * @return ExternalSharesController
+ */
+ public function getExternalShareController() {
+ return new ExternalSharesController(
+ 'files_sharing',
+ $this->request,
+ $this->externalManager,
+ $this->clientService,
+ $this->config,
+ );
+ }
+
+ public function testIndex(): void {
+ $this->externalManager
+ ->expects($this->once())
+ ->method('getOpenShares')
+ ->willReturn(['MyDummyArray']);
+
+ $this->assertEquals(new JSONResponse(['MyDummyArray']), $this->getExternalShareController()->index());
+ }
+
+ public function testCreate(): void {
+ $this->externalManager
+ ->expects($this->once())
+ ->method('acceptShare')
+ ->with(4);
+
+ $this->assertEquals(new JSONResponse(), $this->getExternalShareController()->create(4));
+ }
+
+ public function testDestroy(): void {
+ $this->externalManager
+ ->expects($this->once())
+ ->method('declineShare')
+ ->with(4);
+
+ $this->assertEquals(new JSONResponse(), $this->getExternalShareController()->destroy(4));
+ }
+}
diff --git a/apps/files_sharing/tests/Controller/PublicPreviewControllerTest.php b/apps/files_sharing/tests/Controller/PublicPreviewControllerTest.php
new file mode 100644
index 00000000000..f49d839e8d4
--- /dev/null
+++ b/apps/files_sharing/tests/Controller/PublicPreviewControllerTest.php
@@ -0,0 +1,292 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Sharing\Tests\Controller;
+
+use OCA\Files_Sharing\Controller\PublicPreviewController;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Http\FileDisplayResponse;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Constants;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\NotFoundException;
+use OCP\Files\SimpleFS\ISimpleFile;
+use OCP\IPreview;
+use OCP\IRequest;
+use OCP\ISession;
+use OCP\Preview\IMimeIconProvider;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\IManager;
+use OCP\Share\IShare;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class PublicPreviewControllerTest extends TestCase {
+
+ private IPreview&MockObject $previewManager;
+ private IManager&MockObject $shareManager;
+ private ITimeFactory&MockObject $timeFactory;
+ private IRequest&MockObject $request;
+
+ private PublicPreviewController $controller;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->previewManager = $this->createMock(IPreview::class);
+ $this->shareManager = $this->createMock(IManager::class);
+ $this->timeFactory = $this->createMock(ITimeFactory::class);
+ $this->request = $this->createMock(IRequest::class);
+
+ $this->timeFactory->method('getTime')
+ ->willReturn(1337);
+
+ $this->overwriteService(ITimeFactory::class, $this->timeFactory);
+
+ $this->controller = new PublicPreviewController(
+ 'files_sharing',
+ $this->request,
+ $this->shareManager,
+ $this->createMock(ISession::class),
+ $this->previewManager,
+ $this->createMock(IMimeIconProvider::class),
+ );
+ }
+
+ public function testInvalidToken(): void {
+ $res = $this->controller->getPreview('', 'file', 10, 10, '');
+ $expected = new DataResponse([], Http::STATUS_BAD_REQUEST);
+
+ $this->assertEquals($expected, $res);
+ }
+
+ public function testInvalidWidth(): void {
+ $res = $this->controller->getPreview('token', 'file', 0);
+ $expected = new DataResponse([], Http::STATUS_BAD_REQUEST);
+
+ $this->assertEquals($expected, $res);
+ }
+
+ public function testInvalidHeight(): void {
+ $res = $this->controller->getPreview('token', 'file', 10, 0);
+ $expected = new DataResponse([], Http::STATUS_BAD_REQUEST);
+
+ $this->assertEquals($expected, $res);
+ }
+
+ public function testInvalidShare(): void {
+ $this->shareManager->method('getShareByToken')
+ ->with($this->equalTo('token'))
+ ->willThrowException(new ShareNotFound());
+
+ $res = $this->controller->getPreview('token', 'file', 10, 10);
+ $expected = new DataResponse([], Http::STATUS_NOT_FOUND);
+
+ $this->assertEquals($expected, $res);
+ }
+
+ public function testShareNotAccessable(): void {
+ $share = $this->createMock(IShare::class);
+ $this->shareManager->method('getShareByToken')
+ ->with($this->equalTo('token'))
+ ->willReturn($share);
+
+ $share->method('getPermissions')
+ ->willReturn(0);
+
+ $res = $this->controller->getPreview('token', 'file', 10, 10);
+ $expected = new DataResponse([], Http::STATUS_FORBIDDEN);
+
+ $this->assertEquals($expected, $res);
+ }
+
+ public function testShareNoDownload() {
+ $share = $this->createMock(IShare::class);
+ $this->shareManager->method('getShareByToken')
+ ->with($this->equalTo('token'))
+ ->willReturn($share);
+
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ);
+
+ $share->method('canSeeContent')
+ ->willReturn(false);
+
+ $res = $this->controller->getPreview('token', 'file', 10, 10);
+ $expected = new DataResponse([], Http::STATUS_FORBIDDEN);
+
+ $this->assertEquals($expected, $res);
+ }
+
+ public function testShareNoDownloadButPreviewHeader() {
+ $share = $this->createMock(IShare::class);
+ $this->shareManager->method('getShareByToken')
+ ->with($this->equalTo('token'))
+ ->willReturn($share);
+
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ);
+
+ $share->method('canSeeContent')
+ ->willReturn(false);
+
+ $this->request->method('getHeader')
+ ->with('x-nc-preview')
+ ->willReturn('true');
+
+ $file = $this->createMock(File::class);
+ $share->method('getNode')
+ ->willReturn($file);
+
+ $preview = $this->createMock(ISimpleFile::class);
+ $preview->method('getName')->willReturn('name');
+ $preview->method('getMTime')->willReturn(42);
+ $this->previewManager->method('getPreview')
+ ->with($this->equalTo($file), 10, 10, false)
+ ->willReturn($preview);
+
+ $preview->method('getMimeType')
+ ->willReturn('myMime');
+
+ $res = $this->controller->getPreview('token', 'file', 10, 10, true);
+ $expected = new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => 'myMime']);
+ $expected->cacheFor(15 * 60);
+ $this->assertEquals($expected, $res);
+ }
+
+ public function testShareWithAttributes() {
+ $share = $this->createMock(IShare::class);
+ $this->shareManager->method('getShareByToken')
+ ->with($this->equalTo('token'))
+ ->willReturn($share);
+
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ);
+
+ $share->method('canSeeContent')
+ ->willReturn(true);
+
+ $this->request->method('getHeader')
+ ->with('x-nc-preview')
+ ->willReturn('true');
+
+ $file = $this->createMock(File::class);
+ $share->method('getNode')
+ ->willReturn($file);
+
+ $preview = $this->createMock(ISimpleFile::class);
+ $preview->method('getName')->willReturn('name');
+ $preview->method('getMTime')->willReturn(42);
+ $this->previewManager->method('getPreview')
+ ->with($this->equalTo($file), 10, 10, false)
+ ->willReturn($preview);
+
+ $preview->method('getMimeType')
+ ->willReturn('myMime');
+
+ $res = $this->controller->getPreview('token', 'file', 10, 10, true);
+ $expected = new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => 'myMime']);
+ $expected->cacheFor(3600 * 24);
+ $this->assertEquals($expected, $res);
+ }
+
+ public function testPreviewFile() {
+ $share = $this->createMock(IShare::class);
+ $this->shareManager->method('getShareByToken')
+ ->with($this->equalTo('token'))
+ ->willReturn($share);
+
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ);
+
+ $file = $this->createMock(File::class);
+ $share->method('getNode')
+ ->willReturn($file);
+
+ $share->method('canSeeContent')
+ ->willReturn(true);
+
+ $preview = $this->createMock(ISimpleFile::class);
+ $preview->method('getName')->willReturn('name');
+ $preview->method('getMTime')->willReturn(42);
+ $this->previewManager->method('getPreview')
+ ->with($this->equalTo($file), 10, 10, false)
+ ->willReturn($preview);
+
+ $preview->method('getMimeType')
+ ->willReturn('myMime');
+
+ $res = $this->controller->getPreview('token', 'file', 10, 10, true);
+ $expected = new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => 'myMime']);
+ $expected->cacheFor(3600 * 24);
+ $this->assertEquals($expected, $res);
+ }
+
+ public function testPreviewFolderInvalidFile(): void {
+ $share = $this->createMock(IShare::class);
+ $this->shareManager->method('getShareByToken')
+ ->with($this->equalTo('token'))
+ ->willReturn($share);
+
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ);
+
+ $folder = $this->createMock(Folder::class);
+ $share->method('getNode')
+ ->willReturn($folder);
+
+ $share->method('canSeeContent')
+ ->willReturn(true);
+
+ $folder->method('get')
+ ->with($this->equalTo('file'))
+ ->willThrowException(new NotFoundException());
+
+ $res = $this->controller->getPreview('token', 'file', 10, 10, true);
+ $expected = new DataResponse([], Http::STATUS_NOT_FOUND);
+ $this->assertEquals($expected, $res);
+ }
+
+
+ public function testPreviewFolderValidFile(): void {
+ $share = $this->createMock(IShare::class);
+ $this->shareManager->method('getShareByToken')
+ ->with($this->equalTo('token'))
+ ->willReturn($share);
+
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ);
+
+ $folder = $this->createMock(Folder::class);
+ $share->method('getNode')
+ ->willReturn($folder);
+
+ $share->method('canSeeContent')
+ ->willReturn(true);
+
+ $file = $this->createMock(File::class);
+ $folder->method('get')
+ ->with($this->equalTo('file'))
+ ->willReturn($file);
+
+ $preview = $this->createMock(ISimpleFile::class);
+ $preview->method('getName')->willReturn('name');
+ $preview->method('getMTime')->willReturn(42);
+ $this->previewManager->method('getPreview')
+ ->with($this->equalTo($file), 10, 10, false)
+ ->willReturn($preview);
+
+ $preview->method('getMimeType')
+ ->willReturn('myMime');
+
+ $res = $this->controller->getPreview('token', 'file', 10, 10, true);
+ $expected = new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => 'myMime']);
+ $expected->cacheFor(3600 * 24);
+ $this->assertEquals($expected, $res);
+ }
+}
diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
new file mode 100644
index 00000000000..e6be0342c26
--- /dev/null
+++ b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
@@ -0,0 +1,5380 @@
+<?php
+
+/**
+ * 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\Controller;
+
+use OCA\Federation\TrustedServers;
+use OCA\Files_Sharing\Controller\ShareAPIController;
+use OCP\App\IAppManager;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCS\OCSBadRequestException;
+use OCP\AppFramework\OCS\OCSException;
+use OCP\AppFramework\OCS\OCSForbiddenException;
+use OCP\AppFramework\OCS\OCSNotFoundException;
+use OCP\Constants;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Mount\IMountPoint;
+use OCP\Files\Mount\IShareOwnerlessMount;
+use OCP\Files\NotFoundException;
+use OCP\Files\Storage\IStorage;
+use OCP\IAppConfig;
+use OCP\IConfig;
+use OCP\IDateTimeZone;
+use OCP\IGroup;
+use OCP\IGroupManager;
+use OCP\IL10N;
+use OCP\IPreview;
+use OCP\IRequest;
+use OCP\ITagManager;
+use OCP\ITags;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\Lock\ILockingProvider;
+use OCP\Lock\LockedException;
+use OCP\Mail\IMailer;
+use OCP\Server;
+use OCP\Share\Exceptions\GenericShareException;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\IAttributes as IShareAttributes;
+use OCP\Share\IManager;
+use OCP\Share\IProviderFactory;
+use OCP\Share\IShare;
+use OCP\UserStatus\IManager as IUserStatusManager;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Container\ContainerInterface;
+use Psr\Log\LoggerInterface;
+use Test\TestCase;
+
+/**
+ * Class ShareAPIControllerTest
+ *
+ * @package OCA\Files_Sharing\Tests\Controller
+ * @group DB
+ */
+class ShareAPIControllerTest extends TestCase {
+
+ private string $appName = 'files_sharing';
+ private string $currentUser;
+
+ private ShareAPIController $ocs;
+
+ private IManager&MockObject $shareManager;
+ private IGroupManager&MockObject $groupManager;
+ private IUserManager&MockObject $userManager;
+ private IRequest&MockObject $request;
+ private IRootFolder&MockObject $rootFolder;
+ private IURLGenerator&MockObject $urlGenerator;
+ private IL10N&MockObject $l;
+ private IConfig&MockObject $config;
+ private IAppConfig&MockObject $appConfig;
+ private IAppManager&MockObject $appManager;
+ private ContainerInterface&MockObject $serverContainer;
+ private IUserStatusManager&MockObject $userStatusManager;
+ private IPreview&MockObject $previewManager;
+ private IDateTimeZone&MockObject $dateTimeZone;
+ private LoggerInterface&MockObject $logger;
+ private IProviderFactory&MockObject $factory;
+ private IMailer&MockObject $mailer;
+ private ITagManager&MockObject $tagManager;
+ private TrustedServers&MockObject $trustedServers;
+
+ protected function setUp(): void {
+ $this->shareManager = $this->createMock(IManager::class);
+ $this->shareManager
+ ->expects($this->any())
+ ->method('shareApiEnabled')
+ ->willReturn(true);
+ $this->shareManager
+ ->expects($this->any())
+ ->method('shareProviderExists')->willReturn(true);
+ $this->groupManager = $this->createMock(IGroupManager::class);
+ $this->userManager = $this->createMock(IUserManager::class);
+ $this->request = $this->createMock(IRequest::class);
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->urlGenerator = $this->createMock(IURLGenerator::class);
+ $this->currentUser = 'currentUser';
+
+ $this->l = $this->createMock(IL10N::class);
+ $this->l->method('t')
+ ->willReturnCallback(function ($text, $parameters = []) {
+ return vsprintf($text, $parameters);
+ });
+ $this->config = $this->createMock(IConfig::class);
+ $this->appConfig = $this->createMock(IAppConfig::class);
+ $this->appManager = $this->createMock(IAppManager::class);
+ $this->serverContainer = $this->createMock(ContainerInterface::class);
+ $this->userStatusManager = $this->createMock(IUserStatusManager::class);
+ $this->previewManager = $this->createMock(IPreview::class);
+ $this->previewManager->method('isAvailable')
+ ->willReturnCallback(function ($fileInfo) {
+ return $fileInfo->getMimeType() === 'mimeWithPreview';
+ });
+ $this->dateTimeZone = $this->createMock(IDateTimeZone::class);
+ $this->logger = $this->createMock(LoggerInterface::class);
+ $this->factory = $this->createMock(IProviderFactory::class);
+ $this->mailer = $this->createMock(IMailer::class);
+ $this->tagManager = $this->createMock(ITagManager::class);
+ $this->trustedServers = $this->createMock(TrustedServers::class);
+
+ $this->ocs = new ShareAPIController(
+ $this->appName,
+ $this->request,
+ $this->shareManager,
+ $this->groupManager,
+ $this->userManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->l,
+ $this->config,
+ $this->appConfig,
+ $this->appManager,
+ $this->serverContainer,
+ $this->userStatusManager,
+ $this->previewManager,
+ $this->dateTimeZone,
+ $this->logger,
+ $this->factory,
+ $this->mailer,
+ $this->tagManager,
+ $this->trustedServers,
+ $this->currentUser
+ );
+
+ }
+
+ /**
+ * @return ShareAPIController&MockObject
+ */
+ private function mockFormatShare() {
+ return $this->getMockBuilder(ShareAPIController::class)
+ ->setConstructorArgs([
+ $this->appName,
+ $this->request,
+ $this->shareManager,
+ $this->groupManager,
+ $this->userManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->l,
+ $this->config,
+ $this->appConfig,
+ $this->appManager,
+ $this->serverContainer,
+ $this->userStatusManager,
+ $this->previewManager,
+ $this->dateTimeZone,
+ $this->logger,
+ $this->factory,
+ $this->mailer,
+ $this->tagManager,
+ $this->trustedServers,
+ $this->currentUser,
+ ])->onlyMethods(['formatShare'])
+ ->getMock();
+ }
+
+ private function newShare() {
+ return Server::get(IManager::class)->newShare();
+ }
+
+
+ private function mockShareAttributes() {
+ $formattedShareAttributes = [
+ [
+ 'scope' => 'permissions',
+ 'key' => 'download',
+ 'value' => true
+ ]
+ ];
+
+ $shareAttributes = $this->createMock(IShareAttributes::class);
+ $shareAttributes->method('toArray')->willReturn($formattedShareAttributes);
+ $shareAttributes->method('getAttribute')->with('permissions', 'download')->willReturn(true);
+
+ // send both IShare attributes class and expected json string
+ return [$shareAttributes, \json_encode($formattedShareAttributes)];
+ }
+
+ public function testDeleteShareShareNotFound(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Wrong share ID, share does not exist');
+
+ $this->shareManager
+ ->expects($this->exactly(7))
+ ->method('getShareById')
+ ->willReturnCallback(function ($id): void {
+ if ($id === 'ocinternal:42' || $id === 'ocRoomShare:42' || $id === 'ocFederatedSharing:42' || $id === 'ocCircleShare:42' || $id === 'ocMailShare:42' || $id === 'deck:42' || $id === 'sciencemesh:42') {
+ throw new ShareNotFound();
+ } else {
+ throw new \Exception();
+ }
+ });
+
+ $this->shareManager->method('outgoingServer2ServerSharesAllowed')->willReturn(true);
+
+ $this->ocs->deleteShare(42);
+ }
+
+ public function testDeleteShare(): void {
+ $node = $this->getMockBuilder(File::class)->getMock();
+
+ $share = $this->newShare();
+ $share->setSharedBy($this->currentUser)
+ ->setNode($node);
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42')
+ ->willReturn($share);
+ $this->shareManager
+ ->expects($this->once())
+ ->method('deleteShare')
+ ->with($share);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $expected = new DataResponse();
+ $result = $this->ocs->deleteShare(42);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+
+ public function testDeleteShareLocked(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Could not delete share');
+
+ $node = $this->getMockBuilder(File::class)->getMock();
+ $node->method('getId')->willReturn(1);
+
+ $share = $this->newShare();
+ $share->setNode($node);
+
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$node]);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42')
+ ->willReturn($share);
+
+ $this->shareManager
+ ->expects($this->never())
+ ->method('deleteShare')
+ ->with($share);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED)
+ ->willThrowException(new LockedException('mypath'));
+
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteFromSelf', [$share]));
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteShare', [$share]));
+
+ $this->ocs->deleteShare(42);
+ }
+
+ /**
+ * You can always remove a share that was shared with you
+ */
+ public function testDeleteShareWithMe(): void {
+ $node = $this->getMockBuilder(File::class)->getMock();
+
+ $share = $this->newShare();
+ $share->setSharedWith($this->currentUser)
+ ->setShareType(IShare::TYPE_USER)
+ ->setNode($node);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42')
+ ->willReturn($share);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('deleteShare')
+ ->with($share);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteFromSelf', [$share]));
+ $this->assertTrue($this->invokePrivate($this->ocs, 'canDeleteShare', [$share]));
+
+ $this->ocs->deleteShare(42);
+ }
+
+ /**
+ * You can always delete a share you own
+ */
+ public function testDeleteShareOwner(): void {
+ $node = $this->getMockBuilder(File::class)->getMock();
+
+ $share = $this->newShare();
+ $share->setSharedBy($this->currentUser)
+ ->setNode($node);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42')
+ ->willReturn($share);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('deleteShare')
+ ->with($share);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteFromSelf', [$share]));
+ $this->assertTrue($this->invokePrivate($this->ocs, 'canDeleteShare', [$share]));
+
+ $this->ocs->deleteShare(42);
+ }
+
+ /**
+ * You can always delete a share when you own
+ * the file path it belong to
+ */
+ public function testDeleteShareFileOwner(): void {
+ $node = $this->getMockBuilder(File::class)->getMock();
+ $node->method('getId')->willReturn(1);
+
+ $share = $this->newShare();
+ $share->setShareOwner($this->currentUser)
+ ->setNode($node);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42')
+ ->willReturn($share);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('deleteShare')
+ ->with($share);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteFromSelf', [$share]));
+ $this->assertTrue($this->invokePrivate($this->ocs, 'canDeleteShare', [$share]));
+
+ $this->ocs->deleteShare(42);
+ }
+
+ /**
+ * You can remove (the mountpoint, not the share)
+ * a share if you're in the group the share is shared with
+ */
+ public function testDeleteSharedWithMyGroup(): void {
+ $node = $this->getMockBuilder(File::class)->getMock();
+ $node->method('getId')->willReturn(1);
+
+ $share = $this->newShare();
+ $share->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('group')
+ ->setNode($node);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42')
+ ->willReturn($share);
+
+ // canDeleteShareFromSelf
+ $user = $this->createMock(IUser::class);
+ $group = $this->getMockBuilder(IGroup::class)->getMock();
+ $this->groupManager
+ ->method('get')
+ ->with('group')
+ ->willReturn($group);
+ $this->userManager
+ ->method('get')
+ ->with($this->currentUser)
+ ->willReturn($user);
+ $group->method('inGroup')
+ ->with($user)
+ ->willReturn(true);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$share->getNode()]);
+
+ $this->shareManager->expects($this->once())
+ ->method('deleteFromSelf')
+ ->with($share, $this->currentUser);
+
+ $this->shareManager->expects($this->never())
+ ->method('deleteShare');
+
+ $this->assertTrue($this->invokePrivate($this->ocs, 'canDeleteShareFromSelf', [$share]));
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteShare', [$share]));
+
+ $this->ocs->deleteShare(42);
+ }
+
+ /**
+ * You cannot remove a share if you're not
+ * in the group the share is shared with
+ */
+ public function testDeleteSharedWithGroupIDontBelongTo(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Wrong share ID, share does not exist');
+
+ $node = $this->getMockBuilder(File::class)->getMock();
+ $node->method('getId')->willReturn(42);
+
+ $share = $this->newShare();
+ $share->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('group')
+ ->setNode($node);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42')
+ ->willReturn($share);
+
+ // canDeleteShareFromSelf
+ $user = $this->createMock(IUser::class);
+ $group = $this->getMockBuilder(IGroup::class)->getMock();
+ $this->groupManager
+ ->method('get')
+ ->with('group')
+ ->willReturn($group);
+ $this->userManager
+ ->method('get')
+ ->with($this->currentUser)
+ ->willReturn($user);
+ $group->method('inGroup')
+ ->with($user)
+ ->willReturn(false);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$share->getNode()]);
+
+ $this->shareManager->expects($this->never())
+ ->method('deleteFromSelf');
+
+ $this->shareManager->expects($this->never())
+ ->method('deleteShare');
+
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteShareFromSelf', [$share]));
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteShare', [$share]));
+
+ $this->ocs->deleteShare(42);
+ }
+
+ public function testDeleteShareOwnerless(): void {
+ $ocs = $this->mockFormatShare();
+
+ $mount = $this->createMock(IShareOwnerlessMount::class);
+
+ $file = $this->createMock(File::class);
+ $file
+ ->expects($this->exactly(2))
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_SHARE);
+ $file
+ ->expects($this->once())
+ ->method('getMountPoint')
+ ->willReturn($mount);
+
+ $userFolder = $this->createMock(Folder::class);
+ $userFolder->method('getById')
+ ->with(2)
+ ->willReturn([$file]);
+ $userFolder->method('getFirstNodeById')
+ ->with(2)
+ ->willReturn($file);
+
+ $this->rootFolder
+ ->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $share = $this->createMock(IShare::class);
+ $share
+ ->expects($this->once())
+ ->method('getNode')
+ ->willReturn($file);
+ $share
+ ->expects($this->exactly(2))
+ ->method('getNodeId')
+ ->willReturn(2);
+ $share
+ ->expects($this->exactly(2))
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_SHARE);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:1', $this->currentUser)
+ ->willReturn($share);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('deleteShare')
+ ->with($share);
+
+ $result = $ocs->deleteShare(1);
+ $this->assertInstanceOf(DataResponse::class, $result);
+ }
+
+ /*
+ * FIXME: Enable once we have a federated Share Provider
+
+ public function testGetGetShareNotExists() {
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42', 'currentUser')
+ ->will($this->throwException(new \OC\Share20\Exception\ShareNotFound()));
+
+ $expected = new \OC\OCS\Result(null, 404, 'wrong share ID, share does not exist.');
+ $this->assertEquals($expected, $this->ocs->getShare(42));
+ }
+ */
+
+ public function createShare($id, $shareType, $sharedWith, $sharedBy, $shareOwner, $path, $permissions,
+ $shareTime, $expiration, $parent, $target, $mail_send, $note = '', $token = null,
+ $password = null, $label = '', $attributes = null) {
+ $share = $this->getMockBuilder(IShare::class)->getMock();
+ $share->method('getId')->willReturn($id);
+ $share->method('getShareType')->willReturn($shareType);
+ $share->method('getSharedWith')->willReturn($sharedWith);
+ $share->method('getSharedBy')->willReturn($sharedBy);
+ $share->method('getShareOwner')->willReturn($shareOwner);
+ $share->method('getNode')->willReturn($path);
+ $share->method('getPermissions')->willReturn($permissions);
+ $share->method('getNote')->willReturn($note);
+ $share->method('getLabel')->willReturn($label);
+ $share->method('getAttributes')->willReturn($attributes);
+ $time = new \DateTime();
+ $time->setTimestamp($shareTime);
+ $share->method('getShareTime')->willReturn($time);
+ $share->method('getExpirationDate')->willReturn($expiration);
+ $share->method('getTarget')->willReturn($target);
+ $share->method('getMailSend')->willReturn($mail_send);
+ $share->method('getToken')->willReturn($token);
+ $share->method('getPassword')->willReturn($password);
+
+ if ($shareType === IShare::TYPE_USER
+ || $shareType === IShare::TYPE_GROUP
+ || $shareType === IShare::TYPE_LINK) {
+ $share->method('getFullId')->willReturn('ocinternal:' . $id);
+ }
+
+ return $share;
+ }
+
+ public function dataGetShare() {
+ $data = [];
+
+ $cache = $this->getMockBuilder('OC\Files\Cache\Cache')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $cache->method('getNumericStorageId')->willReturn(101);
+
+ $storage = $this->getMockBuilder(IStorage::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $storage->method('getId')->willReturn('STORAGE');
+ $storage->method('getCache')->willReturn($cache);
+
+ $parentFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $parentFolder->method('getId')->willReturn(3);
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $mountPoint->method('getMountType')->willReturn('');
+
+ $file = $this->getMockBuilder('OCP\Files\File')->getMock();
+ $file->method('getId')->willReturn(1);
+ $file->method('getPath')->willReturn('file');
+ $file->method('getStorage')->willReturn($storage);
+ $file->method('getParent')->willReturn($parentFolder);
+ $file->method('getSize')->willReturn(123465);
+ $file->method('getMTime')->willReturn(1234567890);
+ $file->method('getMimeType')->willReturn('myMimeType');
+ $file->method('getMountPoint')->willReturn($mountPoint);
+
+ $folder = $this->getMockBuilder(Folder::class)->getMock();
+ $folder->method('getId')->willReturn(2);
+ $folder->method('getPath')->willReturn('folder');
+ $folder->method('getStorage')->willReturn($storage);
+ $folder->method('getParent')->willReturn($parentFolder);
+ $folder->method('getSize')->willReturn(123465);
+ $folder->method('getMTime')->willReturn(1234567890);
+ $folder->method('getMimeType')->willReturn('myFolderMimeType');
+ $folder->method('getMountPoint')->willReturn($mountPoint);
+
+ [$shareAttributes, $shareAttributesReturnJson] = $this->mockShareAttributes();
+
+ // File shared with user
+ $share = $this->createShare(
+ 100,
+ IShare::TYPE_USER,
+ 'userId',
+ 'initiatorId',
+ 'ownerId',
+ $file,
+ 4,
+ 5,
+ null,
+ 6,
+ 'target',
+ 0,
+ 'personal note',
+ $shareAttributes,
+ );
+ $expected = [
+ 'id' => 100,
+ 'share_type' => IShare::TYPE_USER,
+ 'share_with' => 'userId',
+ 'share_with_displayname' => 'userDisplay',
+ 'share_with_displayname_unique' => 'userId@example.com',
+ 'uid_owner' => 'initiatorId',
+ 'displayname_owner' => 'initiatorDisplay',
+ 'item_type' => 'file',
+ 'item_source' => 1,
+ 'file_source' => 1,
+ 'file_target' => 'target',
+ 'file_parent' => 3,
+ 'token' => null,
+ 'expiration' => null,
+ 'permissions' => 4,
+ 'attributes' => $shareAttributesReturnJson,
+ 'stime' => 5,
+ 'parent' => null,
+ 'storage_id' => 'STORAGE',
+ 'path' => 'file',
+ 'storage' => 101,
+ 'mail_send' => 0,
+ 'uid_file_owner' => 'ownerId',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'displayname_file_owner' => 'ownerDisplay',
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123465,
+ 'item_mtime' => 1234567890,
+ 'attributes' => null,
+ 'item_permissions' => 4,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ ];
+ $data[] = [$share, $expected];
+
+ // Folder shared with group
+ $share = $this->createShare(
+ 101,
+ IShare::TYPE_GROUP,
+ 'groupId',
+ 'initiatorId',
+ 'ownerId',
+ $folder,
+ 4,
+ 5,
+ null,
+ 6,
+ 'target',
+ 0,
+ 'personal note',
+ $shareAttributes,
+ );
+ $expected = [
+ 'id' => 101,
+ 'share_type' => IShare::TYPE_GROUP,
+ 'share_with' => 'groupId',
+ 'share_with_displayname' => 'groupId',
+ 'uid_owner' => 'initiatorId',
+ 'displayname_owner' => 'initiatorDisplay',
+ 'item_type' => 'folder',
+ 'item_source' => 2,
+ 'file_source' => 2,
+ 'file_target' => 'target',
+ 'file_parent' => 3,
+ 'token' => null,
+ 'expiration' => null,
+ 'permissions' => 4,
+ 'attributes' => $shareAttributesReturnJson,
+ 'stime' => 5,
+ 'parent' => null,
+ 'storage_id' => 'STORAGE',
+ 'path' => 'folder',
+ 'storage' => 101,
+ 'mail_send' => 0,
+ 'uid_file_owner' => 'ownerId',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'displayname_file_owner' => 'ownerDisplay',
+ 'mimetype' => 'myFolderMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123465,
+ 'item_mtime' => 1234567890,
+ 'attributes' => null,
+ 'item_permissions' => 4,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ ];
+ $data[] = [$share, $expected];
+
+ // File shared by link with Expire
+ $expire = \DateTime::createFromFormat('Y-m-d h:i:s', '2000-01-02 01:02:03');
+ $share = $this->createShare(
+ 101,
+ IShare::TYPE_LINK,
+ null,
+ 'initiatorId',
+ 'ownerId',
+ $folder,
+ 4,
+ 5,
+ $expire,
+ 6,
+ 'target',
+ 0,
+ 'personal note',
+ 'token',
+ 'password',
+ 'first link share'
+ );
+ $expected = [
+ 'id' => 101,
+ 'share_type' => IShare::TYPE_LINK,
+ 'password' => 'password',
+ 'share_with' => 'password',
+ 'share_with_displayname' => '(Shared link)',
+ 'send_password_by_talk' => false,
+ 'uid_owner' => 'initiatorId',
+ 'displayname_owner' => 'initiatorDisplay',
+ 'item_type' => 'folder',
+ 'item_source' => 2,
+ 'file_source' => 2,
+ 'file_target' => 'target',
+ 'file_parent' => 3,
+ 'token' => 'token',
+ 'expiration' => '2000-01-02 00:00:00',
+ 'permissions' => 4,
+ 'attributes' => null,
+ 'stime' => 5,
+ 'parent' => null,
+ 'storage_id' => 'STORAGE',
+ 'path' => 'folder',
+ 'storage' => 101,
+ 'mail_send' => 0,
+ 'url' => 'url',
+ 'uid_file_owner' => 'ownerId',
+ 'note' => 'personal note',
+ 'label' => 'first link share',
+ 'displayname_file_owner' => 'ownerDisplay',
+ 'mimetype' => 'myFolderMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123465,
+ 'item_mtime' => 1234567890,
+ 'attributes' => null,
+ 'item_permissions' => 4,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ ];
+ $data[] = [$share, $expected];
+
+ return $data;
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataGetShare')]
+ public function testGetShare(IShare $share, array $result): void {
+ /** @var ShareAPIController&MockObject $ocs */
+ $ocs = $this->getMockBuilder(ShareAPIController::class)
+ ->setConstructorArgs([
+ $this->appName,
+ $this->request,
+ $this->shareManager,
+ $this->groupManager,
+ $this->userManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->l,
+ $this->config,
+ $this->appConfig,
+ $this->appManager,
+ $this->serverContainer,
+ $this->userStatusManager,
+ $this->previewManager,
+ $this->dateTimeZone,
+ $this->logger,
+ $this->factory,
+ $this->mailer,
+ $this->tagManager,
+ $this->trustedServers,
+ $this->currentUser,
+ ])
+ ->onlyMethods(['canAccessShare'])
+ ->getMock();
+
+ $ocs->expects($this->any())
+ ->method('canAccessShare')
+ ->willReturn(true);
+
+ $this->shareManager
+ ->expects($this->any())
+ ->method('getShareById')
+ ->with($share->getFullId(), 'currentUser')
+ ->willReturn($share);
+
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $userFolder
+ ->method('getRelativePath')
+ ->willReturnArgument(0);
+
+ $userFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$share->getNode()]);
+ $userFolder->method('getFirstNodeById')
+ ->with($share->getNodeId())
+ ->willReturn($share->getNode());
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $this->urlGenerator
+ ->method('linkToRouteAbsolute')
+ ->willReturn('url');
+
+ $initiator = $this->getMockBuilder(IUser::class)->getMock();
+ $initiator->method('getUID')->willReturn('initiatorId');
+ $initiator->method('getDisplayName')->willReturn('initiatorDisplay');
+
+ $owner = $this->getMockBuilder(IUser::class)->getMock();
+ $owner->method('getUID')->willReturn('ownerId');
+ $owner->method('getDisplayName')->willReturn('ownerDisplay');
+
+ $user = $this->getMockBuilder(IUser::class)->getMock();
+ $user->method('getUID')->willReturn('userId');
+ $user->method('getDisplayName')->willReturn('userDisplay');
+ $user->method('getSystemEMailAddress')->willReturn('userId@example.com');
+
+ $group = $this->getMockBuilder(IGroup::class)->getMock();
+ $group->method('getGID')->willReturn('groupId');
+
+ $this->userManager->method('get')->willReturnMap([
+ ['userId', $user],
+ ['initiatorId', $initiator],
+ ['ownerId', $owner],
+ ]);
+ $this->groupManager->method('get')->willReturnMap([
+ ['group', $group],
+ ]);
+ $this->dateTimeZone->method('getTimezone')->willReturn(new \DateTimeZone('UTC'));
+
+ $data = $ocs->getShare($share->getId())->getData()[0];
+ $this->assertEquals($result, $data);
+ }
+
+
+ public function testGetShareInvalidNode(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Wrong share ID, share does not exist');
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setSharedBy('initiator')
+ ->setSharedWith('recipient')
+ ->setShareOwner('owner');
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:42', 'currentUser')
+ ->willReturn($share);
+
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $this->ocs->getShare(42);
+ }
+
+ public function dataGetShares() {
+ $folder = $this->getMockBuilder(Folder::class)->getMock();
+ $file1 = $this->getMockBuilder(File::class)->getMock();
+ $file1->method('getName')
+ ->willReturn('file1');
+ $file2 = $this->getMockBuilder(File::class)->getMock();
+ $file2->method('getName')
+ ->willReturn('file2');
+
+ $folder->method('getDirectoryListing')
+ ->willReturn([$file1, $file2]);
+
+ $file1UserShareOwner = Server::get(IManager::class)->newShare();
+ $file1UserShareOwner->setShareType(IShare::TYPE_USER)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(4);
+
+ $file1UserShareOwnerExpected = [
+ 'id' => 4,
+ 'share_type' => IShare::TYPE_USER,
+ ];
+
+ $file1UserShareInitiator = Server::get(IManager::class)->newShare();
+ $file1UserShareInitiator->setShareType(IShare::TYPE_USER)
+ ->setSharedWith('recipient')
+ ->setSharedBy('currentUser')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(8);
+
+ $file1UserShareInitiatorExpected = [
+ 'id' => 8,
+ 'share_type' => IShare::TYPE_USER,
+ ];
+
+ $file1UserShareRecipient = Server::get(IManager::class)->newShare();
+ $file1UserShareRecipient->setShareType(IShare::TYPE_USER)
+ ->setSharedWith('currentUser')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(15);
+
+ $file1UserShareRecipientExpected = [
+ 'id' => 15,
+ 'share_type' => IShare::TYPE_USER,
+ ];
+
+ $file1UserShareOther = Server::get(IManager::class)->newShare();
+ $file1UserShareOther->setShareType(IShare::TYPE_USER)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(16);
+
+ $file1UserShareOtherExpected = [
+ 'id' => 16,
+ 'share_type' => IShare::TYPE_USER,
+ ];
+
+ $file1GroupShareOwner = Server::get(IManager::class)->newShare();
+ $file1GroupShareOwner->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(23);
+
+ $file1GroupShareOwnerExpected = [
+ 'id' => 23,
+ 'share_type' => IShare::TYPE_GROUP,
+ ];
+
+ $file1GroupShareRecipient = Server::get(IManager::class)->newShare();
+ $file1GroupShareRecipient->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('currentUserGroup')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(42);
+
+ $file1GroupShareRecipientExpected = [
+ 'id' => 42,
+ 'share_type' => IShare::TYPE_GROUP,
+ ];
+
+ $file1GroupShareOther = Server::get(IManager::class)->newShare();
+ $file1GroupShareOther->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(108);
+
+ $file1LinkShareOwner = Server::get(IManager::class)->newShare();
+ $file1LinkShareOwner->setShareType(IShare::TYPE_LINK)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(415);
+
+ $file1LinkShareOwnerExpected = [
+ 'id' => 415,
+ 'share_type' => IShare::TYPE_LINK,
+ ];
+
+ $file1EmailShareOwner = Server::get(IManager::class)->newShare();
+ $file1EmailShareOwner->setShareType(IShare::TYPE_EMAIL)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(416);
+
+ $file1EmailShareOwnerExpected = [
+ 'id' => 416,
+ 'share_type' => IShare::TYPE_EMAIL,
+ ];
+
+ $file1CircleShareOwner = Server::get(IManager::class)->newShare();
+ $file1CircleShareOwner->setShareType(IShare::TYPE_CIRCLE)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(423);
+
+ $file1CircleShareOwnerExpected = [
+ 'id' => 423,
+ 'share_type' => IShare::TYPE_CIRCLE,
+ ];
+
+ $file1RoomShareOwner = Server::get(IManager::class)->newShare();
+ $file1RoomShareOwner->setShareType(IShare::TYPE_ROOM)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file1)
+ ->setId(442);
+
+ $file1RoomShareOwnerExpected = [
+ 'id' => 442,
+ 'share_type' => IShare::TYPE_ROOM,
+ ];
+
+ $file1RemoteShareOwner = Server::get(IManager::class)->newShare();
+ $file1RemoteShareOwner->setShareType(IShare::TYPE_REMOTE)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setExpirationDate(new \DateTime('2000-01-01T01:02:03'))
+ ->setNode($file1)
+ ->setId(815);
+
+ $file1RemoteShareOwnerExpected = [
+ 'id' => 815,
+ 'share_type' => IShare::TYPE_REMOTE,
+ ];
+
+ $file1RemoteGroupShareOwner = Server::get(IManager::class)->newShare();
+ $file1RemoteGroupShareOwner->setShareType(IShare::TYPE_REMOTE_GROUP)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setExpirationDate(new \DateTime('2000-01-02T01:02:03'))
+ ->setNode($file1)
+ ->setId(816);
+
+ $file1RemoteGroupShareOwnerExpected = [
+ 'id' => 816,
+ 'share_type' => IShare::TYPE_REMOTE_GROUP,
+ ];
+
+ $file2UserShareOwner = Server::get(IManager::class)->newShare();
+ $file2UserShareOwner->setShareType(IShare::TYPE_USER)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file2)
+ ->setId(823);
+
+ $file2UserShareOwnerExpected = [
+ 'id' => 823,
+ 'share_type' => IShare::TYPE_USER,
+ ];
+
+ $data = [
+ [
+ [
+ 'path' => $file1,
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner, $file1UserShareOwner, $file1UserShareOwner],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected
+ ]
+ ],
+ [
+ [
+ 'path' => $file1,
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner, $file1UserShareRecipient],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $file1,
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner, $file1UserShareRecipient, $file1UserShareInitiator, $file1UserShareOther],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ $file1UserShareInitiatorExpected,
+ $file1UserShareOtherExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $file1,
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareRecipient, $file1UserShareInitiator, $file1UserShareOther],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareInitiatorExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $file1,
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner],
+ IShare::TYPE_GROUP => [$file1GroupShareRecipient],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ $file1GroupShareRecipientExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $file1,
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner],
+ IShare::TYPE_GROUP => [$file1GroupShareOwner],
+ IShare::TYPE_LINK => [$file1LinkShareOwner],
+ IShare::TYPE_EMAIL => [$file1EmailShareOwner],
+ IShare::TYPE_CIRCLE => [$file1CircleShareOwner],
+ IShare::TYPE_ROOM => [$file1RoomShareOwner],
+ IShare::TYPE_REMOTE => [$file1RemoteShareOwner],
+ IShare::TYPE_REMOTE_GROUP => [$file1RemoteGroupShareOwner],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ $file1GroupShareOwnerExpected,
+ $file1LinkShareOwnerExpected,
+ $file1EmailShareOwnerExpected,
+ $file1CircleShareOwnerExpected,
+ $file1RoomShareOwnerExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $file1,
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner],
+ IShare::TYPE_GROUP => [$file1GroupShareOwner],
+ IShare::TYPE_LINK => [$file1LinkShareOwner],
+ IShare::TYPE_EMAIL => [$file1EmailShareOwner],
+ IShare::TYPE_CIRCLE => [$file1CircleShareOwner],
+ IShare::TYPE_ROOM => [$file1RoomShareOwner],
+ IShare::TYPE_REMOTE => [$file1RemoteShareOwner],
+ IShare::TYPE_REMOTE_GROUP => [$file1RemoteGroupShareOwner],
+ ],
+ ],
+ [
+ IShare::TYPE_REMOTE => true,
+ IShare::TYPE_REMOTE_GROUP => true,
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ $file1GroupShareOwnerExpected,
+ $file1LinkShareOwnerExpected,
+ $file1EmailShareOwnerExpected,
+ $file1CircleShareOwnerExpected,
+ $file1RoomShareOwnerExpected,
+ $file1RemoteShareOwnerExpected,
+ $file1RemoteGroupShareOwnerExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $folder,
+ 'subfiles' => 'true',
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner],
+ ],
+ 'file2' => [
+ IShare::TYPE_USER => [$file2UserShareOwner],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ $file2UserShareOwnerExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $folder,
+ 'subfiles' => 'true',
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner, $file1UserShareOwner, $file1UserShareOwner],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $folder,
+ 'subfiles' => 'true',
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner, $file1UserShareRecipient],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected
+ ]
+ ],
+ [
+ [
+ 'path' => $folder,
+ 'subfiles' => 'true',
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareRecipient, $file1UserShareInitiator, $file1UserShareOther],
+ ],
+ 'file2' => [
+ IShare::TYPE_USER => [$file2UserShareOwner],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareInitiatorExpected,
+ $file1UserShareOtherExpected,
+ $file2UserShareOwnerExpected,
+ ]
+ ],
+ // This might not happen in a real environment, as the combination
+ // of shares does not seem to be possible on a folder without
+ // resharing rights; if the folder has resharing rights then the
+ // share with others would be included too in the results.
+ [
+ [
+ 'path' => $folder,
+ 'subfiles' => 'true',
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareRecipient, $file1UserShareInitiator, $file1UserShareOther],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareInitiatorExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $folder,
+ 'subfiles' => 'true',
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner],
+ IShare::TYPE_GROUP => [$file1GroupShareRecipient],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ $file1GroupShareRecipientExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $folder,
+ 'subfiles' => 'true',
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner],
+ IShare::TYPE_GROUP => [$file1GroupShareOwner],
+ IShare::TYPE_LINK => [$file1LinkShareOwner],
+ IShare::TYPE_EMAIL => [$file1EmailShareOwner],
+ IShare::TYPE_CIRCLE => [$file1CircleShareOwner],
+ IShare::TYPE_ROOM => [$file1RoomShareOwner],
+ IShare::TYPE_REMOTE => [$file1RemoteShareOwner],
+ IShare::TYPE_REMOTE_GROUP => [$file1RemoteGroupShareOwner],
+ ],
+ ],
+ [
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ $file1GroupShareOwnerExpected,
+ $file1LinkShareOwnerExpected,
+ $file1EmailShareOwnerExpected,
+ $file1CircleShareOwnerExpected,
+ $file1RoomShareOwnerExpected,
+ ]
+ ],
+ [
+ [
+ 'path' => $folder,
+ 'subfiles' => 'true',
+ ],
+ [
+ 'file1' => [
+ IShare::TYPE_USER => [$file1UserShareOwner],
+ IShare::TYPE_GROUP => [$file1GroupShareOwner],
+ IShare::TYPE_LINK => [$file1LinkShareOwner],
+ IShare::TYPE_EMAIL => [$file1EmailShareOwner],
+ IShare::TYPE_CIRCLE => [$file1CircleShareOwner],
+ IShare::TYPE_ROOM => [$file1RoomShareOwner],
+ IShare::TYPE_REMOTE => [$file1RemoteShareOwner],
+ IShare::TYPE_REMOTE_GROUP => [$file1RemoteGroupShareOwner],
+ ],
+ ],
+ [
+ IShare::TYPE_REMOTE => true,
+ IShare::TYPE_REMOTE_GROUP => true,
+ ],
+ [
+ $file1UserShareOwnerExpected,
+ $file1GroupShareOwnerExpected,
+ $file1LinkShareOwnerExpected,
+ $file1EmailShareOwnerExpected,
+ $file1CircleShareOwnerExpected,
+ $file1RoomShareOwnerExpected,
+ $file1RemoteShareOwnerExpected,
+ $file1RemoteGroupShareOwnerExpected,
+ ]
+ ],
+ ];
+
+ return $data;
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataGetShares')]
+ public function testGetShares(array $getSharesParameters, array $shares, array $extraShareTypes, array $expected): void {
+ /** @var ShareAPIController&MockObject $ocs */
+ $ocs = $this->getMockBuilder(ShareAPIController::class)
+ ->setConstructorArgs([
+ $this->appName,
+ $this->request,
+ $this->shareManager,
+ $this->groupManager,
+ $this->userManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->l,
+ $this->config,
+ $this->appConfig,
+ $this->appManager,
+ $this->serverContainer,
+ $this->userStatusManager,
+ $this->previewManager,
+ $this->dateTimeZone,
+ $this->logger,
+ $this->factory,
+ $this->mailer,
+ $this->tagManager,
+ $this->trustedServers,
+ $this->currentUser,
+ ])
+ ->onlyMethods(['formatShare'])
+ ->getMock();
+
+ $ocs->method('formatShare')
+ ->willReturnCallback(
+ function ($share) {
+ return [
+ 'id' => $share->getId(),
+ 'share_type' => $share->getShareType()
+ ];
+ }
+ );
+
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $userFolder->method('get')
+ ->with('path')
+ ->willReturn($getSharesParameters['path']);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $this->shareManager
+ ->method('getSharesBy')
+ ->willReturnCallback(
+ function ($user, $shareType, $node) use ($shares) {
+ if (!isset($shares[$node->getName()]) || !isset($shares[$node->getName()][$shareType])) {
+ return [];
+ }
+ return $shares[$node->getName()][$shareType];
+ }
+ );
+
+ $this->shareManager
+ ->method('outgoingServer2ServerSharesAllowed')
+ ->willReturn($extraShareTypes[ISHARE::TYPE_REMOTE] ?? false);
+
+ $this->shareManager
+ ->method('outgoingServer2ServerGroupSharesAllowed')
+ ->willReturn($extraShareTypes[ISHARE::TYPE_REMOTE_GROUP] ?? false);
+
+ $this->groupManager
+ ->method('isInGroup')
+ ->willReturnCallback(
+ function ($user, $group) {
+ return $group === 'currentUserGroup';
+ }
+ );
+
+ $result = $ocs->getShares(
+ $getSharesParameters['sharedWithMe'] ?? 'false',
+ $getSharesParameters['reshares'] ?? 'false',
+ $getSharesParameters['subfiles'] ?? 'false',
+ 'path'
+ );
+
+ $this->assertEquals($expected, $result->getData());
+ }
+
+ public function testCanAccessShareAsOwner(): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getShareOwner')->willReturn($this->currentUser);
+ $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+ }
+
+ public function testCanAccessShareAsSharer(): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getSharedBy')->willReturn($this->currentUser);
+ $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+ }
+
+ public function testCanAccessShareAsSharee(): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getShareType')->willReturn(IShare::TYPE_USER);
+ $share->method('getSharedWith')->willReturn($this->currentUser);
+ $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+ }
+
+ public function testCannotAccessLinkShare(): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getShareType')->willReturn(IShare::TYPE_LINK);
+ $share->method('getNodeId')->willReturn(42);
+
+ $userFolder = $this->createMock(Folder::class);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataCanAccessShareWithPermissions')]
+ public function testCanAccessShareWithPermissions(int $permissions, bool $expected): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getShareType')->willReturn(IShare::TYPE_USER);
+ $share->method('getSharedWith')->willReturn($this->createMock(IUser::class));
+ $share->method('getNodeId')->willReturn(42);
+
+ $file = $this->createMock(File::class);
+
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $userFolder->method('getFirstNodeById')
+ ->with($share->getNodeId())
+ ->willReturn($file);
+ $userFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$file]);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $file->method('getPermissions')
+ ->willReturn($permissions);
+
+ if ($expected) {
+ $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+ } else {
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+ }
+ }
+
+ public static function dataCanAccessShareWithPermissions(): array {
+ return [
+ [Constants::PERMISSION_SHARE, true],
+ [Constants::PERMISSION_READ, false],
+ [Constants::PERMISSION_READ | Constants::PERMISSION_SHARE, true],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataCanAccessShareAsGroupMember')]
+ public function testCanAccessShareAsGroupMember(string $group, bool $expected): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getShareType')->willReturn(IShare::TYPE_GROUP);
+ $share->method('getSharedWith')->willReturn($group);
+ $share->method('getNodeId')->willReturn(42);
+
+ $file = $this->createMock(File::class);
+
+ $userFolder = $this->createMock(Folder::class);
+ $userFolder->method('getFirstNodeById')
+ ->with($share->getNodeId())
+ ->willReturn($file);
+ $userFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$file]);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $user = $this->createMock(IUser::class);
+ $this->userManager->method('get')
+ ->with($this->currentUser)
+ ->willReturn($user);
+
+ $group = $this->createMock(IGroup::class);
+ $group->method('inGroup')->with($user)->willReturn(true);
+ $group2 = $this->createMock(IGroup::class);
+ $group2->method('inGroup')->with($user)->willReturn(false);
+
+ $this->groupManager->method('get')->willReturnMap([
+ ['group', $group],
+ ['group2', $group2],
+ ['group-null', null],
+ ]);
+
+ if ($expected) {
+ $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+ } else {
+ $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+ }
+ }
+
+ public static function dataCanAccessShareAsGroupMember(): array {
+ return [
+ ['group', true],
+ ['group2', false],
+ ['group-null', false],
+ ];
+ }
+
+ public function dataCanAccessRoomShare() {
+ $result = [];
+
+ $share = $this->createMock(IShare::class);
+ $share->method('getShareType')->willReturn(IShare::TYPE_ROOM);
+ $share->method('getSharedWith')->willReturn('recipientRoom');
+
+ $result[] = [
+ false, $share, false, false
+ ];
+
+ $result[] = [
+ false, $share, false, true
+ ];
+
+ $result[] = [
+ true, $share, true, true
+ ];
+
+ $result[] = [
+ false, $share, true, false
+ ];
+
+ return $result;
+ }
+
+ /**
+ *
+ * @param bool $expects
+ * @param IShare $share
+ * @param bool helperAvailable
+ * @param bool canAccessShareByHelper
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataCanAccessRoomShare')]
+ public function testCanAccessRoomShare(bool $expected, IShare $share, bool $helperAvailable, bool $canAccessShareByHelper): void {
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$share->getNode()]);
+
+ if (!$helperAvailable) {
+ $this->appManager->method('isEnabledForUser')
+ ->with('spreed')
+ ->willReturn(false);
+ } else {
+ $this->appManager->method('isEnabledForUser')
+ ->with('spreed')
+ ->willReturn(true);
+
+ // This is not possible anymore with PHPUnit 10+
+ // as `setMethods` was removed and now real reflection is used, thus the class needs to exist.
+ // $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController')
+ $helper = $this->getMockBuilder(\stdClass::class)
+ ->addMethods(['canAccessShare'])
+ ->getMock();
+ $helper->method('canAccessShare')
+ ->with($share, $this->currentUser)
+ ->willReturn($canAccessShareByHelper);
+
+ $this->serverContainer->method('get')
+ ->with('\OCA\Talk\Share\Helper\ShareAPIController')
+ ->willReturn($helper);
+ }
+
+ $this->assertEquals($expected, $this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
+ }
+
+
+ public function testCreateShareNoPath(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Please specify a file or folder path');
+
+ $this->ocs->createShare();
+ }
+
+
+ public function testCreateShareInvalidPath(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Wrong path, file/folder does not exist');
+
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $this->rootFolder->expects($this->once())
+ ->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('invalid-path')
+ ->willThrowException(new NotFoundException());
+
+ $this->ocs->createShare('invalid-path');
+ }
+
+ public function testCreateShareInvalidShareType(): void {
+ $this->expectException(OCSBadRequestException::class);
+ $this->expectExceptionMessage('Unknown share type');
+
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ [$userFolder, $file] = $this->getNonSharedUserFile();
+ $this->rootFolder->expects($this->atLeastOnce())
+ ->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->atLeastOnce())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($file);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $file->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->ocs->createShare('valid-path', 31);
+ }
+
+ public function testCreateShareUserNoShareWith(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Please specify a valid account to share with');
+
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ [$userFolder, $path] = $this->getNonSharedUserFile();
+ $this->rootFolder->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_USER);
+ }
+
+
+ public function testCreateShareUserNoValidShareWith(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Please specify a valid account to share with');
+
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ [$userFolder, $path] = $this->getNonSharedUserFile();
+ $this->rootFolder->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+ $this->userManager->method('userExists')
+ ->with('invalidUser')
+ ->willReturn(false);
+
+ $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_USER, 'invalidUser');
+ }
+
+ public function testCreateShareUser(): void {
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ /** @var ShareAPIController $ocs */
+ $ocs = $this->getMockBuilder(ShareAPIController::class)
+ ->setConstructorArgs([
+ $this->appName,
+ $this->request,
+ $this->shareManager,
+ $this->groupManager,
+ $this->userManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->l,
+ $this->config,
+ $this->appConfig,
+ $this->appManager,
+ $this->serverContainer,
+ $this->userStatusManager,
+ $this->previewManager,
+ $this->dateTimeZone,
+ $this->logger,
+ $this->factory,
+ $this->mailer,
+ $this->tagManager,
+ $this->trustedServers,
+ $this->currentUser,
+ ])->onlyMethods(['formatShare'])
+ ->getMock();
+
+ [$userFolder, $path] = $this->getNonSharedUserFile();
+ $this->rootFolder->expects($this->exactly(2))
+ ->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $this->userManager->method('userExists')->with('validUser')->willReturn(true);
+
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('createShare')
+ ->with($this->callback(function (IShare $share) use ($path) {
+ return $share->getNode() === $path
+ && $share->getPermissions() === (
+ Constants::PERMISSION_ALL
+ & ~Constants::PERMISSION_DELETE
+ & ~Constants::PERMISSION_CREATE
+ )
+ && $share->getShareType() === IShare::TYPE_USER
+ && $share->getSharedWith() === 'validUser'
+ && $share->getSharedBy() === 'currentUser';
+ }))
+ ->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_USER, 'validUser');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+
+ public function testCreateShareGroupNoValidShareWith(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Please specify a valid group');
+
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+ $this->shareManager->method('createShare')->willReturnArgument(0);
+ $this->shareManager->method('allowGroupSharing')->willReturn(true);
+
+ [$userFolder, $path] = $this->getNonSharedUserFile();
+ $this->rootFolder->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_GROUP, 'invalidGroup');
+ }
+
+ public function testCreateShareGroup(): void {
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ /** @var ShareAPIController&MockObject $ocs */
+ $ocs = $this->getMockBuilder(ShareAPIController::class)
+ ->setConstructorArgs([
+ $this->appName,
+ $this->request,
+ $this->shareManager,
+ $this->groupManager,
+ $this->userManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->l,
+ $this->config,
+ $this->appConfig,
+ $this->appManager,
+ $this->serverContainer,
+ $this->userStatusManager,
+ $this->previewManager,
+ $this->dateTimeZone,
+ $this->logger,
+ $this->factory,
+ $this->mailer,
+ $this->tagManager,
+ $this->trustedServers,
+ $this->currentUser,
+ ])->onlyMethods(['formatShare'])
+ ->getMock();
+
+ $this->request
+ ->method('getParam')
+ ->willReturnMap([
+ ['path', null, 'valid-path'],
+ ['permissions', null, Constants::PERMISSION_ALL],
+ ['shareType', '-1', IShare::TYPE_GROUP],
+ ['shareWith', null, 'validGroup'],
+ ]);
+
+ [$userFolder, $path] = $this->getNonSharedUserFolder();
+ $this->rootFolder->expects($this->exactly(2))
+ ->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
+
+ $this->shareManager->expects($this->once())
+ ->method('allowGroupSharing')
+ ->willReturn(true);
+
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('createShare')
+ ->with($this->callback(function (IShare $share) use ($path) {
+ return $share->getNode() === $path
+ && $share->getPermissions() === Constants::PERMISSION_ALL
+ && $share->getShareType() === IShare::TYPE_GROUP
+ && $share->getSharedWith() === 'validGroup'
+ && $share->getSharedBy() === 'currentUser';
+ }))
+ ->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_GROUP, 'validGroup');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+
+ public function testCreateShareGroupNotAllowed(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Group sharing is disabled by the administrator');
+
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ [$userFolder, $path] = $this->getNonSharedUserFolder();
+ $this->rootFolder->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
+
+ $this->shareManager->expects($this->once())
+ ->method('allowGroupSharing')
+ ->willReturn(false);
+
+ $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_GROUP, 'invalidGroup');
+ }
+
+
+ public function testCreateShareLinkNoLinksAllowed(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Public link sharing is disabled by the administrator');
+
+ $this->request
+ ->method('getParam')
+ ->willReturnMap([
+ ['path', null, 'valid-path'],
+ ['shareType', '-1', IShare::TYPE_LINK],
+ ]);
+
+ $path = $this->getMockBuilder(Folder::class)->getMock();
+ $path->method('getId')->willReturn(42);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $path->method('getStorage')->willReturn($storage);
+ $this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
+ $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+ $this->rootFolder->method('getById')
+ ->willReturn([]);
+
+ $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare());
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+ $this->shareManager->method('shareApiAllowLinks')->willReturn(false);
+
+ $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK);
+ }
+
+
+ public function testCreateShareLinkNoPublicUpload(): void {
+ $this->expectException(OCSForbiddenException::class);
+ $this->expectExceptionMessage('Public upload disabled by the administrator');
+
+ $path = $this->getMockBuilder(Folder::class)->getMock();
+ $path->method('getId')->willReturn(42);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $path->method('getStorage')->willReturn($storage);
+ $this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
+ $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+ $this->rootFolder->method('getById')
+ ->willReturn([]);
+
+ $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare());
+ $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+
+ $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true');
+ }
+
+
+ public function testCreateShareLinkPublicUploadFile(): void {
+ $this->expectException(OCSBadRequestException::class);
+ $this->expectExceptionMessage('Public upload is only possible for publicly shared folders');
+
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+
+ $file = $this->createMock(File::class);
+ $file->method('getId')->willReturn(42);
+ $file->method('getStorage')->willReturn($storage);
+
+ $this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
+ $this->rootFolder->method('get')->with('valid-path')->willReturn($file);
+ $this->rootFolder->method('getById')
+ ->willReturn([]);
+
+ $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare());
+ $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true');
+ }
+
+ public function testCreateShareLinkPublicUploadFolder(): void {
+ $ocs = $this->mockFormatShare();
+
+ $path = $this->getMockBuilder(Folder::class)->getMock();
+ $path->method('getId')->willReturn(1);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $path->method('getStorage')->willReturn($storage);
+ $this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
+ $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+ $this->rootFolder->method('getById')
+ ->willReturn([]);
+
+ $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare());
+ $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('createShare')->with(
+ $this->callback(function (IShare $share) use ($path) {
+ return $share->getNode() === $path
+ && $share->getShareType() === IShare::TYPE_LINK
+ && $share->getPermissions() === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
+ && $share->getSharedBy() === 'currentUser'
+ && $share->getPassword() === null
+ && $share->getExpirationDate() === null;
+ })
+ )->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true', '', null, '');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testCreateShareLinkPassword(): void {
+ $ocs = $this->mockFormatShare();
+
+ $path = $this->getMockBuilder(Folder::class)->getMock();
+ $path->method('getId')->willReturn(42);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $path->method('getStorage')->willReturn($storage);
+ $this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
+ $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+ $this->rootFolder->method('getById')
+ ->willReturn([]);
+
+ $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare());
+ $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('createShare')->with(
+ $this->callback(function (IShare $share) use ($path) {
+ return $share->getNode() === $path
+ && $share->getShareType() === IShare::TYPE_LINK
+ && $share->getPermissions() === Constants::PERMISSION_READ // publicUpload was set to false
+ && $share->getSharedBy() === 'currentUser'
+ && $share->getPassword() === 'password'
+ && $share->getExpirationDate() === null;
+ })
+ )->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->createShare('valid-path', Constants::PERMISSION_READ, IShare::TYPE_LINK, null, 'false', 'password', null, '');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testCreateShareLinkSendPasswordByTalk(): void {
+ $ocs = $this->mockFormatShare();
+
+ $path = $this->getMockBuilder(Folder::class)->getMock();
+ $path->method('getId')->willReturn(42);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $path->method('getStorage')->willReturn($storage);
+ $this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
+ $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+ $this->rootFolder->method('getById')
+ ->willReturn([]);
+
+ $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare());
+ $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->appManager->method('isEnabledForUser')->with('spreed')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('createShare')->with(
+ $this->callback(function (IShare $share) use ($path) {
+ return $share->getNode() === $path
+ && $share->getShareType() === IShare::TYPE_LINK
+ && $share->getPermissions() === (Constants::PERMISSION_ALL & ~(Constants::PERMISSION_SHARE))
+ && $share->getSharedBy() === 'currentUser'
+ && $share->getPassword() === 'password'
+ && $share->getSendPasswordByTalk() === true
+ && $share->getExpirationDate() === null;
+ })
+ )->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true', 'password', 'true', '');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+
+ public function testCreateShareLinkSendPasswordByTalkWithTalkDisabled(): void {
+ $this->expectException(OCSForbiddenException::class);
+ $this->expectExceptionMessage('Sharing valid-path sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled');
+
+ $ocs = $this->mockFormatShare();
+
+ $path = $this->getMockBuilder(Folder::class)->getMock();
+ $path->method('getId')->willReturn(42);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $path->method('getStorage')->willReturn($storage);
+ $path->method('getPath')->willReturn('valid-path');
+ $this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
+ $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+ $this->rootFolder->method('getById')
+ ->willReturn([]);
+
+ $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare());
+ $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->appManager->method('isEnabledForUser')->with('spreed')->willReturn(false);
+
+ $this->shareManager->expects($this->never())->method('createShare');
+
+ $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', 'password', 'true', '');
+ }
+
+ public function testCreateShareValidExpireDate(): void {
+ $ocs = $this->mockFormatShare();
+
+ $this->request
+ ->method('getParam')
+ ->willReturnMap([
+ ['path', null, 'valid-path'],
+ ['shareType', '-1', IShare::TYPE_LINK],
+ ['publicUpload', null, 'false'],
+ ['expireDate', '', '2000-01-01'],
+ ['password', '', ''],
+ ]);
+
+ $path = $this->getMockBuilder(Folder::class)->getMock();
+ $path->method('getId')->willReturn(42);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $path->method('getStorage')->willReturn($storage);
+ $this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
+ $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+ $this->rootFolder->method('getById')
+ ->willReturn([]);
+
+ $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare());
+ $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('createShare')->with(
+ $this->callback(function (IShare $share) use ($path) {
+ $date = new \DateTime('2000-01-01');
+ $date->setTime(0, 0, 0);
+
+ return $share->getNode() === $path
+ && $share->getShareType() === IShare::TYPE_LINK
+ && $share->getPermissions() === Constants::PERMISSION_READ | Constants::PERMISSION_SHARE
+ && $share->getSharedBy() === 'currentUser'
+ && $share->getPassword() === null
+ && $share->getExpirationDate() == $date;
+ })
+ )->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->createShare('valid-path', null, IShare::TYPE_LINK, null, 'false', '', null, '2000-01-01');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+
+ public function testCreateShareInvalidExpireDate(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Invalid date. Format must be YYYY-MM-DD');
+
+ $ocs = $this->mockFormatShare();
+
+ $path = $this->getMockBuilder(Folder::class)->getMock();
+ $path->method('getId')->willReturn(42);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $path->method('getStorage')->willReturn($storage);
+ $this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
+ $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
+ $this->rootFolder->method('getById')
+ ->willReturn([]);
+
+ $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare());
+ $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, 'a1b2d3');
+ }
+
+ public function testCreateShareRemote(): void {
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ /** @var ShareAPIController $ocs */
+ $ocs = $this->getMockBuilder(ShareAPIController::class)
+ ->setConstructorArgs([
+ $this->appName,
+ $this->request,
+ $this->shareManager,
+ $this->groupManager,
+ $this->userManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->l,
+ $this->config,
+ $this->appConfig,
+ $this->appManager,
+ $this->serverContainer,
+ $this->userStatusManager,
+ $this->previewManager,
+ $this->dateTimeZone,
+ $this->logger,
+ $this->factory,
+ $this->mailer,
+ $this->tagManager,
+ $this->trustedServers,
+ $this->currentUser,
+ ])->onlyMethods(['formatShare'])
+ ->getMock();
+
+ [$userFolder, $path] = $this->getNonSharedUserFile();
+ $this->rootFolder->expects($this->exactly(2))
+ ->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $this->userManager->method('userExists')->with('validUser')->willReturn(true);
+
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('createShare')
+ ->with($this->callback(function (IShare $share) use ($path) {
+ return $share->getNode() === $path
+ && $share->getPermissions() === (
+ Constants::PERMISSION_ALL
+ & ~Constants::PERMISSION_DELETE
+ & ~Constants::PERMISSION_CREATE
+ )
+ && $share->getShareType() === IShare::TYPE_REMOTE
+ && $share->getSharedWith() === 'user@example.org'
+ && $share->getSharedBy() === 'currentUser';
+ }))
+ ->willReturnArgument(0);
+
+ $this->shareManager->method('outgoingServer2ServerSharesAllowed')->willReturn(true);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_REMOTE, 'user@example.org');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testCreateShareRemoteGroup(): void {
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ /** @var ShareAPIController $ocs */
+ $ocs = $this->getMockBuilder(ShareAPIController::class)
+ ->setConstructorArgs([
+ $this->appName,
+ $this->request,
+ $this->shareManager,
+ $this->groupManager,
+ $this->userManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->l,
+ $this->config,
+ $this->appConfig,
+ $this->appManager,
+ $this->serverContainer,
+ $this->userStatusManager,
+ $this->previewManager,
+ $this->dateTimeZone,
+ $this->logger,
+ $this->factory,
+ $this->mailer,
+ $this->tagManager,
+ $this->trustedServers,
+ $this->currentUser,
+ ])->onlyMethods(['formatShare'])
+ ->getMock();
+
+ [$userFolder, $path] = $this->getNonSharedUserFile();
+ $this->rootFolder->expects($this->exactly(2))
+ ->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $this->userManager->method('userExists')->with('validUser')->willReturn(true);
+
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('createShare')
+ ->with($this->callback(function (IShare $share) use ($path) {
+ return $share->getNode() === $path
+ && $share->getPermissions() === (
+ Constants::PERMISSION_ALL
+ & ~Constants::PERMISSION_DELETE
+ & ~Constants::PERMISSION_CREATE
+ )
+ && $share->getShareType() === IShare::TYPE_REMOTE_GROUP
+ && $share->getSharedWith() === 'group@example.org'
+ && $share->getSharedBy() === 'currentUser';
+ }))
+ ->willReturnArgument(0);
+
+ $this->shareManager->method('outgoingServer2ServerGroupSharesAllowed')->willReturn(true);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_REMOTE_GROUP, 'group@example.org');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testCreateShareRoom(): void {
+ $ocs = $this->mockFormatShare();
+
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ [$userFolder, $path] = $this->getNonSharedUserFile();
+ $this->rootFolder->expects($this->exactly(2))
+ ->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->appManager->method('isEnabledForUser')
+ ->with('spreed')
+ ->willReturn(true);
+
+ // This is not possible anymore with PHPUnit 10+
+ // as `setMethods` was removed and now real reflection is used, thus the class needs to exist.
+ // $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController')
+ $helper = $this->getMockBuilder(\stdClass::class)
+ ->addMethods(['createShare'])
+ ->getMock();
+ $helper->method('createShare')
+ ->with(
+ $share,
+ 'recipientRoom',
+ Constants::PERMISSION_ALL
+ & ~Constants::PERMISSION_DELETE
+ & ~Constants::PERMISSION_CREATE,
+ ''
+ )->willReturnCallback(
+ function ($share): void {
+ $share->setSharedWith('recipientRoom');
+ $share->setPermissions(Constants::PERMISSION_ALL);
+ }
+ );
+
+ $this->serverContainer->method('get')
+ ->with('\OCA\Talk\Share\Helper\ShareAPIController')
+ ->willReturn($helper);
+
+ $this->shareManager->method('createShare')
+ ->with($this->callback(function (IShare $share) use ($path) {
+ return $share->getNode() === $path
+ && $share->getPermissions() === Constants::PERMISSION_ALL
+ && $share->getShareType() === IShare::TYPE_ROOM
+ && $share->getSharedWith() === 'recipientRoom'
+ && $share->getSharedBy() === 'currentUser';
+ }))
+ ->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_ROOM, 'recipientRoom');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+
+ public function testCreateShareRoomHelperNotAvailable(): void {
+ $this->expectException(OCSForbiddenException::class);
+ $this->expectExceptionMessage('Sharing valid-path failed because the back end does not support room shares');
+
+ $ocs = $this->mockFormatShare();
+
+ $share = $this->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ [$userFolder, $path] = $this->getNonSharedUserFolder();
+ $this->rootFolder->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $path->method('getPath')->willReturn('valid-path');
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->appManager->method('isEnabledForUser')
+ ->with('spreed')
+ ->willReturn(false);
+
+ $this->shareManager->expects($this->never())->method('createShare');
+
+ $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_ROOM, 'recipientRoom');
+ }
+
+
+ public function testCreateShareRoomHelperThrowException(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Exception thrown by the helper');
+
+ $ocs = $this->mockFormatShare();
+
+ $share = $this->newShare();
+ $share->setSharedBy('currentUser');
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ [$userFolder, $path] = $this->getNonSharedUserFile();
+ $this->rootFolder->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $path->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->appManager->method('isEnabledForUser')
+ ->with('spreed')
+ ->willReturn(true);
+
+ // This is not possible anymore with PHPUnit 10+
+ // as `setMethods` was removed and now real reflection is used, thus the class needs to exist.
+ // $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController')
+ $helper = $this->getMockBuilder(\stdClass::class)
+ ->addMethods(['createShare'])
+ ->getMock();
+ $helper->method('createShare')
+ ->with(
+ $share,
+ 'recipientRoom',
+ Constants::PERMISSION_ALL & ~(Constants::PERMISSION_CREATE | Constants::PERMISSION_DELETE),
+ ''
+ )->willReturnCallback(
+ function ($share): void {
+ throw new OCSNotFoundException('Exception thrown by the helper');
+ }
+ );
+
+ $this->serverContainer->method('get')
+ ->with('\OCA\Talk\Share\Helper\ShareAPIController')
+ ->willReturn($helper);
+
+ $this->shareManager->expects($this->never())->method('createShare');
+
+ $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_ROOM, 'recipientRoom');
+ }
+
+ /**
+ * Test for https://github.com/owncloud/core/issues/22587
+ * TODO: Remove once proper solution is in place
+ */
+ public function testCreateReshareOfFederatedMountNoDeletePermissions(): void {
+ $share = Server::get(IManager::class)->newShare();
+ $this->shareManager->method('newShare')->willReturn($share);
+
+ /** @var ShareAPIController&MockObject $ocs */
+ $ocs = $this->getMockBuilder(ShareAPIController::class)
+ ->setConstructorArgs([
+ $this->appName,
+ $this->request,
+ $this->shareManager,
+ $this->groupManager,
+ $this->userManager,
+ $this->rootFolder,
+ $this->urlGenerator,
+ $this->l,
+ $this->config,
+ $this->appConfig,
+ $this->appManager,
+ $this->serverContainer,
+ $this->userStatusManager,
+ $this->previewManager,
+ $this->dateTimeZone,
+ $this->logger,
+ $this->factory,
+ $this->mailer,
+ $this->tagManager,
+ $this->trustedServers,
+ $this->currentUser,
+ ])->onlyMethods(['formatShare'])
+ ->getMock();
+
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $this->rootFolder->expects($this->exactly(2))
+ ->method('getUserFolder')
+ ->with('currentUser')
+ ->willReturn($userFolder);
+
+ $path = $this->getMockBuilder(Folder::class)->getMock();
+ $path->method('getId')->willReturn(42);
+
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', true],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $userFolder->method('getStorage')->willReturn($storage);
+ $path->method('getStorage')->willReturn($storage);
+
+ $path->method('getPermissions')->willReturn(Constants::PERMISSION_READ);
+ $userFolder->expects($this->once())
+ ->method('get')
+ ->with('valid-path')
+ ->willReturn($path);
+ $userFolder->method('getById')
+ ->willReturn([]);
+
+ $this->userManager->method('userExists')->with('validUser')->willReturn(true);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('createShare')
+ ->with($this->callback(function (IShare $share) {
+ return $share->getPermissions() === Constants::PERMISSION_READ;
+ }))
+ ->willReturnArgument(0);
+
+ $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_USER, 'validUser');
+ }
+
+
+ public function testUpdateShareCantAccess(): void {
+ $this->expectException(OCSNotFoundException::class);
+ $this->expectExceptionMessage('Wrong share ID, share does not exist');
+
+ [$userFolder, $node] = $this->getNonSharedUserFolder();
+ $share = $this->newShare();
+ $share->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with($share->getNodeId())
+ ->willReturn([$share->getNode()]);
+
+ $this->ocs->updateShare(42);
+ }
+
+
+ public function testUpdateNoParametersLink(): void {
+ $this->expectException(OCSBadRequestException::class);
+ $this->expectExceptionMessage('Wrong or no update parameter given');
+
+ $node = $this->getMockBuilder(Folder::class)->getMock();
+ $share = $this->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->ocs->updateShare(42);
+ }
+
+
+ public function testUpdateNoParametersOther(): void {
+ $this->expectException(OCSBadRequestException::class);
+ $this->expectExceptionMessage('Wrong or no update parameter given');
+
+ $node = $this->getMockBuilder(Folder::class)->getMock();
+ $share = $this->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_GROUP)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->ocs->updateShare(42);
+ }
+
+ public function testUpdateLinkShareClear(): void {
+ $ocs = $this->mockFormatShare();
+
+ [$userFolder, $node] = $this->getNonSharedUserFolder();
+ $node->method('getId')
+ ->willReturn(42);
+ $share = $this->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setExpirationDate(new \DateTime())
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_ALL)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) {
+ return $share->getPermissions() === Constants::PERMISSION_READ
+ && $share->getPassword() === null
+ && $share->getExpirationDate() === null
+ // Once set a note or a label are never back to null, only to an
+ // empty string.
+ && $share->getNote() === ''
+ && $share->getLabel() === ''
+ && $share->getHideDownload() === false;
+ })
+ )->willReturnArgument(0);
+
+ $this->shareManager->method('getSharedWith')
+ ->willReturn([]);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$node]);
+ $userFolder->method('getFirstNodeById')
+ ->with(42)
+ ->willReturn($node);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $node->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, null, '', null, 'false', '', '', '', 'false');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testUpdateLinkShareSet(): void {
+ $ocs = $this->mockFormatShare();
+
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $folder->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setNode($folder);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) {
+ $date = new \DateTime('2000-01-01');
+ $date->setTime(0, 0, 0);
+
+ return $share->getPermissions() === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
+ && $share->getPassword() === 'password'
+ && $share->getExpirationDate() == $date
+ && $share->getNote() === 'note'
+ && $share->getLabel() === 'label'
+ && $share->getHideDownload() === true;
+ })
+ )->willReturnArgument(0);
+
+ $this->shareManager->method('getSharedWith')
+ ->willReturn([]);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $folder->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, null, 'password', null, 'true', '2000-01-01', 'note', 'label', 'true');
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('publicUploadParamsProvider')]
+ public function testUpdateLinkShareEnablePublicUpload($permissions, $publicUpload, $expireDate, $password): void {
+ $ocs = $this->mockFormatShare();
+
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $folder->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setNode($folder);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+ $this->shareManager->method('getSharedWith')->willReturn([]);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) {
+ return $share->getPermissions() === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
+ && $share->getPassword() === 'password'
+ && $share->getExpirationDate() === null;
+ })
+ )->willReturnArgument(0);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $folder->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, $permissions, $password, null, $publicUpload, $expireDate);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+
+ public static function publicLinkValidPermissionsProvider() {
+ return [
+ [Constants::PERMISSION_CREATE],
+ [Constants::PERMISSION_READ],
+ [Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE],
+ [Constants::PERMISSION_READ | Constants::PERMISSION_DELETE],
+ [Constants::PERMISSION_READ | Constants::PERMISSION_CREATE],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('publicLinkValidPermissionsProvider')]
+ public function testUpdateLinkShareSetCRUDPermissions($permissions): void {
+ $ocs = $this->mockFormatShare();
+
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $folder->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setNode($folder);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+ $this->shareManager->method('getSharedWith')->willReturn([]);
+
+ $this->shareManager
+ ->expects($this->any())
+ ->method('updateShare')
+ ->willReturnArgument(0);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $folder->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, $permissions, 'password', null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public static function publicLinkInvalidPermissionsProvider1() {
+ return [
+ [Constants::PERMISSION_DELETE],
+ [Constants::PERMISSION_UPDATE],
+ [Constants::PERMISSION_SHARE],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('publicLinkInvalidPermissionsProvider1')]
+ public function testUpdateLinkShareSetInvalidCRUDPermissions1($permissions): void {
+ $this->expectException(OCSBadRequestException::class);
+ $this->expectExceptionMessage('Share must at least have READ or CREATE permissions');
+
+ $this->testUpdateLinkShareSetCRUDPermissions($permissions, null);
+ }
+
+ public static function publicLinkInvalidPermissionsProvider2() {
+ return [
+ [Constants::PERMISSION_CREATE | Constants::PERMISSION_DELETE],
+ [Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('publicLinkInvalidPermissionsProvider2')]
+ public function testUpdateLinkShareSetInvalidCRUDPermissions2($permissions): void {
+ $this->expectException(OCSBadRequestException::class);
+ $this->expectExceptionMessage('Share must have READ permission if UPDATE or DELETE permission is set');
+
+ $this->testUpdateLinkShareSetCRUDPermissions($permissions);
+ }
+
+ public function testUpdateLinkShareInvalidDate(): void {
+ $this->expectException(OCSBadRequestException::class);
+ $this->expectExceptionMessage('Invalid date. Format must be YYYY-MM-DD');
+
+ $ocs = $this->mockFormatShare();
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $folder->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setNode($folder);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $ocs->updateShare(42, null, 'password', null, 'true', '2000-01-a');
+ }
+
+ public static function publicUploadParamsProvider() {
+ return [
+ [null, 'true', null, 'password'],
+ // legacy had no delete
+ [
+ Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE,
+ 'true', null, 'password'
+ ],
+ // correct
+ [
+ Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE,
+ null, null, 'password'
+ ],
+ ];
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('publicUploadParamsProvider')]
+ public function testUpdateLinkSharePublicUploadNotAllowed($permissions, $publicUpload, $expireDate, $password): void {
+ $this->expectException(OCSForbiddenException::class);
+ $this->expectExceptionMessage('Public upload disabled by the administrator');
+
+ $ocs = $this->mockFormatShare();
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $folder->method('getId')->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setNode($folder);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false);
+
+ $ocs->updateShare(42, $permissions, $password, null, $publicUpload, $expireDate);
+ }
+
+
+ public function testUpdateLinkSharePublicUploadOnFile(): void {
+ $this->expectException(OCSBadRequestException::class);
+ $this->expectExceptionMessage('Public upload is only possible for publicly shared folders');
+
+ $ocs = $this->mockFormatShare();
+
+ $file = $this->getMockBuilder(File::class)->getMock();
+ $file->method('getId')
+ ->willReturn(42);
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setNode($file);
+
+ $this->shareManager
+ ->method('getShareById')
+ ->with('ocinternal:42')
+ ->willReturn($share);
+ $this->shareManager
+ ->method('shareApiLinkAllowPublicUpload')
+ ->willReturn(true);
+ $this->shareManager
+ ->method('updateShare')
+ ->with($share)
+ ->willThrowException(new \InvalidArgumentException('File shares cannot have create or delete permissions'));
+
+ $ocs->updateShare(42, null, 'password', null, 'true', '');
+ }
+
+ public function testUpdateLinkSharePasswordDoesNotChangeOther(): void {
+ $ocs = $this->mockFormatShare();
+
+ $date = new \DateTime('2000-01-01');
+ $date->setTime(0, 0, 0);
+
+ [$userFolder, $node] = $this->getNonSharedUserFolder();
+ $node->method('getId')->willReturn(42);
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$node]);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+ $share = $this->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(true)
+ ->setExpirationDate($date)
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_ALL)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) use ($date) {
+ return $share->getPermissions() === Constants::PERMISSION_ALL
+ && $share->getPassword() === 'newpassword'
+ && $share->getSendPasswordByTalk() === true
+ && $share->getExpirationDate() === $date
+ && $share->getNote() === 'note'
+ && $share->getLabel() === 'label'
+ && $share->getHideDownload() === true;
+ })
+ )->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, null, 'newpassword', null, null, null, null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testUpdateLinkShareSendPasswordByTalkDoesNotChangeOther(): void {
+ $ocs = $this->mockFormatShare();
+
+ $date = new \DateTime('2000-01-01');
+ $date->setTime(0, 0, 0);
+
+ [$userFolder, $node] = $this->getNonSharedUserFolder();
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$node]);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+ $node->method('getId')->willReturn(42);
+ $share = $this->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(false)
+ ->setExpirationDate($date)
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_ALL)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->appManager->method('isEnabledForUser')->with('spreed')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) use ($date) {
+ return $share->getPermissions() === Constants::PERMISSION_ALL
+ && $share->getPassword() === 'password'
+ && $share->getSendPasswordByTalk() === true
+ && $share->getExpirationDate() === $date
+ && $share->getNote() === 'note'
+ && $share->getLabel() === 'label'
+ && $share->getHideDownload() === true;
+ })
+ )->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, null, null, 'true', null, null, null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+
+ public function testUpdateLinkShareSendPasswordByTalkWithTalkDisabledDoesNotChangeOther(): void {
+ $this->expectException(OCSForbiddenException::class);
+ $this->expectExceptionMessage('"Sending the password by Nextcloud Talk" for sharing a file or folder failed because Nextcloud Talk is not enabled.');
+
+ $ocs = $this->mockFormatShare();
+
+ $date = new \DateTime('2000-01-01');
+ $date->setTime(0, 0, 0);
+
+ [$userFolder, $node] = $this->getNonSharedUserFolder();
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$node]);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+ $node->method('getId')->willReturn(42);
+ $share = $this->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(false)
+ ->setExpirationDate($date)
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_ALL)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->appManager->method('isEnabledForUser')->with('spreed')->willReturn(false);
+
+ $this->shareManager->expects($this->never())->method('updateShare');
+
+ $ocs->updateShare(42, null, null, 'true', null, null, null, null, null);
+ }
+
+ public function testUpdateLinkShareDoNotSendPasswordByTalkDoesNotChangeOther(): void {
+ $ocs = $this->mockFormatShare();
+
+ $date = new \DateTime('2000-01-01');
+ $date->setTime(0, 0, 0);
+
+ [$userFolder, $node] = $this->getNonSharedUserFolder();
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$node]);
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+ $node->method('getId')->willReturn(42);
+ $share = $this->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(true)
+ ->setExpirationDate($date)
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_ALL)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->appManager->method('isEnabledForUser')->with('spreed')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) use ($date) {
+ return $share->getPermissions() === Constants::PERMISSION_ALL
+ && $share->getPassword() === 'password'
+ && $share->getSendPasswordByTalk() === false
+ && $share->getExpirationDate() === $date
+ && $share->getNote() === 'note'
+ && $share->getLabel() === 'label'
+ && $share->getHideDownload() === true;
+ })
+ )->willReturnArgument(0);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, null, null, 'false', null, null, null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testUpdateLinkShareDoNotSendPasswordByTalkWithTalkDisabledDoesNotChangeOther(): void {
+ $ocs = $this->mockFormatShare();
+
+ $date = new \DateTime('2000-01-01');
+ $date->setTime(0, 0, 0);
+
+ [$userFolder, $node] = $this->getNonSharedUserFolder();
+ $node->method('getId')
+ ->willReturn(42);
+
+ $share = $this->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(true)
+ ->setExpirationDate($date)
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_ALL)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->appManager->method('isEnabledForUser')->with('spreed')->willReturn(false);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) use ($date) {
+ return $share->getPermissions() === Constants::PERMISSION_ALL
+ && $share->getPassword() === 'password'
+ && $share->getSendPasswordByTalk() === false
+ && $share->getExpirationDate() === $date
+ && $share->getNote() === 'note'
+ && $share->getLabel() === 'label'
+ && $share->getHideDownload() === true;
+ })
+ )->willReturnArgument(0);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$node]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $node->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $node->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, null, null, 'false', null, null, null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testUpdateLinkShareExpireDateDoesNotChangeOther(): void {
+ $ocs = $this->mockFormatShare();
+
+ [$userFolder, $node] = $this->getNonSharedUserFolder();
+ $node->method('getId')
+ ->willReturn(42);
+
+ $share = $this->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(true)
+ ->setExpirationDate(new \DateTime())
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_ALL)
+ ->setNode($node);
+
+ $node->expects($this->once())
+ ->method('lock')
+ ->with(ILockingProvider::LOCK_SHARED);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) {
+ $date = new \DateTime('2010-12-23');
+ $date->setTime(0, 0, 0);
+
+ return $share->getPermissions() === Constants::PERMISSION_ALL
+ && $share->getPassword() === 'password'
+ && $share->getSendPasswordByTalk() === true
+ && $share->getExpirationDate() == $date
+ && $share->getNote() === 'note'
+ && $share->getLabel() === 'label'
+ && $share->getHideDownload() === true;
+ })
+ )->willReturnArgument(0);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$node]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $node->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, null, null, null, null, '2010-12-23', null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testUpdateLinkSharePublicUploadDoesNotChangeOther(): void {
+ $ocs = $this->mockFormatShare();
+
+ $date = new \DateTime('2000-01-01');
+
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $folder->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(true)
+ ->setExpirationDate($date)
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_ALL)
+ ->setNode($folder);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) use ($date) {
+ return $share->getPermissions() === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
+ && $share->getPassword() === 'password'
+ && $share->getSendPasswordByTalk() === true
+ && $share->getExpirationDate() === $date
+ && $share->getNote() === 'note'
+ && $share->getLabel() === 'label'
+ && $share->getHideDownload() === true;
+ })
+ )->willReturnArgument(0);
+
+ $this->shareManager->method('getSharedWith')
+ ->willReturn([]);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $folder->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, null, null, null, 'true', null, null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testUpdateLinkSharePermissions(): void {
+ $ocs = $this->mockFormatShare();
+
+ $date = new \DateTime('2000-01-01');
+
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $folder->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(true)
+ ->setExpirationDate($date)
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_ALL)
+ ->setNode($folder);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) use ($date): bool {
+ return $share->getPermissions() === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
+ && $share->getPassword() === 'password'
+ && $share->getSendPasswordByTalk() === true
+ && $share->getExpirationDate() === $date
+ && $share->getNote() === 'note'
+ && $share->getLabel() === 'label'
+ && $share->getHideDownload() === true;
+ })
+ )->willReturnArgument(0);
+
+ $this->shareManager->method('getSharedWith')->willReturn([]);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $folder->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, 7, null, null, 'true', null, null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testUpdateLinkSharePermissionsShare(): void {
+ $ocs = $this->mockFormatShare();
+
+ $date = new \DateTime('2000-01-01');
+
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $folder->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(true)
+ ->setExpirationDate($date)
+ ->setNote('note')
+ ->setLabel('label')
+ ->setHideDownload(true)
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->shareManager->expects($this->once())
+ ->method('updateShare')
+ ->with(
+ $this->callback(function (IShare $share) use ($date) {
+ return $share->getPermissions() === Constants::PERMISSION_ALL
+ && $share->getPassword() === 'password'
+ && $share->getSendPasswordByTalk() === true
+ && $share->getExpirationDate() === $date
+ && $share->getNote() === 'note'
+ && $share->getLabel() === 'label'
+ && $share->getHideDownload() === true;
+ })
+ )->willReturnArgument(0);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $folder->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $this->shareManager->method('getSharedWith')->willReturn([]);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, Constants::PERMISSION_ALL, null, null, null, null, null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testUpdateOtherPermissions(): void {
+ $ocs = $this->mockFormatShare();
+
+ [$userFolder, $file] = $this->getNonSharedUserFolder();
+ $file->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setPermissions(Constants::PERMISSION_ALL)
+ ->setSharedBy($this->currentUser)
+ ->setShareType(IShare::TYPE_USER)
+ ->setNode($file);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+ $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
+
+ $this->shareManager->expects($this->once())->method('updateShare')->with(
+ $this->callback(function (IShare $share) {
+ return $share->getPermissions() === Constants::PERMISSION_ALL;
+ })
+ )->willReturnArgument(0);
+
+ $this->shareManager->method('getSharedWith')->willReturn([]);
+
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$file]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $file->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $expected = new DataResponse([]);
+ $result = $ocs->updateShare(42, 31, null, null, null, null);
+
+ $this->assertInstanceOf(get_class($expected), $result);
+ $this->assertEquals($expected->getData(), $result->getData());
+ }
+
+ public function testUpdateShareCannotIncreasePermissions(): void {
+ $ocs = $this->mockFormatShare();
+
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $folder->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share
+ ->setId(42)
+ ->setSharedBy($this->currentUser)
+ ->setShareOwner('anotheruser')
+ ->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('group1')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder);
+
+ // note: updateShare will modify the received instance but getSharedWith will reread from the database,
+ // so their values will be different
+ $incomingShare = Server::get(IManager::class)->newShare();
+ $incomingShare
+ ->setId(42)
+ ->setSharedBy($this->currentUser)
+ ->setShareOwner('anotheruser')
+ ->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('group1')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder);
+
+ $this->request
+ ->method('getParam')
+ ->willReturnMap([
+ ['permissions', null, '31'],
+ ]);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->shareManager->expects($this->any())
+ ->method('getSharedWith')
+ ->willReturnMap([
+ ['currentUser', IShare::TYPE_USER, $share->getNode(), -1, 0, []],
+ ['currentUser', IShare::TYPE_GROUP, $share->getNode(), -1, 0, [$incomingShare]],
+ ['currentUser', IShare::TYPE_ROOM, $share->getNode(), -1, 0, []]
+ ]);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+ $userFolder->method('getFirstNodeById')
+ ->with(42)
+ ->willReturn($folder);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $folder->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $this->shareManager->expects($this->once())
+ ->method('updateShare')
+ ->with($share)
+ ->willThrowException(new GenericShareException('Cannot increase permissions of path/file', 'Cannot increase permissions of path/file', 404));
+
+ try {
+ $ocs->updateShare(42, 31);
+ $this->fail();
+ } catch (OCSException $e) {
+ $this->assertEquals('Cannot increase permissions of path/file', $e->getMessage());
+ }
+ }
+
+ public function testUpdateShareCanIncreasePermissionsIfOwner(): void {
+ $ocs = $this->mockFormatShare();
+
+ [$userFolder, $folder] = $this->getNonSharedUserFolder();
+ $folder->method('getId')
+ ->willReturn(42);
+
+ $share = Server::get(IManager::class)->newShare();
+ $share
+ ->setId(42)
+ ->setSharedBy($this->currentUser)
+ ->setShareOwner($this->currentUser)
+ ->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('group1')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder);
+
+ // note: updateShare will modify the received instance but getSharedWith will reread from the database,
+ // so their values will be different
+ $incomingShare = Server::get(IManager::class)->newShare();
+ $incomingShare
+ ->setId(42)
+ ->setSharedBy($this->currentUser)
+ ->setShareOwner($this->currentUser)
+ ->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('group1')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder);
+
+ $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
+
+ $this->shareManager->expects($this->any())
+ ->method('getSharedWith')
+ ->willReturnMap([
+ ['currentUser', IShare::TYPE_USER, $share->getNode(), -1, 0, []],
+ ['currentUser', IShare::TYPE_GROUP, $share->getNode(), -1, 0, [$incomingShare]]
+ ]);
+
+ $this->shareManager->expects($this->once())
+ ->method('updateShare')
+ ->with($share)
+ ->willReturn($share);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getById')
+ ->with(42)
+ ->willReturn([$folder]);
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $folder->method('getMountPoint')
+ ->willReturn($mountPoint);
+ $mountPoint->method('getStorageRootId')
+ ->willReturn(42);
+
+ $result = $ocs->updateShare(42, 31);
+ $this->assertInstanceOf(DataResponse::class, $result);
+ }
+
+ public function testUpdateShareOwnerless(): void {
+ $ocs = $this->mockFormatShare();
+
+ $mount = $this->createMock(IShareOwnerlessMount::class);
+
+ $file = $this->createMock(File::class);
+ $file
+ ->expects($this->exactly(2))
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_SHARE);
+ $file
+ ->expects($this->once())
+ ->method('getMountPoint')
+ ->willReturn($mount);
+
+ $userFolder = $this->createMock(Folder::class);
+ $userFolder->method('getById')
+ ->with(2)
+ ->willReturn([$file]);
+ $userFolder->method('getFirstNodeById')
+ ->with(2)
+ ->willReturn($file);
+
+ $this->rootFolder
+ ->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $share = $this->createMock(IShare::class);
+ $share
+ ->expects($this->once())
+ ->method('getNode')
+ ->willReturn($file);
+ $share
+ ->expects($this->exactly(2))
+ ->method('getNodeId')
+ ->willReturn(2);
+ $share
+ ->expects($this->exactly(2))
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_SHARE);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:1', $this->currentUser)
+ ->willReturn($share);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('updateShare')
+ ->with($share)
+ ->willReturn($share);
+
+ $result = $ocs->updateShare(1, Constants::PERMISSION_ALL);
+ $this->assertInstanceOf(DataResponse::class, $result);
+ }
+
+ public function dataFormatShare() {
+ $file = $this->getMockBuilder(File::class)->getMock();
+ $folder = $this->getMockBuilder(Folder::class)->getMock();
+ $parent = $this->getMockBuilder(Folder::class)->getMock();
+ $fileWithPreview = $this->getMockBuilder(File::class)->getMock();
+
+ $file->method('getMimeType')->willReturn('myMimeType');
+ $folder->method('getMimeType')->willReturn('myFolderMimeType');
+ $fileWithPreview->method('getMimeType')->willReturn('mimeWithPreview');
+
+ $mountPoint = $this->createMock(IMountPoint::class);
+ $mountPoint->method('getMountType')->willReturn('');
+ $file->method('getMountPoint')->willReturn($mountPoint);
+ $folder->method('getMountPoint')->willReturn($mountPoint);
+ $fileWithPreview->method('getMountPoint')->willReturn($mountPoint);
+
+ $file->method('getPath')->willReturn('file');
+ $folder->method('getPath')->willReturn('folder');
+ $fileWithPreview->method('getPath')->willReturn('fileWithPreview');
+
+ $parent->method('getId')->willReturn(1);
+ $folder->method('getId')->willReturn(2);
+ $file->method('getId')->willReturn(3);
+ $fileWithPreview->method('getId')->willReturn(4);
+
+ $file->method('getParent')->willReturn($parent);
+ $folder->method('getParent')->willReturn($parent);
+ $fileWithPreview->method('getParent')->willReturn($parent);
+
+ $file->method('getSize')->willReturn(123456);
+ $folder->method('getSize')->willReturn(123456);
+ $fileWithPreview->method('getSize')->willReturn(123456);
+ $file->method('getMTime')->willReturn(1234567890);
+ $folder->method('getMTime')->willReturn(1234567890);
+ $fileWithPreview->method('getMTime')->willReturn(1234567890);
+
+ $cache = $this->getMockBuilder('OCP\Files\Cache\ICache')->getMock();
+ $cache->method('getNumericStorageId')->willReturn(100);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('getId')->willReturn('storageId');
+ $storage->method('getCache')->willReturn($cache);
+
+ $file->method('getStorage')->willReturn($storage);
+ $folder->method('getStorage')->willReturn($storage);
+ $fileWithPreview->method('getStorage')->willReturn($storage);
+
+
+ $mountPoint = $this->getMockBuilder(IMountPoint::class)->getMock();
+ $mountPoint->method('getMountType')->willReturn('');
+ $file->method('getMountPoint')->willReturn($mountPoint);
+ $folder->method('getMountPoint')->willReturn($mountPoint);
+
+ $owner = $this->getMockBuilder(IUser::class)->getMock();
+ $owner->method('getDisplayName')->willReturn('ownerDN');
+ $initiator = $this->getMockBuilder(IUser::class)->getMock();
+ $initiator->method('getDisplayName')->willReturn('initiatorDN');
+ $recipient = $this->getMockBuilder(IUser::class)->getMock();
+ $recipient->method('getDisplayName')->willReturn('recipientDN');
+ $recipient->method('getSystemEMailAddress')->willReturn('recipient');
+ [$shareAttributes, $shareAttributesReturnJson] = $this->mockShareAttributes();
+
+ $result = [];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_USER)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setAttributes($shareAttributes)
+ ->setNode($file)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+
+ // User backend down
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_USER,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'attributes' => $shareAttributesReturnJson,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'recipient',
+ 'share_with_displayname' => 'recipient',
+ 'share_with_displayname_unique' => 'recipient',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'mail_send' => 0,
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => '[{"scope":"permissions","key":"download","value":true}]',
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+ // User backend up
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_USER,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiatorDN',
+ 'permissions' => 1,
+ 'attributes' => $shareAttributesReturnJson,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'ownerDN',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'recipient',
+ 'share_with_displayname' => 'recipientDN',
+ 'share_with_displayname_unique' => 'recipient',
+ 'mail_send' => 0,
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => '[{"scope":"permissions","key":"download","value":true}]',
+ 'item_permissions' => 1,
+ ], $share, [
+ ['owner', $owner],
+ ['initiator', $initiator],
+ ['recipient', $recipient],
+ ], false
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_USER)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+ // User backend down
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_USER,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'attributes' => null,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'recipient',
+ 'share_with_displayname' => 'recipient',
+ 'share_with_displayname_unique' => 'recipient',
+ 'mail_send' => 0,
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_USER)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+ // User backend down
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_USER,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'attributes' => null,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'currentUser',
+ 'displayname_file_owner' => 'currentUser',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'recipient',
+ 'share_with_displayname' => 'recipient',
+ 'share_with_displayname_unique' => 'recipient',
+ 'mail_send' => 0,
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => true,
+ 'can_delete' => true,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 11,
+ ], $share, [], false
+ ];
+
+ // with existing group
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('recipientGroup')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_GROUP,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'attributes' => null,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'recipientGroup',
+ 'share_with_displayname' => 'recipientGroupDisplayName',
+ 'mail_send' => 0,
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ // with unknown group / no group backend
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_GROUP)
+ ->setSharedWith('recipientGroup2')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_GROUP,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'recipientGroup2',
+ 'share_with_displayname' => 'recipientGroup2',
+ 'mail_send' => 0,
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_LINK)
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setPassword('mypassword')
+ ->setExpirationDate(new \DateTime('2001-01-02T00:00:00'))
+ ->setToken('myToken')
+ ->setNote('personal note')
+ ->setLabel('new link share')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_LINK,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'attributes' => null,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => '2001-01-02 00:00:00',
+ 'token' => 'myToken',
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => 'personal note',
+ 'label' => 'new link share',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'password' => 'mypassword',
+ 'share_with' => 'mypassword',
+ 'share_with_displayname' => '(Shared link)',
+ 'send_password_by_talk' => false,
+ 'mail_send' => 0,
+ 'url' => 'myLink',
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_LINK)
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setPassword('mypassword')
+ ->setSendPasswordByTalk(true)
+ ->setExpirationDate(new \DateTime('2001-01-02T00:00:00'))
+ ->setToken('myToken')
+ ->setNote('personal note')
+ ->setLabel('new link share')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_LINK,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => '2001-01-02 00:00:00',
+ 'token' => 'myToken',
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => 'personal note',
+ 'label' => 'new link share',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'password' => 'mypassword',
+ 'share_with' => 'mypassword',
+ 'share_with_displayname' => '(Shared link)',
+ 'send_password_by_talk' => true,
+ 'mail_send' => 0,
+ 'url' => 'myLink',
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_REMOTE)
+ ->setSharedBy('initiator')
+ ->setSharedWith('user@server.com')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setExpirationDate(new \DateTime('2001-02-03T04:05:06'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_REMOTE,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => '2001-02-03 00:00:00',
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'path' => 'folder',
+ 'item_type' => 'folder',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 2,
+ 'file_source' => 2,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'user@server.com',
+ 'share_with_displayname' => 'foobar',
+ 'mail_send' => 0,
+ 'mimetype' => 'myFolderMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ 'is_trusted_server' => false,
+ ], $share, [], false
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_REMOTE_GROUP)
+ ->setSharedBy('initiator')
+ ->setSharedWith('user@server.com')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setExpirationDate(new \DateTime('2001-02-03T04:05:06'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_REMOTE_GROUP,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => '2001-02-03 00:00:00',
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'path' => 'folder',
+ 'item_type' => 'folder',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 2,
+ 'file_source' => 2,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'user@server.com',
+ 'share_with_displayname' => 'foobar',
+ 'mail_send' => 0,
+ 'mimetype' => 'myFolderMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ 'is_trusted_server' => false,
+ ], $share, [], false
+ ];
+
+ // Circle with id, display name and avatar set by the Circles app
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_CIRCLE)
+ ->setSharedBy('initiator')
+ ->setSharedWith('Circle (Public circle, circleOwner) [4815162342]')
+ ->setSharedWithDisplayName('The display name')
+ ->setSharedWithAvatar('path/to/the/avatar')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_CIRCLE,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'attributes' => null,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => '',
+ 'label' => '',
+ 'path' => 'folder',
+ 'item_type' => 'folder',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 2,
+ 'file_source' => 2,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => '4815162342',
+ 'share_with_displayname' => 'The display name',
+ 'share_with_avatar' => 'path/to/the/avatar',
+ 'mail_send' => 0,
+ 'mimetype' => 'myFolderMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ // Circle with id set by the Circles app
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_CIRCLE)
+ ->setSharedBy('initiator')
+ ->setSharedWith('Circle (Public circle, circleOwner) [4815162342]')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_CIRCLE,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => '',
+ 'label' => '',
+ 'path' => 'folder',
+ 'item_type' => 'folder',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 2,
+ 'file_source' => 2,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => '4815162342',
+ 'share_with_displayname' => 'Circle (Public circle, circleOwner)',
+ 'share_with_avatar' => '',
+ 'mail_send' => 0,
+ 'mimetype' => 'myFolderMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ // Circle with id not set by the Circles app
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_CIRCLE)
+ ->setSharedBy('initiator')
+ ->setSharedWith('Circle (Public circle, circleOwner)')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_CIRCLE,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => '',
+ 'label' => '',
+ 'path' => 'folder',
+ 'item_type' => 'folder',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 2,
+ 'file_source' => 2,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'Circle',
+ 'share_with_displayname' => 'Circle (Public circle, circleOwner)',
+ 'share_with_avatar' => '',
+ 'mail_send' => 0,
+ 'mimetype' => 'myFolderMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_USER)
+ ->setSharedBy('initiator')
+ ->setSharedWith('recipient')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+
+ $result[] = [
+ [], $share, [], true
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_EMAIL)
+ ->setSharedBy('initiator')
+ ->setSharedWith('user@server.com')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setId(42)
+ ->setPassword('password');
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_EMAIL,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => '',
+ 'label' => '',
+ 'path' => 'folder',
+ 'item_type' => 'folder',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 2,
+ 'file_source' => 2,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'user@server.com',
+ 'share_with_displayname' => 'mail display name',
+ 'mail_send' => 0,
+ 'mimetype' => 'myFolderMimeType',
+ 'has_preview' => false,
+ 'password' => 'password',
+ 'send_password_by_talk' => false,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'password_expiration_time' => null,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_EMAIL)
+ ->setSharedBy('initiator')
+ ->setSharedWith('user@server.com')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($folder)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setId(42)
+ ->setPassword('password')
+ ->setSendPasswordByTalk(true);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_EMAIL,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => '',
+ 'label' => '',
+ 'path' => 'folder',
+ 'item_type' => 'folder',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 2,
+ 'file_source' => 2,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'user@server.com',
+ 'share_with_displayname' => 'mail display name',
+ 'mail_send' => 0,
+ 'mimetype' => 'myFolderMimeType',
+ 'has_preview' => false,
+ 'password' => 'password',
+ 'send_password_by_talk' => true,
+ 'hide_download' => 0,
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'password_expiration_time' => null,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, [], false
+ ];
+
+ // Preview is available
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_USER)
+ ->setSharedWith('recipient')
+ ->setSharedBy('initiator')
+ ->setShareOwner('currentUser')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($fileWithPreview)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_USER,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'currentUser',
+ 'displayname_file_owner' => 'currentUser',
+ 'note' => 'personal note',
+ 'label' => '',
+ 'path' => 'fileWithPreview',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 4,
+ 'file_source' => 4,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'recipient',
+ 'share_with_displayname' => 'recipient',
+ 'share_with_displayname_unique' => 'recipient',
+ 'mail_send' => 0,
+ 'mimetype' => 'mimeWithPreview',
+ 'has_preview' => true,
+ 'hide_download' => 0,
+ 'can_edit' => true,
+ 'can_delete' => true,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 11,
+ ], $share, [], false
+ ];
+
+ return $result;
+ }
+
+ /**
+ *
+ * @param array $expects
+ * @param IShare $share
+ * @param array $users
+ * @param $exception
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataFormatShare')]
+ public function testFormatShare(array $expects, IShare $share, array $users, $exception): void {
+ $this->userManager->method('get')->willReturnMap($users);
+
+ $recipientGroup = $this->createMock(IGroup::class);
+ $recipientGroup->method('getDisplayName')->willReturn('recipientGroupDisplayName');
+ $this->groupManager->method('get')->willReturnMap([
+ ['recipientGroup', $recipientGroup],
+ ]);
+
+ $this->urlGenerator->method('linkToRouteAbsolute')
+ ->with('files_sharing.sharecontroller.showShare', ['token' => 'myToken'])
+ ->willReturn('myLink');
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturnSelf();
+ $this->dateTimeZone->method('getTimezone')->willReturn(new \DateTimeZone('UTC'));
+
+ if (!$exception) {
+ $this->rootFolder->method('getFirstNodeById')
+ ->with($share->getNodeId())
+ ->willReturn($share->getNode());
+
+ $this->rootFolder->method('getRelativePath')
+ ->with($share->getNode()->getPath())
+ ->willReturnArgument(0);
+ }
+
+ $cm = $this->createMock(\OCP\Contacts\IManager::class);
+ $this->overwriteService(\OCP\Contacts\IManager::class, $cm);
+
+ $cm->method('search')
+ ->willReturnMap([
+ ['user@server.com', ['CLOUD'], [
+ 'limit' => 1,
+ 'enumeration' => false,
+ 'strict_search' => true,
+ ],
+ [
+ [
+ 'CLOUD' => [
+ 'user@server.com',
+ ],
+ 'FN' => 'foobar',
+ ],
+ ],
+ ],
+ ['user@server.com', ['EMAIL'], [
+ 'limit' => 1,
+ 'enumeration' => false,
+ 'strict_search' => true,
+ ],
+ [
+ [
+ 'EMAIL' => [
+ 'user@server.com',
+ ],
+ 'FN' => 'mail display name',
+ ],
+ ],
+ ],
+ ]);
+
+ try {
+ $result = $this->invokePrivate($this->ocs, 'formatShare', [$share]);
+ $this->assertFalse($exception);
+ $this->assertEquals($expects, $result);
+ } catch (NotFoundException $e) {
+ $this->assertTrue($exception);
+ }
+ }
+
+ public function dataFormatRoomShare() {
+ $file = $this->getMockBuilder(File::class)->getMock();
+ $parent = $this->getMockBuilder(Folder::class)->getMock();
+
+ $file->method('getMimeType')->willReturn('myMimeType');
+
+ $file->method('getPath')->willReturn('file');
+
+ $parent->method('getId')->willReturn(1);
+ $file->method('getId')->willReturn(3);
+
+ $file->method('getParent')->willReturn($parent);
+
+ $file->method('getSize')->willReturn(123456);
+ $file->method('getMTime')->willReturn(1234567890);
+
+ $mountPoint = $this->getMockBuilder(IMountPoint::class)->getMock();
+ $mountPoint->method('getMountType')->willReturn('');
+ $file->method('getMountPoint')->willReturn($mountPoint);
+
+ $cache = $this->getMockBuilder('OCP\Files\Cache\ICache')->getMock();
+ $cache->method('getNumericStorageId')->willReturn(100);
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('getId')->willReturn('storageId');
+ $storage->method('getCache')->willReturn($cache);
+
+ $file->method('getStorage')->willReturn($storage);
+
+ $result = [];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_ROOM)
+ ->setSharedWith('recipientRoom')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_ROOM,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => 'personal note',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'recipientRoom',
+ 'share_with_displayname' => '',
+ 'mail_send' => 0,
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'label' => '',
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 1,
+ ], $share, false, []
+ ];
+
+ $share = Server::get(IManager::class)->newShare();
+ $share->setShareType(IShare::TYPE_ROOM)
+ ->setSharedWith('recipientRoom')
+ ->setSharedBy('initiator')
+ ->setShareOwner('owner')
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setNode($file)
+ ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
+ ->setTarget('myTarget')
+ ->setNote('personal note')
+ ->setId(42);
+
+ $result[] = [
+ [
+ 'id' => '42',
+ 'share_type' => IShare::TYPE_ROOM,
+ 'uid_owner' => 'initiator',
+ 'displayname_owner' => 'initiator',
+ 'permissions' => 1,
+ 'stime' => 946684862,
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => 'owner',
+ 'displayname_file_owner' => 'owner',
+ 'note' => 'personal note',
+ 'path' => 'file',
+ 'item_type' => 'file',
+ 'storage_id' => 'storageId',
+ 'storage' => 100,
+ 'item_source' => 3,
+ 'file_source' => 3,
+ 'file_parent' => 1,
+ 'file_target' => 'myTarget',
+ 'share_with' => 'recipientRoom',
+ 'share_with_displayname' => 'recipientRoomName',
+ 'mail_send' => 0,
+ 'mimetype' => 'myMimeType',
+ 'has_preview' => false,
+ 'hide_download' => 0,
+ 'label' => '',
+ 'can_edit' => false,
+ 'can_delete' => false,
+ 'item_size' => 123456,
+ 'item_mtime' => 1234567890,
+ 'is-mount-root' => false,
+ 'mount-type' => '',
+ 'attributes' => null,
+ 'item_permissions' => 9,
+ ], $share, true, [
+ 'share_with_displayname' => 'recipientRoomName'
+ ]
+ ];
+
+ return $result;
+ }
+
+ /**
+ *
+ * @param array $expects
+ * @param IShare $share
+ * @param bool $helperAvailable
+ * @param array $formatShareByHelper
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataFormatRoomShare')]
+ public function testFormatRoomShare(array $expects, IShare $share, bool $helperAvailable, array $formatShareByHelper): void {
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturnSelf();
+
+ $this->rootFolder->method('getFirstNodeById')
+ ->with($share->getNodeId())
+ ->willReturn($share->getNode());
+
+ $this->rootFolder->method('getRelativePath')
+ ->with($share->getNode()->getPath())
+ ->willReturnArgument(0);
+
+ if (!$helperAvailable) {
+ $this->appManager->method('isEnabledForUser')
+ ->with('spreed')
+ ->willReturn(false);
+ } else {
+ $this->appManager->method('isEnabledForUser')
+ ->with('spreed')
+ ->willReturn(true);
+
+ // This is not possible anymore with PHPUnit 10+
+ // as `setMethods` was removed and now real reflection is used, thus the class needs to exist.
+ // $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController')
+ $helper = $this->getMockBuilder(\stdClass::class)
+ ->addMethods(['formatShare', 'canAccessShare'])
+ ->getMock();
+ $helper->method('formatShare')
+ ->with($share)
+ ->willReturn($formatShareByHelper);
+ $helper->method('canAccessShare')
+ ->with($share)
+ ->willReturn(true);
+
+ $this->serverContainer->method('get')
+ ->with('\OCA\Talk\Share\Helper\ShareAPIController')
+ ->willReturn($helper);
+ }
+
+ $result = $this->invokePrivate($this->ocs, 'formatShare', [$share]);
+ $this->assertEquals($expects, $result);
+ }
+
+ /**
+ * @return list{Folder, Folder}
+ */
+ private function getNonSharedUserFolder(): array {
+ $node = $this->getMockBuilder(Folder::class)->getMock();
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $userFolder->method('getStorage')->willReturn($storage);
+ $node->method('getStorage')->willReturn($storage);
+ $node->method('getId')->willReturn(42);
+ $user = $this->createMock(IUser::class);
+ $user->method('getUID')->willReturn($this->currentUser);
+ $node->method('getOwner')->willReturn($user);
+ return [$userFolder, $node];
+ }
+
+ /**
+ * @return list{Folder, File}
+ */
+ private function getNonSharedUserFile(): array {
+ $node = $this->getMockBuilder(File::class)->getMock();
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $storage = $this->createMock(IStorage::class);
+ $storage->method('instanceOfStorage')
+ ->willReturnMap([
+ ['OCA\Files_Sharing\External\Storage', false],
+ ['OCA\Files_Sharing\SharedStorage', false],
+ ]);
+ $userFolder->method('getStorage')->willReturn($storage);
+ $node->method('getStorage')->willReturn($storage);
+ $node->method('getId')->willReturn(42);
+ return [$userFolder, $node];
+ }
+
+ public function testPopulateTags(): void {
+ $tagger = $this->createMock(ITags::class);
+ $this->tagManager->method('load')
+ ->with('files')
+ ->willReturn($tagger);
+ $data = [
+ ['file_source' => 10],
+ ['file_source' => 22, 'foo' => 'bar'],
+ ['file_source' => 42, 'x' => 'y'],
+ ];
+ $tags = [
+ 10 => ['tag3'],
+ 42 => ['tag1', 'tag2'],
+ ];
+ $tagger->method('getTagsForObjects')
+ ->with([10, 22, 42])
+ ->willReturn($tags);
+
+ $result = self::invokePrivate($this->ocs, 'populateTags', [$data]);
+ $this->assertSame([
+ ['file_source' => 10, 'tags' => ['tag3']],
+ ['file_source' => 22, 'foo' => 'bar', 'tags' => []],
+ ['file_source' => 42, 'x' => 'y', 'tags' => ['tag1', 'tag2']],
+ ], $result);
+ }
+
+ public function trustedServerProvider(): array {
+ return [
+ 'Trusted server' => [true, true],
+ 'Untrusted server' => [false, false],
+ ];
+ }
+
+ /**
+ * @dataProvider trustedServerProvider
+ */
+ public function testFormatShareWithFederatedShare(bool $isKnownServer, bool $isTrusted): void {
+ $nodeId = 12;
+ $nodePath = '/test.txt';
+ $share = $this->createShare(
+ 1,
+ IShare::TYPE_REMOTE,
+ 'recipient@remoteserver.com', // shared with
+ 'sender@testserver.com', // shared by
+ 'shareOwner', // share owner
+ $nodePath, // path
+ Constants::PERMISSION_READ,
+ time(),
+ null,
+ null,
+ $nodePath,
+ $nodeId
+ );
+
+ $node = $this->createMock(\OCP\Files\File::class);
+ $node->method('getId')->willReturn($nodeId);
+ $node->method('getPath')->willReturn($nodePath);
+ $node->method('getInternalPath')->willReturn(ltrim($nodePath, '/'));
+ $mountPoint = $this->createMock(\OCP\Files\Mount\IMountPoint::class);
+ $mountPoint->method('getMountType')->willReturn('local');
+ $node->method('getMountPoint')->willReturn($mountPoint);
+ $node->method('getMimetype')->willReturn('text/plain');
+ $storage = $this->createMock(\OCP\Files\Storage\IStorage::class);
+ $storageCache = $this->createMock(\OCP\Files\Cache\ICache::class);
+ $storageCache->method('getNumericStorageId')->willReturn(1);
+ $storage->method('getCache')->willReturn($storageCache);
+ $storage->method('getId')->willReturn('home::shareOwner');
+ $node->method('getStorage')->willReturn($storage);
+ $parent = $this->createMock(\OCP\Files\Folder::class);
+ $parent->method('getId')->willReturn(2);
+ $node->method('getParent')->willReturn($parent);
+ $node->method('getSize')->willReturn(1234);
+ $node->method('getMTime')->willReturn(1234567890);
+
+ $this->previewManager->method('isAvailable')->with($node)->willReturn(false);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturnSelf();
+
+ $this->rootFolder->method('getFirstNodeById')
+ ->with($share->getNodeId())
+ ->willReturn($node);
+
+ $this->rootFolder->method('getRelativePath')
+ ->with($node->getPath())
+ ->willReturnArgument(0);
+
+ $serverName = 'remoteserver.com';
+ $this->trustedServers->method('isTrustedServer')
+ ->with($serverName)
+ ->willReturn($isKnownServer);
+
+ $result = $this->invokePrivate($this->ocs, 'formatShare', [$share]);
+
+ $this->assertSame($isTrusted, $result['is_trusted_server']);
+ }
+
+ public function testFormatShareWithFederatedShareWithAtInUsername(): void {
+ $nodeId = 12;
+ $nodePath = '/test.txt';
+ $share = $this->createShare(
+ 1,
+ IShare::TYPE_REMOTE,
+ 'recipient@domain.com@remoteserver.com',
+ 'sender@testserver.com',
+ 'shareOwner',
+ $nodePath,
+ Constants::PERMISSION_READ,
+ time(),
+ null,
+ null,
+ $nodePath,
+ $nodeId
+ );
+
+ $node = $this->createMock(\OCP\Files\File::class);
+ $node->method('getId')->willReturn($nodeId);
+ $node->method('getPath')->willReturn($nodePath);
+ $node->method('getInternalPath')->willReturn(ltrim($nodePath, '/'));
+ $mountPoint = $this->createMock(\OCP\Files\Mount\IMountPoint::class);
+ $mountPoint->method('getMountType')->willReturn('local');
+ $node->method('getMountPoint')->willReturn($mountPoint);
+ $node->method('getMimetype')->willReturn('text/plain');
+ $storage = $this->createMock(\OCP\Files\Storage\IStorage::class);
+ $storageCache = $this->createMock(\OCP\Files\Cache\ICache::class);
+ $storageCache->method('getNumericStorageId')->willReturn(1);
+ $storage->method('getCache')->willReturn($storageCache);
+ $storage->method('getId')->willReturn('home::shareOwner');
+ $node->method('getStorage')->willReturn($storage);
+ $parent = $this->createMock(\OCP\Files\Folder::class);
+ $parent->method('getId')->willReturn(2);
+ $node->method('getParent')->willReturn($parent);
+ $node->method('getSize')->willReturn(1234);
+ $node->method('getMTime')->willReturn(1234567890);
+
+ $this->previewManager->method('isAvailable')->with($node)->willReturn(false);
+
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturnSelf();
+
+ $this->rootFolder->method('getFirstNodeById')
+ ->with($share->getNodeId())
+ ->willReturn($node);
+
+ $this->rootFolder->method('getRelativePath')
+ ->with($node->getPath())
+ ->willReturnArgument(0);
+
+ $serverName = 'remoteserver.com';
+ $this->trustedServers->method('isTrustedServer')
+ ->with($serverName)
+ ->willReturn(true);
+
+ $result = $this->invokePrivate($this->ocs, 'formatShare', [$share]);
+
+ $this->assertTrue($result['is_trusted_server']);
+ }
+}
diff --git a/apps/files_sharing/tests/Controller/ShareControllerTest.php b/apps/files_sharing/tests/Controller/ShareControllerTest.php
new file mode 100644
index 00000000000..011210aff42
--- /dev/null
+++ b/apps/files_sharing/tests/Controller/ShareControllerTest.php
@@ -0,0 +1,822 @@
+<?php
+
+/**
+ * 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\Controllers;
+
+use OC\Files\Filesystem;
+use OC\Files\Node\Folder;
+use OC\Share20\Manager;
+use OCA\FederatedFileSharing\FederatedShareProvider;
+use OCA\Files_Sharing\Controller\ShareController;
+use OCA\Files_Sharing\DefaultPublicShareTemplateProvider;
+use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent;
+use OCP\Accounts\IAccount;
+use OCP\Accounts\IAccountManager;
+use OCP\Accounts\IAccountProperty;
+use OCP\Activity\IManager;
+use OCP\AppFramework\Http\ContentSecurityPolicy;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Http\Template\ExternalShareMenuAction;
+use OCP\AppFramework\Http\Template\LinkMenuAction;
+use OCP\AppFramework\Http\Template\PublicTemplateResponse;
+use OCP\AppFramework\Http\Template\SimpleMenuAction;
+use OCP\AppFramework\Services\IInitialState;
+use OCP\Constants;
+use OCP\Defaults;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\File;
+use OCP\Files\IRootFolder;
+use OCP\Files\NotFoundException;
+use OCP\IAppConfig;
+use OCP\IConfig;
+use OCP\IL10N;
+use OCP\IPreview;
+use OCP\IRequest;
+use OCP\ISession;
+use OCP\IURLGenerator;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\Security\ISecureRandom;
+use OCP\Server;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\IAttributes;
+use OCP\Share\IPublicShareTemplateFactory;
+use OCP\Share\IShare;
+use PHPUnit\Framework\MockObject\MockObject;
+
+/**
+ * @group DB
+ *
+ * @package OCA\Files_Sharing\Controllers
+ */
+class ShareControllerTest extends \Test\TestCase {
+
+ private string $user;
+ private string $oldUser;
+ private string $appName = 'files_sharing';
+ private ShareController $shareController;
+
+ private IL10N&MockObject $l10n;
+ private IConfig&MockObject $config;
+ private ISession&MockObject $session;
+ private Defaults&MockObject $defaults;
+ private IAppConfig&MockObject $appConfig;
+ private Manager&MockObject $shareManager;
+ private IPreview&MockObject $previewManager;
+ private IUserManager&MockObject $userManager;
+ private IInitialState&MockObject $initialState;
+ private IURLGenerator&MockObject $urlGenerator;
+ private ISecureRandom&MockObject $secureRandom;
+ private IAccountManager&MockObject $accountManager;
+ private IEventDispatcher&MockObject $eventDispatcher;
+ private FederatedShareProvider&MockObject $federatedShareProvider;
+ private IPublicShareTemplateFactory&MockObject $publicShareTemplateFactory;
+
+ protected function setUp(): void {
+ parent::setUp();
+ $this->appName = 'files_sharing';
+
+ $this->shareManager = $this->createMock(Manager::class);
+ $this->urlGenerator = $this->createMock(IURLGenerator::class);
+ $this->session = $this->createMock(ISession::class);
+ $this->previewManager = $this->createMock(IPreview::class);
+ $this->config = $this->createMock(IConfig::class);
+ $this->appConfig = $this->createMock(IAppConfig::class);
+ $this->userManager = $this->createMock(IUserManager::class);
+ $this->initialState = $this->createMock(IInitialState::class);
+ $this->federatedShareProvider = $this->createMock(FederatedShareProvider::class);
+ $this->federatedShareProvider->expects($this->any())
+ ->method('isOutgoingServer2serverShareEnabled')->willReturn(true);
+ $this->federatedShareProvider->expects($this->any())
+ ->method('isIncomingServer2serverShareEnabled')->willReturn(true);
+ $this->accountManager = $this->createMock(IAccountManager::class);
+ $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+ $this->l10n = $this->createMock(IL10N::class);
+ $this->secureRandom = $this->createMock(ISecureRandom::class);
+ $this->defaults = $this->createMock(Defaults::class);
+ $this->publicShareTemplateFactory = $this->createMock(IPublicShareTemplateFactory::class);
+ $this->publicShareTemplateFactory
+ ->expects($this->any())
+ ->method('getProvider')
+ ->willReturn(
+ new DefaultPublicShareTemplateProvider(
+ $this->userManager,
+ $this->accountManager,
+ $this->previewManager,
+ $this->federatedShareProvider,
+ $this->urlGenerator,
+ $this->eventDispatcher,
+ $this->l10n,
+ $this->defaults,
+ $this->config,
+ $this->createMock(IRequest::class),
+ $this->initialState,
+ $this->appConfig,
+ )
+ );
+
+ $this->shareController = new ShareController(
+ $this->appName,
+ $this->createMock(IRequest::class),
+ $this->config,
+ $this->urlGenerator,
+ $this->userManager,
+ $this->createMock(IManager::class),
+ $this->shareManager,
+ $this->session,
+ $this->previewManager,
+ $this->createMock(IRootFolder::class),
+ $this->federatedShareProvider,
+ $this->accountManager,
+ $this->eventDispatcher,
+ $this->l10n,
+ $this->secureRandom,
+ $this->defaults,
+ $this->publicShareTemplateFactory,
+ );
+
+
+ // Store current user
+ $this->oldUser = \OC_User::getUser();
+
+ // Create a dummy user
+ $this->user = Server::get(ISecureRandom::class)->generate(12, ISecureRandom::CHAR_LOWER);
+
+ Server::get(IUserManager::class)->createUser($this->user, $this->user);
+ \OC_Util::tearDownFS();
+ $this->loginAsUser($this->user);
+ }
+
+ protected function tearDown(): void {
+ \OC_Util::tearDownFS();
+ \OC_User::setUserId('');
+ Filesystem::tearDown();
+ $user = Server::get(IUserManager::class)->get($this->user);
+ if ($user !== null) {
+ $user->delete();
+ }
+ \OC_User::setIncognitoMode(false);
+
+ Server::get(ISession::class)->set('public_link_authenticated', '');
+
+ // Set old user
+ \OC_User::setUserId($this->oldUser);
+ \OC_Util::setupFS($this->oldUser);
+ parent::tearDown();
+ }
+
+ public function testShowShareInvalidToken(): void {
+ $this->shareController->setToken('invalidtoken');
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareByToken')
+ ->with('invalidtoken')
+ ->willThrowException(new ShareNotFound());
+
+ $this->expectException(NotFoundException::class);
+
+ // Test without a not existing token
+ $this->shareController->showShare();
+ }
+
+ public function testShowShareNotAuthenticated(): void {
+ $this->shareController->setToken('validtoken');
+
+ $share = Server::get(\OCP\Share\IManager::class)->newShare();
+ $share->setPassword('password');
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareByToken')
+ ->with('validtoken')
+ ->willReturn($share);
+
+ $this->expectException(NotFoundException::class);
+
+ // Test without a not existing token
+ $this->shareController->showShare();
+ }
+
+
+ public function testShowShare(): void {
+ $note = 'personal note';
+ $filename = 'file1.txt';
+
+ $this->shareController->setToken('token');
+
+ $owner = $this->createMock(IUser::class);
+ $owner->method('getDisplayName')->willReturn('ownerDisplay');
+ $owner->method('getUID')->willReturn('ownerUID');
+ $owner->method('isEnabled')->willReturn(true);
+
+ $initiator = $this->createMock(IUser::class);
+ $initiator->method('getDisplayName')->willReturn('initiatorDisplay');
+ $initiator->method('getUID')->willReturn('initiatorUID');
+ $initiator->method('isEnabled')->willReturn(true);
+
+ $file = $this->createMock(File::class);
+ $file->method('getName')->willReturn($filename);
+ $file->method('getMimetype')->willReturn('text/plain');
+ $file->method('getSize')->willReturn(33);
+ $file->method('isReadable')->willReturn(true);
+ $file->method('isShareable')->willReturn(true);
+ $file->method('getId')->willReturn(111);
+
+ $accountName = $this->createMock(IAccountProperty::class);
+ $accountName->method('getScope')
+ ->willReturn(IAccountManager::SCOPE_PUBLISHED);
+ $account = $this->createMock(IAccount::class);
+ $account->method('getProperty')
+ ->with(IAccountManager::PROPERTY_DISPLAYNAME)
+ ->willReturn($accountName);
+ $this->accountManager->expects($this->once())
+ ->method('getAccount')
+ ->with($owner)
+ ->willReturn($account);
+
+ /** @var Manager */
+ $manager = Server::get(Manager::class);
+ $share = $manager->newShare();
+ $share->setId(42)
+ ->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE)
+ ->setPassword('password')
+ ->setShareOwner('ownerUID')
+ ->setSharedBy('initiatorUID')
+ ->setNode($file)
+ ->setNote($note)
+ ->setTarget("/$filename")
+ ->setToken('token');
+
+ $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
+ $this->session->method('get')->with('public_link_authenticated')->willReturn('42');
+
+ $this->urlGenerator->expects(self::atLeast(2))
+ ->method('linkToRouteAbsolute')
+ ->willReturnMap([
+ // every file has the show show share url in the opengraph url prop
+ ['files_sharing.sharecontroller.showShare', ['token' => 'token'], 'shareUrl'],
+ // this share is not an image to the default preview is used
+ ['files_sharing.PublicPreview.getPreview', ['x' => 256, 'y' => 256, 'file' => $share->getTarget(), 'token' => 'token'], 'previewUrl'],
+ ]);
+
+ $this->urlGenerator->expects($this->once())
+ ->method('getAbsoluteURL')
+ ->willReturnMap([
+ ['/public.php/dav/files/token/?accept=zip', 'downloadUrl'],
+ ]);
+
+ $this->previewManager->method('isMimeSupported')->with('text/plain')->willReturn(true);
+
+ $this->config->method('getSystemValue')
+ ->willReturnMap(
+ [
+ ['max_filesize_animated_gifs_public_sharing', 10, 10],
+ ['enable_previews', true, true],
+ ['preview_max_x', 1024, 1024],
+ ['preview_max_y', 1024, 1024],
+ ]
+ );
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+
+ $this->userManager->method('get')->willReturnCallback(function (string $uid) use ($owner, $initiator) {
+ if ($uid === 'ownerUID') {
+ return $owner;
+ }
+ if ($uid === 'initiatorUID') {
+ return $initiator;
+ }
+ return null;
+ });
+
+ $this->eventDispatcher->method('dispatchTyped')->with(
+ $this->callback(function ($event) use ($share) {
+ if ($event instanceof BeforeTemplateRenderedEvent) {
+ return $event->getShare() === $share;
+ } else {
+ return true;
+ }
+ })
+ );
+
+ $this->l10n->expects($this->any())
+ ->method('t')
+ ->willReturnCallback(function ($text, $parameters) {
+ return vsprintf($text, $parameters);
+ });
+
+ $this->defaults->expects(self::any())
+ ->method('getProductName')
+ ->willReturn('Nextcloud');
+
+ // Ensure the correct initial state is setup
+ // Shared node is a file so this is a single file share:
+ $view = 'public-file-share';
+ // Set up initial state
+ $initialState = [];
+ $this->initialState->expects(self::any())
+ ->method('provideInitialState')
+ ->willReturnCallback(function ($key, $value) use (&$initialState): void {
+ $initialState[$key] = $value;
+ });
+ $expectedInitialState = [
+ 'isPublic' => true,
+ 'sharingToken' => 'token',
+ 'sharePermissions' => (Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE),
+ 'filename' => $filename,
+ 'view' => $view,
+ 'fileId' => 111,
+ 'owner' => 'ownerUID',
+ 'ownerDisplayName' => 'ownerDisplay',
+ 'isFileRequest' => false,
+ ];
+
+ $response = $this->shareController->showShare();
+
+ $this->assertEquals($expectedInitialState, $initialState);
+
+ $csp = new ContentSecurityPolicy();
+ $csp->addAllowedFrameDomain('\'self\'');
+ $expectedResponse = new PublicTemplateResponse('files', 'index');
+ $expectedResponse->setParams(['pageTitle' => $filename]);
+ $expectedResponse->setContentSecurityPolicy($csp);
+ $expectedResponse->setHeaderTitle($filename);
+ $expectedResponse->setHeaderDetails('shared by ownerDisplay');
+ $expectedResponse->setHeaderActions([
+ new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', 'downloadUrl', 0, '33'),
+ new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', 'owner', 'ownerDisplay', $filename),
+ new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', 'downloadUrl'),
+ ]);
+
+ $this->assertEquals($expectedResponse, $response);
+ }
+
+ public function testShowFileDropShare(): void {
+ $filename = 'folder1';
+
+ $this->shareController->setToken('token');
+
+ $owner = $this->createMock(IUser::class);
+ $owner->method('getDisplayName')->willReturn('ownerDisplay');
+ $owner->method('getUID')->willReturn('ownerUID');
+ $owner->method('isEnabled')->willReturn(true);
+
+ $initiator = $this->createMock(IUser::class);
+ $initiator->method('getDisplayName')->willReturn('initiatorDisplay');
+ $initiator->method('getUID')->willReturn('initiatorUID');
+ $initiator->method('isEnabled')->willReturn(true);
+
+ $file = $this->createMock(Folder::class);
+ $file->method('isReadable')->willReturn(true);
+ $file->method('isShareable')->willReturn(true);
+ $file->method('getId')->willReturn(1234);
+ $file->method('getName')->willReturn($filename);
+
+ $accountName = $this->createMock(IAccountProperty::class);
+ $accountName->method('getScope')
+ ->willReturn(IAccountManager::SCOPE_PUBLISHED);
+ $account = $this->createMock(IAccount::class);
+ $account->method('getProperty')
+ ->with(IAccountManager::PROPERTY_DISPLAYNAME)
+ ->willReturn($accountName);
+ $this->accountManager->expects($this->once())
+ ->method('getAccount')
+ ->with($owner)
+ ->willReturn($account);
+
+ /** @var Manager */
+ $manager = Server::get(Manager::class);
+ $share = $manager->newShare();
+ $share->setId(42)
+ ->setPermissions(Constants::PERMISSION_CREATE)
+ ->setPassword('password')
+ ->setShareOwner('ownerUID')
+ ->setSharedBy('initiatorUID')
+ ->setNote('The note')
+ ->setLabel('A label')
+ ->setNode($file)
+ ->setTarget("/$filename")
+ ->setToken('token');
+
+ $this->appConfig
+ ->expects($this->once())
+ ->method('getValueString')
+ ->with('core', 'shareapi_public_link_disclaimertext', '')
+ ->willReturn('My disclaimer text');
+
+ $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
+ $this->session->method('get')->with('public_link_authenticated')->willReturn('42');
+
+ $this->urlGenerator->expects(self::atLeastOnce())
+ ->method('linkToRouteAbsolute')
+ ->willReturnMap([
+ // every file has the show show share url in the opengraph url prop
+ ['files_sharing.sharecontroller.showShare', ['token' => 'token'], 'shareUrl'],
+ // there is no preview or folders so no other link for opengraph
+ ]);
+
+ $this->config->method('getSystemValue')
+ ->willReturnMap(
+ [
+ ['max_filesize_animated_gifs_public_sharing', 10, 10],
+ ['enable_previews', true, true],
+ ['preview_max_x', 1024, 1024],
+ ['preview_max_y', 1024, 1024],
+ ]
+ );
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+
+ $this->userManager->method('get')->willReturnCallback(function (string $uid) use ($owner, $initiator) {
+ if ($uid === 'ownerUID') {
+ return $owner;
+ }
+ if ($uid === 'initiatorUID') {
+ return $initiator;
+ }
+ return null;
+ });
+
+ $this->eventDispatcher->method('dispatchTyped')->with(
+ $this->callback(function ($event) use ($share) {
+ if ($event instanceof BeforeTemplateRenderedEvent) {
+ return $event->getShare() === $share;
+ } else {
+ return true;
+ }
+ })
+ );
+
+ $this->l10n->expects($this->any())
+ ->method('t')
+ ->willReturnCallback(function ($text, $parameters) {
+ return vsprintf($text, $parameters);
+ });
+
+ // Set up initial state
+ $initialState = [];
+ $this->initialState->expects(self::any())
+ ->method('provideInitialState')
+ ->willReturnCallback(function ($key, $value) use (&$initialState): void {
+ $initialState[$key] = $value;
+ });
+ $expectedInitialState = [
+ 'isPublic' => true,
+ 'sharingToken' => 'token',
+ 'sharePermissions' => Constants::PERMISSION_CREATE,
+ 'filename' => $filename,
+ 'view' => 'public-file-drop',
+ 'disclaimer' => 'My disclaimer text',
+ 'owner' => 'ownerUID',
+ 'ownerDisplayName' => 'ownerDisplay',
+ 'isFileRequest' => false,
+ 'note' => 'The note',
+ 'label' => 'A label',
+ ];
+
+ $response = $this->shareController->showShare();
+
+ $this->assertEquals($expectedInitialState, $initialState);
+
+ $csp = new ContentSecurityPolicy();
+ $csp->addAllowedFrameDomain('\'self\'');
+ $expectedResponse = new PublicTemplateResponse('files', 'index');
+ $expectedResponse->setParams(['pageTitle' => 'A label']);
+ $expectedResponse->setContentSecurityPolicy($csp);
+ $expectedResponse->setHeaderTitle('A label');
+ $expectedResponse->setHeaderDetails('shared by ownerDisplay');
+ $expectedResponse->setHeaderActions([
+ new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', 'shareUrl'),
+ ]);
+
+ $this->assertEquals($expectedResponse, $response);
+ }
+
+ public function testShowShareWithPrivateName(): void {
+ $note = 'personal note';
+ $filename = 'file1.txt';
+
+ $this->shareController->setToken('token');
+
+ $owner = $this->createMock(IUser::class);
+ $owner->method('getDisplayName')->willReturn('ownerDisplay');
+ $owner->method('getUID')->willReturn('ownerUID');
+ $owner->method('isEnabled')->willReturn(true);
+
+ $initiator = $this->createMock(IUser::class);
+ $initiator->method('getDisplayName')->willReturn('initiatorDisplay');
+ $initiator->method('getUID')->willReturn('initiatorUID');
+ $initiator->method('isEnabled')->willReturn(true);
+
+ $file = $this->createMock(File::class);
+ $file->method('getName')->willReturn($filename);
+ $file->method('getMimetype')->willReturn('text/plain');
+ $file->method('getSize')->willReturn(33);
+ $file->method('isReadable')->willReturn(true);
+ $file->method('isShareable')->willReturn(true);
+ $file->method('getId')->willReturn(111);
+
+ $accountName = $this->createMock(IAccountProperty::class);
+ $accountName->method('getScope')
+ ->willReturn(IAccountManager::SCOPE_LOCAL);
+ $account = $this->createMock(IAccount::class);
+ $account->method('getProperty')
+ ->with(IAccountManager::PROPERTY_DISPLAYNAME)
+ ->willReturn($accountName);
+ $this->accountManager->expects($this->once())
+ ->method('getAccount')
+ ->with($owner)
+ ->willReturn($account);
+
+ /** @var IShare */
+ $share = Server::get(Manager::class)->newShare();
+ $share->setId(42);
+ $share->setPassword('password')
+ ->setShareOwner('ownerUID')
+ ->setSharedBy('initiatorUID')
+ ->setNode($file)
+ ->setNote($note)
+ ->setToken('token')
+ ->setPermissions(Constants::PERMISSION_ALL & ~Constants::PERMISSION_SHARE)
+ ->setTarget("/$filename");
+
+ $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
+ $this->session->method('get')->with('public_link_authenticated')->willReturn('42');
+
+ $this->urlGenerator->expects(self::atLeast(2))
+ ->method('linkToRouteAbsolute')
+ ->willReturnMap([
+ // every file has the show show share url in the opengraph url prop
+ ['files_sharing.sharecontroller.showShare', ['token' => 'token'], 'shareUrl'],
+ // this share is not an image to the default preview is used
+ ['files_sharing.PublicPreview.getPreview', ['x' => 256, 'y' => 256, 'file' => $share->getTarget(), 'token' => 'token'], 'previewUrl'],
+ ]);
+
+ $this->urlGenerator->expects($this->once())
+ ->method('getAbsoluteURL')
+ ->willReturnMap([
+ ['/public.php/dav/files/token/?accept=zip', 'downloadUrl'],
+ ]);
+
+ $this->previewManager->method('isMimeSupported')->with('text/plain')->willReturn(true);
+
+ $this->config->method('getSystemValue')
+ ->willReturnMap(
+ [
+ ['max_filesize_animated_gifs_public_sharing', 10, 10],
+ ['enable_previews', true, true],
+ ['preview_max_x', 1024, 1024],
+ ['preview_max_y', 1024, 1024],
+ ]
+ );
+ $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
+ $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+
+ $this->userManager->method('get')->willReturnCallback(function (string $uid) use ($owner, $initiator) {
+ if ($uid === 'ownerUID') {
+ return $owner;
+ }
+ if ($uid === 'initiatorUID') {
+ return $initiator;
+ }
+ return null;
+ });
+
+ $this->eventDispatcher->method('dispatchTyped')->with(
+ $this->callback(function ($event) use ($share) {
+ if ($event instanceof BeforeTemplateRenderedEvent) {
+ return $event->getShare() === $share;
+ } else {
+ return true;
+ }
+ })
+ );
+
+ $this->l10n->expects($this->any())
+ ->method('t')
+ ->willReturnCallback(function ($text, $parameters) {
+ return vsprintf($text, $parameters);
+ });
+
+ $this->defaults->expects(self::any())
+ ->method('getProductName')
+ ->willReturn('Nextcloud');
+
+ $response = $this->shareController->showShare();
+
+ $csp = new ContentSecurityPolicy();
+ $csp->addAllowedFrameDomain('\'self\'');
+ $expectedResponse = new PublicTemplateResponse('files', 'index');
+ $expectedResponse->setParams(['pageTitle' => $filename]);
+ $expectedResponse->setContentSecurityPolicy($csp);
+ $expectedResponse->setHeaderTitle($filename);
+ $expectedResponse->setHeaderDetails('');
+ $expectedResponse->setHeaderActions([
+ new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', 'downloadUrl', 0, '33'),
+ new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', 'owner', 'ownerDisplay', $filename),
+ new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', 'downloadUrl'),
+ ]);
+
+ $this->assertEquals($expectedResponse, $response);
+ }
+
+
+ public function testShowShareInvalid(): void {
+ $this->expectException(NotFoundException::class);
+
+ $filename = 'file1.txt';
+ $this->shareController->setToken('token');
+
+ $owner = $this->getMockBuilder(IUser::class)->getMock();
+ $owner->method('getDisplayName')->willReturn('ownerDisplay');
+ $owner->method('getUID')->willReturn('ownerUID');
+
+ $file = $this->getMockBuilder('OCP\Files\File')->getMock();
+ $file->method('getName')->willReturn($filename);
+ $file->method('getMimetype')->willReturn('text/plain');
+ $file->method('getSize')->willReturn(33);
+ $file->method('isShareable')->willReturn(false);
+ $file->method('isReadable')->willReturn(true);
+
+ $share = Server::get(\OCP\Share\IManager::class)->newShare();
+ $share->setId(42);
+ $share->setPassword('password')
+ ->setShareOwner('ownerUID')
+ ->setNode($file)
+ ->setTarget("/$filename");
+
+ $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
+ $this->session->method('get')->with('public_link_authenticated')->willReturn('42');
+
+ $this->previewManager->method('isMimeSupported')->with('text/plain')->willReturn(true);
+
+ $this->config->method('getSystemValue')
+ ->willReturnMap(
+ [
+ ['max_filesize_animated_gifs_public_sharing', 10, 10],
+ ['enable_previews', true, true],
+ ]
+ );
+ $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
+ $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+
+ $this->userManager->method('get')->with('ownerUID')->willReturn($owner);
+
+ $this->shareController->showShare();
+ }
+
+ public function testDownloadShareWithCreateOnlyShare(): void {
+ $share = $this->getMockBuilder(IShare::class)->getMock();
+ $share->method('getPassword')->willReturn('password');
+ $share
+ ->expects($this->once())
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_CREATE);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareByToken')
+ ->with('validtoken')
+ ->willReturn($share);
+
+ // Test with a password protected share and no authentication
+ $response = $this->shareController->downloadShare('validtoken');
+ $expectedResponse = new DataResponse('Share has no read permission');
+ $this->assertEquals($expectedResponse, $response);
+ }
+
+ public function testDownloadShareWithoutDownloadPermission(): void {
+ $attributes = $this->createMock(IAttributes::class);
+ $attributes->expects(self::once())
+ ->method('getAttribute')
+ ->with('permissions', 'download')
+ ->willReturn(false);
+
+ $share = $this->createMock(IShare::class);
+ $share->method('getPassword')->willReturn('password');
+ $share->expects(self::once())
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ);
+ $share->expects(self::once())
+ ->method('getAttributes')
+ ->willReturn($attributes);
+
+ $this->shareManager
+ ->expects(self::once())
+ ->method('getShareByToken')
+ ->with('validtoken')
+ ->willReturn($share);
+
+ // Test with a password protected share and no authentication
+ $response = $this->shareController->downloadShare('validtoken');
+ $expectedResponse = new DataResponse('Share has no download permission');
+ $this->assertEquals($expectedResponse, $response);
+ }
+
+ public function testDisabledOwner(): void {
+ $this->shareController->setToken('token');
+
+ $owner = $this->getMockBuilder(IUser::class)->getMock();
+ $owner->method('isEnabled')->willReturn(false);
+
+ $initiator = $this->createMock(IUser::class);
+ $initiator->method('isEnabled')->willReturn(false);
+
+ /* @var MockObject|Folder $folder */
+ $folder = $this->createMock(Folder::class);
+
+ $share = Server::get(\OCP\Share\IManager::class)->newShare();
+ $share->setId(42);
+ $share->setPermissions(Constants::PERMISSION_CREATE)
+ ->setShareOwner('ownerUID')
+ ->setSharedBy('initiatorUID')
+ ->setNode($folder)
+ ->setTarget('/share');
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+
+ $this->userManager->method('get')->willReturnCallback(function (string $uid) use ($owner, $initiator) {
+ if ($uid === 'ownerUID') {
+ return $owner;
+ }
+ if ($uid === 'initiatorUID') {
+ return $initiator;
+ }
+ return null;
+ });
+
+ $this->expectException(NotFoundException::class);
+
+ $this->shareController->showShare();
+ }
+
+ public function testDisabledInitiator(): void {
+ $this->shareController->setToken('token');
+
+ $owner = $this->getMockBuilder(IUser::class)->getMock();
+ $owner->method('isEnabled')->willReturn(false);
+
+ $initiator = $this->createMock(IUser::class);
+ $initiator->method('isEnabled')->willReturn(true);
+
+ /* @var MockObject|Folder $folder */
+ $folder = $this->createMock(Folder::class);
+
+ $share = Server::get(\OCP\Share\IManager::class)->newShare();
+ $share->setId(42);
+ $share->setPermissions(Constants::PERMISSION_CREATE)
+ ->setShareOwner('ownerUID')
+ ->setSharedBy('initiatorUID')
+ ->setNode($folder)
+ ->setTarget('/share');
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+
+ $this->userManager->method('get')->willReturnCallback(function (string $uid) use ($owner, $initiator) {
+ if ($uid === 'ownerUID') {
+ return $owner;
+ }
+ if ($uid === 'initiatorUID') {
+ return $initiator;
+ }
+ return null;
+ });
+
+ $this->expectException(NotFoundException::class);
+
+ $this->shareController->showShare();
+ }
+}
diff --git a/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php b/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php
new file mode 100644
index 00000000000..1a678610805
--- /dev/null
+++ b/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php
@@ -0,0 +1,277 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Sharing\Tests\Controller;
+
+use OCA\Files_Sharing\Controller\ShareInfoController;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\Constants;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\IRequest;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\IManager as ShareManager;
+use OCP\Share\IShare;
+use PHPUnit\Framework\MockObject\MockObject;
+use Test\TestCase;
+
+class ShareInfoControllerTest extends TestCase {
+
+ protected ShareInfoController $controller;
+ protected ShareManager&MockObject $shareManager;
+
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->shareManager = $this->createMock(ShareManager::class);
+
+ $this->controller = new ShareInfoController(
+ 'files_sharing',
+ $this->createMock(IRequest::class),
+ $this->shareManager
+ );
+ }
+
+ public function testNoShare(): void {
+ $this->shareManager->method('getShareByToken')
+ ->with('token')
+ ->willThrowException(new ShareNotFound());
+
+ $expected = new JSONResponse([], Http::STATUS_NOT_FOUND);
+ $expected->throttle(['token' => 'token']);
+ $this->assertEquals($expected, $this->controller->info('token'));
+ }
+
+ public function testWrongPassword(): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getPassword')
+ ->willReturn('sharePass');
+
+ $this->shareManager->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+ $this->shareManager->method('checkPassword')
+ ->with($share, 'pass')
+ ->willReturn(false);
+
+ $expected = new JSONResponse([], Http::STATUS_FORBIDDEN);
+ $expected->throttle(['token' => 'token']);
+ $this->assertEquals($expected, $this->controller->info('token', 'pass'));
+ }
+
+ public function testNoReadPermissions(): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getPassword')
+ ->willReturn('sharePass');
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_CREATE);
+
+ $this->shareManager->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+ $this->shareManager->method('checkPassword')
+ ->with($share, 'pass')
+ ->willReturn(true);
+
+ $expected = new JSONResponse([], Http::STATUS_FORBIDDEN);
+ $expected->throttle(['token' => 'token']);
+ $this->assertEquals($expected, $this->controller->info('token', 'pass'));
+ }
+
+ private function prepareFile() {
+ $file = $this->createMock(File::class);
+
+ $file->method('getId')->willReturn(42);
+
+ $parent = $this->createMock(Folder::class);
+ $parent->method('getId')->willReturn(41);
+ $file->method('getParent')->willReturn($parent);
+
+ $file->method('getMTime')->willReturn(1337);
+ $file->method('getName')->willReturn('file');
+ $file->method('getPermissions')->willReturn(Constants::PERMISSION_READ);
+ $file->method('getMimeType')->willReturn('mime/type');
+ $file->method('getSize')->willReturn(1);
+ $file->method('getType')->willReturn('file');
+ $file->method('getEtag')->willReturn('etag');
+
+ return $file;
+ }
+
+ public function testInfoFile(): void {
+ $file = $this->prepareFile();
+
+ $share = $this->createMock(IShare::class);
+ $share->method('getPassword')
+ ->willReturn('sharePass');
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE);
+ $share->method('getNode')
+ ->willReturn($file);
+
+ $this->shareManager->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+ $this->shareManager->method('checkPassword')
+ ->with($share, 'pass')
+ ->willReturn(true);
+
+ $expected = new JSONResponse([
+ 'id' => 42,
+ 'parentId' => 41,
+ 'mtime' => 1337 ,
+ 'name' => 'file',
+ 'permissions' => 1,
+ 'mimetype' => 'mime/type',
+ 'size' => 1,
+ 'type' => 'file',
+ 'etag' => 'etag',
+ ]);
+ $this->assertEquals($expected, $this->controller->info('token', 'pass'));
+ }
+
+ public function testInfoFileRO(): void {
+ $file = $this->prepareFile();
+
+ $share = $this->createMock(IShare::class);
+ $share->method('getPassword')
+ ->willReturn('sharePass');
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ);
+ $share->method('getNode')
+ ->willReturn($file);
+
+ $this->shareManager->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+ $this->shareManager->method('checkPassword')
+ ->with($share, 'pass')
+ ->willReturn(true);
+
+ $expected = new JSONResponse([
+ 'id' => 42,
+ 'parentId' => 41,
+ 'mtime' => 1337 ,
+ 'name' => 'file',
+ 'permissions' => 1,
+ 'mimetype' => 'mime/type',
+ 'size' => 1,
+ 'type' => 'file',
+ 'etag' => 'etag',
+ ]);
+ $this->assertEquals($expected, $this->controller->info('token', 'pass'));
+ }
+
+ private function prepareFolder() {
+ $root = $this->createMock(Folder::class);
+
+ $root->method('getId')->willReturn(42);
+
+ $parent = $this->createMock(Folder::class);
+ $parent->method('getId')->willReturn(41);
+ $root->method('getParent')->willReturn($parent);
+
+ $root->method('getMTime')->willReturn(1337);
+ $root->method('getName')->willReturn('root');
+ $root->method('getPermissions')->willReturn(Constants::PERMISSION_READ);
+ $root->method('getMimeType')->willReturn('mime/type');
+ $root->method('getSize')->willReturn(1);
+ $root->method('getType')->willReturn('folder');
+ $root->method('getEtag')->willReturn('etag');
+
+
+ //Subfolder
+ $sub = $this->createMock(Folder::class);
+
+ $sub->method('getId')->willReturn(43);
+ $sub->method('getParent')->willReturn($root);
+ $sub->method('getMTime')->willReturn(1338);
+ $sub->method('getName')->willReturn('sub');
+ $sub->method('getPermissions')->willReturn(Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE);
+ $sub->method('getMimeType')->willReturn('mime/type');
+ $sub->method('getSize')->willReturn(2);
+ $sub->method('getType')->willReturn('folder');
+ $sub->method('getEtag')->willReturn('etag2');
+
+ $root->method('getDirectoryListing')->willReturn([$sub]);
+
+ //Subfile
+ $file = $this->createMock(File::class);
+ $file->method('getId')->willReturn(88);
+ $file->method('getParent')->willReturn($sub);
+ $file->method('getMTime')->willReturn(1339);
+ $file->method('getName')->willReturn('file');
+ $file->method('getPermissions')->willReturn(Constants::PERMISSION_READ | Constants::PERMISSION_DELETE);
+ $file->method('getMimeType')->willReturn('mime/type');
+ $file->method('getSize')->willReturn(3);
+ $file->method('getType')->willReturn('file');
+ $file->method('getEtag')->willReturn('etag3');
+
+ $sub->method('getDirectoryListing')->willReturn([$file]);
+
+ return $root;
+ }
+
+ public function testInfoFolder(): void {
+ $file = $this->prepareFolder();
+
+ $share = $this->createMock(IShare::class);
+ $share->method('getPassword')
+ ->willReturn('sharePass');
+ $share->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE);
+ $share->method('getNode')
+ ->willReturn($file);
+
+ $this->shareManager->method('getShareByToken')
+ ->with('token')
+ ->willReturn($share);
+ $this->shareManager->method('checkPassword')
+ ->with($share, 'pass')
+ ->willReturn(true);
+
+ $expected = new JSONResponse([
+ 'id' => 42,
+ 'parentId' => 41,
+ 'mtime' => 1337,
+ 'name' => 'root',
+ 'permissions' => 1,
+ 'mimetype' => 'mime/type',
+ 'size' => 1,
+ 'type' => 'folder',
+ 'etag' => 'etag',
+ 'children' => [
+ [
+ 'id' => 43,
+ 'parentId' => 42,
+ 'mtime' => 1338,
+ 'name' => 'sub',
+ 'permissions' => 3,
+ 'mimetype' => 'mime/type',
+ 'size' => 2,
+ 'type' => 'folder',
+ 'etag' => 'etag2',
+ 'children' => [
+ [
+ 'id' => 88,
+ 'parentId' => 43,
+ 'mtime' => 1339,
+ 'name' => 'file',
+ 'permissions' => 1,
+ 'mimetype' => 'mime/type',
+ 'size' => 3,
+ 'type' => 'file',
+ 'etag' => 'etag3',
+ ]
+ ],
+ ]
+ ],
+ ]);
+ $this->assertEquals($expected, $this->controller->info('token', 'pass'));
+ }
+}
diff --git a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php
new file mode 100644
index 00000000000..18e1bf0347b
--- /dev/null
+++ b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php
@@ -0,0 +1,466 @@
+<?php
+
+/**
+ * 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\Controller;
+
+use OCA\Files_Sharing\Controller\ShareesAPIController;
+use OCA\Files_Sharing\Tests\TestCase;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCS\OCSBadRequestException;
+use OCP\Collaboration\Collaborators\ISearch;
+use OCP\GlobalScale\IConfig as GlobalScaleIConfig;
+use OCP\IConfig;
+use OCP\IRequest;
+use OCP\IURLGenerator;
+use OCP\Share\IManager;
+use OCP\Share\IShare;
+use PHPUnit\Framework\MockObject\MockObject;
+
+/**
+ * Class ShareesTest
+ *
+ * @group DB
+ *
+ * @package OCA\Files_Sharing\Tests\API
+ */
+class ShareesAPIControllerTest extends TestCase {
+ /** @var ShareesAPIController */
+ protected $sharees;
+
+ /** @var string */
+ protected $uid;
+
+ /** @var IRequest|MockObject */
+ protected $request;
+
+ /** @var IManager|MockObject */
+ protected $shareManager;
+
+ /** @var ISearch|MockObject */
+ protected $collaboratorSearch;
+
+ /** @var IConfig|MockObject */
+ protected $config;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->uid = 'test123';
+ $this->request = $this->createMock(IRequest::class);
+ $this->shareManager = $this->createMock(IManager::class);
+ $this->config = $this->createMock(IConfig::class);
+
+ /** @var IURLGenerator|MockObject $urlGeneratorMock */
+ $urlGeneratorMock = $this->createMock(IURLGenerator::class);
+
+ $this->collaboratorSearch = $this->createMock(ISearch::class);
+
+ $this->sharees = new ShareesAPIController(
+ 'files_sharing',
+ $this->request,
+ $this->uid,
+ $this->config,
+ $urlGeneratorMock,
+ $this->shareManager,
+ $this->collaboratorSearch
+ );
+ }
+
+ public static function dataSearch(): array {
+ $noRemote = [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_EMAIL];
+ $allTypes = [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE, IShare::TYPE_REMOTE_GROUP, IShare::TYPE_EMAIL];
+
+ return [
+ [[], '', 'yes', false, true, true, true, $noRemote, false, true, true],
+
+ // Test itemType
+ [[
+ 'search' => '',
+ ], '', 'yes', false, true, true, true, $noRemote, false, true, true],
+ [[
+ 'search' => 'foobar',
+ ], '', 'yes', false, true, true, true, $noRemote, false, true, true],
+ [[
+ 'search' => 0,
+ ], '', 'yes', false, true, true, true, $noRemote, false, true, true],
+
+ // Test itemType
+ [[
+ 'itemType' => '',
+ ], '', 'yes', false, true, true, true, $noRemote, false, true, true],
+ [[
+ 'itemType' => 'folder',
+ ], '', 'yes', false, true, true, true, $allTypes, false, true, true],
+ [[
+ 'itemType' => 0,
+ ], '', 'yes', false, true, true , true, $noRemote, false, true, true],
+ // Test shareType
+ [[
+ 'itemType' => 'call',
+ ], '', 'yes', false, true, true, true, $noRemote, false, true, true],
+ [[
+ 'itemType' => 'call',
+ ], '', 'yes', false, true, true, true, [0, 4], false, true, false],
+ [[
+ 'itemType' => 'folder',
+ ], '', 'yes', false, true, true, true, $allTypes, false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => 0,
+ ], '', 'yes', false, true, true, false, [0], false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => '0',
+ ], '', 'yes', false, true, true, false, [0], false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => 1,
+ ], '', 'yes', false, true, true, false, [1], false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => 12,
+ ], '', 'yes', false, true, true, false, [], false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => 'foobar',
+ ], '', 'yes', false, true, true, true, $allTypes, false, true, true],
+
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => [0, 1, 2],
+ ], '', 'yes', false, false, false, false, [0, 1], false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => [0, 1],
+ ], '', 'yes', false, false, false, false, [0, 1], false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => $allTypes,
+ ], '', 'yes', false, true, true, true, $allTypes, false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => $allTypes,
+ ], '', 'yes', false, false, false, false, [0, 1], false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => $allTypes,
+ ], '', 'yes', false, true, false, false, [0, 6], false, true, false],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => $allTypes,
+ ], '', 'yes', false, false, false, true, [0, 4], false, true, false],
+ [[
+ 'itemType' => 'folder',
+ 'shareType' => $allTypes,
+ ], '', 'yes', false, true, true, false, [0, 6, 9], false, true, false],
+
+ // Test pagination
+ [[
+ 'itemType' => 'folder',
+ 'page' => 1,
+ ], '', 'yes', false, true, true, true, $allTypes, false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'page' => 10,
+ ], '', 'yes', false, true, true, true, $allTypes, false, true, true],
+
+ // Test perPage
+ [[
+ 'itemType' => 'folder',
+ 'perPage' => 1,
+ ], '', 'yes', false, true, true, true, $allTypes, false, true, true],
+ [[
+ 'itemType' => 'folder',
+ 'perPage' => 10,
+ ], '', 'yes', false, true, true, true, $allTypes, false, true, true],
+
+ // Test $shareWithGroupOnly setting
+ [[
+ 'itemType' => 'folder',
+ ], 'no', 'yes', false, true, true, true, $allTypes, false, true, true],
+ [[
+ 'itemType' => 'folder',
+ ], 'yes', 'yes', false, true, true, true, $allTypes, true, true, true],
+
+ // Test $shareeEnumeration setting
+ [[
+ 'itemType' => 'folder',
+ ], 'no', 'yes', false, true, true, true, $allTypes, false, true, true],
+ [[
+ 'itemType' => 'folder',
+ ], 'no', 'no', false, true, true, true, $allTypes, false, false, true],
+
+ ];
+ }
+
+ /**
+ *
+ * @param array $getData
+ * @param string $apiSetting
+ * @param string $enumSetting
+ * @param bool $remoteSharingEnabled
+ * @param bool $isRemoteGroupSharingEnabled
+ * @param bool $emailSharingEnabled
+ * @param array $shareTypes
+ * @param bool $shareWithGroupOnly
+ * @param bool $shareeEnumeration
+ * @param bool $allowGroupSharing
+ * @throws OCSBadRequestException
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataSearch')]
+ public function testSearch(
+ array $getData,
+ string $apiSetting,
+ string $enumSetting,
+ bool $sharingDisabledForUser,
+ bool $remoteSharingEnabled,
+ bool $isRemoteGroupSharingEnabled,
+ bool $emailSharingEnabled,
+ array $shareTypes,
+ bool $shareWithGroupOnly,
+ bool $shareeEnumeration,
+ bool $allowGroupSharing,
+ ): void {
+ $search = $getData['search'] ?? '';
+ $itemType = $getData['itemType'] ?? 'irrelevant';
+ $page = $getData['page'] ?? 1;
+ $perPage = $getData['perPage'] ?? 200;
+ $shareType = $getData['shareType'] ?? null;
+
+ $globalConfig = $this->createMock(GlobalScaleIConfig::class);
+ $globalConfig->expects(self::once())
+ ->method('isGlobalScaleEnabled')
+ ->willReturn(true);
+ $this->overwriteService(GlobalScaleIConfig::class, $globalConfig);
+
+ /** @var IConfig|MockObject $config */
+ $config = $this->createMock(IConfig::class);
+
+ $this->shareManager->expects($this->once())
+ ->method('allowGroupSharing')
+ ->willReturn($allowGroupSharing);
+
+ /** @var string */
+ $uid = 'test123';
+ /** @var IRequest|MockObject $request */
+ $request = $this->createMock(IRequest::class);
+ /** @var IURLGenerator|MockObject $urlGenerator */
+ $urlGenerator = $this->createMock(IURLGenerator::class);
+
+ /** @var MockObject|ShareesAPIController $sharees */
+ $sharees = $this->getMockBuilder(ShareesAPIController::class)
+ ->setConstructorArgs([
+ 'files_sharing',
+ $request,
+ $uid,
+ $config,
+ $urlGenerator,
+ $this->shareManager,
+ $this->collaboratorSearch
+ ])
+ ->onlyMethods(['isRemoteSharingAllowed', 'isRemoteGroupSharingAllowed'])
+ ->getMock();
+
+ $expectedShareTypes = $shareTypes;
+ sort($expectedShareTypes);
+
+ $this->collaboratorSearch->expects($this->once())
+ ->method('search')
+ ->with($search, $expectedShareTypes, $this->anything(), $perPage, $perPage * ($page - 1))
+ ->willReturn([[], false]);
+
+ $sharees->expects($this->any())
+ ->method('isRemoteSharingAllowed')
+ ->with($itemType)
+ ->willReturn($remoteSharingEnabled);
+
+
+ $sharees->expects($this->any())
+ ->method('isRemoteGroupSharingAllowed')
+ ->with($itemType)
+ ->willReturn($isRemoteGroupSharingEnabled);
+
+ $this->shareManager->expects($this->any())
+ ->method('sharingDisabledForUser')
+ ->with($uid)
+ ->willReturn($sharingDisabledForUser);
+
+ $this->shareManager->expects($this->any())
+ ->method('shareProviderExists')
+ ->willReturnCallback(function ($shareType) use ($emailSharingEnabled) {
+ if ($shareType === IShare::TYPE_EMAIL) {
+ return $emailSharingEnabled;
+ } else {
+ return false;
+ }
+ });
+
+ $this->assertInstanceOf(DataResponse::class, $sharees->search($search, $itemType, $page, $perPage, $shareType));
+ }
+
+ public static function dataSearchInvalid(): array {
+ return [
+ // Test invalid pagination
+ [[
+ 'page' => 0,
+ ], 'Invalid page'],
+ [[
+ 'page' => '0',
+ ], 'Invalid page'],
+ [[
+ 'page' => -1,
+ ], 'Invalid page'],
+
+ // Test invalid perPage
+ [[
+ 'perPage' => 0,
+ ], 'Invalid perPage argument'],
+ [[
+ 'perPage' => '0',
+ ], 'Invalid perPage argument'],
+ [[
+ 'perPage' => -1,
+ ], 'Invalid perPage argument'],
+ ];
+ }
+
+ /**
+ *
+ * @param array $getData
+ * @param string $message
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataSearchInvalid')]
+ public function testSearchInvalid($getData, $message): void {
+ $page = $getData['page'] ?? 1;
+ $perPage = $getData['perPage'] ?? 200;
+
+ /** @var IConfig|MockObject $config */
+ $config = $this->createMock(IConfig::class);
+ $config->expects($this->never())
+ ->method('getAppValue');
+
+ /** @var string */
+ $uid = 'test123';
+ /** @var IRequest|MockObject $request */
+ $request = $this->createMock(IRequest::class);
+ /** @var IURLGenerator|MockObject $urlGenerator */
+ $urlGenerator = $this->createMock(IURLGenerator::class);
+
+ /** @var MockObject|ShareesAPIController $sharees */
+ $sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController')
+ ->setConstructorArgs([
+ 'files_sharing',
+ $request,
+ $uid,
+ $config,
+ $urlGenerator,
+ $this->shareManager,
+ $this->collaboratorSearch
+ ])
+ ->onlyMethods(['isRemoteSharingAllowed'])
+ ->getMock();
+ $sharees->expects($this->never())
+ ->method('isRemoteSharingAllowed');
+
+ $this->collaboratorSearch->expects($this->never())
+ ->method('search');
+
+ try {
+ $sharees->search('', null, $page, $perPage, null);
+ $this->fail();
+ } catch (OCSBadRequestException $e) {
+ $this->assertEquals($message, $e->getMessage());
+ }
+ }
+
+ public static function dataIsRemoteSharingAllowed() {
+ return [
+ ['file', true],
+ ['folder', true],
+ ['', false],
+ ['contacts', false],
+ ];
+ }
+
+ /**
+ *
+ * @param string $itemType
+ * @param bool $expected
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataIsRemoteSharingAllowed')]
+ public function testIsRemoteSharingAllowed($itemType, $expected): void {
+ $this->assertSame($expected, $this->invokePrivate($this->sharees, 'isRemoteSharingAllowed', [$itemType]));
+ }
+
+ public function testSearchSharingDisabled(): void {
+ $this->shareManager->expects($this->once())
+ ->method('sharingDisabledForUser')
+ ->with($this->uid)
+ ->willReturn(true);
+
+ $this->config->expects($this->once())
+ ->method('getSystemValueInt')
+ ->with('sharing.minSearchStringLength', 0)
+ ->willReturn(0);
+
+ $this->shareManager->expects($this->never())
+ ->method('allowGroupSharing');
+
+ $this->assertInstanceOf(DataResponse::class, $this->sharees->search('', null, 1, 10, [], false));
+ }
+
+ public function testSearchNoItemType(): void {
+ $this->expectException(OCSBadRequestException::class);
+ $this->expectExceptionMessage('Missing itemType');
+
+ $this->sharees->search('', null, 1, 10, [], false);
+ }
+
+ public static function dataGetPaginationLink() {
+ return [
+ [1, '/ocs/v1.php', ['perPage' => 2], '<?perPage=2&page=2>; rel="next"'],
+ [10, '/ocs/v2.php', ['perPage' => 2], '<?perPage=2&page=11>; rel="next"'],
+ ];
+ }
+
+ /**
+ *
+ * @param int $page
+ * @param string $scriptName
+ * @param array $params
+ * @param array $expected
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataGetPaginationLink')]
+ public function testGetPaginationLink($page, $scriptName, $params, $expected): void {
+ $this->request->expects($this->once())
+ ->method('getScriptName')
+ ->willReturn($scriptName);
+
+ $this->assertEquals($expected, $this->invokePrivate($this->sharees, 'getPaginationLink', [$page, $params]));
+ }
+
+ public static function dataIsV2() {
+ return [
+ ['/ocs/v1.php', false],
+ ['/ocs/v2.php', true],
+ ];
+ }
+
+ /**
+ *
+ * @param string $scriptName
+ * @param bool $expected
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataIsV2')]
+ public function testIsV2($scriptName, $expected): void {
+ $this->request->expects($this->once())
+ ->method('getScriptName')
+ ->willReturn($scriptName);
+
+ $this->assertEquals($expected, $this->invokePrivate($this->sharees, 'isV2'));
+ }
+}
diff --git a/apps/files_sharing/tests/DeleteOrphanedSharesJobTest.php b/apps/files_sharing/tests/DeleteOrphanedSharesJobTest.php
new file mode 100644
index 00000000000..c245d157151
--- /dev/null
+++ b/apps/files_sharing/tests/DeleteOrphanedSharesJobTest.php
@@ -0,0 +1,148 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\Filesystem;
+use OC\SystemConfig;
+use OCA\Files_Sharing\DeleteOrphanedSharesJob;
+use OCP\App\IAppManager;
+use OCP\Constants;
+use OCP\IDBConnection;
+use OCP\IUserManager;
+use OCP\Server;
+use OCP\Share\IShare;
+
+/**
+ * Class DeleteOrphanedSharesJobTest
+ *
+ * @group DB
+ *
+ * @package OCA\Files_Sharing\Tests
+ */
+class DeleteOrphanedSharesJobTest extends \Test\TestCase {
+ /**
+ * @var bool
+ */
+ private static $trashBinStatus;
+
+ /**
+ * @var DeleteOrphanedSharesJob
+ */
+ private $job;
+
+ /**
+ * @var IDBConnection
+ */
+ private $connection;
+
+ /**
+ * @var string
+ */
+ private $user1;
+
+ /**
+ * @var string
+ */
+ private $user2;
+
+ public static function setUpBeforeClass(): void {
+ $appManager = Server::get(IAppManager::class);
+ self::$trashBinStatus = $appManager->isEnabledForUser('files_trashbin');
+ $appManager->disableApp('files_trashbin');
+
+ // just in case...
+ Filesystem::getLoader()->removeStorageWrapper('oc_trashbin');
+ }
+
+ public static function tearDownAfterClass(): void {
+ if (self::$trashBinStatus) {
+ Server::get(IAppManager::class)->enableApp('files_trashbin');
+ }
+ }
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->connection = Server::get(IDBConnection::class);
+ // clear occasional leftover shares from other tests
+ $this->connection->executeUpdate('DELETE FROM `*PREFIX*share`');
+
+ $this->user1 = $this->getUniqueID('user1_');
+ $this->user2 = $this->getUniqueID('user2_');
+
+ $userManager = Server::get(IUserManager::class);
+ $userManager->createUser($this->user1, 'pass');
+ $userManager->createUser($this->user2, 'pass');
+
+ \OC::registerShareHooks(Server::get(SystemConfig::class));
+
+ $this->job = Server::get(DeleteOrphanedSharesJob::class);
+ }
+
+ protected function tearDown(): void {
+ $this->connection->executeUpdate('DELETE FROM `*PREFIX*share`');
+
+ $userManager = Server::get(IUserManager::class);
+ $user1 = $userManager->get($this->user1);
+ if ($user1) {
+ $user1->delete();
+ }
+ $user2 = $userManager->get($this->user2);
+ if ($user2) {
+ $user2->delete();
+ }
+
+ $this->logout();
+
+ parent::tearDown();
+ }
+
+ private function getShares() {
+ $shares = [];
+ $result = $this->connection->executeQuery('SELECT * FROM `*PREFIX*share`');
+ while ($row = $result->fetch()) {
+ $shares[] = $row;
+ }
+ $result->closeCursor();
+ return $shares;
+ }
+
+ /**
+ * Test clearing orphaned shares
+ */
+ public function testClearShares(): void {
+ $this->loginAsUser($this->user1);
+
+ $user1Folder = \OC::$server->getUserFolder($this->user1);
+ $testFolder = $user1Folder->newFolder('test');
+ $testSubFolder = $testFolder->newFolder('sub');
+
+ $shareManager = Server::get(\OCP\Share\IManager::class);
+ $share = $shareManager->newShare();
+
+ $share->setNode($testSubFolder)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setSharedWith($this->user2)
+ ->setSharedBy($this->user1);
+
+ $shareManager->createShare($share);
+
+ $this->assertCount(1, $this->getShares());
+
+ $this->job->run([]);
+
+ $this->assertCount(1, $this->getShares(), 'Linked shares not deleted');
+
+ $testFolder->delete();
+
+ $this->job->run([]);
+
+ $this->assertCount(0, $this->getShares(), 'Orphaned shares deleted');
+ }
+}
diff --git a/apps/files_sharing/tests/EncryptedSizePropagationTest.php b/apps/files_sharing/tests/EncryptedSizePropagationTest.php
new file mode 100644
index 00000000000..1be17df3957
--- /dev/null
+++ b/apps/files_sharing/tests/EncryptedSizePropagationTest.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\View;
+use OCP\ITempManager;
+use OCP\Server;
+use Test\Traits\EncryptionTrait;
+
+/**
+ * @group DB
+ */
+class EncryptedSizePropagationTest extends SizePropagationTest {
+ use EncryptionTrait;
+
+ protected function setUp(): void {
+ parent::setUp();
+ $this->config->setAppValue('encryption', 'useMasterKey', '0');
+ }
+
+ protected function setupUser($name, $password = '') {
+ $this->createUser($name, $password);
+ $this->registerMountForUser($name);
+ $this->setupForUser($name, $password);
+ $this->loginWithEncryption($name);
+ return new View('/' . $name . '/files');
+ }
+
+ private function registerMountForUser($user): void {
+ $tmpFolder = Server::get(ITempManager::class)->getTemporaryFolder();
+ $this->registerMount($user, '\OC\Files\Storage\Local', '/' . $user, ['datadir' => $tmpFolder]);
+ }
+
+ protected function loginHelper($user, $create = false, $password = false) {
+ $this->registerMountForUser($user);
+ $this->setupForUser($user, $password);
+ parent::loginHelper($user, $create, $password);
+ }
+}
diff --git a/apps/files_sharing/tests/etagpropagation.php b/apps/files_sharing/tests/EtagPropagationTest.php
index 55972dd9221..d8580ea92d5 100644
--- a/apps/files_sharing/tests/etagpropagation.php
+++ b/apps/files_sharing/tests/EtagPropagationTest.php
@@ -1,41 +1,27 @@
<?php
+
/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * 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;
+namespace OCA\Files_Sharing\Tests;
use OC\Files\Filesystem;
use OC\Files\View;
+use OCP\Constants;
+use OCP\Files\IRootFolder;
+use OCP\Server;
+use OCP\Share\IShare;
/**
- * Class EtagPropagation
+ * Class EtagPropagationTest
*
- * @group DB
+ * @group SLOWDB
*
- * @package OCA\Files_sharing\Tests
+ * @package OCA\Files_Sharing\Tests
*/
-class EtagPropagation extends PropagationTestCase {
+class EtagPropagationTest extends PropagationTestCase {
/**
* "user1" is the admin who shares a folder "sub1/sub2/folder" with "user2" and "user3"
@@ -50,13 +36,15 @@ class EtagPropagation extends PropagationTestCase {
$this->fileIds[self::TEST_FILES_SHARING_API_USER3] = [];
$this->fileIds[self::TEST_FILES_SHARING_API_USER4] = [];
+ $rootFolder = Server::get(IRootFolder::class);
+ $shareManager = Server::get(\OCP\Share\IManager::class);
+
$this->rootView = new View('');
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
$view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
$view1->mkdir('/sub1/sub2/folder/inside');
$view1->mkdir('/directReshare');
$view1->mkdir('/sub1/sub2/folder/other');
- $view1->mkdir('/sub1/sub2/folder/other');
$view1->file_put_contents('/foo.txt', 'foobar');
$view1->file_put_contents('/sub1/sub2/folder/file.txt', 'foobar');
$view1->file_put_contents('/sub1/sub2/folder/inside/file.txt', 'foobar');
@@ -64,30 +52,100 @@ class EtagPropagation extends PropagationTestCase {
$this->assertInstanceOf('\OC\Files\FileInfo', $folderInfo);
$fileInfo = $view1->getFileInfo('/foo.txt');
$this->assertInstanceOf('\OC\Files\FileInfo', $fileInfo);
- \OCP\Share::shareItem('file', $fileInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
- \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
- \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER3, 31);
+
+ $node = $rootFolder->getUserFolder(self::TEST_FILES_SHARING_API_USER1)
+ ->get('/foo.txt');
+ $share = $shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE);
+ $share = $shareManager->createShare($share);
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER2);
+ $node = $rootFolder->getUserFolder(self::TEST_FILES_SHARING_API_USER1)
+ ->get('/sub1/sub2/folder');
+
+ $share = $shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $shareManager->createShare($share);
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER2);
+
+ $share = $shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER3)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $shareManager->createShare($share);
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER3);
+
$folderInfo = $view1->getFileInfo('/directReshare');
$this->assertInstanceOf('\OC\Files\FileInfo', $folderInfo);
- \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
+
+ $node = $rootFolder->getUserFolder(self::TEST_FILES_SHARING_API_USER1)
+ ->get('/directReshare');
+ $share = $shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $shareManager->createShare($share);
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER2);
+
$this->fileIds[self::TEST_FILES_SHARING_API_USER1][''] = $view1->getFileInfo('')->getId();
$this->fileIds[self::TEST_FILES_SHARING_API_USER1]['sub1'] = $view1->getFileInfo('sub1')->getId();
$this->fileIds[self::TEST_FILES_SHARING_API_USER1]['sub1/sub2'] = $view1->getFileInfo('sub1/sub2')->getId();
+ /*
+ * User 2
+ */
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
$view2 = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
$view2->mkdir('/sub1/sub2');
$view2->rename('/folder', '/sub1/sub2/folder');
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+
$insideInfo = $view2->getFileInfo('/sub1/sub2/folder/inside');
$this->assertInstanceOf('\OC\Files\FileInfo', $insideInfo);
- \OCP\Share::shareItem('folder', $insideInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER4, 31);
+
+ $node = $rootFolder->getUserFolder(self::TEST_FILES_SHARING_API_USER2)
+ ->get('/sub1/sub2/folder/inside');
+ $share = $shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER4)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $shareManager->createShare($share);
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER4);
+
$folderInfo = $view2->getFileInfo('/directReshare');
$this->assertInstanceOf('\OC\Files\FileInfo', $folderInfo);
- \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER4, 31);
+
+ $node = $rootFolder->getUserFolder(self::TEST_FILES_SHARING_API_USER2)
+ ->get('/directReshare');
+ $share = $shareManager->newShare();
+ $share->setNode($node)
+ ->setShareType(IShare::TYPE_USER)
+ ->setSharedWith(self::TEST_FILES_SHARING_API_USER4)
+ ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
+ ->setPermissions(Constants::PERMISSION_ALL);
+ $share = $shareManager->createShare($share);
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER4);
+
$this->fileIds[self::TEST_FILES_SHARING_API_USER2][''] = $view2->getFileInfo('')->getId();
$this->fileIds[self::TEST_FILES_SHARING_API_USER2]['sub1'] = $view2->getFileInfo('sub1')->getId();
$this->fileIds[self::TEST_FILES_SHARING_API_USER2]['sub1/sub2'] = $view2->getFileInfo('sub1/sub2')->getId();
+ /*
+ * User 3
+ */
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER3);
$view3 = new View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files');
$view3->mkdir('/sub1/sub2');
@@ -96,6 +154,9 @@ class EtagPropagation extends PropagationTestCase {
$this->fileIds[self::TEST_FILES_SHARING_API_USER3]['sub1'] = $view3->getFileInfo('sub1')->getId();
$this->fileIds[self::TEST_FILES_SHARING_API_USER3]['sub1/sub2'] = $view3->getFileInfo('sub1/sub2')->getId();
+ /*
+ * User 4
+ */
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
$view4 = new View('/' . self::TEST_FILES_SHARING_API_USER4 . '/files');
$view4->mkdir('/sub1/sub2');
@@ -108,12 +169,13 @@ class EtagPropagation extends PropagationTestCase {
$this->loginAsUser($user);
foreach ($ids as $id) {
$path = $this->rootView->getPath($id);
+ $ls = $this->rootView->getDirectoryContent($path);
$this->fileEtags[$id] = $this->rootView->getFileInfo($path)->getEtag();
}
}
}
- public function testOwnerWritesToShare() {
+ public function testOwnerWritesToShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
Filesystem::file_put_contents('/sub1/sub2/folder/asd.txt', 'bar');
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
@@ -123,17 +185,18 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testOwnerWritesToSingleFileShare() {
+ public function testOwnerWritesToSingleFileShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
Filesystem::file_put_contents('/foo.txt', 'longer_bar');
- Filesystem::touch('/foo.txt', time() - 1);
+ $t = (int)Filesystem::filemtime('/foo.txt') - 1;
+ Filesystem::touch('/foo.txt', $t);
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4, self::TEST_FILES_SHARING_API_USER3]);
$this->assertEtagsChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2]);
$this->assertAllUnchanged();
}
- public function testOwnerWritesToShareWithReshare() {
+ public function testOwnerWritesToShareWithReshare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
Filesystem::file_put_contents('/sub1/sub2/folder/inside/bar.txt', 'bar');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -142,7 +205,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testOwnerRenameInShare() {
+ public function testOwnerRenameInShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
Filesystem::rename('/sub1/sub2/folder/file.txt', '/sub1/sub2/folder/renamed.txt');
@@ -152,7 +215,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testOwnerRenameInReShare() {
+ public function testOwnerRenameInReShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
Filesystem::rename('/sub1/sub2/folder/inside/file.txt', '/sub1/sub2/folder/inside/renamed.txt');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -161,7 +224,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testOwnerRenameIntoReShare() {
+ public function testOwnerRenameIntoReShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
Filesystem::rename('/sub1/sub2/folder/file.txt', '/sub1/sub2/folder/inside/renamed.txt');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -170,7 +233,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testOwnerRenameOutOfReShare() {
+ public function testOwnerRenameOutOfReShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
Filesystem::rename('/sub1/sub2/folder/inside/file.txt', '/sub1/sub2/folder/renamed.txt');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -179,7 +242,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testOwnerDeleteInShare() {
+ public function testOwnerDeleteInShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
Filesystem::unlink('/sub1/sub2/folder/file.txt');
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
@@ -189,7 +252,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testOwnerDeleteInReShare() {
+ public function testOwnerDeleteInReShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
Filesystem::unlink('/sub1/sub2/folder/inside/file.txt');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -198,55 +261,78 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testOwnerUnshares() {
+ public function testOwnerUnshares(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
$folderInfo = $this->rootView->getFileInfo('/' . self::TEST_FILES_SHARING_API_USER1 . '/files/sub1/sub2/folder');
$this->assertInstanceOf('\OC\Files\FileInfo', $folderInfo);
- $folderId = $folderInfo->getId();
- $this->assertTrue(
- \OCP\Share::unshare(
- 'folder',
- $folderId,
- \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2
- )
- );
+
+ $node = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1)->get('/sub1/sub2/folder');
+ $shareManager = Server::get(\OCP\Share\IManager::class);
+ $shares = $shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER1, IShare::TYPE_USER, $node, true);
+
+ foreach ($shares as $share) {
+ if ($share->getSharedWith() === self::TEST_FILES_SHARING_API_USER2) {
+ $shareManager->deleteShare($share);
+ }
+ }
+
$this->assertEtagsForFoldersChanged([
// direct recipient affected
self::TEST_FILES_SHARING_API_USER2,
- // reshare recipient affected
+ ]);
+
+ $this->assertAllUnchanged();
+ }
+
+ public function testOwnerUnsharesFlatReshares(): void {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ $folderInfo = $this->rootView->getFileInfo('/' . self::TEST_FILES_SHARING_API_USER1 . '/files/sub1/sub2/folder/inside');
+ $this->assertInstanceOf('\OC\Files\FileInfo', $folderInfo);
+
+ $node = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1)->get('/sub1/sub2/folder/inside');
+ $shareManager = Server::get(\OCP\Share\IManager::class);
+ $shares = $shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER1, IShare::TYPE_USER, $node, true);
+
+ foreach ($shares as $share) {
+ $shareManager->deleteShare($share);
+ }
+
+ $this->assertEtagsForFoldersChanged([
+ // direct recipient affected
self::TEST_FILES_SHARING_API_USER4,
]);
$this->assertAllUnchanged();
}
- public function testRecipientUnsharesFromSelf() {
+ public function testRecipientUnsharesFromSelf(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ $ls = $this->rootView->getDirectoryContent('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/sub1/sub2/');
$this->assertTrue(
$this->rootView->unlink('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/sub1/sub2/folder')
);
$this->assertEtagsForFoldersChanged([
// direct recipient affected
self::TEST_FILES_SHARING_API_USER2,
- // reshare recipient affected
- self::TEST_FILES_SHARING_API_USER4,
]);
$this->assertAllUnchanged();
}
- public function testRecipientWritesToShare() {
+ public function testRecipientWritesToShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
Filesystem::file_put_contents('/sub1/sub2/folder/asd.txt', 'bar');
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
- $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
- self::TEST_FILES_SHARING_API_USER3]);
+ $this->assertEtagsForFoldersChanged([
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3
+ ]);
$this->assertAllUnchanged();
}
- public function testRecipientWritesToReshare() {
+ public function testRecipientWritesToReshare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
Filesystem::file_put_contents('/sub1/sub2/folder/inside/asd.txt', 'bar');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -255,7 +341,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testRecipientWritesToOtherRecipientsReshare() {
+ public function testRecipientWritesToOtherRecipientsReshare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER3);
Filesystem::file_put_contents('/sub1/sub2/folder/inside/asd.txt', 'bar');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -264,7 +350,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testRecipientRenameInShare() {
+ public function testRecipientRenameInShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
Filesystem::rename('/sub1/sub2/folder/file.txt', '/sub1/sub2/folder/renamed.txt');
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
@@ -274,7 +360,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testRecipientRenameInReShare() {
+ public function testRecipientRenameInReShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
Filesystem::rename('/sub1/sub2/folder/inside/file.txt', '/sub1/sub2/folder/inside/renamed.txt');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -283,7 +369,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testRecipientRenameResharedFolder() {
+ public function testRecipientRenameResharedFolder(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
Filesystem::rename('/directReshare', '/sub1/directReshare');
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
@@ -294,7 +380,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testRecipientDeleteInShare() {
+ public function testRecipientDeleteInShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
Filesystem::unlink('/sub1/sub2/folder/file.txt');
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
@@ -304,7 +390,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testRecipientDeleteInReShare() {
+ public function testRecipientDeleteInReShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
Filesystem::unlink('/sub1/sub2/folder/inside/file.txt');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -313,7 +399,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testReshareRecipientWritesToReshare() {
+ public function testReshareRecipientWritesToReshare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
Filesystem::file_put_contents('/sub1/sub2/inside/asd.txt', 'bar');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -322,7 +408,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testReshareRecipientRenameInReShare() {
+ public function testReshareRecipientRenameInReShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
Filesystem::rename('/sub1/sub2/inside/file.txt', '/sub1/sub2/inside/renamed.txt');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -331,7 +417,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testReshareRecipientDeleteInReShare() {
+ public function testReshareRecipientDeleteInReShare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
Filesystem::unlink('/sub1/sub2/inside/file.txt');
$this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
@@ -340,7 +426,7 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testRecipientUploadInDirectReshare() {
+ public function testRecipientUploadInDirectReshare(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
Filesystem::file_put_contents('/directReshare/test.txt', 'sad');
$this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER3]);
@@ -349,15 +435,22 @@ class EtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testEtagChangeOnPermissionsChange() {
- $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ public function testEtagChangeOnPermissionsChange(): void {
+ $userFolder = $this->rootFolder->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
+ $node = $userFolder->get('/sub1/sub2/folder');
- $view = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
- $folderInfo = $view->getFileInfo('/sub1/sub2/folder');
+ $shares = $this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER1, IShare::TYPE_USER, $node);
+ /** @var IShare[] $shares */
+ $shares = array_filter($shares, function (IShare $share) {
+ return $share->getSharedWith() === self::TEST_FILES_SHARING_API_USER2;
+ });
+ $this->assertCount(1, $shares);
- \OCP\Share::setPermissions('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 17);
+ $share = $shares[0];
+ $share->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE);
+ $this->shareManager->updateShare($share);
- $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_USER4]);
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER2]);
$this->assertAllUnchanged();
}
diff --git a/apps/files_sharing/tests/expiresharesjobtest.php b/apps/files_sharing/tests/ExpireSharesJobTest.php
index bb4f756e6c7..42bc5a4b659 100644
--- a/apps/files_sharing/tests/expiresharesjobtest.php
+++ b/apps/files_sharing/tests/ExpireSharesJobTest.php
@@ -1,28 +1,21 @@
<?php
+
/**
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * 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;
+use OC\SystemConfig;
use OCA\Files_Sharing\ExpireSharesJob;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Constants;
+use OCP\IDBConnection;
+use OCP\IUserManager;
+use OCP\Server;
+use OCP\Share\IManager;
+use OCP\Share\IShare;
/**
* Class ExpireSharesJobTest
@@ -33,55 +26,47 @@ use OCA\Files_Sharing\ExpireSharesJob;
*/
class ExpireSharesJobTest extends \Test\TestCase {
- /**
- * @var ExpireSharesJob
- */
+ /** @var ExpireSharesJob */
private $job;
- /**
- * @var \OCP\IDBConnection
- */
+ /** @var IDBConnection */
private $connection;
- /**
- * @var string
- */
+ /** @var string */
private $user1;
- /**
- * @var string
- */
+ /** @var string */
private $user2;
- protected function setup() {
+ protected function setUp(): void {
parent::setUp();
- $this->connection = \OC::$server->getDatabaseConnection();
+ $this->connection = Server::get(IDBConnection::class);
// clear occasional leftover shares from other tests
$this->connection->executeUpdate('DELETE FROM `*PREFIX*share`');
$this->user1 = $this->getUniqueID('user1_');
$this->user2 = $this->getUniqueID('user2_');
- $userManager = \OC::$server->getUserManager();
- $userManager->createUser($this->user1, 'pass');
- $userManager->createUser($this->user2, 'pass');
+ $userManager = Server::get(IUserManager::class);
+ $userManager->createUser($this->user1, 'longrandompassword');
+ $userManager->createUser($this->user2, 'longrandompassword');
- \OC::registerShareHooks();
+ \OC::registerShareHooks(Server::get(SystemConfig::class));
- $this->job = new ExpireSharesJob();
+ $this->job = new ExpireSharesJob(Server::get(ITimeFactory::class), Server::get(IManager::class), $this->connection);
}
- protected function tearDown() {
+ protected function tearDown(): void {
$this->connection->executeUpdate('DELETE FROM `*PREFIX*share`');
- $userManager = \OC::$server->getUserManager();
+ $userManager = Server::get(IUserManager::class);
$user1 = $userManager->get($this->user1);
- if($user1) {
+ if ($user1) {
$user1->delete();
}
$user2 = $userManager->get($this->user2);
- if($user2) {
+ if ($user2) {
$user2->delete();
}
@@ -105,7 +90,7 @@ class ExpireSharesJobTest extends \Test\TestCase {
return $shares;
}
- public function dataExpireLinkShare() {
+ public static function dataExpireLinkShare() {
return [
[false, '', false, false],
[false, '', true, false],
@@ -121,25 +106,28 @@ class ExpireSharesJobTest extends \Test\TestCase {
}
/**
- * @dataProvider dataExpireLinkShare
*
* @param bool addExpiration Should we add an expire date
* @param string $interval The dateInterval
* @param bool $addInterval If true add to the current time if false subtract
* @param bool $shouldExpire Should this share be expired
*/
- public function testExpireLinkShare($addExpiration, $interval, $addInterval, $shouldExpire) {
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataExpireLinkShare')]
+ public function testExpireLinkShare($addExpiration, $interval, $addInterval, $shouldExpire): void {
$this->loginAsUser($this->user1);
- $view = new \OC\Files\View('/' . $this->user1 . '/');
- $view->mkdir('files/test');
+ $user1Folder = \OC::$server->getUserFolder($this->user1);
+ $testFolder = $user1Folder->newFolder('test');
+
+ $shareManager = Server::get(\OCP\Share\IManager::class);
+ $share = $shareManager->newShare();
- $fileInfo = $view->getFileInfo('files/test');
+ $share->setNode($testFolder)
+ ->setShareType(IShare::TYPE_LINK)
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setSharedBy($this->user1);
- $this->assertNotNull(
- \OCP\Share::shareItem('folder', $fileInfo->getId(), \OCP\Share::SHARE_TYPE_LINK, null, \OCP\Constants::PERMISSION_READ),
- 'Failed asserting that user 1 successfully shared "test" by link.'
- );
+ $shareManager->createShare($share);
$shares = $this->getShares();
$this->assertCount(1, $shares);
@@ -182,23 +170,25 @@ class ExpireSharesJobTest extends \Test\TestCase {
}
}
- public function testDoNotExpireOtherShares() {
+ public function testDoNotExpireOtherShares(): void {
$this->loginAsUser($this->user1);
- $view = new \OC\Files\View('/' . $this->user1 . '/');
- $view->mkdir('files/test');
+ $user1Folder = \OC::$server->getUserFolder($this->user1);
+ $testFolder = $user1Folder->newFolder('test');
- $fileInfo = $view->getFileInfo('files/test');
+ $shareManager = Server::get(\OCP\Share\IManager::class);
+ $share = $shareManager->newShare();
- $this->assertNotNull(
- \OCP\Share::shareItem('folder', $fileInfo->getId(), \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ),
- 'Failed asserting that user 1 successfully shared "test" by link with user2.'
- );
+ $share->setNode($testFolder)
+ ->setShareType(IShare::TYPE_USER)
+ ->setPermissions(Constants::PERMISSION_READ)
+ ->setSharedBy($this->user1)
+ ->setSharedWith($this->user2);
+
+ $shareManager->createShare($share);
$shares = $this->getShares();
$this->assertCount(1, $shares);
- reset($shares);
- $share = current($shares);
$this->logout();
@@ -207,6 +197,4 @@ class ExpireSharesJobTest extends \Test\TestCase {
$shares = $this->getShares();
$this->assertCount(1, $shares);
}
-
}
-
diff --git a/apps/files_sharing/tests/External/CacheTest.php b/apps/files_sharing/tests/External/CacheTest.php
new file mode 100644
index 00000000000..39e2057a24c
--- /dev/null
+++ b/apps/files_sharing/tests/External/CacheTest.php
@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * 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
+ *
+ * @group DB
+ *
+ * @package OCA\Files_Sharing\Tests\External
+ */
+class CacheTest extends TestCase {
+ /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
+ protected $contactsManager;
+
+ /**
+ * @var Storage
+ **/
+ private $storage;
+
+ /**
+ * @var Cache
+ */
+ private $cache;
+
+ /**
+ * @var string
+ */
+ private $remoteUser;
+
+ /** @var ICloudIdManager */
+ private $cloudIdManager;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->contactsManager = $this->createMock(IManager::class);
+
+ $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')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->storage
+ ->expects($this->any())
+ ->method('getId')
+ ->willReturn('dummystorage::');
+
+ $this->contactsManager->expects($this->any())
+ ->method('search')
+ ->willReturn([]);
+
+ $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',
+ [
+ 'mimetype' => 'text/plain',
+ 'size' => 5,
+ 'mtime' => 123,
+ ]
+ );
+ }
+
+ protected function tearDown(): void {
+ if ($this->cache) {
+ $this->cache->clear();
+ }
+ parent::tearDown();
+ }
+
+ public function testGetInjectsOwnerDisplayName(): void {
+ $info = $this->cache->get('test.txt');
+ $this->assertEquals(
+ $this->remoteUser . '@example.com/owncloud',
+ $info['displayname_owner']
+ );
+ }
+
+ public function testGetReturnsFalseIfNotFound(): void {
+ $info = $this->cache->get('unexisting-entry.txt');
+ $this->assertFalse($info);
+ }
+
+ public function testGetFolderPopulatesOwner(): void {
+ $dirId = $this->cache->put(
+ 'subdir',
+ [
+ 'mimetype' => 'httpd/unix-directory',
+ 'size' => 5,
+ 'mtime' => 123,
+ ]
+ );
+ $this->cache->put(
+ 'subdir/contents.txt',
+ [
+ 'mimetype' => 'text/plain',
+ 'size' => 5,
+ 'mtime' => 123,
+ ]
+ );
+
+ $results = $this->cache->getFolderContentsById($dirId);
+ $this->assertEquals(1, count($results));
+ $this->assertEquals(
+ $this->remoteUser . '@example.com/owncloud',
+ $results[0]['displayname_owner']
+ );
+ }
+}
diff --git a/apps/files_sharing/tests/External/ManagerTest.php b/apps/files_sharing/tests/External/ManagerTest.php
new file mode 100644
index 00000000000..14c6afec4d8
--- /dev/null
+++ b/apps/files_sharing/tests/External/ManagerTest.php
@@ -0,0 +1,730 @@
+<?php
+
+/**
+ * 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;
+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;
+
+/**
+ * Class ManagerTest
+ *
+ * @group DB
+ *
+ * @package OCA\Files_Sharing\Tests\External
+ */
+class ManagerTest extends TestCase {
+ use UserTrait;
+
+ 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->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);
+ $this->cloudFederationFactory = $this->createMock(ICloudFederationFactory::class);
+ $this->groupManager = $this->createMock(IGroupManager::class);
+ $this->userManager = $this->createMock(IUserManager::class);
+ $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+
+ $this->contactsManager = $this->createMock(IManager::class);
+ // needed for MountProvider() initialization
+ $this->contactsManager->expects($this->any())
+ ->method('search')
+ ->willReturn([]);
+
+ $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(
+ [
+ Server::get(IDBConnection::class),
+ $this->mountManager,
+ new StorageFactory(),
+ $this->clientService,
+ Server::get(\OCP\Notification\IManager::class),
+ Server::get(IDiscoveryService::class),
+ $this->cloudFederationProviderManager,
+ $this->cloudFederationFactory,
+ $this->groupManager,
+ $this->userManager,
+ $userSession,
+ $this->eventDispatcher,
+ $this->logger,
+ ]
+ )->onlyMethods(['tryOCMEndPoint'])->getMock();
+ }
+
+ private function setupMounts() {
+ $this->clearMounts();
+ $mounts = $this->testMountProvider->getMountsForUser($this->user, new StorageFactory());
+ foreach ($mounts as $mount) {
+ $this->mountManager->addMount($mount);
+ }
+ }
+
+ 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' => '',
+ 'name' => '/SharedFolder',
+ 'owner' => 'foobar',
+ 'shareType' => IShare::TYPE_USER,
+ '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';
+
+ 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'] . '}}', $shareData1['user']);
+
+ $this->setupMounts();
+ $this->assertNotMount('SharedFolder');
+ $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
+
+ // Add a second share for "user" with the same name
+ $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'] . '}}', $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', $shareData2['user']);
+
+ $this->setupMounts();
+ $this->assertNotMount('SharedFolder');
+ $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
+ $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1');
+
+ $newClientCalls = [];
+ $this->clientService
+ ->method('newClient')
+ ->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);
+ }
+
+ // Accept the first share
+ $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->uid);
+ // Check remaining shares - Open
+ $openShares = $this->manager->getOpenShares();
+ $this->assertCount(1, $openShares);
+ $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1', $shareData2['user']);
+
+ $this->setupMounts();
+ $this->assertMount($shareData1['name']);
+ $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
+ $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1');
+
+ // Add another share for "user" with the same name
+ $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', $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');
+
+ 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);
+ }
+
+ // Decline the third share
+ $this->assertTrue($this->manager->declineShare($openShares[1]['id']));
+
+ $this->setupMounts();
+ $this->assertMount($shareData1['name']);
+ $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
+ $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1');
+
+ // 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->uid);
+ // Check remaining shares - Open
+ $openShares = $this->manager->getOpenShares();
+ 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');
+
+ 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);
+
+ $this->manager->removeUserShares($this->uid);
+ }
+
+ $this->assertEmpty(self::invokePrivate($this->manager, 'getShares', [null]), 'Asserting all shares for the user have been deleted');
+
+ $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, $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($targetEntity, $actual['user'], 'Asserting user of a share #' . $share);
+ $this->assertEquals($mountPoint, $actual['mountpoint'], 'Asserting mountpoint of a share #' . $share);
+ }
+
+ private function assertMount($mountPoint) {
+ $mountPoint = rtrim($mountPoint, '/');
+ $mount = $this->mountManager->find($this->getFullPath($mountPoint));
+ $this->assertInstanceOf('\OCA\Files_Sharing\External\Mount', $mount);
+ $this->assertInstanceOf('\OCP\Files\Mount\IMountPoint', $mount);
+ $this->assertEquals($this->getFullPath($mountPoint), rtrim($mount->getMountPoint(), '/'));
+ $storage = $mount->getStorage();
+ $this->assertInstanceOf('\OCA\Files_Sharing\External\Storage', $storage);
+ }
+
+ private function assertNotMount($mountPoint) {
+ $mountPoint = rtrim($mountPoint, '/');
+ try {
+ $mount = $this->mountManager->find($this->getFullPath($mountPoint));
+ $this->assertInstanceOf('\OCP\Files\Mount\IMountPoint', $mount);
+ $this->assertNotEquals($this->getFullPath($mountPoint), rtrim($mount->getMountPoint(), '/'));
+ } catch (NotFoundException $e) {
+
+ }
+ }
+
+ private function getFullPath($path) {
+ return '/' . $this->uid . '/files' . $path;
+ }
+}
diff --git a/apps/files_sharing/tests/External/ScannerTest.php b/apps/files_sharing/tests/External/ScannerTest.php
new file mode 100644
index 00000000000..8b44d47f2b1
--- /dev/null
+++ b/apps/files_sharing/tests/External/ScannerTest.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * 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 {
+ protected Scanner $scanner;
+ /** @var Storage|\PHPUnit\Framework\MockObject\MockObject */
+ protected $storage;
+ /** @var Cache|\PHPUnit\Framework\MockObject\MockObject */
+ protected $cache;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->storage = $this->getMockBuilder('\OCA\Files_Sharing\External\Storage')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->storage->expects($this->any())
+ ->method('getCache')
+ ->willReturn($this->cache);
+
+ $this->scanner = new Scanner($this->storage);
+ }
+
+ public function testScan(): void {
+ $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->scan('test', Scanner::SCAN_RECURSIVE);
+ $this->addToAssertionCount(1);
+ }
+
+ 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::*()
+ $this->scanner->scanFile('test', Scanner::SCAN_RECURSIVE);
+ $this->addToAssertionCount(1);
+ }
+}
diff --git a/apps/files_sharing/tests/ExternalStorageTest.php b/apps/files_sharing/tests/ExternalStorageTest.php
new file mode 100644
index 00000000000..1d9d2eed7bd
--- /dev/null
+++ b/apps/files_sharing/tests/ExternalStorageTest.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Federation\CloudId;
+use OCA\Files_Sharing\External\Manager as ExternalShareManager;
+use OCA\Files_Sharing\External\Storage;
+use OCP\Http\Client\IClient;
+use OCP\Http\Client\IClientService;
+use OCP\Http\Client\IResponse;
+
+/**
+ * Tests for the external Storage class for remote shares.
+ *
+ * @group DB
+ */
+class ExternalStorageTest extends \Test\TestCase {
+ public static function optionsProvider() {
+ return [
+ [
+ 'http://remoteserver:8080/owncloud',
+ 'http://remoteserver:8080/owncloud/public.php/webdav/',
+ ],
+ // extra slash
+ [
+ 'http://remoteserver:8080/owncloud/',
+ 'http://remoteserver:8080/owncloud/public.php/webdav/',
+ ],
+ // extra path
+ [
+ 'http://remoteserver:8080/myservices/owncloud/',
+ 'http://remoteserver:8080/myservices/owncloud/public.php/webdav/',
+ ],
+ // root path
+ [
+ 'http://remoteserver:8080/',
+ 'http://remoteserver:8080/public.php/webdav/',
+ ],
+ // without port
+ [
+ 'http://remoteserver/oc.test',
+ 'http://remoteserver/oc.test/public.php/webdav/',
+ ],
+ // https
+ [
+ 'https://remoteserver/',
+ 'https://remoteserver/public.php/webdav/',
+ ],
+ ];
+ }
+
+ private function getTestStorage($uri) {
+ $certificateManager = \OC::$server->getCertificateManager();
+ $httpClientService = $this->createMock(IClientService::class);
+ $manager = $this->createMock(ExternalShareManager::class);
+ $client = $this->createMock(IClient::class);
+ $response = $this->createMock(IResponse::class);
+ $client
+ ->expects($this->any())
+ ->method('get')
+ ->willReturn($response);
+ $client
+ ->expects($this->any())
+ ->method('post')
+ ->willReturn($response);
+ $httpClientService
+ ->expects($this->any())
+ ->method('newClient')
+ ->willReturn($client);
+
+ return new TestSharingExternalStorage(
+ [
+ 'cloudId' => new CloudId('testOwner@' . $uri, 'testOwner', $uri),
+ 'remote' => $uri,
+ 'owner' => 'testOwner',
+ 'mountpoint' => 'remoteshare',
+ 'token' => 'abcdef',
+ 'password' => '',
+ 'manager' => $manager,
+ 'certificateManager' => $certificateManager,
+ 'HttpClientService' => $httpClientService,
+ ]
+ );
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('optionsProvider')]
+ public function testStorageMountOptions($inputUri, $baseUri): void {
+ $storage = $this->getTestStorage($inputUri);
+ $this->assertEquals($baseUri, $storage->getBaseUri());
+ }
+
+ public function testIfTestReturnsTheValue(): void {
+ $storage = $this->getTestStorage('https://remoteserver');
+ $result = $storage->test();
+ $this->assertSame(true, $result);
+ }
+}
+
+/**
+ * Dummy subclass to make it possible to access private members
+ */
+class TestSharingExternalStorage extends Storage {
+ public function getBaseUri() {
+ return $this->createBaseUri();
+ }
+
+ public function stat(string $path): array|false {
+ if ($path === '') {
+ return ['key' => 'value'];
+ }
+ return parent::stat($path);
+ }
+}
diff --git a/apps/files_sharing/tests/groupetagpropagation.php b/apps/files_sharing/tests/GroupEtagPropagationTest.php
index 9f6b1e2f720..da9c7c6bd07 100644
--- a/apps/files_sharing/tests/groupetagpropagation.php
+++ b/apps/files_sharing/tests/GroupEtagPropagationTest.php
@@ -1,35 +1,23 @@
<?php
+
/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * 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;
+namespace OCA\Files_Sharing\Tests;
use OC\Files\Filesystem;
use OC\Files\View;
+use OCP\Constants;
+use OCP\Share\IShare;
/**
- * @group DB
+ * @group SLOWDB
*
- * @package OCA\Files_sharing\Tests
+ * @package OCA\Files_Sharing\Tests
*/
-class GroupEtagPropagation extends PropagationTestCase {
+class GroupEtagPropagationTest extends PropagationTestCase {
/**
* "user1" creates /test, /test/sub and shares with group1
* "user2" (in group1) reshares /test with group2 and reshared /test/sub with group3
@@ -46,18 +34,39 @@ class GroupEtagPropagation extends PropagationTestCase {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
$view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
$view1->mkdir('/test/sub');
- $folderInfo = $view1->getFileInfo('/test');
- \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_GROUP, 'group1', 31);
+
+ $share = $this->share(
+ IShare::TYPE_GROUP,
+ '/test',
+ self::TEST_FILES_SHARING_API_USER1,
+ 'group1',
+ Constants::PERMISSION_ALL
+ );
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER2);
$this->fileIds[self::TEST_FILES_SHARING_API_USER1][''] = $view1->getFileInfo('')->getId();
$this->fileIds[self::TEST_FILES_SHARING_API_USER1]['test'] = $view1->getFileInfo('test')->getId();
$this->fileIds[self::TEST_FILES_SHARING_API_USER1]['test/sub'] = $view1->getFileInfo('test/sub')->getId();
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
$view2 = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
- $folderInfo = $view2->getFileInfo('/test');
- $subFolderInfo = $view2->getFileInfo('/test/sub');
- \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_GROUP, 'group2', 31);
- \OCP\Share::shareItem('folder', $subFolderInfo->getId(), \OCP\Share::SHARE_TYPE_GROUP, 'group3', 31);
+
+ $share = $this->share(
+ IShare::TYPE_GROUP,
+ '/test',
+ self::TEST_FILES_SHARING_API_USER2,
+ 'group2',
+ Constants::PERMISSION_ALL
+ );
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER3);
+ $share = $this->share(
+ IShare::TYPE_GROUP,
+ '/test/sub',
+ self::TEST_FILES_SHARING_API_USER2,
+ 'group3',
+ Constants::PERMISSION_ALL
+ );
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER4);
+
$this->fileIds[self::TEST_FILES_SHARING_API_USER2][''] = $view2->getFileInfo('')->getId();
$this->fileIds[self::TEST_FILES_SHARING_API_USER2]['test'] = $view2->getFileInfo('test')->getId();
$this->fileIds[self::TEST_FILES_SHARING_API_USER2]['test/sub'] = $view2->getFileInfo('test/sub')->getId();
@@ -82,7 +91,7 @@ class GroupEtagPropagation extends PropagationTestCase {
}
}
- public function testGroupReShareRecipientWrites() {
+ public function testGroupReShareRecipientWrites(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER3);
Filesystem::file_put_contents('/test/sub/file.txt', 'asd');
@@ -92,7 +101,7 @@ class GroupEtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
- public function testGroupReShareSubFolderRecipientWrites() {
+ public function testGroupReShareSubFolderRecipientWrites(): void {
$this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
Filesystem::file_put_contents('/sub/file.txt', 'asd');
@@ -101,4 +110,26 @@ class GroupEtagPropagation extends PropagationTestCase {
$this->assertAllUnchanged();
}
+
+ public function testRecipientUnsharesFromSelf(): void {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertTrue(
+ $this->rootView->unlink('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/test')
+ );
+ $this->assertEtagsChanged([self::TEST_FILES_SHARING_API_USER2]);
+
+ $this->assertAllUnchanged();
+ }
+
+ public function testRecipientUnsharesFromSelfUniqueGroupShare(): void {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ // rename to create an extra entry in the share table
+ $this->rootView->rename('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/test', '/' . self::TEST_FILES_SHARING_API_USER2 . '/files/test_renamed');
+ $this->assertTrue(
+ $this->rootView->unlink('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/test_renamed')
+ );
+ $this->assertEtagsChanged([self::TEST_FILES_SHARING_API_USER2]);
+
+ $this->assertAllUnchanged();
+ }
}
diff --git a/apps/files_sharing/tests/HelperTest.php b/apps/files_sharing/tests/HelperTest.php
new file mode 100644
index 00000000000..4d0d747b3e4
--- /dev/null
+++ b/apps/files_sharing/tests/HelperTest.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\Filesystem;
+use OCA\Files_Sharing\Helper;
+use OCP\IConfig;
+use OCP\Server;
+
+/**
+ * Class HelperTest
+ *
+ * @group DB
+ */
+class HelperTest extends TestCase {
+
+ /**
+ * test set and get share folder
+ */
+ public function testSetGetShareFolder(): void {
+ $this->assertSame('/', Helper::getShareFolder());
+
+ Helper::setShareFolder('/Shared/Folder');
+
+ $sharedFolder = Helper::getShareFolder();
+ $this->assertSame('/Shared/Folder', Helper::getShareFolder());
+ $this->assertTrue(Filesystem::is_dir($sharedFolder));
+
+ // cleanup
+ Server::get(IConfig::class)->deleteSystemValue('share_folder');
+ }
+}
diff --git a/apps/files_sharing/tests/Listener/LoadAdditionalListenerTest.php b/apps/files_sharing/tests/Listener/LoadAdditionalListenerTest.php
new file mode 100644
index 00000000000..75bee35d58a
--- /dev/null
+++ b/apps/files_sharing/tests/Listener/LoadAdditionalListenerTest.php
@@ -0,0 +1,120 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\Files_Sharing\Tests\Listener;
+
+use OC\InitialStateService;
+use OCA\Files\Event\LoadAdditionalScriptsEvent;
+use OCA\Files_Sharing\Listener\LoadAdditionalListener;
+use OCP\EventDispatcher\Event;
+use OCP\IConfig;
+use OCP\L10N\IFactory;
+use OCP\Share\IManager;
+use OCP\Util;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\LoggerInterface;
+use Test\TestCase;
+
+class LoadAdditionalListenerTest extends TestCase {
+ protected LoggerInterface&MockObject $logger;
+ protected LoadAdditionalScriptsEvent&MockObject $event;
+ protected IManager&MockObject $shareManager;
+ protected IFactory&MockObject $factory;
+ protected InitialStateService&MockObject $initialStateService;
+ protected IConfig&MockObject $config;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->logger = $this->createMock(LoggerInterface::class);
+ $this->event = $this->createMock(LoadAdditionalScriptsEvent::class);
+ $this->shareManager = $this->createMock(IManager::class);
+ $this->factory = $this->createMock(IFactory::class);
+ $this->initialStateService = $this->createMock(InitialStateService::class);
+ $this->config = $this->createMock(IConfig::class);
+
+ /* Empty static array to avoid inter-test conflicts */
+ \OC_Util::$styles = [];
+ self::invokePrivate(Util::class, 'scripts', [[]]);
+ self::invokePrivate(Util::class, 'scriptDeps', [[]]);
+ self::invokePrivate(Util::class, 'scriptsInit', [[]]);
+ }
+
+ protected function tearDown(): void {
+ parent::tearDown();
+
+ \OC_Util::$styles = [];
+ self::invokePrivate(Util::class, 'scripts', [[]]);
+ self::invokePrivate(Util::class, 'scriptDeps', [[]]);
+ self::invokePrivate(Util::class, 'scriptsInit', [[]]);
+ }
+
+ public function testHandleIgnoresNonMatchingEvent(): void {
+ $listener = new LoadAdditionalListener();
+ $event = $this->createMock(Event::class);
+
+ // Should not throw or call anything
+ $listener->handle($event);
+
+ $this->assertTrue(true); // No exception means pass
+ }
+
+ public function testHandleWithLoadAdditionalScriptsEvent(): void {
+ $listener = new LoadAdditionalListener();
+
+ $this->shareManager->method('shareApiEnabled')->willReturn(false);
+ $this->factory->method('findLanguage')->willReturn('language_mock');
+ $this->config->method('getSystemValueBool')->willReturn(true);
+
+ $this->overwriteService(IManager::class, $this->shareManager);
+ $this->overwriteService(IFactory::class, $this->factory);
+ $this->overwriteService(InitialStateService::class, $this->initialStateService);
+ $this->overwriteService(IConfig::class, $this->config);
+
+ $scriptsBefore = Util::getScripts();
+ $this->assertNotContains('files_sharing/l10n/language_mock', $scriptsBefore);
+ $this->assertNotContains('files_sharing/js/additionalScripts', $scriptsBefore);
+ $this->assertNotContains('files_sharing/js/init', $scriptsBefore);
+ $this->assertNotContains('files_sharing/css/icons', \OC_Util::$styles);
+
+ // Util static methods can't be easily mocked, so just ensure no exceptions
+ $listener->handle($this->event);
+
+ // assert array $scripts contains the expected scripts
+ $scriptsAfter = Util::getScripts();
+ $this->assertContains('files_sharing/l10n/language_mock', $scriptsAfter);
+ $this->assertContains('files_sharing/js/additionalScripts', $scriptsAfter);
+ $this->assertNotContains('files_sharing/js/init', $scriptsAfter);
+
+ $this->assertContains('files_sharing/css/icons', \OC_Util::$styles);
+ }
+
+ public function testHandleWithLoadAdditionalScriptsEventWithShareApiEnabled(): void {
+ $listener = new LoadAdditionalListener();
+
+ $this->shareManager->method('shareApiEnabled')->willReturn(true);
+ $this->config->method('getSystemValueBool')->willReturn(true);
+
+ $this->overwriteService(IManager::class, $this->shareManager);
+ $this->overwriteService(InitialStateService::class, $this->initialStateService);
+ $this->overwriteService(IConfig::class, $this->config);
+ $this->overwriteService(IFactory::class, $this->factory);
+
+ $scriptsBefore = Util::getScripts();
+ $this->assertNotContains('files_sharing/js/init', $scriptsBefore);
+
+ // Util static methods can't be easily mocked, so just ensure no exceptions
+ $listener->handle($this->event);
+
+ $scriptsAfter = Util::getScripts();
+
+ // assert array $scripts contains the expected scripts
+ $this->assertContains('files_sharing/js/init', $scriptsAfter);
+ }
+}
diff --git a/apps/files_sharing/tests/locking.php b/apps/files_sharing/tests/LockingTest.php
index ef8b2bb1cd4..280c364a136 100644
--- a/apps/files_sharing/tests/locking.php
+++ b/apps/files_sharing/tests/LockingTest.php
@@ -1,40 +1,29 @@
<?php
+
/**
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * 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;
+namespace OCA\Files_Sharing\Tests;
use OC\Files\Filesystem;
use OC\Files\View;
+use OCP\Constants;
+use OCP\IUserManager;
use OCP\Lock\ILockingProvider;
+use OCP\Lock\LockedException;
+use OCP\Server;
+use OCP\Share\IShare;
/**
- * Class Locking
+ * Class LockingTest
*
* @group DB
*
- * @package OCA\Files_sharing\Tests
+ * @package OCA\Files_Sharing\Tests
*/
-class Locking extends TestCase {
+class LockingTest extends TestCase {
/**
* @var \Test\Util\User\Dummy
*/
@@ -43,11 +32,11 @@ class Locking extends TestCase {
private $ownerUid;
private $recipientUid;
- public function setUp() {
+ protected function setUp(): void {
parent::setUp();
$this->userBackend = new \Test\Util\User\Dummy();
- \OC::$server->getUserManager()->registerBackend($this->userBackend);
+ Server::get(IUserManager::class)->registerBackend($this->userBackend);
$this->ownerUid = $this->getUniqueID('owner_');
$this->recipientUid = $this->getUniqueID('recipient_');
@@ -59,21 +48,27 @@ class Locking extends TestCase {
Filesystem::file_put_contents('/foo/bar.txt', 'asd');
$fileId = Filesystem::getFileInfo('/foo/bar.txt')->getId();
- \OCP\Share::shareItem('file', $fileId, \OCP\Share::SHARE_TYPE_USER, $this->recipientUid, 31);
+ $this->share(
+ IShare::TYPE_USER,
+ '/foo/bar.txt',
+ $this->ownerUid,
+ $this->recipientUid,
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
+ );
$this->loginAsUser($this->recipientUid);
$this->assertTrue(Filesystem::file_exists('bar.txt'));
}
- public function tearDown() {
- \OC::$server->getUserManager()->removeBackend($this->userBackend);
+ protected function tearDown(): void {
+ Server::get(IUserManager::class)->removeBackend($this->userBackend);
parent::tearDown();
}
- /**
- * @expectedException \OCP\Lock\LockedException
- */
- public function testLockAsRecipient() {
+
+ public function testLockAsRecipient(): void {
+ $this->expectException(LockedException::class);
+
$this->loginAsUser($this->ownerUid);
Filesystem::initMountPoints($this->recipientUid);
@@ -83,7 +78,7 @@ class Locking extends TestCase {
Filesystem::rename('/foo', '/asd');
}
- public function testUnLockAsRecipient() {
+ public function testUnLockAsRecipient(): void {
$this->loginAsUser($this->ownerUid);
Filesystem::initMountPoints($this->recipientUid);
@@ -94,14 +89,13 @@ class Locking extends TestCase {
$this->assertTrue(Filesystem::rename('/foo', '/asd'));
}
- public function testChangeLock() {
-
+ public function testChangeLock(): void {
Filesystem::initMountPoints($this->recipientUid);
$recipientView = new View('/' . $this->recipientUid . '/files');
$recipientView->lockFile('bar.txt', ILockingProvider::LOCK_SHARED);
$recipientView->changeLock('bar.txt', ILockingProvider::LOCK_EXCLUSIVE);
$recipientView->unlockFile('bar.txt', ILockingProvider::LOCK_EXCLUSIVE);
- $this->assertTrue(true);
+ $this->addToAssertionCount(1);
}
}
diff --git a/apps/files_sharing/tests/Middleware/OCSShareAPIMiddlewareTest.php b/apps/files_sharing/tests/Middleware/OCSShareAPIMiddlewareTest.php
new file mode 100644
index 00000000000..efc6b3f7f7f
--- /dev/null
+++ b/apps/files_sharing/tests/Middleware/OCSShareAPIMiddlewareTest.php
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Sharing\Tests\Middleware;
+
+use OCA\Files_Sharing\Controller\ShareAPIController;
+use OCA\Files_Sharing\Middleware\OCSShareAPIMiddleware;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\OCS\OCSNotFoundException;
+use OCP\AppFramework\OCSController;
+use OCP\IL10N;
+use OCP\Share\IManager;
+
+/**
+ * @package OCA\Files_Sharing\Middleware\SharingCheckMiddleware
+ */
+class OCSShareAPIMiddlewareTest extends \Test\TestCase {
+
+ /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
+ private $shareManager;
+ /** @var IL10N */
+ private $l;
+ /** @var OCSShareAPIMiddleware */
+ private $middleware;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->shareManager = $this->createMock(IManager::class);
+ $this->l = $this->createMock(IL10N::class);
+
+ $this->l->method('t')->willReturnArgument(0);
+
+ $this->middleware = new OCSShareAPIMiddleware($this->shareManager, $this->l);
+ }
+
+ public function dataBeforeController() {
+ return [
+ [
+ $this->createMock(Controller::class),
+ false,
+ false
+ ],
+ [
+ $this->createMock(Controller::class),
+ true,
+ false
+ ],
+ [
+ $this->createMock(OCSController::class),
+ false,
+ false
+ ],
+ [
+ $this->createMock(OCSController::class),
+ true,
+ false
+ ],
+ [
+ $this->createMock(ShareAPIController::class),
+ false,
+ true
+ ],
+ [
+ $this->createMock(ShareAPIController::class),
+ true,
+ false
+ ],
+ ];
+ }
+
+ /**
+ *
+ * @param Controller $controller
+ * @param bool $enabled
+ * @param bool $exception
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataBeforeController')]
+ public function testBeforeController(Controller $controller, $enabled, $exception): void {
+ $this->shareManager->method('shareApiEnabled')->willReturn($enabled);
+
+ try {
+ $this->middleware->beforeController($controller, 'foo');
+ $this->assertFalse($exception);
+ } catch (OCSNotFoundException $e) {
+ $this->assertTrue($exception);
+ }
+ }
+
+ public function dataAfterController() {
+ return [
+ [
+ $this->createMock(Controller::class),
+ ],
+ [
+ $this->createMock(OCSController::class),
+ ],
+ [
+ $this->createMock(ShareAPIController::class),
+ ],
+ ];
+ }
+
+ /**
+ *
+ * @param Controller $controller
+ * @param bool $called
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataAfterController')]
+ public function testAfterController(Controller $controller): void {
+ if ($controller instanceof ShareAPIController) {
+ $controller->expects($this->once())->method('cleanup');
+ }
+
+ $response = $this->getMockBuilder('OCP\AppFramework\Http\Response')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->middleware->afterController($controller, 'foo', $response);
+ $this->addToAssertionCount(1);
+ }
+}
diff --git a/apps/files_sharing/tests/Middleware/ShareInfoMiddlewareTest.php b/apps/files_sharing/tests/Middleware/ShareInfoMiddlewareTest.php
new file mode 100644
index 00000000000..631b6a0f51c
--- /dev/null
+++ b/apps/files_sharing/tests/Middleware/ShareInfoMiddlewareTest.php
@@ -0,0 +1,140 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Sharing\Tests\Middleware;
+
+use OCA\Files_Sharing\Controller\ShareInfoController;
+use OCA\Files_Sharing\Exceptions\S2SException;
+use OCA\Files_Sharing\Middleware\ShareInfoMiddleware;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Http\Response;
+use OCP\Share\IManager as ShareManager;
+use Test\TestCase;
+
+class ShareInfoMiddlewareTest extends TestCase {
+
+ /** @var ShareManager|\PHPUnit\Framework\MockObject\MockObject */
+ private $shareManager;
+
+ /** @var ShareInfoMiddleware */
+ private $middleware;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->shareManager = $this->createMock(ShareManager::class);
+ $this->middleware = new ShareInfoMiddleware($this->shareManager);
+ }
+
+ public function testBeforeControllerNoShareInfo(): void {
+ $this->shareManager->expects($this->never())
+ ->method($this->anything());
+
+ $this->middleware->beforeController($this->createMock(ShareInfoMiddlewareTestController::class), 'foo');
+ }
+
+ public function testBeforeControllerShareInfoNoS2s(): void {
+ $this->shareManager->expects($this->once())
+ ->method('outgoingServer2ServerSharesAllowed')
+ ->willReturn(false);
+
+ $this->expectException(S2SException::class);
+ $this->middleware->beforeController($this->createMock(ShareInfoController::class), 'foo');
+ }
+
+ public function testBeforeControllerShareInfo(): void {
+ $this->shareManager->expects($this->once())
+ ->method('outgoingServer2ServerSharesAllowed')
+ ->willReturn(true);
+
+ $this->middleware->beforeController($this->createMock(ShareInfoController::class), 'foo');
+ }
+
+ public function testAfterExceptionNoShareInfo(): void {
+ $exeption = new \Exception();
+
+ try {
+ $this->middleware->afterException($this->createMock(ShareInfoMiddlewareTestController::class), 'foo', $exeption);
+ $this->fail();
+ } catch (\Exception $e) {
+ $this->assertSame($exeption, $e);
+ }
+ }
+
+
+ public function testAfterExceptionNoS2S(): void {
+ $exeption = new \Exception();
+
+ try {
+ $this->middleware->afterException($this->createMock(ShareInfoController::class), 'foo', $exeption);
+ $this->fail();
+ } catch (\Exception $e) {
+ $this->assertSame($exeption, $e);
+ }
+ }
+
+ public function testAfterExceptionS2S(): void {
+ $expected = new JSONResponse([], Http::STATUS_NOT_FOUND);
+
+ $this->assertEquals(
+ $expected,
+ $this->middleware->afterException($this->createMock(ShareInfoController::class), 'foo', new S2SException())
+ );
+ }
+
+ public function testAfterControllerNoShareInfo(): void {
+ $response = $this->createMock(Response::class);
+
+ $this->assertEquals(
+ $response,
+ $this->middleware->afterController($this->createMock(ShareInfoMiddlewareTestController::class), 'foo', $response)
+ );
+ }
+
+ public function testAfterControllerNoJSON(): void {
+ $response = $this->createMock(Response::class);
+
+ $this->assertEquals(
+ $response,
+ $this->middleware->afterController($this->createMock(ShareInfoController::class), 'foo', $response)
+ );
+ }
+
+ public function testAfterControllerJSONok(): void {
+ $data = ['foo' => 'bar'];
+ $response = new JSONResponse($data);
+
+ $expected = new JSONResponse([
+ 'data' => $data,
+ 'status' => 'success',
+ ]);
+
+ $this->assertEquals(
+ $expected,
+ $this->middleware->afterController($this->createMock(ShareInfoController::class), 'foo', $response)
+ );
+ }
+
+ public function testAfterControllerJSONerror(): void {
+ $data = ['foo' => 'bar'];
+ $response = new JSONResponse($data, Http::STATUS_FORBIDDEN);
+
+ $expected = new JSONResponse([
+ 'data' => $data,
+ 'status' => 'error',
+ ], Http::STATUS_FORBIDDEN);
+
+ $this->assertEquals(
+ $expected,
+ $this->middleware->afterController($this->createMock(ShareInfoController::class), 'foo', $response)
+ );
+ }
+}
+
+class ShareInfoMiddlewareTestController extends Controller {
+}
diff --git a/apps/files_sharing/tests/Middleware/SharingCheckMiddlewareTest.php b/apps/files_sharing/tests/Middleware/SharingCheckMiddlewareTest.php
new file mode 100644
index 00000000000..3d86007a54c
--- /dev/null
+++ b/apps/files_sharing/tests/Middleware/SharingCheckMiddlewareTest.php
@@ -0,0 +1,205 @@
+<?php
+
+/**
+ * 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\Middleware;
+
+use OCA\Files_Sharing\Controller\ExternalSharesController;
+use OCA\Files_Sharing\Controller\ShareController;
+use OCA\Files_Sharing\Exceptions\S2SException;
+use OCP\App\IAppManager;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Http\NotFoundResponse;
+use OCP\AppFramework\Utility\IControllerMethodReflector;
+use OCP\Files\NotFoundException;
+use OCP\IConfig;
+use OCP\IRequest;
+use OCP\Share\IManager;
+use OCP\Share\IShare;
+
+/**
+ * @package OCA\Files_Sharing\Middleware\SharingCheckMiddleware
+ */
+class SharingCheckMiddlewareTest extends \Test\TestCase {
+
+ /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
+ private $config;
+ /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */
+ private $appManager;
+ /** @var SharingCheckMiddleware */
+ private $sharingCheckMiddleware;
+ /** @var Controller|\PHPUnit\Framework\MockObject\MockObject */
+ private $controllerMock;
+ /** @var IControllerMethodReflector|\PHPUnit\Framework\MockObject\MockObject */
+ private $reflector;
+ /** @var IManager | \PHPUnit\Framework\MockObject\MockObject */
+ private $shareManager;
+ /** @var IRequest | \PHPUnit\Framework\MockObject\MockObject */
+ private $request;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->config = $this->createMock(IConfig::class);
+ $this->appManager = $this->createMock(IAppManager::class);
+ $this->controllerMock = $this->createMock(Controller::class);
+ $this->reflector = $this->createMock(IControllerMethodReflector::class);
+ $this->shareManager = $this->createMock(IManager::class);
+ $this->request = $this->createMock(IRequest::class);
+
+ $this->sharingCheckMiddleware = new SharingCheckMiddleware(
+ 'files_sharing',
+ $this->config,
+ $this->appManager,
+ $this->reflector,
+ $this->shareManager,
+ $this->request);
+ }
+
+ public function testIsSharingEnabledWithAppEnabled(): void {
+ $this->appManager
+ ->expects($this->once())
+ ->method('isEnabledForUser')
+ ->with('files_sharing')
+ ->willReturn(true);
+
+ $this->assertTrue(self::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled'));
+ }
+
+ public function testIsSharingEnabledWithAppDisabled(): void {
+ $this->appManager
+ ->expects($this->once())
+ ->method('isEnabledForUser')
+ ->with('files_sharing')
+ ->willReturn(false);
+
+ $this->assertFalse(self::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled'));
+ }
+
+ public static function externalSharesChecksDataProvider() {
+ $data = [];
+
+ foreach ([false, true] as $annIn) {
+ foreach ([false, true] as $annOut) {
+ foreach ([false, true] as $confIn) {
+ foreach ([false, true] as $confOut) {
+ $res = true;
+ if (!$annIn && !$confIn) {
+ $res = false;
+ } elseif (!$annOut && !$confOut) {
+ $res = false;
+ }
+
+ $d = [
+ [
+ ['NoIncomingFederatedSharingRequired', $annIn],
+ ['NoOutgoingFederatedSharingRequired', $annOut],
+ ],
+ [
+ ['files_sharing', 'incoming_server2server_share_enabled', 'yes', $confIn ? 'yes' : 'no'],
+ ['files_sharing', 'outgoing_server2server_share_enabled', 'yes', $confOut ? 'yes' : 'no'],
+ ],
+ $res
+ ];
+
+ $data[] = $d;
+ }
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('externalSharesChecksDataProvider')]
+ public function testExternalSharesChecks($annotations, $config, $expectedResult): void {
+ $this->reflector
+ ->expects($this->atLeastOnce())
+ ->method('hasAnnotation')
+ ->willReturnMap($annotations);
+
+ $this->config
+ ->method('getAppValue')
+ ->willReturnMap($config);
+
+ $this->assertEquals($expectedResult, self::invokePrivate($this->sharingCheckMiddleware, 'externalSharesChecks'));
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('externalSharesChecksDataProvider')]
+ public function testBeforeControllerWithExternalShareControllerWithSharingEnabled($annotations, $config, $noException): void {
+ $this->appManager
+ ->expects($this->once())
+ ->method('isEnabledForUser')
+ ->with('files_sharing')
+ ->willReturn(true);
+
+ $this->reflector
+ ->expects($this->atLeastOnce())
+ ->method('hasAnnotation')
+ ->willReturnMap($annotations);
+
+ $this->config
+ ->method('getAppValue')
+ ->willReturnMap($config);
+
+ $controller = $this->createMock(ExternalSharesController::class);
+
+ $exceptionThrown = false;
+
+ try {
+ $this->sharingCheckMiddleware->beforeController($controller, 'myMethod');
+ } catch (S2SException $exception) {
+ $exceptionThrown = true;
+ }
+
+ $this->assertNotEquals($noException, $exceptionThrown);
+ }
+
+ public function testBeforeControllerWithShareControllerWithSharingEnabled(): void {
+ $share = $this->createMock(IShare::class);
+
+ $this->appManager
+ ->expects($this->once())
+ ->method('isEnabledForUser')
+ ->with('files_sharing')
+ ->willReturn(true);
+
+ $controller = $this->createMock(ShareController::class);
+
+ $this->sharingCheckMiddleware->beforeController($controller, 'myMethod');
+ }
+
+
+ public function testBeforeControllerWithSharingDisabled(): void {
+ $this->expectException(NotFoundException::class);
+ $this->expectExceptionMessage('Sharing is disabled.');
+
+ $this->appManager
+ ->expects($this->once())
+ ->method('isEnabledForUser')
+ ->with('files_sharing')
+ ->willReturn(false);
+
+ $this->sharingCheckMiddleware->beforeController($this->controllerMock, 'myMethod');
+ }
+
+
+ public function testAfterExceptionWithRegularException(): void {
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('My Exception message');
+
+ $this->sharingCheckMiddleware->afterException($this->controllerMock, 'myMethod', new \Exception('My Exception message'));
+ }
+
+ public function testAfterExceptionWithNotFoundException(): void {
+ $this->assertEquals(new NotFoundResponse(), $this->sharingCheckMiddleware->afterException($this->controllerMock, 'myMethod', new NotFoundException('My Exception message')));
+ }
+
+ public function testAfterExceptionWithS2SException(): void {
+ $this->assertEquals(new JSONResponse('My Exception message', 405), $this->sharingCheckMiddleware->afterException($this->controllerMock, 'myMethod', new S2SException('My Exception message')));
+ }
+}
diff --git a/apps/files_sharing/tests/Migration/SetPasswordColumnTest.php b/apps/files_sharing/tests/Migration/SetPasswordColumnTest.php
new file mode 100644
index 00000000000..3cbbad0f8bc
--- /dev/null
+++ b/apps/files_sharing/tests/Migration/SetPasswordColumnTest.php
@@ -0,0 +1,108 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2017 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Files_Sharing\Tests\Migration;
+
+use OCA\Files_Sharing\Migration\SetPasswordColumn;
+use OCA\Files_Sharing\Tests\TestCase;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\Migration\IOutput;
+use OCP\Server;
+use OCP\Share\IShare;
+
+/**
+ * Class SetPasswordColumnTest
+ *
+ * @group DB
+ */
+class SetPasswordColumnTest extends TestCase {
+
+ /** @var IDBConnection */
+ private $connection;
+
+ /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
+ private $config;
+
+ /** @var SetPasswordColumn */
+ private $migration;
+
+ private $table = 'share';
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->connection = Server::get(IDBConnection::class);
+ $this->config = $this->createMock(IConfig::class);
+ $this->migration = new SetPasswordColumn($this->connection, $this->config);
+
+ $this->cleanDB();
+ }
+
+ protected function tearDown(): void {
+ parent::tearDown();
+ $this->cleanDB();
+ }
+
+ private function cleanDB() {
+ $query = $this->connection->getQueryBuilder();
+ $query->delete($this->table)->execute();
+ }
+
+ public function testAddPasswordColumn(): void {
+ $this->config->expects($this->once())
+ ->method('getAppValue')
+ ->with('files_sharing', 'installed_version', '0.0.0')
+ ->willReturn('1.3.0');
+
+ $shareTypes = [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL, IShare::TYPE_LINK];
+
+ foreach ($shareTypes as $shareType) {
+ for ($i = 0; $i < 5; $i++) {
+ $query = $this->connection->getQueryBuilder();
+ $query->insert($this->table)
+ ->values([
+ 'share_type' => $query->createNamedParameter($shareType),
+ 'share_with' => $query->createNamedParameter('shareWith'),
+ 'uid_owner' => $query->createNamedParameter('user' . $i),
+ 'uid_initiator' => $query->createNamedParameter(null),
+ 'parent' => $query->createNamedParameter(0),
+ 'item_type' => $query->createNamedParameter('file'),
+ 'item_source' => $query->createNamedParameter('2'),
+ 'item_target' => $query->createNamedParameter('/2'),
+ 'file_source' => $query->createNamedParameter(2),
+ 'file_target' => $query->createNamedParameter('/foobar'),
+ 'permissions' => $query->createNamedParameter(31),
+ 'stime' => $query->createNamedParameter(time()),
+ ]);
+
+ $this->assertSame(1, $query->execute());
+ }
+ }
+
+ /** @var IOutput $output */
+ $output = $this->createMock(IOutput::class);
+ $this->migration->run($output);
+
+ $query = $this->connection->getQueryBuilder();
+ $query->select('*')
+ ->from('share');
+ $result = $query->execute();
+ $allShares = $result->fetchAll();
+ $result->closeCursor();
+
+ foreach ($allShares as $share) {
+ if ((int)$share['share_type'] === IShare::TYPE_LINK) {
+ $this->assertNull($share['share_with']);
+ $this->assertSame('shareWith', $share['password']);
+ } else {
+ $this->assertSame('shareWith', $share['share_with']);
+ $this->assertNull($share['password']);
+ }
+ }
+ }
+}
diff --git a/apps/files_sharing/tests/MountProviderTest.php b/apps/files_sharing/tests/MountProviderTest.php
new file mode 100644
index 00000000000..e043a1cb1ef
--- /dev/null
+++ b/apps/files_sharing/tests/MountProviderTest.php
@@ -0,0 +1,409 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Memcache\NullCache;
+use OC\Share20\Share;
+use OCA\Files_Sharing\MountProvider;
+use OCA\Files_Sharing\SharedMount;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\IRootFolder;
+use OCP\Files\Mount\IMountManager;
+use OCP\Files\Storage\IStorageFactory;
+use OCP\ICacheFactory;
+use OCP\IConfig;
+use OCP\IUser;
+use OCP\IUserManager;
+use OCP\Share\IAttributes as IShareAttributes;
+use OCP\Share\IManager;
+use OCP\Share\IShare;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\LoggerInterface;
+
+/**
+ * @group DB
+ */
+class MountProviderTest extends \Test\TestCase {
+
+ protected MountProvider $provider;
+
+ protected IUser&MockObject $user;
+ protected IConfig&MockObject $config;
+ protected IManager&MockObject $shareManager;
+ protected IStorageFactory&MockObject $loader;
+ protected LoggerInterface&MockObject $logger;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->config = $this->getMockBuilder(IConfig::class)->getMock();
+ $this->user = $this->getMockBuilder(IUser::class)->getMock();
+ $this->loader = $this->getMockBuilder('OCP\Files\Storage\IStorageFactory')->getMock();
+ $this->shareManager = $this->getMockBuilder(IManager::class)->getMock();
+ $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
+ $eventDispatcher = $this->createMock(IEventDispatcher::class);
+ $cacheFactory = $this->createMock(ICacheFactory::class);
+ $cacheFactory->method('createLocal')
+ ->willReturn(new NullCache());
+ $mountManager = $this->createMock(IMountManager::class);
+
+ $this->provider = new MountProvider($this->config, $this->shareManager, $this->logger, $eventDispatcher, $cacheFactory, $mountManager);
+ }
+
+ private function makeMockShareAttributes($attrs) {
+ if ($attrs === null) {
+ return null;
+ }
+
+ $shareAttributes = $this->createMock(IShareAttributes::class);
+ $shareAttributes->method('toArray')->willReturn($attrs);
+ $shareAttributes->method('getAttribute')->willReturnCallback(
+ function ($scope, $key) use ($attrs) {
+ $result = null;
+ foreach ($attrs as $attr) {
+ if ($attr['key'] === $key && $attr['scope'] === $scope) {
+ $result = $attr['value'];
+ }
+ }
+ return $result;
+ }
+ );
+ return $shareAttributes;
+ }
+
+ private function makeMockShare($id, $nodeId, $owner = 'user2', $target = null, $permissions = 31, $attributes = null) {
+ $share = $this->createMock(IShare::class);
+ $share->expects($this->any())
+ ->method('getPermissions')
+ ->willReturn($permissions);
+ $share->expects($this->any())
+ ->method('getAttributes')
+ ->willReturn($this->makeMockShareAttributes($attributes));
+ $share->expects($this->any())
+ ->method('getShareOwner')
+ ->willReturn($owner);
+ $share->expects($this->any())
+ ->method('getTarget')
+ ->willReturn($target);
+ $share->expects($this->any())
+ ->method('getId')
+ ->willReturn($id);
+ $share->expects($this->any())
+ ->method('getNodeId')
+ ->willReturn($nodeId);
+ $share->expects($this->any())
+ ->method('getShareTime')
+ ->willReturn(
+ // compute share time based on id, simulating share order
+ new \DateTime('@' . (1469193980 + 1000 * $id))
+ );
+ return $share;
+ }
+
+ /**
+ * Tests excluding shares from the current view. This includes:
+ * - shares that were opted out of (permissions === 0)
+ * - shares with a group in which the owner is already in
+ */
+ public function testExcludeShares(): void {
+ $rootFolder = $this->createMock(IRootFolder::class);
+ $userManager = $this->createMock(IUserManager::class);
+ $attr1 = [];
+ $attr2 = [['scope' => 'permission', 'key' => 'download', 'value' => true]];
+ $userShares = [
+ $this->makeMockShare(1, 100, 'user2', '/share2', 0, $attr1),
+ $this->makeMockShare(2, 100, 'user2', '/share2', 31, $attr2),
+ ];
+ $groupShares = [
+ $this->makeMockShare(3, 100, 'user2', '/share2', 0, $attr1),
+ $this->makeMockShare(4, 101, 'user2', '/share4', 31, $attr2),
+ $this->makeMockShare(5, 100, 'user1', '/share4', 31, $attr2),
+ ];
+ $roomShares = [
+ $this->makeMockShare(6, 102, 'user2', '/share6', 0),
+ $this->makeMockShare(7, 102, 'user1', '/share6', 31),
+ $this->makeMockShare(8, 102, 'user2', '/share6', 31),
+ $this->makeMockShare(9, 102, 'user2', '/share6', 31),
+ ];
+ $deckShares = [
+ $this->makeMockShare(10, 103, 'user2', '/share7', 0),
+ $this->makeMockShare(11, 103, 'user1', '/share7', 31),
+ $this->makeMockShare(12, 103, 'user2', '/share7', 31),
+ $this->makeMockShare(13, 103, 'user2', '/share7', 31),
+ ];
+ // tests regarding circles and sciencemesh are made in the apps themselves.
+ $circleShares = [];
+ $scienceMeshShares = [];
+ $this->user->expects($this->any())
+ ->method('getUID')
+ ->willReturn('user1');
+ $this->shareManager->expects($this->exactly(6))
+ ->method('getSharedWith')
+ ->willReturnMap([
+ ['user1', IShare::TYPE_USER, null, -1, 0, $userShares],
+ ['user1', IShare::TYPE_GROUP, null, -1, 0, $groupShares],
+ ['user1', IShare::TYPE_CIRCLE, null, -1, 0, $circleShares],
+ ['user1', IShare::TYPE_ROOM, null, -1, 0, $roomShares],
+ ['user1', IShare::TYPE_DECK, null, -1, 0, $deckShares],
+ ['user1', IShare::TYPE_SCIENCEMESH, null, -1, 0, $scienceMeshShares],
+ ]);
+
+ $this->shareManager->expects($this->any())
+ ->method('newShare')
+ ->willReturnCallback(function () use ($rootFolder, $userManager) {
+ return new Share($rootFolder, $userManager);
+ });
+
+ $mounts = $this->provider->getMountsForUser($this->user, $this->loader);
+ $this->assertCount(4, $mounts);
+ $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mounts[0]);
+ $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mounts[1]);
+ $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mounts[2]);
+ $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mounts[3]);
+ /** @var SharedMount[] $mounts */
+ $mountedShare1 = $mounts[0]->getShare();
+ $this->assertEquals('2', $mountedShare1->getId());
+ $this->assertEquals('user2', $mountedShare1->getShareOwner());
+ $this->assertEquals(100, $mountedShare1->getNodeId());
+ $this->assertEquals('/share2', $mountedShare1->getTarget());
+ $this->assertEquals(31, $mountedShare1->getPermissions());
+ $this->assertEquals(true, $mountedShare1->getAttributes()->getAttribute('permission', 'download'));
+ $mountedShare2 = $mounts[1]->getShare();
+ $this->assertEquals('4', $mountedShare2->getId());
+ $this->assertEquals('user2', $mountedShare2->getShareOwner());
+ $this->assertEquals(101, $mountedShare2->getNodeId());
+ $this->assertEquals('/share4', $mountedShare2->getTarget());
+ $this->assertEquals(31, $mountedShare2->getPermissions());
+ $this->assertEquals(true, $mountedShare2->getAttributes()->getAttribute('permission', 'download'));
+ $mountedShare3 = $mounts[2]->getShare();
+ $this->assertEquals('8', $mountedShare3->getId());
+ $this->assertEquals('user2', $mountedShare3->getShareOwner());
+ $this->assertEquals(102, $mountedShare3->getNodeId());
+ $this->assertEquals('/share6', $mountedShare3->getTarget());
+ $this->assertEquals(31, $mountedShare3->getPermissions());
+ $mountedShare4 = $mounts[3]->getShare();
+ $this->assertEquals('12', $mountedShare4->getId());
+ $this->assertEquals('user2', $mountedShare4->getShareOwner());
+ $this->assertEquals(103, $mountedShare4->getNodeId());
+ $this->assertEquals('/share7', $mountedShare4->getTarget());
+ $this->assertEquals(31, $mountedShare4->getPermissions());
+ }
+
+ public static function mergeSharesDataProvider(): array {
+ // note: the user in the specs here is the shareOwner not recipient
+ // the recipient is always "user1"
+ return [
+ // #0: share as outsider with "group1" and "user1" with same permissions
+ [
+ [
+ [1, 100, 'user2', '/share2', 31, null],
+ ],
+ [
+ [2, 100, 'user2', '/share2', 31, null],
+ ],
+ [
+ // combined, user share has higher priority
+ ['1', 100, 'user2', '/share2', 31, []],
+ ],
+ ],
+ // #1: share as outsider with "group1" and "user1" with different permissions
+ [
+ [
+ [1, 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => true], ['scope' => 'app', 'key' => 'attribute1', 'value' => true]]],
+ ],
+ [
+ [2, 100, 'user2', '/share', 15, [['scope' => 'permission', 'key' => 'download', 'value' => false], ['scope' => 'app', 'key' => 'attribute2', 'value' => false]]],
+ ],
+ [
+ // use highest permissions
+ ['1', 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => true], ['scope' => 'app', 'key' => 'attribute1', 'value' => true], ['scope' => 'app', 'key' => 'attribute2', 'value' => false]]],
+ ],
+ ],
+ // #2: share as outsider with "group1" and "group2" with same permissions
+ [
+ [
+ ],
+ [
+ [1, 100, 'user2', '/share', 31, null],
+ [2, 100, 'user2', '/share', 31, []],
+ ],
+ [
+ // combined, first group share has higher priority
+ ['1', 100, 'user2', '/share', 31, []],
+ ],
+ ],
+ // #3: share as outsider with "group1" and "group2" with different permissions
+ [
+ [
+ ],
+ [
+ [1, 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => false]]],
+ [2, 100, 'user2', '/share', 15, [['scope' => 'permission', 'key' => 'download', 'value' => true]]],
+ ],
+ [
+ // use higher permissions (most permissive)
+ ['1', 100, 'user2', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => true]]],
+ ],
+ ],
+ // #4: share as insider with "group1"
+ [
+ [
+ ],
+ [
+ [1, 100, 'user1', '/share', 31, []],
+ ],
+ [
+ // no received share since "user1" is the sharer/owner
+ ],
+ ],
+ // #5: share as insider with "group1" and "group2" with different permissions
+ [
+ [
+ ],
+ [
+ [1, 100, 'user1', '/share', 31, [['scope' => 'permission', 'key' => 'download', 'value' => true]]],
+ [2, 100, 'user1', '/share', 15, [['scope' => 'permission', 'key' => 'download', 'value' => false]]],
+ ],
+ [
+ // no received share since "user1" is the sharer/owner
+ ],
+ ],
+ // #6: share as outside with "group1", recipient opted out
+ [
+ [
+ ],
+ [
+ [1, 100, 'user2', '/share', 0, []],
+ ],
+ [
+ // no received share since "user1" opted out
+ ],
+ ],
+ // #7: share as outsider with "group1" and "user1" where recipient renamed in between
+ [
+ [
+ [1, 100, 'user2', '/share2-renamed', 31, []],
+ ],
+ [
+ [2, 100, 'user2', '/share2', 31, []],
+ ],
+ [
+ // use target of least recent share
+ ['1', 100, 'user2', '/share2-renamed', 31, []],
+ ],
+ ],
+ // #8: share as outsider with "group1" and "user1" where recipient renamed in between
+ [
+ [
+ [2, 100, 'user2', '/share2', 31, []],
+ ],
+ [
+ [1, 100, 'user2', '/share2-renamed', 31, []],
+ ],
+ [
+ // use target of least recent share
+ ['1', 100, 'user2', '/share2-renamed', 31, []],
+ ],
+ ],
+ // #9: share as outsider with "nullgroup" and "user1" where recipient renamed in between
+ [
+ [
+ [2, 100, 'user2', '/share2', 31, []],
+ ],
+ [
+ [1, 100, 'nullgroup', '/share2-renamed', 31, []],
+ ],
+ [
+ // use target of least recent share
+ ['1', 100, 'nullgroup', '/share2-renamed', 31, []],
+ ],
+ true
+ ],
+ ];
+ }
+
+ /**
+ * Tests merging shares.
+ *
+ * Happens when sharing the same entry to a user through multiple ways,
+ * like several groups and also direct shares at the same time.
+ *
+ *
+ * @param array $userShares array of user share specs
+ * @param array $groupShares array of group share specs
+ * @param array $expectedShares array of expected supershare specs
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('mergeSharesDataProvider')]
+ public function testMergeShares($userShares, $groupShares, $expectedShares, $moveFails = false): void {
+ $rootFolder = $this->createMock(IRootFolder::class);
+ $userManager = $this->createMock(IUserManager::class);
+
+ $userShares = array_map(function ($shareSpec) {
+ return $this->makeMockShare($shareSpec[0], $shareSpec[1], $shareSpec[2], $shareSpec[3], $shareSpec[4], $shareSpec[5]);
+ }, $userShares);
+ $groupShares = array_map(function ($shareSpec) {
+ return $this->makeMockShare($shareSpec[0], $shareSpec[1], $shareSpec[2], $shareSpec[3], $shareSpec[4], $shareSpec[5]);
+ }, $groupShares);
+
+ $this->user->expects($this->any())
+ ->method('getUID')
+ ->willReturn('user1');
+
+ // tests regarding circles are made in the app itself.
+ $circleShares = [];
+ $roomShares = [];
+ $deckShares = [];
+ $scienceMeshShares = [];
+ $this->shareManager->expects($this->exactly(6))
+ ->method('getSharedWith')
+ ->willReturnMap([
+ ['user1', IShare::TYPE_USER, null, -1, 0, $userShares],
+ ['user1', IShare::TYPE_GROUP, null, -1, 0, $groupShares],
+ ['user1', IShare::TYPE_CIRCLE, null, -1, 0, $circleShares],
+ ['user1', IShare::TYPE_ROOM, null, -1, 0, $roomShares],
+ ['user1', IShare::TYPE_DECK, null, -1, 0, $deckShares],
+ ['user1', IShare::TYPE_SCIENCEMESH, null, -1, 0, $scienceMeshShares],
+ ]);
+
+ $this->shareManager->expects($this->any())
+ ->method('newShare')
+ ->willReturnCallback(function () use ($rootFolder, $userManager) {
+ return new Share($rootFolder, $userManager);
+ });
+
+ if ($moveFails) {
+ $this->shareManager->expects($this->any())
+ ->method('moveShare')
+ ->willThrowException(new \InvalidArgumentException());
+ }
+
+ $mounts = $this->provider->getMountsForUser($this->user, $this->loader);
+
+ $this->assertCount(count($expectedShares), $mounts);
+
+ foreach ($mounts as $index => $mount) {
+ $expectedShare = $expectedShares[$index];
+ $this->assertInstanceOf('OCA\Files_Sharing\SharedMount', $mount);
+
+ // supershare
+ /** @var SharedMount $mount */
+ $share = $mount->getShare();
+
+ $this->assertEquals($expectedShare[0], $share->getId());
+ $this->assertEquals($expectedShare[1], $share->getNodeId());
+ $this->assertEquals($expectedShare[2], $share->getShareOwner());
+ $this->assertEquals($expectedShare[3], $share->getTarget());
+ $this->assertEquals($expectedShare[4], $share->getPermissions());
+ if ($expectedShare[5] === null) {
+ $this->assertNull($share->getAttributes());
+ } else {
+ $this->assertEquals($expectedShare[5], $share->getAttributes()->toArray());
+ }
+ }
+ }
+}
diff --git a/apps/files_sharing/tests/propagationtestcase.php b/apps/files_sharing/tests/PropagationTestCase.php
index 159a7b859aa..98bf5ad92fd 100644
--- a/apps/files_sharing/tests/propagationtestcase.php
+++ b/apps/files_sharing/tests/PropagationTestCase.php
@@ -1,45 +1,36 @@
<?php
+
/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
+namespace OCA\Files_Sharing\Tests;
-namespace OCA\Files_sharing\Tests;
+use OC\Files\View;
+use OCA\Files_Sharing\Helper;
+use OCP\IUserSession;
+use OCP\Server;
abstract class PropagationTestCase extends TestCase {
/**
- * @var \OC\Files\View
+ * @var View
*/
protected $rootView;
protected $fileIds = []; // [$user=>[$path=>$id]]
protected $fileEtags = []; // [$id=>$etag]
- public static function setUpBeforeClass() {
+ public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
- \OCA\Files_Sharing\Helper::registerHooks();
+ Helper::registerHooks();
}
- protected function setUp() {
+ protected function setUp(): void {
parent::setUp();
$this->setUpShares();
}
- protected function tearDown() {
+ protected function tearDown(): void {
\OC_Hook::clear('OC_Filesystem', 'post_write');
\OC_Hook::clear('OC_Filesystem', 'post_delete');
\OC_Hook::clear('OC_Filesystem', 'post_rename');
@@ -54,7 +45,7 @@ abstract class PropagationTestCase extends TestCase {
* @param string $subPath
*/
protected function assertEtagsChanged($users, $subPath = '') {
- $oldUser = \OC::$server->getUserSession()->getUser();
+ $oldUser = Server::get(IUserSession::class)->getUser();
foreach ($users as $user) {
$this->loginAsUser($user);
$id = $this->fileIds[$user][$subPath];
@@ -71,7 +62,7 @@ abstract class PropagationTestCase extends TestCase {
* @param string $subPath
*/
protected function assertEtagsNotChanged($users, $subPath = '') {
- $oldUser = \OC::$server->getUserSession()->getUser();
+ $oldUser = Server::get(IUserSession::class)->getUser();
foreach ($users as $user) {
$this->loginAsUser($user);
$id = $this->fileIds[$user][$subPath];
diff --git a/apps/files_sharing/tests/ShareTest.php b/apps/files_sharing/tests/ShareTest.php
new file mode 100644
index 00000000000..737ad6dcb4e
--- /dev/null
+++ b/apps/files_sharing/tests/ShareTest.php
@@ -0,0 +1,242 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\FileInfo;
+use OC\Files\Filesystem;
+use OCA\Files_Sharing\Helper;
+use OCP\Constants;
+use OCP\IConfig;
+use OCP\IGroupManager;
+use OCP\IUserManager;
+use OCP\Server;
+use OCP\Share\IShare;
+
+/**
+ * Class ShareTest
+ *
+ * @group DB
+ */
+class ShareTest extends TestCase {
+ public const TEST_FOLDER_NAME = '/folder_share_api_test';
+
+ private static $tempStorage;
+
+ private string $subsubfolder = '';
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->folder = self::TEST_FOLDER_NAME;
+ $this->subfolder = '/subfolder_share_api_test';
+ $this->subsubfolder = '/subsubfolder_share_api_test';
+
+ $this->filename = '/share-api-test.txt';
+
+ // save file with content
+ $this->view->file_put_contents($this->filename, $this->data);
+ $this->view->mkdir($this->folder);
+ $this->view->mkdir($this->folder . $this->subfolder);
+ $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder);
+ $this->view->file_put_contents($this->folder . $this->filename, $this->data);
+ $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data);
+ }
+
+ protected function tearDown(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->view->unlink($this->filename);
+ $this->view->deleteAll($this->folder);
+
+ self::$tempStorage = null;
+
+ parent::tearDown();
+ }
+
+ public function testUnshareFromSelf(): void {
+ $groupManager = Server::get(IGroupManager::class);
+ $userManager = Server::get(IUserManager::class);
+
+ $testGroup = $groupManager->createGroup('testGroup');
+ $user1 = $userManager->get(self::TEST_FILES_SHARING_API_USER2);
+ $user2 = $userManager->get(self::TEST_FILES_SHARING_API_USER3);
+ $testGroup->addUser($user1);
+ $testGroup->addUser($user2);
+
+ $share1 = $this->share(
+ IShare::TYPE_USER,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
+ );
+
+ $share2 = $this->share(
+ IShare::TYPE_GROUP,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ 'testGroup',
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
+ );
+ $this->shareManager->acceptShare($share2, self::TEST_FILES_SHARING_API_USER2);
+ $this->shareManager->acceptShare($share2, self::TEST_FILES_SHARING_API_USER3);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertTrue(Filesystem::file_exists($this->filename));
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
+ $this->assertTrue(Filesystem::file_exists($this->filename));
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ Filesystem::unlink($this->filename);
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ // both group share and user share should be gone
+ $this->assertFalse(Filesystem::file_exists($this->filename));
+
+ // for user3 nothing should change
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
+ $this->assertTrue(Filesystem::file_exists($this->filename));
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ }
+
+ /**
+ * @param FileInfo[] $content
+ * @param string[] $expected
+ */
+ public function verifyDirContent($content, $expected) {
+ foreach ($content as $c) {
+ if (!in_array($c['name'], $expected)) {
+ $this->assertTrue(false, "folder should only contain '" . implode(',', $expected) . "', found: " . $c['name']);
+ }
+ }
+ }
+
+ public function testShareWithDifferentShareFolder(): void {
+ $fileinfo = $this->view->getFileInfo($this->filename);
+ $folderinfo = $this->view->getFileInfo($this->folder);
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
+ );
+
+ Helper::setShareFolder('/Shared/subfolder');
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $this->assertTrue(Filesystem::file_exists($this->filename));
+ $this->assertTrue(Filesystem::file_exists('/Shared/subfolder/' . $this->folder));
+
+ //cleanup
+ Server::get(IConfig::class)->deleteSystemValue('share_folder');
+ }
+
+ public function testShareWithGroupUniqueName(): void {
+ $this->markTestSkipped('TODO: Disable because fails on drone');
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::file_put_contents('test.txt', 'test');
+
+ $share = $this->share(
+ IShare::TYPE_GROUP,
+ 'test.txt',
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_GROUP1,
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
+ );
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $shares = $this->shareManager->getSharedWith(self::TEST_FILES_SHARING_API_USER2, IShare::TYPE_GROUP);
+ $share = $shares[0];
+ $this->assertSame('/test.txt', $share->getTarget());
+ $this->assertSame(19, $share->getPermissions());
+
+ Filesystem::rename('test.txt', 'new test.txt');
+
+ $shares = $this->shareManager->getSharedWith(self::TEST_FILES_SHARING_API_USER2, IShare::TYPE_GROUP);
+ $share = $shares[0];
+ $this->assertSame('/new test.txt', $share->getTarget());
+ $this->assertSame(19, $share->getPermissions());
+
+ $share->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE);
+ $this->shareManager->updateShare($share);
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $shares = $this->shareManager->getSharedWith(self::TEST_FILES_SHARING_API_USER2, IShare::TYPE_GROUP);
+ $share = $shares[0];
+
+ $this->assertSame('/new test.txt', $share->getTarget());
+ $this->assertSame(3, $share->getPermissions());
+ }
+
+ /**
+ * shared files should never have delete permissions
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataProviderTestFileSharePermissions')]
+ public function testFileSharePermissions($permission, $expectedvalid): void {
+ $pass = true;
+ try {
+ $this->share(
+ IShare::TYPE_USER,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ $permission
+ );
+ } catch (\Exception $e) {
+ $pass = false;
+ }
+
+ $this->assertEquals($expectedvalid, $pass);
+ }
+
+ public static function dataProviderTestFileSharePermissions() {
+ $permission1 = Constants::PERMISSION_ALL;
+ $permission3 = Constants::PERMISSION_READ;
+ $permission4 = Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE;
+ $permission5 = Constants::PERMISSION_READ | Constants::PERMISSION_DELETE;
+ $permission6 = Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
+
+ return [
+ [$permission1, false],
+ [$permission3, true],
+ [$permission4, true],
+ [$permission5, false],
+ [$permission6, false],
+ ];
+ }
+
+ public function testFileOwner(): void {
+ $this->share(
+ IShare::TYPE_USER,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ
+ );
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $info = Filesystem::getFileInfo($this->filename);
+
+ $this->assertSame(self::TEST_FILES_SHARING_API_USER1, $info->getOwner()->getUID());
+ }
+}
diff --git a/apps/files_sharing/tests/SharedMountTest.php b/apps/files_sharing/tests/SharedMountTest.php
new file mode 100644
index 00000000000..cc9c70a241f
--- /dev/null
+++ b/apps/files_sharing/tests/SharedMountTest.php
@@ -0,0 +1,436 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\Filesystem;
+use OC\Files\View;
+use OC\Memcache\ArrayCache;
+use OCA\Files_Sharing\MountProvider;
+use OCA\Files_Sharing\SharedMount;
+use OCP\Constants;
+use OCP\ICacheFactory;
+use OCP\IDBConnection;
+use OCP\IGroupManager;
+use OCP\IUserManager;
+use OCP\Server;
+use OCP\Share\IShare;
+
+/**
+ * Class SharedMountTest
+ *
+ * @group SLOWDB
+ */
+class SharedMountTest extends TestCase {
+
+ /** @var IGroupManager */
+ private $groupManager;
+
+ /** @var IUserManager */
+ private $userManager;
+
+ private $folder2;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->folder = '/folder_share_storage_test';
+ $this->folder2 = '/folder_share_storage_test2';
+
+ $this->filename = '/share-api-storage.txt';
+
+
+ $this->view->mkdir($this->folder);
+ $this->view->mkdir($this->folder2);
+
+ // save file with content
+ $this->view->file_put_contents($this->filename, 'root file');
+ $this->view->file_put_contents($this->folder . $this->filename, 'file in subfolder');
+ $this->view->file_put_contents($this->folder2 . $this->filename, 'file in subfolder2');
+
+ $this->groupManager = Server::get(IGroupManager::class);
+ $this->userManager = Server::get(IUserManager::class);
+ }
+
+ protected function tearDown(): void {
+ if ($this->view) {
+ if ($this->view->file_exists($this->folder)) {
+ $this->view->unlink($this->folder);
+ }
+ if ($this->view->file_exists($this->filename)) {
+ $this->view->unlink($this->filename);
+ }
+ }
+
+ parent::tearDown();
+ }
+
+ /**
+ * test if the mount point moves up if the parent folder no longer exists
+ */
+ public function testShareMountLoseParentFolder(): void {
+
+ // share to user
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL);
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER2);
+
+ $share->setTarget('/foo/bar' . $this->folder);
+ $this->shareManager->moveShare($share, self::TEST_FILES_SHARING_API_USER2);
+
+ $share = $this->shareManager->getShareById($share->getFullId());
+ $this->assertSame('/foo/bar' . $this->folder, $share->getTarget());
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ // share should have moved up
+
+ $share = $this->shareManager->getShareById($share->getFullId());
+ $this->assertSame($this->folder, $share->getTarget());
+
+ //cleanup
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->shareManager->deleteShare($share);
+ $this->view->unlink($this->folder);
+ }
+
+ /**
+ * @medium
+ */
+ public function testDeleteParentOfMountPoint(): void {
+ // share to user
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+ $this->assertTrue($user2View->file_exists($this->folder));
+
+ // create a local folder
+ $result = $user2View->mkdir('localfolder');
+ $this->assertTrue($result);
+
+ // move mount point to local folder
+ $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder);
+ $this->assertTrue($result);
+
+ // mount point in the root folder should no longer exist
+ $this->assertFalse($user2View->is_dir($this->folder));
+
+ // delete the local folder
+ $result = $user2View->unlink('/localfolder');
+ $this->assertTrue($result);
+
+ //enforce reload of the mount points
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ //mount point should be back at the root
+ $this->assertTrue($user2View->is_dir($this->folder));
+
+ //cleanup
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->view->unlink($this->folder);
+ }
+
+ public function testMoveSharedFile(): void {
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ Filesystem::rename($this->filename, $this->filename . '_renamed');
+
+ $this->assertTrue(Filesystem::file_exists($this->filename . '_renamed'));
+ $this->assertFalse(Filesystem::file_exists($this->filename));
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->assertTrue(Filesystem::file_exists($this->filename));
+ $this->assertFalse(Filesystem::file_exists($this->filename . '_renamed'));
+
+ // rename back to original name
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ Filesystem::rename($this->filename . '_renamed', $this->filename);
+ $this->assertFalse(Filesystem::file_exists($this->filename . '_renamed'));
+ $this->assertTrue(Filesystem::file_exists($this->filename));
+
+ //cleanup
+ $this->shareManager->deleteShare($share);
+ }
+
+ /**
+ * share file with a group if a user renames the file the filename should not change
+ * for the other users
+ */
+ public function testMoveGroupShare(): void {
+ $testGroup = $this->groupManager->createGroup('testGroup');
+ $user1 = $this->userManager->get(self::TEST_FILES_SHARING_API_USER1);
+ $user2 = $this->userManager->get(self::TEST_FILES_SHARING_API_USER2);
+ $user3 = $this->userManager->get(self::TEST_FILES_SHARING_API_USER3);
+ $testGroup->addUser($user1);
+ $testGroup->addUser($user2);
+ $testGroup->addUser($user3);
+
+ $fileinfo = $this->view->getFileInfo($this->filename);
+ $share = $this->share(
+ IShare::TYPE_GROUP,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ 'testGroup',
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
+ );
+ $this->shareManager->acceptShare($share, $user1->getUID());
+ $this->shareManager->acceptShare($share, $user2->getUID());
+ $this->shareManager->acceptShare($share, $user3->getUID());
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $this->assertTrue(Filesystem::file_exists($this->filename));
+
+ Filesystem::rename($this->filename, 'newFileName');
+
+ $this->assertTrue(Filesystem::file_exists('newFileName'));
+ $this->assertFalse(Filesystem::file_exists($this->filename));
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
+ $this->assertTrue(Filesystem::file_exists($this->filename));
+ $this->assertFalse(Filesystem::file_exists('newFileName'));
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
+ $this->assertTrue(Filesystem::file_exists($this->filename));
+ $this->assertFalse(Filesystem::file_exists('newFileName'));
+
+ //cleanup
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->shareManager->deleteShare($share);
+ $testGroup->removeUser($user1);
+ $testGroup->removeUser($user2);
+ $testGroup->removeUser($user3);
+ }
+
+ /**
+ * @param string $path
+ * @param string $expectedResult
+ * @param bool $exception if a exception is expected
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataProviderTestStripUserFilesPath')]
+ public function testStripUserFilesPath($path, $expectedResult, $exception): void {
+ $testClass = new DummyTestClassSharedMount(null, null);
+ try {
+ $result = $testClass->stripUserFilesPathDummy($path);
+ $this->assertSame($expectedResult, $result);
+ } catch (\Exception $e) {
+ if ($exception) {
+ $this->assertSame(10, $e->getCode());
+ } else {
+ $this->assertTrue(false, 'Exception caught, but expected: ' . $expectedResult);
+ }
+ }
+ }
+
+ public static function dataProviderTestStripUserFilesPath() {
+ return [
+ ['/user/files/foo.txt', '/foo.txt', false],
+ ['/user/files/folder/foo.txt', '/folder/foo.txt', false],
+ ['/data/user/files/foo.txt', null, true],
+ ['/data/user/files/', null, true],
+ ['/files/foo.txt', null, true],
+ ['/foo.txt', null, true],
+ ];
+ }
+
+ /**
+ * If the permissions on a group share are upgraded be sure to still respect
+ * removed shares by a member of that group
+ */
+ public function testPermissionUpgradeOnUserDeletedGroupShare(): void {
+ $testGroup = $this->groupManager->createGroup('testGroup');
+ $user1 = $this->userManager->get(self::TEST_FILES_SHARING_API_USER1);
+ $user2 = $this->userManager->get(self::TEST_FILES_SHARING_API_USER2);
+ $user3 = $this->userManager->get(self::TEST_FILES_SHARING_API_USER3);
+ $testGroup->addUser($user1);
+ $testGroup->addUser($user2);
+ $testGroup->addUser($user3);
+
+ $connection = Server::get(IDBConnection::class);
+
+ // Share item with group
+ $fileinfo = $this->view->getFileInfo($this->folder);
+ $share = $this->share(
+ IShare::TYPE_GROUP,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ 'testGroup',
+ Constants::PERMISSION_READ
+ );
+ $this->shareManager->acceptShare($share, $user1->getUID());
+ $this->shareManager->acceptShare($share, $user2->getUID());
+ $this->shareManager->acceptShare($share, $user3->getUID());
+
+ // Login as user 2 and verify the item exists
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertTrue(Filesystem::file_exists($this->folder));
+ $result = $this->shareManager->getShareById($share->getFullId(), self::TEST_FILES_SHARING_API_USER2);
+ $this->assertNotEmpty($result);
+ $this->assertEquals(Constants::PERMISSION_READ, $result->getPermissions());
+
+ // Delete the share
+ $this->assertTrue(Filesystem::rmdir($this->folder));
+ $this->assertFalse(Filesystem::file_exists($this->folder));
+
+ // Verify we do not get a share
+ $result = $this->shareManager->getShareById($share->getFullId(), self::TEST_FILES_SHARING_API_USER2);
+ $this->assertEquals(0, $result->getPermissions());
+
+ // Login as user 1 again and change permissions
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $share->setPermissions(Constants::PERMISSION_ALL);
+ $share = $this->shareManager->updateShare($share);
+
+ // Login as user 2 and verify
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertFalse(Filesystem::file_exists($this->folder));
+ $result = $this->shareManager->getShareById($share->getFullId(), self::TEST_FILES_SHARING_API_USER2);
+ $this->assertEquals(0, $result->getPermissions());
+
+ $this->shareManager->deleteShare($share);
+
+ //cleanup
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $testGroup->removeUser($user1);
+ $testGroup->removeUser($user2);
+ $testGroup->removeUser($user3);
+ }
+
+ /**
+ * test if the mount point gets renamed if a folder exists at the target
+ */
+ public function testShareMountOverFolder(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->view2->mkdir('bar');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ // share to user
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL);
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER2);
+
+ $share->setTarget('/bar');
+ $this->shareManager->moveShare($share, self::TEST_FILES_SHARING_API_USER2);
+
+ $share = $this->shareManager->getShareById($share->getFullId());
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ // share should have been moved
+
+ $share = $this->shareManager->getShareById($share->getFullId());
+ $this->assertSame('/bar (2)', $share->getTarget());
+
+ //cleanup
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->shareManager->deleteShare($share);
+ $this->view->unlink($this->folder);
+ }
+
+ /**
+ * test if the mount point gets renamed if another share exists at the target
+ */
+ public function testShareMountOverShare(): void {
+ // create a shared cache
+ $caches = [];
+ $cacheFactory = $this->createMock(ICacheFactory::class);
+ $cacheFactory->method('createLocal')
+ ->willReturnCallback(function (string $prefix) use (&$caches) {
+ if (!isset($caches[$prefix])) {
+ $caches[$prefix] = new ArrayCache($prefix);
+ }
+ return $caches[$prefix];
+ });
+ $cacheFactory->method('createDistributed')
+ ->willReturnCallback(function (string $prefix) use (&$caches) {
+ if (!isset($caches[$prefix])) {
+ $caches[$prefix] = new ArrayCache($prefix);
+ }
+ return $caches[$prefix];
+ });
+
+ // hack to overwrite the cache factory, we can't use the proper "overwriteService" since the mount provider is created before this test is called
+ $mountProvider = Server::get(MountProvider::class);
+ $reflectionClass = new \ReflectionClass($mountProvider);
+ $reflectionCacheFactory = $reflectionClass->getProperty('cacheFactory');
+ $reflectionCacheFactory->setAccessible(true);
+ $reflectionCacheFactory->setValue($mountProvider, $cacheFactory);
+
+ // share to user
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL);
+ $this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER2);
+
+ $share->setTarget('/foobar');
+ $this->shareManager->moveShare($share, self::TEST_FILES_SHARING_API_USER2);
+
+
+ // share to user
+ $share2 = $this->share(
+ IShare::TYPE_USER,
+ $this->folder2,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL);
+ $this->shareManager->acceptShare($share2, self::TEST_FILES_SHARING_API_USER2);
+
+ $share2->setTarget('/foobar');
+ $this->shareManager->moveShare($share2, self::TEST_FILES_SHARING_API_USER2);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ // one of the shares should have been moved
+
+ $share = $this->shareManager->getShareById($share->getFullId());
+ $share2 = $this->shareManager->getShareById($share2->getFullId());
+
+ // we don't know or care which share got the "(2)" just that one of them did
+ $this->assertNotEquals($share->getTarget(), $share2->getTarget());
+ $this->assertSame('/foobar', min($share->getTarget(), $share2->getTarget()));
+ $this->assertSame('/foobar (2)', max($share->getTarget(), $share2->getTarget()));
+
+ //cleanup
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->shareManager->deleteShare($share);
+ $this->view->unlink($this->folder);
+ }
+}
+
+class DummyTestClassSharedMount extends SharedMount {
+ public function __construct($storage, $mountpoint, $arguments = null, $loader = null) {
+ // noop
+ }
+
+ public function stripUserFilesPathDummy($path) {
+ return $this->stripUserFilesPath($path);
+ }
+}
diff --git a/apps/files_sharing/tests/SharedStorageTest.php b/apps/files_sharing/tests/SharedStorageTest.php
new file mode 100644
index 00000000000..1c1f0a7b71d
--- /dev/null
+++ b/apps/files_sharing/tests/SharedStorageTest.php
@@ -0,0 +1,612 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\Cache\FailedCache;
+use OC\Files\Filesystem;
+use OC\Files\Storage\FailedStorage;
+use OC\Files\Storage\Storage;
+use OC\Files\Storage\Temporary;
+use OC\Files\View;
+use OCA\Files_Sharing\SharedStorage;
+use OCA\Files_Trashbin\AppInfo\Application;
+use OCP\AppFramework\Bootstrap\IBootContext;
+use OCP\Constants;
+use OCP\Files\Config\IMountProviderCollection;
+use OCP\Files\NotFoundException;
+use OCP\IUserManager;
+use OCP\Server;
+use OCP\Share\IShare;
+
+/**
+ * Class SharedStorageTest
+ *
+ * @group DB
+ */
+class SharedStorageTest extends TestCase {
+ protected function setUp(): void {
+ parent::setUp();
+ // register trashbin hooks
+ $trashbinApp = new Application();
+ $trashbinApp->boot($this->createMock(IBootContext::class));
+ $this->folder = '/folder_share_storage_test';
+
+ $this->filename = '/share-api-storage.txt';
+
+
+ $this->view->mkdir($this->folder);
+
+ // save file with content
+ $this->view->file_put_contents($this->filename, 'root file');
+ $this->view->file_put_contents($this->folder . $this->filename, 'file in subfolder');
+ }
+
+ protected function tearDown(): void {
+ if ($this->view) {
+ if ($this->view->file_exists($this->folder)) {
+ $this->view->unlink($this->folder);
+ }
+ if ($this->view->file_exists($this->filename)) {
+ $this->view->unlink($this->filename);
+ }
+ }
+
+ Filesystem::getLoader()->removeStorageWrapper('oc_trashbin');
+
+ parent::tearDown();
+ }
+
+ /**
+ * if the parent of the mount point is gone then the mount point should move up
+ *
+ * @medium
+ */
+ public function testParentOfMountPointIsGone(): void {
+
+ // share to user
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+ $this->assertTrue($user2View->file_exists($this->folder));
+
+ // create a local folder
+ $result = $user2View->mkdir('localfolder');
+ $this->assertTrue($result);
+
+ // move mount point to local folder
+ $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder);
+ $this->assertTrue($result);
+
+ // mount point in the root folder should no longer exist
+ $this->assertFalse($user2View->is_dir($this->folder));
+
+ // delete the local folder
+ /** @var Storage $storage */
+ [$storage, $internalPath] = Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/localfolder');
+ $storage->rmdir($internalPath);
+
+ //enforce reload of the mount points
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ //mount point should be back at the root
+ $this->assertTrue($user2View->is_dir($this->folder));
+
+ //cleanup
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->view->unlink($this->folder);
+ }
+
+ /**
+ * @medium
+ */
+ public function testRenamePartFile(): void {
+
+ // share to user
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ $this->assertTrue($user2View->file_exists($this->folder));
+
+ // create part file
+ $result = $user2View->file_put_contents($this->folder . '/foo.txt.part', 'some test data');
+
+ $this->assertTrue(is_int($result));
+ // rename part file to real file
+ $result = $user2View->rename($this->folder . '/foo.txt.part', $this->folder . '/foo.txt');
+
+ $this->assertTrue($result);
+
+ // check if the new file really exists
+ $this->assertTrue($user2View->file_exists($this->folder . '/foo.txt'));
+
+ // check if the rename also affected the owner
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $this->assertTrue($this->view->file_exists($this->folder . '/foo.txt'));
+
+ //cleanup
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testFilesize(): void {
+ $folderSize = $this->view->filesize($this->folder);
+ $file1Size = $this->view->filesize($this->folder . $this->filename);
+ $file2Size = $this->view->filesize($this->filename);
+
+ $share1 = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ $share2 = $this->share(
+ IShare::TYPE_USER,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
+ );
+
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ // compare file size between user1 and user2, should always be the same
+ $this->assertSame($folderSize, Filesystem::filesize($this->folder));
+ $this->assertSame($file1Size, Filesystem::filesize($this->folder . $this->filename));
+ $this->assertSame($file2Size, Filesystem::filesize($this->filename));
+
+ //cleanup
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ }
+
+ public function testGetPermissions(): void {
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ
+ );
+
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $this->assertTrue(Filesystem::is_dir($this->folder));
+
+ // for the share root we expect:
+ // the read permissions (1)
+ // the delete permission (8), to enable unshare
+ $rootInfo = Filesystem::getFileInfo($this->folder);
+ $this->assertSame(9, $rootInfo->getPermissions());
+
+ // for the file within the shared folder we expect:
+ // the read permissions (1)
+ $subfileInfo = Filesystem::getFileInfo($this->folder . $this->filename);
+ $this->assertSame(1, $subfileInfo->getPermissions());
+
+
+ //cleanup
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testFopenWithReadOnlyPermission(): void {
+ $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ // part file should be forbidden
+ $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
+ $this->assertFalse($handle);
+
+ // regular file forbidden
+ $handle = $user2View->fopen($this->folder . '/test.txt', 'w');
+ $this->assertFalse($handle);
+
+ // rename forbidden
+ $this->assertFalse($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing2.txt'));
+
+ // delete forbidden
+ $this->assertFalse($user2View->unlink($this->folder . '/existing.txt'));
+
+ //cleanup
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testFopenWithCreateOnlyPermission(): void {
+ $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
+ $fileinfoFolder = $this->view->getFileInfo($this->folder);
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ | Constants::PERMISSION_CREATE
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ // create part file allowed
+ $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
+ $this->assertNotFalse($handle);
+ fclose($handle);
+
+ // create regular file allowed
+ $handle = $user2View->fopen($this->folder . '/test-create.txt', 'w');
+ $this->assertNotFalse($handle);
+ fclose($handle);
+
+ // rename file never allowed
+ $this->assertFalse($user2View->rename($this->folder . '/test-create.txt', $this->folder . '/newtarget.txt'));
+ $this->assertFalse($user2View->file_exists($this->folder . '/newtarget.txt'));
+
+ // rename file not allowed if target exists
+ $this->assertFalse($user2View->rename($this->folder . '/newtarget.txt', $this->folder . '/existing.txt'));
+
+ // overwriting file not allowed
+ $handle = $user2View->fopen($this->folder . '/existing.txt', 'w');
+ $this->assertFalse($handle);
+
+ // overwrite forbidden (no update permission)
+ $this->assertFalse($user2View->rename($this->folder . '/test.txt.part', $this->folder . '/existing.txt'));
+
+ // delete forbidden
+ $this->assertFalse($user2View->unlink($this->folder . '/existing.txt'));
+
+ //cleanup
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testFopenWithUpdateOnlyPermission(): void {
+ $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ // create part file allowed
+ $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
+ $this->assertNotFalse($handle);
+ fclose($handle);
+
+ // create regular file not allowed
+ $handle = $user2View->fopen($this->folder . '/test-create.txt', 'w');
+ $this->assertFalse($handle);
+
+ // rename part file not allowed to non-existing file
+ $this->assertFalse($user2View->rename($this->folder . '/test.txt.part', $this->folder . '/nonexist.txt'));
+
+ // rename part file allowed to target existing file
+ $this->assertTrue($user2View->rename($this->folder . '/test.txt.part', $this->folder . '/existing.txt'));
+ $this->assertTrue($user2View->file_exists($this->folder . '/existing.txt'));
+
+ // rename regular file allowed
+ $this->assertTrue($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing-renamed.txt'));
+ $this->assertTrue($user2View->file_exists($this->folder . '/existing-renamed.txt'));
+
+ // overwriting file directly is allowed
+ $handle = $user2View->fopen($this->folder . '/existing-renamed.txt', 'w');
+ $this->assertNotFalse($handle);
+ fclose($handle);
+
+ // delete forbidden
+ $this->assertFalse($user2View->unlink($this->folder . '/existing-renamed.txt'));
+
+ //cleanup
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testFopenWithDeleteOnlyPermission(): void {
+ $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ | Constants::PERMISSION_DELETE
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $user2View = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ // part file should be forbidden
+ $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
+ $this->assertFalse($handle);
+
+ // regular file forbidden
+ $handle = $user2View->fopen($this->folder . '/test.txt', 'w');
+ $this->assertFalse($handle);
+
+ // rename forbidden
+ $this->assertFalse($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing2.txt'));
+
+ // delete allowed
+ $this->assertTrue($user2View->unlink($this->folder . '/existing.txt'));
+
+ //cleanup
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testMountSharesOtherUser(): void {
+ $rootView = new View('');
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ // share 2 different files with 2 different users
+ $share1 = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+ $share2 = $this->share(
+ IShare::TYPE_USER,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER3,
+ Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->folder));
+
+ $mountConfigManager = Server::get(IMountProviderCollection::class);
+ $mounts = $mountConfigManager->getMountsForUser(Server::get(IUserManager::class)->get(self::TEST_FILES_SHARING_API_USER3));
+ array_walk($mounts, [Filesystem::getMountManager(), 'addMount']);
+
+ $this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER3 . '/files/' . $this->filename));
+
+ // make sure we didn't double setup shares for user 2 or mounted the shares for user 3 in user's 2 home
+ $this->assertFalse($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->folder . ' (2)'));
+ $this->assertFalse($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->filename));
+
+ //cleanup
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->view->unlink($this->folder);
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ }
+
+ public function testCopyFromStorage(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+ $this->assertTrue($view->file_exists($this->folder));
+
+ [$sharedStorage,] = $view->resolvePath($this->folder);
+ $this->assertTrue($sharedStorage->instanceOfStorage('OCA\Files_Sharing\ISharedStorage'));
+
+ $sourceStorage = new Temporary([]);
+ $sourceStorage->file_put_contents('foo.txt', 'asd');
+
+ $sharedStorage->copyFromStorage($sourceStorage, 'foo.txt', 'bar.txt');
+ $this->assertTrue($sharedStorage->file_exists('bar.txt'));
+ $this->assertEquals('asd', $sharedStorage->file_get_contents('bar.txt'));
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->view->unlink($this->folder);
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testMoveFromStorage(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+ $this->assertTrue($view->file_exists($this->folder));
+
+ [$sharedStorage,] = $view->resolvePath($this->folder);
+ $this->assertTrue($sharedStorage->instanceOfStorage('OCA\Files_Sharing\ISharedStorage'));
+
+ $sourceStorage = new Temporary([]);
+ $sourceStorage->file_put_contents('foo.txt', 'asd');
+ $sourceStorage->getScanner()->scan('');
+
+ $sharedStorage->moveFromStorage($sourceStorage, 'foo.txt', 'bar.txt');
+ $this->assertTrue($sharedStorage->file_exists('bar.txt'));
+ $this->assertEquals('asd', $sharedStorage->file_get_contents('bar.txt'));
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->view->unlink($this->folder);
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testNameConflict(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
+ $view1->mkdir('foo');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
+ $view3 = new View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files');
+ $view3->mkdir('foo');
+
+ // share a folder with the same name from two different users to the same user
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $share1 = $this->share(
+ IShare::TYPE_GROUP,
+ 'foo',
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_GROUP1,
+ Constants::PERMISSION_ALL
+ );
+ $this->shareManager->acceptShare($share1, self::TEST_FILES_SHARING_API_USER2);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
+
+ $share2 = $this->share(
+ IShare::TYPE_GROUP,
+ 'foo',
+ self::TEST_FILES_SHARING_API_USER3,
+ self::TEST_FILES_SHARING_API_GROUP1,
+ Constants::PERMISSION_ALL
+ );
+ $this->shareManager->acceptShare($share2, self::TEST_FILES_SHARING_API_USER2);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $view2 = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ $this->assertTrue($view2->file_exists('/foo'));
+ $this->assertTrue($view2->file_exists('/foo (2)'));
+
+ $mount = $view2->getMount('/foo');
+ $this->assertInstanceOf('\OCA\Files_Sharing\SharedMount', $mount);
+ /** @var SharedStorage $storage */
+ $storage = $mount->getStorage();
+
+ $this->assertEquals(self::TEST_FILES_SHARING_API_USER1, $storage->getOwner(''));
+
+ $this->shareManager->deleteShare($share1);
+ $this->shareManager->deleteShare($share2);
+ }
+
+ public function testOwnerPermissions(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL - Constants::PERMISSION_DELETE
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+ $this->assertTrue($view->file_exists($this->folder));
+
+ $view->file_put_contents($this->folder . '/newfile.txt', 'asd');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $this->assertTrue($this->view->file_exists($this->folder . '/newfile.txt'));
+ $this->assertEquals(Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE,
+ $this->view->getFileInfo($this->folder . '/newfile.txt')->getPermissions());
+
+ $this->view->unlink($this->folder);
+ $this->shareManager->deleteShare($share);
+ }
+
+ public function testInitWithNonExistingUser(): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getShareOwner')->willReturn('unexist');
+ $ownerView = $this->createMock(View::class);
+ $storage = new SharedStorage([
+ 'ownerView' => $ownerView,
+ 'superShare' => $share,
+ 'groupedShares' => [$share],
+ 'user' => 'user1',
+ ]);
+
+ // trigger init
+ $this->assertInstanceOf(FailedStorage::class, $storage->getSourceStorage());
+ $this->assertInstanceOf(FailedCache::class, $storage->getCache());
+ }
+
+ public function testInitWithNotFoundSource(): void {
+ $share = $this->createMock(IShare::class);
+ $share->method('getShareOwner')->willReturn(self::TEST_FILES_SHARING_API_USER1);
+ $share->method('getNodeId')->willReturn(1);
+ $ownerView = $this->createMock(View::class);
+ $ownerView->method('getPath')->willThrowException(new NotFoundException());
+ $storage = new SharedStorage([
+ 'ownerView' => $ownerView,
+ 'superShare' => $share,
+ 'groupedShares' => [$share],
+ 'user' => 'user1',
+ ]);
+
+ // trigger init
+ $this->assertInstanceOf(FailedStorage::class, $storage->getSourceStorage());
+ $this->assertInstanceOf(FailedCache::class, $storage->getCache());
+ }
+
+ public function testCopyPermissions(): void {
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->filename,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE - Constants::PERMISSION_DELETE
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+ $this->assertTrue($view->file_exists($this->filename));
+
+ $this->assertTrue($view->copy($this->filename, '/target.txt'));
+
+ $this->assertTrue($view->file_exists('/target.txt'));
+
+ $info = $view->getFileInfo('/target.txt');
+ $this->assertEquals(Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE, $info->getPermissions());
+
+ $this->view->unlink($this->filename);
+ $this->shareManager->deleteShare($share);
+ }
+}
diff --git a/apps/files_sharing/tests/SharesReminderJobTest.php b/apps/files_sharing/tests/SharesReminderJobTest.php
new file mode 100644
index 00000000000..ce468e279ec
--- /dev/null
+++ b/apps/files_sharing/tests/SharesReminderJobTest.php
@@ -0,0 +1,193 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Sharing\Tests;
+
+use OC\SystemConfig;
+use OCA\Files_Sharing\SharesReminderJob;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Constants;
+use OCP\Defaults;
+use OCP\Files\IMimeTypeLoader;
+use OCP\Files\IRootFolder;
+use OCP\IDBConnection;
+use OCP\IURLGenerator;
+use OCP\IUserManager;
+use OCP\L10N\IFactory;
+use OCP\Mail\IMailer;
+use OCP\Mail\IMessage;
+use OCP\Server;
+use OCP\Share\IManager;
+use OCP\Share\IShare;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class SharesReminderJobTest
+ *
+ * @group DB
+ *
+ * @package OCA\Files_Sharing\Tests
+ */
+class SharesReminderJobTest extends \Test\TestCase {
+ private SharesReminderJob $job;
+ private IDBConnection $db;
+ private IManager $shareManager;
+ private IUserManager $userManager;
+ private IMailer|MockObject $mailer;
+ private string $user1;
+ private string $user2;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->db = Server::get(IDBConnection::class);
+ $this->shareManager = Server::get(IManager::class);
+ $this->userManager = Server::get(IUserManager::class);
+ $this->mailer = $this->createMock(IMailer::class);
+
+ // Clear occasional leftover shares from other tests
+ $this->db->executeUpdate('DELETE FROM `*PREFIX*share`');
+
+ $this->user1 = $this->getUniqueID('user1_');
+ $this->user2 = $this->getUniqueID('user2_');
+
+ $user1 = $this->userManager->createUser($this->user1, 'longrandompassword');
+ $user2 = $this->userManager->createUser($this->user2, 'longrandompassword');
+ $user1->setSystemEMailAddress('user1@test.com');
+ $user2->setSystemEMailAddress('user2@test.com');
+
+ \OC::registerShareHooks(Server::get(SystemConfig::class));
+
+ $this->job = new SharesReminderJob(
+ Server::get(ITimeFactory::class),
+ $this->db,
+ Server::get(IManager::class),
+ $this->userManager,
+ Server::get(LoggerInterface::class),
+ Server::get(IURLGenerator::class),
+ Server::get(IFactory::class),
+ $this->mailer,
+ Server::get(Defaults::class),
+ Server::get(IMimeTypeLoader::class),
+ );
+ }
+
+ protected function tearDown(): void {
+ $this->db->executeUpdate('DELETE FROM `*PREFIX*share`');
+
+ $userManager = Server::get(IUserManager::class);
+ $user1 = $userManager->get($this->user1);
+ if ($user1) {
+ $user1->delete();
+ }
+ $user2 = $userManager->get($this->user2);
+ if ($user2) {
+ $user2->delete();
+ }
+
+ $this->logout();
+
+ parent::tearDown();
+ }
+
+ public static function dataSharesReminder() {
+ $someMail = 'test@test.com';
+ $noExpirationDate = null;
+ $today = new \DateTime();
+ // For expiration dates, the time is always automatically set to zero by ShareAPIController
+ $today->setTime(0, 0);
+ $nearFuture = new \DateTime();
+ $nearFuture->setTimestamp($today->getTimestamp() + 86400 * 1);
+ $farFuture = new \DateTime();
+ $farFuture->setTimestamp($today->getTimestamp() + 86400 * 2);
+ $permissionRead = Constants::PERMISSION_READ;
+ $permissionCreate = $permissionRead | Constants::PERMISSION_CREATE;
+ $permissionUpdate = $permissionRead | Constants::PERMISSION_UPDATE;
+ $permissionDelete = $permissionRead | Constants::PERMISSION_DELETE;
+ $permissionAll = Constants::PERMISSION_ALL;
+
+ return [
+ // No reminders for folders without expiration date
+ [$noExpirationDate, '', false, $permissionRead, false],
+ [$noExpirationDate, '', false, $permissionCreate, false],
+ [$noExpirationDate, '', true, $permissionDelete, false],
+ [$noExpirationDate, '', true, $permissionCreate, false],
+ [$noExpirationDate, $someMail, false, $permissionUpdate, false],
+ [$noExpirationDate, $someMail, false, $permissionCreate, false],
+ [$noExpirationDate, $someMail, true, $permissionRead, false],
+ [$noExpirationDate, $someMail, true, $permissionAll, false],
+ // No reminders for folders with expiration date in the far future
+ [$farFuture, '', false, $permissionRead, false],
+ [$farFuture, '', false, $permissionCreate, false],
+ [$farFuture, '', true, $permissionDelete, false],
+ [$farFuture, '', true, $permissionCreate, false],
+ [$farFuture, $someMail, false, $permissionUpdate, false],
+ [$farFuture, $someMail, false, $permissionCreate, false],
+ [$farFuture, $someMail, true, $permissionRead, false],
+ [$farFuture, $someMail, true, $permissionAll, false],
+ /* Should send reminders for folders with expiration date in the near future
+ if the folder is empty and the user has write permission */
+ [$nearFuture, '', false, $permissionRead, false],
+ [$nearFuture, '', false, $permissionCreate, false],
+ [$nearFuture, '', true, $permissionDelete, false],
+ [$nearFuture, '', true, $permissionCreate, true],
+ [$nearFuture, $someMail, false, $permissionUpdate, false],
+ [$nearFuture, $someMail, false, $permissionCreate, false],
+ [$nearFuture, $someMail, true, $permissionRead, false],
+ [$nearFuture, $someMail, true, $permissionAll, true],
+ ];
+ }
+
+ /**
+ *
+ * @param \DateTime|null $expirationDate Share expiration date
+ * @param string $email Share with this email. If empty, the share is of type TYPE_USER and the sharee is user2
+ * @param bool $isEmpty Is share folder empty?
+ * @param int $permissions
+ * @param bool $shouldBeReminded
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataSharesReminder')]
+ public function testSharesReminder(
+ ?\DateTime $expirationDate, string $email, bool $isEmpty, int $permissions, bool $shouldBeReminded,
+ ): void {
+ $this->loginAsUser($this->user1);
+
+ $user1Folder = Server::get(IRootFolder::class)->getUserFolder($this->user1);
+ $testFolder = $user1Folder->newFolder('test');
+
+ if (!$isEmpty) {
+ $testFolder->newFile('some_file.txt', 'content');
+ }
+
+ $share = $this->shareManager->newShare();
+
+ $share->setNode($testFolder)
+ ->setShareType(($email ? IShare::TYPE_EMAIL : IShare::TYPE_USER))
+ ->setPermissions($permissions)
+ ->setSharedBy($this->user1)
+ ->setSharedWith(($email ?: $this->user2))
+ ->setExpirationDate($expirationDate);
+ $share = $this->shareManager->createShare($share);
+
+ $this->logout();
+ $messageMock = $this->createMock(IMessage::class);
+ $this->mailer->method('createMessage')->willReturn($messageMock);
+ $this->mailer
+ ->expects(($shouldBeReminded ? $this->once() : $this->never()))
+ ->method('send')
+ ->with($messageMock);
+ $messageMock
+ ->expects(($shouldBeReminded ? $this->once() : $this->never()))
+ ->method('setTo')
+ ->with([$email ?: $this->userManager->get($this->user2)->getSystemEMailAddress()]);
+ $this->assertSame(false, $share->getReminderSent());
+ $this->job->run([]);
+ $share = $this->shareManager->getShareById($share->getFullId());
+ $this->assertEquals($shouldBeReminded, $share->getReminderSent());
+ }
+}
diff --git a/apps/files_sharing/tests/SizePropagationTest.php b/apps/files_sharing/tests/SizePropagationTest.php
new file mode 100644
index 00000000000..e1b67abca90
--- /dev/null
+++ b/apps/files_sharing/tests/SizePropagationTest.php
@@ -0,0 +1,108 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\View;
+use OCP\Constants;
+use OCP\ITempManager;
+use OCP\Server;
+use OCP\Share\IShare;
+use Test\Traits\UserTrait;
+
+/**
+ * Class SizePropagationTest
+ *
+ * @group DB
+ *
+ * @package OCA\Files_Sharing\Tests
+ */
+class SizePropagationTest extends TestCase {
+ use UserTrait;
+
+ protected function setupUser($name, $password = '') {
+ $this->createUser($name, $password);
+ $tmpFolder = Server::get(ITempManager::class)->getTemporaryFolder();
+ $this->registerMount($name, '\OC\Files\Storage\Local', '/' . $name, ['datadir' => $tmpFolder]);
+ $this->loginAsUser($name);
+ return new View('/' . $name . '/files');
+ }
+
+ public function testSizePropagationWhenOwnerChangesFile(): void {
+ $recipientView = $this->setupUser(self::TEST_FILES_SHARING_API_USER1);
+
+ $ownerView = $this->setupUser(self::TEST_FILES_SHARING_API_USER2);
+ $ownerView->mkdir('/sharedfolder/subfolder');
+ $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'bar');
+
+ $this->share(
+ IShare::TYPE_USER,
+ '/sharedfolder',
+ self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER1,
+ Constants::PERMISSION_ALL
+ );
+ $ownerRootInfo = $ownerView->getFileInfo('', false);
+
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ $this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt'));
+ $recipientRootInfo = $recipientView->getFileInfo('', false);
+
+ // when file changed as owner
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar');
+
+ // size of recipient's root stays the same
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ $newRecipientRootInfo = $recipientView->getFileInfo('', false);
+ $this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize());
+
+ // size of owner's root increases
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ $newOwnerRootInfo = $ownerView->getFileInfo('', false);
+ $this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize());
+ }
+
+ public function testSizePropagationWhenRecipientChangesFile(): void {
+ $recipientView = $this->setupUser(self::TEST_FILES_SHARING_API_USER1);
+
+ $ownerView = $this->setupUser(self::TEST_FILES_SHARING_API_USER2);
+ $ownerView->mkdir('/sharedfolder/subfolder');
+ $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'bar');
+
+ $this->share(
+ IShare::TYPE_USER,
+ '/sharedfolder',
+ self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER1,
+ Constants::PERMISSION_ALL
+ );
+ $ownerRootInfo = $ownerView->getFileInfo('', false);
+
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ $this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt'));
+ $recipientRootInfo = $recipientView->getFileInfo('', false);
+ $recipientRootInfoWithMounts = $recipientView->getFileInfo('', true);
+ $oldRecipientSize = $recipientRootInfoWithMounts->getSize();
+
+ // when file changed as recipient
+ $recipientView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar');
+
+ // size of recipient's root stays the same
+ $newRecipientRootInfo = $recipientView->getFileInfo('', false);
+ $this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize());
+
+ // but the size including mountpoints increases
+ $newRecipientRootInfo = $recipientView->getFileInfo('', true);
+ $this->assertEquals($oldRecipientSize + 3, $newRecipientRootInfo->getSize());
+
+ // size of owner's root increases
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ $newOwnerRootInfo = $ownerView->getFileInfo('', false);
+ $this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize());
+ }
+}
diff --git a/apps/files_sharing/tests/TestCase.php b/apps/files_sharing/tests/TestCase.php
new file mode 100644
index 00000000000..9a6935e46b6
--- /dev/null
+++ b/apps/files_sharing/tests/TestCase.php
@@ -0,0 +1,247 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\Cache\Storage;
+use OC\Files\Filesystem;
+use OC\Files\View;
+use OC\Group\Database;
+use OC\SystemConfig;
+use OC\User\DisplayNameCache;
+use OCA\Files_Sharing\AppInfo\Application;
+use OCA\Files_Sharing\External\MountProvider as ExternalMountProvider;
+use OCA\Files_Sharing\MountProvider;
+use OCP\Files\Config\IMountProviderCollection;
+use OCP\Files\IRootFolder;
+use OCP\IDBConnection;
+use OCP\IGroupManager;
+use OCP\IUserManager;
+use OCP\IUserSession;
+use OCP\Server;
+use OCP\Share\IShare;
+use Test\Traits\MountProviderTrait;
+
+/**
+ * Class TestCase
+ *
+ * @group DB
+ *
+ * Base class for sharing tests.
+ */
+abstract class TestCase extends \Test\TestCase {
+ use MountProviderTrait;
+
+ public const TEST_FILES_SHARING_API_USER1 = 'test-share-user1';
+ public const TEST_FILES_SHARING_API_USER2 = 'test-share-user2';
+ public const TEST_FILES_SHARING_API_USER3 = 'test-share-user3';
+ public const TEST_FILES_SHARING_API_USER4 = 'test-share-user4';
+
+ public const TEST_FILES_SHARING_API_GROUP1 = 'test-share-group1';
+
+ public $filename;
+ public $data;
+ /**
+ * @var View
+ */
+ public $view;
+ /**
+ * @var View
+ */
+ public $view2;
+ public $folder;
+ public $subfolder;
+
+ /** @var \OCP\Share\IManager */
+ protected $shareManager;
+ /** @var IRootFolder */
+ protected $rootFolder;
+
+ public static function setUpBeforeClass(): void {
+ parent::setUpBeforeClass();
+
+ $app = new Application();
+ $app->registerMountProviders(
+ Server::get(IMountProviderCollection::class),
+ Server::get(MountProvider::class),
+ Server::get(ExternalMountProvider::class),
+ );
+
+ // reset backend
+ Server::get(IUserManager::class)->clearBackends();
+ Server::get(IGroupManager::class)->clearBackends();
+
+ // clear share hooks
+ \OC_Hook::clear('OCP\\Share');
+ \OC::registerShareHooks(Server::get(SystemConfig::class));
+
+ // create users
+ $backend = new \Test\Util\User\Dummy();
+ Server::get(IUserManager::class)->registerBackend($backend);
+ $backend->createUser(self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER1);
+ $backend->createUser(self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_USER2);
+ $backend->createUser(self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER3);
+ $backend->createUser(self::TEST_FILES_SHARING_API_USER4, self::TEST_FILES_SHARING_API_USER4);
+
+ // create group
+ $groupBackend = new \Test\Util\Group\Dummy();
+ $groupBackend->createGroup(self::TEST_FILES_SHARING_API_GROUP1);
+ $groupBackend->createGroup('group');
+ $groupBackend->createGroup('group1');
+ $groupBackend->createGroup('group2');
+ $groupBackend->createGroup('group3');
+ $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER1, 'group');
+ $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER2, 'group');
+ $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER3, 'group');
+ $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER2, 'group1');
+ $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER3, 'group2');
+ $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER4, 'group3');
+ $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_GROUP1);
+ Server::get(IGroupManager::class)->addBackend($groupBackend);
+ }
+
+ protected function setUp(): void {
+ parent::setUp();
+ Server::get(DisplayNameCache::class)->clear();
+
+ //login as user1
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $this->data = 'foobar';
+ $this->view = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
+ $this->view2 = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ $this->shareManager = Server::get(\OCP\Share\IManager::class);
+ $this->rootFolder = Server::get(IRootFolder::class);
+ }
+
+ protected function tearDown(): void {
+ $qb = Server::get(IDBConnection::class)->getQueryBuilder();
+ $qb->delete('share');
+ $qb->execute();
+
+ $qb = Server::get(IDBConnection::class)->getQueryBuilder();
+ $qb->delete('mounts');
+ $qb->execute();
+
+ $qb = Server::get(IDBConnection::class)->getQueryBuilder();
+ $qb->delete('filecache')->runAcrossAllShards();
+ $qb->execute();
+
+ parent::tearDown();
+ }
+
+ public static function tearDownAfterClass(): void {
+ // cleanup users
+ $user = Server::get(IUserManager::class)->get(self::TEST_FILES_SHARING_API_USER1);
+ if ($user !== null) {
+ $user->delete();
+ }
+ $user = Server::get(IUserManager::class)->get(self::TEST_FILES_SHARING_API_USER2);
+ if ($user !== null) {
+ $user->delete();
+ }
+ $user = Server::get(IUserManager::class)->get(self::TEST_FILES_SHARING_API_USER3);
+ if ($user !== null) {
+ $user->delete();
+ }
+
+ // delete group
+ $group = Server::get(IGroupManager::class)->get(self::TEST_FILES_SHARING_API_GROUP1);
+ if ($group) {
+ $group->delete();
+ }
+
+ \OC_Util::tearDownFS();
+ \OC_User::setUserId('');
+ Filesystem::tearDown();
+
+ // reset backend
+ Server::get(IUserManager::class)->clearBackends();
+ Server::get(IUserManager::class)->registerBackend(new \OC\User\Database());
+ Server::get(IGroupManager::class)->clearBackends();
+ Server::get(IGroupManager::class)->addBackend(new Database());
+
+ parent::tearDownAfterClass();
+ }
+
+ /**
+ * @param string $user
+ * @param bool $create
+ * @param bool $password
+ */
+ protected function loginHelper($user, $create = false, $password = false) {
+ if ($password === false) {
+ $password = $user;
+ }
+
+ if ($create) {
+ $userManager = Server::get(IUserManager::class);
+ $groupManager = Server::get(IGroupManager::class);
+
+ $userObject = $userManager->createUser($user, $password);
+ $group = $groupManager->createGroup('group');
+
+ if ($group && $userObject) {
+ $group->addUser($userObject);
+ }
+ }
+
+ \OC_Util::tearDownFS();
+ Storage::getGlobalCache()->clearCache();
+ Server::get(IUserSession::class)->setUser(null);
+ Filesystem::tearDown();
+ Server::get(IUserSession::class)->login($user, $password);
+ \OC::$server->getUserFolder($user);
+
+ \OC_Util::setupFS($user);
+ }
+
+ /**
+ * get some information from a given share
+ * @param int $shareID
+ * @return array with: item_source, share_type, share_with, item_type, permissions
+ */
+ protected function getShareFromId($shareID) {
+ $qb = Server::get(IDBConnection::class)->getQueryBuilder();
+ $qb->select('item_source', '`share_type', 'share_with', 'item_type', 'permissions')
+ ->from('share')
+ ->where(
+ $qb->expr()->eq('id', $qb->createNamedParameter($shareID))
+ );
+ $result = $qb->execute();
+ $share = $result->fetch();
+ $result->closeCursor();
+
+ return $share;
+ }
+
+ /**
+ * @param int $type The share type
+ * @param string $path The path to share relative to $initiators root
+ * @param string $initiator
+ * @param string $recipient
+ * @param int $permissions
+ * @return IShare
+ */
+ protected function share($type, $path, $initiator, $recipient, $permissions) {
+ $userFolder = $this->rootFolder->getUserFolder($initiator);
+ $node = $userFolder->get($path);
+
+ $share = $this->shareManager->newShare();
+ $share->setShareType($type)
+ ->setSharedWith($recipient)
+ ->setSharedBy($initiator)
+ ->setNode($node)
+ ->setPermissions($permissions);
+ $share = $this->shareManager->createShare($share);
+ $share->setStatus(IShare::STATUS_ACCEPTED);
+ $share = $this->shareManager->updateShare($share);
+
+ return $share;
+ }
+}
diff --git a/apps/files_sharing/tests/UnshareChildrenTest.php b/apps/files_sharing/tests/UnshareChildrenTest.php
new file mode 100644
index 00000000000..ac870212c99
--- /dev/null
+++ b/apps/files_sharing/tests/UnshareChildrenTest.php
@@ -0,0 +1,96 @@
+<?php
+
+/**
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Files_Sharing\Tests;
+
+use OC\Files\Filesystem;
+use OCP\Constants;
+use OCP\Share\IShare;
+use OCP\Util;
+
+/**
+ * Class UnshareChildrenTest
+ *
+ * @group DB
+ *
+ * @package OCA\Files_Sharing\Tests
+ */
+class UnshareChildrenTest extends TestCase {
+ protected $subsubfolder;
+
+ public const TEST_FOLDER_NAME = '/folder_share_api_test';
+
+ private static $tempStorage;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ Util::connectHook('OC_Filesystem', 'post_delete', '\OCA\Files_Sharing\Hooks', 'unshareChildren');
+
+ $this->folder = self::TEST_FOLDER_NAME;
+ $this->subfolder = '/subfolder_share_api_test';
+ $this->subsubfolder = '/subsubfolder_share_api_test';
+
+ $this->filename = '/share-api-test';
+
+ // save file with content
+ $this->view->mkdir($this->folder);
+ $this->view->mkdir($this->folder . $this->subfolder);
+ $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder);
+ $this->view->file_put_contents($this->folder . $this->filename, $this->data);
+ $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data);
+ }
+
+ protected function tearDown(): void {
+ if ($this->view) {
+ $this->view->deleteAll($this->folder);
+ }
+
+ self::$tempStorage = null;
+
+ parent::tearDown();
+ }
+
+ /**
+ * @medium
+ */
+ public function testUnshareChildren(): void {
+ $fileInfo2 = Filesystem::getFileInfo($this->folder);
+
+ $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ // one folder should be shared with the user
+ $shares = $this->shareManager->getSharedWith(self::TEST_FILES_SHARING_API_USER2, IShare::TYPE_USER);
+ $this->assertCount(1, $shares);
+
+ // move shared folder to 'localDir'
+ Filesystem::mkdir('localDir');
+ $result = Filesystem::rename($this->folder, '/localDir/' . $this->folder);
+ $this->assertTrue($result);
+
+ Filesystem::unlink('localDir');
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ // after the parent directory was deleted the share should be unshared
+ $shares = $this->shareManager->getSharedWith(self::TEST_FILES_SHARING_API_USER2, IShare::TYPE_USER);
+ $this->assertEmpty($shares);
+
+ self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ // the folder for the owner should still exists
+ $this->assertTrue(Filesystem::file_exists($this->folder));
+ }
+}
diff --git a/apps/files_sharing/tests/UpdaterTest.php b/apps/files_sharing/tests/UpdaterTest.php
new file mode 100644
index 00000000000..23044e0b2f3
--- /dev/null
+++ b/apps/files_sharing/tests/UpdaterTest.php
@@ -0,0 +1,345 @@
+<?php
+
+/**
+ * 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;
+
+use OC\Files\FileInfo;
+use OC\Files\Filesystem;
+use OC\Files\View;
+use OCA\Files_Sharing\Helper;
+use OCA\Files_Trashbin\AppInfo\Application;
+use OCP\App\IAppManager;
+use OCP\AppFramework\Bootstrap\IBootContext;
+use OCP\Constants;
+use OCP\IConfig;
+use OCP\Server;
+use OCP\Share\IShare;
+
+/**
+ * Class UpdaterTest
+ *
+ * @group DB
+ */
+class UpdaterTest extends TestCase {
+ public const TEST_FOLDER_NAME = '/folder_share_updater_test';
+
+ public static function setUpBeforeClass(): void {
+ parent::setUpBeforeClass();
+ Helper::registerHooks();
+ }
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->folder = self::TEST_FOLDER_NAME;
+
+ $this->filename = '/share-updater-test.txt';
+
+ // save file with content
+ $this->view->file_put_contents($this->filename, $this->data);
+ $this->view->mkdir($this->folder);
+ $this->view->file_put_contents($this->folder . '/' . $this->filename, $this->data);
+ }
+
+ protected function tearDown(): void {
+ if ($this->view) {
+ $this->view->unlink($this->filename);
+ $this->view->deleteAll($this->folder);
+ }
+
+ parent::tearDown();
+ }
+
+ /**
+ * test deletion of a folder which contains share mount points. Share mount
+ * points should be unshared before the folder gets deleted so
+ * that the mount point doesn't end up at the trash bin
+ */
+ public function testDeleteParentFolder(): void {
+ $appManager = Server::get(IAppManager::class);
+ $status = $appManager->isEnabledForUser('files_trashbin');
+ $appManager->enableApp('files_trashbin');
+
+ // register trashbin hooks
+ $trashbinApp = new Application();
+ $trashbinApp->boot($this->createMock(IBootContext::class));
+
+ $fileinfo = Filesystem::getFileInfo($this->folder);
+ $this->assertTrue($fileinfo instanceof FileInfo);
+
+ $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+
+ // check if user2 can see the shared folder
+ $this->assertTrue($view->file_exists($this->folder));
+
+ $foldersShared = $this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER1, IShare::TYPE_USER);
+ $this->assertCount(1, $foldersShared);
+
+ $view->mkdir('localFolder');
+ $view->file_put_contents('localFolder/localFile.txt', 'local file');
+
+ $view->rename($this->folder, 'localFolder/' . $this->folder);
+
+ // share mount point should now be moved to the subfolder
+ $this->assertFalse($view->file_exists($this->folder));
+ $this->assertTrue($view->file_exists('localFolder/' . $this->folder));
+
+ $view->unlink('localFolder');
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ // shared folder should be unshared
+ $foldersShared = $this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER1, IShare::TYPE_USER);
+ $this->assertCount(0, $foldersShared);
+
+ // trashbin should contain the local file but not the mount point
+ $rootView = new View('/' . self::TEST_FILES_SHARING_API_USER2);
+ $trashContent = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_FILES_SHARING_API_USER2);
+ $this->assertSame(1, count($trashContent));
+ $firstElement = reset($trashContent);
+ $timestamp = $firstElement['mtime'];
+ $this->assertTrue($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/localFile.txt'));
+ $this->assertFalse($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/' . $this->folder));
+
+ //cleanup
+ $rootView->deleteAll('files_trashin');
+
+ if ($status === false) {
+ $appManager->disableApp('files_trashbin');
+ }
+
+ Filesystem::getLoader()->removeStorageWrapper('oc_trashbin');
+ }
+
+ public static function shareFolderProvider() {
+ return [
+ ['/'],
+ ['/my_shares'],
+ ];
+ }
+
+ /**
+ * if a file gets shared the etag for the recipients root should change
+ *
+ *
+ * @param string $shareFolder share folder to use
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('shareFolderProvider')]
+ public function testShareFile($shareFolder): void {
+ $config = Server::get(IConfig::class);
+ $oldShareFolder = $config->getSystemValue('share_folder');
+ $config->setSystemValue('share_folder', $shareFolder);
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $beforeShareRoot = Filesystem::getFileInfo('');
+ $etagBeforeShareRoot = $beforeShareRoot->getEtag();
+
+ Filesystem::mkdir($shareFolder);
+
+ $beforeShareDir = Filesystem::getFileInfo($shareFolder);
+ $etagBeforeShareDir = $beforeShareDir->getEtag();
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $afterShareRoot = Filesystem::getFileInfo('');
+ $etagAfterShareRoot = $afterShareRoot->getEtag();
+
+ $afterShareDir = Filesystem::getFileInfo($shareFolder);
+ $etagAfterShareDir = $afterShareDir->getEtag();
+
+ $this->assertTrue(is_string($etagBeforeShareRoot));
+ $this->assertTrue(is_string($etagBeforeShareDir));
+ $this->assertTrue(is_string($etagAfterShareRoot));
+ $this->assertTrue(is_string($etagAfterShareDir));
+ $this->assertTrue($etagBeforeShareRoot !== $etagAfterShareRoot);
+ $this->assertTrue($etagBeforeShareDir !== $etagAfterShareDir);
+
+ // cleanup
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
+ $this->shareManager->deleteShare($share);
+
+ $config->setSystemValue('share_folder', $oldShareFolder);
+ }
+
+ /**
+ * if a folder gets renamed all children mount points should be renamed too
+ */
+ public function testRename(): void {
+ $fileinfo = Filesystem::getFileInfo($this->folder);
+
+ $share = $this->share(
+ IShare::TYPE_USER,
+ $this->folder,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ // make sure that the shared folder exists
+ $this->assertTrue(Filesystem::file_exists($this->folder));
+
+ Filesystem::mkdir('oldTarget');
+ Filesystem::mkdir('oldTarget/subfolder');
+ Filesystem::mkdir('newTarget');
+
+ Filesystem::rename($this->folder, 'oldTarget/subfolder/' . $this->folder);
+
+ // re-login to make sure that the new mount points are initialized
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ Filesystem::rename('/oldTarget', '/newTarget/oldTarget');
+
+ // re-login to make sure that the new mount points are initialized
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+
+ $this->assertTrue(Filesystem::file_exists('/newTarget/oldTarget/subfolder/' . $this->folder));
+
+ // cleanup
+ $this->shareManager->deleteShare($share);
+ }
+
+ /**
+ * If a folder gets moved into shared folder, children shares should have their uid_owner and permissions adjusted
+ * user1
+ * |-folder1 --> shared with user2
+ * user2
+ * |-folder2 --> shared with user3 and moved into folder1
+ * |-subfolder1 --> shared with user3
+ * |-file1.txt --> shared with user3
+ * |-subfolder2
+ * |-file2.txt --> shared with user3
+ */
+ public function testMovedIntoShareChangeOwner(): void {
+ $this->markTestSkipped('Skipped because this is failing with S3 as primary as file id are change when moved.');
+
+ // user1 creates folder1
+ $viewUser1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
+ $folder1 = 'folder1';
+ $viewUser1->mkdir($folder1);
+
+ // user1 shares folder1 to user2
+ $folder1Share = $this->share(
+ IShare::TYPE_USER,
+ $folder1,
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_READ | Constants::PERMISSION_SHARE
+ );
+
+ $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
+ $viewUser2 = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+ // Create user2 files
+ $folder2 = 'folder2';
+ $viewUser2->mkdir($folder2);
+ $file1 = 'folder2/file1.txt';
+ $viewUser2->touch($file1);
+ $subfolder1 = 'folder2/subfolder1';
+ $viewUser2->mkdir($subfolder1);
+ $subfolder2 = 'folder2/subfolder2';
+ $viewUser2->mkdir($subfolder2);
+ $file2 = 'folder2/subfolder2/file2.txt';
+ $viewUser2->touch($file2);
+
+ // user2 shares folder2 to user3
+ $folder2Share = $this->share(
+ IShare::TYPE_USER,
+ $folder2,
+ self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3,
+ Constants::PERMISSION_ALL
+ );
+ // user2 shares folder2/file1 to user3
+ $file1Share = $this->share(
+ IShare::TYPE_USER,
+ $file1,
+ self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3,
+ Constants::PERMISSION_READ | Constants::PERMISSION_SHARE
+ );
+ // user2 shares subfolder1 to user3
+ $subfolder1Share = $this->share(
+ IShare::TYPE_USER,
+ $subfolder1,
+ self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3,
+ Constants::PERMISSION_ALL
+ );
+ // user2 shares subfolder2/file2.txt to user3
+ $file2Share = $this->share(
+ IShare::TYPE_USER,
+ $file2,
+ self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3,
+ Constants::PERMISSION_READ | Constants::PERMISSION_SHARE
+ );
+
+ // user2 moves folder2 into folder1
+ $viewUser2->rename($folder2, $folder1 . '/' . $folder2);
+ $folder2Share = $this->shareManager->getShareById($folder2Share->getFullId());
+ $file1Share = $this->shareManager->getShareById($file1Share->getFullId());
+ $subfolder1Share = $this->shareManager->getShareById($subfolder1Share->getFullId());
+ $file2Share = $this->shareManager->getShareById($file2Share->getFullId());
+
+ // Expect uid_owner of both shares to be user1
+ $this->assertEquals(self::TEST_FILES_SHARING_API_USER1, $folder2Share->getShareOwner());
+ $this->assertEquals(self::TEST_FILES_SHARING_API_USER1, $file1Share->getShareOwner());
+ $this->assertEquals(self::TEST_FILES_SHARING_API_USER1, $subfolder1Share->getShareOwner());
+ $this->assertEquals(self::TEST_FILES_SHARING_API_USER1, $file2Share->getShareOwner());
+ // Expect permissions to be limited by the permissions of the destination share
+ $this->assertEquals(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE, $folder2Share->getPermissions());
+ $this->assertEquals(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE, $file1Share->getPermissions());
+ $this->assertEquals(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE, $subfolder1Share->getPermissions());
+ $this->assertEquals(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE, $file2Share->getPermissions());
+
+ // user2 moves folder2 out of folder1
+ $viewUser2->rename($folder1 . '/' . $folder2, $folder2);
+ $folder2Share = $this->shareManager->getShareById($folder2Share->getFullId());
+ $file1Share = $this->shareManager->getShareById($file1Share->getFullId());
+ $subfolder1Share = $this->shareManager->getShareById($subfolder1Share->getFullId());
+ $file2Share = $this->shareManager->getShareById($file2Share->getFullId());
+
+ // Expect uid_owner of both shares to be user2
+ $this->assertEquals(self::TEST_FILES_SHARING_API_USER2, $folder2Share->getShareOwner());
+ $this->assertEquals(self::TEST_FILES_SHARING_API_USER2, $file1Share->getShareOwner());
+ $this->assertEquals(self::TEST_FILES_SHARING_API_USER2, $subfolder1Share->getShareOwner());
+ $this->assertEquals(self::TEST_FILES_SHARING_API_USER2, $file2Share->getShareOwner());
+ // Expect permissions to not change
+ $this->assertEquals(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE, $folder2Share->getPermissions());
+ $this->assertEquals(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE, $file1Share->getPermissions());
+ $this->assertEquals(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE, $subfolder1Share->getPermissions());
+ $this->assertEquals(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE, $file2Share->getPermissions());
+
+ // cleanup
+ $this->shareManager->deleteShare($folder1Share);
+ $this->shareManager->deleteShare($folder2Share);
+ $this->shareManager->deleteShare($file1Share);
+ $this->shareManager->deleteShare($subfolder1Share);
+ $this->shareManager->deleteShare($file2Share);
+ }
+}
diff --git a/apps/files_sharing/tests/watcher.php b/apps/files_sharing/tests/WatcherTest.php
index 247fb59f351..15676836915 100644
--- a/apps/files_sharing/tests/watcher.php
+++ b/apps/files_sharing/tests/WatcherTest.php
@@ -1,87 +1,76 @@
<?php
+
/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
+namespace OCA\Files_Sharing\Tests;
+
+use OC\Files\Cache\Cache;
+use OC\Files\Storage\Storage;
+use OC\Files\View;
+use OCP\Constants;
+use OCP\Share\IShare;
/**
- * Class Test_Files_Sharing_Watcher
+ * Class WatcherTest
*
* @group DB
*/
-class Test_Files_Sharing_Watcher extends OCA\Files_sharing\Tests\TestCase {
+class WatcherTest extends TestCase {
- /**
- * @var \OC\Files\Storage\Storage
- */
+ /** @var Storage */
private $ownerStorage;
- /**
- * @var \OC\Files\Cache\Cache
- */
+ /** @var Cache */
private $ownerCache;
- /**
- * @var \OC\Files\Storage\Storage
- */
+ /** @var Storage */
private $sharedStorage;
- /**
- * @var \OC\Files\Cache\Cache
- */
+ /** @var Cache */
private $sharedCache;
- protected function setUp() {
+ /** @var IShare */
+ private $_share;
+
+ protected function setUp(): void {
parent::setUp();
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
// prepare user1's dir structure
- $textData = "dummy file data\n";
$this->view->mkdir('container');
$this->view->mkdir('container/shareddir');
$this->view->mkdir('container/shareddir/subdir');
- list($this->ownerStorage, $internalPath) = $this->view->resolvePath('');
+ [$this->ownerStorage, $internalPath] = $this->view->resolvePath('');
$this->ownerCache = $this->ownerStorage->getCache();
$this->ownerStorage->getScanner()->scan('');
// share "shareddir" with user2
- $fileinfo = $this->view->getFileInfo('container/shareddir');
- \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
+ $this->_share = $this->share(
+ IShare::TYPE_USER,
+ 'container/shareddir',
+ self::TEST_FILES_SHARING_API_USER1,
+ self::TEST_FILES_SHARING_API_USER2,
+ Constants::PERMISSION_ALL
+ );
+
+ $this->_share->setStatus(IShare::STATUS_ACCEPTED);
+ $this->shareManager->updateShare($this->_share);
// login as user2
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
// retrieve the shared storage
- $secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2);
- list($this->sharedStorage, $internalPath) = $secondView->resolvePath('files/shareddir');
+ $secondView = new View('/' . self::TEST_FILES_SHARING_API_USER2);
+ [$this->sharedStorage, $internalPath] = $secondView->resolvePath('files/shareddir');
$this->sharedCache = $this->sharedStorage->getCache();
}
- protected function tearDown() {
+ protected function tearDown(): void {
if ($this->sharedCache) {
$this->sharedCache->clear();
}
@@ -89,9 +78,7 @@ class Test_Files_Sharing_Watcher extends OCA\Files_sharing\Tests\TestCase {
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
if ($this->view) {
- $fileinfo = $this->view->getFileInfo('container/shareddir');
- \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
+ $this->shareManager->deleteShare($this->_share);
$this->view->deleteAll('container');
@@ -105,14 +92,14 @@ class Test_Files_Sharing_Watcher extends OCA\Files_sharing\Tests\TestCase {
* Tests that writing a file using the shared storage will propagate the file
* size to the owner's parent folders.
*/
- function testFolderSizePropagationToOwnerStorage() {
+ public function testFolderSizePropagationToOwnerStorage(): void {
$initialSizes = self::getOwnerDirSizes('files/container/shareddir');
$textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$dataLen = strlen($textData);
- $this->sharedCache->put('bar.txt', array('mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain'));
+ $this->sharedCache->put('bar.txt', ['mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain']);
$this->sharedStorage->file_put_contents('bar.txt', $textData);
- $this->sharedCache->put('', array('mtime' => 10, 'storage_mtime' => 10, 'size' => '-1', 'mimetype' => 'httpd/unix-directory'));
+ $this->sharedCache->put('', ['mtime' => 10, 'storage_mtime' => 10, 'size' => '-1', 'mimetype' => 'httpd/unix-directory']);
// run the propagation code
$this->sharedStorage->getWatcher()->checkUpdate('');
@@ -135,14 +122,14 @@ class Test_Files_Sharing_Watcher extends OCA\Files_sharing\Tests\TestCase {
* Tests that writing a file using the shared storage will propagate the file
* size to the owner's parent folders.
*/
- function testSubFolderSizePropagationToOwnerStorage() {
+ public function testSubFolderSizePropagationToOwnerStorage(): void {
$initialSizes = self::getOwnerDirSizes('files/container/shareddir/subdir');
$textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$dataLen = strlen($textData);
- $this->sharedCache->put('subdir/bar.txt', array('mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain'));
+ $this->sharedCache->put('subdir/bar.txt', ['mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain']);
$this->sharedStorage->file_put_contents('subdir/bar.txt', $textData);
- $this->sharedCache->put('subdir', array('mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain'));
+ $this->sharedCache->put('subdir', ['mtime' => 10, 'storage_mtime' => 10, 'size' => $dataLen, 'mimetype' => 'text/plain']);
// run the propagation code
$this->sharedStorage->getWatcher()->checkUpdate('subdir');
@@ -167,8 +154,8 @@ class Test_Files_Sharing_Watcher extends OCA\Files_sharing\Tests\TestCase {
* where the key is the path and the value is the size.
* @param string $path
*/
- function getOwnerDirSizes($path) {
- $result = array();
+ public function getOwnerDirSizes($path) {
+ $result = [];
while ($path != '' && $path != '' && $path != '.') {
$cachedData = $this->ownerCache->get($path);
diff --git a/apps/files_sharing/tests/activity.php b/apps/files_sharing/tests/activity.php
deleted file mode 100644
index 40a1031f779..00000000000
--- a/apps/files_sharing/tests/activity.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_sharing\Tests;
-
-/**
- * Class Activity
- *
- * @group DB
- *
- * @package OCA\Files_sharing\Tests
- */
-class Activity extends \OCA\Files_Sharing\Tests\TestCase {
-
- /**
- * @var \OCA\Files_Sharing\Activity
- */
- private $activity;
-
- protected function setUp() {
- parent::setUp();
- $this->activity = new \OCA\Files_Sharing\Activity(
- $this->getMockBuilder('OCP\L10N\IFactory')
- ->disableOriginalConstructor()
- ->getMock(),
- $this->getMockBuilder('OCP\IURLGenerator')
- ->disableOriginalConstructor()
- ->getMock(),
- $this->getMockBuilder('OCP\Activity\IManager')
- ->disableOriginalConstructor()
- ->getMock()
- );
- }
-
- /**
- * @dataProvider dataTestGetDefaultType
- */
- public function testGetDefaultTypes($method, $expectedResult) {
- $result = $this->activity->getDefaultTypes($method);
-
- if (is_array($expectedResult)) {
- $this->assertSame(count($expectedResult), count($result));
- foreach ($expectedResult as $key => $expected) {
- $this->assertSame($expected, $result[$key]);
- }
- } else {
- $this->assertSame($expectedResult, $result);
- }
-
- }
-
- public function dataTestGetDefaultType() {
- return array(
- array('email', array(\OCA\Files_Sharing\Activity::TYPE_SHARED, \OCA\Files_Sharing\Activity::TYPE_REMOTE_SHARE)),
- array('stream', array(\OCA\Files_Sharing\Activity::TYPE_SHARED, \OCA\Files_Sharing\Activity::TYPE_REMOTE_SHARE, \OCA\Files_Sharing\Activity::TYPE_PUBLIC_LINKS)),
- );
- }
-
-}
diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php
deleted file mode 100644
index 08f8b6f243d..00000000000
--- a/apps/files_sharing/tests/api.php
+++ /dev/null
@@ -1,1586 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-use OCA\Files\Share;
-use OCA\Files_sharing\Tests\TestCase;
-
-/**
- * Class Test_Files_Sharing_Api
- *
- * @group DB
- */
-class Test_Files_Sharing_Api extends TestCase {
-
- const TEST_FOLDER_NAME = '/folder_share_api_test';
-
- private static $tempStorage;
-
- /** @var \OCP\Share\IManager */
- private $shareManager;
-
- /** @var \OCP\Files\Folder */
- private $userFolder;
-
- protected function setUp() {
- parent::setUp();
-
- \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups', 'no');
- \OC::$server->getAppConfig()->setValue('core', 'shareapi_expire_after_n_days', '7');
-
- $this->folder = self::TEST_FOLDER_NAME;
- $this->subfolder = '/subfolder_share_api_test';
- $this->subsubfolder = '/subsubfolder_share_api_test';
-
- $this->filename = '/share-api-test.txt';
-
- // save file with content
- $this->view->file_put_contents($this->filename, $this->data);
- $this->view->mkdir($this->folder);
- $this->view->mkdir($this->folder . $this->subfolder);
- $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder);
- $this->view->file_put_contents($this->folder.$this->filename, $this->data);
- $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data);
-
- $this->shareManager = \OC::$server->getShareManager();
- $this->userFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
- }
-
- protected function tearDown() {
- if($this->view instanceof \OC\Files\View) {
- $this->view->unlink($this->filename);
- $this->view->deleteAll($this->folder);
- }
-
- self::$tempStorage = null;
-
- parent::tearDown();
- }
-
- /**
- * @param array $data
- * @return \OCP\IRequest
- */
- private function createRequest(array $data) {
- $request = $this->getMock('\OCP\IRequest');
- $request->method('getParam')
- ->will($this->returnCallback(function($param, $default = null) use ($data) {
- if (isset($data[$param])) {
- return $data[$param];
- }
- return $default;
- }));
- return $request;
- }
-
- /**
- * @param \OCP\IRequest $request
- * @param string $userId The userId of the caller
- * @return \OCA\Files_Sharing\API\Share20OCS
- */
- private function createOCS($request, $userId) {
- $currentUser = \OC::$server->getUserManager()->get($userId);
-
- return new \OCA\Files_Sharing\API\Share20OCS(
- $this->shareManager,
- \OC::$server->getGroupManager(),
- \OC::$server->getUserManager(),
- $request,
- \OC::$server->getRootFolder(),
- \OC::$server->getURLGenerator(),
- $currentUser
- );
- }
-
- /**
- * @medium
- */
- function testCreateShareUserFile() {
- // simulate a post request
- $data['path'] = $this->filename;
- $data['shareWith'] = \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2;
- $data['shareType'] = \OCP\Share::SHARE_TYPE_USER;
-
- $request = $this->createRequest($data);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- $this->assertTrue($result->succeeded());
- $data = $result->getData();
- $this->assertEquals(19, $data['permissions']);
- $this->assertEmpty($data['expiration']);
-
- $this->shareManager->getShareById('ocinternal:'.$data['id']);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($data['id']);
- $this->assertTrue($result->succeeded());
- }
-
- function testCreateShareUserFolder() {
- // simulate a post request
- $data['path'] = $this->folder;
- $data['shareWith'] = \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2;
- $data['shareType'] = \OCP\Share::SHARE_TYPE_USER;
-
- $request = $this->createRequest($data);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- $this->assertTrue($result->succeeded());
- $data = $result->getData();
- $this->assertEquals(31, $data['permissions']);
- $this->assertEmpty($data['expiration']);
-
- $this->shareManager->getShareById('ocinternal:'.$data['id']);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($data['id']);
- $this->assertTrue($result->succeeded());
- }
-
-
- function testCreateShareGroupFile() {
- // simulate a post request
- $data['path'] = $this->filename;
- $data['shareWith'] = \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_GROUP1;
- $data['shareType'] = \OCP\Share::SHARE_TYPE_GROUP;
-
- $request = $this->createRequest($data);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- $this->assertTrue($result->succeeded());
- $data = $result->getData();
- $this->assertEquals(19, $data['permissions']);
- $this->assertEmpty($data['expiration']);
-
- $this->shareManager->getShareById('ocinternal:'.$data['id']);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($data['id']);
- $this->assertTrue($result->succeeded());
- }
-
- function testCreateShareGroupFolder() {
- // simulate a post request
- $data['path'] = $this->folder;
- $data['shareWith'] = \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_GROUP1;
- $data['shareType'] = \OCP\Share::SHARE_TYPE_GROUP;
-
- $request = $this->createRequest($data);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- $this->assertTrue($result->succeeded());
- $data = $result->getData();
- $this->assertEquals(31, $data['permissions']);
- $this->assertEmpty($data['expiration']);
-
- $this->shareManager->getShareById('ocinternal:'.$data['id']);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($data['id']);
- $this->assertTrue($result->succeeded());
- }
-
- public function testCreateShareLink() {
- // simulate a post request
- $data['path'] = $this->folder;
- $data['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
-
- $request = $this->createRequest($data);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- // check if API call was successful
- $this->assertTrue($result->succeeded());
-
- $data = $result->getData();
- $this->assertEquals(1, $data['permissions']);
- $this->assertEmpty($data['expiration']);
- $this->assertTrue(is_string($data['token']));
-
- // check for correct link
- $url = \OC::$server->getURLGenerator()->getAbsoluteURL('/index.php/s/' . $data['token']);
- $this->assertEquals($url, $data['url']);
-
- $this->shareManager->getShareById('ocinternal:'.$data['id']);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($data['id']);
- $this->assertTrue($result->succeeded());
- }
-
- public function testCreateShareLinkPublicUpload() {
- // simulate a post request
- $data['path'] = $this->folder;
- $data['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
- $data['publicUpload'] = 'true';
-
- $request = $this->createRequest($data);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- // check if API call was successful
- $this->assertTrue($result->succeeded());
-
- $data = $result->getData();
- $this->assertEquals(7, $data['permissions']);
- $this->assertEmpty($data['expiration']);
- $this->assertTrue(is_string($data['token']));
-
- // check for correct link
- $url = \OC::$server->getURLGenerator()->getAbsoluteURL('/index.php/s/' . $data['token']);
- $this->assertEquals($url, $data['url']);
-
- $this->shareManager->getShareById('ocinternal:'.$data['id']);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($data['id']);
- $this->assertTrue($result->succeeded());
- }
-
- function testEnfoceLinkPassword() {
-
- $appConfig = \OC::$server->getAppConfig();
- $appConfig->setValue('core', 'shareapi_enforce_links_password', 'yes');
-
- // don't allow to share link without a password
- $data['path'] = $this->folder;
- $data['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
-
- $request = $this->createRequest($data);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
- $this->assertFalse($result->succeeded());
-
- // don't allow to share link without a empty password
- $data = [];
- $data['path'] = $this->folder;
- $data['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
- $data['password'] = '';
-
- $request = $this->createRequest($data);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
- $this->assertFalse($result->succeeded());
-
- // share with password should succeed
- $data = [];
- $data['path'] = $this->folder;
- $data['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
- $data['password'] = 'foo';
-
- $request = $this->createRequest($data);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
- $this->assertTrue($result->succeeded());
-
- $data = $result->getData();
-
- // setting new password should succeed
- $data2 = [
- 'password' => 'bar',
- ];
- $request = $this->createRequest($data2);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($data['id']);
- $this->assertTrue($result->succeeded());
-
- // removing password should fail
- $data2 = [
- 'password' => '',
- ];
- $request = $this->createRequest($data2);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($data['id']);
- $this->assertFalse($result->succeeded());
-
- // cleanup
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($data['id']);
- $this->assertTrue($result->succeeded());
-
- $appConfig->setValue('core', 'shareapi_enforce_links_password', 'no');
- }
-
- /**
- * @medium
- */
- function testSharePermissions() {
- // sharing file to a user should work if shareapi_exclude_groups is set
- // to no
- \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups', 'no');
- $post['path'] = $this->filename;
- $post['shareWith'] = \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2;
- $post['shareType'] = \OCP\Share::SHARE_TYPE_USER;
-
- $request = $this->createRequest($post);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- $this->assertTrue($result->succeeded());
- $data = $result->getData();
-
- $this->shareManager->getShareById('ocinternal:'.$data['id']);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($data['id']);
- $this->assertTrue($result->succeeded());
-
- // exclude groups, but not the group the user belongs to. Sharing should still work
- \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups', 'yes');
- \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups_list', 'admin,group1,group2');
-
- $post = [];
- $post['path'] = $this->filename;
- $post['shareWith'] = \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2;
- $post['shareType'] = \OCP\Share::SHARE_TYPE_USER;
-
- $request = $this->createRequest($post);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- $this->assertTrue($result->succeeded());
- $data = $result->getData();
-
- $this->shareManager->getShareById('ocinternal:' . $data['id']);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($data['id']);
- $this->assertTrue($result->succeeded());
-
- // now we exclude the group the user belongs to ('group'), sharing should fail now
- \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups_list', 'admin,group');
-
- $post = [];
- $post['path'] = $this->filename;
- $post['shareWith'] = \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2;
- $post['shareType'] = \OCP\Share::SHARE_TYPE_USER;
-
- $request = $this->createRequest($post);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- // cleanup
- \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups', 'no');
- \OC::$server->getAppConfig()->setValue('core', 'shareapi_exclude_groups_list', '');
- }
-
-
- /**
- * @medium
- */
- function testGetAllShares() {
- $node = $this->userFolder->get($this->filename);
-
- $share = $this->shareManager->newShare();
- $share->setNode($node)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
-
- $share = $this->shareManager->createShare($share);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
-
- $this->assertTrue($result->succeeded());
- $this->assertTrue(count($result->getData()) === 1);
-
- $this->shareManager->deleteShare($share);
- }
-
- function testGetAllSharesWithMe() {
- $node1 = $this->userFolder->get($this->filename);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share1 = $this->shareManager->createShare($share1);
-
- $node2 = $this->userFolder->get($this->folder);
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node2)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(31);
- $share2 = $this->shareManager->createShare($share2);
-
- $request = $this->createRequest(['shared_with_me' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER2);
- $result = $ocs->getShares();
-
- $this->assertTrue($result->succeeded());
- $this->assertTrue(count($result->getData()) === 2);
-
- $this->shareManager->deleteShare($share1);
- $this->shareManager->deleteShare($share2);
- }
-
- /**
- * @medium
- */
- function testPublicLinkUrl() {
- // simulate a post request
- $post['path'] = $this->folder;
- $post['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
-
- $request = $this->createRequest($post);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
- $this->assertTrue($result->succeeded());
-
- $data = $result->getData();
-
- // check if we have a token
- $this->assertTrue(is_string($data['token']));
- $id = $data['id'];
-
- // check for correct link
- $url = \OC::$server->getURLGenerator()->getAbsoluteURL('/index.php/s/' . $data['token']);
- $this->assertEquals($url, $data['url']);
-
- // check for link in getall shares
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- $data = $result->getData();
- $this->assertEquals($url, current($data)['url']);
-
- // check for path
- $request = $this->createRequest(['path' => $this->folder]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- $data = $result->getData();
- $this->assertEquals($url, current($data)['url']);
-
- // check in share id
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShare($id);
- $this->assertTrue($result->succeeded());
-
- $data = $result->getData();
- $this->assertEquals($url, current($data)['url']);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($id);
- $this->assertTrue($result->succeeded());
- }
-
- /**
- * @medium
- * @depends testCreateShareUserFile
- * @depends testCreateShareLink
- */
- function testGetShareFromSource() {
- $node = $this->userFolder->get($this->filename);
- $share = $this->shareManager->newShare();
- $share->setNode($node)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share1 = $this->shareManager->createShare($share);
-
- $share = $this->shareManager->newShare();
- $share->setNode($node)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share2 = $this->shareManager->createShare($share);
-
- $request = $this->createRequest(['path' => $this->filename]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- // test should return one share created from testCreateShare()
- $this->assertTrue(count($result->getData()) === 2);
-
- $this->shareManager->deleteShare($share1);
- $this->shareManager->deleteShare($share2);
- }
-
- /**
- * @medium
- * @depends testCreateShareUserFile
- * @depends testCreateShareLink
- */
- function testGetShareFromSourceWithReshares() {
- $node = $this->userFolder->get($this->filename);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share1 = $this->shareManager->createShare($share1);
-
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER3)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share2 = $this->shareManager->createShare($share2);
-
- $request = $this->createRequest(['path' => $this->filename]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- // test should return one share
- $this->assertTrue(count($result->getData()) === 1);
-
- // now also ask for the reshares
- $request = $this->createRequest(['path' => $this->filename, 'reshares' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- $this->assertTrue($result->succeeded());
-
- // now we should get two shares, the initial share and the reshare
- $this->assertCount(2, $result->getData());
-
- $this->shareManager->deleteShare($share1);
- $this->shareManager->deleteShare($share2);
- }
-
- /**
- * @medium
- * @depends testCreateShareUserFile
- */
- function testGetShareFromId() {
- $node = $this->userFolder->get($this->filename);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share1 = $this->shareManager->createShare($share1);
-
- // call getShare() with share ID
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShare($share1->getId());
- $this->assertTrue($result->succeeded());
-
- // test should return one share created from testCreateShare()
- $this->assertEquals(1, count($result->getData()));
-
- $this->shareManager->deleteShare($share1);
- }
-
- /**
- * @medium
- */
- function testGetShareFromFolder() {
- $node1 = $this->userFolder->get($this->filename);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share1 = $this->shareManager->createShare($share1);
-
- $node2 = $this->userFolder->get($this->folder.'/'.$this->filename);
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node2)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share2 = $this->shareManager->createShare($share2);
-
-
- $request = $this->createRequest(['path' => $this->folder, 'subfiles' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- // test should return one share within $this->folder
- $this->assertTrue(count($result->getData()) === 1);
-
- $this->shareManager->deleteShare($share1);
- $this->shareManager->deleteShare($share2);
- }
-
- function testGetShareFromFolderWithFile() {
- $node1 = $this->userFolder->get($this->filename);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share1 = $this->shareManager->createShare($share1);
-
- $request = $this->createRequest(['path' => $this->filename, 'subfiles' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
-
- $this->assertFalse($result->succeeded());
- $this->assertEquals(400, $result->getStatusCode());
- $this->assertEquals('not a directory', $result->getMeta()['message']);
-
- $this->shareManager->deleteShare($share1);
- }
-
- /**
- * share a folder, than reshare a file within the shared folder and check if we construct the correct path
- * @medium
- */
- function testGetShareFromFolderReshares() {
- $node1 = $this->userFolder->get($this->folder);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(31);
- $share1 = $this->shareManager->createShare($share1);
-
- $node2 = $this->userFolder->get($this->folder.'/'.$this->filename);
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node2)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share2 = $this->shareManager->createShare($share2);
-
- $node3 = $this->userFolder->get($this->folder.'/'.$this->subfolder.'/'.$this->filename);
- $share3 = $this->shareManager->newShare();
- $share3->setNode($node3)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share3 = $this->shareManager->createShare($share3);
-
- $testValues=array(
- array('query' => $this->folder,
- 'expectedResult' => $this->folder . $this->filename),
- array('query' => $this->folder . $this->subfolder,
- 'expectedResult' => $this->folder . $this->subfolder . $this->filename),
- );
- foreach ($testValues as $value) {
-
- $request = $this->createRequest(['path' => $value['query'], 'subfiles' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER2);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- // test should return one share within $this->folder
- $data = $result->getData();
-
- $this->assertEquals($value['expectedResult'], $data[0]['path']);
- }
-
- // cleanup
- $this->shareManager->deleteShare($share1);
- $this->shareManager->deleteShare($share2);
- $this->shareManager->deleteShare($share3);
- }
-
- /**
- * reshare a sub folder and check if we get the correct path
- * @medium
- */
- function testGetShareFromSubFolderReShares() {
- $node1 = $this->userFolder->get($this->folder . $this->subfolder);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(31);
- $share1 = $this->shareManager->createShare($share1);
-
- $node2 = \OC::$server->getRootFolder()->getUserFolder(self::TEST_FILES_SHARING_API_USER2)->get($this->subfolder);
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node2)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share2 = $this->shareManager->createShare($share2);
-
- $request = $this->createRequest(['path' => '/', 'subfiles' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER2);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- // test should return one share within $this->folder
- $data = $result->getData();
-
- // we should get exactly one result
- $this->assertCount(1, $data);
-
- $expectedPath = $this->folder . $this->subfolder;
- $this->assertEquals($expectedPath, $data[0]['path']);
-
- $this->shareManager->deleteShare($share2);
- $this->shareManager->deleteShare($share1);
- }
-
- /**
- * test re-re-share of folder if the path gets constructed correctly
- * @medium
- */
- function testGetShareFromFolderReReShares() {
- $node1 = $this->userFolder->get($this->folder . $this->subfolder);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(31);
- $share1 = $this->shareManager->createShare($share1);
-
- $node2 = $this->userFolder->get($this->folder . $this->subfolder . $this->subsubfolder);
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node2)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER3)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(31);
- $share2 = $this->shareManager->createShare($share2);
-
- $share3 = $this->shareManager->newShare();
- $share3->setNode($node2)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER3)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share3 = $this->shareManager->createShare($share3);
-
- $request = $this->createRequest(['path' => '/', 'subfiles' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER3);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- // test should return one share within $this->folder
- $data = $result->getData();
-
- // we should get exactly one result
- $this->assertCount(1, $data);
-
- $expectedPath = $this->folder . $this->subfolder . $this->subsubfolder;
- $this->assertEquals($expectedPath, $data[0]['path']);
-
- $this->shareManager->deleteShare($share1);
- $this->shareManager->deleteShare($share2);
- $this->shareManager->deleteShare($share3);
- }
-
- /**
- * test multiple shared folder if the path gets constructed correctly
- * @medium
- */
- function testGetShareMultipleSharedFolder() {
- $node1 = $this->userFolder->get($this->folder . $this->subfolder);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(31);
- $share1 = $this->shareManager->createShare($share1);
-
- $node2 = $this->userFolder->get($this->folder);
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node2)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(31);
- $share2 = $this->shareManager->createShare($share2);
-
- $share3 = $this->shareManager->newShare();
- $share3->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share3 = $this->shareManager->createShare($share3);
-
- $request = $this->createRequest(['path' => $this->subfolder]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER2);
- $result1 = $ocs->getShares();
- $this->assertTrue($result1->succeeded());
-
- // test should return one share within $this->folder
- $data1 = $result1->getData();
- $this->assertCount(1, $data1);
- $s1 = reset($data1);
-
- $request = $this->createRequest(['path' => $this->folder.$this->subfolder]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER2);
- $result2 = $ocs->getShares();
- $this->assertTrue($result2->succeeded());
-
- // test should return one share within $this->folder
- $data2 = $result2->getData();
- $this->assertCount(1, $data2);
- $s2 = reset($data2);
-
- $this->assertEquals($this->folder.$this->subfolder, $s1['path']);
- $this->assertEquals($this->folder.$this->subfolder, $s2['path']);
-
- $this->shareManager->deleteShare($share1);
- $this->shareManager->deleteShare($share2);
- $this->shareManager->deleteShare($share3);
- }
-
- /**
- * test re-re-share of folder if the path gets constructed correctly
- * @medium
- */
- function testGetShareFromFileReReShares() {
- $node1 = $this->userFolder->get($this->folder . $this->subfolder);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(31);
- $share1 = $this->shareManager->createShare($share1);
-
- $user2Folder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER2);
- $node2 = $user2Folder->get($this->subfolder . $this->filename);
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node2)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER3)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share2 = $this->shareManager->createShare($share2);
-
- $user3Folder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER3);
- $node3 = $user3Folder->get($this->filename);
- $share3 = $this->shareManager->newShare();
- $share3->setNode($node3)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER3)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share3 = $this->shareManager->createShare($share3);
-
- $request = $this->createRequest(['path' => '/', 'subfiles' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER3);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- // test should return one share within $this->folder
- $data = $result->getData();
-
- // we should get exactly one result
- $this->assertCount(1, $data);
-
- $expectedPath = $this->folder.$this->subfolder.$this->filename;
- $this->assertEquals($expectedPath, $data[0]['path']);
-
- $this->shareManager->deleteShare($share1);
- $this->shareManager->deleteShare($share2);
- $this->shareManager->deleteShare($share3);
- }
-
- /**
- * @medium
- */
- function testGetShareFromUnknownId() {
- $request = $this->createRequest(['path' => '/', 'subfiles' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER3);
- $result = $ocs->getShare(0);
- $this->assertFalse($result->succeeded());
-
- $this->assertEquals(404, $result->getStatusCode());
- $meta = $result->getMeta();
- $this->assertEquals('wrong share ID, share doesn\'t exist.', $meta['message']);
- }
-
- /**
- * @medium
- * @depends testCreateShareUserFile
- * @depends testCreateShareLink
- */
- function testUpdateShare() {
- $node1 = $this->userFolder->get($this->filename);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share1 = $this->shareManager->createShare($share1);
-
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share2 = $this->shareManager->createShare($share2);
-
- // update permissions
- $params = array();
- $params['permissions'] = 1;
-
- $request = $this->createRequest(['permissions' => 1]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($share1->getId());
- $this->assertTrue($result->succeeded());
-
- $meta = $result->getMeta();
- $this->assertTrue($result->succeeded(), $meta['message']);
-
- $share1 = $this->shareManager->getShareById('ocinternal:' . $share1->getId());
- $this->assertEquals(1, $share1->getPermissions());
-
- // update password for link share
- $this->assertNull($share2->getPassword());
-
- $request = $this->createRequest(['password' => 'foo']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($share2->getId());
- $this->assertTrue($result->succeeded());
-
- $share2 = $this->shareManager->getShareById('ocinternal:' . $share2->getId());
- $this->assertNotNull($share2->getPassword());
-
- $request = $this->createRequest(['password' => '']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($share2->getId());
- $this->assertTrue($result->succeeded());
-
- $share2 = $this->shareManager->getShareById('ocinternal:' . $share2->getId());
- $this->assertNull($share2->getPassword());
-
- $this->shareManager->deleteShare($share1);
- $this->shareManager->deleteShare($share2);
- }
-
- /**
- * @medium
- * @depends testCreateShareUserFile
- */
- public function testUpdateShareInvalidPermissions() {
- $node1 = $this->userFolder->get($this->filename);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share1 = $this->shareManager->createShare($share1);
-
- $request = $this->createRequest(['permissions' => \OCP\Constants::PERMISSION_ALL]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($share1->getId());
-
- //Updating should fail with 400
- $this->assertFalse($result->succeeded());
- $this->assertEquals(400, $result->getStatusCode());
-
- //Permissions should not have changed!
- $share1 = $this->shareManager->getShareById('ocinternal:' . $share1->getId());
- $this->assertEquals(19, $share1->getPermissions());
-
- $this->shareManager->deleteShare($share1);
- }
-
- /**
- * @medium
- */
- function testUpdateShareUpload() {
- $node1 = $this->userFolder->get($this->folder);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share1 = $this->shareManager->createShare($share1);
-
- // update public upload
- $request = $this->createRequest(['publicUpload' => 'true']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($share1->getId());
- $this->assertTrue($result->succeeded());
-
- $share1 = $this->shareManager->getShareById($share1->getFullId());
- $this->assertEquals(7, $share1->getPermissions());
-
- // cleanup
- $this->shareManager->deleteShare($share1);
- }
-
- /**
- * @medium
- */
- function testUpdateShareExpireDate() {
- $node1 = $this->userFolder->get($this->folder);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share1 = $this->shareManager->createShare($share1);
-
- $config = \OC::$server->getConfig();
-
- // enforce expire date, by default 7 days after the file was shared
- $config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
- $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
-
- $dateWithinRange = new \DateTime();
- $dateWithinRange->setTime(0,0,0);
- $dateWithinRange->add(new \DateInterval('P5D'));
- $dateOutOfRange = new \DateTime();
- $dateOutOfRange->setTime(0,0,0);
- $dateOutOfRange->add(new \DateInterval('P8D'));
-
- // update expire date to a valid value
- $request = $this->createRequest(['expireDate' => $dateWithinRange->format('Y-m-d')]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($share1->getId());
- $this->assertTrue($result->succeeded());
-
- $share1 = $this->shareManager->getShareById($share1->getFullId());
-
- // date should be changed
- $this->assertEquals($dateWithinRange, $share1->getExpirationDate());
-
- // update expire date to a value out of range
- $request = $this->createRequest(['expireDate' => $dateOutOfRange->format('Y-m-d')]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($share1->getId());
- $this->assertFalse($result->succeeded());
-
- $share1 = $this->shareManager->getShareById($share1->getFullId());
-
- // date shouldn't be changed
- $this->assertEquals($dateWithinRange, $share1->getExpirationDate());
-
- // Try to remove expire date
- $request = $this->createRequest(['expireDate' => '']);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->updateShare($share1->getId());
- $this->assertFalse($result->succeeded());
-
- $share1 = $this->shareManager->getShareById($share1->getFullId());
-
-
- // date shouldn't be changed
- $this->assertEquals($dateWithinRange, $share1->getExpirationDate());
- // cleanup
- $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
- $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
- $this->shareManager->deleteShare($share1);
- }
-
- /**
- * @medium
- * @depends testCreateShareUserFile
- */
- function testDeleteShare() {
- $node1 = $this->userFolder->get($this->filename);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(19);
- $share1 = $this->shareManager->createShare($share1);
-
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share2 = $this->shareManager->createShare($share1);
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($share1->getId());
- $this->assertTrue($result->succeeded());
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($share2->getId());
- $this->assertTrue($result->succeeded());
-
- $this->assertEmpty($this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER2, \OCP\Share::SHARE_TYPE_USER));
- $this->assertEmpty($this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER2, \OCP\Share::SHARE_TYPE_LINK));
- }
-
- /**
- * test unshare of a reshared file
- */
- function testDeleteReshare() {
- $node1 = $this->userFolder->get($this->folder);
- $share1 = $this->shareManager->newShare();
- $share1->setNode($node1)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
- ->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setPermissions(31);
- $share1 = $this->shareManager->createShare($share1);
-
- $user2folder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER2);
- $node2 = $user2folder->get($this->folder.'/'.$this->filename);
- $share2 = $this->shareManager->newShare();
- $share2->setNode($node2)
- ->setSharedBy(self::TEST_FILES_SHARING_API_USER2)
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPermissions(1);
- $share2 = $this->shareManager->createShare($share2);
-
- // test if we can unshare the link again
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER2);
- $result = $ocs->deleteShare($share2->getId());
- $this->assertTrue($result->succeeded());
-
- $this->shareManager->deleteShare($share1);
- }
-
- /**
- * share a folder which contains a share mount point, should be forbidden
- */
- public function testShareFolderWithAMountPoint() {
- // user 1 shares a folder with user2
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1);
-
- $fileInfo = $this->view->getFileInfo($this->folder);
-
- $result = \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31);
-
- $this->assertTrue($result);
-
- // user2 shares a file from the folder as link
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2);
-
- $view = new \OC\Files\View('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2 . '/files');
- $view->mkdir("localDir");
-
- // move mount point to the folder "localDir"
- $result = $view->rename($this->folder, 'localDir/'.$this->folder);
- $this->assertTrue($result !== false);
-
- // try to share "localDir"
- $fileInfo2 = $view->getFileInfo('localDir');
-
- $this->assertTrue($fileInfo2 instanceof \OC\Files\FileInfo);
-
- try {
- $result2 = \OCP\Share::shareItem('folder', $fileInfo2['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER3, 31);
- } catch (\Exception $e) {
- $result2 = false;
- }
-
- $this->assertFalse($result2);
-
- //cleanup
-
- $result = $view->rename('localDir/' . $this->folder, $this->folder);
- $this->assertTrue($result !== false);
- $view->unlink('localDir');
-
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1);
-
- \OCP\Share::unshare('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2);
- }
-
- /**
- * Post init mount points hook for mounting simulated ext storage
- */
- public static function initTestMountPointsHook($data) {
- if ($data['user'] === \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1) {
- \OC\Files\Filesystem::mount(self::$tempStorage, array(), '/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1 . '/files' . self::TEST_FOLDER_NAME);
- }
- }
-
- /**
- * Tests mounting a folder that is an external storage mount point.
- */
- public function testShareStorageMountPoint() {
- self::$tempStorage = new \OC\Files\Storage\Temporary(array());
- self::$tempStorage->file_put_contents('test.txt', 'abcdef');
- self::$tempStorage->getScanner()->scan('');
-
- // needed because the sharing code sometimes switches the user internally and mounts the user's
- // storages. In our case the temp storage isn't mounted automatically, so doing it in the post hook
- // (similar to how ext storage works)
- OCP\Util::connectHook('OC_Filesystem', 'post_initMountPoints', '\Test_Files_Sharing_Api', 'initTestMountPointsHook');
-
- // logging in will auto-mount the temp storage for user1 as well
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1);
-
- $fileInfo = $this->view->getFileInfo($this->folder);
-
- // user 1 shares the mount point folder with user2
- $result = \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31);
-
- $this->assertTrue($result);
-
- // user2: check that mount point name appears correctly
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2);
-
- $view = new \OC\Files\View('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2 . '/files');
-
- $this->assertTrue($view->file_exists($this->folder));
- $this->assertTrue($view->file_exists($this->folder . '/test.txt'));
-
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1);
-
- \OCP\Share::unshare('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2);
-
- \OC_Hook::clear('OC_Filesystem', 'post_initMountPoints', '\Test_Files_Sharing_Api', 'initTestMountPointsHook');
- }
- /**
- * @expectedException \Exception
- */
- public function testShareNonExisting() {
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1);
-
- $id = PHP_INT_MAX - 1;
- \OCP\Share::shareItem('file', $id, \OCP\Share::SHARE_TYPE_LINK, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31);
- }
-
- /**
- * @expectedException \Exception
- */
- public function testShareNotOwner() {
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2);
- \OC\Files\Filesystem::file_put_contents('foo.txt', 'bar');
- $info = \OC\Files\Filesystem::getFileInfo('foo.txt');
-
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1);
-
- \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_LINK, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31);
- }
-
- public function testDefaultExpireDate() {
- \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1);
-
- // TODO drop this once all code paths use the DI version - otherwise
- // the cache inside this config object is out of date because
- // OC_Appconfig is used and bypasses this cache which lead to integrity
- // constraint violations
- $config = \OC::$server->getConfig();
- $config->deleteAppValue('core', 'shareapi_default_expire_date');
- $config->deleteAppValue('core', 'shareapi_enforce_expire_date');
- $config->deleteAppValue('core', 'shareapi_expire_after_n_days');
-
- $config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
- $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
- $config->setAppValue('core', 'shareapi_expire_after_n_days', '2');
-
- // default expire date is set to 2 days
- // the time when the share was created is set to 3 days in the past
- // user defined expire date is set to +2 days from now on
- // -> link should be already expired by the default expire date but the user
- // share should still exists.
- $now = time();
- $dateFormat = 'Y-m-d H:i:s';
- $shareCreated = $now - 3 * 24 * 60 * 60;
- $expireDate = date($dateFormat, $now + 2 * 24 * 60 * 60);
-
- $info = OC\Files\Filesystem::getFileInfo($this->filename);
- $this->assertTrue($info instanceof \OC\Files\FileInfo);
-
- $result = \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_LINK, null, \OCP\Constants::PERMISSION_READ);
- $this->assertTrue(is_string($result));
-
- $result = \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31);
- $this->assertTrue($result);
-
- $result = \OCP\Share::setExpirationDate('file', $info->getId() , $expireDate, $now);
- $this->assertTrue($result);
-
- //manipulate stime so that both shares are older then the default expire date
- $statement = "UPDATE `*PREFIX*share` SET `stime` = ? WHERE `share_type` = ?";
- $query = \OCP\DB::prepare($statement);
- $result = $query->execute(array($shareCreated, \OCP\Share::SHARE_TYPE_LINK));
- $this->assertSame(1, $result);
- $query = \OCP\DB::prepare($statement);
- $result = $query->execute(array($shareCreated, \OCP\Share::SHARE_TYPE_USER));
- $this->assertSame(1, $result);
-
- // now the link share should expire because of enforced default expire date
- // the user share should still exist
- $result = \OCP\Share::getItemShared('file', $info->getId());
- $this->assertTrue(is_array($result));
- $this->assertSame(1, count($result));
- $share = reset($result);
- $this->assertSame(\OCP\Share::SHARE_TYPE_USER, $share['share_type']);
-
- //cleanup
- $result = \OCP\Share::unshare('file', $info->getId(), \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
- $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
- $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
-
- }
-
- public function datesProvider() {
- $date = new \DateTime();
- $date->add(new \DateInterval('P5D'));
-
- return [
- [$date->format('Y-m-d'), true],
- ['abc', false],
- [$date->format('Y-m-d') . 'xyz', false],
- ];
- }
-
- /**
- * Make sure only ISO 8601 dates are accepted
- *
- * @dataProvider datesProvider
- */
- public function testPublicLinkExpireDate($date, $valid) {
- $request = $this->createRequest([
- 'path' => $this->folder,
- 'shareType' => \OCP\Share::SHARE_TYPE_LINK,
- 'expireDate' => $date,
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
-
- if ($valid === false) {
- $this->assertFalse($result->succeeded());
- $this->assertEquals(404, $result->getStatusCode());
- $this->assertEquals('Invalid Date. Format must be YYYY-MM-DD.', $result->getMeta()['message']);
- return;
- }
-
- $this->assertTrue($result->succeeded());
-
- $data = $result->getData();
- $this->assertTrue(is_string($data['token']));
- $this->assertEquals($date, substr($data['expiration'], 0, 10));
-
- // check for correct link
- $url = \OC::$server->getURLGenerator()->getAbsoluteURL('/index.php/s/' . $data['token']);
- $this->assertEquals($url, $data['url']);
-
- $share = $this->shareManager->getShareById('ocinternal:'.$data['id']);
-
- $this->assertEquals($date, $share->getExpirationDate()->format('Y-m-d'));
-
- $this->shareManager->deleteShare($share);
- }
-
- public function testCreatePublicLinkExpireDateValid() {
- $config = \OC::$server->getConfig();
-
- // enforce expire date, by default 7 days after the file was shared
- $config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
- $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
-
- $date = new \DateTime();
- $date->add(new \DateInterval('P5D'));
-
- $request = $this->createRequest([
- 'path' => $this->folder,
- 'shareType' => \OCP\Share::SHARE_TYPE_LINK,
- 'expireDate' => $date->format('Y-m-d'),
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
- $this->assertTrue($result->succeeded());
-
- $data = $result->getData();
- $this->assertTrue(is_string($data['token']));
- $this->assertEquals($date->format('Y-m-d') . ' 00:00:00', $data['expiration']);
-
- // check for correct link
- $url = \OC::$server->getURLGenerator()->getAbsoluteURL('/index.php/s/' . $data['token']);
- $this->assertEquals($url, $data['url']);
-
- $share = $this->shareManager->getShareById('ocinternal:'.$data['id']);
- $date->setTime(0,0,0);
- $this->assertEquals($date, $share->getExpirationDate());
-
- $this->shareManager->deleteShare($share);
-
- $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
- $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
- }
-
- public function testCreatePublicLinkExpireDateInvalidFuture() {
- $config = \OC::$server->getConfig();
-
- // enforce expire date, by default 7 days after the file was shared
- $config->setAppValue('core', 'shareapi_default_expire_date', 'yes');
- $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
-
- $date = new \DateTime();
- $date->add(new \DateInterval('P8D'));
-
- $request = $this->createRequest([
- 'path' => $this->folder,
- 'shareType' => \OCP\Share::SHARE_TYPE_LINK,
- 'expireDate' => $date->format('Y-m-d'),
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
- $this->assertFalse($result->succeeded());
- $this->assertEquals(404, $result->getStatusCode());
- $this->assertEquals('Cannot set expiration date more than 7 days in the future', $result->getMeta()['message']);
-
- $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
- $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
- }
-
- public function testCreatePublicLinkExpireDateInvalidPast() {
- $config = \OC::$server->getConfig();
-
- $date = new \DateTime();
- $date->sub(new \DateInterval('P8D'));
-
- $request = $this->createRequest([
- 'path' => $this->folder,
- 'shareType' => \OCP\Share::SHARE_TYPE_LINK,
- 'expireDate' => $date->format('Y-m-d'),
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
- $this->assertFalse($result->succeeded());
- $this->assertEquals(404, $result->getStatusCode());
- $this->assertEquals('Expiration date is in the past', $result->getMeta()['message']);
-
- $config->setAppValue('core', 'shareapi_default_expire_date', 'no');
- $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no');
- }
-
- /**
- * test for no invisible shares
- * See: https://github.com/owncloud/core/issues/22295
- */
- public function testInvisibleSharesUser() {
- // simulate a post request
- $request = $this->createRequest([
- 'path' => $this->folder,
- 'shareWith' => self::TEST_FILES_SHARING_API_USER2,
- 'shareType' => \OCP\Share::SHARE_TYPE_USER
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
- $this->assertTrue($result->succeeded());
- $data = $result->getData();
-
- $topId = $data['id'];
-
- $request = $this->createRequest([
- 'path' => $this->folder . $this->subfolder,
- 'shareType' => \OCP\Share::SHARE_TYPE_LINK,
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER2);
- $result = $ocs->createShare();
- $this->assertTrue($result->succeeded());
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($topId);
- $this->assertTrue($result->succeeded());
-
- $request = $this->createRequest([
- 'reshares' => 'true',
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- $this->assertEmpty($result->getData());
- }
-
- /**
- * test for no invisible shares
- * See: https://github.com/owncloud/core/issues/22295
- */
- public function testInvisibleSharesGroup() {
- // simulate a post request
- $request = $this->createRequest([
- 'path' => $this->folder,
- 'shareWith' => self::TEST_FILES_SHARING_API_GROUP1,
- 'shareType' => \OCP\Share::SHARE_TYPE_GROUP
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->createShare();
- $this->assertTrue($result->succeeded());
- $data = $result->getData();
-
- $topId = $data['id'];
-
- $request = $this->createRequest([
- 'path' => $this->folder . $this->subfolder,
- 'shareType' => \OCP\Share::SHARE_TYPE_LINK,
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER2);
- $result = $ocs->createShare();
- $this->assertTrue($result->succeeded());
-
- $request = $this->createRequest([]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->deleteShare($topId);
- $this->assertTrue($result->succeeded());
-
- $request = $this->createRequest([
- 'reshares' => 'true',
- ]);
- $ocs = $this->createOCS($request, self::TEST_FILES_SHARING_API_USER1);
- $result = $ocs->getShares();
- $this->assertTrue($result->succeeded());
-
- $this->assertEmpty($result->getData());
- }
-}
diff --git a/apps/files_sharing/tests/api/share20ocstest.php b/apps/files_sharing/tests/api/share20ocstest.php
deleted file mode 100644
index 42a23b43ce1..00000000000
--- a/apps/files_sharing/tests/api/share20ocstest.php
+++ /dev/null
@@ -1,1952 +0,0 @@
-<?php
-/**
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-namespace OCA\Files_Sharing\Tests\API;
-
-use OCA\Files_Sharing\API\Share20OCS;
-use OCP\Files\NotFoundException;
-use OCP\IGroupManager;
-use OCP\IUserManager;
-use OCP\IRequest;
-use OCP\IURLGenerator;
-use OCP\IUser;
-use OCP\Files\IRootFolder;
-
-/**
- * Class Share20OCSTest
- *
- * @package OCA\Files_Sharing\Tests\API
- * @group DB
- */
-class Share20OCSTest extends \Test\TestCase {
-
- /** @var \OC\Share20\Manager | \PHPUnit_Framework_MockObject_MockObject */
- private $shareManager;
-
- /** @var IGroupManager | \PHPUnit_Framework_MockObject_MockObject */
- private $groupManager;
-
- /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */
- private $userManager;
-
- /** @var IRequest | \PHPUnit_Framework_MockObject_MockObject */
- private $request;
-
- /** @var IRootFolder | \PHPUnit_Framework_MockObject_MockObject */
- private $rootFolder;
-
- /** @var IURLGenerator */
- private $urlGenerator;
-
- /** @var IUser */
- private $currentUser;
-
- /** @var Share20OCS */
- private $ocs;
-
- protected function setUp() {
- $this->shareManager = $this->getMockBuilder('OCP\Share\IManager')
- ->disableOriginalConstructor()
- ->getMock();
- $this->shareManager
- ->expects($this->any())
- ->method('shareApiEnabled')
- ->willReturn(true);
- $this->groupManager = $this->getMock('OCP\IGroupManager');
- $this->userManager = $this->getMock('OCP\IUserManager');
- $this->request = $this->getMock('OCP\IRequest');
- $this->rootFolder = $this->getMock('OCP\Files\IRootFolder');
- $this->urlGenerator = $this->getMock('OCP\IURLGenerator');
- $this->currentUser = $this->getMock('OCP\IUser');
- $this->currentUser->method('getUID')->willReturn('currentUser');
-
- $this->ocs = new Share20OCS(
- $this->shareManager,
- $this->groupManager,
- $this->userManager,
- $this->request,
- $this->rootFolder,
- $this->urlGenerator,
- $this->currentUser
- );
- }
-
- private function mockFormatShare() {
- return $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
- ->setConstructorArgs([
- $this->shareManager,
- $this->groupManager,
- $this->userManager,
- $this->request,
- $this->rootFolder,
- $this->urlGenerator,
- $this->currentUser
- ])->setMethods(['formatShare'])
- ->getMock();
- }
-
- private function newShare() {
- return \OC::$server->getShareManager()->newShare();
- }
-
- public function testDeleteShareShareNotFound() {
- $this->shareManager
- ->expects($this->exactly(2))
- ->method('getShareById')
- ->will($this->returnCallback(function($id) {
- if ($id === 'ocinternal:42' || $id === 'ocFederatedSharing:42') {
- throw new \OCP\Share\Exceptions\ShareNotFound();
- } else {
- throw new \Exception();
- }
- }));
-
- $this->shareManager->method('outgoingServer2ServerSharesAllowed')->willReturn(true);
-
- $expected = new \OC_OCS_Result(null, 404, 'wrong share ID, share doesn\'t exist.');
- $this->assertEquals($expected, $this->ocs->deleteShare(42));
- }
-
- public function testDeleteShare() {
- $share = $this->newShare();
- $share->setSharedBy($this->currentUser->getUID());
- $this->shareManager
- ->expects($this->once())
- ->method('getShareById')
- ->with('ocinternal:42')
- ->willReturn($share);
- $this->shareManager
- ->expects($this->once())
- ->method('deleteShare')
- ->with($share);
-
- $expected = new \OC_OCS_Result();
- $this->assertEquals($expected, $this->ocs->deleteShare(42));
- }
-
- /*
- * FIXME: Enable once we have a federated Share Provider
-
- public function testGetGetShareNotExists() {
- $this->shareManager
- ->expects($this->once())
- ->method('getShareById')
- ->with('ocinternal:42')
- ->will($this->throwException(new \OC\Share20\Exception\ShareNotFound()));
-
- $expected = new \OC_OCS_Result(null, 404, 'wrong share ID, share doesn\'t exist.');
- $this->assertEquals($expected, $this->ocs->getShare(42));
- }
- */
-
- public function createShare($id, $shareType, $sharedWith, $sharedBy, $shareOwner, $path, $permissions,
- $shareTime, $expiration, $parent, $target, $mail_send, $token=null,
- $password=null) {
- $share = $this->getMock('\OCP\Share\IShare');
- $share->method('getId')->willReturn($id);
- $share->method('getShareType')->willReturn($shareType);
- $share->method('getSharedWith')->willReturn($sharedWith);
- $share->method('getSharedBy')->willReturn($sharedBy);
- $share->method('getShareOwner')->willReturn($shareOwner);
- $share->method('getNode')->willReturn($path);
- $share->method('getPermissions')->willReturn($permissions);
- $time = new \DateTime();
- $time->setTimestamp($shareTime);
- $share->method('getShareTime')->willReturn($time);
- $share->method('getExpirationDate')->willReturn($expiration);
- $share->method('getTarget')->willReturn($target);
- $share->method('getMailSend')->willReturn($mail_send);
- $share->method('getToken')->willReturn($token);
- $share->method('getPassword')->willReturn($password);
-
- if ($shareType === \OCP\Share::SHARE_TYPE_USER ||
- $shareType === \OCP\Share::SHARE_TYPE_GROUP ||
- $shareType === \OCP\Share::SHARE_TYPE_LINK) {
- $share->method('getFullId')->willReturn('ocinternal:'.$id);
- }
-
- return $share;
- }
-
- public function dataGetShare() {
- $data = [];
-
- $cache = $this->getMockBuilder('OC\Files\Cache\Cache')
- ->disableOriginalConstructor()
- ->getMock();
- $cache->method('getNumericStorageId')->willReturn(101);
-
- $storage = $this->getMockBuilder('OC\Files\Storage\Storage')
- ->disableOriginalConstructor()
- ->getMock();
- $storage->method('getId')->willReturn('STORAGE');
- $storage->method('getCache')->willReturn($cache);
-
- $parentFolder = $this->getMock('OCP\Files\Folder');
- $parentFolder->method('getId')->willReturn(3);
-
- $file = $this->getMock('OCP\Files\File');
- $file->method('getId')->willReturn(1);
- $file->method('getPath')->willReturn('file');
- $file->method('getStorage')->willReturn($storage);
- $file->method('getParent')->willReturn($parentFolder);
- $file->method('getMimeType')->willReturn('myMimeType');
-
- $folder = $this->getMock('OCP\Files\Folder');
- $folder->method('getId')->willReturn(2);
- $folder->method('getPath')->willReturn('folder');
- $folder->method('getStorage')->willReturn($storage);
- $folder->method('getParent')->willReturn($parentFolder);
- $folder->method('getMimeType')->willReturn('myFolderMimeType');
-
- // File shared with user
- $share = $this->createShare(
- 100,
- \OCP\Share::SHARE_TYPE_USER,
- 'userId',
- 'initiatorId',
- 'ownerId',
- $file,
- 4,
- 5,
- null,
- 6,
- 'target',
- 0
- );
- $expected = [
- 'id' => 100,
- 'share_type' => \OCP\Share::SHARE_TYPE_USER,
- 'share_with' => 'userId',
- 'share_with_displayname' => 'userDisplay',
- 'uid_owner' => 'initiatorId',
- 'displayname_owner' => 'initiatorDisplay',
- 'item_type' => 'file',
- 'item_source' => 1,
- 'file_source' => 1,
- 'file_target' => 'target',
- 'file_parent' => 3,
- 'token' => null,
- 'expiration' => null,
- 'permissions' => 4,
- 'stime' => 5,
- 'parent' => null,
- 'storage_id' => 'STORAGE',
- 'path' => 'file',
- 'storage' => 101,
- 'mail_send' => 0,
- 'uid_file_owner' => 'ownerId',
- 'displayname_file_owner' => 'ownerDisplay',
- 'mimetype' => 'myMimeType',
- ];
- $data[] = [$share, $expected];
-
- // Folder shared with group
- $share = $this->createShare(
- 101,
- \OCP\Share::SHARE_TYPE_GROUP,
- 'groupId',
- 'initiatorId',
- 'ownerId',
- $folder,
- 4,
- 5,
- null,
- 6,
- 'target',
- 0
- );
- $expected = [
- 'id' => 101,
- 'share_type' => \OCP\Share::SHARE_TYPE_GROUP,
- 'share_with' => 'groupId',
- 'share_with_displayname' => 'groupId',
- 'uid_owner' => 'initiatorId',
- 'displayname_owner' => 'initiatorDisplay',
- 'item_type' => 'folder',
- 'item_source' => 2,
- 'file_source' => 2,
- 'file_target' => 'target',
- 'file_parent' => 3,
- 'token' => null,
- 'expiration' => null,
- 'permissions' => 4,
- 'stime' => 5,
- 'parent' => null,
- 'storage_id' => 'STORAGE',
- 'path' => 'folder',
- 'storage' => 101,
- 'mail_send' => 0,
- 'uid_file_owner' => 'ownerId',
- 'displayname_file_owner' => 'ownerDisplay',
- 'mimetype' => 'myFolderMimeType',
- ];
- $data[] = [$share, $expected];
-
- // File shared by link with Expire
- $expire = \DateTime::createFromFormat('Y-m-d h:i:s', '2000-01-02 01:02:03');
- $share = $this->createShare(
- 101,
- \OCP\Share::SHARE_TYPE_LINK,
- null,
- 'initiatorId',
- 'ownerId',
- $folder,
- 4,
- 5,
- $expire,
- 6,
- 'target',
- 0,
- 'token',
- 'password'
- );
- $expected = [
- 'id' => 101,
- 'share_type' => \OCP\Share::SHARE_TYPE_LINK,
- 'share_with' => 'password',
- 'share_with_displayname' => 'password',
- 'uid_owner' => 'initiatorId',
- 'displayname_owner' => 'initiatorDisplay',
- 'item_type' => 'folder',
- 'item_source' => 2,
- 'file_source' => 2,
- 'file_target' => 'target',
- 'file_parent' => 3,
- 'token' => 'token',
- 'expiration' => '2000-01-02 00:00:00',
- 'permissions' => 4,
- 'stime' => 5,
- 'parent' => null,
- 'storage_id' => 'STORAGE',
- 'path' => 'folder',
- 'storage' => 101,
- 'mail_send' => 0,
- 'url' => 'url',
- 'uid_file_owner' => 'ownerId',
- 'displayname_file_owner' => 'ownerDisplay',
- 'mimetype' => 'myFolderMimeType',
- ];
- $data[] = [$share, $expected];
-
- return $data;
- }
-
- /**
- * @dataProvider dataGetShare
- */
- public function testGetShare(\OCP\Share\IShare $share, array $result) {
- $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
- ->setConstructorArgs([
- $this->shareManager,
- $this->groupManager,
- $this->userManager,
- $this->request,
- $this->rootFolder,
- $this->urlGenerator,
- $this->currentUser
- ])->setMethods(['canAccessShare'])
- ->getMock();
-
- $ocs->method('canAccessShare')->willReturn(true);
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareById')
- ->with($share->getFullId())
- ->willReturn($share);
-
- $userFolder = $this->getMock('OCP\Files\Folder');
- $userFolder
- ->method('getRelativePath')
- ->will($this->returnArgument(0));
-
- $this->rootFolder->method('getUserFolder')
- ->with($share->getShareOwner())
- ->willReturn($userFolder);
-
- $this->urlGenerator
- ->method('linkToRouteAbsolute')
- ->willReturn('url');
-
- $initiator = $this->getMock('OCP\IUser');
- $initiator->method('getUID')->willReturn('initiatorId');
- $initiator->method('getDisplayName')->willReturn('initiatorDisplay');
-
- $owner = $this->getMock('OCP\IUser');
- $owner->method('getUID')->willReturn('ownerId');
- $owner->method('getDisplayName')->willReturn('ownerDisplay');
-
- $user = $this->getMock('OCP\IUser');
- $user->method('getUID')->willReturn('userId');
- $user->method('getDisplayName')->willReturn('userDisplay');
-
- $group = $this->getMock('OCP\IGroup');
- $group->method('getGID')->willReturn('groupId');
-
- $this->userManager->method('get')->will($this->returnValueMap([
- ['userId', $user],
- ['initiatorId', $initiator],
- ['ownerId', $owner],
- ]));
- $this->groupManager->method('get')->will($this->returnValueMap([
- ['group', $group],
- ]));
-
- $expected = new \OC_OCS_Result([$result]);
- $this->assertEquals($expected->getData(), $ocs->getShare($share->getId())->getData());
- }
-
- public function testGetShareInvalidNode() {
- $share = \OC::$server->getShareManager()->newShare();
- $share->setSharedBy('initiator')
- ->setSharedWith('recipient')
- ->setShareOwner('owner');
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareById')
- ->with('ocinternal:42')
- ->willReturn($share);
-
- $expected = new \OC_OCS_Result(null, 404, 'wrong share ID, share doesn\'t exist.');
- $this->assertEquals($expected->getMeta(), $this->ocs->getShare(42)->getMeta());
- }
-
- public function testCanAccessShare() {
- $share = $this->getMock('OCP\Share\IShare');
- $share->method('getShareOwner')->willReturn($this->currentUser->getUID());
- $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
- $share = $this->getMock('OCP\Share\IShare');
- $share->method('getSharedBy')->willReturn($this->currentUser->getUID());
- $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
- $share = $this->getMock('OCP\Share\IShare');
- $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER);
- $share->method('getSharedWith')->willReturn($this->currentUser->getUID());
- $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
- $share = $this->getMock('OCP\Share\IShare');
- $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER);
- $share->method('getSharedWith')->willReturn($this->getMock('OCP\IUser'));
- $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
- $share = $this->getMock('OCP\Share\IShare');
- $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP);
- $share->method('getSharedWith')->willReturn('group');
-
- $group = $this->getMock('OCP\IGroup');
- $group->method('inGroup')->with($this->currentUser)->willReturn(true);
- $group2 = $this->getMock('OCP\IGroup');
- $group2->method('inGroup')->with($this->currentUser)->willReturn(false);
-
-
- $this->groupManager->method('get')->will($this->returnValueMap([
- ['group', $group],
- ['group2', $group2],
- ]));
- $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
- $share = $this->getMock('OCP\Share\IShare');
- $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP);
- $share->method('getSharedWith')->willReturn('group2');
-
- $this->groupManager->method('get')->with('group2')->willReturn($group);
- $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
-
- $share = $this->getMock('OCP\Share\IShare');
- $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK);
- $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
- }
-
- public function testCreateShareNoPath() {
- $expected = new \OC_OCS_Result(null, 404, 'please specify a file or folder path');
-
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareInvalidPath() {
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'invalid-path'],
- ]));
-
- $userFolder = $this->getMock('\OCP\Files\Folder');
- $this->rootFolder->expects($this->once())
- ->method('getUserFolder')
- ->with('currentUser')
- ->willReturn($userFolder);
-
- $userFolder->expects($this->once())
- ->method('get')
- ->with('invalid-path')
- ->will($this->throwException(new \OCP\Files\NotFoundException()));
-
- $expected = new \OC_OCS_Result(null, 404, 'wrong path, file/folder doesn\'t exist');
-
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareInvalidPermissions() {
- $share = $this->getMock('\OCP\Share\IShare');
- $this->shareManager->method('newShare')->willReturn($share);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['permissions', null, 32],
- ]));
-
- $userFolder = $this->getMock('\OCP\Files\Folder');
- $this->rootFolder->expects($this->once())
- ->method('getUserFolder')
- ->with('currentUser')
- ->willReturn($userFolder);
-
- $path = $this->getMock('\OCP\Files\File');
- $userFolder->expects($this->once())
- ->method('get')
- ->with('valid-path')
- ->willReturn($path);
-
- $expected = new \OC_OCS_Result(null, 404, 'invalid permissions');
-
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareUserNoShareWith() {
- $share = $this->getMock('\OCP\Share\IShare');
- $this->shareManager->method('newShare')->willReturn($share);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['permissions', null, \OCP\Constants::PERMISSION_ALL],
- ['shareType', $this->any(), \OCP\Share::SHARE_TYPE_USER],
- ]));
-
- $userFolder = $this->getMock('\OCP\Files\Folder');
- $this->rootFolder->expects($this->once())
- ->method('getUserFolder')
- ->with('currentUser')
- ->willReturn($userFolder);
-
- $path = $this->getMock('\OCP\Files\File');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $userFolder->expects($this->once())
- ->method('get')
- ->with('valid-path')
- ->willReturn($path);
-
- $expected = new \OC_OCS_Result(null, 404, 'please specify a valid user');
-
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareUserNoValidShareWith() {
- $share = $this->getMock('\OCP\Share\IShare');
- $this->shareManager->method('newShare')->willReturn($share);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['permissions', null, \OCP\Constants::PERMISSION_ALL],
- ['shareType', $this->any(), \OCP\Share::SHARE_TYPE_USER],
- ['shareWith', $this->any(), 'invalidUser'],
- ]));
-
- $userFolder = $this->getMock('\OCP\Files\Folder');
- $this->rootFolder->expects($this->once())
- ->method('getUserFolder')
- ->with('currentUser')
- ->willReturn($userFolder);
-
- $path = $this->getMock('\OCP\Files\File');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $userFolder->expects($this->once())
- ->method('get')
- ->with('valid-path')
- ->willReturn($path);
-
- $expected = new \OC_OCS_Result(null, 404, 'please specify a valid user');
-
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareUser() {
- $share = $this->getMock('\OCP\Share\IShare');
- $this->shareManager->method('newShare')->willReturn($share);
- $this->shareManager->method('createShare')->will($this->returnArgument(0));
-
- $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
- ->setConstructorArgs([
- $this->shareManager,
- $this->groupManager,
- $this->userManager,
- $this->request,
- $this->rootFolder,
- $this->urlGenerator,
- $this->currentUser
- ])->setMethods(['formatShare'])
- ->getMock();
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['permissions', null, \OCP\Constants::PERMISSION_ALL],
- ['shareType', $this->any(), \OCP\Share::SHARE_TYPE_USER],
- ['shareWith', null, 'validUser'],
- ]));
-
- $userFolder = $this->getMock('\OCP\Files\Folder');
- $this->rootFolder->expects($this->once())
- ->method('getUserFolder')
- ->with('currentUser')
- ->willReturn($userFolder);
-
- $path = $this->getMock('\OCP\Files\File');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $userFolder->expects($this->once())
- ->method('get')
- ->with('valid-path')
- ->willReturn($path);
-
- $user = $this->getMock('\OCP\IUser');
- $this->userManager->method('userExists')->with('validUser')->willReturn(true);
-
- $share->method('setPath')->with($path);
- $share->method('setPermissions')
- ->with(
- \OCP\Constants::PERMISSION_ALL &
- ~\OCP\Constants::PERMISSION_DELETE &
- ~\OCP\Constants::PERMISSION_CREATE);
- $share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_USER);
- $share->method('setSharedWith')->with('validUser');
- $share->method('setSharedBy')->with('currentUser');
-
- $expected = new \OC_OCS_Result();
- $result = $ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareGroupNoValidShareWith() {
- $share = $this->getMock('\OCP\Share\IShare');
- $this->shareManager->method('newShare')->willReturn($share);
- $this->shareManager->method('createShare')->will($this->returnArgument(0));
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['permissions', null, \OCP\Constants::PERMISSION_ALL],
- ['shareType', $this->any(), \OCP\Share::SHARE_TYPE_GROUP],
- ['shareWith', $this->any(), 'invalidGroup'],
- ]));
-
- $userFolder = $this->getMock('\OCP\Files\Folder');
- $this->rootFolder->expects($this->once())
- ->method('getUserFolder')
- ->with('currentUser')
- ->willReturn($userFolder);
-
- $path = $this->getMock('\OCP\Files\File');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $userFolder->expects($this->once())
- ->method('get')
- ->with('valid-path')
- ->willReturn($path);
-
- $expected = new \OC_OCS_Result(null, 404, 'please specify a valid user');
-
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareGroup() {
- $share = $this->getMock('\OCP\Share\IShare');
- $this->shareManager->method('newShare')->willReturn($share);
- $this->shareManager->method('createShare')->will($this->returnArgument(0));
-
- $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
- ->setConstructorArgs([
- $this->shareManager,
- $this->groupManager,
- $this->userManager,
- $this->request,
- $this->rootFolder,
- $this->urlGenerator,
- $this->currentUser
- ])->setMethods(['formatShare'])
- ->getMock();
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['permissions', null, \OCP\Constants::PERMISSION_ALL],
- ['shareType', '-1', \OCP\Share::SHARE_TYPE_GROUP],
- ['shareWith', null, 'validGroup'],
- ]));
-
- $userFolder = $this->getMock('\OCP\Files\Folder');
- $this->rootFolder->expects($this->once())
- ->method('getUserFolder')
- ->with('currentUser')
- ->willReturn($userFolder);
-
- $path = $this->getMock('\OCP\Files\Folder');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $userFolder->expects($this->once())
- ->method('get')
- ->with('valid-path')
- ->willReturn($path);
-
- $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
-
- $this->shareManager->expects($this->once())
- ->method('allowGroupSharing')
- ->willReturn(true);
-
- $share->method('setPath')->with($path);
- $share->method('setPermissions')->with(\OCP\Constants::PERMISSION_ALL);
- $share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_GROUP);
- $share->method('setSharedWith')->with('validGroup');
- $share->method('setSharedBy')->with('currentUser');
-
- $expected = new \OC_OCS_Result();
- $result = $ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareGroupNotAllowed() {
- $share = $this->getMock('\OCP\Share\IShare');
- $this->shareManager->method('newShare')->willReturn($share);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['permissions', null, \OCP\Constants::PERMISSION_ALL],
- ['shareType', '-1', \OCP\Share::SHARE_TYPE_GROUP],
- ['shareWith', null, 'validGroup'],
- ]));
-
- $userFolder = $this->getMock('\OCP\Files\Folder');
- $this->rootFolder->expects($this->once())
- ->method('getUserFolder')
- ->with('currentUser')
- ->willReturn($userFolder);
-
- $path = $this->getMock('\OCP\Files\Folder');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $userFolder->expects($this->once())
- ->method('get')
- ->with('valid-path')
- ->willReturn($path);
-
- $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
-
- $this->shareManager->expects($this->once())
- ->method('allowGroupSharing')
- ->willReturn(false);
-
- $share->method('setPath')->with($path);
-
- $expected = new \OC_OCS_Result(null, 404, 'group sharing is disabled by the administrator');
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareLinkNoLinksAllowed() {
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
- ]));
-
- $path = $this->getMock('\OCP\Files\Folder');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
- $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
- $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
-
- $expected = new \OC_OCS_Result(null, 404, 'public link sharing is disabled by the administrator');
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareLinkNoPublicUpload() {
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
- ['publicUpload', null, 'true'],
- ]));
-
- $path = $this->getMock('\OCP\Files\Folder');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
- $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
- $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
- $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
-
- $expected = new \OC_OCS_Result(null, 403, 'public upload disabled by the administrator');
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareLinkPublicUploadFile() {
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
- ['publicUpload', null, 'true'],
- ]));
-
- $path = $this->getMock('\OCP\Files\File');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
- $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
- $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
- $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $expected = new \OC_OCS_Result(null, 404, 'public upload is only possible for public shared folders');
- $result = $this->ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareLinkPublicUploadFolder() {
- $ocs = $this->mockFormatShare();
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
- ['publicUpload', null, 'true'],
- ['expireDate', '', ''],
- ['password', '', ''],
- ]));
-
- $path = $this->getMock('\OCP\Files\Folder');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
- $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
- $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
- $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $this->shareManager->expects($this->once())->method('createShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) use ($path) {
- return $share->getNode() === $path &&
- $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
- $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE &&
- $share->getSharedBy() === 'currentUser' &&
- $share->getPassword() === null &&
- $share->getExpirationDate() === null;
- })
- )->will($this->returnArgument(0));
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareLinkPassword() {
- $ocs = $this->mockFormatShare();
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
- ['publicUpload', null, 'false'],
- ['expireDate', '', ''],
- ['password', '', 'password'],
- ]));
-
- $path = $this->getMock('\OCP\Files\Folder');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
- $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
- $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
- $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $this->shareManager->expects($this->once())->method('createShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) use ($path) {
- return $share->getNode() === $path &&
- $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
- $share->getPermissions() === \OCP\Constants::PERMISSION_READ &&
- $share->getSharedBy() === 'currentUser' &&
- $share->getPassword() === 'password' &&
- $share->getExpirationDate() === null;
- })
- )->will($this->returnArgument(0));
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareValidExpireDate() {
- $ocs = $this->mockFormatShare();
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
- ['publicUpload', null, 'false'],
- ['expireDate', '', '2000-01-01'],
- ['password', '', ''],
- ]));
-
- $path = $this->getMock('\OCP\Files\Folder');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
- $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
- $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
- $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $this->shareManager->expects($this->once())->method('createShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) use ($path) {
- $date = new \DateTime('2000-01-01');
- $date->setTime(0,0,0);
-
- return $share->getNode() === $path &&
- $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
- $share->getPermissions() === \OCP\Constants::PERMISSION_READ &&
- $share->getSharedBy() === 'currentUser' &&
- $share->getPassword() === null &&
- $share->getExpirationDate() == $date;
- })
- )->will($this->returnArgument(0));
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testCreateShareInvalidExpireDate() {
- $ocs = $this->mockFormatShare();
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK],
- ['publicUpload', null, 'false'],
- ['expireDate', '', 'a1b2d3'],
- ['password', '', ''],
- ]));
-
- $path = $this->getMock('\OCP\Files\Folder');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(false);
- $path->method('getStorage')->willReturn($storage);
- $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf());
- $this->rootFolder->method('get')->with('valid-path')->willReturn($path);
-
- $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
- $this->shareManager->method('shareApiAllowLinks')->willReturn(true);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $expected = new \OC_OCS_Result(null, 404, 'Invalid Date. Format must be YYYY-MM-DD.');
- $result = $ocs->createShare();
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- /**
- * Test for https://github.com/owncloud/core/issues/22587
- * TODO: Remove once proper solution is in place
- */
- public function testCreateReshareOfFederatedMountNoDeletePermissions() {
- $share = \OC::$server->getShareManager()->newShare();
- $this->shareManager->method('newShare')->willReturn($share);
-
- $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS')
- ->setConstructorArgs([
- $this->shareManager,
- $this->groupManager,
- $this->userManager,
- $this->request,
- $this->rootFolder,
- $this->urlGenerator,
- $this->currentUser
- ])->setMethods(['formatShare'])
- ->getMock();
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['path', null, 'valid-path'],
- ['permissions', null, \OCP\Constants::PERMISSION_ALL],
- ['shareType', $this->any(), \OCP\Share::SHARE_TYPE_USER],
- ['shareWith', null, 'validUser'],
- ]));
-
- $userFolder = $this->getMock('\OCP\Files\Folder');
- $this->rootFolder->expects($this->once())
- ->method('getUserFolder')
- ->with('currentUser')
- ->willReturn($userFolder);
-
- $path = $this->getMock('\OCP\Files\Folder');
- $storage = $this->getMock('OCP\Files\Storage');
- $storage->method('instanceOfStorage')
- ->with('OCA\Files_Sharing\External\Storage')
- ->willReturn(true);
- $path->method('getStorage')->willReturn($storage);
- $path->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_READ);
- $userFolder->expects($this->once())
- ->method('get')
- ->with('valid-path')
- ->willReturn($path);
-
- $this->userManager->method('userExists')->with('validUser')->willReturn(true);
-
- $this->shareManager
- ->expects($this->once())
- ->method('createShare')
- ->with($this->callback(function (\OCP\Share\IShare $share) {
- return $share->getPermissions() === \OCP\Constants::PERMISSION_READ;
- }))
- ->will($this->returnArgument(0));
-
- $ocs->createShare();
- }
-
- public function testUpdateShareCantAccess() {
- $share = \OC::$server->getShareManager()->newShare();
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
- $expected = new \OC_OCS_Result(null, 404, 'wrong share Id, share doesn\'t exist.');
- $result = $this->ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateNoParametersLink() {
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK);
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
- $expected = new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given');
- $result = $this->ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateNoParametersOther() {
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_GROUP);
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
- $expected = new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given');
- $result = $this->ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkShareClear() {
- $ocs = $this->mockFormatShare();
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPassword('password')
- ->setExpirationDate(new \DateTime())
- ->setPermissions(\OCP\Constants::PERMISSION_ALL);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['publicUpload', null, 'false'],
- ['expireDate', null, ''],
- ['password', null, ''],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
- $this->shareManager->expects($this->once())->method('updateShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) {
- return $share->getPermissions() === \OCP\Constants::PERMISSION_READ &&
- $share->getPassword() === null &&
- $share->getExpirationDate() === null;
- })
- )->will($this->returnArgument(0));
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkShareSet() {
- $ocs = $this->mockFormatShare();
-
- $folder = $this->getMock('\OCP\Files\Folder');
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setNode($folder);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['publicUpload', null, 'true'],
- ['expireDate', null, '2000-01-01'],
- ['password', null, 'password'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $this->shareManager->expects($this->once())->method('updateShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) {
- $date = new \DateTime('2000-01-01');
- $date->setTime(0,0,0);
-
- return $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE && \OCP\Constants::PERMISSION_DELETE &&
- $share->getPassword() === 'password' &&
- $share->getExpirationDate() == $date;
- })
- )->will($this->returnArgument(0));
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkShareInvalidDate() {
- $ocs = $this->mockFormatShare();
-
- $folder = $this->getMock('\OCP\Files\Folder');
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setNode($folder);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['publicUpload', null, 'true'],
- ['expireDate', null, '2000-01-a'],
- ['password', null, 'password'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $expected = new \OC_OCS_Result(null, 400, 'Invalid date. Format must be YYYY-MM-DD');
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkSharePublicUploadNotAllowed() {
- $ocs = $this->mockFormatShare();
-
- $folder = $this->getMock('\OCP\Files\Folder');
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setNode($folder);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['publicUpload', null, 'true'],
- ['expireDate', '', null],
- ['password', '', 'password'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false);
-
- $expected = new \OC_OCS_Result(null, 403, 'public upload disabled by the administrator');
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkSharePublicUploadOnFile() {
- $ocs = $this->mockFormatShare();
-
- $file = $this->getMock('\OCP\Files\File');
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setNode($file);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['publicUpload', null, 'true'],
- ['expireDate', '', ''],
- ['password', '', 'password'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $expected = new \OC_OCS_Result(null, 400, 'public upload is only possible for public shared folders');
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkSharePasswordDoesNotChangeOther() {
- $ocs = $this->mockFormatShare();
-
- $date = new \DateTime('2000-01-01');
- $date->setTime(0,0,0);
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPassword('password')
- ->setExpirationDate($date)
- ->setPermissions(\OCP\Constants::PERMISSION_ALL);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['password', null, 'newpassword'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
- $this->shareManager->expects($this->once())->method('updateShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) use ($date) {
- return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
- $share->getPassword() === 'newpassword' &&
- $share->getExpirationDate() === $date;
- })
- )->will($this->returnArgument(0));
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkShareExpireDateDoesNotChangeOther() {
- $ocs = $this->mockFormatShare();
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPassword('password')
- ->setExpirationDate(new \DateTime())
- ->setPermissions(\OCP\Constants::PERMISSION_ALL);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['expireDate', null, '2010-12-23'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
-
- $this->shareManager->expects($this->once())->method('updateShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) {
- $date = new \DateTime('2010-12-23');
- $date->setTime(0,0,0);
-
- return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL &&
- $share->getPassword() === 'password' &&
- $share->getExpirationDate() == $date;
- })
- )->will($this->returnArgument(0));
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkSharePublicUploadDoesNotChangeOther() {
- $ocs = $this->mockFormatShare();
-
- $date = new \DateTime('2000-01-01');
-
- $folder = $this->getMock('\OCP\Files\Folder');
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPassword('password')
- ->setExpirationDate($date)
- ->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setNode($folder);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['publicUpload', null, 'true'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $this->shareManager->expects($this->once())->method('updateShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) use ($date) {
- return $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE &&
- $share->getPassword() === 'password' &&
- $share->getExpirationDate() === $date;
- })
- )->will($this->returnArgument(0));
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkSharePermissions() {
- $ocs = $this->mockFormatShare();
-
- $date = new \DateTime('2000-01-01');
-
- $folder = $this->getMock('\OCP\Files\Folder');
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPassword('password')
- ->setExpirationDate($date)
- ->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setNode($folder);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['permissions', null, '7'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $this->shareManager->expects($this->once())->method('updateShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) use ($date) {
- return $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE &&
- $share->getPassword() === 'password' &&
- $share->getExpirationDate() === $date;
- })
- )->will($this->returnArgument(0));
-
- $this->shareManager->method('getSharedWith')->willReturn([]);
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateLinkShareInvalidPermissions() {
- $ocs = $this->mockFormatShare();
-
- $date = new \DateTime('2000-01-01');
-
- $folder = $this->getMock('\OCP\Files\Folder');
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setPassword('password')
- ->setExpirationDate($date)
- ->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setNode($folder);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['permissions', null, '31'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $expected = new \OC_OCS_Result(null, 400, 'can\'t change permission for public link share');
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function testUpdateOtherPermissions() {
- $ocs = $this->mockFormatShare();
-
- $file = $this->getMock('\OCP\Files\File');
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPermissions(\OCP\Constants::PERMISSION_ALL)
- ->setSharedBy($this->currentUser->getUID())
- ->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setNode($file);
-
- $this->request
- ->method('getParam')
- ->will($this->returnValueMap([
- ['permissions', null, '31'],
- ]));
-
- $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
- $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
-
- $this->shareManager->expects($this->once())->method('updateShare')->with(
- $this->callback(function (\OCP\Share\IShare $share) {
- return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL;
- })
- )->will($this->returnArgument(0));
-
- $this->shareManager->method('getSharedWith')->willReturn([]);
-
- $expected = new \OC_OCS_Result(null);
- $result = $ocs->updateShare(42);
-
- $this->assertEquals($expected->getMeta(), $result->getMeta());
- $this->assertEquals($expected->getData(), $result->getData());
- }
-
- public function dataFormatShare() {
- $file = $this->getMock('\OCP\Files\File');
- $folder = $this->getMock('\OCP\Files\Folder');
- $parent = $this->getMock('\OCP\Files\Folder');
-
- $file->method('getMimeType')->willReturn('myMimeType');
- $folder->method('getMimeType')->willReturn('myFolderMimeType');
-
- $file->method('getPath')->willReturn('file');
- $folder->method('getPath')->willReturn('folder');
-
- $parent->method('getId')->willReturn(1);
- $folder->method('getId')->willReturn(2);
- $file->method('getId')->willReturn(3);
-
- $file->method('getParent')->willReturn($parent);
- $folder->method('getParent')->willReturn($parent);
-
- $cache = $this->getMock('OCP\Files\Cache\ICache');
- $cache->method('getNumericStorageId')->willReturn(100);
- $storage = $this->getMock('\OCP\Files\Storage');
- $storage->method('getId')->willReturn('storageId');
- $storage->method('getCache')->willReturn($cache);
-
- $file->method('getStorage')->willReturn($storage);
- $folder->method('getStorage')->willReturn($storage);
-
- $owner = $this->getMock('\OCP\IUser');
- $owner->method('getDisplayName')->willReturn('ownerDN');
- $initiator = $this->getMock('\OCP\IUser');
- $initiator->method('getDisplayName')->willReturn('initiatorDN');
- $recipient = $this->getMock('\OCP\IUser');
- $recipient->method('getDisplayName')->willReturn('recipientDN');
-
- $result = [];
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setSharedWith('recipient')
- ->setSharedBy('initiator')
- ->setShareOwner('owner')
- ->setPermissions(\OCP\Constants::PERMISSION_READ)
- ->setNode($file)
- ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
- ->setTarget('myTarget')
- ->setId(42);
-
- /* User backend down */
- $result[] = [
- [
- 'id' => 42,
- 'share_type' => \OCP\Share::SHARE_TYPE_USER,
- 'uid_owner' => 'initiator',
- 'displayname_owner' => 'initiator',
- 'permissions' => 1,
- 'stime' => 946684862,
- 'parent' => null,
- 'expiration' => null,
- 'token' => null,
- 'uid_file_owner' => 'owner',
- 'displayname_file_owner' => 'owner',
- 'path' => 'file',
- 'item_type' => 'file',
- 'storage_id' => 'storageId',
- 'storage' => 100,
- 'item_source' => 3,
- 'file_source' => 3,
- 'file_parent' => 1,
- 'file_target' => 'myTarget',
- 'share_with' => 'recipient',
- 'share_with_displayname' => 'recipient',
- 'mail_send' => 0,
- 'mimetype' => 'myMimeType',
- ], $share, [], false
- ];
-
- /* User backend up */
- $result[] = [
- [
- 'id' => 42,
- 'share_type' => \OCP\Share::SHARE_TYPE_USER,
- 'uid_owner' => 'initiator',
- 'displayname_owner' => 'initiatorDN',
- 'permissions' => 1,
- 'stime' => 946684862,
- 'parent' => null,
- 'expiration' => null,
- 'token' => null,
- 'uid_file_owner' => 'owner',
- 'displayname_file_owner' => 'ownerDN',
- 'path' => 'file',
- 'item_type' => 'file',
- 'storage_id' => 'storageId',
- 'storage' => 100,
- 'item_source' => 3,
- 'file_source' => 3,
- 'file_parent' => 1,
- 'file_target' => 'myTarget',
- 'share_with' => 'recipient',
- 'share_with_displayname' => 'recipientDN',
- 'mail_send' => 0,
- 'mimetype' => 'myMimeType',
- ], $share, [
- ['owner', $owner],
- ['initiator', $initiator],
- ['recipient', $recipient],
- ], false
- ];
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setSharedWith('recipient')
- ->setSharedBy('initiator')
- ->setShareOwner('owner')
- ->setPermissions(\OCP\Constants::PERMISSION_READ)
- ->setNode($file)
- ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
- ->setTarget('myTarget')
- ->setId(42);
-
- /* User backend down */
- $result[] = [
- [
- 'id' => 42,
- 'share_type' => \OCP\Share::SHARE_TYPE_USER,
- 'uid_owner' => 'initiator',
- 'displayname_owner' => 'initiator',
- 'permissions' => 1,
- 'stime' => 946684862,
- 'parent' => null,
- 'expiration' => null,
- 'token' => null,
- 'uid_file_owner' => 'owner',
- 'displayname_file_owner' => 'owner',
- 'path' => 'file',
- 'item_type' => 'file',
- 'storage_id' => 'storageId',
- 'storage' => 100,
- 'item_source' => 3,
- 'file_source' => 3,
- 'file_parent' => 1,
- 'file_target' => 'myTarget',
- 'share_with' => 'recipient',
- 'share_with_displayname' => 'recipient',
- 'mail_send' => 0,
- 'mimetype' => 'myMimeType',
- ], $share, [], false
- ];
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP)
- ->setSharedWith('recipient')
- ->setSharedBy('initiator')
- ->setShareOwner('owner')
- ->setPermissions(\OCP\Constants::PERMISSION_READ)
- ->setNode($file)
- ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
- ->setTarget('myTarget')
- ->setId(42);
-
- $result[] = [
- [
- 'id' => 42,
- 'share_type' => \OCP\Share::SHARE_TYPE_GROUP,
- 'uid_owner' => 'initiator',
- 'displayname_owner' => 'initiator',
- 'permissions' => 1,
- 'stime' => 946684862,
- 'parent' => null,
- 'expiration' => null,
- 'token' => null,
- 'uid_file_owner' => 'owner',
- 'displayname_file_owner' => 'owner',
- 'path' => 'file',
- 'item_type' => 'file',
- 'storage_id' => 'storageId',
- 'storage' => 100,
- 'item_source' => 3,
- 'file_source' => 3,
- 'file_parent' => 1,
- 'file_target' => 'myTarget',
- 'share_with' => 'recipient',
- 'share_with_displayname' => 'recipient',
- 'mail_send' => 0,
- 'mimetype' => 'myMimeType',
- ], $share, [], false
- ];
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setShareType(\OCP\Share::SHARE_TYPE_LINK)
- ->setSharedBy('initiator')
- ->setShareOwner('owner')
- ->setPermissions(\OCP\Constants::PERMISSION_READ)
- ->setNode($file)
- ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
- ->setTarget('myTarget')
- ->setPassword('mypassword')
- ->setExpirationDate(new \DateTime('2001-01-02T00:00:00'))
- ->setToken('myToken')
- ->setId(42);
-
- $result[] = [
- [
- 'id' => 42,
- 'share_type' => \OCP\Share::SHARE_TYPE_LINK,
- 'uid_owner' => 'initiator',
- 'displayname_owner' => 'initiator',
- 'permissions' => 1,
- 'stime' => 946684862,
- 'parent' => null,
- 'expiration' => '2001-01-02 00:00:00',
- 'token' => 'myToken',
- 'uid_file_owner' => 'owner',
- 'displayname_file_owner' => 'owner',
- 'path' => 'file',
- 'item_type' => 'file',
- 'storage_id' => 'storageId',
- 'storage' => 100,
- 'item_source' => 3,
- 'file_source' => 3,
- 'file_parent' => 1,
- 'file_target' => 'myTarget',
- 'share_with' => 'mypassword',
- 'share_with_displayname' => 'mypassword',
- 'mail_send' => 0,
- 'url' => 'myLink',
- 'mimetype' => 'myMimeType',
- ], $share, [], false
- ];
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setShareType(\OCP\Share::SHARE_TYPE_REMOTE)
- ->setSharedBy('initiator')
- ->setSharedWith('user@server.com')
- ->setShareOwner('owner')
- ->setPermissions(\OCP\Constants::PERMISSION_READ)
- ->setNode($folder)
- ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
- ->setTarget('myTarget')
- ->setId(42);
-
- $result[] = [
- [
- 'id' => 42,
- 'share_type' => \OCP\Share::SHARE_TYPE_REMOTE,
- 'uid_owner' => 'initiator',
- 'displayname_owner' => 'initiator',
- 'permissions' => 1,
- 'stime' => 946684862,
- 'parent' => null,
- 'expiration' => null,
- 'token' => null,
- 'uid_file_owner' => 'owner',
- 'displayname_file_owner' => 'owner',
- 'path' => 'folder',
- 'item_type' => 'folder',
- 'storage_id' => 'storageId',
- 'storage' => 100,
- 'item_source' => 2,
- 'file_source' => 2,
- 'file_parent' => 1,
- 'file_target' => 'myTarget',
- 'share_with' => 'user@server.com',
- 'share_with_displayname' => 'user@server.com',
- 'mail_send' => 0,
- 'mimetype' => 'myFolderMimeType',
- ], $share, [], false
- ];
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setShareType(\OCP\Share::SHARE_TYPE_USER)
- ->setSharedBy('initiator')
- ->setSharedWith('recipient')
- ->setShareOwner('owner')
- ->setPermissions(\OCP\Constants::PERMISSION_READ)
- ->setShareTime(new \DateTime('2000-01-01T00:01:02'))
- ->setTarget('myTarget')
- ->setId(42);
-
- $result[] = [
- [], $share, [], true
- ];
-
-
-
- return $result;
- }
-
- /**
- * @dataProvider dataFormatShare
- *
- * @param array $expects
- * @param \OCP\Share\IShare $share
- * @param array $users
- * @param $exception
- */
- public function testFormatShare(array $expects, \OCP\Share\IShare $share, array $users, $exception) {
- $this->userManager->method('get')->will($this->returnValueMap($users));
- $this->urlGenerator->method('linkToRouteAbsolute')
- ->with('files_sharing.sharecontroller.showShare', ['token' => 'myToken'])
- ->willReturn('myLink');
-
-
- $this->rootFolder->method('getUserFolder')->with($share->getShareOwner())->will($this->returnSelf());
- $this->rootFolder->method('getRelativePath')->will($this->returnArgument(0));
-
- try {
- $result = $this->invokePrivate($this->ocs, 'formatShare', [$share]);
- $this->assertFalse($exception);
- $this->assertEquals($expects, $result);
- } catch (NotFoundException $e) {
- $this->assertTrue($exception);
- }
- }
-
- /**
- * @return Share20OCS
- */
- public function getOcsDisabledAPI() {
- $shareManager = $this->getMockBuilder('OCP\Share\IManager')
- ->disableOriginalConstructor()
- ->getMock();
- $shareManager
- ->expects($this->any())
- ->method('shareApiEnabled')
- ->willReturn(false);
-
- return new Share20OCS(
- $shareManager,
- $this->groupManager,
- $this->userManager,
- $this->request,
- $this->rootFolder,
- $this->urlGenerator,
- $this->currentUser
- );
- }
-
- public function testGetShareApiDisabled() {
- $ocs = $this->getOcsDisabledAPI();
-
- $expected = new \OC_OCS_Result(null, 404, 'Share API is disabled');
- $result = $ocs->getShare('my:id');
-
- $this->assertEquals($expected, $result);
- }
-
- public function testDeleteShareApiDisabled() {
- $ocs = $this->getOcsDisabledAPI();
-
- $expected = new \OC_OCS_Result(null, 404, 'Share API is disabled');
- $result = $ocs->deleteShare('my:id');
-
- $this->assertEquals($expected, $result);
- }
-
-
- public function testCreateShareApiDisabled() {
- $ocs = $this->getOcsDisabledAPI();
-
- $expected = new \OC_OCS_Result(null, 404, 'Share API is disabled');
- $result = $ocs->createShare();
-
- $this->assertEquals($expected, $result);
- }
-
- public function testGetSharesApiDisabled() {
- $ocs = $this->getOcsDisabledAPI();
-
- $expected = new \OC_OCS_Result();
- $result = $ocs->getShares();
-
- $this->assertEquals($expected, $result);
- }
-
- public function testUpdateShareApiDisabled() {
- $ocs = $this->getOcsDisabledAPI();
-
- $expected = new \OC_OCS_Result(null, 404, 'Share API is disabled');
- $result = $ocs->updateShare('my:id');
-
- $this->assertEquals($expected, $result);
- }
-}
diff --git a/apps/files_sharing/tests/api/shareestest.php b/apps/files_sharing/tests/api/shareestest.php
deleted file mode 100644
index cda41f55183..00000000000
--- a/apps/files_sharing/tests/api/shareestest.php
+++ /dev/null
@@ -1,1553 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Tests\API;
-
-use OCA\Files_Sharing\API\Sharees;
-use OCA\Files_sharing\Tests\TestCase;
-use OCP\AppFramework\Http;
-use OCP\Share;
-
-/**
- * Class ShareesTest
- *
- * @group DB
- *
- * @package OCA\Files_Sharing\Tests\API
- */
-class ShareesTest extends TestCase {
- /** @var Sharees */
- protected $sharees;
-
- /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */
- protected $userManager;
-
- /** @var \OCP\IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
- protected $groupManager;
-
- /** @var \OCP\Contacts\IManager|\PHPUnit_Framework_MockObject_MockObject */
- protected $contactsManager;
-
- /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */
- protected $session;
-
- /** @var \OCP\IRequest|\PHPUnit_Framework_MockObject_MockObject */
- protected $request;
-
- /** @var \OCP\Share\IManager|\PHPUnit_Framework_MockObject_MockObject */
- protected $shareManager;
-
- protected function setUp() {
- parent::setUp();
-
- $this->userManager = $this->getMockBuilder('OCP\IUserManager')
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->groupManager = $this->getMockBuilder('OCP\IGroupManager')
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->contactsManager = $this->getMockBuilder('OCP\Contacts\IManager')
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->session = $this->getMockBuilder('OCP\IUserSession')
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->request = $this->getMockBuilder('OCP\IRequest')
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->shareManager = $this->getMockBuilder('OCP\Share\IManager')
- ->disableOriginalConstructor()
- ->getMock();
-
- $this->sharees = new Sharees(
- $this->groupManager,
- $this->userManager,
- $this->contactsManager,
- $this->getMockBuilder('OCP\IConfig')->disableOriginalConstructor()->getMock(),
- $this->session,
- $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
- $this->request,
- $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(),
- $this->shareManager
- );
- }
-
- /**
- * @param string $uid
- * @param string $displayName
- * @return \OCP\IUser|\PHPUnit_Framework_MockObject_MockObject
- */
- protected function getUserMock($uid, $displayName) {
- $user = $this->getMockBuilder('OCP\IUser')
- ->disableOriginalConstructor()
- ->getMock();
-
- $user->expects($this->any())
- ->method('getUID')
- ->willReturn($uid);
-
- $user->expects($this->any())
- ->method('getDisplayName')
- ->willReturn($displayName);
-
- return $user;
- }
-
- /**
- * @param string $gid
- * @return \OCP\IGroup|\PHPUnit_Framework_MockObject_MockObject
- */
- protected function getGroupMock($gid) {
- $group = $this->getMockBuilder('OCP\IGroup')
- ->disableOriginalConstructor()
- ->getMock();
-
- $group->expects($this->any())
- ->method('getGID')
- ->willReturn($gid);
-
- return $group;
- }
-
- public function dataGetUsers() {
- return [
- ['test', false, true, [], [], [], [], true, false],
- ['test', false, false, [], [], [], [], true, false],
- ['test', true, true, [], [], [], [], true, false],
- ['test', true, false, [], [], [], [], true, false],
- [
- 'test', false, true, [], [],
- [
- ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']],
- ], [], true, $this->getUserMock('test', 'Test')
- ],
- [
- 'test', false, false, [], [],
- [
- ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']],
- ], [], true, $this->getUserMock('test', 'Test')
- ],
- [
- 'test', true, true, [], [],
- [], [], true, $this->getUserMock('test', 'Test')
- ],
- [
- 'test', true, false, [], [],
- [], [], true, $this->getUserMock('test', 'Test')
- ],
- [
- 'test', true, true, ['test-group'], [['test-group', 'test', 2, 0, []]],
- [
- ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']],
- ], [], true, $this->getUserMock('test', 'Test')
- ],
- [
- 'test', true, false, ['test-group'], [['test-group', 'test', 2, 0, []]],
- [
- ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']],
- ], [], true, $this->getUserMock('test', 'Test')
- ],
- [
- 'test',
- false,
- true,
- [],
- [
- $this->getUserMock('test1', 'Test One'),
- ],
- [],
- [
- ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ],
- true,
- false,
- ],
- [
- 'test',
- false,
- false,
- [],
- [
- $this->getUserMock('test1', 'Test One'),
- ],
- [],
- [],
- true,
- false,
- ],
- [
- 'test',
- false,
- true,
- [],
- [
- $this->getUserMock('test1', 'Test One'),
- $this->getUserMock('test2', 'Test Two'),
- ],
- [],
- [
- ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ['label' => 'Test Two', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
- ],
- false,
- false,
- ],
- [
- 'test',
- false,
- false,
- [],
- [
- $this->getUserMock('test1', 'Test One'),
- $this->getUserMock('test2', 'Test Two'),
- ],
- [],
- [],
- true,
- false,
- ],
- [
- 'test',
- false,
- true,
- [],
- [
- $this->getUserMock('test0', 'Test'),
- $this->getUserMock('test1', 'Test One'),
- $this->getUserMock('test2', 'Test Two'),
- ],
- [
- ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test0']],
- ],
- [
- ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ['label' => 'Test Two', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
- ],
- false,
- false,
- ],
- [
- 'test',
- false,
- false,
- [],
- [
- $this->getUserMock('test0', 'Test'),
- $this->getUserMock('test1', 'Test One'),
- $this->getUserMock('test2', 'Test Two'),
- ],
- [
- ['label' => 'Test', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test0']],
- ],
- [],
- true,
- false,
- ],
- [
- 'test',
- true,
- true,
- ['abc', 'xyz'],
- [
- ['abc', 'test', 2, 0, ['test1' => 'Test One']],
- ['xyz', 'test', 2, 0, []],
- ],
- [],
- [
- ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ],
- true,
- false,
- ],
- [
- 'test',
- true,
- false,
- ['abc', 'xyz'],
- [
- ['abc', 'test', 2, 0, ['test1' => 'Test One']],
- ['xyz', 'test', 2, 0, []],
- ],
- [],
- [],
- true,
- false,
- ],
- [
- 'test',
- true,
- true,
- ['abc', 'xyz'],
- [
- ['abc', 'test', 2, 0, [
- 'test1' => 'Test One',
- 'test2' => 'Test Two',
- ]],
- ['xyz', 'test', 2, 0, [
- 'test1' => 'Test One',
- 'test2' => 'Test Two',
- ]],
- ],
- [],
- [
- ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ['label' => 'Test Two', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
- ],
- false,
- false,
- ],
- [
- 'test',
- true,
- false,
- ['abc', 'xyz'],
- [
- ['abc', 'test', 2, 0, [
- 'test1' => 'Test One',
- 'test2' => 'Test Two',
- ]],
- ['xyz', 'test', 2, 0, [
- 'test1' => 'Test One',
- 'test2' => 'Test Two',
- ]],
- ],
- [],
- [],
- true,
- false,
- ],
- [
- 'test',
- true,
- true,
- ['abc', 'xyz'],
- [
- ['abc', 'test', 2, 0, [
- 'test' => 'Test One',
- ]],
- ['xyz', 'test', 2, 0, [
- 'test2' => 'Test Two',
- ]],
- ],
- [
- ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']],
- ],
- [
- ['label' => 'Test Two', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
- ],
- false,
- false,
- ],
- [
- 'test',
- true,
- false,
- ['abc', 'xyz'],
- [
- ['abc', 'test', 2, 0, [
- 'test' => 'Test One',
- ]],
- ['xyz', 'test', 2, 0, [
- 'test2' => 'Test Two',
- ]],
- ],
- [
- ['label' => 'Test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test']],
- ],
- [],
- true,
- false,
- ],
- ];
- }
-
- /**
- * @dataProvider dataGetUsers
- *
- * @param string $searchTerm
- * @param bool $shareWithGroupOnly
- * @param bool $shareeEnumeration
- * @param array $groupResponse
- * @param array $userResponse
- * @param array $exactExpected
- * @param array $expected
- * @param bool $reachedEnd
- * @param mixed $singleUser
- */
- public function testGetUsers($searchTerm, $shareWithGroupOnly, $shareeEnumeration, $groupResponse, $userResponse, $exactExpected, $expected, $reachedEnd, $singleUser) {
- $this->invokePrivate($this->sharees, 'limit', [2]);
- $this->invokePrivate($this->sharees, 'offset', [0]);
- $this->invokePrivate($this->sharees, 'shareWithGroupOnly', [$shareWithGroupOnly]);
- $this->invokePrivate($this->sharees, 'shareeEnumeration', [$shareeEnumeration]);
-
- $user = $this->getUserMock('admin', 'Administrator');
- $this->session->expects($this->any())
- ->method('getUser')
- ->willReturn($user);
-
- if (!$shareWithGroupOnly) {
- $this->userManager->expects($this->once())
- ->method('searchDisplayName')
- ->with($searchTerm, $this->invokePrivate($this->sharees, 'limit'), $this->invokePrivate($this->sharees, 'offset'))
- ->willReturn($userResponse);
- } else {
- if ($singleUser !== false) {
- $this->groupManager->expects($this->exactly(2))
- ->method('getUserGroupIds')
- ->withConsecutive(
- $user,
- $singleUser
- )
- ->willReturn($groupResponse);
- } else {
- $this->groupManager->expects($this->once())
- ->method('getUserGroupIds')
- ->with($user)
- ->willReturn($groupResponse);
- }
-
- $this->groupManager->expects($this->exactly(sizeof($groupResponse)))
- ->method('displayNamesInGroup')
- ->with($this->anything(), $searchTerm, $this->invokePrivate($this->sharees, 'limit'), $this->invokePrivate($this->sharees, 'offset'))
- ->willReturnMap($userResponse);
- }
-
- if ($singleUser !== false) {
- $this->userManager->expects($this->once())
- ->method('get')
- ->with($searchTerm)
- ->willReturn($singleUser);
- }
-
- $this->invokePrivate($this->sharees, 'getUsers', [$searchTerm]);
- $result = $this->invokePrivate($this->sharees, 'result');
-
- $this->assertEquals($exactExpected, $result['exact']['users']);
- $this->assertEquals($expected, $result['users']);
- $this->assertCount((int) $reachedEnd, $this->invokePrivate($this->sharees, 'reachedEndFor'));
- }
-
- public function dataGetGroups() {
- return [
- ['test', false, true, [], [], [], [], true, false],
- ['test', false, false, [], [], [], [], true, false],
- [
- 'test', false, true,
- [$this->getGroupMock('test1')],
- [],
- [],
- [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
- true,
- false,
- ],
- [
- 'test', false, false,
- [$this->getGroupMock('test1')],
- [],
- [],
- [],
- true,
- false,
- ],
- [
- 'test', false, true,
- [
- $this->getGroupMock('test'),
- $this->getGroupMock('test1'),
- ],
- [],
- [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]],
- [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
- false,
- false,
- ],
- [
- 'test', false, false,
- [
- $this->getGroupMock('test'),
- $this->getGroupMock('test1'),
- ],
- [],
- [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]],
- [],
- true,
- false,
- ],
- [
- 'test', false, true,
- [
- $this->getGroupMock('test0'),
- $this->getGroupMock('test1'),
- ],
- [],
- [],
- [
- ['label' => 'test0', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test0']],
- ['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']],
- ],
- false,
- null,
- ],
- [
- 'test', false, false,
- [
- $this->getGroupMock('test0'),
- $this->getGroupMock('test1'),
- ],
- [],
- [],
- [],
- true,
- null,
- ],
- [
- 'test', false, true,
- [
- $this->getGroupMock('test0'),
- $this->getGroupMock('test1'),
- ],
- [],
- [
- ['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']],
- ],
- [
- ['label' => 'test0', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test0']],
- ['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']],
- ],
- false,
- $this->getGroupMock('test'),
- ],
- [
- 'test', false, false,
- [
- $this->getGroupMock('test0'),
- $this->getGroupMock('test1'),
- ],
- [],
- [
- ['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']],
- ],
- [],
- true,
- $this->getGroupMock('test'),
- ],
- ['test', true, true, [], [], [], [], true, false],
- ['test', true, false, [], [], [], [], true, false],
- [
- 'test', true, true,
- [
- $this->getGroupMock('test1'),
- $this->getGroupMock('test2'),
- ],
- [$this->getGroupMock('test1')],
- [],
- [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
- false,
- false,
- ],
- [
- 'test', true, false,
- [
- $this->getGroupMock('test1'),
- $this->getGroupMock('test2'),
- ],
- [$this->getGroupMock('test1')],
- [],
- [],
- true,
- false,
- ],
- [
- 'test', true, true,
- [
- $this->getGroupMock('test'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test')],
- [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]],
- [],
- false,
- false,
- ],
- [
- 'test', true, false,
- [
- $this->getGroupMock('test'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test')],
- [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]],
- [],
- true,
- false,
- ],
- [
- 'test', true, true,
- [
- $this->getGroupMock('test'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test1')],
- [],
- [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
- false,
- false,
- ],
- [
- 'test', true, false,
- [
- $this->getGroupMock('test'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test1')],
- [],
- [],
- true,
- false,
- ],
- [
- 'test', true, true,
- [
- $this->getGroupMock('test'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
- [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]],
- [['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']]],
- false,
- false,
- ],
- [
- 'test', true, false,
- [
- $this->getGroupMock('test'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
- [['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']]],
- [],
- true,
- false,
- ],
- [
- 'test', true, true,
- [
- $this->getGroupMock('test0'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
- [],
- [
- ['label' => 'test0', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test0']],
- ['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']],
- ],
- false,
- null,
- ],
- [
- 'test', true, false,
- [
- $this->getGroupMock('test0'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
- [],
- [],
- true,
- null,
- ],
- [
- 'test', true, true,
- [
- $this->getGroupMock('test0'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
- [
- ['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']],
- ],
- [
- ['label' => 'test0', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test0']],
- ['label' => 'test1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test1']],
- ],
- false,
- $this->getGroupMock('test'),
- ],
- [
- 'test', true, false,
- [
- $this->getGroupMock('test0'),
- $this->getGroupMock('test1'),
- ],
- [$this->getGroupMock('test'), $this->getGroupMock('test0'), $this->getGroupMock('test1')],
- [
- ['label' => 'test', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'test']],
- ],
- [],
- true,
- $this->getGroupMock('test'),
- ],
- ];
- }
-
- /**
- * @dataProvider dataGetGroups
- *
- * @param string $searchTerm
- * @param bool $shareWithGroupOnly
- * @param bool $shareeEnumeration
- * @param array $groupResponse
- * @param array $userGroupsResponse
- * @param array $exactExpected
- * @param array $expected
- * @param bool $reachedEnd
- * @param mixed $singleGroup
- */
- public function testGetGroups($searchTerm, $shareWithGroupOnly, $shareeEnumeration, $groupResponse, $userGroupsResponse, $exactExpected, $expected, $reachedEnd, $singleGroup) {
- $this->invokePrivate($this->sharees, 'limit', [2]);
- $this->invokePrivate($this->sharees, 'offset', [0]);
- $this->invokePrivate($this->sharees, 'shareWithGroupOnly', [$shareWithGroupOnly]);
- $this->invokePrivate($this->sharees, 'shareeEnumeration', [$shareeEnumeration]);
-
- $this->groupManager->expects($this->once())
- ->method('search')
- ->with($searchTerm, $this->invokePrivate($this->sharees, 'limit'), $this->invokePrivate($this->sharees, 'offset'))
- ->willReturn($groupResponse);
-
- if ($singleGroup !== false) {
- $this->groupManager->expects($this->once())
- ->method('get')
- ->with($searchTerm)
- ->willReturn($singleGroup);
- }
-
- if ($shareWithGroupOnly) {
- $user = $this->getUserMock('admin', 'Administrator');
- $this->session->expects($this->any())
- ->method('getUser')
- ->willReturn($user);
-
- $numGetUserGroupsCalls = empty($groupResponse) ? 0 : 1;
- $this->groupManager->expects($this->exactly($numGetUserGroupsCalls))
- ->method('getUserGroups')
- ->with($user)
- ->willReturn($userGroupsResponse);
- }
-
- $this->invokePrivate($this->sharees, 'getGroups', [$searchTerm]);
- $result = $this->invokePrivate($this->sharees, 'result');
-
- $this->assertEquals($exactExpected, $result['exact']['groups']);
- $this->assertEquals($expected, $result['groups']);
- $this->assertCount((int) $reachedEnd, $this->invokePrivate($this->sharees, 'reachedEndFor'));
- }
-
- public function dataGetRemote() {
- return [
- ['test', [], true, [], [], true],
- ['test', [], false, [], [], true],
- [
- 'test@remote',
- [],
- true,
- [
- ['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']],
- ],
- [],
- true,
- ],
- [
- 'test@remote',
- [],
- false,
- [
- ['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']],
- ],
- [],
- true,
- ],
- [
- 'test',
- [
- [
- 'FN' => 'User3 @ Localhost',
- ],
- [
- 'FN' => 'User2 @ Localhost',
- 'CLOUD' => [
- ],
- ],
- [
- 'FN' => 'User @ Localhost',
- 'CLOUD' => [
- 'username@localhost',
- ],
- ],
- ],
- true,
- [],
- [
- ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']],
- ],
- true,
- ],
- [
- 'test',
- [
- [
- 'FN' => 'User3 @ Localhost',
- ],
- [
- 'FN' => 'User2 @ Localhost',
- 'CLOUD' => [
- ],
- ],
- [
- 'FN' => 'User @ Localhost',
- 'CLOUD' => [
- 'username@localhost',
- ],
- ],
- ],
- false,
- [],
- [],
- true,
- ],
- [
- 'test@remote',
- [
- [
- 'FN' => 'User3 @ Localhost',
- ],
- [
- 'FN' => 'User2 @ Localhost',
- 'CLOUD' => [
- ],
- ],
- [
- 'FN' => 'User @ Localhost',
- 'CLOUD' => [
- 'username@localhost',
- ],
- ],
- ],
- true,
- [
- ['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']],
- ],
- [
- ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']],
- ],
- true,
- ],
- [
- 'test@remote',
- [
- [
- 'FN' => 'User3 @ Localhost',
- ],
- [
- 'FN' => 'User2 @ Localhost',
- 'CLOUD' => [
- ],
- ],
- [
- 'FN' => 'User @ Localhost',
- 'CLOUD' => [
- 'username@localhost',
- ],
- ],
- ],
- false,
- [
- ['label' => 'test@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'test@remote']],
- ],
- [],
- true,
- ],
- [
- 'username@localhost',
- [
- [
- 'FN' => 'User3 @ Localhost',
- ],
- [
- 'FN' => 'User2 @ Localhost',
- 'CLOUD' => [
- ],
- ],
- [
- 'FN' => 'User @ Localhost',
- 'CLOUD' => [
- 'username@localhost',
- ],
- ],
- ],
- true,
- [
- ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']],
- ],
- [],
- true,
- ],
- [
- 'username@localhost',
- [
- [
- 'FN' => 'User3 @ Localhost',
- ],
- [
- 'FN' => 'User2 @ Localhost',
- 'CLOUD' => [
- ],
- ],
- [
- 'FN' => 'User @ Localhost',
- 'CLOUD' => [
- 'username@localhost',
- ],
- ],
- ],
- false,
- [
- ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']],
- ],
- [],
- true,
- ],
- ];
- }
-
- /**
- * @dataProvider dataGetRemote
- *
- * @param string $searchTerm
- * @param array $contacts
- * @param bool $shareeEnumeration
- * @param array $exactExpected
- * @param array $expected
- * @param bool $reachedEnd
- */
- public function testGetRemote($searchTerm, $contacts, $shareeEnumeration, $exactExpected, $expected, $reachedEnd) {
- $this->invokePrivate($this->sharees, 'shareeEnumeration', [$shareeEnumeration]);
- $this->contactsManager->expects($this->any())
- ->method('search')
- ->with($searchTerm, ['CLOUD', 'FN'])
- ->willReturn($contacts);
-
- $this->invokePrivate($this->sharees, 'getRemote', [$searchTerm]);
- $result = $this->invokePrivate($this->sharees, 'result');
-
- $this->assertEquals($exactExpected, $result['exact']['remotes']);
- $this->assertEquals($expected, $result['remotes']);
- $this->assertCount((int) $reachedEnd, $this->invokePrivate($this->sharees, 'reachedEndFor'));
- }
-
- public function dataSearch() {
- $allTypes = [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE];
-
- return [
- [[], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true],
-
- // Test itemType
- [[
- 'search' => '',
- ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true],
- [[
- 'search' => 'foobar',
- ], '', 'yes', true, 'foobar', null, $allTypes, 1, 200, false, true, true],
- [[
- 'search' => 0,
- ], '', 'yes', true, '0', null, $allTypes, 1, 200, false, true, true],
-
- // Test itemType
- [[
- 'itemType' => '',
- ], '', 'yes', true, '', '', $allTypes, 1, 200, false, true, true],
- [[
- 'itemType' => 'folder',
- ], '', 'yes', true, '', 'folder', $allTypes, 1, 200, false, true, true],
- [[
- 'itemType' => 0,
- ], '', 'yes', true, '', '0', $allTypes, 1, 200, false, true, true],
-
- // Test shareType
- [[
- ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true],
- [[
- 'shareType' => 0,
- ], '', 'yes', true, '', null, [0], 1, 200, false, true, true],
- [[
- 'shareType' => '0',
- ], '', 'yes', true, '', null, [0], 1, 200, false, true, true],
- [[
- 'shareType' => 1,
- ], '', 'yes', true, '', null, [1], 1, 200, false, true, true],
- [[
- 'shareType' => 12,
- ], '', 'yes', true, '', null, [], 1, 200, false, true, true],
- [[
- 'shareType' => 'foobar',
- ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true],
- [[
- 'shareType' => [0, 1, 2],
- ], '', 'yes', true, '', null, [0, 1], 1, 200, false, true, true],
- [[
- 'shareType' => [0, 1],
- ], '', 'yes', true, '', null, [0, 1], 1, 200, false, true, true],
- [[
- 'shareType' => $allTypes,
- ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true],
- [[
- 'shareType' => $allTypes,
- ], '', 'yes', false, '', null, [0, 1], 1, 200, false, true, true],
- [[
- 'shareType' => $allTypes,
- ], '', 'yes', true, '', null, [0, 6], 1, 200, false, true, false],
- [[
- 'shareType' => $allTypes,
- ], '', 'yes', false, '', null, [0], 1, 200, false, true, false],
-
- // Test pagination
- [[
- 'page' => 1,
- ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true],
- [[
- 'page' => 10,
- ], '', 'yes', true, '', null, $allTypes, 10, 200, false, true, true],
-
- // Test perPage
- [[
- 'perPage' => 1,
- ], '', 'yes', true, '', null, $allTypes, 1, 1, false, true, true],
- [[
- 'perPage' => 10,
- ], '', 'yes', true, '', null, $allTypes, 1, 10, false, true, true],
-
- // Test $shareWithGroupOnly setting
- [[], 'no', 'yes', true, '', null, $allTypes, 1, 200, false, true, true],
- [[], 'yes', 'yes', true, '', null, $allTypes, 1, 200, true, true, true],
-
- // Test $shareeEnumeration setting
- [[], 'no', 'yes', true, '', null, $allTypes, 1, 200, false, true, true],
- [[], 'no', 'no', true, '', null, $allTypes, 1, 200, false, false, true],
-
- // Test keep case for search
- [[
- 'search' => 'foo@example.com/ownCloud',
- ], '', 'yes', true, 'foo@example.com/ownCloud', null, $allTypes, 1, 200, false, true, true],
- ];
- }
-
- /**
- * @dataProvider dataSearch
- *
- * @param array $getData
- * @param string $apiSetting
- * @param string $enumSetting
- * @param bool $remoteSharingEnabled
- * @param string $search
- * @param string $itemType
- * @param array $shareTypes
- * @param int $page
- * @param int $perPage
- * @param bool $shareWithGroupOnly
- * @param bool $shareeEnumeration
- * @param bool $allowGroupSharing
- */
- public function testSearch($getData, $apiSetting, $enumSetting, $remoteSharingEnabled, $search, $itemType, $shareTypes, $page, $perPage, $shareWithGroupOnly, $shareeEnumeration, $allowGroupSharing) {
- $oldGet = $_GET;
- $_GET = $getData;
-
- $config = $this->getMockBuilder('OCP\IConfig')
- ->disableOriginalConstructor()
- ->getMock();
- $config->expects($this->exactly(2))
- ->method('getAppValue')
- ->with('core', $this->anything(), $this->anything())
- ->willReturnMap([
- ['core', 'shareapi_only_share_with_group_members', 'no', $apiSetting],
- ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', $enumSetting],
- ]);
-
- $this->shareManager->expects($this->once())
- ->method('allowGroupSharing')
- ->willReturn($allowGroupSharing);
-
- $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees')
- ->setConstructorArgs([
- $this->groupManager,
- $this->userManager,
- $this->contactsManager,
- $config,
- $this->session,
- $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
- $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(),
- $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(),
- $this->shareManager
- ])
- ->setMethods(array('searchSharees', 'isRemoteSharingAllowed'))
- ->getMock();
- $sharees->expects($this->once())
- ->method('searchSharees')
- ->with($search, $itemType, $shareTypes, $page, $perPage)
- ->willReturnCallback(function
- ($isearch, $iitemType, $ishareTypes, $ipage, $iperPage)
- use ($search, $itemType, $shareTypes, $page, $perPage) {
-
- // We are doing strict comparisons here, so we can differ 0/'' and null on shareType/itemType
- $this->assertSame($search, $isearch);
- $this->assertSame($itemType, $iitemType);
- $this->assertSame($shareTypes, $ishareTypes);
- $this->assertSame($page, $ipage);
- $this->assertSame($perPage, $iperPage);
- return new \OC_OCS_Result([]);
- });
- $sharees->expects($this->any())
- ->method('isRemoteSharingAllowed')
- ->with($itemType)
- ->willReturn($remoteSharingEnabled);
-
- /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\API\Sharees $sharees */
- $this->assertInstanceOf('\OC_OCS_Result', $sharees->search());
-
- $this->assertSame($shareWithGroupOnly, $this->invokePrivate($sharees, 'shareWithGroupOnly'));
- $this->assertSame($shareeEnumeration, $this->invokePrivate($sharees, 'shareeEnumeration'));
-
- $_GET = $oldGet;
- }
-
- public function dataSearchInvalid() {
- return [
- // Test invalid pagination
- [[
- 'page' => 0,
- ], 'Invalid page'],
- [[
- 'page' => '0',
- ], 'Invalid page'],
- [[
- 'page' => -1,
- ], 'Invalid page'],
-
- // Test invalid perPage
- [[
- 'perPage' => 0,
- ], 'Invalid perPage argument'],
- [[
- 'perPage' => '0',
- ], 'Invalid perPage argument'],
- [[
- 'perPage' => -1,
- ], 'Invalid perPage argument'],
- ];
- }
-
- /**
- * @dataProvider dataSearchInvalid
- *
- * @param array $getData
- * @param string $message
- */
- public function testSearchInvalid($getData, $message) {
- $oldGet = $_GET;
- $_GET = $getData;
-
- $config = $this->getMockBuilder('OCP\IConfig')
- ->disableOriginalConstructor()
- ->getMock();
- $config->expects($this->never())
- ->method('getAppValue');
-
- $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees')
- ->setConstructorArgs([
- $this->groupManager,
- $this->userManager,
- $this->contactsManager,
- $config,
- $this->session,
- $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
- $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(),
- $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(),
- $this->shareManager
- ])
- ->setMethods(array('searchSharees', 'isRemoteSharingAllowed'))
- ->getMock();
- $sharees->expects($this->never())
- ->method('searchSharees');
- $sharees->expects($this->never())
- ->method('isRemoteSharingAllowed');
-
- /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\API\Sharees $sharees */
- $ocs = $sharees->search();
- $this->assertInstanceOf('\OC_OCS_Result', $ocs);
-
- $this->assertOCSError($ocs, $message);
-
- $_GET = $oldGet;
- }
-
- public function dataIsRemoteSharingAllowed() {
- return [
- ['file', true],
- ['folder', true],
- ['', false],
- ['contacts', false],
- ];
- }
-
- /**
- * @dataProvider dataIsRemoteSharingAllowed
- *
- * @param string $itemType
- * @param bool $expected
- */
- public function testIsRemoteSharingAllowed($itemType, $expected) {
- $this->assertSame($expected, $this->invokePrivate($this->sharees, 'isRemoteSharingAllowed', [$itemType]));
- }
-
- public function dataSearchSharees() {
- return [
- ['test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, false, [], [], [],
- [
- 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
- 'users' => [],
- 'groups' => [],
- 'remotes' => [],
- ], false],
- ['test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, false, [], [], [],
- [
- 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
- 'users' => [],
- 'groups' => [],
- 'remotes' => [],
- ], false],
- [
- 'test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, false, [
- ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ], [
- ['label' => 'testgroup1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'testgroup1']],
- ], [
- ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']],
- ],
- [
- 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
- 'users' => [
- ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ],
- 'groups' => [
- ['label' => 'testgroup1', 'value' => ['shareType' => Share::SHARE_TYPE_GROUP, 'shareWith' => 'testgroup1']],
- ],
- 'remotes' => [
- ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']],
- ],
- ], true,
- ],
- // No groups requested
- [
- 'test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_REMOTE], 1, 2, false, [
- ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ], null, [
- ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']],
- ],
- [
- 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
- 'users' => [
- ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ],
- 'groups' => [],
- 'remotes' => [
- ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']],
- ],
- ], false,
- ],
- // Share type restricted to user - Only one user
- [
- 'test', 'folder', [Share::SHARE_TYPE_USER], 1, 2, false, [
- ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ], null, null,
- [
- 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
- 'users' => [
- ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ],
- 'groups' => [],
- 'remotes' => [],
- ], false,
- ],
- // Share type restricted to user - Multipage result
- [
- 'test', 'folder', [Share::SHARE_TYPE_USER], 1, 2, false, [
- ['label' => 'test 1', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ['label' => 'test 2', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
- ], null, null,
- [
- 'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
- 'users' => [
- ['label' => 'test 1', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
- ['label' => 'test 2', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
- ],
- 'groups' => [],
- 'remotes' => [],
- ], true,
- ],
- ];
- }
-
- /**
- * @dataProvider dataSearchSharees
- *
- * @param string $searchTerm
- * @param string $itemType
- * @param array $shareTypes
- * @param int $page
- * @param int $perPage
- * @param bool $shareWithGroupOnly
- * @param array $mockedUserResult
- * @param array $mockedGroupsResult
- * @param array $mockedRemotesResult
- * @param array $expected
- * @param bool $nextLink
- */
- public function testSearchSharees($searchTerm, $itemType, array $shareTypes, $page, $perPage, $shareWithGroupOnly,
- $mockedUserResult, $mockedGroupsResult, $mockedRemotesResult, $expected, $nextLink) {
- /** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\API\Sharees $sharees */
- $sharees = $this->getMockBuilder('\OCA\Files_Sharing\API\Sharees')
- ->setConstructorArgs([
- $this->groupManager,
- $this->userManager,
- $this->contactsManager,
- $this->getMockBuilder('OCP\IConfig')->disableOriginalConstructor()->getMock(),
- $this->session,
- $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(),
- $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(),
- $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(),
- $this->shareManager
- ])
- ->setMethods(array('getShareesForShareIds', 'getUsers', 'getGroups', 'getRemote'))
- ->getMock();
- $sharees->expects(($mockedUserResult === null) ? $this->never() : $this->once())
- ->method('getUsers')
- ->with($searchTerm)
- ->willReturnCallback(function() use ($sharees, $mockedUserResult) {
- $result = $this->invokePrivate($sharees, 'result');
- $result['users'] = $mockedUserResult;
- $this->invokePrivate($sharees, 'result', [$result]);
- });
- $sharees->expects(($mockedGroupsResult === null) ? $this->never() : $this->once())
- ->method('getGroups')
- ->with($searchTerm)
- ->willReturnCallback(function() use ($sharees, $mockedGroupsResult) {
- $result = $this->invokePrivate($sharees, 'result');
- $result['groups'] = $mockedGroupsResult;
- $this->invokePrivate($sharees, 'result', [$result]);
- });
- $sharees->expects(($mockedRemotesResult === null) ? $this->never() : $this->once())
- ->method('getRemote')
- ->with($searchTerm)
- ->willReturnCallback(function() use ($sharees, $mockedRemotesResult) {
- $result = $this->invokePrivate($sharees, 'result');
- $result['remotes'] = $mockedRemotesResult;
- $this->invokePrivate($sharees, 'result', [$result]);
- });
-
- /** @var \OC_OCS_Result $ocs */
- $ocs = $this->invokePrivate($sharees, 'searchSharees', [$searchTerm, $itemType, $shareTypes, $page, $perPage, $shareWithGroupOnly]);
- $this->assertInstanceOf('\OC_OCS_Result', $ocs);
- $this->assertEquals($expected, $ocs->getData());
-
- // Check if next link is set
- if ($nextLink) {
- $headers = $ocs->getHeaders();
- $this->assertArrayHasKey('Link', $headers);
- $this->assertStringStartsWith('<', $headers['Link']);
- $this->assertStringEndsWith('>; rel="next"', $headers['Link']);
- }
- }
-
- public function testSearchShareesNoItemType() {
- /** @var \OC_OCS_Result $ocs */
- $ocs = $this->invokePrivate($this->sharees, 'searchSharees', ['', null, [], [], 0, 0, false]);
- $this->assertInstanceOf('\OC_OCS_Result', $ocs);
-
- $this->assertOCSError($ocs, 'Missing itemType');
- }
-
- public function dataGetPaginationLink() {
- return [
- [1, '/ocs/v1.php', ['perPage' => 2], '<?perPage=2&page=2>; rel="next"'],
- [10, '/ocs/v2.php', ['perPage' => 2], '<?perPage=2&page=11>; rel="next"'],
- ];
- }
-
- /**
- * @dataProvider dataGetPaginationLink
- *
- * @param int $page
- * @param string $scriptName
- * @param array $params
- * @param array $expected
- */
- public function testGetPaginationLink($page, $scriptName, $params, $expected) {
- $this->request->expects($this->once())
- ->method('getScriptName')
- ->willReturn($scriptName);
-
- $this->assertEquals($expected, $this->invokePrivate($this->sharees, 'getPaginationLink', [$page, $params]));
- }
-
- public function dataIsV2() {
- return [
- ['/ocs/v1.php', false],
- ['/ocs/v2.php', true],
- ];
- }
-
- /**
- * @dataProvider dataIsV2
- *
- * @param string $scriptName
- * @param bool $expected
- */
- public function testIsV2($scriptName, $expected) {
- $this->request->expects($this->once())
- ->method('getScriptName')
- ->willReturn($scriptName);
-
- $this->assertEquals($expected, $this->invokePrivate($this->sharees, 'isV2'));
- }
-
- /**
- * @param \OC_OCS_Result $ocs
- * @param string $message
- */
- protected function assertOCSError(\OC_OCS_Result $ocs, $message) {
- $this->assertSame(Http::STATUS_BAD_REQUEST, $ocs->getStatusCode(), 'Expected status code 400');
- $this->assertSame([], $ocs->getData(), 'Expected that no data is send');
-
- $meta = $ocs->getMeta();
- $this->assertNotEmpty($meta);
- $this->assertArrayHasKey('message', $meta);
- $this->assertSame($message, $meta['message']);
- }
-
- /**
- * @dataProvider dataTestSplitUserRemote
- *
- * @param string $remote
- * @param string $expectedUser
- * @param string $expectedUrl
- */
- public function testSplitUserRemote($remote, $expectedUser, $expectedUrl) {
- list($remoteUser, $remoteUrl) = $this->sharees->splitUserRemote($remote);
- $this->assertSame($expectedUser, $remoteUser);
- $this->assertSame($expectedUrl, $remoteUrl);
- }
-
- public function dataTestSplitUserRemote() {
- $userPrefix = ['user@name', 'username'];
- $protocols = ['', 'http://', 'https://'];
- $remotes = [
- 'localhost',
- 'local.host',
- 'dev.local.host',
- 'dev.local.host/path',
- 'dev.local.host/at@inpath',
- '127.0.0.1',
- '::1',
- '::192.0.2.128',
- '::192.0.2.128/at@inpath',
- ];
-
- $testCases = [];
- foreach ($userPrefix as $user) {
- foreach ($remotes as $remote) {
- foreach ($protocols as $protocol) {
- $baseUrl = $user . '@' . $protocol . $remote;
-
- $testCases[] = [$baseUrl, $user, $protocol . $remote];
- $testCases[] = [$baseUrl . '/', $user, $protocol . $remote];
- $testCases[] = [$baseUrl . '/index.php', $user, $protocol . $remote];
- $testCases[] = [$baseUrl . '/index.php/s/token', $user, $protocol . $remote];
- }
- }
- }
- return $testCases;
- }
-
- public function dataTestSplitUserRemoteError() {
- return array(
- // Invalid path
- array('user@'),
-
- // Invalid user
- array('@server'),
- array('us/er@server'),
- array('us:er@server'),
-
- // Invalid splitting
- array('user'),
- array(''),
- array('us/erserver'),
- array('us:erserver'),
- );
- }
-
- /**
- * @dataProvider dataTestSplitUserRemoteError
- *
- * @param string $id
- * @expectedException \Exception
- */
- public function testSplitUserRemoteError($id) {
- $this->sharees->splitUserRemote($id);
- }
-
- /**
- * @dataProvider dataTestFixRemoteUrl
- *
- * @param string $url
- * @param string $expected
- */
- public function testFixRemoteUrl($url, $expected) {
- $this->assertSame($expected,
- $this->invokePrivate($this->sharees, 'fixRemoteURL', [$url])
- );
- }
-
- public function dataTestFixRemoteUrl() {
- return [
- ['http://localhost', 'http://localhost'],
- ['http://localhost/', 'http://localhost'],
- ['http://localhost/index.php', 'http://localhost'],
- ['http://localhost/index.php/s/AShareToken', 'http://localhost'],
- ];
- }
-}
diff --git a/apps/files_sharing/tests/backend.php b/apps/files_sharing/tests/backend.php
deleted file mode 100644
index e5e6ceb6315..00000000000
--- a/apps/files_sharing/tests/backend.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-use OCA\Files\Share;
-use OCA\Files_sharing\Tests\TestCase;
-
-/**
- * Class Test_Files_Sharing
- *
- * @group DB
- */
-class Test_Files_Sharing_Backend extends TestCase {
-
- const TEST_FOLDER_NAME = '/folder_share_api_test';
-
- public $folder;
- public $subfolder;
- public $subsubfolder;
-
- protected function setUp() {
- parent::setUp();
-
- $this->folder = self::TEST_FOLDER_NAME;
- $this->subfolder = '/subfolder_share_backend_test';
- $this->subsubfolder = '/subsubfolder_share_backend_test';
-
- $this->filename = '/share-backend-test.txt';
-
- // save file with content
- $this->view->file_put_contents($this->filename, $this->data);
- $this->view->mkdir($this->folder);
- $this->view->mkdir($this->folder . $this->subfolder);
- $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder);
- $this->view->file_put_contents($this->folder.$this->filename, $this->data);
- $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data);
- $this->view->file_put_contents($this->folder . $this->subfolder . $this->subsubfolder . $this->filename, $this->data);
- }
-
- protected function tearDown() {
- if ($this->view) {
- $this->view->unlink($this->filename);
- $this->view->deleteAll($this->folder);
- }
-
- parent::tearDown();
- }
-
- function testGetParents() {
-
- $fileinfo1 = $this->view->getFileInfo($this->folder);
- $fileinfo2 = $this->view->getFileInfo($this->folder . $this->subfolder . $this->subsubfolder);
- $fileinfo3 = $this->view->getFileInfo($this->folder . $this->subfolder . $this->subsubfolder . $this->filename);
-
- $this->assertTrue(\OCP\Share::shareItem('folder', $fileinfo1['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31));
- $this->assertTrue(\OCP\Share::shareItem('folder', $fileinfo2['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER3, 31));
-
- $backend = new \OC_Share_Backend_Folder();
-
- $result = $backend->getParents($fileinfo3['fileid']);
- $this->assertSame(2, count($result));
-
- $count1 = 0;
- $count2 = 0;
- foreach($result as $r) {
- if ($r['path'] === 'files' . $this->folder) {
- $this->assertSame(ltrim($this->folder, '/'), $r['collection']['path']);
- $count1++;
- } elseif ($r['path'] === 'files' . $this->folder . $this->subfolder . $this->subsubfolder) {
- $this->assertSame(ltrim($this->subsubfolder, '/'), $r['collection']['path']);
- $count2++;
- } else {
- $this->assertTrue(false, 'unexpected result');
- }
- }
-
- $this->assertSame(1, $count1);
- $this->assertSame(1, $count2);
-
- $result1 = $backend->getParents($fileinfo3['fileid'], self::TEST_FILES_SHARING_API_USER3);
- $this->assertSame(1, count($result1));
- $elemet = reset($result1);
- $this->assertSame('files' . $this->folder . $this->subfolder . $this->subsubfolder ,$elemet['path']);
- $this->assertSame(ltrim($this->subsubfolder, '/') ,$elemet['collection']['path']);
-
- }
-
-}
diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php
deleted file mode 100644
index c137ba0728d..00000000000
--- a/apps/files_sharing/tests/cache.php
+++ /dev/null
@@ -1,508 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-use OCA\Files_sharing\Tests\TestCase;
-
-/**
- * ownCloud
- *
- * @author Vincent Petry, Bjoern Schiessle
- * @copyright 2014 Vincent Petry <pvince81@owncloud.com>
- * 2014 Bjoern Schiessle <schiessle@owncloud.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library 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 library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/**
- * Class Test_Files_Sharing_Cache
- *
- * @group DB
- */
-class Test_Files_Sharing_Cache extends TestCase {
-
- /**
- * @var OC\Files\View
- */
- public $user2View;
-
- /** @var \OC\Files\Cache\Cache */
- protected $ownerCache;
-
- /** @var \OC\Files\Cache\Cache */
- protected $sharedCache;
-
- /** @var \OC\Files\Storage\Storage */
- protected $ownerStorage;
-
- /** @var \OC\Files\Storage\Storage */
- protected $sharedStorage;
-
- protected function setUp() {
- parent::setUp();
-
- \OC_User::setDisplayName(self::TEST_FILES_SHARING_API_USER1, 'User One');
- \OC_User::setDisplayName(self::TEST_FILES_SHARING_API_USER2, 'User Two');
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- $this->user2View = new \OC\Files\View('/'. self::TEST_FILES_SHARING_API_USER2 . '/files');
-
- // prepare user1's dir structure
- $this->view->mkdir('container');
- $this->view->mkdir('container/shareddir');
- $this->view->mkdir('container/shareddir/subdir');
- $this->view->mkdir('container/shareddir/emptydir');
-
- $textData = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
- $this->view->file_put_contents('container/not shared.txt', $textData);
- $this->view->file_put_contents('container/shared single file.txt', $textData);
- $this->view->file_put_contents('container/shareddir/bar.txt', $textData);
- $this->view->file_put_contents('container/shareddir/subdir/another.txt', $textData);
- $this->view->file_put_contents('container/shareddir/subdir/another too.txt', $textData);
- $this->view->file_put_contents('container/shareddir/subdir/not a text file.xml', '<xml></xml>');
-
- list($this->ownerStorage,) = $this->view->resolvePath('');
- $this->ownerCache = $this->ownerStorage->getCache();
- $this->ownerStorage->getScanner()->scan('');
-
- // share "shareddir" with user2
- $fileinfo = $this->view->getFileInfo('container/shareddir');
- \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
-
- $fileinfo = $this->view->getFileInfo('container/shared single file.txt');
- \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
-
- // login as user2
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- // retrieve the shared storage
- $secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2);
- list($this->sharedStorage,) = $secondView->resolvePath('files/shareddir');
- $this->sharedCache = $this->sharedStorage->getCache();
- }
-
- protected function tearDown() {
- if($this->sharedCache) {
- $this->sharedCache->clear();
- }
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- $fileinfo = $this->view->getFileInfo('container/shareddir');
- \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
-
- $fileinfo = $this->view->getFileInfo('container/shared single file.txt');
- \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
-
- $this->view->deleteAll('container');
-
- $this->ownerCache->clear();
-
- parent::tearDown();
- }
-
- function searchDataProvider() {
- return array(
- array('%another%',
- array(
- array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'),
- array('name' => 'another.txt', 'path' => 'subdir/another.txt'),
- )
- ),
- array('%Another%',
- array(
- array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'),
- array('name' => 'another.txt', 'path' => 'subdir/another.txt'),
- )
- ),
- array('%dir%',
- array(
- array('name' => 'emptydir', 'path' => 'emptydir'),
- array('name' => 'subdir', 'path' => 'subdir'),
- array('name' => 'shareddir', 'path' => ''),
- )
- ),
- array('%Dir%',
- array(
- array('name' => 'emptydir', 'path' => 'emptydir'),
- array('name' => 'subdir', 'path' => 'subdir'),
- array('name' => 'shareddir', 'path' => ''),
- )
- ),
- array('%txt%',
- array(
- array('name' => 'bar.txt', 'path' => 'bar.txt'),
- array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'),
- array('name' => 'another.txt', 'path' => 'subdir/another.txt'),
- )
- ),
- array('%Txt%',
- array(
- array('name' => 'bar.txt', 'path' => 'bar.txt'),
- array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'),
- array('name' => 'another.txt', 'path' => 'subdir/another.txt'),
- )
- ),
- array('%',
- array(
- array('name' => 'bar.txt', 'path' => 'bar.txt'),
- array('name' => 'emptydir', 'path' => 'emptydir'),
- array('name' => 'subdir', 'path' => 'subdir'),
- array('name' => 'another too.txt', 'path' => 'subdir/another too.txt'),
- array('name' => 'another.txt', 'path' => 'subdir/another.txt'),
- array('name' => 'not a text file.xml', 'path' => 'subdir/not a text file.xml'),
- array('name' => 'shareddir', 'path' => ''),
- )
- ),
- array('%nonexistant%',
- array(
- )
- ),
- );
- }
-
- /**
- * we cannot use a dataProvider because that would cause the stray hook detection to remove the hooks
- * that were added in setUpBeforeClass.
- */
- function testSearch() {
- foreach ($this->searchDataProvider() as $data) {
- list($pattern, $expectedFiles) = $data;
-
- $results = $this->sharedStorage->getCache()->search($pattern);
-
- $this->verifyFiles($expectedFiles, $results);
- }
-
- }
- /**
- * Test searching by mime type
- */
- function testSearchByMime() {
- $results = $this->sharedStorage->getCache()->searchByMime('text');
- $check = array(
- array(
- 'name' => 'bar.txt',
- 'path' => 'bar.txt'
- ),
- array(
- 'name' => 'another too.txt',
- 'path' => 'subdir/another too.txt'
- ),
- array(
- 'name' => 'another.txt',
- 'path' => 'subdir/another.txt'
- ),
- );
- $this->verifyFiles($check, $results);
- }
-
- /**
- * Test searching by tag
- */
- function testSearchByTag() {
- $userId = \OC::$server->getUserSession()->getUser()->getUId();
- $id1 = $this->sharedCache->get('bar.txt')['fileid'];
- $id2 = $this->sharedCache->get('subdir/another too.txt')['fileid'];
- $id3 = $this->sharedCache->get('subdir/not a text file.xml')['fileid'];
- $id4 = $this->sharedCache->get('subdir/another.txt')['fileid'];
- $tagManager = \OC::$server->getTagManager()->load('files', null, null, $userId);
- $tagManager->tagAs($id1, 'tag1');
- $tagManager->tagAs($id1, 'tag2');
- $tagManager->tagAs($id2, 'tag1');
- $tagManager->tagAs($id3, 'tag1');
- $tagManager->tagAs($id4, 'tag2');
- $results = $this->sharedStorage->getCache()->searchByTag('tag1', $userId);
- $check = array(
- array(
- 'name' => 'bar.txt',
- 'path' => 'bar.txt'
- ),
- array(
- 'name' => 'another too.txt',
- 'path' => 'subdir/another too.txt'
- ),
- array(
- 'name' => 'not a text file.xml',
- 'path' => 'subdir/not a text file.xml'
- ),
- );
- $this->verifyFiles($check, $results);
- $tagManager->delete(array('tag1', 'tag2'));
- }
-
- /**
- * Test searching by tag for multiple sections of the tree
- */
- function testSearchByTagTree() {
- $userId = \OC::$server->getUserSession()->getUser()->getUId();
- $this->sharedStorage->mkdir('subdir/emptydir');
- $this->sharedStorage->mkdir('subdir/emptydir2');
- $this->ownerStorage->getScanner()->scan('');
- $allIds = array(
- $this->sharedCache->get('')['fileid'],
- $this->sharedCache->get('bar.txt')['fileid'],
- $this->sharedCache->get('subdir/another too.txt')['fileid'],
- $this->sharedCache->get('subdir/not a text file.xml')['fileid'],
- $this->sharedCache->get('subdir/another.txt')['fileid'],
- $this->sharedCache->get('subdir/emptydir')['fileid'],
- $this->sharedCache->get('subdir/emptydir2')['fileid'],
- );
- $tagManager = \OC::$server->getTagManager()->load('files', null, null, $userId);
- foreach ($allIds as $id) {
- $tagManager->tagAs($id, 'tag1');
- }
- $results = $this->sharedStorage->getCache()->searchByTag('tag1', $userId);
- $check = array(
- array(
- 'name' => 'shareddir',
- 'path' => ''
- ),
- array(
- 'name' => 'bar.txt',
- 'path' => 'bar.txt'
- ),
- array(
- 'name' => 'another.txt',
- 'path' => 'subdir/another.txt'
- ),
- array(
- 'name' => 'another too.txt',
- 'path' => 'subdir/another too.txt'
- ),
- array(
- 'name' => 'emptydir',
- 'path' => 'subdir/emptydir'
- ),
- array(
- 'name' => 'emptydir2',
- 'path' => 'subdir/emptydir2'
- ),
- array(
- 'name' => 'not a text file.xml',
- 'path' => 'subdir/not a text file.xml'
- ),
- );
- $this->verifyFiles($check, $results);
- $tagManager->delete(array('tag1'));
- }
-
- function testGetFolderContentsInRoot() {
- $results = $this->user2View->getDirectoryContent('/');
-
- // we should get the shared items "shareddir" and "shared single file.txt"
- // additional root will always contain the example file "welcome.txt",
- // so this will be part of the result
- $this->verifyFiles(
- array(
- array(
- 'name' => 'welcome.txt',
- 'path' => 'files/welcome.txt',
- 'mimetype' => 'text/plain',
- ),
- array(
- 'name' => 'shareddir',
- 'path' => 'files/shareddir',
- 'mimetype' => 'httpd/unix-directory',
- 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
- 'displayname_owner' => 'User One',
- ),
- array(
- 'name' => 'shared single file.txt',
- 'path' => 'files/shared single file.txt',
- 'mimetype' => 'text/plain',
- 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
- 'displayname_owner' => 'User One',
- ),
- ),
- $results
- );
- }
-
- function testGetFolderContentsInSubdir() {
- $results = $this->user2View->getDirectoryContent('/shareddir');
-
- $this->verifyFiles(
- array(
- array(
- 'name' => 'bar.txt',
- 'path' => 'bar.txt',
- 'mimetype' => 'text/plain',
- 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
- 'displayname_owner' => 'User One',
- ),
- array(
- 'name' => 'emptydir',
- 'path' => 'emptydir',
- 'mimetype' => 'httpd/unix-directory',
- 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
- 'displayname_owner' => 'User One',
- ),
- array(
- 'name' => 'subdir',
- 'path' => 'subdir',
- 'mimetype' => 'httpd/unix-directory',
- 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
- 'displayname_owner' => 'User One',
- ),
- ),
- $results
- );
- }
-
- function testGetFolderContentsWhenSubSubdirShared() {
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- $fileinfo = $this->view->getFileInfo('container/shareddir/subdir');
- \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER3, 31);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
-
- $thirdView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files');
- $results = $thirdView->getDirectoryContent('/subdir');
-
- $this->verifyFiles(
- array(
- array(
- 'name' => 'another too.txt',
- 'path' => 'another too.txt',
- 'mimetype' => 'text/plain',
- 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
- 'displayname_owner' => 'User One',
- ),
- array(
- 'name' => 'another.txt',
- 'path' => 'another.txt',
- 'mimetype' => 'text/plain',
- 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
- 'displayname_owner' => 'User One',
- ),
- array(
- 'name' => 'not a text file.xml',
- 'path' => 'not a text file.xml',
- 'mimetype' => 'application/xml',
- 'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
- 'displayname_owner' => 'User One',
- ),
- ),
- $results
- );
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER3);
- }
-
- /**
- * Check if 'results' contains the expected 'examples' only.
- *
- * @param array $examples array of example files
- * @param array $results array of files
- */
- private function verifyFiles($examples, $results) {
- $this->assertEquals(count($examples), count($results));
-
- foreach ($examples as $example) {
- foreach ($results as $key => $result) {
- if ($result['name'] === $example['name']) {
- $this->verifyKeys($example, $result);
- unset($results[$key]);
- break;
- }
- }
- }
- $this->assertEquals(array(), $results);
- }
-
- /**
- * verify if each value from the result matches the expected result
- * @param array $example array with the expected results
- * @param array $result array with the results
- */
- private function verifyKeys($example, $result) {
- foreach ($example as $key => $value) {
- $this->assertEquals($value, $result[$key]);
- }
- }
-
- public function testGetPathByIdDirectShare() {
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- \OC\Files\Filesystem::file_put_contents('test.txt', 'foo');
- $info = \OC\Files\Filesystem::getFileInfo('test.txt');
- \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_ALL);
- \OC_Util::tearDownFS();
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue(\OC\Files\Filesystem::file_exists('/test.txt'));
- list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/test.txt');
- /**
- * @var \OC\Files\Storage\Shared $sharedStorage
- */
-
- $sharedCache = $sharedStorage->getCache();
- $this->assertEquals('', $sharedCache->getPathById($info->getId()));
- }
-
- public function testGetPathByIdShareSubFolder() {
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- \OC\Files\Filesystem::mkdir('foo');
- \OC\Files\Filesystem::mkdir('foo/bar');
- \OC\Files\Filesystem::touch('foo/bar/test.txt');
- $folderInfo = \OC\Files\Filesystem::getFileInfo('foo');
- $fileInfo = \OC\Files\Filesystem::getFileInfo('foo/bar/test.txt');
- \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_ALL);
- \OC_Util::tearDownFS();
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue(\OC\Files\Filesystem::file_exists('/foo'));
- list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/foo');
- /**
- * @var \OC\Files\Storage\Shared $sharedStorage
- */
-
- $sharedCache = $sharedStorage->getCache();
- $this->assertEquals('', $sharedCache->getPathById($folderInfo->getId()));
- $this->assertEquals('bar/test.txt', $sharedCache->getPathById($fileInfo->getId()));
- }
-}
diff --git a/apps/files_sharing/tests/capabilities.php b/apps/files_sharing/tests/capabilities.php
deleted file mode 100644
index 7572f5c84aa..00000000000
--- a/apps/files_sharing/tests/capabilities.php
+++ /dev/null
@@ -1,282 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-namespace OCA\Files_Sharing\Tests;
-
-use OCA\Files_Sharing\Capabilities;
-use OCA\Files_Sharing\Tests\TestCase;
-
-/**
- * Class FilesSharingCapabilitiesTest
- *
- * @group DB
- */
-class FilesSharingCapabilitiesTest extends \Test\TestCase {
-
- /**
- * Test for the general part in each return statement and assert.
- * Strip of the general part on the way.
- *
- * @param string[] $data Capabilities
- * @return string[]
- */
- private function getFilesSharingPart(array $data) {
- $this->assertArrayHasKey('files_sharing', $data);
- return $data['files_sharing'];
- }
-
- /**
- * Create a mock config object and insert the values in $map tot the getAppValue
- * function. Then obtain the capabilities and extract the first few
- * levels in the array
- *
- * @param (string[])[] $map Map of arguments to return types for the getAppValue function in the mock
- * @return string[]
- */
- private function getResults(array $map) {
- $stub = $this->getMockBuilder('\OCP\IConfig')->disableOriginalConstructor()->getMock();
- $stub->method('getAppValue')->will($this->returnValueMap($map));
- $cap = new Capabilities($stub);
- $result = $this->getFilesSharingPart($cap->getCapabilities());
- return $result;
- }
-
- public function testEnabledSharingAPI() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertTrue($result['api_enabled']);
- $this->assertContains('public', $result);
- $this->assertContains('user', $result);
- $this->assertContains('resharing', $result);
- }
-
- public function testDisabledSharingAPI() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertFalse($result['api_enabled']);
- $this->assertNotContains('public', $result);
- $this->assertNotContains('user', $result);
- $this->assertNotContains('resharing', $result);
- }
-
- public function testNoLinkSharing() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertInternalType('array', $result['public']);
- $this->assertFalse($result['public']['enabled']);
- }
-
- public function testOnlyLinkSharing() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertInternalType('array', $result['public']);
- $this->assertTrue($result['public']['enabled']);
- }
-
- public function testLinkPassword() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ['core', 'shareapi_enforce_links_password', 'no', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertArrayHasKey('password', $result['public']);
- $this->assertArrayHasKey('enforced', $result['public']['password']);
- $this->assertTrue($result['public']['password']['enforced']);
- }
-
- public function testLinkNoPassword() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ['core', 'shareapi_enforce_links_password', 'no', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertArrayHasKey('password', $result['public']);
- $this->assertArrayHasKey('enforced', $result['public']['password']);
- $this->assertFalse($result['public']['password']['enforced']);
- }
-
- public function testLinkNoExpireDate() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ['core', 'shareapi_default_expire_date', 'no', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertArrayHasKey('expire_date', $result['public']);
- $this->assertInternalType('array', $result['public']['expire_date']);
- $this->assertFalse($result['public']['expire_date']['enabled']);
- }
-
- public function testLinkExpireDate() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ['core', 'shareapi_default_expire_date', 'no', 'yes'],
- ['core', 'shareapi_expire_after_n_days', '7', '7'],
- ['core', 'shareapi_enforce_expire_date', 'no', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertArrayHasKey('expire_date', $result['public']);
- $this->assertInternalType('array', $result['public']['expire_date']);
- $this->assertTrue($result['public']['expire_date']['enabled']);
- $this->assertArrayHasKey('days', $result['public']['expire_date']);
- $this->assertFalse($result['public']['expire_date']['enforced']);
- }
-
- public function testLinkExpireDateEnforced() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ['core', 'shareapi_default_expire_date', 'no', 'yes'],
- ['core', 'shareapi_enforce_expire_date', 'no', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertArrayHasKey('expire_date', $result['public']);
- $this->assertInternalType('array', $result['public']['expire_date']);
- $this->assertTrue($result['public']['expire_date']['enforced']);
- }
-
- public function testLinkSendMail() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ['core', 'shareapi_allow_public_notification', 'no', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertTrue($result['public']['send_mail']);
- }
-
- public function testLinkNoSendMail() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ['core', 'shareapi_allow_public_notification', 'no', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertFalse($result['public']['send_mail']);
- }
-
- public function testUserSendMail() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_mail_notification', 'no', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertTrue($result['user']['send_mail']);
- }
-
- public function testUserNoSendMail() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_mail_notification', 'no', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertFalse($result['user']['send_mail']);
- }
-
- public function testResharing() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_resharing', 'yes', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertTrue($result['resharing']);
- }
-
- public function testNoResharing() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_resharing', 'yes', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertFalse($result['resharing']);
- }
-
- public function testLinkPublicUpload() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ['core', 'shareapi_allow_public_upload', 'yes', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertTrue($result['public']['upload']);
- }
-
- public function testLinkNoPublicUpload() {
- $map = [
- ['core', 'shareapi_enabled', 'yes', 'yes'],
- ['core', 'shareapi_allow_links', 'yes', 'yes'],
- ['core', 'shareapi_allow_public_upload', 'yes', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertFalse($result['public']['upload']);
- }
-
- public function testFederatedSharingIncomming() {
- $map = [
- ['files_sharing', 'incoming_server2server_share_enabled', 'yes', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertArrayHasKey('federation', $result);
- $this->assertTrue($result['federation']['incoming']);
- }
-
- public function testFederatedSharingNoIncomming() {
- $map = [
- ['files_sharing', 'incoming_server2server_share_enabled', 'yes', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertArrayHasKey('federation', $result);
- $this->assertFalse($result['federation']['incoming']);
- }
-
- public function testFederatedSharingOutgoing() {
- $map = [
- ['files_sharing', 'outgoing_server2server_share_enabled', 'yes', 'yes'],
- ];
- $result = $this->getResults($map);
- $this->assertArrayHasKey('federation', $result);
- $this->assertTrue($result['federation']['outgoing']);
- }
-
- public function testFederatedSharingNoOutgoing() {
- $map = [
- ['files_sharing', 'outgoing_server2server_share_enabled', 'yes', 'no'],
- ];
- $result = $this->getResults($map);
- $this->assertArrayHasKey('federation', $result);
- $this->assertFalse($result['federation']['outgoing']);
- }
-
-}
diff --git a/apps/files_sharing/tests/controller/externalsharecontroller.php b/apps/files_sharing/tests/controller/externalsharecontroller.php
deleted file mode 100644
index bd20bffb36c..00000000000
--- a/apps/files_sharing/tests/controller/externalsharecontroller.php
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php
-/**
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Controllers;
-
-use OCP\AppFramework\Http\DataResponse;
-use OCP\AppFramework\Http\JSONResponse;
-use OCP\Http\Client\IClientService;
-use OCP\IRequest;
-
-/**
- * Class ExternalShareControllerTest
- *
- * @package OCA\Files_Sharing\Controllers
- */
-class ExternalShareControllerTest extends \Test\TestCase {
- /** @var IRequest */
- private $request;
- /** @var \OCA\Files_Sharing\External\Manager */
- private $externalManager;
- /** @var IClientService */
- private $clientService;
-
- public function setUp() {
- $this->request = $this->getMockBuilder('\\OCP\\IRequest')
- ->disableOriginalConstructor()->getMock();
- $this->externalManager = $this->getMockBuilder('\\OCA\\Files_Sharing\\External\\Manager')
- ->disableOriginalConstructor()->getMock();
- $this->clientService = $this->getMockBuilder('\\OCP\Http\\Client\\IClientService')
- ->disableOriginalConstructor()->getMock();
- }
-
- /**
- * @return ExternalSharesController
- */
- public function getExternalShareController() {
- return new ExternalSharesController(
- 'files_sharing',
- $this->request,
- $this->externalManager,
- $this->clientService
- );
- }
-
- public function testIndex() {
- $this->externalManager
- ->expects($this->once())
- ->method('getOpenShares')
- ->will($this->returnValue(['MyDummyArray']));
-
- $this->assertEquals(new JSONResponse(['MyDummyArray']), $this->getExternalShareController()->index());
- }
-
- public function testCreate() {
- $this->externalManager
- ->expects($this->once())
- ->method('acceptShare')
- ->with(4);
-
- $this->assertEquals(new JSONResponse(), $this->getExternalShareController()->create(4));
- }
-
- public function testDestroy() {
- $this->externalManager
- ->expects($this->once())
- ->method('declineShare')
- ->with(4);
-
- $this->assertEquals(new JSONResponse(), $this->getExternalShareController()->destroy(4));
- }
-
- public function testRemoteWithValidHttps() {
- $client = $this->getMockBuilder('\\OCP\\Http\\Client\\IClient')
- ->disableOriginalConstructor()->getMock();
- $response = $this->getMockBuilder('\\OCP\\Http\\Client\\IResponse')
- ->disableOriginalConstructor()->getMock();
- $response
- ->expects($this->exactly(2))
- ->method('getBody')
- ->will($this->onConsecutiveCalls('Certainly not a JSON string', '{"installed":true,"maintenance":false,"version":"8.1.0.8","versionstring":"8.1.0","edition":""}'));
- $client
- ->expects($this->any())
- ->method('get')
- ->will($this->returnValue($response));
-
- $this->clientService
- ->expects($this->exactly(2))
- ->method('newClient')
- ->will($this->returnValue($client));
-
- $this->assertEquals(new DataResponse('https'), $this->getExternalShareController()->testRemote('owncloud.org'));
- }
-
- public function testRemoteWithWorkingHttp() {
- $client = $this->getMockBuilder('\\OCP\\Http\\Client\\IClient')
- ->disableOriginalConstructor()->getMock();
- $response = $this->getMockBuilder('\\OCP\\Http\\Client\\IResponse')
- ->disableOriginalConstructor()->getMock();
- $client
- ->method('get')
- ->will($this->returnValue($response));
- $response
- ->expects($this->exactly(5))
- ->method('getBody')
- ->will($this->onConsecutiveCalls('Certainly not a JSON string', 'Certainly not a JSON string', 'Certainly not a JSON string', 'Certainly not a JSON string', '{"installed":true,"maintenance":false,"version":"8.1.0.8","versionstring":"8.1.0","edition":""}'));
- $this->clientService
- ->expects($this->exactly(5))
- ->method('newClient')
- ->will($this->returnValue($client));
-
- $this->assertEquals(new DataResponse('http'), $this->getExternalShareController()->testRemote('owncloud.org'));
- }
-
- public function testRemoteWithInvalidRemote() {
- $client = $this->getMockBuilder('\\OCP\\Http\\Client\\IClient')
- ->disableOriginalConstructor()->getMock();
- $response = $this->getMockBuilder('\\OCP\\Http\\Client\\IResponse')
- ->disableOriginalConstructor()->getMock();
- $client
- ->method('get')
- ->will($this->returnValue($response));
- $response
- ->expects($this->exactly(6))
- ->method('getBody')
- ->will($this->returnValue('Certainly not a JSON string'));
- $this->clientService
- ->expects($this->exactly(6))
- ->method('newClient')
- ->will($this->returnValue($client));
-
- $this->assertEquals(new DataResponse(false), $this->getExternalShareController()->testRemote('owncloud.org'));
- }
-}
diff --git a/apps/files_sharing/tests/controller/sharecontroller.php b/apps/files_sharing/tests/controller/sharecontroller.php
deleted file mode 100644
index db8c7fe553c..00000000000
--- a/apps/files_sharing/tests/controller/sharecontroller.php
+++ /dev/null
@@ -1,437 +0,0 @@
-<?php
-/**
- * @author Georg Ehrke <georg@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Cloutier <vincent1cloutier@gmail.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Controllers;
-
-use OC\Files\Filesystem;
-use OCP\Share\Exceptions\ShareNotFound;
-use OCP\AppFramework\Http\NotFoundResponse;
-use OCP\AppFramework\Http\RedirectResponse;
-use OCP\AppFramework\Http\TemplateResponse;
-use OCP\ISession;
-use OCP\IUserManager;
-use OCP\Security\ISecureRandom;
-use OCP\IURLGenerator;
-
-/**
- * @group DB
- *
- * @package OCA\Files_Sharing\Controllers
- */
-class ShareControllerTest extends \Test\TestCase {
-
- /** @var string */
- private $user;
- /** @var string */
- private $oldUser;
-
- /** @var string */
- private $appName = 'files_sharing';
- /** @var ShareController */
- private $shareController;
- /** @var IURLGenerator | \PHPUnit_Framework_MockObject_MockObject */
- private $urlGenerator;
- /** @var ISession | \PHPUnit_Framework_MockObject_MockObject */
- private $session;
- /** @var \OCP\IPreview | \PHPUnit_Framework_MockObject_MockObject */
- private $previewManager;
- /** @var \OCP\IConfig | \PHPUnit_Framework_MockObject_MockObject */
- private $config;
- /** @var \OC\Share20\Manager | \PHPUnit_Framework_MockObject_MockObject */
- private $shareManager;
- /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */
- private $userManager;
-
- protected function setUp() {
- $this->appName = 'files_sharing';
-
- $this->shareManager = $this->getMockBuilder('\OC\Share20\Manager')->disableOriginalConstructor()->getMock();
- $this->urlGenerator = $this->getMock('\OCP\IURLGenerator');
- $this->session = $this->getMock('\OCP\ISession');
- $this->previewManager = $this->getMock('\OCP\IPreview');
- $this->config = $this->getMock('\OCP\IConfig');
- $this->userManager = $this->getMock('\OCP\IUserManager');
-
- $this->shareController = new \OCA\Files_Sharing\Controllers\ShareController(
- $this->appName,
- $this->getMock('\OCP\IRequest'),
- $this->config,
- $this->urlGenerator,
- $this->userManager,
- $this->getMock('\OCP\ILogger'),
- $this->getMock('\OCP\Activity\IManager'),
- $this->shareManager,
- $this->session,
- $this->previewManager,
- $this->getMock('\OCP\Files\IRootFolder')
- );
-
-
- // Store current user
- $this->oldUser = \OC_User::getUser();
-
- // Create a dummy user
- $this->user = \OC::$server->getSecureRandom()->generate(12, ISecureRandom::CHAR_LOWER);
-
- \OC::$server->getUserManager()->createUser($this->user, $this->user);
- \OC_Util::tearDownFS();
- $this->loginAsUser($this->user);
- }
-
- protected function tearDown() {
- \OC_Util::tearDownFS();
- \OC_User::setUserId('');
- Filesystem::tearDown();
- $user = \OC::$server->getUserManager()->get($this->user);
- if ($user !== null) { $user->delete(); }
- \OC_User::setIncognitoMode(false);
-
- \OC::$server->getSession()->set('public_link_authenticated', '');
-
- // Set old user
- \OC_User::setUserId($this->oldUser);
- \OC_Util::setupFS($this->oldUser);
- }
-
- public function testShowAuthenticateNotAuthenticated() {
- $share = \OC::$server->getShareManager()->newShare();
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('token')
- ->willReturn($share);
-
- $response = $this->shareController->showAuthenticate('token');
- $expectedResponse = new TemplateResponse($this->appName, 'authenticate', [], 'guest');
- $this->assertEquals($expectedResponse, $response);
- }
-
- public function testShowAuthenticateAuthenticatedForDifferentShare() {
- $share = \OC::$server->getShareManager()->newShare();
- $share->setId(1);
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('token')
- ->willReturn($share);
-
- $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
- $this->session->method('get')->with('public_link_authenticated')->willReturn('2');
-
- $response = $this->shareController->showAuthenticate('token');
- $expectedResponse = new TemplateResponse($this->appName, 'authenticate', [], 'guest');
- $this->assertEquals($expectedResponse, $response);
- }
-
- public function testShowAuthenticateCorrectShare() {
- $share = \OC::$server->getShareManager()->newShare();
- $share->setId(1);
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('token')
- ->willReturn($share);
-
- $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
- $this->session->method('get')->with('public_link_authenticated')->willReturn('1');
-
- $this->urlGenerator->expects($this->once())
- ->method('linkToRoute')
- ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
- ->willReturn('redirect');
-
- $response = $this->shareController->showAuthenticate('token');
- $expectedResponse = new RedirectResponse('redirect');
- $this->assertEquals($expectedResponse, $response);
- }
-
- public function testAutehnticateInvalidToken() {
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('token')
- ->will($this->throwException(new \OCP\Share\Exceptions\ShareNotFound()));
-
- $response = $this->shareController->authenticate('token');
- $expectedResponse = new NotFoundResponse();
- $this->assertEquals($expectedResponse, $response);
- }
-
- public function testAuthenticateValidPassword() {
- $share = \OC::$server->getShareManager()->newShare();
- $share->setId(42);
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('token')
- ->willReturn($share);
-
- $this->shareManager
- ->expects($this->once())
- ->method('checkPassword')
- ->with($share, 'validpassword')
- ->willReturn(true);
-
- $this->session
- ->expects($this->once())
- ->method('set')
- ->with('public_link_authenticated', '42');
-
- $this->urlGenerator->expects($this->once())
- ->method('linkToRoute')
- ->with('files_sharing.sharecontroller.showShare', ['token'=>'token'])
- ->willReturn('redirect');
-
- $response = $this->shareController->authenticate('token', 'validpassword');
- $expectedResponse = new RedirectResponse('redirect');
- $this->assertEquals($expectedResponse, $response);
- }
-
- public function testAuthenticateInvalidPassword() {
- $share = \OC::$server->getShareManager()->newShare();
- $share->setNodeId(100)
- ->setNodeType('file')
- ->setToken('token')
- ->setSharedBy('initiator')
- ->setId(42);
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('token')
- ->willReturn($share);
-
- $this->shareManager
- ->expects($this->once())
- ->method('checkPassword')
- ->with($share, 'invalidpassword')
- ->willReturn(false);
-
- $this->session
- ->expects($this->never())
- ->method('set');
-
- $hookListner = $this->getMockBuilder('Dummy')->setMethods(['access'])->getMock();
- \OCP\Util::connectHook('OCP\Share', 'share_link_access', $hookListner, 'access');
-
- $hookListner->expects($this->once())
- ->method('access')
- ->with($this->callback(function(array $data) {
- return $data['itemType'] === 'file' &&
- $data['itemSource'] === 100 &&
- $data['uidOwner'] === 'initiator' &&
- $data['token'] === 'token' &&
- $data['errorCode'] === 403 &&
- $data['errorMessage'] === 'Wrong password';
- }));
-
- $response = $this->shareController->authenticate('token', 'invalidpassword');
- $expectedResponse = new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest');
- $this->assertEquals($expectedResponse, $response);
- }
-
- public function testShowShareInvalidToken() {
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('invalidtoken')
- ->will($this->throwException(new ShareNotFound()));
-
- // Test without a not existing token
- $response = $this->shareController->showShare('invalidtoken');
- $expectedResponse = new NotFoundResponse();
- $this->assertEquals($expectedResponse, $response);
- }
-
- public function testShowShareNotAuthenticated() {
- $share = \OC::$server->getShareManager()->newShare();
- $share->setPassword('password');
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('validtoken')
- ->willReturn($share);
-
- $this->urlGenerator->expects($this->once())
- ->method('linkToRoute')
- ->with('files_sharing.sharecontroller.authenticate', ['token' => 'validtoken'])
- ->willReturn('redirect');
-
- // Test without a not existing token
- $response = $this->shareController->showShare('validtoken');
- $expectedResponse = new RedirectResponse('redirect');
- $this->assertEquals($expectedResponse, $response);
- }
-
-
- public function testShowShare() {
- $owner = $this->getMock('OCP\IUser');
- $owner->method('getDisplayName')->willReturn('ownerDisplay');
- $owner->method('getUID')->willReturn('ownerUID');
-
- $file = $this->getMock('OCP\Files\File');
- $file->method('getName')->willReturn('file1.txt');
- $file->method('getMimetype')->willReturn('text/plain');
- $file->method('getSize')->willReturn(33);
- $file->method('isReadable')->willReturn(true);
- $file->method('isShareable')->willReturn(true);
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setId(42);
- $share->setPassword('password')
- ->setShareOwner('ownerUID')
- ->setNode($file)
- ->setTarget('/file1.txt');
-
- $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
- $this->session->method('get')->with('public_link_authenticated')->willReturn('42');
-
- $this->previewManager->method('isMimeSupported')->with('text/plain')->willReturn(true);
-
- $this->config->method('getSystemValue')
- ->willReturnMap(
- [
- ['max_filesize_animated_gifs_public_sharing', 10, 10],
- ['enable_previews', true, true],
- ]
- );
- $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
- $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('token')
- ->willReturn($share);
-
- $this->userManager->method('get')->with('ownerUID')->willReturn($owner);
-
- $response = $this->shareController->showShare('token');
- $sharedTmplParams = array(
- 'displayName' => 'ownerDisplay',
- 'owner' => 'ownerUID',
- 'filename' => 'file1.txt',
- 'directory_path' => '/file1.txt',
- 'mimetype' => 'text/plain',
- 'dirToken' => 'token',
- 'sharingToken' => 'token',
- 'server2serversharing' => true,
- 'protected' => 'true',
- 'dir' => '',
- 'downloadURL' => null,
- 'fileSize' => '33 B',
- 'nonHumanFileSize' => 33,
- 'maxSizeAnimateGif' => 10,
- 'previewSupported' => true,
- 'previewEnabled' => true,
- );
-
- $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
- $csp->addAllowedFrameDomain('\'self\'');
- $expectedResponse = new TemplateResponse($this->appName, 'public', $sharedTmplParams, 'base');
- $expectedResponse->setContentSecurityPolicy($csp);
-
- $this->assertEquals($expectedResponse, $response);
- }
-
- /**
- * @expectedException \OCP\Files\NotFoundException
- */
- public function testShowShareInvalid() {
- $owner = $this->getMock('OCP\IUser');
- $owner->method('getDisplayName')->willReturn('ownerDisplay');
- $owner->method('getUID')->willReturn('ownerUID');
-
- $file = $this->getMock('OCP\Files\File');
- $file->method('getName')->willReturn('file1.txt');
- $file->method('getMimetype')->willReturn('text/plain');
- $file->method('getSize')->willReturn(33);
- $file->method('isShareable')->willReturn(false);
- $file->method('isReadable')->willReturn(true);
-
- $share = \OC::$server->getShareManager()->newShare();
- $share->setId(42);
- $share->setPassword('password')
- ->setShareOwner('ownerUID')
- ->setNode($file)
- ->setTarget('/file1.txt');
-
- $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
- $this->session->method('get')->with('public_link_authenticated')->willReturn('42');
-
- $this->previewManager->method('isMimeSupported')->with('text/plain')->willReturn(true);
-
- $this->config->method('getSystemValue')
- ->willReturnMap(
- [
- ['max_filesize_animated_gifs_public_sharing', 10, 10],
- ['enable_previews', true, true],
- ]
- );
- $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
- $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('token')
- ->willReturn($share);
-
- $this->userManager->method('get')->with('ownerUID')->willReturn($owner);
-
- $this->shareController->showShare('token');
- }
-
-
- public function testDownloadShare() {
- $share = $this->getMock('\OCP\Share\IShare');
- $share->method('getPassword')->willReturn('password');
-
- $this->shareManager
- ->expects($this->once())
- ->method('getShareByToken')
- ->with('validtoken')
- ->willReturn($share);
-
- $this->urlGenerator->expects($this->once())
- ->method('linkToRoute')
- ->with('files_sharing.sharecontroller.authenticate', ['token' => 'validtoken'])
- ->willReturn('redirect');
-
- // Test with a password protected share and no authentication
- $response = $this->shareController->downloadShare('validtoken');
- $expectedResponse = new RedirectResponse('redirect');
- $this->assertEquals($expectedResponse, $response);
- }
-
-}
diff --git a/apps/files_sharing/tests/deleteorphanedsharesjobtest.php b/apps/files_sharing/tests/deleteorphanedsharesjobtest.php
deleted file mode 100644
index 353520bd604..00000000000
--- a/apps/files_sharing/tests/deleteorphanedsharesjobtest.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-/**
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace Test\BackgroundJob;
-
-use OCA\Files_sharing\Lib\DeleteOrphanedSharesJob;
-
-/**
- * Class DeleteOrphanedSharesJobTest
- *
- * @group DB
- *
- * @package Test\BackgroundJob
- */
-class DeleteOrphanedSharesJobTest extends \Test\TestCase {
-
- /**
- * @var bool
- */
- private static $trashBinStatus;
-
- /**
- * @var DeleteOrphanedSharesJob
- */
- private $job;
-
- /**
- * @var \OCP\IDBConnection
- */
- private $connection;
-
- /**
- * @var string
- */
- private $user1;
-
- /**
- * @var string
- */
- private $user2;
-
- public static function setUpBeforeClass() {
- $appManager = \OC::$server->getAppManager();
- self::$trashBinStatus = $appManager->isEnabledForUser('files_trashbin');
- $appManager->disableApp('files_trashbin');
-
- // just in case...
- \OC\Files\Filesystem::getLoader()->removeStorageWrapper('oc_trashbin');
- }
-
- public static function tearDownAfterClass() {
- if (self::$trashBinStatus) {
- \OC::$server->getAppManager()->enableApp('files_trashbin');
- }
- }
-
- protected function setup() {
- parent::setUp();
-
- $this->connection = \OC::$server->getDatabaseConnection();
- // clear occasional leftover shares from other tests
- $this->connection->executeUpdate('DELETE FROM `*PREFIX*share`');
-
- $this->user1 = $this->getUniqueID('user1_');
- $this->user2 = $this->getUniqueID('user2_');
-
- $userManager = \OC::$server->getUserManager();
- $userManager->createUser($this->user1, 'pass');
- $userManager->createUser($this->user2, 'pass');
-
- \OC::registerShareHooks();
-
- $this->job = new DeleteOrphanedSharesJob();
- }
-
- protected function tearDown() {
- $this->connection->executeUpdate('DELETE FROM `*PREFIX*share`');
-
- $userManager = \OC::$server->getUserManager();
- $user1 = $userManager->get($this->user1);
- if($user1) {
- $user1->delete();
- }
- $user2 = $userManager->get($this->user2);
- if($user2) {
- $user2->delete();
- }
-
- $this->logout();
-
- parent::tearDown();
- }
-
- private function getShares() {
- $shares = [];
- $result = $this->connection->executeQuery('SELECT * FROM `*PREFIX*share`');
- while ($row = $result->fetch()) {
- $shares[] = $row;
- }
- $result->closeCursor();
- return $shares;
- }
-
- /**
- * Test clearing orphaned shares
- */
- public function testClearShares() {
- $this->loginAsUser($this->user1);
-
- $view = new \OC\Files\View('/' . $this->user1 . '/');
- $view->mkdir('files/test');
- $view->mkdir('files/test/sub');
-
- $fileInfo = $view->getFileInfo('files/test/sub');
- $fileId = $fileInfo->getId();
-
- $this->assertTrue(
- \OCP\Share::shareItem('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ),
- 'Failed asserting that user 1 successfully shared "test/sub" with user 2.'
- );
-
- $this->assertCount(1, $this->getShares());
-
- $this->job->run([]);
-
- $this->assertCount(1, $this->getShares(), 'Linked shares not deleted');
-
- $view->unlink('files/test');
-
- $this->job->run([]);
-
- $this->assertCount(0, $this->getShares(), 'Orphaned shares deleted');
- }
-
- public function testKeepNonFileShares() {
- $this->loginAsUser($this->user1);
-
- \OCP\Share::registerBackend('test', 'Test_Share_Backend');
-
- $this->assertTrue(
- \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ),
- 'Failed asserting that user 1 successfully shared something with user 2.'
- );
-
- $this->assertCount(1, $this->getShares());
-
- $this->job->run([]);
-
- $this->assertCount(1, $this->getShares(), 'Non-file shares kept');
- }
-}
-
diff --git a/apps/files_sharing/tests/external/cache.php b/apps/files_sharing/tests/external/cache.php
deleted file mode 100644
index 4ae1bc563df..00000000000
--- a/apps/files_sharing/tests/external/cache.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-namespace OCA\Files_sharing\Tests\External;
-
-use OCA\Files_sharing\Tests\TestCase;
-
-/**
- * Class Cache
- *
- * @group DB
- *
- * @package OCA\Files_sharing\Tests\External
- */
-class Cache extends TestCase {
-
- /**
- * @var \OC\Files\Storage\Storage
- **/
- private $storage;
-
- /**
- * @var \OCA\Files_Sharing\External\Cache
- */
- private $cache;
-
- /**
- * @var string
- */
- private $remoteUser;
-
- protected function setUp() {
- parent::setUp();
-
- $this->remoteUser = $this->getUniqueID('remoteuser');
-
- $this->storage = $this->getMockBuilder('\OCA\Files_Sharing\External\Storage')
- ->disableOriginalConstructor()
- ->getMock();
- $this->storage
- ->expects($this->any())
- ->method('getId')
- ->will($this->returnValue('dummystorage::'));
- $this->cache = new \OCA\Files_Sharing\External\Cache(
- $this->storage,
- 'http://example.com/owncloud',
- $this->remoteUser
- );
- $this->cache->put(
- 'test.txt',
- array(
- 'mimetype' => 'text/plain',
- 'size' => 5,
- 'mtime' => 123,
- )
- );
- }
-
- protected function tearDown() {
- if ($this->cache) {
- $this->cache->clear();
- }
- parent::tearDown();
- }
-
- public function testGetInjectsOwnerDisplayName() {
- $info = $this->cache->get('test.txt');
- $this->assertEquals(
- $this->remoteUser . '@example.com/owncloud',
- $info['displayname_owner']
- );
- }
-
- public function testGetReturnsFalseIfNotFound() {
- $info = $this->cache->get('unexisting-entry.txt');
- $this->assertFalse($info);
- }
-
- public function testGetFolderPopulatesOwner() {
- $dirId = $this->cache->put(
- 'subdir',
- array(
- 'mimetype' => 'httpd/unix-directory',
- 'size' => 5,
- 'mtime' => 123,
- )
- );
- $this->cache->put(
- 'subdir/contents.txt',
- array(
- 'mimetype' => 'text/plain',
- 'size' => 5,
- 'mtime' => 123,
- )
- );
-
- $results = $this->cache->getFolderContentsById($dirId);
- $this->assertEquals(1, count($results));
- $this->assertEquals(
- $this->remoteUser . '@example.com/owncloud',
- $results[0]['displayname_owner']
- );
- }
-
-}
diff --git a/apps/files_sharing/tests/external/managertest.php b/apps/files_sharing/tests/external/managertest.php
deleted file mode 100644
index 48a9098ae1d..00000000000
--- a/apps/files_sharing/tests/external/managertest.php
+++ /dev/null
@@ -1,253 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Tests\External;
-
-use OC\Files\Storage\StorageFactory;
-use OCA\FederatedFileSharing\DiscoveryManager;
-use OCA\Files_Sharing\External\Manager;
-use OCA\Files_Sharing\External\MountProvider;
-use OCA\Files_Sharing\Tests\TestCase;
-use Test\Traits\UserTrait;
-
-/**
- * Class ManagerTest
- *
- * @group DB
- *
- * @package OCA\Files_Sharing\Tests\External
- */
-class ManagerTest extends TestCase {
- use UserTrait;
-
- /** @var Manager **/
- private $manager;
-
- /** @var \OC\Files\Mount\Manager */
- private $mountManager;
-
- /** @var \PHPUnit_Framework_MockObject_MockObject */
- private $httpHelper;
-
- private $uid;
-
- /**
- * @var \OCP\IUser
- */
- private $user;
- private $mountProvider;
-
- protected function setUp() {
- 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->httpHelper = $httpHelper = $this->getMockBuilder('\OC\HTTPHelper')->disableOriginalConstructor()->getMock();
- $discoveryManager = new DiscoveryManager(
- \OC::$server->getMemCacheFactory(),
- \OC::$server->getHTTPClientService()
- );
- /** @var \OC\HTTPHelper $httpHelper */
- $this->manager = new Manager(
- \OC::$server->getDatabaseConnection(),
- $this->mountManager,
- new StorageFactory(),
- $httpHelper,
- \OC::$server->getNotificationManager(),
- $discoveryManager,
- $this->uid
- );
- $this->mountProvider = new MountProvider(\OC::$server->getDatabaseConnection(), function() {
- return $this->manager;
- });
- }
-
- private function setupMounts() {
- $mounts = $this->mountProvider->getMountsForUser($this->user, new StorageFactory());
- foreach ($mounts as $mount) {
- $this->mountManager->addMount($mount);
- }
- }
-
- public function testAddShare() {
-
- $shareData1 = [
- 'remote' => 'http://localhost',
- 'token' => 'token1',
- 'password' => '',
- 'name' => '/SharedFolder',
- 'owner' => 'foobar',
- 'accepted' => false,
- 'user' => $this->uid,
- ];
- $shareData2 = $shareData1;
- $shareData2['token'] = 'token2';
- $shareData3 = $shareData1;
- $shareData3['token'] = 'token3';
-
- // 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->setupMounts();
- $this->assertNotMount('SharedFolder');
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
-
- // Add a second share for "user" with the same name
- $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'] . '}}');
- // New share falls back to "-1" appendix, because the name is already taken
- $this->assertExternalShareEntry($shareData2, $openShares[1], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1');
-
- $this->setupMounts();
- $this->assertNotMount('SharedFolder');
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1');
-
- $this->httpHelper->expects($this->at(0))
- ->method('post')
- ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $openShares[0]['remote_id']), $this->anything());
-
- // Accept the first share
- $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']);
- // Check remaining shares - Open
- $openShares = $this->manager->getOpenShares();
- $this->assertCount(1, $openShares);
- $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1');
-
- $this->setupMounts();
- $this->assertMount($shareData1['name']);
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1');
-
- // Add another share for "user" with the same name
- $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->setupMounts();
- $this->assertMount($shareData1['name']);
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1');
-
- $this->httpHelper->expects($this->at(0))
- ->method('post')
- ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $openShares[1]['remote_id'] . '/decline'), $this->anything());
-
- // Decline the third share
- $this->manager->declineShare($openShares[1]['id']);
-
- $this->setupMounts();
- $this->assertMount($shareData1['name']);
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1');
-
- // 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']);
- // Check remaining shares - Open
- $openShares = $this->manager->getOpenShares();
- $this->assertCount(1, $openShares);
- $this->assertExternalShareEntry($shareData2, $openShares[0], 2, '{{TemporaryMountPointName#' . $shareData2['name'] . '}}-1');
-
- $this->setupMounts();
- $this->assertMount($shareData1['name']);
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1');
-
- $this->httpHelper->expects($this->at(0))
- ->method('post')
- ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $openShares[0]['remote_id'] . '/decline'), $this->anything());
- $this->httpHelper->expects($this->at(1))
- ->method('post')
- ->with($this->stringStartsWith('http://localhost/ocs/v1.php/cloud/shares/' . $acceptedShares[0]['remote_id'] . '/decline'), $this->anything());
-
- $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();
- self::invokePrivate($this->manager, 'setupMounts');
- $this->assertNotMount($shareData1['name']);
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}');
- $this->assertNotMount('{{TemporaryMountPointName#' . $shareData1['name'] . '}}-1');
- }
-
- /**
- * @param array $expected
- * @param array $actual
- * @param int $share
- * @param string $mountPoint
- */
- protected function assertExternalShareEntry($expected, $actual, $share, $mountPoint) {
- $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($mountPoint, $actual['mountpoint'], 'Asserting mountpoint of a share #' . $share);
- }
-
- private function assertMount($mountPoint) {
- $mountPoint = rtrim($mountPoint, '/');
- $mount = $this->mountManager->find($this->getFullPath($mountPoint));
- $this->assertInstanceOf('\OCA\Files_Sharing\External\Mount', $mount);
- $this->assertInstanceOf('\OCP\Files\Mount\IMountPoint', $mount);
- $this->assertEquals($this->getFullPath($mountPoint), rtrim($mount->getMountPoint(), '/'));
- $storage = $mount->getStorage();
- $this->assertInstanceOf('\OCA\Files_Sharing\External\Storage', $storage);
- }
-
- private function assertNotMount($mountPoint) {
- $mountPoint = rtrim($mountPoint, '/');
- $mount = $this->mountManager->find($this->getFullPath($mountPoint));
- if ($mount) {
- $this->assertInstanceOf('\OCP\Files\Mount\IMountPoint', $mount);
- $this->assertNotEquals($this->getFullPath($mountPoint), rtrim($mount->getMountPoint(), '/'));
- } else {
- $this->assertNull($mount);
- }
- }
-
- private function getFullPath($path) {
- return '/' . $this->uid . '/files' . $path;
- }
-}
diff --git a/apps/files_sharing/tests/external/scannertest.php b/apps/files_sharing/tests/external/scannertest.php
deleted file mode 100644
index f16e9952fce..00000000000
--- a/apps/files_sharing/tests/external/scannertest.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Tests\External;
-
-use OCA\Files_Sharing\External\Scanner;
-use Test\TestCase;
-
-class ScannerTest extends TestCase {
- /** @var \OCA\Files_Sharing\External\Scanner */
- protected $scanner;
- /** @var \OCA\Files_Sharing\External\Storage|\PHPUnit_Framework_MockObject_MockObject */
- protected $storage;
- /** @var \OC\Files\Cache\Cache|\PHPUnit_Framework_MockObject_MockObject */
- protected $cache;
-
- protected function setUp() {
- parent::setUp();
-
- $this->storage = $this->getMockBuilder('\OCA\Files_Sharing\External\Storage')
- ->disableOriginalConstructor()
- ->getMock();
- $this->cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
- ->disableOriginalConstructor()
- ->getMock();
- $this->storage->expects($this->any())
- ->method('getCache')
- ->willReturn($this->cache);
-
- $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->assertTrue(true);
- }
-
- public function testScan() {
- $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->scan('test', Scanner::SCAN_RECURSIVE);
- $this->assertTrue(true);
- }
-
- public function testScanFile() {
- // 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->scanFile('test', Scanner::SCAN_RECURSIVE);
- $this->assertTrue(true);
- }
-}
diff --git a/apps/files_sharing/tests/externalstorage.php b/apps/files_sharing/tests/externalstorage.php
deleted file mode 100644
index 54cd7d1645c..00000000000
--- a/apps/files_sharing/tests/externalstorage.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-/**
- * Tests for the external Storage class for remote shares.
- *
- * @group DB
- */
-class Test_Files_Sharing_External_Storage extends \Test\TestCase {
-
- function optionsProvider() {
- return array(
- array(
- 'http://remoteserver:8080/owncloud',
- 'http://remoteserver:8080/owncloud/public.php/webdav/',
- ),
- // extra slash
- array(
- 'http://remoteserver:8080/owncloud/',
- 'http://remoteserver:8080/owncloud/public.php/webdav/',
- ),
- // extra path
- array(
- 'http://remoteserver:8080/myservices/owncloud/',
- 'http://remoteserver:8080/myservices/owncloud/public.php/webdav/',
- ),
- // root path
- array(
- 'http://remoteserver:8080/',
- 'http://remoteserver:8080/public.php/webdav/',
- ),
- // without port
- array(
- 'http://remoteserver/oc.test',
- 'http://remoteserver/oc.test/public.php/webdav/',
- ),
- // https
- array(
- 'https://remoteserver/',
- 'https://remoteserver/public.php/webdav/',
- ),
- );
- }
-
- /**
- * @dataProvider optionsProvider
- */
- public function testStorageMountOptions($inputUri, $baseUri) {
- $certificateManager = \OC::$server->getCertificateManager();
- $storage = new TestSharingExternalStorage(
- array(
- 'remote' => $inputUri,
- 'owner' => 'testOwner',
- 'mountpoint' => 'remoteshare',
- 'token' => 'abcdef',
- 'password' => '',
- 'manager' => null,
- 'certificateManager' => $certificateManager
- )
- );
- $this->assertEquals($baseUri, $storage->getBaseUri());
- }
-}
-
-/**
- * Dummy subclass to make it possible to access private members
- */
-class TestSharingExternalStorage extends \OCA\Files_Sharing\External\Storage {
-
- public function getBaseUri() {
- return $this->createBaseUri();
- }
-}
diff --git a/apps/files_sharing/tests/helper.php b/apps/files_sharing/tests/helper.php
deleted file mode 100644
index 07f07f911cb..00000000000
--- a/apps/files_sharing/tests/helper.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-use OCA\Files_sharing\Tests\TestCase;
-
-/**
- * Class Test_Files_Sharing_Helper
- *
- * @group DB
- */
-class Test_Files_Sharing_Helper extends TestCase {
-
- /**
- * test set and get share folder
- */
- function testSetGetShareFolder() {
- $this->assertSame('/', \OCA\Files_Sharing\Helper::getShareFolder());
-
- \OCA\Files_Sharing\Helper::setShareFolder('/Shared/Folder');
-
- $sharedFolder = \OCA\Files_Sharing\Helper::getShareFolder();
- $this->assertSame('/Shared/Folder', \OCA\Files_Sharing\Helper::getShareFolder());
- $this->assertTrue(\OC\Files\Filesystem::is_dir($sharedFolder));
-
- // cleanup
- \OC::$server->getConfig()->deleteSystemValue('share_folder');
-
- }
-
-}
diff --git a/apps/files_sharing/tests/js/appSpec.js b/apps/files_sharing/tests/js/appSpec.js
deleted file mode 100644
index 133bd44f750..00000000000
--- a/apps/files_sharing/tests/js/appSpec.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-describe('OCA.Sharing.App tests', function() {
- var App = OCA.Sharing.App;
- var fileListIn;
- var fileListOut;
-
- beforeEach(function() {
- $('#testArea').append(
- '<div id="app-navigation">' +
- '<ul><li data-id="files"><a>Files</a></li>' +
- '<li data-id="sharingin"><a></a></li>' +
- '<li data-id="sharingout"><a></a></li>' +
- '</ul></div>' +
- '<div id="app-content">' +
- '<div id="app-content-files" class="hidden">' +
- '</div>' +
- '<div id="app-content-sharingin" class="hidden">' +
- '</div>' +
- '<div id="app-content-sharingout" class="hidden">' +
- '</div>' +
- '</div>' +
- '</div>'
- );
- fileListIn = App.initSharingIn($('#app-content-sharingin'));
- fileListOut = App.initSharingOut($('#app-content-sharingout'));
- });
- afterEach(function() {
- App.destroy();
- });
-
- describe('initialization', function() {
- it('inits sharing-in list on show', function() {
- expect(fileListIn._sharedWithUser).toEqual(true);
- });
- it('inits sharing-out list on show', function() {
- expect(fileListOut._sharedWithUser).toBeFalsy();
- });
- });
- describe('file actions', function() {
- var oldLegacyFileActions;
-
- beforeEach(function() {
- oldLegacyFileActions = window.FileActions;
- window.FileActions = new OCA.Files.FileActions();
- });
-
- afterEach(function() {
- window.FileActions = oldLegacyFileActions;
- });
- it('provides default file actions', function() {
- _.each([fileListIn, fileListOut], function(fileList) {
- var fileActions = fileList.fileActions;
-
- expect(fileActions.actions.all).toBeDefined();
- expect(fileActions.actions.all.Delete).toBeDefined();
- expect(fileActions.actions.all.Rename).toBeDefined();
- expect(fileActions.actions.all.Download).toBeDefined();
-
- expect(fileActions.defaults.dir).toEqual('Open');
- });
- });
- it('provides custom file actions', function() {
- var actionStub = sinon.stub();
- // regular file action
- OCA.Files.fileActions.register(
- 'all',
- 'RegularTest',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/shared'),
- actionStub
- );
-
- App._inFileList = null;
- fileListIn = App.initSharingIn($('#app-content-sharingin'));
-
- expect(fileListIn.fileActions.actions.all.RegularTest).toBeDefined();
- });
- it('does not provide legacy file actions', function() {
- var actionStub = sinon.stub();
- // legacy file action
- window.FileActions.register(
- 'all',
- 'LegacyTest',
- OC.PERMISSION_READ,
- OC.imagePath('core', 'actions/shared'),
- actionStub
- );
-
- App._inFileList = null;
- fileListIn = App.initSharingIn($('#app-content-sharingin'));
-
- expect(fileListIn.fileActions.actions.all.LegacyTest).not.toBeDefined();
- });
- it('redirects to files app when opening a directory', function() {
- var oldList = OCA.Files.App.fileList;
- // dummy new list to make sure it exists
- OCA.Files.App.fileList = new OCA.Files.FileList($('<table><thead></thead><tbody></tbody></table>'));
-
- var setActiveViewStub = sinon.stub(OCA.Files.App, 'setActiveView');
- // create dummy table so we can click the dom
- var $table = '<table><thead></thead><tbody id="fileList"></tbody></table>';
- $('#app-content-sharingin').append($table);
-
- App._inFileList = null;
- fileListIn = App.initSharingIn($('#app-content-sharingin'));
-
- fileListIn.setFiles([{
- name: 'testdir',
- type: 'dir',
- path: '/somewhere/inside/subdir',
- counterParts: ['user2'],
- shareOwner: 'user2'
- }]);
-
- fileListIn.findFileEl('testdir').find('td .nametext').click();
-
- expect(OCA.Files.App.fileList.getCurrentDirectory()).toEqual('/somewhere/inside/subdir/testdir');
-
- expect(setActiveViewStub.calledOnce).toEqual(true);
- expect(setActiveViewStub.calledWith('files')).toEqual(true);
-
- setActiveViewStub.restore();
-
- // restore old list
- OCA.Files.App.fileList = oldList;
- });
- });
-});
diff --git a/apps/files_sharing/tests/js/externalSpec.js b/apps/files_sharing/tests/js/externalSpec.js
deleted file mode 100644
index 362df49252b..00000000000
--- a/apps/files_sharing/tests/js/externalSpec.js
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-describe('OCA.Sharing external tests', function() {
- var plugin;
- var urlQueryStub;
- var promptDialogStub;
- var confirmDialogStub;
-
- function dummyShowDialog() {
- var deferred = $.Deferred();
- deferred.resolve();
- return deferred.promise();
- }
-
- beforeEach(function() {
- plugin = OCA.Sharing.ExternalShareDialogPlugin;
- urlQueryStub = sinon.stub(OC.Util.History, 'parseUrlQuery');
-
- confirmDialogStub = sinon.stub(OC.dialogs, 'confirm', dummyShowDialog);
- promptDialogStub = sinon.stub(OC.dialogs, 'prompt', dummyShowDialog);
-
- plugin.filesApp = {
- fileList: {
- reload: sinon.stub()
- }
- };
- });
- afterEach(function() {
- urlQueryStub.restore();
- confirmDialogStub.restore();
- promptDialogStub.restore();
- plugin = null;
- });
- describe('confirmation dialog from URL', function() {
- var testShare;
-
- /**
- * Checks that the server call's query matches what is
- * expected.
- *
- * @param {Object} expectedQuery expected query params
- */
- function checkRequest(expectedQuery) {
- var request = fakeServer.requests[0];
- var query = OC.parseQueryString(request.requestBody);
- expect(request.method).toEqual('POST');
- expect(query).toEqual(expectedQuery);
-
- request.respond(
- 200,
- {'Content-Type': 'application/json'},
- JSON.stringify({status: 'success'})
- );
- expect(plugin.filesApp.fileList.reload.calledOnce).toEqual(true);
- }
-
- beforeEach(function() {
- testShare = {
- remote: 'http://example.com/owncloud',
- token: 'abcdefg',
- owner: 'theowner',
- ownerDisplayName: 'The Generous Owner',
- name: 'the share name'
- };
- });
- it('does nothing when no share was passed in URL', function() {
- urlQueryStub.returns({});
- plugin.processIncomingShareFromUrl();
- expect(promptDialogStub.notCalled).toEqual(true);
- expect(confirmDialogStub.notCalled).toEqual(true);
- expect(fakeServer.requests.length).toEqual(0);
- });
- it('sends share info to server on confirm', function() {
- urlQueryStub.returns(testShare);
- plugin.processIncomingShareFromUrl();
- expect(promptDialogStub.notCalled).toEqual(true);
- expect(confirmDialogStub.calledOnce).toEqual(true);
- confirmDialogStub.getCall(0).args[2](true);
- expect(fakeServer.requests.length).toEqual(1);
- checkRequest({
- remote: 'http://example.com/owncloud',
- token: 'abcdefg',
- owner: 'theowner',
- ownerDisplayName: 'The Generous Owner',
- name: 'the share name',
- password: ''
- });
- });
- it('sends share info with password to server on confirm', function() {
- testShare = _.extend(testShare, {protected: 1});
- urlQueryStub.returns(testShare);
- plugin.processIncomingShareFromUrl();
- expect(promptDialogStub.calledOnce).toEqual(true);
- expect(confirmDialogStub.notCalled).toEqual(true);
- promptDialogStub.getCall(0).args[2](true, 'thepassword');
- expect(fakeServer.requests.length).toEqual(1);
- checkRequest({
- remote: 'http://example.com/owncloud',
- token: 'abcdefg',
- owner: 'theowner',
- ownerDisplayName: 'The Generous Owner',
- name: 'the share name',
- password: 'thepassword'
- });
- });
- it('does not send share info on cancel', function() {
- urlQueryStub.returns(testShare);
- plugin.processIncomingShareFromUrl();
- expect(promptDialogStub.notCalled).toEqual(true);
- expect(confirmDialogStub.calledOnce).toEqual(true);
- confirmDialogStub.getCall(0).args[2](false);
- expect(fakeServer.requests.length).toEqual(0);
- });
- });
- describe('show dialog for each share to confirm', function() {
- var testShare;
-
- /**
- * Call processSharesToConfirm() and make the fake server
- * return the passed response.
- *
- * @param {Array} response list of shares to process
- */
- function processShares(response) {
- plugin.processSharesToConfirm();
-
- expect(fakeServer.requests.length).toEqual(1);
-
- var req = fakeServer.requests[0];
- expect(req.method).toEqual('GET');
- expect(req.url).toEqual(OC.webroot + '/index.php/apps/files_sharing/api/externalShares');
-
- req.respond(
- 200,
- {'Content-Type': 'application/json'},
- JSON.stringify(response)
- );
- }
-
- beforeEach(function() {
- testShare = {
- id: 123,
- remote: 'http://example.com/owncloud',
- token: 'abcdefg',
- owner: 'theowner',
- ownerDisplayName: 'The Generous Owner',
- name: 'the share name'
- };
- });
-
- it('does not show any dialog if no shares to confirm', function() {
- processShares([]);
- expect(confirmDialogStub.notCalled).toEqual(true);
- expect(promptDialogStub.notCalled).toEqual(true);
- });
- it('sends accept info to server on confirm', function() {
- processShares([testShare]);
-
- expect(promptDialogStub.notCalled).toEqual(true);
- expect(confirmDialogStub.calledOnce).toEqual(true);
-
- confirmDialogStub.getCall(0).args[2](true);
-
- expect(fakeServer.requests.length).toEqual(2);
-
- var request = fakeServer.requests[1];
- var query = OC.parseQueryString(request.requestBody);
- expect(request.method).toEqual('POST');
- expect(query).toEqual({id: '123'});
- expect(request.url).toEqual(
- OC.webroot + '/index.php/apps/files_sharing/api/externalShares'
- );
-
- expect(plugin.filesApp.fileList.reload.notCalled).toEqual(true);
- request.respond(
- 200,
- {'Content-Type': 'application/json'},
- JSON.stringify({status: 'success'})
- );
- expect(plugin.filesApp.fileList.reload.calledOnce).toEqual(true);
- });
- it('sends delete info to server on cancel', function() {
- processShares([testShare]);
-
- expect(promptDialogStub.notCalled).toEqual(true);
- expect(confirmDialogStub.calledOnce).toEqual(true);
-
- confirmDialogStub.getCall(0).args[2](false);
-
- expect(fakeServer.requests.length).toEqual(2);
-
- var request = fakeServer.requests[1];
- expect(request.method).toEqual('DELETE');
- expect(request.url).toEqual(
- OC.webroot + '/index.php/apps/files_sharing/api/externalShares/123'
- );
-
- expect(plugin.filesApp.fileList.reload.notCalled).toEqual(true);
- request.respond(
- 200,
- {'Content-Type': 'application/json'},
- JSON.stringify({status: 'success'})
- );
- expect(plugin.filesApp.fileList.reload.notCalled).toEqual(true);
- });
- xit('shows another dialog when multiple shares need to be accepted', function() {
- // TODO: enable this test when fixing multiple dialogs issue / confirm loop
- var testShare2 = _.extend({}, testShare);
- testShare2.id = 256;
- processShares([testShare, testShare2]);
-
- // confirm first one
- expect(confirmDialogStub.calledOnce).toEqual(true);
- confirmDialogStub.getCall(0).args[2](true);
-
- // next dialog not shown yet
- expect(confirmDialogStub.calledOnce);
-
- // respond to the first accept request
- fakeServer.requests[1].respond(
- 200,
- {'Content-Type': 'application/json'},
- JSON.stringify({status: 'success'})
- );
-
- // don't reload yet, there are other shares to confirm
- expect(plugin.filesApp.fileList.reload.notCalled).toEqual(true);
-
- // cancel second share
- expect(confirmDialogStub.calledTwice).toEqual(true);
- confirmDialogStub.getCall(1).args[2](true);
-
- // reload only called at the very end
- expect(plugin.filesApp.fileList.reload.calledOnce).toEqual(true);
- });
- });
-});
diff --git a/apps/files_sharing/tests/js/publicAppSpec.js b/apps/files_sharing/tests/js/publicAppSpec.js
deleted file mode 100644
index 58565744882..00000000000
--- a/apps/files_sharing/tests/js/publicAppSpec.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
-* ownCloud
-*
-* @author Vincent Petry
-* @copyright 2015 Vincent Petry <pvince81@owncloud.com>
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library 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 library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-describe('OCA.Sharing.PublicApp tests', function() {
- var App = OCA.Sharing.PublicApp;
- var hostStub, protocolStub, webrootStub;
- var $preview;
-
- beforeEach(function() {
- protocolStub = sinon.stub(OC, 'getProtocol').returns('https');
- hostStub = sinon.stub(OC, 'getHost').returns('example.com:9876');
- webrootStub = sinon.stub(OC, 'getRootPath').returns('/owncloud');
- $preview = $('<div id="preview"></div>');
- $('#testArea').append($preview);
- $preview.append(
- '<div id="mimetype"></div>' +
- '<div id="mimetypeIcon"></div>' +
- '<input type="hidden" id="sharingToken" value="sh4tok"></input>'
- );
- });
-
- afterEach(function() {
- protocolStub.restore();
- hostStub.restore();
- webrootStub.restore();
- });
-
- describe('File list', function() {
- // TODO: this should be moved to a separate file once the PublicFileList is extracted from public.js
- beforeEach(function() {
- $preview.append(
- '<div id="app-content-files">' +
- // init horrible parameters
- '<input type="hidden" id="dir" value="/subdir"/>' +
- '<input type="hidden" id="permissions" value="31"/>' +
- // dummy controls
- '<div id="controls">' +
- ' <div class="actions creatable"></div>' +
- ' <div class="notCreatable"></div>' +
- '</div>' +
- // uploader
- '<input type="file" id="file_upload_start" name="files[]" multiple="multiple">' +
- // dummy table
- // TODO: at some point this will be rendered by the fileList class itself!
- '<table id="filestable">' +
- '<thead><tr>' +
- '<th id="headerName" class="hidden column-name">' +
- '<input type="checkbox" id="select_all_files" class="select-all">' +
- '<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' +
- '<span class="selectedActions hidden">' +
- '<a href class="download">Download</a>' +
- '</th>' +
- '<th class="hidden column-size"><a class="columntitle" data-sort="size"><span class="sort-indicator"></span></a></th>' +
- '<th class="hidden column-mtime"><a class="columntitle" data-sort="mtime"><span class="sort-indicator"></span></a></th>' +
- '</tr></thead>' +
- '<tbody id="fileList"></tbody>' +
- '<tfoot></tfoot>' +
- '</table>' +
- // TODO: move to handlebars template
- '<div id="emptycontent"><h2>Empty content message</h2><p class="uploadmessage">Upload message</p></div>' +
- '<div class="nofilterresults hidden"></div>' +
- '</div>'
- );
-
- App.initialize($('#preview'));
- });
- afterEach(function() {
- App._initialized = false;
- });
-
- it('Uses public webdav endpoint', function() {
- expect(fakeServer.requests.length).toEqual(1);
- expect(fakeServer.requests[0].method).toEqual('PROPFIND');
- expect(fakeServer.requests[0].url).toEqual('https://example.com:9876/owncloud/public.php/webdav/subdir');
- expect(fakeServer.requests[0].requestHeaders.Authorization).toEqual('Basic c2g0dG9rOm51bGw=');
- });
-
- describe('Download Url', function() {
- var fileList;
-
- beforeEach(function() {
- fileList = App.fileList;
- });
-
- it('returns correct download URL for single files', function() {
- expect(fileList.getDownloadUrl('some file.txt'))
- .toEqual(OC.webroot + '/index.php/s/sh4tok/download?path=%2Fsubdir&files=some%20file.txt');
- expect(fileList.getDownloadUrl('some file.txt', '/anotherpath/abc'))
- .toEqual(OC.webroot + '/index.php/s/sh4tok/download?path=%2Fanotherpath%2Fabc&files=some%20file.txt');
- fileList.changeDirectory('/');
- expect(fileList.getDownloadUrl('some file.txt'))
- .toEqual(OC.webroot + '/index.php/s/sh4tok/download?path=%2F&files=some%20file.txt');
- });
- it('returns correct download URL for multiple files', function() {
- expect(fileList.getDownloadUrl(['a b c.txt', 'd e f.txt']))
- .toEqual(OC.webroot + '/index.php/s/sh4tok/download?path=%2Fsubdir&files=%5B%22a%20b%20c.txt%22%2C%22d%20e%20f.txt%22%5D');
- });
- it('returns the correct ajax URL', function() {
- expect(fileList.getAjaxUrl('test', {a:1, b:'x y'}))
- .toEqual(OC.webroot + '/index.php/apps/files_sharing/ajax/test.php?a=1&b=x%20y&t=sh4tok');
- });
- });
- });
-});
diff --git a/apps/files_sharing/tests/js/shareSpec.js b/apps/files_sharing/tests/js/shareSpec.js
deleted file mode 100644
index c34234bfe13..00000000000
--- a/apps/files_sharing/tests/js/shareSpec.js
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-describe('OCA.Sharing.Util tests', function() {
- var fileList;
- var testFiles;
-
- function getImageUrl($el) {
- // might be slightly different cross-browser
- var url = $el.css('background-image');
- var r = url.match(/url\(['"]?([^'")]*)['"]?\)/);
- if (!r) {
- return url;
- }
- return r[1];
- }
-
- beforeEach(function() {
- var $content = $('<div id="content"></div>');
- $('#testArea').append($content);
- // dummy file list
- var $div = $(
- '<div id="listContainer">' +
- '<table id="filestable">' +
- '<thead></thead>' +
- '<tbody id="fileList"></tbody>' +
- '</table>' +
- '</div>');
- $('#content').append($div);
-
- var fileActions = new OCA.Files.FileActions();
- fileList = new OCA.Files.FileList(
- $div, {
- fileActions : fileActions
- }
- );
- OCA.Sharing.Util.attach(fileList);
-
- testFiles = [{
- id: 1,
- type: 'file',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc',
- shareOwner: 'User One',
- isShareMountPoint: false,
- shareTypes: [OC.Share.SHARE_TYPE_USER]
- }];
- });
- afterEach(function() {
- delete OCA.Sharing.sharesLoaded;
- delete OC.Share.droppedDown;
- fileList.destroy();
- fileList = null;
- });
-
- describe('Sharing data in table row', function() {
- // TODO: test data-permissions, data-share-owner, etc
- });
- describe('Share action icon', function() {
- it('do not shows share text when not shared', function() {
- var $action, $tr;
- OC.Share.statuses = {};
- fileList.setFiles([{
- id: 1,
- type: 'dir',
- name: 'One',
- path: '/subdir',
- mimetype: 'httpd/unix-directory',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc',
- shareTypes: []
- }]);
- $tr = fileList.$el.find('tbody tr:first');
- $action = $tr.find('.action-share');
- expect($action.find('.icon').hasClass('icon-share')).toEqual(true);
- expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
- expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder.svg');
- });
- it('shows simple share text with share icon', function() {
- var $action, $tr;
- fileList.setFiles([{
- id: 1,
- type: 'dir',
- name: 'One',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc',
- shareTypes: [OC.Share.SHARE_TYPE_USER]
- }]);
- $tr = fileList.$el.find('tbody tr:first');
- $action = $tr.find('.action-share');
- expect($action.find('>span').text().trim()).toEqual('Shared');
- expect($action.find('.icon').hasClass('icon-share')).toEqual(true);
- expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
- expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder-shared.svg');
- });
- it('shows simple share text with public icon when shared with link', function() {
- var $action, $tr;
- OC.Share.statuses = {1: {link: true, path: '/subdir'}};
- fileList.setFiles([{
- id: 1,
- type: 'dir',
- name: 'One',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc',
- shareTypes: [OC.Share.SHARE_TYPE_LINK]
- }]);
- $tr = fileList.$el.find('tbody tr:first');
- $action = $tr.find('.action-share');
- expect($action.find('>span').text().trim()).toEqual('Shared');
- expect($action.find('.icon').hasClass('icon-share')).toEqual(false);
- expect($action.find('.icon').hasClass('icon-public')).toEqual(true);
- expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder-public.svg');
- });
- it('shows owner name when owner is available', function() {
- var $action, $tr;
- fileList.setFiles([{
- id: 1,
- type: 'dir',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- shareOwner: 'User One',
- etag: 'abc',
- shareTypes: []
- }]);
- $tr = fileList.$el.find('tbody tr:first');
- $action = $tr.find('.action-share');
- expect($action.find('>span').text().trim()).toEqual('User One');
- expect($action.find('.icon').hasClass('icon-share')).toEqual(true);
- expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
- expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder-shared.svg');
- });
- it('shows recipients when recipients are available', function() {
- var $action, $tr;
- fileList.setFiles([{
- id: 1,
- type: 'dir',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- recipientsDisplayName: 'User One, User Two',
- etag: 'abc',
- shareTypes: [OC.Share.SHARE_TYPE_USER]
- }]);
- $tr = fileList.$el.find('tbody tr:first');
- $action = $tr.find('.action-share');
- expect($action.find('>span').text().trim()).toEqual('Shared with User One, User Two');
- expect($action.find('.icon').hasClass('icon-share')).toEqual(true);
- expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
- expect(OC.basename(getImageUrl($tr.find('.filename .thumbnail')))).toEqual('folder-shared.svg');
- });
- it('shows share action when shared with user who has no share permission', function() {
- var $action, $tr;
- fileList.setFiles([{
- id: 1,
- type: 'dir',
- name: 'One',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_CREATE,
- etag: 'abc',
- shareOwner: 'User One'
- }]);
- $tr = fileList.$el.find('tbody tr:first');
- expect($tr.find('.action-share').length).toEqual(1);
- });
- it('do not show share action when share exists but neither permission nor owner is available', function() {
- var $action, $tr;
- fileList.setFiles([{
- id: 1,
- type: 'dir',
- name: 'One',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_CREATE,
- etag: 'abc'
- }]);
- $tr = fileList.$el.find('tbody tr:first');
- expect($tr.find('.action-share').length).toEqual(0);
- });
- });
- describe('Share action', function() {
- var shareTab;
-
- function makeDummyShareItem(displayName) {
- return {
- share_with_displayname: displayName
- };
- }
-
- beforeEach(function() {
- // make it look like not the "All files" list
- fileList.id = 'test';
- shareTab = fileList._detailsView._tabViews[0];
- });
- afterEach(function() {
- shareTab = null;
- });
- it('clicking share action opens sidebar and share tab', function() {
- var showDetailsViewStub = sinon.stub(fileList, 'showDetailsView');
-
- fileList.setFiles([{
- id: 1,
- type: 'file',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc'
- }]);
-
- var $tr = fileList.$el.find('tr:first');
- $tr.find('.action-share').click();
-
- expect(showDetailsViewStub.calledOnce).toEqual(true);
- expect(showDetailsViewStub.getCall(0).args[0]).toEqual('One.txt');
- expect(showDetailsViewStub.getCall(0).args[1]).toEqual('shareTabView');
-
- showDetailsViewStub.restore();
- });
- it('adds share icon after sharing a non-shared file', function() {
- var $action, $tr;
- OC.Share.statuses = {};
- fileList.setFiles([{
- id: 1,
- type: 'file',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc'
- }]);
- $action = fileList.$el.find('tbody tr:first .action-share');
- $tr = fileList.$el.find('tr:first');
-
- $tr.find('.action-share').click();
-
- // simulate updating shares
- shareTab._dialog.model.set({
- shares: [
- {share_with_displayname: 'User One'},
- {share_with_displayname: 'User Two'},
- {share_with_displayname: 'Group One'},
- {share_with_displayname: 'Group Two'}
- ]
- });
-
- expect($tr.attr('data-share-recipients')).toEqual('Group One, Group Two, User One, User Two');
-
- expect($action.find('>span').text().trim()).toEqual('Shared with Group One, Group Two, User One, User Two');
- expect($action.find('.icon').hasClass('icon-share')).toEqual(true);
- expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
- });
- it('updates share icon after updating shares of a file', function() {
- var $action, $tr;
- OC.Share.statuses = {1: {link: false, path: '/subdir'}};
- fileList.setFiles([{
- id: 1,
- type: 'file',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc'
- }]);
- $action = fileList.$el.find('tbody tr:first .action-share');
- $tr = fileList.$el.find('tr:first');
-
- $tr.find('.action-share').click();
-
- // simulate updating shares
- shareTab._dialog.model.set({
- shares: [
- {share_with_displayname: 'User One'},
- {share_with_displayname: 'User Two'},
- {share_with_displayname: 'User Three'}
- ]
- });
-
- expect($tr.attr('data-share-recipients')).toEqual('User One, User Three, User Two');
-
- expect($action.find('>span').text().trim()).toEqual('Shared with User One, User Three, User Two');
- expect($action.find('.icon').hasClass('icon-share')).toEqual(true);
- expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
- });
- it('removes share icon after removing all shares from a file', function() {
- var $action, $tr;
- OC.Share.statuses = {1: {link: false, path: '/subdir'}};
- fileList.setFiles([{
- id: 1,
- type: 'file',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc',
- recipients: 'User One, User Two'
- }]);
- $action = fileList.$el.find('tbody tr:first .action-share');
- $tr = fileList.$el.find('tr:first');
-
- $tr.find('.action-share').click();
-
- // simulate updating shares
- shareTab._dialog.model.set({
- shares: []
- });
-
- expect($tr.attr('data-share-recipients')).not.toBeDefined();
- });
- it('keep share text after updating reshare', function() {
- var $action, $tr;
- OC.Share.statuses = {1: {link: false, path: '/subdir'}};
- fileList.setFiles([{
- id: 1,
- type: 'file',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc',
- shareOwner: 'User One'
- }]);
- $action = fileList.$el.find('tbody tr:first .action-share');
- $tr = fileList.$el.find('tr:first');
-
- $tr.find('.action-share').click();
-
- // simulate updating shares
- shareTab._dialog.model.set({
- shares: [{share_with_displayname: 'User Two'}]
- });
-
- expect($tr.attr('data-share-recipients')).toEqual('User Two');
-
- expect($action.find('>span').text().trim()).toEqual('User One');
- expect($action.find('.icon').hasClass('icon-share')).toEqual(true);
- expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
- });
- it('keep share text after unsharing reshare', function() {
- var $action, $tr;
- OC.Share.statuses = {1: {link: false, path: '/subdir'}};
- fileList.setFiles([{
- id: 1,
- type: 'file',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_ALL,
- etag: 'abc',
- shareOwner: 'User One',
- recipients: 'User Two'
- }]);
- $action = fileList.$el.find('tbody tr:first .action-share');
- $tr = fileList.$el.find('tr:first');
-
- $tr.find('.action-share').click();
-
- // simulate updating shares
- shareTab._dialog.model.set({
- shares: []
- });
-
- expect($tr.attr('data-share-recipients')).not.toBeDefined();
-
- expect($action.find('>span').text().trim()).toEqual('User One');
- expect($action.find('.icon').hasClass('icon-share')).toEqual(true);
- expect($action.find('.icon').hasClass('icon-public')).toEqual(false);
- });
- });
- describe('formatRecipients', function() {
- it('returns a single recipient when one passed', function() {
- expect(OCA.Sharing.Util.formatRecipients(['User one']))
- .toEqual('User one');
- });
- it('returns two recipients when two passed', function() {
- expect(OCA.Sharing.Util.formatRecipients(['User one', 'User two']))
- .toEqual('User one, User two');
- });
- it('returns four recipients with plus when five passed', function() {
- var recipients = [
- 'User one',
- 'User two',
- 'User three',
- 'User four',
- 'User five'
- ];
- expect(OCA.Sharing.Util.formatRecipients(recipients))
- .toEqual('User four, User one, User three, User two, +1');
- });
- it('returns four recipients with plus when ten passed', function() {
- var recipients = [
- 'User one',
- 'User two',
- 'User three',
- 'User four',
- 'User five',
- 'User six',
- 'User seven',
- 'User eight',
- 'User nine',
- 'User ten'
- ];
- expect(OCA.Sharing.Util.formatRecipients(recipients))
- .toEqual('User four, User one, User three, User two, +6');
- });
- it('returns four recipients with plus when four passed with counter', function() {
- var recipients = [
- 'User one',
- 'User two',
- 'User three',
- 'User four'
- ];
- expect(OCA.Sharing.Util.formatRecipients(recipients, 10))
- .toEqual('User four, User one, User three, User two, +6');
- });
- });
- describe('Excluded lists', function() {
- function createListThenAttach(listId) {
- var fileActions = new OCA.Files.FileActions();
- fileList.destroy();
- fileList = new OCA.Files.FileList(
- $('#listContainer'), {
- id: listId,
- fileActions: fileActions
- }
- );
- OCA.Sharing.Util.attach(fileList);
- fileList.setFiles(testFiles);
- return fileList;
- }
-
- it('does not attach to trashbin or public file lists', function() {
- createListThenAttach('trashbin');
- expect($('.action-share').length).toEqual(0);
- expect($('[data-share-recipient]').length).toEqual(0);
- createListThenAttach('files.public');
- expect($('.action-share').length).toEqual(0);
- expect($('[data-share-recipient]').length).toEqual(0);
- });
- });
-
-});
diff --git a/apps/files_sharing/tests/js/sharedfilelistSpec.js b/apps/files_sharing/tests/js/sharedfilelistSpec.js
deleted file mode 100644
index 0b0676a19e6..00000000000
--- a/apps/files_sharing/tests/js/sharedfilelistSpec.js
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
- *
- * This file is licensed under the Affero General Public License version 3
- * or later.
- *
- * See the COPYING-README file.
- *
- */
-
-describe('OCA.Sharing.FileList tests', function() {
- var testFiles, alertStub, notificationStub, fileList;
-
- beforeEach(function() {
- alertStub = sinon.stub(OC.dialogs, 'alert');
- notificationStub = sinon.stub(OC.Notification, 'show');
-
- // init parameters and test table elements
- $('#testArea').append(
- '<div id="app-content-container">' +
- // init horrible parameters
- '<input type="hidden" id="dir" value="/"></input>' +
- '<input type="hidden" id="permissions" value="31"></input>' +
- // dummy controls
- '<div id="controls">' +
- ' <div class="actions creatable"></div>' +
- ' <div class="notCreatable"></div>' +
- '</div>' +
- // dummy table
- // TODO: at some point this will be rendered by the fileList class itself!
- '<table id="filestable">' +
- '<thead><tr>' +
- '<th id="headerName" class="hidden column-name">' +
- '<input type="checkbox" id="select_all_files" class="select-all">' +
- '<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' +
- '<span class="selectedActions hidden">' +
- '</th>' +
- '<th class="hidden column-mtime">' +
- '<a class="columntitle" data-sort="mtime"><span class="sort-indicator"></span></a>' +
- '</th>' +
- '</tr></thead>' +
- '<tbody id="fileList"></tbody>' +
- '<tfoot></tfoot>' +
- '</table>' +
- '<div id="emptycontent">Empty content message</div>' +
- '</div>'
- );
- });
- afterEach(function() {
- testFiles = undefined;
- fileList.destroy();
- fileList = undefined;
-
- notificationStub.restore();
- alertStub.restore();
- });
-
- describe('loading file list for incoming shares', function() {
- var ocsResponse;
- var ocsResponseRemote;
-
- beforeEach(function() {
- fileList = new OCA.Sharing.FileList(
- $('#app-content-container'), {
- sharedWithUser: true
- }
- );
- OCA.Sharing.Util.attach(fileList);
-
- fileList.reload();
-
- /* jshint camelcase: false */
- ocsResponse = {
- ocs: {
- meta: {
- status: 'ok',
- statuscode: 100,
- message: null
- },
- data: [{
- id: 7,
- item_type: 'file',
- item_source: 49,
- item_target: '/49',
- file_source: 49,
- file_target: '/local path/local name.txt',
- path: 'files/something shared.txt',
- permissions: 31,
- stime: 11111,
- share_type: OC.Share.SHARE_TYPE_USER,
- share_with: 'user1',
- share_with_displayname: 'User One',
- mimetype: 'text/plain',
- uid_owner: 'user2',
- displayname_owner: 'User Two'
- }]
- }
- };
-
- /* jshint camelcase: false */
- ocsResponseRemote = {
- ocs: {
- meta: {
- status: 'ok',
- statuscode: 100,
- message: null
- },
- data: [{
- id: 8,
- remote: 'https://foo.bar/',
- remote_id: 42,
- share_token: 'abc',
- name: '/a.txt',
- owner: 'user3',
- user: 'user1',
- mountpoint: '/b.txt',
- mountpoint_hash: 'def',
- accepted: 1,
- mimetype: 'text/plain',
- mtime: 22222,
- permissions: 31,
- type: 'file',
- file_id: 1337
- }]
- }
- };
-
- });
- it('render file shares', function() {
- expect(fakeServer.requests.length).toEqual(2);
- expect(fakeServer.requests[0].url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'shares?format=json&shared_with_me=true'
- );
-
- expect(fakeServer.requests[1].url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'remote_shares?format=json'
- );
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponse)
- );
-
- fakeServer.requests[1].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponseRemote)
- );
-
- var $rows = fileList.$el.find('tbody tr');
- expect($rows.length).toEqual(2);
-
- var $tr = $rows.eq(0);
- expect($tr.attr('data-id')).toEqual('49');
- expect($tr.attr('data-type')).toEqual('file');
- expect($tr.attr('data-file')).toEqual('local name.txt');
- expect($tr.attr('data-path')).toEqual('/local path');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
- expect($tr.attr('data-mime')).toEqual('text/plain');
- expect($tr.attr('data-mtime')).toEqual('11111000');
- expect($tr.attr('data-share-owner')).toEqual('User Two');
- expect($tr.attr('data-share-id')).toEqual('7');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot +
- '/remote.php/webdav/local%20path/local%20name.txt'
- );
- expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
-
- $tr = $rows.eq(1);
- expect($tr.attr('data-id')).toEqual('1337');
- expect($tr.attr('data-type')).toEqual('file');
- expect($tr.attr('data-file')).toEqual('b.txt');
- expect($tr.attr('data-path')).toEqual('');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect(parseInt($tr.attr('data-permissions'), 10))
- .toEqual(OC.PERMISSION_ALL); // read and delete
- expect($tr.attr('data-mime')).toEqual('text/plain');
- expect($tr.attr('data-mtime')).toEqual('22222000');
- expect($tr.attr('data-share-owner')).toEqual('user3@foo.bar/');
- expect($tr.attr('data-share-id')).toEqual('8');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot +
- '/remote.php/webdav/b.txt'
- );
- expect($tr.find('.nametext').text().trim()).toEqual('b.txt');
- });
- it('render folder shares', function() {
- /* jshint camelcase: false */
- ocsResponse.ocs.data[0] = _.extend(ocsResponse.ocs.data[0], {
- item_type: 'folder',
- file_target: '/local path/local name',
- path: 'files/something shared',
- });
-
- ocsResponseRemote.ocs.data[0] = _.extend(ocsResponseRemote.ocs.data[0], {
- type: 'dir',
- mimetype: 'httpd/unix-directory',
- name: '/a',
- mountpoint: '/b'
- });
-
- expect(fakeServer.requests.length).toEqual(2);
- expect(fakeServer.requests[0].url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'shares?format=json&shared_with_me=true'
- );
- expect(fakeServer.requests[1].url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'remote_shares?format=json'
- );
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponse)
- );
- fakeServer.requests[1].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponseRemote)
- );
-
- var $rows = fileList.$el.find('tbody tr');
- expect($rows.length).toEqual(2);
-
- var $tr = $rows.eq(0);
- expect($tr.attr('data-id')).toEqual('49');
- expect($tr.attr('data-type')).toEqual('dir');
- expect($tr.attr('data-file')).toEqual('local name');
- expect($tr.attr('data-path')).toEqual('/local path');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
- expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
- expect($tr.attr('data-mtime')).toEqual('11111000');
- expect($tr.attr('data-share-owner')).toEqual('User Two');
- expect($tr.attr('data-share-id')).toEqual('7');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot +
- '/index.php/apps/files' +
- '?dir=/local%20path/local%20name'
- );
- expect($tr.find('.nametext').text().trim()).toEqual('local name');
-
- $tr = $rows.eq(1);
- expect($tr.attr('data-id')).toEqual('1337');
- expect($tr.attr('data-type')).toEqual('dir');
- expect($tr.attr('data-file')).toEqual('b');
- expect($tr.attr('data-path')).toEqual('');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect(parseInt($tr.attr('data-permissions'), 10))
- .toEqual(OC.PERMISSION_ALL); // read and delete
- expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
- expect($tr.attr('data-mtime')).toEqual('22222000');
- expect($tr.attr('data-share-owner')).toEqual('user3@foo.bar/');
- expect($tr.attr('data-share-id')).toEqual('8');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot +
- '/index.php/apps/files' +
- '?dir=/b'
- );
- expect($tr.find('.nametext').text().trim()).toEqual('b');
-
- });
- });
- describe('loading file list for outgoing shares', function() {
- var ocsResponse;
-
- beforeEach(function() {
- fileList = new OCA.Sharing.FileList(
- $('#app-content-container'), {
- sharedWithUser: false
- }
- );
- OCA.Sharing.Util.attach(fileList);
-
- fileList.reload();
-
- /* jshint camelcase: false */
- ocsResponse = {
- ocs: {
- meta: {
- status: 'ok',
- statuscode: 100,
- message: null
- },
- data: [{
- id: 7,
- item_type: 'file',
- item_source: 49,
- file_source: 49,
- path: '/local path/local name.txt',
- permissions: 27,
- stime: 11111,
- share_type: OC.Share.SHARE_TYPE_USER,
- share_with: 'user2',
- share_with_displayname: 'User Two',
- mimetype: 'text/plain',
- uid_owner: 'user1',
- displayname_owner: 'User One'
- }]
- }
- };
- });
- it('render file shares', function() {
- var request;
-
- expect(fakeServer.requests.length).toEqual(1);
- request = fakeServer.requests[0];
- expect(request.url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'shares?format=json&shared_with_me=false'
- );
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponse)
- );
-
- var $rows = fileList.$el.find('tbody tr');
- var $tr = $rows.eq(0);
- expect($rows.length).toEqual(1);
- expect($tr.attr('data-id')).toEqual('49');
- expect($tr.attr('data-type')).toEqual('file');
- expect($tr.attr('data-file')).toEqual('local name.txt');
- expect($tr.attr('data-path')).toEqual('/local path');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
- expect($tr.attr('data-mime')).toEqual('text/plain');
- expect($tr.attr('data-mtime')).toEqual('11111000');
- expect($tr.attr('data-share-owner')).not.toBeDefined();
- expect($tr.attr('data-share-id')).toEqual('7');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot +
- '/remote.php/webdav/local%20path/local%20name.txt'
- );
- expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
- });
- it('render folder shares', function() {
- var request;
- /* jshint camelcase: false */
- ocsResponse.ocs.data[0] = _.extend(ocsResponse.ocs.data[0], {
- item_type: 'folder',
- path: '/local path/local name',
- });
-
- expect(fakeServer.requests.length).toEqual(1);
- request = fakeServer.requests[0];
- expect(request.url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'shares?format=json&shared_with_me=false'
- );
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponse)
- );
-
- var $rows = fileList.$el.find('tbody tr');
- var $tr = $rows.eq(0);
- expect($rows.length).toEqual(1);
- expect($tr.attr('data-id')).toEqual('49');
- expect($tr.attr('data-type')).toEqual('dir');
- expect($tr.attr('data-file')).toEqual('local name');
- expect($tr.attr('data-path')).toEqual('/local path');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
- expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
- expect($tr.attr('data-mtime')).toEqual('11111000');
- expect($tr.attr('data-share-owner')).not.toBeDefined();
- expect($tr.attr('data-share-id')).toEqual('7');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot +
- '/index.php/apps/files' +
- '?dir=/local%20path/local%20name'
- );
- expect($tr.find('.nametext').text().trim()).toEqual('local name');
- });
- it('render link shares', function() {
- /* jshint camelcase: false */
- var request;
- ocsResponse.ocs.data[0] = {
- id: 7,
- item_type: 'file',
- item_source: 49,
- file_source: 49,
- path: '/local path/local name.txt',
- permissions: 1,
- stime: 11111,
- share_type: OC.Share.SHARE_TYPE_LINK,
- share_with: null,
- token: 'abc',
- mimetype: 'text/plain',
- uid_owner: 'user1',
- displayname_owner: 'User One'
- };
- expect(fakeServer.requests.length).toEqual(1);
- request = fakeServer.requests[0];
- expect(request.url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'shares?format=json&shared_with_me=false'
- );
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponse)
- );
-
- var $rows = fileList.$el.find('tbody tr');
- var $tr = $rows.eq(0);
- expect($rows.length).toEqual(1);
- expect($tr.attr('data-id')).toEqual('49');
- expect($tr.attr('data-type')).toEqual('file');
- expect($tr.attr('data-file')).toEqual('local name.txt');
- expect($tr.attr('data-path')).toEqual('/local path');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
- expect($tr.attr('data-mime')).toEqual('text/plain');
- expect($tr.attr('data-mtime')).toEqual('11111000');
- expect($tr.attr('data-share-owner')).not.toBeDefined();
- expect($tr.attr('data-share-id')).toEqual('7');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot + '/remote.php/webdav/local%20path/local%20name.txt'
- );
-
- expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
- });
- it('groups link shares with regular shares', function() {
- /* jshint camelcase: false */
- var request;
- // link share
- ocsResponse.ocs.data.push({
- id: 8,
- item_type: 'file',
- item_source: 49,
- file_source: 49,
- path: '/local path/local name.txt',
- permissions: 1,
- stime: 11111,
- share_type: OC.Share.SHARE_TYPE_LINK,
- share_with: null,
- token: 'abc',
- mimetype: 'text/plain',
- uid_owner: 'user1',
- displayname_owner: 'User One'
- });
- // another share of the same file
- ocsResponse.ocs.data.push({
- id: 9,
- item_type: 'file',
- item_source: 49,
- file_source: 49,
- path: '/local path/local name.txt',
- permissions: 27,
- stime: 22222,
- share_type: OC.Share.SHARE_TYPE_USER,
- share_with: 'user3',
- share_with_displayname: 'User Three',
- mimetype: 'text/plain',
- uid_owner: 'user1',
- displayname_owner: 'User One'
- });
- expect(fakeServer.requests.length).toEqual(1);
- request = fakeServer.requests[0];
- expect(request.url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'shares?format=json&shared_with_me=false'
- );
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponse)
- );
-
- var $rows = fileList.$el.find('tbody tr');
- var $tr = $rows.eq(0);
- expect($rows.length).toEqual(1);
- expect($tr.attr('data-id')).toEqual('49');
- expect($tr.attr('data-type')).toEqual('file');
- expect($tr.attr('data-file')).toEqual('local name.txt');
- expect($tr.attr('data-path')).toEqual('/local path');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
- expect($tr.attr('data-mime')).toEqual('text/plain');
- // always use the most recent stime
- expect($tr.attr('data-mtime')).toEqual('22222000');
- expect($tr.attr('data-share-owner')).not.toBeDefined();
- expect($tr.attr('data-share-id')).toEqual('7,8,9');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot + '/remote.php/webdav/local%20path/local%20name.txt'
- );
- expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
- });
- });
- describe('loading file list for link shares', function() {
- var ocsResponse;
-
- beforeEach(function() {
- fileList = new OCA.Sharing.FileList(
- $('#app-content-container'), {
- linksOnly: true
- }
- );
- OCA.Sharing.Util.attach(fileList);
-
- fileList.reload();
-
- /* jshint camelcase: false */
- ocsResponse = {
- ocs: {
- meta: {
- status: 'ok',
- statuscode: 100,
- message: null
- },
- data: [{
- id: 7,
- item_type: 'file',
- item_source: 49,
- file_source: 49,
- path: '/local path/local name.txt',
- permissions: 1,
- stime: 11111,
- share_type: OC.Share.SHARE_TYPE_LINK,
- share_with: null,
- token: 'abc',
- mimetype: 'text/plain',
- uid_owner: 'user1',
- displayname_owner: 'User One'
- }]
- }
- };
- });
- it('render only link shares', function() {
- /* jshint camelcase: false */
- var request;
- ocsResponse.ocs.data.push({
- // non-link share
- id: 8,
- item_type: 'file',
- item_source: 49,
- file_source: 49,
- path: '/local path/local name.txt',
- permissions: 27,
- stime: 11111,
- share_type: OC.Share.SHARE_TYPE_USER,
- share_with: 'user2',
- share_with_displayname: 'User Two',
- mimetype: 'text/plain',
- uid_owner: 'user1',
- displayname_owner: 'User One'
- });
- expect(fakeServer.requests.length).toEqual(1);
- request = fakeServer.requests[0];
- expect(request.url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'shares?format=json&shared_with_me=false'
- );
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponse)
- );
-
- // only renders the link share entry
- var $rows = fileList.$el.find('tbody tr');
- var $tr = $rows.eq(0);
- expect($rows.length).toEqual(1);
- expect($tr.attr('data-id')).toEqual('49');
- expect($tr.attr('data-type')).toEqual('file');
- expect($tr.attr('data-file')).toEqual('local name.txt');
- expect($tr.attr('data-path')).toEqual('/local path');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
- expect($tr.attr('data-mime')).toEqual('text/plain');
- expect($tr.attr('data-mtime')).toEqual('11111000');
- expect($tr.attr('data-share-recipients')).not.toBeDefined();
- expect($tr.attr('data-share-owner')).not.toBeDefined();
- expect($tr.attr('data-share-id')).toEqual('7');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot + '/remote.php/webdav/local%20path/local%20name.txt'
- );
-
- expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
- });
- it('does not show virtual token recipient as recipient when password was set', function() {
- /* jshint camelcase: false */
- var request;
- // when a password is set, share_with contains an auth token
- ocsResponse.ocs.data[0].share_with = 'abc01234/01234abc';
- ocsResponse.ocs.data[0].share_with_displayname = 'abc01234/01234abc';
- expect(fakeServer.requests.length).toEqual(1);
- request = fakeServer.requests[0];
- expect(request.url).toEqual(
- OC.linkToOCS('apps/files_sharing/api/v1') +
- 'shares?format=json&shared_with_me=false'
- );
-
- fakeServer.requests[0].respond(
- 200,
- { 'Content-Type': 'application/json' },
- JSON.stringify(ocsResponse)
- );
-
- // only renders the link share entry
- var $rows = fileList.$el.find('tbody tr');
- var $tr = $rows.eq(0);
- expect($rows.length).toEqual(1);
- expect($tr.attr('data-id')).toEqual('49');
- expect($tr.attr('data-type')).toEqual('file');
- expect($tr.attr('data-file')).toEqual('local name.txt');
- expect($tr.attr('data-path')).toEqual('/local path');
- expect($tr.attr('data-size')).not.toBeDefined();
- expect($tr.attr('data-permissions')).toEqual('31'); // read and delete
- expect($tr.attr('data-mime')).toEqual('text/plain');
- expect($tr.attr('data-mtime')).toEqual('11111000');
- expect($tr.attr('data-share-recipients')).not.toBeDefined();
- expect($tr.attr('data-share-owner')).not.toBeDefined();
- expect($tr.attr('data-share-id')).toEqual('7');
- expect($tr.find('a.name').attr('href')).toEqual(
- OC.webroot +
- '/remote.php/webdav/local%20path/local%20name.txt');
-
- expect($tr.find('.nametext').text().trim()).toEqual('local name.txt');
- });
- });
- describe('setting share permissions for files', function () {
- beforeEach(function () {
-
- var $content = $('<div id="content"></div>');
- $('#testArea').append($content);
- // dummy file list
- var $div = $(
- '<div>' +
- '<table id="filestable">' +
- '<thead></thead>' +
- '<tbody id="fileList"></tbody>' +
- '</table>' +
- '</div>');
- $('#content').append($div);
-
- fileList = new OCA.Files.FileList($div);
- OCA.Sharing.Util.attach(fileList);
- });
-
- it('external storage root folder', function () {
- var $tr;
- OC.Share.statuses = {1: {link: false, path: '/subdir'}};
- fileList.setFiles([{
- id: 1,
- type: 'dir',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_READ,
- etag: 'abc',
- shareOwner: 'User One',
- recipients: 'User Two',
- mountType: 'external-root'
- }]);
- $tr = fileList.$el.find('tr:first');
-
- expect(parseInt($tr.attr('data-share-permissions'), 10)).toEqual(OC.PERMISSION_ALL - OC.PERMISSION_SHARE);
- });
-
- it('external storage root folder reshare', function () {
- var $tr;
- OC.Share.statuses = {1: {link: false, path: '/subdir'}};
- fileList.setFiles([{
- id: 1,
- type: 'dir',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_READ + OC.PERMISSION_SHARE,
- etag: 'abc',
- shareOwner: 'User One',
- recipients: 'User Two',
- mountType: 'external-root'
- }]);
- $tr = fileList.$el.find('tr:first');
-
- expect(parseInt($tr.attr('data-share-permissions'), 10)).toEqual(OC.PERMISSION_ALL);
- });
-
- it('external storage root folder file', function () {
- var $tr;
- OC.Share.statuses = {1: {link: false, path: '/subdir'}};
- fileList.setFiles([{
- id: 1,
- type: 'file',
- name: 'One.txt',
- path: '/subdir',
- mimetype: 'text/plain',
- size: 12,
- permissions: OC.PERMISSION_READ,
- etag: 'abc',
- shareOwner: 'User One',
- recipients: 'User Two',
- mountType: 'external-root'
- }]);
- $tr = fileList.$el.find('tr:first');
-
- expect(parseInt($tr.attr('data-share-permissions'), 10))
- .toEqual(OC.PERMISSION_ALL - OC.PERMISSION_SHARE - OC.PERMISSION_DELETE - OC.PERMISSION_CREATE);
- });
- });
-});
diff --git a/apps/files_sharing/tests/middleware/sharingcheckmiddleware.php b/apps/files_sharing/tests/middleware/sharingcheckmiddleware.php
deleted file mode 100644
index e80be772a92..00000000000
--- a/apps/files_sharing/tests/middleware/sharingcheckmiddleware.php
+++ /dev/null
@@ -1,287 +0,0 @@
-<?php
-/**
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Middleware;
-use OCP\AppFramework\Http\NotFoundResponse;
-use OCP\Files\NotFoundException;
-use OCP\AppFramework\Utility\IControllerMethodReflector;
-use OCA\Files_Sharing\Exceptions\S2SException;
-use OCP\AppFramework\Http\JSONResponse;
-
-/**
- * @package OCA\Files_Sharing\Middleware\SharingCheckMiddleware
- */
-class SharingCheckMiddlewareTest extends \Test\TestCase {
-
- /** @var \OCP\IConfig */
- private $config;
- /** @var \OCP\App\IAppManager */
- private $appManager;
- /** @var SharingCheckMiddleware */
- private $sharingCheckMiddleware;
- /** @var \OCP\AppFramework\Controller */
- private $controllerMock;
- /** @var IControllerMethodReflector */
- private $reflector;
-
- protected function setUp() {
- $this->config = $this->getMockBuilder('\OCP\IConfig')
- ->disableOriginalConstructor()->getMock();
- $this->appManager = $this->getMockBuilder('\OCP\App\IAppManager')
- ->disableOriginalConstructor()->getMock();
- $this->controllerMock = $this->getMockBuilder('\OCP\AppFramework\Controller')
- ->disableOriginalConstructor()->getMock();
- $this->reflector = $this->getMockBuilder('\OCP\AppFramework\Utility\IControllerMethodReflector')
- ->disableOriginalConstructor()->getMock();
-
- $this->sharingCheckMiddleware = new SharingCheckMiddleware(
- 'files_sharing',
- $this->config,
- $this->appManager,
- $this->reflector);
- }
-
- public function testIsSharingEnabledWithAppEnabled() {
- $this->appManager
- ->expects($this->once())
- ->method('isEnabledForUser')
- ->with('files_sharing')
- ->will($this->returnValue(true));
-
- $this->assertTrue(self::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled'));
- }
-
- public function testIsSharingEnabledWithAppDisabled() {
- $this->appManager
- ->expects($this->once())
- ->method('isEnabledForUser')
- ->with('files_sharing')
- ->will($this->returnValue(false));
-
- $this->assertFalse(self::invokePrivate($this->sharingCheckMiddleware, 'isSharingEnabled'));
- }
-
- public function testIsLinkSharingEnabledWithEverythinEnabled() {
- $this->config
- ->expects($this->at(0))
- ->method('getAppValue')
- ->with('core', 'shareapi_enabled', 'yes')
- ->will($this->returnValue('yes'));
-
- $this->config
- ->expects($this->at(1))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_links', 'yes')
- ->will($this->returnValue('yes'));
-
- $this->assertTrue(self::invokePrivate($this->sharingCheckMiddleware, 'isLinkSharingEnabled'));
- }
-
-
- public function testIsLinkSharingEnabledWithLinkSharingDisabled() {
- $this->config
- ->expects($this->at(0))
- ->method('getAppValue')
- ->with('core', 'shareapi_enabled', 'yes')
- ->will($this->returnValue('yes'));
-
- $this->config
- ->expects($this->at(1))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_links', 'yes')
- ->will($this->returnValue('no'));
-
- $this->assertFalse(self::invokePrivate($this->sharingCheckMiddleware, 'isLinkSharingEnabled'));
- }
-
- public function testIsLinkSharingEnabledWithSharingAPIDisabled() {
- $this->config
- ->expects($this->once())
- ->method('getAppValue')
- ->with('core', 'shareapi_enabled', 'yes')
- ->will($this->returnValue('no'));
-
- $this->assertFalse(self::invokePrivate($this->sharingCheckMiddleware, 'isLinkSharingEnabled'));
- }
-
- public function externalSharesChecksDataProvider() {
-
- $data = [];
-
- foreach ([false, true] as $annIn) {
- foreach ([false, true] as $annOut) {
- foreach ([false, true] as $confIn) {
- foreach ([false, true] as $confOut) {
-
- $res = true;
- if (!$annIn && !$confIn) {
- $res = false;
- } elseif (!$annOut && !$confOut) {
- $res = false;
- }
-
- $d = [
- [
- ['NoIncomingFederatedSharingRequired', $annIn],
- ['NoOutgoingFederatedSharingRequired', $annOut],
- ],
- [
- ['files_sharing', 'incoming_server2server_share_enabled', 'yes', $confIn ? 'yes' : 'no'],
- ['files_sharing', 'outgoing_server2server_share_enabled', 'yes', $confOut ? 'yes' : 'no'],
- ],
- $res
- ];
-
- $data[] = $d;
- }
- }
- }
- }
-
- return $data;
- }
-
- /**
- * @dataProvider externalSharesChecksDataProvider
- */
- public function testExternalSharesChecks($annotations, $config, $expectedResult) {
- $this->reflector
- ->expects($this->atLeastOnce())
- ->method('hasAnnotation')
- ->will($this->returnValueMap($annotations));
-
- $this->config
- ->method('getAppValue')
- ->will($this->returnValueMap($config));
-
- $this->assertEquals($expectedResult, self::invokePrivate($this->sharingCheckMiddleware, 'externalSharesChecks'));
- }
-
- /**
- * @dataProvider externalSharesChecksDataProvider
- */
- public function testBeforeControllerWithExternalShareControllerWithSharingEnabled($annotations, $config, $noException) {
- $this->appManager
- ->expects($this->once())
- ->method('isEnabledForUser')
- ->with('files_sharing')
- ->will($this->returnValue(true));
-
- $this->reflector
- ->expects($this->atLeastOnce())
- ->method('hasAnnotation')
- ->will($this->returnValueMap($annotations));
-
- $this->config
- ->method('getAppValue')
- ->will($this->returnValueMap($config));
-
- $controller = $this->getMockBuilder('\OCA\Files_Sharing\Controllers\ExternalSharesController')
- ->disableOriginalConstructor()->getMock();
-
- $exceptionThrown = false;
-
- try {
- $this->sharingCheckMiddleware->beforeController($controller, 'myMethod');
- } catch (\OCA\Files_Sharing\Exceptions\S2SException $exception) {
- $exceptionThrown = true;
- }
-
- $this->assertNotEquals($noException, $exceptionThrown);
- }
-
- public function testBeforeControllerWithShareControllerWithSharingEnabled() {
- $this->appManager
- ->expects($this->once())
- ->method('isEnabledForUser')
- ->with('files_sharing')
- ->will($this->returnValue(true));
-
- $this->config
- ->expects($this->at(0))
- ->method('getAppValue')
- ->with('core', 'shareapi_enabled', 'yes')
- ->will($this->returnValue('yes'));
-
- $this->config
- ->expects($this->at(1))
- ->method('getAppValue')
- ->with('core', 'shareapi_allow_links', 'yes')
- ->will($this->returnValue('yes'));
-
- $controller = $this->getMockBuilder('\OCA\Files_Sharing\Controllers\ShareController')
- ->disableOriginalConstructor()->getMock();
-
- $this->sharingCheckMiddleware->beforeController($controller, 'myMethod');
- }
-
- /**
- * @expectedException \OCP\Files\NotFoundException
- * @expectedExceptionMessage Link sharing is disabled
- */
- public function testBeforeControllerWithShareControllerWithSharingEnabledAPIDisabled() {
- $this->appManager
- ->expects($this->once())
- ->method('isEnabledForUser')
- ->with('files_sharing')
- ->will($this->returnValue(true));
-
- $controller = $this->getMockBuilder('\OCA\Files_Sharing\Controllers\ShareController')
- ->disableOriginalConstructor()->getMock();
-
- $this->sharingCheckMiddleware->beforeController($controller, 'myMethod');
- }
-
- /**
- * @expectedException \OCP\Files\NotFoundException
- * @expectedExceptionMessage Sharing is disabled.
- */
- public function testBeforeControllerWithSharingDisabled() {
- $this->appManager
- ->expects($this->once())
- ->method('isEnabledForUser')
- ->with('files_sharing')
- ->will($this->returnValue(false));
-
- $this->sharingCheckMiddleware->beforeController($this->controllerMock, 'myMethod');
- }
-
- /**
- * @expectedException \Exception
- * @expectedExceptionMessage My Exception message
- */
- public function testAfterExceptionWithRegularException() {
- $this->sharingCheckMiddleware->afterException($this->controllerMock, 'myMethod', new \Exception('My Exception message'));
- }
-
- public function testAfterExceptionWithNotFoundException() {
- $this->assertEquals(new NotFoundResponse(), $this->sharingCheckMiddleware->afterException($this->controllerMock, 'myMethod', new NotFoundException('My Exception message')));
- }
-
- public function testAfterExceptionWithS2SException() {
- $this->assertEquals(new JSONResponse('My Exception message', 405), $this->sharingCheckMiddleware->afterException($this->controllerMock, 'myMethod', new S2SException('My Exception message')));
- }
-
-
-}
diff --git a/apps/files_sharing/tests/migrationtest.php b/apps/files_sharing/tests/migrationtest.php
deleted file mode 100644
index 82e6f47addb..00000000000
--- a/apps/files_sharing/tests/migrationtest.php
+++ /dev/null
@@ -1,351 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-
-use OCA\Files_Sharing\Tests\TestCase;
-use OCA\Files_Sharing\Migration;
-
-/**
- * Class MigrationTest
- *
- * @group DB
- */
-class MigrationTest extends TestCase {
-
- /** @var \OCP\IDBConnection */
- private $connection;
-
- /** @var Migration */
- private $migration;
-
- private $table = 'share';
-
- public function setUp() {
- parent::setUp();
-
- $this->connection = \OC::$server->getDatabaseConnection();
- $this->migration = new Migration($this->connection);
-
- $this->cleanDB();
- }
-
- public function tearDown() {
- parent::tearDown();
- $this->cleanDB();
- }
-
- private function cleanDB() {
- $query = $this->connection->getQueryBuilder();
- $query->delete($this->table)->execute();
- }
-
- public function addDummyValues() {
- $query = $this->connection->getQueryBuilder();
- $query->insert($this->table)
- ->values(
- array(
- 'share_type' => $query->createParameter('share_type'),
- 'share_with' => $query->createParameter('share_with'),
- 'uid_owner' => $query->createParameter('uid_owner'),
- 'uid_initiator' => $query->createParameter('uid_initiator'),
- 'parent' => $query->createParameter('parent'),
- 'item_type' => $query->createParameter('item_type'),
- 'item_source' => $query->createParameter('item_source'),
- 'item_target' => $query->createParameter('item_target'),
- 'file_source' => $query->createParameter('file_source'),
- 'file_target' => $query->createParameter('file_target'),
- 'permissions' => $query->createParameter('permissions'),
- 'stime' => $query->createParameter('stime'),
- )
- );
- // shared contact, shouldn't be modified
- $query->setParameter('share_type', \OCP\Share::SHARE_TYPE_CONTACT)
- ->setParameter('share_with', 'user1')
- ->setParameter('uid_owner', 'owner1')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', null)
- ->setParameter('item_type', 'contact')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', null)
- ->setParameter('file_target', null)
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
- // shared calendar, shouldn't be modified
- $query->setParameter('share_type', \OCP\Share::SHARE_TYPE_USER)
- ->setParameter('share_with', 'user1')
- ->setParameter('uid_owner', 'owner1')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', null)
- ->setParameter('item_type', 'calendar')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', null)
- ->setParameter('file_target', null)
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
- // single user share, shouldn't be modified
- $query->setParameter('share_type', \OCP\Share::SHARE_TYPE_USER)
- ->setParameter('share_with', 'user1')
- ->setParameter('uid_owner', 'owner1')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', null)
- ->setParameter('item_type', 'file')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', 2)
- ->setParameter('file_target', '/foo')
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
- // single group share, shouldn't be modified
- $query->setParameter('share_type', \OCP\Share::SHARE_TYPE_GROUP)
- ->setParameter('share_with', 'group1')
- ->setParameter('uid_owner', 'owner1')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', null)
- ->setParameter('item_type', 'file')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', 2)
- ->setParameter('file_target', '/foo')
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
- $parent = $query->getLastInsertId();
- // unique target for group share, shouldn't be modified
- $query->setParameter('share_type', 2)
- ->setParameter('share_with', 'group1')
- ->setParameter('uid_owner', 'owner1')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', $parent)
- ->setParameter('item_type', 'file')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', 2)
- ->setParameter('file_target', '/foo renamed')
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
- // first user share, shouldn't be modified
- $query->setParameter('share_type', \OCP\Share::SHARE_TYPE_USER)
- ->setParameter('share_with', 'user1')
- ->setParameter('uid_owner', 'owner2')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', null)
- ->setParameter('item_type', 'file')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', 2)
- ->setParameter('file_target', '/foobar')
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
- $parent = $query->getLastInsertId();
- // first re-share, should be attached to the first user share after migration
- $query->setParameter('share_type', \OCP\Share::SHARE_TYPE_USER)
- ->setParameter('share_with', 'user2')
- ->setParameter('uid_owner', 'user1')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', $parent)
- ->setParameter('item_type', 'file')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', 2)
- ->setParameter('file_target', '/foobar')
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
- $parent = $query->getLastInsertId();
- // second re-share, should be attached to the first user share after migration
- $query->setParameter('share_type', \OCP\Share::SHARE_TYPE_USER)
- ->setParameter('share_with', 'user3')
- ->setParameter('uid_owner', 'user2')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', $parent)
- ->setParameter('item_type', 'file')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', 2)
- ->setParameter('file_target', '/foobar')
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
- $parent = $query->getLastInsertId();
- // third re-share, should be attached to the first user share after migration
- $query->setParameter('share_type', \OCP\Share::SHARE_TYPE_REMOTE)
- ->setParameter('share_with', 'user@server.com')
- ->setParameter('uid_owner', 'user3')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', $parent)
- ->setParameter('item_type', 'file')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', 2)
- ->setParameter('file_target', '/foobar')
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
-
- // Link reshare should keep its parent
- $query->setParameter('share_type', \OCP\Share::SHARE_TYPE_LINK)
- ->setParameter('share_with', null)
- ->setParameter('uid_owner', 'user3')
- ->setParameter('uid_initiator', '')
- ->setParameter('parent', $parent)
- ->setParameter('item_type', 'file')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', 2)
- ->setParameter('file_target', '/foobar')
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
- $this->assertSame(1,
- $query->execute()
- );
- }
-
- public function testRemoveReShares() {
- $this->addDummyValues();
- $this->migration->removeReShares();
- $this->verifyResult();
- }
-
- public function verifyResult() {
- $query = $this->connection->getQueryBuilder();
- $query->select('*')->from($this->table)->orderBy('id');
- $result = $query->execute()->fetchAll();
- $this->assertSame(10, count($result));
-
- // shares which shouldn't be modified
- for ($i = 0; $i < 4; $i++) {
- $this->assertSame('owner1', $result[$i]['uid_owner']);
- $this->assertEmpty($result[$i]['uid_initiator']);
- $this->assertNull($result[$i]['parent']);
- }
- // group share with unique target
- $this->assertSame('owner1', $result[4]['uid_owner']);
- $this->assertEmpty($result[4]['uid_initiator']);
- $this->assertNotEmpty($result[4]['parent']);
- // initial user share which was re-shared
- $this->assertSame('owner2', $result[5]['uid_owner']);
- $this->assertEmpty($result[5]['uid_initiator']);
- $this->assertNull($result[5]['parent']);
- // flatted re-shares
- for($i = 6; $i < 9; $i++) {
- $this->assertSame('owner2', $result[$i]['uid_owner']);
- $user = 'user' . ($i - 5);
- $this->assertSame($user, $result[$i]['uid_initiator']);
- $this->assertNull($result[$i]['parent']);
- }
-
- /*
- * The link share is flattend but has an owner to avoid invisible shares
- * see: https://github.com/owncloud/core/pull/22317
- */
- $this->assertSame('owner2', $result[9]['uid_owner']);
- $this->assertSame('user3', $result[9]['uid_initiator']);
- $this->assertSame($result[7]['id'], $result[9]['parent']);
- }
-
- public function test1001DeepReshares() {
- $parent = null;
- for ($i = 0; $i < 1001; $i++) {
- $query = $this->connection->getQueryBuilder();
- $query->insert($this->table)
- ->values(
- [
- 'share_type' => $query->createParameter('share_type'),
- 'share_with' => $query->createParameter('share_with'),
- 'uid_owner' => $query->createParameter('uid_owner'),
- 'uid_initiator' => $query->createParameter('uid_initiator'),
- 'parent' => $query->createParameter('parent'),
- 'item_type' => $query->createParameter('item_type'),
- 'item_source' => $query->createParameter('item_source'),
- 'item_target' => $query->createParameter('item_target'),
- 'file_source' => $query->createParameter('file_source'),
- 'file_target' => $query->createParameter('file_target'),
- 'permissions' => $query->createParameter('permissions'),
- 'stime' => $query->createParameter('stime'),
- ]
- )
- ->setParameter('share_type', \OCP\Share::SHARE_TYPE_USER)
- ->setParameter('share_with', 'user'.($i+1))
- ->setParameter('uid_owner', 'user'.($i))
- ->setParameter('uid_initiator', null)
- ->setParameter('parent', $parent)
- ->setParameter('item_type', 'file')
- ->setParameter('item_source', '2')
- ->setParameter('item_target', '/2')
- ->setParameter('file_source', 2)
- ->setParameter('file_target', '/foobar')
- ->setParameter('permissions', 31)
- ->setParameter('stime', time());
-
- $this->assertSame(1, $query->execute());
- $parent = $query->getLastInsertId();
- }
-
- $this->migration->removeReShares();
- $this->migration->updateInitiatorInfo();
-
- $qb = $this->connection->getQueryBuilder();
-
- $stmt = $qb->select('id', 'share_with', 'uid_owner', 'uid_initiator', 'parent')
- ->from('share')
- ->orderBy('id', 'asc')
- ->execute();
-
- $i = 0;
- while($share = $stmt->fetch()) {
- $this->assertEquals('user'.($i+1), $share['share_with']);
- $this->assertEquals('user' . ($i), $share['uid_initiator']);
- $this->assertEquals('user0', $share['uid_owner']);
- $this->assertEquals(null, $share['parent']);
- $i++;
- }
- $stmt->closeCursor();
- $this->assertEquals(1001, $i);
- }
-}
diff --git a/apps/files_sharing/tests/permissions.php b/apps/files_sharing/tests/permissions.php
deleted file mode 100644
index 43a57266851..00000000000
--- a/apps/files_sharing/tests/permissions.php
+++ /dev/null
@@ -1,161 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-use OC\Files\Cache\Cache;
-use OC\Files\Storage\Storage;
-use OC\Files\View;
-
-/**
- * Class Test_Files_Sharing_Permissions
- *
- * @group DB
- */
-class Test_Files_Sharing_Permissions extends OCA\Files_sharing\Tests\TestCase {
-
- /**
- * @var Storage
- */
- private $sharedStorageRestrictedShare;
-
- /**
- * @var Storage
- */
- private $sharedCacheRestrictedShare;
-
- /**
- * @var View
- */
- private $secondView;
-
- /**
- * @var Storage
- */
- private $ownerStorage;
-
- /**
- * @var Storage
- */
- private $sharedStorage;
-
- /**
- * @var Cache
- */
- private $sharedCache;
-
- /**
- * @var Cache
- */
- private $ownerCache;
-
- protected function setUp() {
- parent::setUp();
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- // prepare user1's dir structure
- $textData = "dummy file data\n";
- $this->view->mkdir('container');
- $this->view->mkdir('container/shareddir');
- $this->view->mkdir('container/shareddir/subdir');
- $this->view->mkdir('container/shareddirrestricted');
- $this->view->mkdir('container/shareddirrestricted/subdir');
- $this->view->file_put_contents('container/shareddir/textfile.txt', $textData);
- $this->view->file_put_contents('container/shareddirrestricted/textfile1.txt', $textData);
-
- list($this->ownerStorage, $internalPath) = $this->view->resolvePath('');
- $this->ownerCache = $this->ownerStorage->getCache();
- $this->ownerStorage->getScanner()->scan('');
-
- // share "shareddir" with user2
- $fileinfo = $this->view->getFileInfo('container/shareddir');
- \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
- $fileinfo2 = $this->view->getFileInfo('container/shareddirrestricted');
- \OCP\Share::shareItem('folder', $fileinfo2['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 7);
-
- // login as user2
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- // retrieve the shared storage
- $this->secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2);
- list($this->sharedStorage, $internalPath) = $this->secondView->resolvePath('files/shareddir');
- list($this->sharedStorageRestrictedShare, $internalPath) = $this->secondView->resolvePath('files/shareddirrestricted');
- $this->sharedCache = $this->sharedStorage->getCache();
- $this->sharedCacheRestrictedShare = $this->sharedStorageRestrictedShare->getCache();
- }
-
- protected function tearDown() {
- if ($this->sharedCache) {
- $this->sharedCache->clear();
- }
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- $fileinfo = $this->view->getFileInfo('container/shareddir');
- \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
- $fileinfo2 = $this->view->getFileInfo('container/shareddirrestricted');
- \OCP\Share::unshare('folder', $fileinfo2['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
-
- $this->view->deleteAll('container');
-
- $this->ownerCache->clear();
-
- parent::tearDown();
- }
-
- /**
- * Test that the permissions of shared directory are returned correctly
- */
- function testGetPermissions() {
- $sharedDirPerms = $this->sharedStorage->getPermissions('shareddir');
- $this->assertEquals(31, $sharedDirPerms);
- $sharedDirPerms = $this->sharedStorage->getPermissions('shareddir/textfile.txt');
- $this->assertEquals(31, $sharedDirPerms);
- $sharedDirRestrictedPerms = $this->sharedStorageRestrictedShare->getPermissions('shareddirrestricted');
- $this->assertEquals(7, $sharedDirRestrictedPerms);
- $sharedDirRestrictedPerms = $this->sharedStorageRestrictedShare->getPermissions('shareddirrestricted/textfile.txt');
- $this->assertEquals(7, $sharedDirRestrictedPerms);
- }
-
- /**
- * Test that the permissions of shared directory are returned correctly
- */
- function testGetDirectoryPermissions() {
- $contents = $this->secondView->getDirectoryContent('files/shareddir');
- $this->assertEquals('subdir', $contents[0]['name']);
- $this->assertEquals(31, $contents[0]['permissions']);
- $this->assertEquals('textfile.txt', $contents[1]['name']);
- // 27 is correct because create is reserved to folders only - requires more unit tests overall to ensure this
- $this->assertEquals(27, $contents[1]['permissions']);
- $contents = $this->secondView->getDirectoryContent('files/shareddirrestricted');
- $this->assertEquals('subdir', $contents[0]['name']);
- $this->assertEquals(7, $contents[0]['permissions']);
- $this->assertEquals('textfile1.txt', $contents[1]['name']);
- // 3 is correct because create is reserved to folders only
- $this->assertEquals(3, $contents[1]['permissions']);
- }
-}
diff --git a/apps/files_sharing/tests/server2server.php b/apps/files_sharing/tests/server2server.php
deleted file mode 100644
index 7714f274c6d..00000000000
--- a/apps/files_sharing/tests/server2server.php
+++ /dev/null
@@ -1,254 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-use OCA\Files_Sharing\Tests\TestCase;
-
-/**
- * Class Test_Files_Sharing_Api
- *
- * @group DB
- */
-class Test_Files_Sharing_S2S_OCS_API extends TestCase {
-
- const TEST_FOLDER_NAME = '/folder_share_api_test';
-
- /**
- * @var \OCP\IDBConnection
- */
- private $connection;
-
- /**
- * @var \OCA\Files_Sharing\API\Server2Server
- */
- private $s2s;
-
- protected function setUp() {
- parent::setUp();
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- \OCP\Share::registerBackend('test', 'Test_Share_Backend');
-
- $config = $this->getMockBuilder('\OCP\IConfig')
- ->disableOriginalConstructor()->getMock();
- $clientService = $this->getMock('\OCP\Http\Client\IClientService');
- $httpHelperMock = $this->getMockBuilder('\OC\HTTPHelper')
- ->setConstructorArgs([$config, $clientService])
- ->getMock();
- $httpHelperMock->expects($this->any())->method('post')->with($this->anything())->will($this->returnValue(true));
-
- $this->registerHttpHelper($httpHelperMock);
-
- $this->s2s = new \OCA\Files_Sharing\API\Server2Server();
-
- $this->connection = \OC::$server->getDatabaseConnection();
- }
-
- protected function tearDown() {
- $query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share_external`');
- $query->execute();
-
- $this->restoreHttpHelper();
-
- parent::tearDown();
- }
-
- /**
- * Register an http helper mock for testing purposes.
- * @param $httpHelper http helper mock
- */
- private function registerHttpHelper($httpHelper) {
- $this->oldHttpHelper = \OC::$server->query('HTTPHelper');
- \OC::$server->registerService('HTTPHelper', function ($c) use ($httpHelper) {
- return $httpHelper;
- });
- }
-
- /**
- * Restore the original http helper
- */
- private function restoreHttpHelper() {
- $oldHttpHelper = $this->oldHttpHelper;
- \OC::$server->registerService('HTTPHelper', function ($c) use ($oldHttpHelper) {
- return $oldHttpHelper;
- });
- }
-
- /**
- * @medium
- */
- function testCreateShare() {
- // simulate a post request
- $_POST['remote'] = 'localhost';
- $_POST['token'] = 'token';
- $_POST['name'] = 'name';
- $_POST['owner'] = 'owner';
- $_POST['shareWith'] = self::TEST_FILES_SHARING_API_USER2;
- $_POST['remoteId'] = 1;
-
- $result = $this->s2s->createShare(null);
-
- $this->assertTrue($result->succeeded());
-
- $query = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share_external` WHERE `remote_id` = ?');
- $result = $query->execute(array('1'));
- $data = $result->fetchRow();
-
- $this->assertSame('localhost', $data['remote']);
- $this->assertSame('token', $data['share_token']);
- $this->assertSame('/name', $data['name']);
- $this->assertSame('owner', $data['owner']);
- $this->assertSame(self::TEST_FILES_SHARING_API_USER2, $data['user']);
- $this->assertSame(1, (int)$data['remote_id']);
- $this->assertSame(0, (int)$data['accepted']);
- }
-
-
- function testDeclineShare() {
- $dummy = \OCP\DB::prepare('
- INSERT INTO `*PREFIX*share`
- (`share_type`, `uid_owner`, `item_type`, `item_source`, `item_target`, `file_source`, `file_target`, `permissions`, `stime`, `token`, `share_with`)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- ');
- $dummy->execute(array(\OCP\Share::SHARE_TYPE_REMOTE, self::TEST_FILES_SHARING_API_USER1, 'test', '1', '/1', '1', '/test.txt', '1', time(), 'token', 'foo@bar'));
-
- $verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
- $result = $verify->execute();
- $data = $result->fetchAll();
- $this->assertSame(1, count($data));
-
- $_POST['token'] = 'token';
- $this->s2s->declineShare(array('id' => $data[0]['id']));
-
- $verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
- $result = $verify->execute();
- $data = $result->fetchAll();
- $this->assertEmpty($data);
- }
-
- function testDeclineShareMultiple() {
- $dummy = \OCP\DB::prepare('
- INSERT INTO `*PREFIX*share`
- (`share_type`, `uid_owner`, `item_type`, `item_source`, `item_target`, `file_source`, `file_target`, `permissions`, `stime`, `token`, `share_with`)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- ');
- $dummy->execute(array(\OCP\Share::SHARE_TYPE_REMOTE, self::TEST_FILES_SHARING_API_USER1, 'test', '1', '/1', '1', '/test.txt', '1', time(), 'token1', 'foo@bar'));
- $dummy->execute(array(\OCP\Share::SHARE_TYPE_REMOTE, self::TEST_FILES_SHARING_API_USER1, 'test', '1', '/1', '1', '/test.txt', '1', time(), 'token2', 'bar@bar'));
-
- $verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
- $result = $verify->execute();
- $data = $result->fetchAll();
- $this->assertCount(2, $data);
-
- $_POST['token'] = 'token1';
- $this->s2s->declineShare(array('id' => $data[0]['id']));
-
- $verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
- $result = $verify->execute();
- $data = $result->fetchAll();
- $this->assertCount(1, $data);
- $this->assertEquals('bar@bar', $data[0]['share_with']);
-
- $_POST['token'] = 'token2';
- $this->s2s->declineShare(array('id' => $data[0]['id']));
-
- $verify = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
- $result = $verify->execute();
- $data = $result->fetchAll();
- $this->assertEmpty($data);
- }
-
- /**
- * @dataProvider dataTestDeleteUser
- */
- function testDeleteUser($toDelete, $expected, $remainingUsers) {
- $this->createDummyS2SShares();
-
- $discoveryManager = new \OCA\FederatedFileSharing\DiscoveryManager(
- \OC::$server->getMemCacheFactory(),
- \OC::$server->getHTTPClientService()
- );
- $manager = new OCA\Files_Sharing\External\Manager(
- \OC::$server->getDatabaseConnection(),
- \OC\Files\Filesystem::getMountManager(),
- \OC\Files\Filesystem::getLoader(),
- \OC::$server->getHTTPHelper(),
- \OC::$server->getNotificationManager(),
- $discoveryManager,
- $toDelete
- );
-
- $manager->removeUserShares($toDelete);
-
- $query = $this->connection->prepare('SELECT `user` FROM `*PREFIX*share_external`');
- $query->execute();
- $result = $query->fetchAll();
-
- foreach ($result as $r) {
- $remainingShares[$r['user']] = isset($remainingShares[$r['user']]) ? $remainingShares[$r['user']] + 1 : 1;
- }
-
- $this->assertSame($remainingUsers, count($remainingShares));
-
- foreach ($expected as $key => $value) {
- if ($key === $toDelete) {
- $this->assertArrayNotHasKey($key, $remainingShares);
- } else {
- $this->assertSame($value, $remainingShares[$key]);
- }
- }
-
- }
-
- function dataTestDeleteUser() {
- return array(
- array('user1', array('user1' => 0, 'user2' => 3, 'user3' => 3), 2),
- array('user2', array('user1' => 4, 'user2' => 0, 'user3' => 3), 2),
- array('user3', array('user1' => 4, 'user2' => 3, 'user3' => 0), 2),
- array('user4', array('user1' => 4, 'user2' => 3, 'user3' => 3), 3),
- );
- }
-
- private function createDummyS2SShares() {
- $query = $this->connection->prepare('
- INSERT INTO `*PREFIX*share_external`
- (`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`, `remote_id`, `accepted`)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- ');
-
- $users = array('user1', 'user2', 'user3');
-
- for ($i = 0; $i < 10; $i++) {
- $user = $users[$i%3];
- $query->execute(array('remote', 'token', 'password', 'name', 'owner', $user, 'mount point', $i, $i, 0));
- }
-
- $query = $this->connection->prepare('SELECT `id` FROM `*PREFIX*share_external`');
- $query->execute();
- $dummyEntries = $query->fetchAll();
-
- $this->assertSame(10, count($dummyEntries));
- }
-
-}
diff --git a/apps/files_sharing/tests/share.php b/apps/files_sharing/tests/share.php
deleted file mode 100644
index aad698bcdba..00000000000
--- a/apps/files_sharing/tests/share.php
+++ /dev/null
@@ -1,478 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-use OCA\Files\Share;
-
-/**
- * Class Test_Files_Sharing
- *
- * @group DB
- */
-class Test_Files_Sharing extends OCA\Files_sharing\Tests\TestCase {
-
- const TEST_FOLDER_NAME = '/folder_share_api_test';
-
- private static $tempStorage;
-
- protected function setUp() {
- parent::setUp();
-
- $this->folder = self::TEST_FOLDER_NAME;
- $this->subfolder = '/subfolder_share_api_test';
- $this->subsubfolder = '/subsubfolder_share_api_test';
-
- $this->filename = '/share-api-test.txt';
-
- // save file with content
- $this->view->file_put_contents($this->filename, $this->data);
- $this->view->mkdir($this->folder);
- $this->view->mkdir($this->folder . $this->subfolder);
- $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder);
- $this->view->file_put_contents($this->folder.$this->filename, $this->data);
- $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data);
- }
-
- protected function tearDown() {
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->view->unlink($this->filename);
- $this->view->deleteAll($this->folder);
-
- self::$tempStorage = null;
-
- // clear database table
- $query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share`');
- $query->execute();
-
- parent::tearDown();
- }
-
- public function testUnshareFromSelf() {
-
- \OC_Group::createGroup('testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup');
-
- $fileinfo = $this->view->getFileInfo($this->filename);
-
- $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing::TEST_FILES_SHARING_API_USER2, 31);
-
- $this->assertTrue($result);
-
- $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP,
- 'testGroup', 31);
-
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- \OC\Files\Filesystem::unlink($this->filename);
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- // both group share and user share should be gone
- $this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename));
-
- // for user3 nothing should change
- self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
- }
-
- /**
- * if a file was shared as group share and as individual share they should be grouped
- */
- public function testGroupingOfShares() {
-
- $fileinfo = $this->view->getFileInfo($this->filename);
-
- $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP,
- \Test_Files_Sharing::TEST_FILES_SHARING_API_GROUP1, \OCP\Constants::PERMISSION_READ);
-
- $this->assertTrue($result);
-
- $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_UPDATE);
-
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $result = \OCP\Share::getItemSharedWith('file', null);
-
- $this->assertTrue(is_array($result));
-
- // test should return exactly one shares created from testCreateShare()
- $this->assertSame(1, count($result));
-
- $share = reset($result);
- $this->assertSame(\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE, $share['permissions']);
-
- \OC\Files\Filesystem::rename($this->filename, $this->filename . '-renamed');
-
- $result = \OCP\Share::getItemSharedWith('file', null);
-
- $this->assertTrue(is_array($result));
-
- // test should return exactly one shares created from testCreateShare()
- $this->assertSame(1, count($result));
-
- $share = reset($result);
- $this->assertSame(\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE, $share['permissions']);
- $this->assertSame($this->filename . '-renamed', $share['file_target']);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- // unshare user share
- $result = \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $result = \OCP\Share::getItemSharedWith('file', null);
-
- $this->assertTrue(is_array($result));
-
- // test should return the remaining group share
- $this->assertSame(1, count($result));
-
- $share = reset($result);
- // only the group share permissions should be available now
- $this->assertSame(\OCP\Constants::PERMISSION_READ, $share['permissions']);
- $this->assertSame($this->filename . '-renamed', $share['file_target']);
-
- }
-
- /**
- * user1 share file to a group and to a user2 in the same group. Then user2
- * unshares the file from self. Afterwards user1 should no longer see the
- * single user share to user2. If he re-shares the file to user2 the same target
- * then the group share should be used to group the item
- */
- public function testShareAndUnshareFromSelf() {
- $fileinfo = $this->view->getFileInfo($this->filename);
-
- // share the file to group1 (user2 is a member of this group) and explicitely to user2
- \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, self::TEST_FILES_SHARING_API_GROUP1, \OCP\Constants::PERMISSION_ALL);
- \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_ALL);
-
- // user1 should have to shared files
- $shares = \OCP\Share::getItemsShared('file');
- $this->assertSame(2, count($shares));
-
- // user2 should have two files "welcome.txt" and the shared file,
- // both the group share and the single share of the same file should be
- // grouped to one file
- \Test_Files_Sharing::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $dirContent = \OC\Files\Filesystem::getDirectoryContent('/');
- $this->assertSame(2, count($dirContent));
- $this->verifyDirContent($dirContent, array('welcome.txt', ltrim($this->filename, '/')));
-
- // now user2 deletes the share (= unshare from self)
- \OC\Files\Filesystem::unlink($this->filename);
-
- // only welcome.txt should exists
- $dirContent = \OC\Files\Filesystem::getDirectoryContent('/');
- $this->assertSame(1, count($dirContent));
- $this->verifyDirContent($dirContent, array('welcome.txt'));
-
- // login as user1...
- \Test_Files_Sharing::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- // ... now user1 should have only one shared file, the group share
- $shares = \OCP\Share::getItemsShared('file');
- $this->assertSame(1, count($shares));
-
- // user1 shares a gain the file directly to user2
- \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_ALL);
-
- // user2 should see again welcome.txt and the shared file
- \Test_Files_Sharing::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $dirContent = \OC\Files\Filesystem::getDirectoryContent('/');
- $this->assertSame(2, count($dirContent));
- $this->verifyDirContent($dirContent, array('welcome.txt', ltrim($this->filename, '/')));
-
-
- }
-
- /**
- * @param OC\Files\FileInfo[] $content
- * @param string[] $expected
- */
- public function verifyDirContent($content, $expected) {
- foreach ($content as $c) {
- if (!in_array($c['name'], $expected)) {
- $this->assertTrue(false, "folder should only contain '" . implode(',', $expected) . "', found: " .$c['name']);
- }
- }
- }
-
- public function testShareWithDifferentShareFolder() {
-
- $fileinfo = $this->view->getFileInfo($this->filename);
- $folderinfo = $this->view->getFileInfo($this->folder);
-
- $fileShare = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
- $this->assertTrue($fileShare);
-
- \OCA\Files_Sharing\Helper::setShareFolder('/Shared/subfolder');
-
- $folderShare = \OCP\Share::shareItem('folder', $folderinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
- $this->assertTrue($folderShare);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
- $this->assertTrue(\OC\Files\Filesystem::file_exists('/Shared/subfolder/' . $this->folder));
-
- //cleanup
- \OC::$server->getConfig()->deleteSystemValue('share_folder');
- }
-
- public function testShareWithGroupUniqueName() {
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- \OC\Files\Filesystem::file_put_contents('test.txt', 'test');
-
- $fileInfo = \OC\Files\Filesystem::getFileInfo('test.txt');
-
- $this->assertTrue(
- \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, self::TEST_FILES_SHARING_API_GROUP1, 23)
- );
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $items = \OCP\Share::getItemsSharedWith('file');
- $this->assertSame('/test.txt' ,$items[0]['file_target']);
- $this->assertSame(23, $items[0]['permissions']);
-
- \OC\Files\Filesystem::rename('test.txt', 'new test.txt');
-
- $items = \OCP\Share::getItemsSharedWith('file');
- $this->assertSame('/new test.txt' ,$items[0]['file_target']);
- $this->assertSame(23, $items[0]['permissions']);
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- \OCP\Share::setPermissions('file', $items[0]['item_source'], $items[0]['share_type'], $items[0]['share_with'], 3);
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $items = \OCP\Share::getItemsSharedWith('file');
-
- $this->assertSame('/new test.txt' ,$items[0]['file_target']);
- $this->assertSame(3, $items[0]['permissions']);
- }
-
- /**
- * shared files should never have delete permissions
- * @dataProvider dataProviderTestFileSharePermissions
- */
- public function testFileSharePermissions($permission, $expectedPermissions) {
-
- $fileinfo = $this->view->getFileInfo($this->filename);
-
- $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing::TEST_FILES_SHARING_API_USER2, $permission);
-
- $this->assertTrue($result);
-
- $result = \OCP\Share::getItemShared('file', null);
-
- $this->assertTrue(is_array($result));
-
- // test should return exactly one shares created from testCreateShare()
- $this->assertSame(1, count($result), 'more then one share found');
-
- $share = reset($result);
- $this->assertSame($expectedPermissions, $share['permissions']);
- }
-
- public function dataProviderTestFileSharePermissions() {
- $permission1 = \OCP\Constants::PERMISSION_ALL;
- $permission3 = \OCP\Constants::PERMISSION_READ;
- $permission4 = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE;
- $permission5 = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_DELETE;
- $permission6 = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
-
- return array(
- array($permission1, \OCP\Constants::PERMISSION_ALL & ~\OCP\Constants::PERMISSION_DELETE),
- array($permission3, $permission3),
- array($permission4, $permission4),
- array($permission5, $permission3),
- array($permission6, $permission4),
- );
- }
-
- public function testFileOwner() {
-
- $fileinfo = $this->view->getFileInfo($this->filename);
-
- $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- \Test_Files_Sharing::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_ALL);
-
- $this->assertTrue($result);
-
- $this->loginHelper(\Test_Files_Sharing::TEST_FILES_SHARING_API_USER2);
-
- $info = \OC\Files\Filesystem::getFileInfo($this->filename);
-
- $this->assertSame(\Test_Files_Sharing::TEST_FILES_SHARING_API_USER1, $info->getOwner()->getUID());
- }
-
- /**
- * @dataProvider dataProviderGetUsersSharingFile
- *
- * @param string $groupName name of group to share with
- * @param bool $includeOwner whether to include the owner in the result
- * @param bool $includePaths whether to include paths in the result
- * @param array $expectedResult expected result of the API call
- */
- public function testGetUsersSharingFile($groupName, $includeOwner, $includePaths, $expectedResult) {
-
- $fileinfo = $this->view->getFileInfo($this->folder);
-
- $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP,
- $groupName, \OCP\Constants::PERMISSION_READ);
- $this->assertTrue($result);
-
- // public share
- $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK,
- null, \OCP\Constants::PERMISSION_READ);
- $this->assertNotNull($result); // returns the token!
-
- // owner renames after sharing
- $this->view->rename($this->folder, $this->folder . '_owner_renamed');
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
- $user2View->rename($this->folder, $this->folder . '_renamed');
-
- $ownerPath = $this->folder . '_owner_renamed';
- $owner = self::TEST_FILES_SHARING_API_USER1;
-
- $result = \OCP\Share::getUsersSharingFile($ownerPath, $owner, $includeOwner, $includePaths);
-
- // sort users to make sure it matches
- if ($includePaths) {
- ksort($result);
- } else {
- sort($result['users']);
- }
-
- $this->assertEquals(
- $expectedResult,
- $result
- );
- }
-
- public function dataProviderGetUsersSharingFile() {
- // note: "group" contains user1 (the owner), user2 and user3
- // and self::TEST_FILES_SHARING_API_GROUP1 contains only user2
- return [
- // share with group that contains owner
- [
- 'group',
- false,
- false,
- [
- 'users' =>
- [
- // because user1 was in group
- self::TEST_FILES_SHARING_API_USER1,
- self::TEST_FILES_SHARING_API_USER2,
- self::TEST_FILES_SHARING_API_USER3,
- ],
- 'public' => true,
- 'remote' => false,
- ],
- ],
- // share with group that does not contain owner
- [
- self::TEST_FILES_SHARING_API_GROUP1,
- false,
- false,
- [
- 'users' =>
- [
- self::TEST_FILES_SHARING_API_USER2,
- ],
- 'public' => true,
- 'remote' => false,
- ],
- ],
- // share with group that does not contain owner, include owner
- [
- self::TEST_FILES_SHARING_API_GROUP1,
- true,
- false,
- [
- 'users' =>
- [
- self::TEST_FILES_SHARING_API_USER1,
- self::TEST_FILES_SHARING_API_USER2,
- ],
- 'public' => true,
- 'remote' => false,
- ],
- ],
- // include paths, with owner
- [
- 'group',
- true,
- true,
- [
- self::TEST_FILES_SHARING_API_USER1 => self::TEST_FOLDER_NAME . '_owner_renamed',
- self::TEST_FILES_SHARING_API_USER2 => self::TEST_FOLDER_NAME . '_renamed',
- self::TEST_FILES_SHARING_API_USER3 => self::TEST_FOLDER_NAME,
- ],
- ],
- // include paths, group without owner
- [
- self::TEST_FILES_SHARING_API_GROUP1,
- false,
- true,
- [
- self::TEST_FILES_SHARING_API_USER2 => self::TEST_FOLDER_NAME. '_renamed',
- ],
- ],
- // include paths, include owner, group without owner
- [
- self::TEST_FILES_SHARING_API_GROUP1,
- true,
- true,
- [
- self::TEST_FILES_SHARING_API_USER1 => self::TEST_FOLDER_NAME . '_owner_renamed',
- self::TEST_FILES_SHARING_API_USER2 => self::TEST_FOLDER_NAME . '_renamed',
- ],
- ],
- ];
- }
-
-}
diff --git a/apps/files_sharing/tests/sharedmount.php b/apps/files_sharing/tests/sharedmount.php
deleted file mode 100644
index e01deeb60f4..00000000000
--- a/apps/files_sharing/tests/sharedmount.php
+++ /dev/null
@@ -1,466 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-/**
- * Class Test_Files_Sharing_Api
- *
- * @group DB
- */
-class Test_Files_Sharing_Mount extends OCA\Files_sharing\Tests\TestCase {
-
- protected function setUp() {
- parent::setUp();
-
- $this->folder = '/folder_share_storage_test';
-
- $this->filename = '/share-api-storage.txt';
-
-
- $this->view->mkdir($this->folder);
-
- // save file with content
- $this->view->file_put_contents($this->filename, "root file");
- $this->view->file_put_contents($this->folder . $this->filename, "file in subfolder");
- }
-
- protected function tearDown() {
- if ($this->view) {
- $this->view->unlink($this->folder);
- $this->view->unlink($this->filename);
- }
-
- parent::tearDown();
- }
-
- /**
- * test if the mount point moves up if the parent folder no longer exists
- */
- function testShareMountLoseParentFolder() {
-
- // share to user
- $fileinfo = $this->view->getFileInfo($this->folder);
- $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
-
- $statement = "UPDATE `*PREFIX*share` SET `file_target` = ? where `share_with` = ?";
- $query = \OCP\DB::prepare($statement);
- $arguments = array('/foo/bar' . $this->folder, self::TEST_FILES_SHARING_API_USER2);
- $query->execute($arguments);
-
- $query = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
- $result = $query->execute();
-
- $shares = $result->fetchAll();
-
- $this->assertSame(1, count($shares));
-
- $share = reset($shares);
- $this->assertSame('/foo/bar' . $this->folder, $share['file_target']);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- // share should have moved up
-
- $query = \OCP\DB::prepare('SELECT * FROM `*PREFIX*share`');
- $result = $query->execute();
-
- $shares = $result->fetchAll();
-
- $this->assertSame(1, count($shares));
-
- $share = reset($shares);
- $this->assertSame($this->folder, $share['file_target']);
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
- $this->view->unlink($this->folder);
- }
-
- /**
- * @medium
- */
- function testDeleteParentOfMountPoint() {
-
- // share to user
- $fileinfo = $this->view->getFileInfo($this->folder);
- $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
-
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
- $this->assertTrue($user2View->file_exists($this->folder));
-
- // create a local folder
- $result = $user2View->mkdir('localfolder');
- $this->assertTrue($result);
-
- // move mount point to local folder
- $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder);
- $this->assertTrue($result);
-
- // mount point in the root folder should no longer exist
- $this->assertFalse($user2View->is_dir($this->folder));
-
- // delete the local folder
- $result = $user2View->unlink('/localfolder');
- $this->assertTrue($result);
-
- //enforce reload of the mount points
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- //mount point should be back at the root
- $this->assertTrue($user2View->is_dir($this->folder));
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->view->unlink($this->folder);
- }
-
- function testMoveSharedFile() {
- $fileinfo = $this->view->getFileInfo($this->filename);
- $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- \OC\Files\Filesystem::rename($this->filename, $this->filename . '_renamed');
-
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename . '_renamed'));
- $this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename));
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
- $this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename . '_renamed'));
-
- // rename back to original name
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- \OC\Files\Filesystem::rename($this->filename . '_renamed', $this->filename);
- $this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename . '_renamed'));
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
-
- //cleanup
- \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
- }
-
- /**
- * share file with a group if a user renames the file the filename should not change
- * for the other users
- */
- function testMoveGroupShare () {
- \OC_Group::createGroup('testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup');
-
- $fileinfo = $this->view->getFileInfo($this->filename);
- $result = \OCP\Share::shareItem('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP,
- "testGroup", 31);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
-
- \OC\Files\Filesystem::rename($this->filename, "newFileName");
-
- $this->assertTrue(\OC\Files\Filesystem::file_exists('newFileName'));
- $this->assertFalse(\OC\Files\Filesystem::file_exists($this->filename));
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
- $this->assertFalse(\OC\Files\Filesystem::file_exists("newFileName"));
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->filename));
- $this->assertFalse(\OC\Files\Filesystem::file_exists("newFileName"));
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- \OCP\Share::unshare('file', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, 'testGroup');
- \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup');
- \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup');
- \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup');
- }
-
- /**
- * @dataProvider dataProviderTestStripUserFilesPath
- * @param string $path
- * @param string $expectedResult
- * @param bool $exception if a exception is expected
- */
- function testStripUserFilesPath($path, $expectedResult, $exception) {
- $testClass = new DummyTestClassSharedMount(null, null);
- try {
- $result = $testClass->stripUserFilesPathDummy($path);
- $this->assertSame($expectedResult, $result);
- } catch (\Exception $e) {
- if ($exception) {
- $this->assertSame(10, $e->getCode());
- } else {
- $this->assertTrue(false, "Exception catched, but expected: " . $expectedResult);
- }
- }
- }
-
- function dataProviderTestStripUserFilesPath() {
- return array(
- array('/user/files/foo.txt', '/foo.txt', false),
- array('/user/files/folder/foo.txt', '/folder/foo.txt', false),
- array('/data/user/files/foo.txt', null, true),
- array('/data/user/files/', null, true),
- array('/files/foo.txt', null, true),
- array('/foo.txt', null, true),
- );
- }
-
- function dataPermissionMovedGroupShare() {
- $data = [];
-
- $powerset = function($permissions) {
- $results = [\OCP\Constants::PERMISSION_READ];
-
- foreach ($permissions as $permission) {
- foreach ($results as $combination) {
- $results[] = $permission | $combination;
- }
- }
- return $results;
- };
-
- //Generate file permissions
- $permissions = [
- \OCP\Constants::PERMISSION_UPDATE,
- \OCP\Constants::PERMISSION_CREATE,
- \OCP\Constants::PERMISSION_SHARE,
- ];
-
- $allPermissions = $powerset($permissions);
-
- foreach ($allPermissions as $before) {
- foreach ($allPermissions as $after) {
- if ($before === $after) { continue; }
-
- $data[] = [
- 'file',
- $before,
- $after,
- ];
- }
- }
-
- //Generate folder permissions
- $permissions = [
- \OCP\Constants::PERMISSION_UPDATE,
- \OCP\Constants::PERMISSION_CREATE,
- \OCP\Constants::PERMISSION_SHARE,
- \OCP\Constants::PERMISSION_DELETE,
- ];
-
- $allPermissions = $powerset($permissions);
-
- foreach ($allPermissions as $before) {
- foreach ($allPermissions as $after) {
- if ($before === $after) { continue; }
-
- $data[] = [
- 'folder',
- $before,
- $after,
- ];
- }
- }
-
- return $data;
- }
-
-
-
- /**
- * moved mountpoints of a group share should keep the same permission as their parent group share.
- * See #15253
- *
- * @dataProvider dataPermissionMovedGroupShare
- */
- function testPermissionMovedGroupShare($type, $beforePerm, $afterPerm) {
-
- if ($type === 'file') {
- $path = $this->filename;
- } else if ($type === 'folder') {
- $path = $this->folder;
- }
-
- \OC_Group::createGroup('testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup');
-
- // Share item with group
- $fileinfo = $this->view->getFileInfo($path);
- $this->assertTrue(
- \OCP\Share::shareItem($type, $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, "testGroup", $beforePerm)
- );
-
- // Login as user 2 and verify the item exists
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue(\OC\Files\Filesystem::file_exists($path));
- $result = \OCP\Share::getItemSharedWithBySource($type, $fileinfo['fileid']);
- $this->assertNotEmpty($result);
- $this->assertEquals($beforePerm, $result['permissions']);
-
- // Now move the item forcing a new entry in the share table
- \OC\Files\Filesystem::rename($path, "newPath");
- $this->assertTrue(\OC\Files\Filesystem::file_exists('newPath'));
- $this->assertFalse(\OC\Files\Filesystem::file_exists($path));
-
- // Login as user 1 again and change permissions
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->assertTrue(
- \OCP\Share::setPermissions($type, $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, "testGroup", $afterPerm)
- );
-
- // Login as user 3 and verify that the permissions are changed
- self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
- $result = \OCP\Share::getItemSharedWithBySource($type, $fileinfo['fileid']);
- $this->assertNotEmpty($result);
- $this->assertEquals($afterPerm, $result['permissions']);
- $groupShareId = $result['id'];
-
- // Login as user 2 and verify that the permissions are changed
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $result = \OCP\Share::getItemSharedWithBySource($type, $fileinfo['fileid']);
- $this->assertNotEmpty($result);
- $this->assertEquals($afterPerm, $result['permissions']);
- $this->assertNotEquals($groupShareId, $result['id']);
-
- // Also verify in the DB
- $statement = "SELECT `permissions` FROM `*PREFIX*share` WHERE `id`=?";
- $query = \OCP\DB::prepare($statement);
- $result = $query->execute([$result['id']]);
- $shares = $result->fetchAll();
- $this->assertCount(1, $shares);
- $this->assertEquals($afterPerm, $shares[0]['permissions']);
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- \OCP\Share::unshare($type, $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, 'testGroup');
- \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup');
- \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup');
- \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup');
- }
-
- /**
- * If the permissions on a group share are upgraded be sure to still respect
- * removed shares by a member of that group
- */
- function testPermissionUpgradeOnUserDeletedGroupShare() {
- \OC_Group::createGroup('testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup');
- \OC_Group::addToGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup');
-
- $connection = \OC::$server->getDatabaseConnection();
-
- // Share item with group
- $fileinfo = $this->view->getFileInfo($this->folder);
- $this->assertTrue(
- \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, "testGroup", \OCP\Constants::PERMISSION_READ)
- );
-
- // Login as user 2 and verify the item exists
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->folder));
- $result = \OCP\Share::getItemSharedWithBySource('folder', $fileinfo['fileid']);
- $this->assertNotEmpty($result);
- $this->assertEquals(\OCP\Constants::PERMISSION_READ, $result['permissions']);
-
- // Delete the share
- $this->assertTrue(\OC\Files\Filesystem::rmdir($this->folder));
- $this->assertFalse(\OC\Files\Filesystem::file_exists($this->folder));
-
- // Verify we do not get a share
- $result = \OCP\Share::getItemSharedWithBySource('folder', $fileinfo['fileid']);
- $this->assertEmpty($result);
-
- // Verify that the permission is correct in the DB
- $qb = $connection->getQueryBuilder();
- $qb->select('*')
- ->from('share')
- ->where($qb->expr()->eq('file_source', $qb->createParameter('fileSource')))
- ->andWhere($qb->expr()->eq('share_type', $qb->createParameter('shareType')))
- ->setParameter(':fileSource', $fileinfo['fileid'])
- ->setParameter(':shareType', 2);
- $res = $qb->execute()->fetchAll();
-
- $this->assertCount(1, $res);
- $this->assertEquals(0, $res[0]['permissions']);
-
- // Login as user 1 again and change permissions
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->assertTrue(
- \OCP\Share::setPermissions('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, "testGroup", \OCP\Constants::PERMISSION_ALL)
- );
-
- // Login as user 2 and verify
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $this->assertFalse(\OC\Files\Filesystem::file_exists($this->folder));
- $result = \OCP\Share::getItemSharedWithBySource('folder', $fileinfo['fileid']);
- $this->assertEmpty($result);
-
- $connection = \OC::$server->getDatabaseConnection();
- $qb = $connection->getQueryBuilder();
- $qb->select('*')
- ->from('share')
- ->where($qb->expr()->eq('file_source', $qb->createParameter('fileSource')))
- ->andWhere($qb->expr()->eq('share_type', $qb->createParameter('shareType')))
- ->setParameter(':fileSource', $fileinfo['fileid'])
- ->setParameter(':shareType', 2);
- $res = $qb->execute()->fetchAll();
-
- $this->assertCount(1, $res);
- $this->assertEquals(0, $res[0]['permissions']);
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, 'testGroup');
- \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER1, 'testGroup');
- \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER2, 'testGroup');
- \OC_Group::removeFromGroup(self::TEST_FILES_SHARING_API_USER3, 'testGroup');
- }
-
-}
-
-class DummyTestClassSharedMount extends \OCA\Files_Sharing\SharedMount {
- public function __construct($storage, $mountpoint, $arguments = null, $loader = null){
- // noop
- }
-
- public function stripUserFilesPathDummy($path) {
- return $this->stripUserFilesPath($path);
- }
-}
diff --git a/apps/files_sharing/tests/sharedstorage.php b/apps/files_sharing/tests/sharedstorage.php
deleted file mode 100644
index 63f4334103f..00000000000
--- a/apps/files_sharing/tests/sharedstorage.php
+++ /dev/null
@@ -1,488 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-use OCA\Files\Share;
-
-/**
- * Class Test_Files_Sharing_Api
- *
- * @group DB
- */
-class Test_Files_Sharing_Storage extends OCA\Files_sharing\Tests\TestCase {
-
- protected function setUp() {
- parent::setUp();
- \OCA\Files_Trashbin\Trashbin::registerHooks();
- $this->folder = '/folder_share_storage_test';
-
- $this->filename = '/share-api-storage.txt';
-
-
- $this->view->mkdir($this->folder);
-
- // save file with content
- $this->view->file_put_contents($this->filename, "root file");
- $this->view->file_put_contents($this->folder . $this->filename, "file in subfolder");
- }
-
- protected function tearDown() {
- if ($this->view) {
- $this->view->unlink($this->folder);
- $this->view->unlink($this->filename);
- }
-
- \OC\Files\Filesystem::getLoader()->removeStorageWrapper('oc_trashbin');
-
- parent::tearDown();
- }
-
- /**
- * if the parent of the mount point is gone then the mount point should move up
- *
- * @medium
- */
- function testParentOfMountPointIsGone() {
-
- // share to user
- $fileinfo = $this->view->getFileInfo($this->folder);
- $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
-
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
- $this->assertTrue($user2View->file_exists($this->folder));
-
- // create a local folder
- $result = $user2View->mkdir('localfolder');
- $this->assertTrue($result);
-
- // move mount point to local folder
- $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder);
- $this->assertTrue($result);
-
- // mount point in the root folder should no longer exist
- $this->assertFalse($user2View->is_dir($this->folder));
-
- // delete the local folder
- /** @var \OC\Files\Storage\Storage $storage */
- list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/localfolder');
- $storage->rmdir($internalPath);
-
- //enforce reload of the mount points
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- //mount point should be back at the root
- $this->assertTrue($user2View->is_dir($this->folder));
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->view->unlink($this->folder);
- }
-
- /**
- * @medium
- */
- function testRenamePartFile() {
-
- // share to user
- $fileinfo = $this->view->getFileInfo($this->folder);
- $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
-
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
-
- $this->assertTrue($user2View->file_exists($this->folder));
-
- // create part file
- $result = $user2View->file_put_contents($this->folder . '/foo.txt.part', 'some test data');
-
- $this->assertTrue(is_int($result));
- // rename part file to real file
- $result = $user2View->rename($this->folder . '/foo.txt.part', $this->folder . '/foo.txt');
-
- $this->assertTrue($result);
-
- // check if the new file really exists
- $this->assertTrue($user2View->file_exists($this->folder . '/foo.txt'));
-
- // check if the rename also affected the owner
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- $this->assertTrue($this->view->file_exists($this->folder . '/foo.txt'));
-
- //cleanup
- \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
- }
-
- public function testFilesize() {
-
- $fileinfoFolder = $this->view->getFileInfo($this->folder);
- $fileinfoFile = $this->view->getFileInfo($this->filename);
-
- $folderSize = $this->view->filesize($this->folder);
- $file1Size = $this->view->filesize($this->folder . $this->filename);
- $file2Size = $this->view->filesize($this->filename);
-
- $result = \OCP\Share::shareItem('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
- $this->assertTrue($result);
-
- $result = \OCP\Share::shareItem('file', $fileinfoFile['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- // compare file size between user1 and user2, should always be the same
- $this->assertSame($folderSize, \OC\Files\Filesystem::filesize($this->folder));
- $this->assertSame($file1Size, \OC\Files\Filesystem::filesize($this->folder . $this->filename));
- $this->assertSame($file2Size, \OC\Files\Filesystem::filesize($this->filename));
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $result = \OCP\Share::unshare('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
- $result = \OCP\Share::unshare('file', $fileinfoFile['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
- }
-
- function testGetPermissions() {
- $fileinfoFolder = $this->view->getFileInfo($this->folder);
-
- $result = \OCP\Share::shareItem('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 1);
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $this->assertTrue(\OC\Files\Filesystem::is_dir($this->folder));
-
- // for the share root we expect:
- // the shared permissions (1)
- // the delete permission (8), to enable unshare
- $rootInfo = \OC\Files\Filesystem::getFileInfo($this->folder);
- $this->assertSame(9, $rootInfo->getPermissions());
-
- // for the file within the shared folder we expect:
- // the shared permissions (1)
- $subfileInfo = \OC\Files\Filesystem::getFileInfo($this->folder . $this->filename);
- $this->assertSame(1, $subfileInfo->getPermissions());
-
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $result = \OCP\Share::unshare('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
- }
-
- public function testFopenWithReadOnlyPermission() {
- $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
- $fileinfoFolder = $this->view->getFileInfo($this->folder);
- $result = \OCP\Share::shareItem('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_READ);
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
-
- // part file should be forbidden
- $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
- $this->assertFalse($handle);
-
- // regular file forbidden
- $handle = $user2View->fopen($this->folder . '/test.txt', 'w');
- $this->assertFalse($handle);
-
- // rename forbidden
- $this->assertFalse($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing2.txt'));
-
- // delete forbidden
- $this->assertFalse($user2View->unlink($this->folder . '/existing.txt'));
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $result = \OCP\Share::unshare('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
- }
-
- public function testFopenWithCreateOnlyPermission() {
- $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
- $fileinfoFolder = $this->view->getFileInfo($this->folder);
- $result = \OCP\Share::shareItem('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE);
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
-
- // create part file allowed
- $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
- $this->assertNotFalse($handle);
- fclose($handle);
-
- // create regular file allowed
- $handle = $user2View->fopen($this->folder . '/test-create.txt', 'w');
- $this->assertNotFalse($handle);
- fclose($handle);
-
- // rename file never allowed
- $this->assertFalse($user2View->rename($this->folder . '/test-create.txt', $this->folder . '/newtarget.txt'));
- $this->assertFalse($user2View->file_exists($this->folder . '/newtarget.txt'));
-
- // rename file not allowed if target exists
- $this->assertFalse($user2View->rename($this->folder . '/newtarget.txt', $this->folder . '/existing.txt'));
-
- // overwriting file not allowed
- $handle = $user2View->fopen($this->folder . '/existing.txt', 'w');
- $this->assertFalse($handle);
-
- // overwrite forbidden (no update permission)
- $this->assertFalse($user2View->rename($this->folder . '/test.txt.part', $this->folder . '/existing.txt'));
-
- // delete forbidden
- $this->assertFalse($user2View->unlink($this->folder . '/existing.txt'));
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $result = \OCP\Share::unshare('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
- }
-
- public function testFopenWithUpdateOnlyPermission() {
- $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
- $fileinfoFolder = $this->view->getFileInfo($this->folder);
-
- $result = \OCP\Share::shareItem('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE);
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
-
- // create part file allowed
- $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
- $this->assertNotFalse($handle);
- fclose($handle);
-
- // create regular file not allowed
- $handle = $user2View->fopen($this->folder . '/test-create.txt', 'w');
- $this->assertFalse($handle);
-
- // rename part file not allowed to non-existing file
- $this->assertFalse($user2View->rename($this->folder . '/test.txt.part', $this->folder . '/nonexist.txt'));
-
- // rename part file allowed to target existing file
- $this->assertTrue($user2View->rename($this->folder . '/test.txt.part', $this->folder . '/existing.txt'));
- $this->assertTrue($user2View->file_exists($this->folder . '/existing.txt'));
-
- // rename regular file allowed
- $this->assertTrue($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing-renamed.txt'));
- $this->assertTrue($user2View->file_exists($this->folder . '/existing-renamed.txt'));
-
- // overwriting file directly is allowed
- $handle = $user2View->fopen($this->folder . '/existing-renamed.txt', 'w');
- $this->assertNotFalse($handle);
- fclose($handle);
-
- // delete forbidden
- $this->assertFalse($user2View->unlink($this->folder . '/existing-renamed.txt'));
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $result = \OCP\Share::unshare('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
- }
-
- public function testFopenWithDeleteOnlyPermission() {
- $this->view->file_put_contents($this->folder . '/existing.txt', 'foo');
- $fileinfoFolder = $this->view->getFileInfo($this->folder);
- $result = \OCP\Share::shareItem('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_DELETE);
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
-
- // part file should be forbidden
- $handle = $user2View->fopen($this->folder . '/test.txt.part', 'w');
- $this->assertFalse($handle);
-
- // regular file forbidden
- $handle = $user2View->fopen($this->folder . '/test.txt', 'w');
- $this->assertFalse($handle);
-
- // rename forbidden
- $this->assertFalse($user2View->rename($this->folder . '/existing.txt', $this->folder . '/existing2.txt'));
-
- // delete allowed
- $this->assertTrue($user2View->unlink($this->folder . '/existing.txt'));
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $result = \OCP\Share::unshare('folder', $fileinfoFolder['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
- }
-
- function testMountSharesOtherUser() {
- $folderInfo = $this->view->getFileInfo($this->folder);
- $fileInfo = $this->view->getFileInfo($this->filename);
- $rootView = new \OC\Files\View('');
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- // share 2 different files with 2 different users
- \OCP\Share::shareItem('folder', $folderInfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
- \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER3, 31);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->folder));
-
- $mountConfigManager = \OC::$server->getMountProviderCollection();
- $mounts = $mountConfigManager->getMountsForUser(\OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER3));
- array_walk($mounts, array(\OC\Files\Filesystem::getMountManager(), 'addMount'));
-
- $this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER3 . '/files/' . $this->filename));
-
- // make sure we didn't double setup shares for user 2 or mounted the shares for user 3 in user's 2 home
- $this->assertFalse($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->folder . ' (2)'));
- $this->assertFalse($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->filename));
-
- //cleanup
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->view->unlink($this->folder);
- }
-
- public function testCopyFromStorage() {
- $folderInfo = $this->view->getFileInfo($this->folder);
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- // share 2 different files with 2 different users
- \OCP\Share::shareItem('folder', $folderInfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $view = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
- $this->assertTrue($view->file_exists($this->folder));
-
- /**
- * @var \OCP\Files\Storage $sharedStorage
- */
- list($sharedStorage,) = $view->resolvePath($this->folder);
- $this->assertTrue($sharedStorage->instanceOfStorage('OCA\Files_Sharing\ISharedStorage'));
-
- $sourceStorage = new \OC\Files\Storage\Temporary(array());
- $sourceStorage->file_put_contents('foo.txt', 'asd');
-
- $sharedStorage->copyFromStorage($sourceStorage, 'foo.txt', 'bar.txt');
- $this->assertTrue($sharedStorage->file_exists('bar.txt'));
- $this->assertEquals('asd', $sharedStorage->file_get_contents('bar.txt'));
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->view->unlink($this->folder);
- }
-
- public function testMoveFromStorage() {
- $folderInfo = $this->view->getFileInfo($this->folder);
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- // share 2 different files with 2 different users
- \OCP\Share::shareItem('folder', $folderInfo['fileid'], \OCP\Share::SHARE_TYPE_USER,
- self::TEST_FILES_SHARING_API_USER2, 31);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $view = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
- $this->assertTrue($view->file_exists($this->folder));
-
- /**
- * @var \OCP\Files\Storage $sharedStorage
- */
- list($sharedStorage,) = $view->resolvePath($this->folder);
- $this->assertTrue($sharedStorage->instanceOfStorage('OCA\Files_Sharing\ISharedStorage'));
-
- $sourceStorage = new \OC\Files\Storage\Temporary(array());
- $sourceStorage->file_put_contents('foo.txt', 'asd');
-
- $sharedStorage->moveFromStorage($sourceStorage, 'foo.txt', 'bar.txt');
- $this->assertTrue($sharedStorage->file_exists('bar.txt'));
- $this->assertEquals('asd', $sharedStorage->file_get_contents('bar.txt'));
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->view->unlink($this->folder);
- }
-
- public function testNameConflict() {
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $view1 = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
- $view1->mkdir('foo');
- $folderInfo1 = $view1->getFileInfo('foo');
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
- $view3 = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files');
- $view3->mkdir('foo');
- $folderInfo2 = $view3->getFileInfo('foo');
-
- // share a folder with the same name from two different users to the same user
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- \OCP\Share::shareItem('folder', $folderInfo1['fileid'], \OCP\Share::SHARE_TYPE_GROUP,
- self::TEST_FILES_SHARING_API_GROUP1, 31);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER3);
-
- \OCP\Share::shareItem('folder', $folderInfo2['fileid'], \OCP\Share::SHARE_TYPE_GROUP,
- self::TEST_FILES_SHARING_API_GROUP1, 31);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $view2 = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
-
- $this->assertTrue($view2->file_exists('/foo'));
- $this->assertTrue($view2->file_exists('/foo (2)'));
-
- $mount = $view2->getMount('/foo');
- $this->assertInstanceOf('\OCA\Files_Sharing\SharedMount', $mount);
- /** @var \OC\Files\Storage\Shared $storage */
- $storage = $mount->getStorage();
-
- $source = $storage->getFile('');
- $this->assertEquals(self::TEST_FILES_SHARING_API_USER1, $source['uid_owner']);
- }
-}
diff --git a/apps/files_sharing/tests/sizepropagation.php b/apps/files_sharing/tests/sizepropagation.php
deleted file mode 100644
index 7b7884f3f96..00000000000
--- a/apps/files_sharing/tests/sizepropagation.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_sharing\Tests;
-
-use OC\Files\View;
-
-/**
- * Class SizePropagation
- *
- * @group DB
- *
- * @package OCA\Files_sharing\Tests
- */
-class SizePropagation extends TestCase {
-
- public function testSizePropagationWhenOwnerChangesFile() {
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $recipientView = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $ownerView = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
- $ownerView->mkdir('/sharedfolder/subfolder');
- $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'bar');
-
- $sharedFolderInfo = $ownerView->getFileInfo('/sharedfolder', false);
- $this->assertInstanceOf('\OC\Files\FileInfo', $sharedFolderInfo);
- \OCP\Share::shareItem('folder', $sharedFolderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER1, 31);
- $ownerRootInfo = $ownerView->getFileInfo('', false);
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt'));
- $recipientRootInfo = $recipientView->getFileInfo('', false);
-
- // when file changed as owner
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar');
-
- // size of recipient's root stays the same
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $newRecipientRootInfo = $recipientView->getFileInfo('', false);
- $this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize());
-
- // size of owner's root increases
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $newOwnerRootInfo = $ownerView->getFileInfo('', false);
- $this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize());
- }
-
- public function testSizePropagationWhenRecipientChangesFile() {
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $recipientView = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $ownerView = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
- $ownerView->mkdir('/sharedfolder/subfolder');
- $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'bar');
-
- $sharedFolderInfo = $ownerView->getFileInfo('/sharedfolder', false);
- $this->assertInstanceOf('\OC\Files\FileInfo', $sharedFolderInfo);
- \OCP\Share::shareItem('folder', $sharedFolderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER1, 31);
- $ownerRootInfo = $ownerView->getFileInfo('', false);
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt'));
- $recipientRootInfo = $recipientView->getFileInfo('', false);
-
- // when file changed as recipient
- $recipientView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar');
-
- // size of recipient's root stays the same
- $newRecipientRootInfo = $recipientView->getFileInfo('', false);
- $this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize());
-
- // size of owner's root increases
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $newOwnerRootInfo = $ownerView->getFileInfo('', false);
- $this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize());
- }
-}
diff --git a/apps/files_sharing/tests/testcase.php b/apps/files_sharing/tests/testcase.php
deleted file mode 100644
index ce0a8beeec8..00000000000
--- a/apps/files_sharing/tests/testcase.php
+++ /dev/null
@@ -1,204 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_Sharing\Tests;
-
-use OC\Files\Filesystem;
-use OCA\Files\Share;
-use OCA\Files_Sharing\Appinfo\Application;
-
-/**
- * Class Test_Files_Sharing_Base
- *
- * @group DB
- *
- * Base class for sharing tests.
- */
-abstract class TestCase extends \Test\TestCase {
-
- const TEST_FILES_SHARING_API_USER1 = "test-share-user1";
- const TEST_FILES_SHARING_API_USER2 = "test-share-user2";
- const TEST_FILES_SHARING_API_USER3 = "test-share-user3";
- const TEST_FILES_SHARING_API_USER4 = "test-share-user4";
-
- const TEST_FILES_SHARING_API_GROUP1 = "test-share-group1";
-
- public $filename;
- public $data;
- /**
- * @var \OC\Files\View
- */
- public $view;
- public $folder;
- public $subfolder;
-
- public static function setUpBeforeClass() {
- parent::setUpBeforeClass();
-
- $application = new Application();
- $application->registerMountProviders();
-
- // reset backend
- \OC_User::clearBackends();
- \OC_Group::clearBackends();
-
- // clear share hooks
- \OC_Hook::clear('OCP\\Share');
- \OC::registerShareHooks();
-
- // create users
- $backend = new \Test\Util\User\Dummy();
- \OC_User::useBackend($backend);
- $backend->createUser(self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER1);
- $backend->createUser(self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_USER2);
- $backend->createUser(self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER3);
- $backend->createUser(self::TEST_FILES_SHARING_API_USER4, self::TEST_FILES_SHARING_API_USER4);
-
- // create group
- $groupBackend = new \OC_Group_Dummy();
- $groupBackend->createGroup(self::TEST_FILES_SHARING_API_GROUP1);
- $groupBackend->createGroup('group');
- $groupBackend->createGroup('group1');
- $groupBackend->createGroup('group2');
- $groupBackend->createGroup('group3');
- $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER1, 'group');
- $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER2, 'group');
- $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER3, 'group');
- $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER2, 'group1');
- $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER3, 'group2');
- $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER4, 'group3');
- $groupBackend->addToGroup(self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_GROUP1);
- \OC_Group::useBackend($groupBackend);
-
- }
-
- protected function setUp() {
- parent::setUp();
-
- //login as user1
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- $this->data = 'foobar';
- $this->view = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
- }
-
- protected function tearDown() {
- $query = \OCP\DB::prepare('DELETE FROM `*PREFIX*share`');
- $query->execute();
-
- parent::tearDown();
- }
-
- public static function tearDownAfterClass() {
- // cleanup users
- $user = \OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER1);
- if ($user !== null) { $user->delete(); }
- $user = \OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER2);
- if ($user !== null) { $user->delete(); }
- $user = \OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER3);
- if ($user !== null) { $user->delete(); }
-
- // delete group
- \OC_Group::deleteGroup(self::TEST_FILES_SHARING_API_GROUP1);
-
- \OC_Util::tearDownFS();
- \OC_User::setUserId('');
- Filesystem::tearDown();
-
- // reset backend
- \OC_User::clearBackends();
- \OC_User::useBackend('database');
- \OC_Group::clearBackends();
- \OC_Group::useBackend(new \OC_Group_Database());
-
- parent::tearDownAfterClass();
- }
-
- /**
- * @param string $user
- * @param bool $create
- * @param bool $password
- */
- protected static function loginHelper($user, $create = false, $password = false) {
-
- if ($password === false) {
- $password = $user;
- }
-
- if ($create) {
- \OC::$server->getUserManager()->createUser($user, $password);
- \OC_Group::createGroup('group');
- \OC_Group::addToGroup($user, 'group');
- }
-
- self::resetStorage();
-
- \OC_Util::tearDownFS();
- \OC::$server->getUserSession()->setUser(null);
- \OC\Files\Filesystem::tearDown();
- \OC::$server->getUserSession()->login($user, $password);
- \OC::$server->getUserFolder($user);
-
- \OC_Util::setupFS($user);
- }
-
- /**
- * reset init status for the share storage
- */
- protected static function resetStorage() {
- $storage = new \ReflectionClass('\OC\Files\Storage\Shared');
- $isInitialized = $storage->getProperty('initialized');
- $isInitialized->setAccessible(true);
- $isInitialized->setValue($storage, false);
- $isInitialized->setAccessible(false);
- }
-
- /**
- * get some information from a given share
- * @param int $shareID
- * @return array with: item_source, share_type, share_with, item_type, permissions
- */
- protected function getShareFromId($shareID) {
- $sql = 'SELECT `item_source`, `share_type`, `share_with`, `item_type`, `permissions` FROM `*PREFIX*share` WHERE `id` = ?';
- $args = array($shareID);
- $query = \OCP\DB::prepare($sql);
- $result = $query->execute($args);
-
- $share = Null;
-
- if ($result) {
- $share = $result->fetchRow();
- }
-
- return $share;
-
- }
-
-}
diff --git a/apps/files_sharing/tests/unsharechildren.php b/apps/files_sharing/tests/unsharechildren.php
deleted file mode 100644
index 1968007be4e..00000000000
--- a/apps/files_sharing/tests/unsharechildren.php
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OCA\Files_sharing\Tests;
-
-use OCA\Files\Share;
-
-/**
- * Class UnshareChildren
- *
- * @group DB
- *
- * @package OCA\Files_sharing\Tests
- */
-class UnshareChildren extends TestCase {
-
- protected $subsubfolder;
-
- const TEST_FOLDER_NAME = '/folder_share_api_test';
-
- private static $tempStorage;
-
- protected function setUp() {
- parent::setUp();
-
- \OCP\Util::connectHook('OC_Filesystem', 'post_delete', '\OCA\Files_Sharing\Hooks', 'unshareChildren');
-
- $this->folder = self::TEST_FOLDER_NAME;
- $this->subfolder = '/subfolder_share_api_test';
- $this->subsubfolder = '/subsubfolder_share_api_test';
-
- $this->filename = '/share-api-test';
-
- // save file with content
- $this->view->mkdir($this->folder);
- $this->view->mkdir($this->folder . $this->subfolder);
- $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder);
- $this->view->file_put_contents($this->folder . $this->filename, $this->data);
- $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data);
- }
-
- protected function tearDown() {
- if ($this->view) {
- $this->view->deleteAll($this->folder);
- }
-
- self::$tempStorage = null;
-
- parent::tearDown();
- }
-
- /**
- * @medium
- */
- function testUnshareChildren() {
-
- $fileInfo2 = \OC\Files\Filesystem::getFileInfo($this->folder);
-
- $result = \OCP\Share::shareItem('folder', $fileInfo2->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
- $this->assertTrue($result);
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- // one folder should be shared with the user
- $sharedFolders = \OCP\Share::getItemsSharedWith('folder');
- $this->assertSame(1, count($sharedFolders));
-
- // move shared folder to 'localDir'
- \OC\Files\Filesystem::mkdir('localDir');
- $result = \OC\Files\Filesystem::rename($this->folder, '/localDir/' . $this->folder);
- $this->assertTrue($result);
-
- \OC\Files\Filesystem::unlink('localDir');
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- // after the parent directory was deleted the share should be unshared
- $sharedFolders = \OCP\Share::getItemsSharedWith('folder');
- $this->assertTrue(empty($sharedFolders));
-
- self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
-
- // the folder for the owner should still exists
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->folder));
- }
-}
diff --git a/apps/files_sharing/tests/updater.php b/apps/files_sharing/tests/updater.php
deleted file mode 100644
index 67c1642cdd0..00000000000
--- a/apps/files_sharing/tests/updater.php
+++ /dev/null
@@ -1,218 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-
-
-/**
- * Class Test_Files_Sharing_Updater
- *
- * @group DB
- */
-class Test_Files_Sharing_Updater extends OCA\Files_Sharing\Tests\TestCase {
-
- const TEST_FOLDER_NAME = '/folder_share_updater_test';
-
- public static function setUpBeforeClass() {
- parent::setUpBeforeClass();
- \OCA\Files_Sharing\Helper::registerHooks();
- }
-
- protected function setUp() {
- parent::setUp();
-
- $this->folder = self::TEST_FOLDER_NAME;
-
- $this->filename = '/share-updater-test.txt';
-
- // save file with content
- $this->view->file_put_contents($this->filename, $this->data);
- $this->view->mkdir($this->folder);
- $this->view->file_put_contents($this->folder . '/' . $this->filename, $this->data);
- }
-
- protected function tearDown() {
- if ($this->view) {
- $this->view->unlink($this->filename);
- $this->view->deleteAll($this->folder);
- }
-
- parent::tearDown();
- }
-
- /**
- * test deletion of a folder which contains share mount points. Share mount
- * points should be unshared before the folder gets deleted so
- * that the mount point doesn't end up at the trash bin
- */
- function testDeleteParentFolder() {
- $status = \OC_App::isEnabled('files_trashbin');
- \OC_App::enable('files_trashbin');
-
- \OCA\Files_Trashbin\Trashbin::registerHooks();
-
- $fileinfo = \OC\Files\Filesystem::getFileInfo($this->folder);
- $this->assertTrue($fileinfo instanceof \OC\Files\FileInfo);
-
- \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
- $view = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
-
- // check if user2 can see the shared folder
- $this->assertTrue($view->file_exists($this->folder));
-
- $foldersShared = \OCP\Share::getItemsSharedWith('folder');
- $this->assertSame(1, count($foldersShared));
-
- $view->mkdir("localFolder");
- $view->file_put_contents("localFolder/localFile.txt", "local file");
-
- $view->rename($this->folder, 'localFolder/' . $this->folder);
-
- // share mount point should now be moved to the subfolder
- $this->assertFalse($view->file_exists($this->folder));
- $this->assertTrue($view->file_exists('localFolder/' .$this->folder));
-
- $view->unlink('localFolder');
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- // shared folder should be unshared
- $foldersShared = \OCP\Share::getItemsSharedWith('folder');
- $this->assertTrue(empty($foldersShared));
-
- // trashbin should contain the local file but not the mount point
- $rootView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2);
- $trashContent = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_FILES_SHARING_API_USER2);
- $this->assertSame(1, count($trashContent));
- $firstElement = reset($trashContent);
- $timestamp = $firstElement['mtime'];
- $this->assertTrue($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/localFile.txt'));
- $this->assertFalse($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/' . $this->folder));
-
- //cleanup
- $rootView->deleteAll('files_trashin');
-
- if ($status === false) {
- \OC_App::disable('files_trashbin');
- }
-
- \OC\Files\Filesystem::getLoader()->removeStorageWrapper('oc_trashbin');
- }
-
- public function shareFolderProvider() {
- return [
- ['/'],
- ['/my_shares'],
- ];
- }
-
- /**
- * if a file gets shared the etag for the recipients root should change
- *
- * @dataProvider shareFolderProvider
- *
- * @param string $shareFolder share folder to use
- */
- public function testShareFile($shareFolder) {
- $config = \OC::$server->getConfig();
- $oldShareFolder = $config->getSystemValue('share_folder');
- $config->setSystemValue('share_folder', $shareFolder);
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $beforeShareRoot = \OC\Files\Filesystem::getFileInfo('');
- $etagBeforeShareRoot = $beforeShareRoot->getEtag();
-
- \OC\Files\Filesystem::mkdir($shareFolder);
-
- $beforeShareDir = \OC\Files\Filesystem::getFileInfo($shareFolder);
- $etagBeforeShareDir = $beforeShareDir->getEtag();
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $fileinfo = \OC\Files\Filesystem::getFileInfo($this->folder);
- $result = \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
- $this->assertTrue($result);
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $afterShareRoot = \OC\Files\Filesystem::getFileInfo('');
- $etagAfterShareRoot = $afterShareRoot->getEtag();
-
- $afterShareDir = \OC\Files\Filesystem::getFileInfo($shareFolder);
- $etagAfterShareDir = $afterShareDir->getEtag();
-
- $this->assertTrue(is_string($etagBeforeShareRoot));
- $this->assertTrue(is_string($etagBeforeShareDir));
- $this->assertTrue(is_string($etagAfterShareRoot));
- $this->assertTrue(is_string($etagAfterShareDir));
- $this->assertTrue($etagBeforeShareRoot !== $etagAfterShareRoot);
- $this->assertTrue($etagBeforeShareDir !== $etagAfterShareDir);
-
- // cleanup
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $result = \OCP\Share::unshare('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
-
- $config->setSystemValue('share_folder', $oldShareFolder);
- }
-
- /**
- * if a folder gets renamed all children mount points should be renamed too
- */
- function testRename() {
-
- $fileinfo = \OC\Files\Filesystem::getFileInfo($this->folder);
- $result = \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
- $this->assertTrue($result);
-
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- // make sure that the shared folder exists
- $this->assertTrue(\OC\Files\Filesystem::file_exists($this->folder));
-
- \OC\Files\Filesystem::mkdir('oldTarget');
- \OC\Files\Filesystem::mkdir('oldTarget/subfolder');
- \OC\Files\Filesystem::mkdir('newTarget');
-
- \OC\Files\Filesystem::rename($this->folder, 'oldTarget/subfolder/' . $this->folder);
-
- // re-login to make sure that the new mount points are initialized
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- \OC\Files\Filesystem::rename('/oldTarget', '/newTarget/oldTarget');
-
- // re-login to make sure that the new mount points are initialized
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER2);
-
- $this->assertTrue(\OC\Files\Filesystem::file_exists('/newTarget/oldTarget/subfolder/' . $this->folder));
-
- // cleanup
- $this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
- $result = \OCP\Share::unshare('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2);
- $this->assertTrue($result);
- }
-
-}