diff options
Diffstat (limited to 'apps/files_sharing/tests/Controller')
6 files changed, 2116 insertions, 1649 deletions
diff --git a/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php b/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php index 8a7209e52dc..7e054d9a6dc 100644 --- a/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php +++ b/apps/files_sharing/tests/Controller/ExternalShareControllerTest.php @@ -1,36 +1,19 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Joas Schilling <coding@schilljs.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 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 OCP\AppFramework\Http\DataResponse; +use OCA\Files_Sharing\External\Manager; use OCP\AppFramework\Http\JSONResponse; use OCP\Http\Client\IClientService; +use OCP\IConfig; use OCP\IRequest; -use OCP\Http\Client\IResponse; -use OCP\Http\Client\IClient; -use OCA\Files_Sharing\External\Manager; +use PHPUnit\Framework\MockObject\MockObject; /** * Class ExternalShareControllerTest @@ -42,6 +25,8 @@ class ExternalShareControllerTest extends \Test\TestCase { private $request; /** @var \OCA\Files_Sharing\External\Manager */ private $externalManager; + /** @var IConfig|MockObject */ + private $config; /** @var IClientService */ private $clientService; @@ -50,6 +35,7 @@ class ExternalShareControllerTest extends \Test\TestCase { $this->request = $this->createMock(IRequest::class); $this->externalManager = $this->createMock(Manager::class); $this->clientService = $this->createMock(IClientService::class); + $this->config = $this->createMock(IConfig::class); } /** @@ -60,11 +46,12 @@ class ExternalShareControllerTest extends \Test\TestCase { 'files_sharing', $this->request, $this->externalManager, - $this->clientService + $this->clientService, + $this->config, ); } - public function testIndex() { + public function testIndex(): void { $this->externalManager ->expects($this->once()) ->method('getOpenShares') @@ -73,7 +60,7 @@ class ExternalShareControllerTest extends \Test\TestCase { $this->assertEquals(new JSONResponse(['MyDummyArray']), $this->getExternalShareController()->index()); } - public function testCreate() { + public function testCreate(): void { $this->externalManager ->expects($this->once()) ->method('acceptShare') @@ -82,7 +69,7 @@ class ExternalShareControllerTest extends \Test\TestCase { $this->assertEquals(new JSONResponse(), $this->getExternalShareController()->create(4)); } - public function testDestroy() { + public function testDestroy(): void { $this->externalManager ->expects($this->once()) ->method('declineShare') @@ -90,90 +77,4 @@ class ExternalShareControllerTest extends \Test\TestCase { $this->assertEquals(new JSONResponse(), $this->getExternalShareController()->destroy(4)); } - - public function testRemoteWithValidHttps() { - $client = $this->createMock(IClient::class); - $response = $this->createMock(IResponse::class); - $response - ->expects($this->exactly(2)) - ->method('getBody') - ->willReturnOnConsecutiveCalls( - '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') - ->willReturn($response); - - $this->clientService - ->expects($this->exactly(2)) - ->method('newClient') - ->willReturn($client); - - $this->assertEquals(new DataResponse('https'), $this->getExternalShareController()->testRemote('nextcloud.com')); - } - - public function testRemoteWithWorkingHttp() { - $client = $this->createMock(IClient::class); - $response = $this->createMock(IResponse::class); - $client - ->method('get') - ->willReturn($response); - $response - ->expects($this->exactly(5)) - ->method('getBody') - ->willReturnOnConsecutiveCalls( - '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') - ->willReturn($client); - - $this->assertEquals(new DataResponse('http'), $this->getExternalShareController()->testRemote('nextcloud.com')); - } - - public function testRemoteWithInvalidRemote() { - $client = $this->createMock(IClient::class); - $response = $this->createMock(IResponse::class); - $client - ->expects($this->exactly(6)) - ->method('get') - ->willReturn($response); - $response - ->expects($this->exactly(6)) - ->method('getBody') - ->willReturn('Certainly not a JSON string'); - $this->clientService - ->expects($this->exactly(6)) - ->method('newClient') - ->willReturn($client); - - $this->assertEquals(new DataResponse(false), $this->getExternalShareController()->testRemote('nextcloud.com')); - } - - public function dataRemoteWithInvalidRemoteURLs(): array { - return [ - ['nextcloud.com?query'], - ['nextcloud.com/#anchor'], - ['nextcloud.com/;tomcat'], - ]; - } - - /** - * @dataProvider dataRemoteWithInvalidRemoteURLs - * @param string $remote - */ - public function testRemoteWithInvalidRemoteURLs(string $remote) { - $this->clientService - ->expects($this->never()) - ->method('newClient'); - - $this->assertEquals(new DataResponse(false), $this->getExternalShareController()->testRemote($remote)); - } } diff --git a/apps/files_sharing/tests/Controller/PublicPreviewControllerTest.php b/apps/files_sharing/tests/Controller/PublicPreviewControllerTest.php index 9f852721678..f49d839e8d4 100644 --- a/apps/files_sharing/tests/Controller/PublicPreviewControllerTest.php +++ b/apps/files_sharing/tests/Controller/PublicPreviewControllerTest.php @@ -1,26 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2016, Roeland Jago Douma <roeland@famdouma.nl> - * - * @author Julius Härtl <jus@bitgrid.net> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_Sharing\Tests\Controller; @@ -37,6 +19,7 @@ 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; @@ -45,15 +28,12 @@ use Test\TestCase; class PublicPreviewControllerTest extends TestCase { - /** @var IPreview|\PHPUnit\Framework\MockObject\MockObject */ - private $previewManager; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - private $shareManager; - /** @var ITimeFactory|MockObject */ - private $timeFactory; + private IPreview&MockObject $previewManager; + private IManager&MockObject $shareManager; + private ITimeFactory&MockObject $timeFactory; + private IRequest&MockObject $request; - /** @var PublicPreviewController */ - private $controller; + private PublicPreviewController $controller; protected function setUp(): void { parent::setUp(); @@ -61,6 +41,7 @@ class PublicPreviewControllerTest extends TestCase { $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); @@ -69,35 +50,36 @@ class PublicPreviewControllerTest extends TestCase { $this->controller = new PublicPreviewController( 'files_sharing', - $this->createMock(IRequest::class), + $this->request, $this->shareManager, $this->createMock(ISession::class), - $this->previewManager + $this->previewManager, + $this->createMock(IMimeIconProvider::class), ); } - public function testInvalidToken() { + 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() { + 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() { + 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() { + public function testInvalidShare(): void { $this->shareManager->method('getShareByToken') ->with($this->equalTo('token')) ->willThrowException(new ShareNotFound()); @@ -108,7 +90,7 @@ class PublicPreviewControllerTest extends TestCase { $this->assertEquals($expected, $res); } - public function testShareNotAccessable() { + public function testShareNotAccessable(): void { $share = $this->createMock(IShare::class); $this->shareManager->method('getShareByToken') ->with($this->equalTo('token')) @@ -123,6 +105,96 @@ class PublicPreviewControllerTest extends TestCase { $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') @@ -136,6 +208,9 @@ class PublicPreviewControllerTest extends TestCase { $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); @@ -152,7 +227,7 @@ class PublicPreviewControllerTest extends TestCase { $this->assertEquals($expected, $res); } - public function testPreviewFolderInvalidFile() { + public function testPreviewFolderInvalidFile(): void { $share = $this->createMock(IShare::class); $this->shareManager->method('getShareByToken') ->with($this->equalTo('token')) @@ -165,6 +240,9 @@ class PublicPreviewControllerTest extends TestCase { $share->method('getNode') ->willReturn($folder); + $share->method('canSeeContent') + ->willReturn(true); + $folder->method('get') ->with($this->equalTo('file')) ->willThrowException(new NotFoundException()); @@ -175,7 +253,7 @@ class PublicPreviewControllerTest extends TestCase { } - public function testPreviewFolderValidFile() { + public function testPreviewFolderValidFile(): void { $share = $this->createMock(IShare::class); $this->shareManager->method('getShareByToken') ->with($this->equalTo('token')) @@ -188,6 +266,9 @@ class PublicPreviewControllerTest extends TestCase { $share->method('getNode') ->willReturn($folder); + $share->method('canSeeContent') + ->willReturn(true); + $file = $this->createMock(File::class); $folder->method('get') ->with($this->equalTo('file')) diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php index 5555aef1425..e6be0342c26 100644 --- a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php @@ -1,67 +1,56 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Calviño Sánchez <danxuliu@gmail.com> - * @author Georg Ehrke <oc.list@georgehrke.com> - * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ <skjnldsv@protonmail.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Maxence Lange <maxence@artificial-owl.com> - * @author Maxence Lange <maxence@nextcloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Richard Steinmetz <richard@steinmetz.cloud> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Valdnet <47037905+Valdnet@users.noreply.github.com> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 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; +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\IServerContainer; +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 Test\TestCase; use OCP\UserStatus\IManager as IUserStatusManager; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Container\ContainerInterface; +use Psr\Log\LoggerInterface; +use Test\TestCase; /** * Class ShareAPIControllerTest @@ -71,50 +60,30 @@ use OCP\UserStatus\IManager as IUserStatusManager; */ class ShareAPIControllerTest extends TestCase { - /** @var string */ - private $appName = 'files_sharing'; - - /** @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|\PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; - - /** @var string|\PHPUnit\Framework\MockObject\MockObject */ - private $currentUser; - - /** @var ShareAPIController */ - private $ocs; - - /** @var IL10N|\PHPUnit\Framework\MockObject\MockObject */ - private $l; - - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ - private $config; - - /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */ - private $appManager; - - /** @var IServerContainer|\PHPUnit\Framework\MockObject\MockObject */ - private $serverContainer; - - /** @var IUserStatusManager|\PHPUnit\Framework\MockObject\MockObject */ - private $userStatusManager; - - /** @var IPreview|\PHPUnit\Framework\MockObject\MockObject */ - private $previewManager; + 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); @@ -124,7 +93,7 @@ class ShareAPIControllerTest extends TestCase { ->willReturn(true); $this->shareManager ->expects($this->any()) - ->method('shareProviderExists')->willReturn(true); + ->method('shareProviderExists')->willReturn(true); $this->groupManager = $this->createMock(IGroupManager::class); $this->userManager = $this->createMock(IUserManager::class); $this->request = $this->createMock(IRequest::class); @@ -138,14 +107,21 @@ class ShareAPIControllerTest extends TestCase { 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(IServerContainer::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, @@ -155,18 +131,26 @@ class ShareAPIControllerTest extends TestCase { $this->userManager, $this->rootFolder, $this->urlGenerator, - $this->currentUser, $this->l, $this->config, + $this->appConfig, $this->appManager, $this->serverContainer, $this->userStatusManager, - $this->previewManager + $this->previewManager, + $this->dateTimeZone, + $this->logger, + $this->factory, + $this->mailer, + $this->tagManager, + $this->trustedServers, + $this->currentUser ); + } /** - * @return ShareAPIController|\PHPUnit\Framework\MockObject\MockObject + * @return ShareAPIController&MockObject */ private function mockFormatShare() { return $this->getMockBuilder(ShareAPIController::class) @@ -178,32 +162,56 @@ class ShareAPIControllerTest extends TestCase { $this->userManager, $this->rootFolder, $this->urlGenerator, - $this->currentUser, $this->l, $this->config, + $this->appConfig, $this->appManager, $this->serverContainer, $this->userStatusManager, $this->previewManager, - ])->setMethods(['formatShare']) + $this->dateTimeZone, + $this->logger, + $this->factory, + $this->mailer, + $this->tagManager, + $this->trustedServers, + $this->currentUser, + ])->onlyMethods(['formatShare']) ->getMock(); } private function newShare() { - return \OC::$server->getShareManager()->newShare(); + return Server::get(IManager::class)->newShare(); } - public function testDeleteShareShareNotFound() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); - $this->expectExceptionMessage('Wrong share ID, share doesn\'t exist'); + 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(6)) + ->expects($this->exactly(7)) ->method('getShareById') - ->willReturnCallback(function ($id) { - if ($id === 'ocinternal:42' || $id === 'ocRoomShare:42' || $id === 'ocFederatedSharing:42' || $id === 'ocCircleShare:42' || $id === 'ocMailShare:42' || $id === 'deck:42') { - throw new \OCP\Share\Exceptions\ShareNotFound(); + ->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(); } @@ -214,7 +222,7 @@ class ShareAPIControllerTest extends TestCase { $this->ocs->deleteShare(42); } - public function testDeleteShare() { + public function testDeleteShare(): void { $node = $this->getMockBuilder(File::class)->getMock(); $share = $this->newShare(); @@ -232,7 +240,7 @@ class ShareAPIControllerTest extends TestCase { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $expected = new DataResponse(); $result = $this->ocs->deleteShare(42); @@ -242,15 +250,25 @@ class ShareAPIControllerTest extends TestCase { } - public function testDeleteShareLocked() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); + 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') @@ -264,8 +282,8 @@ class ShareAPIControllerTest extends TestCase { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED) - ->will($this->throwException(new LockedException('mypath'))); + ->with(ILockingProvider::LOCK_SHARED) + ->willThrowException(new LockedException('mypath')); $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteFromSelf', [$share])); $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteShare', [$share])); @@ -276,7 +294,7 @@ class ShareAPIControllerTest extends TestCase { /** * You can always remove a share that was shared with you */ - public function testDeleteShareWithMe() { + public function testDeleteShareWithMe(): void { $node = $this->getMockBuilder(File::class)->getMock(); $share = $this->newShare(); @@ -297,7 +315,7 @@ class ShareAPIControllerTest extends TestCase { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteFromSelf', [$share])); $this->assertTrue($this->invokePrivate($this->ocs, 'canDeleteShare', [$share])); @@ -308,7 +326,7 @@ class ShareAPIControllerTest extends TestCase { /** * You can always delete a share you own */ - public function testDeleteShareOwner() { + public function testDeleteShareOwner(): void { $node = $this->getMockBuilder(File::class)->getMock(); $share = $this->newShare(); @@ -328,7 +346,7 @@ class ShareAPIControllerTest extends TestCase { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteFromSelf', [$share])); $this->assertTrue($this->invokePrivate($this->ocs, 'canDeleteShare', [$share])); @@ -340,8 +358,9 @@ class ShareAPIControllerTest extends TestCase { * You can always delete a share when you own * the file path it belong to */ - public function testDeleteShareFileOwner() { + public function testDeleteShareFileOwner(): void { $node = $this->getMockBuilder(File::class)->getMock(); + $node->method('getId')->willReturn(1); $share = $this->newShare(); $share->setShareOwner($this->currentUser) @@ -360,7 +379,7 @@ class ShareAPIControllerTest extends TestCase { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->assertFalse($this->invokePrivate($this->ocs, 'canDeleteFromSelf', [$share])); $this->assertTrue($this->invokePrivate($this->ocs, 'canDeleteShare', [$share])); @@ -372,8 +391,9 @@ class ShareAPIControllerTest extends TestCase { * You can remove (the mountpoint, not the share) * a share if you're in the group the share is shared with */ - public function testDeleteSharedWithMyGroup() { + public function testDeleteSharedWithMyGroup(): void { $node = $this->getMockBuilder(File::class)->getMock(); + $node->method('getId')->willReturn(1); $share = $this->newShare(); $share->setShareType(IShare::TYPE_GROUP) @@ -388,7 +408,7 @@ class ShareAPIControllerTest extends TestCase { // canDeleteShareFromSelf $user = $this->createMock(IUser::class); - $group = $this->getMockBuilder('OCP\IGroup')->getMock(); + $group = $this->getMockBuilder(IGroup::class)->getMock(); $this->groupManager ->method('get') ->with('group') @@ -403,9 +423,9 @@ class ShareAPIControllerTest extends TestCase { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); - $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); + $userFolder = $this->getMockBuilder(Folder::class)->getMock(); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -431,11 +451,12 @@ class ShareAPIControllerTest extends TestCase { * You cannot remove a share if you're not * in the group the share is shared with */ - public function testDeleteSharedWithGroupIDontBelongTo() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); - $this->expectExceptionMessage('Wrong share ID, share doesn\'t exist'); + 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) @@ -450,7 +471,7 @@ class ShareAPIControllerTest extends TestCase { // canDeleteShareFromSelf $user = $this->createMock(IUser::class); - $group = $this->getMockBuilder('OCP\IGroup')->getMock(); + $group = $this->getMockBuilder(IGroup::class)->getMock(); $this->groupManager ->method('get') ->with('group') @@ -465,9 +486,9 @@ class ShareAPIControllerTest extends TestCase { $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); - $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); + $userFolder = $this->getMockBuilder(Folder::class)->getMock(); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -488,6 +509,63 @@ class ShareAPIControllerTest extends TestCase { $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 @@ -498,14 +576,14 @@ class ShareAPIControllerTest extends TestCase { ->with('ocinternal:42', 'currentUser') ->will($this->throwException(new \OC\Share20\Exception\ShareNotFound())); - $expected = new \OC\OCS\Result(null, 404, 'wrong share ID, share doesn\'t exist.'); + $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 = '') { + $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); @@ -516,6 +594,7 @@ class ShareAPIControllerTest extends TestCase { $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); @@ -525,10 +604,10 @@ class ShareAPIControllerTest extends TestCase { $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); + if ($shareType === IShare::TYPE_USER + || $shareType === IShare::TYPE_GROUP + || $shareType === IShare::TYPE_LINK) { + $share->method('getFullId')->willReturn('ocinternal:' . $id); } return $share; @@ -542,28 +621,38 @@ class ShareAPIControllerTest extends TestCase { ->getMock(); $cache->method('getNumericStorageId')->willReturn(101); - $storage = $this->getMockBuilder(Storage::class) + $storage = $this->getMockBuilder(IStorage::class) ->disableOriginalConstructor() ->getMock(); $storage->method('getId')->willReturn('STORAGE'); $storage->method('getCache')->willReturn($cache); - $parentFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); + $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('OCP\Files\Folder')->getMock(); + $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( @@ -579,7 +668,8 @@ class ShareAPIControllerTest extends TestCase { 6, 'target', 0, - 'personal note' + 'personal note', + $shareAttributes, ); $expected = [ 'id' => 100, @@ -597,6 +687,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'expiration' => null, 'permissions' => 4, + 'attributes' => $shareAttributesReturnJson, 'stime' => 5, 'parent' => null, 'storage_id' => 'STORAGE', @@ -612,7 +703,12 @@ class ShareAPIControllerTest extends TestCase { 'hide_download' => 0, 'can_edit' => false, 'can_delete' => false, - 'status' => [], + 'item_size' => 123465, + 'item_mtime' => 1234567890, + 'attributes' => null, + 'item_permissions' => 4, + 'is-mount-root' => false, + 'mount-type' => '', ]; $data[] = [$share, $expected]; @@ -630,7 +726,8 @@ class ShareAPIControllerTest extends TestCase { 6, 'target', 0, - 'personal note' + 'personal note', + $shareAttributes, ); $expected = [ 'id' => 101, @@ -647,6 +744,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => null, 'expiration' => null, 'permissions' => 4, + 'attributes' => $shareAttributesReturnJson, 'stime' => 5, 'parent' => null, 'storage_id' => 'STORAGE', @@ -662,6 +760,12 @@ class ShareAPIControllerTest extends TestCase { '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]; @@ -702,6 +806,7 @@ class ShareAPIControllerTest extends TestCase { 'token' => 'token', 'expiration' => '2000-01-02 00:00:00', 'permissions' => 4, + 'attributes' => null, 'stime' => 5, 'parent' => null, 'storage_id' => 'STORAGE', @@ -718,35 +823,47 @@ class ShareAPIControllerTest extends TestCase { '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; } - /** - * @dataProvider dataGetShare - */ - public function testGetShare(\OCP\Share\IShare $share, array $result) { - /** @var ShareAPIController|\PHPUnit\Framework\MockObject\MockObject $ocs */ + #[\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->currentUser, - $this->l, - $this->config, - $this->appManager, - $this->serverContainer, - $this->userStatusManager, - $this->previewManager, - ])->setMethods(['canAccessShare']) - ->getMock(); + ->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') @@ -758,7 +875,7 @@ class ShareAPIControllerTest extends TestCase { ->with($share->getFullId(), 'currentUser') ->willReturn($share); - $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); + $userFolder = $this->getMockBuilder(Folder::class)->getMock(); $userFolder ->method('getRelativePath') ->willReturnArgument(0); @@ -766,6 +883,9 @@ class ShareAPIControllerTest extends TestCase { $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) @@ -788,7 +908,7 @@ class ShareAPIControllerTest extends TestCase { $user->method('getDisplayName')->willReturn('userDisplay'); $user->method('getSystemEMailAddress')->willReturn('userId@example.com'); - $group = $this->getMockBuilder('OCP\IGroup')->getMock(); + $group = $this->getMockBuilder(IGroup::class)->getMock(); $group->method('getGID')->willReturn('groupId'); $this->userManager->method('get')->willReturnMap([ @@ -799,18 +919,18 @@ class ShareAPIControllerTest extends TestCase { $this->groupManager->method('get')->willReturnMap([ ['group', $group], ]); + $this->dateTimeZone->method('getTimezone')->willReturn(new \DateTimeZone('UTC')); - $d = $ocs->getShare($share->getId())->getData()[0]; - - $this->assertEquals($result, $ocs->getShare($share->getId())->getData()[0]); + $data = $ocs->getShare($share->getId())->getData()[0]; + $this->assertEquals($result, $data); } - public function testGetShareInvalidNode() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); - $this->expectExceptionMessage('Wrong share ID, share doesn\'t exist'); + public function testGetShareInvalidNode(): void { + $this->expectException(OCSNotFoundException::class); + $this->expectExceptionMessage('Wrong share ID, share does not exist'); - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setSharedBy('initiator') ->setSharedWith('recipient') ->setShareOwner('owner'); @@ -821,7 +941,7 @@ class ShareAPIControllerTest extends TestCase { ->with('ocinternal:42', 'currentUser') ->willReturn($share); - $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); + $userFolder = $this->getMockBuilder(Folder::class)->getMock(); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -841,12 +961,12 @@ class ShareAPIControllerTest extends TestCase { $folder->method('getDirectoryListing') ->willReturn([$file1, $file2]); - $file1UserShareOwner = \OC::$server->getShareManager()->newShare(); + $file1UserShareOwner = Server::get(IManager::class)->newShare(); $file1UserShareOwner->setShareType(IShare::TYPE_USER) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(4); @@ -855,12 +975,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_USER, ]; - $file1UserShareInitiator = \OC::$server->getShareManager()->newShare(); + $file1UserShareInitiator = Server::get(IManager::class)->newShare(); $file1UserShareInitiator->setShareType(IShare::TYPE_USER) ->setSharedWith('recipient') ->setSharedBy('currentUser') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(8); @@ -869,12 +989,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_USER, ]; - $file1UserShareRecipient = \OC::$server->getShareManager()->newShare(); + $file1UserShareRecipient = Server::get(IManager::class)->newShare(); $file1UserShareRecipient->setShareType(IShare::TYPE_USER) ->setSharedWith('currentUser') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(15); @@ -883,12 +1003,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_USER, ]; - $file1UserShareOther = \OC::$server->getShareManager()->newShare(); + $file1UserShareOther = Server::get(IManager::class)->newShare(); $file1UserShareOther->setShareType(IShare::TYPE_USER) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(16); @@ -897,12 +1017,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_USER, ]; - $file1GroupShareOwner = \OC::$server->getShareManager()->newShare(); + $file1GroupShareOwner = Server::get(IManager::class)->newShare(); $file1GroupShareOwner->setShareType(IShare::TYPE_GROUP) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(23); @@ -911,12 +1031,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_GROUP, ]; - $file1GroupShareRecipient = \OC::$server->getShareManager()->newShare(); + $file1GroupShareRecipient = Server::get(IManager::class)->newShare(); $file1GroupShareRecipient->setShareType(IShare::TYPE_GROUP) ->setSharedWith('currentUserGroup') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(42); @@ -925,21 +1045,21 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_GROUP, ]; - $file1GroupShareOther = \OC::$server->getShareManager()->newShare(); + $file1GroupShareOther = Server::get(IManager::class)->newShare(); $file1GroupShareOther->setShareType(IShare::TYPE_GROUP) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(108); - $file1LinkShareOwner = \OC::$server->getShareManager()->newShare(); + $file1LinkShareOwner = Server::get(IManager::class)->newShare(); $file1LinkShareOwner->setShareType(IShare::TYPE_LINK) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(415); @@ -948,12 +1068,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_LINK, ]; - $file1EmailShareOwner = \OC::$server->getShareManager()->newShare(); + $file1EmailShareOwner = Server::get(IManager::class)->newShare(); $file1EmailShareOwner->setShareType(IShare::TYPE_EMAIL) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(416); @@ -962,12 +1082,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_EMAIL, ]; - $file1CircleShareOwner = \OC::$server->getShareManager()->newShare(); + $file1CircleShareOwner = Server::get(IManager::class)->newShare(); $file1CircleShareOwner->setShareType(IShare::TYPE_CIRCLE) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(423); @@ -976,12 +1096,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_CIRCLE, ]; - $file1RoomShareOwner = \OC::$server->getShareManager()->newShare(); + $file1RoomShareOwner = Server::get(IManager::class)->newShare(); $file1RoomShareOwner->setShareType(IShare::TYPE_ROOM) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1) ->setId(442); @@ -990,12 +1110,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_ROOM, ]; - $file1RemoteShareOwner = \OC::$server->getShareManager()->newShare(); + $file1RemoteShareOwner = Server::get(IManager::class)->newShare(); $file1RemoteShareOwner->setShareType(IShare::TYPE_REMOTE) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setExpirationDate(new \DateTime('2000-01-01T01:02:03')) ->setNode($file1) ->setId(815); @@ -1005,12 +1125,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_REMOTE, ]; - $file1RemoteGroupShareOwner = \OC::$server->getShareManager()->newShare(); + $file1RemoteGroupShareOwner = Server::get(IManager::class)->newShare(); $file1RemoteGroupShareOwner->setShareType(IShare::TYPE_REMOTE_GROUP) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setExpirationDate(new \DateTime('2000-01-02T01:02:03')) ->setNode($file1) ->setId(816); @@ -1020,12 +1140,12 @@ class ShareAPIControllerTest extends TestCase { 'share_type' => IShare::TYPE_REMOTE_GROUP, ]; - $file2UserShareOwner = \OC::$server->getShareManager()->newShare(); + $file2UserShareOwner = Server::get(IManager::class)->newShare(); $file2UserShareOwner->setShareType(IShare::TYPE_USER) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file2) ->setId(823); @@ -1348,11 +1468,9 @@ class ShareAPIControllerTest extends TestCase { return $data; } - /** - * @dataProvider dataGetShares - */ - public function testGetShares(array $getSharesParameters, array $shares, array $extraShareTypes, array $expected) { - /** @var \OCA\Files_Sharing\Controller\ShareAPIController $ocs */ + #[\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, @@ -1362,14 +1480,22 @@ class ShareAPIControllerTest extends TestCase { $this->userManager, $this->rootFolder, $this->urlGenerator, - $this->currentUser, $this->l, $this->config, + $this->appConfig, $this->appManager, $this->serverContainer, $this->userStatusManager, $this->previewManager, - ])->setMethods(['formatShare']) + $this->dateTimeZone, + $this->logger, + $this->factory, + $this->mailer, + $this->tagManager, + $this->trustedServers, + $this->currentUser, + ]) + ->onlyMethods(['formatShare']) ->getMock(); $ocs->method('formatShare') @@ -1382,7 +1508,7 @@ class ShareAPIControllerTest extends TestCase { } ); - $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); + $userFolder = $this->getMockBuilder(Folder::class)->getMock(); $userFolder->method('get') ->with('path') ->willReturn($getSharesParameters['path']); @@ -1428,81 +1554,125 @@ class ShareAPIControllerTest extends TestCase { $this->assertEquals($expected, $result->getData()); } - public function testCanAccessShare() { - $share = $this->getMockBuilder(IShare::class)->getMock(); + public function testCanAccessShareAsOwner(): void { + $share = $this->createMock(IShare::class); $share->method('getShareOwner')->willReturn($this->currentUser); $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); + } - $share = $this->getMockBuilder(IShare::class)->getMock(); + public function testCanAccessShareAsSharer(): void { + $share = $this->createMock(IShare::class); $share->method('getSharedBy')->willReturn($this->currentUser); $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); + } - $share = $this->getMockBuilder(IShare::class)->getMock(); + 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])); + } - $file = $this->getMockBuilder(File::class)->getMock(); + public function testCannotAccessLinkShare(): void { + $share = $this->createMock(IShare::class); + $share->method('getShareType')->willReturn(IShare::TYPE_LINK); + $share->method('getNodeId')->willReturn(42); - $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); + $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') - ->will($this->onConsecutiveCalls(\OCP\Constants::PERMISSION_SHARE, \OCP\Constants::PERMISSION_READ)); + ->willReturn($permissions); - // getPermissions -> share - $share = $this->getMockBuilder(IShare::class)->getMock(); - $share->method('getShareType')->willReturn(IShare::TYPE_USER); - $share->method('getSharedWith')->willReturn($this->getMockBuilder(IUser::class)->getMock()); - $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); + if ($expected) { + $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); + } else { + $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); + } + } - // getPermissions -> read - $share = $this->getMockBuilder(IShare::class)->getMock(); - $share->method('getShareType')->willReturn(IShare::TYPE_USER); - $share->method('getSharedWith')->willReturn($this->getMockBuilder(IUser::class)->getMock()); - $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], + ]; + } - $share = $this->getMockBuilder(IShare::class)->getMock(); + #[\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('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->getMockBuilder('OCP\IGroup')->getMock(); + $group = $this->createMock(IGroup::class); $group->method('inGroup')->with($user)->willReturn(true); - $group2 = $this->getMockBuilder('OCP\IGroup')->getMock(); + $group2 = $this->createMock(IGroup::class); $group2->method('inGroup')->with($user)->willReturn(false); $this->groupManager->method('get')->willReturnMap([ ['group', $group], ['group2', $group2], - ['groupnull', null], + ['group-null', null], ]); - $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); - $share = $this->createMock(IShare::class); - $share->method('getShareType')->willReturn(IShare::TYPE_GROUP); - $share->method('getSharedWith')->willReturn('group2'); - $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); - - // null group - $share = $this->createMock(IShare::class); - $share->method('getShareType')->willReturn(IShare::TYPE_GROUP); - $share->method('getSharedWith')->willReturn('groupnull'); - $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); + if ($expected) { + $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); + } else { + $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); + } + } - $share = $this->createMock(IShare::class); - $share->method('getShareType')->willReturn(IShare::TYPE_LINK); - $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); + public static function dataCanAccessShareAsGroupMember(): array { + return [ + ['group', true], + ['group2', false], + ['group-null', false], + ]; } public function dataCanAccessRoomShare() { @@ -1532,15 +1702,15 @@ class ShareAPIControllerTest extends TestCase { } /** - * @dataProvider dataCanAccessRoomShare * * @param bool $expects - * @param \OCP\Share\IShare $share + * @param IShare $share * @param bool helperAvailable * @param bool canAccessShareByHelper */ - public function testCanAccessRoomShare(bool $expected, \OCP\Share\IShare $share, bool $helperAvailable, bool $canAccessShareByHelper) { - $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); + #[\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); @@ -1558,8 +1728,11 @@ class ShareAPIControllerTest extends TestCase { ->with('spreed') ->willReturn(true); - $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') - ->setMethods(['canAccessShare']) + // 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) @@ -1574,16 +1747,16 @@ class ShareAPIControllerTest extends TestCase { } - public function testCreateShareNoPath() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); + public function testCreateShareNoPath(): void { + $this->expectException(OCSNotFoundException::class); $this->expectExceptionMessage('Please specify a file or folder path'); $this->ocs->createShare(); } - public function testCreateShareInvalidPath() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); + public function testCreateShareInvalidPath(): void { + $this->expectException(OCSNotFoundException::class); $this->expectExceptionMessage('Wrong path, file/folder does not exist'); $userFolder = $this->getMockBuilder(Folder::class)->getMock(); @@ -1595,60 +1768,50 @@ class ShareAPIControllerTest extends TestCase { $userFolder->expects($this->once()) ->method('get') ->with('invalid-path') - ->will($this->throwException(new \OCP\Files\NotFoundException())); + ->willThrowException(new NotFoundException()); $this->ocs->createShare('invalid-path'); } - - public function testCreateShareInvalidPermissions() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); - $this->expectExceptionMessage('Invalid permissions'); + public function testCreateShareInvalidShareType(): void { + $this->expectException(OCSBadRequestException::class); + $this->expectExceptionMessage('Unknown share type'); $share = $this->newShare(); $this->shareManager->method('newShare')->willReturn($share); - $userFolder = $this->getMockBuilder(Folder::class)->getMock(); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') - ->with('currentUser') - ->willReturn($userFolder); + [$userFolder, $file] = $this->getNonSharedUserFile(); + $this->rootFolder->expects($this->atLeastOnce()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $userFolder->expects($this->once()) - ->method('get') - ->with('valid-path') - ->willReturn($path); + $userFolder->expects($this->atLeastOnce()) + ->method('get') + ->with('valid-path') + ->willReturn($file); $userFolder->method('getById') ->willReturn([]); - $path->expects($this->once()) + $file->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); - $this->ocs->createShare('valid-path', 32); + $this->ocs->createShare('valid-path', 31); } - - public function testCreateShareUserNoShareWith() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); - $this->expectExceptionMessage('Please specify a valid user'); + 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 = $this->getMockBuilder(Folder::class)->getMock(); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') + [$userFolder, $path] = $this->getNonSharedUserFile(); + $this->rootFolder->method('getUserFolder') ->with('currentUser') ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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') @@ -1658,31 +1821,24 @@ class ShareAPIControllerTest extends TestCase { $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); - $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_USER); + $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_USER); } - public function testCreateShareUserNoValidShareWith() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); - $this->expectExceptionMessage('Please specify a valid 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 = $this->getMockBuilder(Folder::class)->getMock(); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') + [$userFolder, $path] = $this->getNonSharedUserFile(); + $this->rootFolder->method('getUserFolder') ->with('currentUser') ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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') @@ -1691,19 +1847,19 @@ class ShareAPIControllerTest extends TestCase { ->willReturn([]); $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->userManager->method('userExists') ->with('invalidUser') ->willReturn(false); - $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_USER, 'invalidUser'); + $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_USER, 'invalidUser'); } - public function testCreateShareUser() { + public function testCreateShareUser(): void { $share = $this->newShare(); $this->shareManager->method('newShare')->willReturn($share); - /** @var \OCA\Files_Sharing\Controller\ShareAPIController $ocs */ + /** @var ShareAPIController $ocs */ $ocs = $this->getMockBuilder(ShareAPIController::class) ->setConstructorArgs([ $this->appName, @@ -1713,32 +1869,33 @@ class ShareAPIControllerTest extends TestCase { $this->userManager, $this->rootFolder, $this->urlGenerator, - $this->currentUser, $this->l, $this->config, + $this->appConfig, $this->appManager, $this->serverContainer, $this->userStatusManager, $this->previewManager, - ])->setMethods(['formatShare']) + $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->once()) - ->method('getUserFolder') - ->with('currentUser') - ->willReturn($userFolder); + [$userFolder, $path] = $this->getNonSharedUserFile(); + $this->rootFolder->expects($this->exactly(2)) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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); + ->method('get') + ->with('valid-path') + ->willReturn($path); $userFolder->method('getById') ->willReturn([]); @@ -1746,32 +1903,32 @@ class ShareAPIControllerTest extends TestCase { $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('createShare') - ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) { - return $share->getNode() === $path && - $share->getPermissions() === ( - \OCP\Constants::PERMISSION_ALL & - ~\OCP\Constants::PERMISSION_DELETE & - ~\OCP\Constants::PERMISSION_CREATE - ) && - $share->getShareType() === IShare::TYPE_USER && - $share->getSharedWith() === 'validUser' && - $share->getSharedBy() === 'currentUser'; + ->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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_USER, 'validUser'); + $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() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); + public function testCreateShareGroupNoValidShareWith(): void { + $this->expectException(OCSNotFoundException::class); $this->expectExceptionMessage('Please specify a valid group'); $share = $this->newShare(); @@ -1779,37 +1936,30 @@ class ShareAPIControllerTest extends TestCase { $this->shareManager->method('createShare')->willReturnArgument(0); $this->shareManager->method('allowGroupSharing')->willReturn(true); - $userFolder = $this->getMockBuilder(Folder::class)->getMock(); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') - ->with('currentUser') - ->willReturn($userFolder); + [$userFolder, $path] = $this->getNonSharedUserFile(); + $this->rootFolder->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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); + ->method('get') + ->with('valid-path') + ->willReturn($path); $userFolder->method('getById') ->willReturn([]); $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); - $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_GROUP, 'invalidGroup'); + $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_GROUP, 'invalidGroup'); } - public function testCreateShareGroup() { + public function testCreateShareGroup(): void { $share = $this->newShare(); $this->shareManager->method('newShare')->willReturn($share); - /** @var ShareAPIController|\PHPUnit\Framework\MockObject\MockObject $ocs */ + /** @var ShareAPIController&MockObject $ocs */ $ocs = $this->getMockBuilder(ShareAPIController::class) ->setConstructorArgs([ $this->appName, @@ -1819,37 +1969,38 @@ class ShareAPIControllerTest extends TestCase { $this->userManager, $this->rootFolder, $this->urlGenerator, - $this->currentUser, $this->l, $this->config, + $this->appConfig, $this->appManager, $this->serverContainer, $this->userStatusManager, $this->previewManager, - ])->setMethods(['formatShare']) + $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, \OCP\Constants::PERMISSION_ALL], + ['permissions', null, Constants::PERMISSION_ALL], ['shareType', '-1', IShare::TYPE_GROUP], ['shareWith', null, 'validGroup'], ]); - $userFolder = $this->getMockBuilder(Folder::class)->getMock(); - $this->rootFolder->expects($this->once()) + [$userFolder, $path] = $this->getNonSharedUserFolder(); + $this->rootFolder->expects($this->exactly(2)) ->method('getUserFolder') ->with('currentUser') ->willReturn($userFolder); - $path = $this->getMockBuilder(Folder::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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') @@ -1865,45 +2016,38 @@ class ShareAPIControllerTest extends TestCase { $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('createShare') - ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) { - return $share->getNode() === $path && - $share->getPermissions() === \OCP\Constants::PERMISSION_ALL && - $share->getShareType() === IShare::TYPE_GROUP && - $share->getSharedWith() === 'validGroup' && - $share->getSharedBy() === 'currentUser'; + ->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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_GROUP, 'validGroup'); + $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() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); + 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 = $this->getMockBuilder(Folder::class)->getMock(); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') + [$userFolder, $path] = $this->getNonSharedUserFolder(); + $this->rootFolder->method('getUserFolder') ->with('currentUser') ->willReturn($userFolder); - $path = $this->getMockBuilder(Folder::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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') @@ -1917,12 +2061,12 @@ class ShareAPIControllerTest extends TestCase { ->method('allowGroupSharing') ->willReturn(false); - $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_GROUP, 'invalidGroup'); + $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_GROUP, 'invalidGroup'); } - public function testCreateShareLinkNoLinksAllowed() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); + public function testCreateShareLinkNoLinksAllowed(): void { + $this->expectException(OCSNotFoundException::class); $this->expectExceptionMessage('Public link sharing is disabled by the administrator'); $this->request @@ -1933,189 +2077,214 @@ class ShareAPIControllerTest extends TestCase { ]); $path = $this->getMockBuilder(Folder::class)->getMock(); - $storage = $this->createMock(Storage::class); + $path->method('getId')->willReturn(42); + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); + ->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(\OC::$server->getShareManager()->newShare()); + $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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK); + $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK); } - public function testCreateShareLinkNoPublicUpload() { - $this->expectException(\OCP\AppFramework\OCS\OCSForbiddenException::class); + public function testCreateShareLinkNoPublicUpload(): void { + $this->expectException(OCSForbiddenException::class); $this->expectExceptionMessage('Public upload disabled by the administrator'); $path = $this->getMockBuilder(Folder::class)->getMock(); - $storage = $this->createMock(Storage::class); + $path->method('getId')->willReturn(42); + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); + ->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(\OC::$server->getShareManager()->newShare()); + $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare()); $this->shareManager->method('shareApiAllowLinks')->willReturn(true); - $this->ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true'); + $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true'); } - public function testCreateShareLinkPublicUploadFile() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); + public function testCreateShareLinkPublicUploadFile(): void { + $this->expectException(OCSBadRequestException::class); $this->expectExceptionMessage('Public upload is only possible for publicly shared folders'); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); - $path->method('getStorage')->willReturn($storage); + ->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($path); + $this->rootFolder->method('get')->with('valid-path')->willReturn($file); $this->rootFolder->method('getById') ->willReturn([]); - $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); + $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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true'); + $this->ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true'); } - public function testCreateShareLinkPublicUploadFolder() { + public function testCreateShareLinkPublicUploadFolder(): void { $ocs = $this->mockFormatShare(); $path = $this->getMockBuilder(Folder::class)->getMock(); - $storage = $this->createMock(Storage::class); + $path->method('getId')->willReturn(1); + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); + ->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(\OC::$server->getShareManager()->newShare()); + $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 (\OCP\Share\IShare $share) use ($path) { - return $share->getNode() === $path && - $share->getShareType() === IShare::TYPE_LINK && - $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) && - $share->getSharedBy() === 'currentUser' && - $share->getPassword() === null && - $share->getExpirationDate() === null; + $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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true', '', null, ''); + $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() { + public function testCreateShareLinkPassword(): void { $ocs = $this->mockFormatShare(); $path = $this->getMockBuilder(Folder::class)->getMock(); - $storage = $this->createMock(Storage::class); + $path->method('getId')->willReturn(42); + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); + ->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(\OC::$server->getShareManager()->newShare()); + $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 (\OCP\Share\IShare $share) use ($path) { - return $share->getNode() === $path && - $share->getShareType() === IShare::TYPE_LINK && - $share->getPermissions() === \OCP\Constants::PERMISSION_READ && - $share->getSharedBy() === 'currentUser' && - $share->getPassword() === 'password' && - $share->getExpirationDate() === null; + $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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', 'password', null, ''); + $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() { + public function testCreateShareLinkSendPasswordByTalk(): void { $ocs = $this->mockFormatShare(); $path = $this->getMockBuilder(Folder::class)->getMock(); - $storage = $this->createMock(Storage::class); + $path->method('getId')->willReturn(42); + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); + ->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(\OC::$server->getShareManager()->newShare()); + $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 (\OCP\Share\IShare $share) use ($path) { - return $share->getNode() === $path && - $share->getShareType() === IShare::TYPE_LINK && - $share->getPermissions() === \OCP\Constants::PERMISSION_READ && - $share->getSharedBy() === 'currentUser' && - $share->getPassword() === 'password' && - $share->getSendPasswordByTalk() === true && - $share->getExpirationDate() === null; + $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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', 'password', 'true', ''); + $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() { - $this->expectException(\OCP\AppFramework\OCS\OCSForbiddenException::class); + 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(); - $storage = $this->createMock(Storage::class); + $path->method('getId')->willReturn(42); + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); + ->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(); @@ -2123,7 +2292,7 @@ class ShareAPIControllerTest extends TestCase { $this->rootFolder->method('getById') ->willReturn([]); - $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); + $this->shareManager->method('newShare')->willReturn(Server::get(IManager::class)->newShare()); $this->shareManager->method('shareApiAllowLinks')->willReturn(true); $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); @@ -2131,10 +2300,10 @@ class ShareAPIControllerTest extends TestCase { $this->shareManager->expects($this->never())->method('createShare'); - $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', 'password', 'true', ''); + $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', 'password', 'true', ''); } - public function testCreateShareValidExpireDate() { + public function testCreateShareValidExpireDate(): void { $ocs = $this->mockFormatShare(); $this->request @@ -2148,71 +2317,77 @@ class ShareAPIControllerTest extends TestCase { ]); $path = $this->getMockBuilder(Folder::class)->getMock(); - $storage = $this->createMock(Storage::class); + $path->method('getId')->willReturn(42); + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); + ->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(\OC::$server->getShareManager()->newShare()); + $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 (\OCP\Share\IShare $share) use ($path) { + $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() === \OCP\Constants::PERMISSION_READ && - $share->getSharedBy() === 'currentUser' && - $share->getPassword() === null && - $share->getExpirationDate() == $date; + $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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, '2000-01-01'); + $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() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); - $this->expectExceptionMessage('Invalid date, date format must be YYYY-MM-DD'); + 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(); - $storage = $this->createMock(Storage::class); + $path->method('getId')->willReturn(42); + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); + ->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(\OC::$server->getShareManager()->newShare()); + $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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, 'a1b2d3'); + $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, 'a1b2d3'); } - public function testCreateShareRemote() { + public function testCreateShareRemote(): void { $share = $this->newShare(); $this->shareManager->method('newShare')->willReturn($share); - /** @var \OCA\Files_Sharing\Controller\ShareAPIController $ocs */ + /** @var ShareAPIController $ocs */ $ocs = $this->getMockBuilder(ShareAPIController::class) ->setConstructorArgs([ $this->appName, @@ -2222,32 +2397,33 @@ class ShareAPIControllerTest extends TestCase { $this->userManager, $this->rootFolder, $this->urlGenerator, - $this->currentUser, $this->l, $this->config, + $this->appConfig, $this->appManager, $this->serverContainer, $this->userStatusManager, $this->previewManager, - ])->setMethods(['formatShare']) + $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->once()) - ->method('getUserFolder') - ->with('currentUser') - ->willReturn($userFolder); + [$userFolder, $path] = $this->getNonSharedUserFile(); + $this->rootFolder->expects($this->exactly(2)) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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); + ->method('get') + ->with('valid-path') + ->willReturn($path); $userFolder->method('getById') ->willReturn([]); @@ -2255,36 +2431,36 @@ class ShareAPIControllerTest extends TestCase { $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('createShare') - ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) { - return $share->getNode() === $path && - $share->getPermissions() === ( - \OCP\Constants::PERMISSION_ALL & - ~\OCP\Constants::PERMISSION_DELETE & - ~\OCP\Constants::PERMISSION_CREATE - ) && - $share->getShareType() === IShare::TYPE_REMOTE && - $share->getSharedWith() === 'user@example.org' && - $share->getSharedBy() === 'currentUser'; + ->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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_REMOTE, 'user@example.org'); + $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() { + public function testCreateShareRemoteGroup(): void { $share = $this->newShare(); $this->shareManager->method('newShare')->willReturn($share); - /** @var \OCA\Files_Sharing\Controller\ShareAPIController $ocs */ + /** @var ShareAPIController $ocs */ $ocs = $this->getMockBuilder(ShareAPIController::class) ->setConstructorArgs([ $this->appName, @@ -2294,32 +2470,33 @@ class ShareAPIControllerTest extends TestCase { $this->userManager, $this->rootFolder, $this->urlGenerator, - $this->currentUser, $this->l, $this->config, + $this->appConfig, $this->appManager, $this->serverContainer, $this->userStatusManager, $this->previewManager, - ])->setMethods(['formatShare']) + $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->once()) - ->method('getUserFolder') - ->with('currentUser') - ->willReturn($userFolder); + [$userFolder, $path] = $this->getNonSharedUserFile(); + $this->rootFolder->expects($this->exactly(2)) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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); + ->method('get') + ->with('valid-path') + ->willReturn($path); $userFolder->method('getById') ->willReturn([]); @@ -2327,83 +2504,76 @@ class ShareAPIControllerTest extends TestCase { $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('createShare') - ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) { - return $share->getNode() === $path && - $share->getPermissions() === ( - \OCP\Constants::PERMISSION_ALL & - ~\OCP\Constants::PERMISSION_DELETE & - ~\OCP\Constants::PERMISSION_CREATE - ) && - $share->getShareType() === IShare::TYPE_REMOTE_GROUP && - $share->getSharedWith() === 'group@example.org' && - $share->getSharedBy() === 'currentUser'; + ->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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_REMOTE_GROUP, 'group@example.org'); + $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() { + public function testCreateShareRoom(): void { $ocs = $this->mockFormatShare(); $share = $this->newShare(); $this->shareManager->method('newShare')->willReturn($share); - $userFolder = $this->getMockBuilder(Folder::class)->getMock(); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') - ->with('currentUser') - ->willReturn($userFolder); + [$userFolder, $path] = $this->getNonSharedUserFile(); + $this->rootFolder->expects($this->exactly(2)) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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); + ->method('get') + ->with('valid-path') + ->willReturn($path); $userFolder->method('getById') ->willReturn([]); $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->appManager->method('isEnabledForUser') ->with('spreed') ->willReturn(true); - $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') - ->setMethods(['createShare']) + // 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', - \OCP\Constants::PERMISSION_ALL & - ~\OCP\Constants::PERMISSION_DELETE & - ~\OCP\Constants::PERMISSION_CREATE, + Constants::PERMISSION_ALL + & ~Constants::PERMISSION_DELETE + & ~Constants::PERMISSION_CREATE, '' )->willReturnCallback( - function ($share) { + function ($share): void { $share->setSharedWith('recipientRoom'); - $share->setPermissions( - \OCP\Constants::PERMISSION_ALL & - ~\OCP\Constants::PERMISSION_DELETE & - ~\OCP\Constants::PERMISSION_CREATE - ); + $share->setPermissions(Constants::PERMISSION_ALL); } ); @@ -2412,29 +2582,25 @@ class ShareAPIControllerTest extends TestCase { ->willReturn($helper); $this->shareManager->method('createShare') - ->with($this->callback(function (\OCP\Share\IShare $share) use ($path) { - return $share->getNode() === $path && - $share->getPermissions() === ( - \OCP\Constants::PERMISSION_ALL & - ~\OCP\Constants::PERMISSION_DELETE & - ~\OCP\Constants::PERMISSION_CREATE - ) && - $share->getShareType() === IShare::TYPE_ROOM && - $share->getSharedWith() === 'recipientRoom' && - $share->getSharedBy() === 'currentUser'; + ->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', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_ROOM, 'recipientRoom'); + $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() { - $this->expectException(\OCP\AppFramework\OCS\OCSForbiddenException::class); + 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(); @@ -2442,29 +2608,22 @@ class ShareAPIControllerTest extends TestCase { $share = $this->newShare(); $this->shareManager->method('newShare')->willReturn($share); - $userFolder = $this->getMockBuilder(Folder::class)->getMock(); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') - ->with('currentUser') - ->willReturn($userFolder); + [$userFolder, $path] = $this->getNonSharedUserFolder(); + $this->rootFolder->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); - $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(false); - $path->method('getStorage')->willReturn($storage); $path->method('getPath')->willReturn('valid-path'); $userFolder->expects($this->once()) - ->method('get') - ->with('valid-path') - ->willReturn($path); + ->method('get') + ->with('valid-path') + ->willReturn($path); $userFolder->method('getById') ->willReturn([]); $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->appManager->method('isEnabledForUser') ->with('spreed') @@ -2472,60 +2631,55 @@ class ShareAPIControllerTest extends TestCase { $this->shareManager->expects($this->never())->method('createShare'); - $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_ROOM, 'recipientRoom'); + $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_ROOM, 'recipientRoom'); } - public function testCreateShareRoomHelperThrowException() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); + 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 = $this->getMockBuilder(Folder::class)->getMock(); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') - ->with('currentUser') - ->willReturn($userFolder); + [$userFolder, $path] = $this->getNonSharedUserFile(); + $this->rootFolder->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); - $path = $this->getMockBuilder(File::class)->getMock(); - $storage = $this->createMock(Storage::class); - $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); + ->method('get') + ->with('valid-path') + ->willReturn($path); $userFolder->method('getById') ->willReturn([]); $path->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->appManager->method('isEnabledForUser') ->with('spreed') ->willReturn(true); - $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') - ->setMethods(['createShare']) + // 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', - \OCP\Constants::PERMISSION_ALL & - ~\OCP\Constants::PERMISSION_DELETE & - ~\OCP\Constants::PERMISSION_CREATE, + Constants::PERMISSION_ALL & ~(Constants::PERMISSION_CREATE | Constants::PERMISSION_DELETE), '' )->willReturnCallback( - function ($share) { - throw new OCSNotFoundException("Exception thrown by the helper"); + function ($share): void { + throw new OCSNotFoundException('Exception thrown by the helper'); } ); @@ -2535,18 +2689,18 @@ class ShareAPIControllerTest extends TestCase { $this->shareManager->expects($this->never())->method('createShare'); - $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_ROOM, 'recipientRoom'); + $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() { - $share = \OC::$server->getShareManager()->newShare(); + public function testCreateReshareOfFederatedMountNoDeletePermissions(): void { + $share = Server::get(IManager::class)->newShare(); $this->shareManager->method('newShare')->willReturn($share); - /** @var ShareAPIController|\PHPUnit\Framework\MockObject\MockObject $ocs */ + /** @var ShareAPIController&MockObject $ocs */ $ocs = $this->getMockBuilder(ShareAPIController::class) ->setConstructorArgs([ $this->appName, @@ -2556,29 +2710,42 @@ class ShareAPIControllerTest extends TestCase { $this->userManager, $this->rootFolder, $this->urlGenerator, - $this->currentUser, $this->l, $this->config, + $this->appConfig, $this->appManager, $this->serverContainer, $this->userStatusManager, $this->previewManager, - ])->setMethods(['formatShare']) + $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->once()) + $this->rootFolder->expects($this->exactly(2)) ->method('getUserFolder') ->with('currentUser') ->willReturn($userFolder); $path = $this->getMockBuilder(Folder::class)->getMock(); - $storage = $this->createMock(Storage::class); + $path->method('getId')->willReturn(42); + + $storage = $this->createMock(IStorage::class); $storage->method('instanceOfStorage') - ->with('OCA\Files_Sharing\External\Storage') - ->willReturn(true); + ->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(\OCP\Constants::PERMISSION_READ); + + $path->method('getPermissions')->willReturn(Constants::PERMISSION_READ); $userFolder->expects($this->once()) ->method('get') ->with('valid-path') @@ -2591,30 +2758,29 @@ class ShareAPIControllerTest extends TestCase { $this->shareManager ->expects($this->once()) ->method('createShare') - ->with($this->callback(function (\OCP\Share\IShare $share) { - return $share->getPermissions() === \OCP\Constants::PERMISSION_READ; + ->with($this->callback(function (IShare $share) { + return $share->getPermissions() === Constants::PERMISSION_READ; })) ->willReturnArgument(0); - $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, IShare::TYPE_USER, 'validUser'); + $ocs->createShare('valid-path', Constants::PERMISSION_ALL, IShare::TYPE_USER, 'validUser'); } - public function testUpdateShareCantAccess() { - $this->expectException(\OCP\AppFramework\OCS\OCSNotFoundException::class); - $this->expectExceptionMessage('Wrong share ID, share doesn\'t exist'); + public function testUpdateShareCantAccess(): void { + $this->expectException(OCSNotFoundException::class); + $this->expectExceptionMessage('Wrong share ID, share does not exist'); - $node = $this->getMockBuilder(Folder::class)->getMock(); + [$userFolder, $node] = $this->getNonSharedUserFolder(); $share = $this->newShare(); $share->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); - $userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock(); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -2627,20 +2793,20 @@ class ShareAPIControllerTest extends TestCase { } - public function testUpdateNoParametersLink() { - $this->expectException(\OCP\AppFramework\OCS\OCSBadRequestException::class); + 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(\OCP\Constants::PERMISSION_ALL) + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); @@ -2648,34 +2814,34 @@ class ShareAPIControllerTest extends TestCase { } - public function testUpdateNoParametersOther() { - $this->expectException(\OCP\AppFramework\OCS\OCSBadRequestException::class); + 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(\OCP\Constants::PERMISSION_ALL) + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_GROUP) ->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->ocs->updateShare(42); } - public function testUpdateLinkShareClear() { + public function testUpdateLinkShareClear(): void { $ocs = $this->mockFormatShare(); - $node = $this->getMockBuilder(Folder::class)->getMock(); + [$userFolder, $node] = $this->getNonSharedUserFolder(); $node->method('getId') ->willReturn(42); $share = $this->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -2683,32 +2849,31 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPermissions(Constants::PERMISSION_ALL) ->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $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 && + $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; + && $share->getNote() === '' + && $share->getLabel() === '' + && $share->getHideDownload() === false; }) )->willReturnArgument(0); $this->shareManager->method('getSharedWith') ->willReturn([]); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -2716,6 +2881,9 @@ class ShareAPIControllerTest extends TestCase { $userFolder->method('getById') ->with(42) ->willReturn([$node]); + $userFolder->method('getFirstNodeById') + ->with(42) + ->willReturn($node); $mountPoint = $this->createMock(IMountPoint::class); $node->method('getMountPoint') @@ -2730,15 +2898,15 @@ class ShareAPIControllerTest extends TestCase { $this->assertEquals($expected->getData(), $result->getData()); } - public function testUpdateLinkShareSet() { + public function testUpdateLinkShareSet(): void { $ocs = $this->mockFormatShare(); - $folder = $this->getMockBuilder(Folder::class)->getMock(); + [$userFolder, $folder] = $this->getNonSharedUserFolder(); $folder->method('getId') ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share = Server::get(IManager::class)->newShare(); + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setNode($folder); @@ -2747,23 +2915,22 @@ class ShareAPIControllerTest extends TestCase { $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); $this->shareManager->expects($this->once())->method('updateShare')->with( - $this->callback(function (\OCP\Share\IShare $share) { + $this->callback(function (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_UPDATE | \OCP\Constants::PERMISSION_DELETE) && - $share->getPassword() === 'password' && - $share->getExpirationDate() == $date && - $share->getNote() === 'note' && - $share->getLabel() === 'label' && - $share->getHideDownload() === true; + $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([]); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -2785,18 +2952,16 @@ class ShareAPIControllerTest extends TestCase { $this->assertEquals($expected->getData(), $result->getData()); } - /** - * @dataProvider publicUploadParamsProvider - */ - public function testUpdateLinkShareEnablePublicUpload($permissions, $publicUpload, $expireDate, $password) { + #[\PHPUnit\Framework\Attributes\DataProvider('publicUploadParamsProvider')] + public function testUpdateLinkShareEnablePublicUpload($permissions, $publicUpload, $expireDate, $password): void { $ocs = $this->mockFormatShare(); - $folder = $this->getMockBuilder(Folder::class)->getMock(); + [$userFolder, $folder] = $this->getNonSharedUserFolder(); $folder->method('getId') ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share = Server::get(IManager::class)->newShare(); + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -2807,14 +2972,13 @@ class ShareAPIControllerTest extends TestCase { $this->shareManager->method('getSharedWith')->willReturn([]); $this->shareManager->expects($this->once())->method('updateShare')->with( - $this->callback(function (\OCP\Share\IShare $share) { - return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) && - $share->getPassword() === 'password' && - $share->getExpirationDate() === null; + $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); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -2837,28 +3001,26 @@ class ShareAPIControllerTest extends TestCase { } - public function publicLinkValidPermissionsProvider() { + public static function publicLinkValidPermissionsProvider() { return [ - [\OCP\Constants::PERMISSION_CREATE], - [\OCP\Constants::PERMISSION_READ], - [\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE], - [\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_DELETE], - [\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE], + [Constants::PERMISSION_CREATE], + [Constants::PERMISSION_READ], + [Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE], + [Constants::PERMISSION_READ | Constants::PERMISSION_DELETE], + [Constants::PERMISSION_READ | Constants::PERMISSION_CREATE], ]; } - /** - * @dataProvider publicLinkValidPermissionsProvider - */ - public function testUpdateLinkShareSetCRUDPermissions($permissions) { + #[\PHPUnit\Framework\Attributes\DataProvider('publicLinkValidPermissionsProvider')] + public function testUpdateLinkShareSetCRUDPermissions($permissions): void { $ocs = $this->mockFormatShare(); - $folder = $this->getMockBuilder(Folder::class)->getMock(); + [$userFolder, $folder] = $this->getNonSharedUserFolder(); $folder->method('getId') ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share = Server::get(IManager::class)->newShare(); + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -2873,7 +3035,6 @@ class ShareAPIControllerTest extends TestCase { ->method('updateShare') ->willReturnArgument(0); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -2889,57 +3050,61 @@ class ShareAPIControllerTest extends TestCase { ->willReturn(42); $expected = new DataResponse([]); - $result = $ocs->updateShare(42, $permissions, 'password', null, 'true', null); + $result = $ocs->updateShare(42, $permissions, 'password', null, null, null); $this->assertInstanceOf(get_class($expected), $result); $this->assertEquals($expected->getData(), $result->getData()); } - public function publicLinkInvalidPermissionsProvider1() { + public static function publicLinkInvalidPermissionsProvider1() { return [ - [\OCP\Constants::PERMISSION_DELETE], - [\OCP\Constants::PERMISSION_UPDATE], - [\OCP\Constants::PERMISSION_SHARE], + [Constants::PERMISSION_DELETE], + [Constants::PERMISSION_UPDATE], + [Constants::PERMISSION_SHARE], ]; } - /** - * @dataProvider publicLinkInvalidPermissionsProvider1 - */ - public function testUpdateLinkShareSetInvalidCRUDPermissions1($permissions) { - $this->expectException(\OCP\AppFramework\OCS\OCSBadRequestException::class); + #[\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); + $this->testUpdateLinkShareSetCRUDPermissions($permissions, null); } - public function publicLinkInvalidPermissionsProvider2() { + public static function publicLinkInvalidPermissionsProvider2() { return [ - [\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE], - [\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE], + [Constants::PERMISSION_CREATE | Constants::PERMISSION_DELETE], + [Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE], ]; } - /** - * @dataProvider publicLinkInvalidPermissionsProvider2 - */ - public function testUpdateLinkShareSetInvalidCRUDPermissions2($permissions) { - $this->expectException(\OCP\AppFramework\OCS\OCSBadRequestException::class); + #[\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() { - $this->expectException(\OCP\AppFramework\OCS\OCSBadRequestException::class); + 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 = $this->getMockBuilder(Folder::class)->getMock(); + $folder->method('getId') + ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share = Server::get(IManager::class)->newShare(); + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setNode($folder); @@ -2950,35 +3115,40 @@ class ShareAPIControllerTest extends TestCase { $ocs->updateShare(42, null, 'password', null, 'true', '2000-01-a'); } - public function publicUploadParamsProvider() { + public static function publicUploadParamsProvider() { return [ [null, 'true', null, 'password'], // legacy had no delete [ - \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE, - null, null, 'password' + Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, + 'true', null, 'password' ], // correct [ - \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE, + Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, null, null, 'password' ], ]; } - /** - * @dataProvider publicUploadParamsProvider - */ - public function testUpdateLinkSharePublicUploadNotAllowed($permissions, $publicUpload, $expireDate, $password) { - $this->expectException(\OCP\AppFramework\OCS\OCSForbiddenException::class); + #[\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 = $this->getMockBuilder(Folder::class)->getMock(); + $folder->method('getId')->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share = Server::get(IManager::class)->newShare(); + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setNode($folder); @@ -2990,35 +3160,60 @@ class ShareAPIControllerTest extends TestCase { } - public function testUpdateLinkSharePublicUploadOnFile() { - $this->expectException(\OCP\AppFramework\OCS\OCSBadRequestException::class); + 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 = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $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('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() { + public function testUpdateLinkSharePasswordDoesNotChangeOther(): void { $ocs = $this->mockFormatShare(); $date = new \DateTime('2000-01-01'); - $date->setTime(0,0,0); + $date->setTime(0, 0, 0); - $node = $this->getMockBuilder(File::class)->getMock(); + [$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(\OCP\Constants::PERMISSION_ALL) + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -3027,24 +3222,24 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPermissions(Constants::PERMISSION_ALL) ->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $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->getSendPasswordByTalk() === true && - $share->getExpirationDate() === $date && - $share->getNote() === 'note' && - $share->getLabel() === 'label' && - $share->getHideDownload() === true; + $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); @@ -3055,15 +3250,22 @@ class ShareAPIControllerTest extends TestCase { $this->assertEquals($expected->getData(), $result->getData()); } - public function testUpdateLinkShareSendPasswordByTalkDoesNotChangeOther() { + public function testUpdateLinkShareSendPasswordByTalkDoesNotChangeOther(): void { $ocs = $this->mockFormatShare(); $date = new \DateTime('2000-01-01'); - $date->setTime(0,0,0); + $date->setTime(0, 0, 0); - $node = $this->getMockBuilder(File::class)->getMock(); + [$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(\OCP\Constants::PERMISSION_ALL) + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -3072,26 +3274,26 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPermissions(Constants::PERMISSION_ALL) ->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->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 (\OCP\Share\IShare $share) use ($date) { - return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL && - $share->getPassword() === 'password' && - $share->getSendPasswordByTalk() === true && - $share->getExpirationDate() === $date && - $share->getNote() === 'note' && - $share->getLabel() === 'label' && - $share->getHideDownload() === true; + $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); @@ -3103,18 +3305,25 @@ class ShareAPIControllerTest extends TestCase { } - public function testUpdateLinkShareSendPasswordByTalkWithTalkDisabledDoesNotChangeOther() { - $this->expectException(\OCP\AppFramework\OCS\OCSForbiddenException::class); + 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); + $date->setTime(0, 0, 0); - $node = $this->getMockBuilder(File::class)->getMock(); + [$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(\OCP\Constants::PERMISSION_ALL) + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -3123,12 +3332,12 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPermissions(Constants::PERMISSION_ALL) ->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); @@ -3139,15 +3348,22 @@ class ShareAPIControllerTest extends TestCase { $ocs->updateShare(42, null, null, 'true', null, null, null, null, null); } - public function testUpdateLinkShareDoNotSendPasswordByTalkDoesNotChangeOther() { + public function testUpdateLinkShareDoNotSendPasswordByTalkDoesNotChangeOther(): void { $ocs = $this->mockFormatShare(); $date = new \DateTime('2000-01-01'); - $date->setTime(0,0,0); + $date->setTime(0, 0, 0); - $node = $this->getMockBuilder(File::class)->getMock(); + [$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(\OCP\Constants::PERMISSION_ALL) + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -3156,26 +3372,26 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPermissions(Constants::PERMISSION_ALL) ->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->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 (\OCP\Share\IShare $share) use ($date) { - return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL && - $share->getPassword() === 'password' && - $share->getSendPasswordByTalk() === false && - $share->getExpirationDate() === $date && - $share->getNote() === 'note' && - $share->getLabel() === 'label' && - $share->getHideDownload() === true; + $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); @@ -3186,18 +3402,18 @@ class ShareAPIControllerTest extends TestCase { $this->assertEquals($expected->getData(), $result->getData()); } - public function testUpdateLinkShareDoNotSendPasswordByTalkWithTalkDisabledDoesNotChangeOther() { + public function testUpdateLinkShareDoNotSendPasswordByTalkWithTalkDisabledDoesNotChangeOther(): void { $ocs = $this->mockFormatShare(); $date = new \DateTime('2000-01-01'); - $date->setTime(0,0,0); + $date->setTime(0, 0, 0); - $node = $this->getMockBuilder(File::class)->getMock(); + [$userFolder, $node] = $this->getNonSharedUserFolder(); $node->method('getId') ->willReturn(42); $share = $this->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -3206,30 +3422,29 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPermissions(Constants::PERMISSION_ALL) ->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->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 (\OCP\Share\IShare $share) use ($date) { - return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL && - $share->getPassword() === 'password' && - $share->getSendPasswordByTalk() === false && - $share->getExpirationDate() === $date && - $share->getNote() === 'note' && - $share->getLabel() === 'label' && - $share->getHideDownload() === true; + $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); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -3257,15 +3472,15 @@ class ShareAPIControllerTest extends TestCase { $this->assertEquals($expected->getData(), $result->getData()); } - public function testUpdateLinkShareExpireDateDoesNotChangeOther() { + public function testUpdateLinkShareExpireDateDoesNotChangeOther(): void { $ocs = $this->mockFormatShare(); - $node = $this->getMockBuilder(File::class)->getMock(); + [$userFolder, $node] = $this->getNonSharedUserFolder(); $node->method('getId') ->willReturn(42); $share = $this->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -3274,31 +3489,30 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPermissions(Constants::PERMISSION_ALL) ->setNode($node); $node->expects($this->once()) ->method('lock') - ->with(\OCP\Lock\ILockingProvider::LOCK_SHARED); + ->with(ILockingProvider::LOCK_SHARED); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); $this->shareManager->expects($this->once())->method('updateShare')->with( - $this->callback(function (\OCP\Share\IShare $share) { + $this->callback(function (IShare $share) { $date = new \DateTime('2010-12-23'); - $date->setTime(0,0,0); - - return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL && - $share->getPassword() === 'password' && - $share->getSendPasswordByTalk() === true && - $share->getExpirationDate() == $date && - $share->getNote() === 'note' && - $share->getLabel() === 'label' && - $share->getHideDownload() === true; + $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); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -3320,17 +3534,17 @@ class ShareAPIControllerTest extends TestCase { $this->assertEquals($expected->getData(), $result->getData()); } - public function testUpdateLinkSharePublicUploadDoesNotChangeOther() { + public function testUpdateLinkSharePublicUploadDoesNotChangeOther(): void { $ocs = $this->mockFormatShare(); $date = new \DateTime('2000-01-01'); - $folder = $this->getMockBuilder(Folder::class)->getMock(); + [$userFolder, $folder] = $this->getNonSharedUserFolder(); $folder->method('getId') ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share = Server::get(IManager::class)->newShare(); + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -3339,28 +3553,27 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->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 (\OCP\Share\IShare $share) use ($date) { - return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) && - $share->getPassword() === 'password' && - $share->getSendPasswordByTalk() === true && - $share->getExpirationDate() === $date && - $share->getNote() === 'note' && - $share->getLabel() === 'label' && - $share->getHideDownload() === true; + $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([]); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -3382,17 +3595,17 @@ class ShareAPIControllerTest extends TestCase { $this->assertEquals($expected->getData(), $result->getData()); } - public function testUpdateLinkSharePermissions() { + public function testUpdateLinkSharePermissions(): void { $ocs = $this->mockFormatShare(); $date = new \DateTime('2000-01-01'); - $folder = $this->getMockBuilder(Folder::class)->getMock(); + [$userFolder, $folder] = $this->getNonSharedUserFolder(); $folder->method('getId') ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share = Server::get(IManager::class)->newShare(); + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -3401,27 +3614,26 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->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 (\OCP\Share\IShare $share) use ($date) { - return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE) && - $share->getPassword() === 'password' && - $share->getSendPasswordByTalk() === true && - $share->getExpirationDate() === $date && - $share->getNote() === 'note' && - $share->getLabel() === 'label' && - $share->getHideDownload() === true; + $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([]); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -3437,23 +3649,23 @@ class ShareAPIControllerTest extends TestCase { ->willReturn(42); $expected = new DataResponse([]); - $result = $ocs->updateShare(42, 7, null, null, null, null, null, null, null); + $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() { + public function testUpdateLinkSharePermissionsShare(): void { $ocs = $this->mockFormatShare(); $date = new \DateTime('2000-01-01'); - $folder = $this->getMockBuilder(Folder::class)->getMock(); + [$userFolder, $folder] = $this->getNonSharedUserFolder(); $folder->method('getId') ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share = Server::get(IManager::class)->newShare(); + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_LINK) ->setPassword('password') @@ -3462,25 +3674,26 @@ class ShareAPIControllerTest extends TestCase { ->setNote('note') ->setLabel('label') ->setHideDownload(true) - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->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 (\OCP\Share\IShare $share) use ($date) { - return $share->getPermissions() === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\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->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); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -3498,21 +3711,21 @@ class ShareAPIControllerTest extends TestCase { $this->shareManager->method('getSharedWith')->willReturn([]); $expected = new DataResponse([]); - $result = $ocs->updateShare(42, 31, null, null, null, null, null, null, null); + $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() { + public function testUpdateOtherPermissions(): void { $ocs = $this->mockFormatShare(); - $file = $this->getMockBuilder(File::class)->getMock(); + [$userFolder, $file] = $this->getNonSharedUserFolder(); $file->method('getId') ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); - $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + $share = Server::get(IManager::class)->newShare(); + $share->setPermissions(Constants::PERMISSION_ALL) ->setSharedBy($this->currentUser) ->setShareType(IShare::TYPE_USER) ->setNode($file); @@ -3521,14 +3734,14 @@ class ShareAPIControllerTest extends TestCase { $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; + $this->callback(function (IShare $share) { + return $share->getPermissions() === Constants::PERMISSION_ALL; }) )->willReturnArgument(0); $this->shareManager->method('getSharedWith')->willReturn([]); - $userFolder = $this->createMock(Folder::class); + [$userFolder, $folder] = $this->getNonSharedUserFolder(); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -3550,33 +3763,33 @@ class ShareAPIControllerTest extends TestCase { $this->assertEquals($expected->getData(), $result->getData()); } - public function testUpdateShareCannotIncreasePermissions() { + public function testUpdateShareCannotIncreasePermissions(): void { $ocs = $this->mockFormatShare(); - $folder = $this->createMock(Folder::class); + [$userFolder, $folder] = $this->getNonSharedUserFolder(); $folder->method('getId') ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share ->setId(42) ->setSharedBy($this->currentUser) ->setShareOwner('anotheruser') ->setShareType(IShare::TYPE_GROUP) ->setSharedWith('group1') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->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 = \OC::$server->getShareManager()->newShare(); + $incomingShare = Server::get(IManager::class)->newShare(); $incomingShare ->setId(42) ->setSharedBy($this->currentUser) ->setShareOwner('anotheruser') ->setShareType(IShare::TYPE_GROUP) ->setSharedWith('group1') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder); $this->request @@ -3595,7 +3808,6 @@ class ShareAPIControllerTest extends TestCase { ['currentUser', IShare::TYPE_ROOM, $share->getNode(), -1, 0, []] ]); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -3603,6 +3815,9 @@ class ShareAPIControllerTest extends TestCase { $userFolder->method('getById') ->with(42) ->willReturn([$folder]); + $userFolder->method('getFirstNodeById') + ->with(42) + ->willReturn($folder); $mountPoint = $this->createMock(IMountPoint::class); $folder->method('getMountPoint') @@ -3623,33 +3838,33 @@ class ShareAPIControllerTest extends TestCase { } } - public function testUpdateShareCanIncreasePermissionsIfOwner() { + public function testUpdateShareCanIncreasePermissionsIfOwner(): void { $ocs = $this->mockFormatShare(); - $folder = $this->createMock(Folder::class); + [$userFolder, $folder] = $this->getNonSharedUserFolder(); $folder->method('getId') ->willReturn(42); - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share ->setId(42) ->setSharedBy($this->currentUser) ->setShareOwner($this->currentUser) ->setShareType(IShare::TYPE_GROUP) ->setSharedWith('group1') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->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 = \OC::$server->getShareManager()->newShare(); + $incomingShare = Server::get(IManager::class)->newShare(); $incomingShare ->setId(42) ->setSharedBy($this->currentUser) ->setShareOwner($this->currentUser) ->setShareType(IShare::TYPE_GROUP) ->setSharedWith('group1') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder); $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); @@ -3666,7 +3881,6 @@ class ShareAPIControllerTest extends TestCase { ->with($share) ->willReturn($share); - $userFolder = $this->createMock(Folder::class); $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturn($userFolder); @@ -3685,6 +3899,64 @@ class ShareAPIControllerTest extends TestCase { $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(); @@ -3695,6 +3967,12 @@ class ShareAPIControllerTest extends TestCase { $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'); @@ -3708,9 +3986,16 @@ class ShareAPIControllerTest extends TestCase { $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(Storage::class); + $storage = $this->createMock(IStorage::class); $storage->method('getId')->willReturn('storageId'); $storage->method('getCache')->willReturn($cache); @@ -3718,6 +4003,12 @@ class ShareAPIControllerTest extends TestCase { $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(); @@ -3725,16 +4016,17 @@ class ShareAPIControllerTest extends TestCase { $recipient = $this->getMockBuilder(IUser::class)->getMock(); $recipient->method('getDisplayName')->willReturn('recipientDN'); $recipient->method('getSystemEMailAddress')->willReturn('recipient'); - + [$shareAttributes, $shareAttributesReturnJson] = $this->mockShareAttributes(); $result = []; - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_USER) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) + ->setAttributes($shareAttributes) ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -3744,11 +4036,12 @@ class ShareAPIControllerTest extends TestCase { // User backend down $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_USER, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', 'permissions' => 1, + 'attributes' => $shareAttributesReturnJson, 'stime' => 946684862, 'parent' => null, 'expiration' => null, @@ -3767,24 +4060,30 @@ class ShareAPIControllerTest extends TestCase { 'share_with_displayname' => 'recipient', 'share_with_displayname_unique' => 'recipient', 'note' => 'personal note', - 'label' => null, + 'label' => '', 'mail_send' => 0, 'mimetype' => 'myMimeType', 'has_preview' => false, 'hide_download' => 0, 'can_edit' => false, 'can_delete' => false, - 'status' => [], + '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, + 'id' => '42', 'share_type' => IShare::TYPE_USER, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiatorDN', 'permissions' => 1, + 'attributes' => $shareAttributesReturnJson, 'stime' => 946684862, 'parent' => null, 'expiration' => null, @@ -3792,7 +4091,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'ownerDN', 'note' => 'personal note', - 'label' => null, + 'label' => '', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -3810,7 +4109,12 @@ class ShareAPIControllerTest extends TestCase { 'hide_download' => 0, 'can_edit' => false, 'can_delete' => false, - 'status' => [], + '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], @@ -3818,12 +4122,12 @@ class ShareAPIControllerTest extends TestCase { ], false ]; - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_USER) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -3832,11 +4136,12 @@ class ShareAPIControllerTest extends TestCase { // User backend down $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_USER, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', 'permissions' => 1, + 'attributes' => null, 'stime' => 946684862, 'parent' => null, 'expiration' => null, @@ -3844,7 +4149,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => 'personal note', - 'label' => null, + 'label' => '', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -3862,16 +4167,21 @@ class ShareAPIControllerTest extends TestCase { 'hide_download' => 0, 'can_edit' => false, 'can_delete' => false, - 'status' => [], + 'item_size' => 123456, + 'item_mtime' => 1234567890, + 'is-mount-root' => false, + 'mount-type' => '', + 'attributes' => null, + 'item_permissions' => 1, ], $share, [], false ]; - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_USER) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -3880,11 +4190,12 @@ class ShareAPIControllerTest extends TestCase { // User backend down $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_USER, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', 'permissions' => 1, + 'attributes' => null, 'stime' => 946684862, 'parent' => null, 'expiration' => null, @@ -3892,7 +4203,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'currentUser', 'displayname_file_owner' => 'currentUser', 'note' => 'personal note', - 'label' => null, + 'label' => '', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -3910,18 +4221,23 @@ class ShareAPIControllerTest extends TestCase { 'hide_download' => 0, 'can_edit' => true, 'can_delete' => true, - 'status' => [], + 'item_size' => 123456, + 'item_mtime' => 1234567890, + 'is-mount-root' => false, + 'mount-type' => '', + 'attributes' => null, + 'item_permissions' => 11, ], $share, [], false ]; // with existing group - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_GROUP) ->setSharedWith('recipientGroup') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -3930,11 +4246,12 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_GROUP, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', 'permissions' => 1, + 'attributes' => null, 'stime' => 946684862, 'parent' => null, 'expiration' => null, @@ -3942,7 +4259,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => 'personal note', - 'label' => null, + 'label' => '', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -3959,16 +4276,22 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_GROUP) ->setSharedWith('recipientGroup2') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -3976,7 +4299,7 @@ class ShareAPIControllerTest extends TestCase { ->setId(42); $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_GROUP, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -3988,7 +4311,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => 'personal note', - 'label' => null, + 'label' => '', 'path' => 'file', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -4005,14 +4328,20 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_LINK) ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4025,11 +4354,12 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + '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', @@ -4057,14 +4387,20 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_LINK) ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4078,7 +4414,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_LINK, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4110,15 +4446,21 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_REMOTE) ->setSharedBy('initiator') ->setSharedWith('user@server.com') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setExpirationDate(new \DateTime('2001-02-03T04:05:06')) @@ -4128,7 +4470,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_REMOTE, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4140,7 +4482,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => 'personal note', - 'label' => null, + 'label' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -4157,15 +4499,22 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_REMOTE_GROUP) ->setSharedBy('initiator') ->setSharedWith('user@server.com') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setExpirationDate(new \DateTime('2001-02-03T04:05:06')) @@ -4175,7 +4524,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_REMOTE_GROUP, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4187,7 +4536,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => 'personal note', - 'label' => null, + 'label' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -4204,18 +4553,25 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $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(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4223,11 +4579,12 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_CIRCLE, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', 'permissions' => 1, + 'attributes' => null, 'stime' => 946684862, 'parent' => null, 'expiration' => null, @@ -4235,7 +4592,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => '', - 'label' => null, + 'label' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -4253,16 +4610,22 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_CIRCLE) ->setSharedBy('initiator') ->setSharedWith('Circle (Public circle, circleOwner) [4815162342]') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4270,7 +4633,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_CIRCLE, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4282,7 +4645,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => '', - 'label' => null, + 'label' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -4300,16 +4663,22 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_CIRCLE) ->setSharedBy('initiator') ->setSharedWith('Circle (Public circle, circleOwner)') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4317,7 +4686,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_CIRCLE, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4329,7 +4698,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => '', - 'label' => null, + 'label' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -4347,15 +4716,21 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_USER) ->setSharedBy('initiator') ->setSharedWith('recipient') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') ->setNote('personal note') @@ -4365,12 +4740,12 @@ class ShareAPIControllerTest extends TestCase { [], $share, [], true ]; - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_EMAIL) ->setSharedBy('initiator') ->setSharedWith('user@server.com') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4379,7 +4754,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_EMAIL, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4391,7 +4766,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => '', - 'label' => null, + 'label' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -4411,15 +4786,21 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_EMAIL) ->setSharedBy('initiator') ->setSharedWith('user@server.com') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4429,7 +4810,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_EMAIL, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4441,7 +4822,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'owner', 'displayname_file_owner' => 'owner', 'note' => '', - 'label' => null, + 'label' => '', 'path' => 'folder', 'item_type' => 'folder', 'storage_id' => 'storageId', @@ -4461,16 +4842,22 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_USER) ->setSharedWith('recipient') ->setSharedBy('initiator') ->setShareOwner('currentUser') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($fileWithPreview) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4479,7 +4866,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_USER, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4491,7 +4878,7 @@ class ShareAPIControllerTest extends TestCase { 'uid_file_owner' => 'currentUser', 'displayname_file_owner' => 'currentUser', 'note' => 'personal note', - 'label' => null, + 'label' => '', 'path' => 'fileWithPreview', 'item_type' => 'file', 'storage_id' => 'storageId', @@ -4509,7 +4896,12 @@ class ShareAPIControllerTest extends TestCase { 'hide_download' => 0, 'can_edit' => true, 'can_delete' => true, - 'status' => [], + 'item_size' => 123456, + 'item_mtime' => 1234567890, + 'is-mount-root' => false, + 'mount-type' => '', + 'attributes' => null, + 'item_permissions' => 11, ], $share, [], false ]; @@ -4517,14 +4909,14 @@ class ShareAPIControllerTest extends TestCase { } /** - * @dataProvider dataFormatShare * * @param array $expects - * @param \OCP\Share\IShare $share + * @param IShare $share * @param array $users * @param $exception */ - public function testFormatShare(array $expects, \OCP\Share\IShare $share, array $users, $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); @@ -4540,11 +4932,12 @@ class ShareAPIControllerTest extends TestCase { $this->rootFolder->method('getUserFolder') ->with($this->currentUser) ->willReturnSelf(); + $this->dateTimeZone->method('getTimezone')->willReturn(new \DateTimeZone('UTC')); if (!$exception) { - $this->rootFolder->method('getById') + $this->rootFolder->method('getFirstNodeById') ->with($share->getNodeId()) - ->willReturn([$share->getNode()]); + ->willReturn($share->getNode()); $this->rootFolder->method('getRelativePath') ->with($share->getNode()->getPath()) @@ -4608,9 +5001,16 @@ class ShareAPIControllerTest extends TestCase { $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(Storage::class); + $storage = $this->createMock(IStorage::class); $storage->method('getId')->willReturn('storageId'); $storage->method('getCache')->willReturn($cache); @@ -4618,12 +5018,12 @@ class ShareAPIControllerTest extends TestCase { $result = []; - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_ROOM) ->setSharedWith('recipientRoom') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4632,7 +5032,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_ROOM, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4661,15 +5061,21 @@ class ShareAPIControllerTest extends TestCase { '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 = \OC::$server->getShareManager()->newShare(); + $share = Server::get(IManager::class)->newShare(); $share->setShareType(IShare::TYPE_ROOM) ->setSharedWith('recipientRoom') ->setSharedBy('initiator') ->setShareOwner('owner') - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file) ->setShareTime(new \DateTime('2000-01-01T00:01:02')) ->setTarget('myTarget') @@ -4678,7 +5084,7 @@ class ShareAPIControllerTest extends TestCase { $result[] = [ [ - 'id' => 42, + 'id' => '42', 'share_type' => IShare::TYPE_ROOM, 'uid_owner' => 'initiator', 'displayname_owner' => 'initiator', @@ -4707,6 +5113,12 @@ class ShareAPIControllerTest extends TestCase { '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' ] @@ -4716,21 +5128,21 @@ class ShareAPIControllerTest extends TestCase { } /** - * @dataProvider dataFormatRoomShare * * @param array $expects - * @param \OCP\Share\IShare $share + * @param IShare $share * @param bool $helperAvailable * @param array $formatShareByHelper */ - public function testFormatRoomShare(array $expects, \OCP\Share\IShare $share, bool $helperAvailable, 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('getById') + $this->rootFolder->method('getFirstNodeById') ->with($share->getNodeId()) - ->willReturn([$share->getNode()]); + ->willReturn($share->getNode()); $this->rootFolder->method('getRelativePath') ->with($share->getNode()->getPath()) @@ -4745,12 +5157,18 @@ class ShareAPIControllerTest extends TestCase { ->with('spreed') ->willReturn(true); - $helper = $this->getMockBuilder('\OCA\Talk\Share\Helper\ShareAPIController') - ->setMethods(['formatShare']) + // 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') @@ -4760,4 +5178,203 @@ class ShareAPIControllerTest extends TestCase { $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 index 04d2a08b4e6..011210aff42 100644 --- a/apps/files_sharing/tests/Controller/ShareControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareControllerTest.php @@ -1,60 +1,39 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Björn Schießle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Calviño Sánchez <danxuliu@gmail.com> - * @author Georg Ehrke <oc.list@georgehrke.com> - * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ <skjnldsv@protonmail.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Michael Weimann <mail@michael-weimann.eu> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_Sharing\Tests\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\Files\Storage; +use OCP\IAppConfig; use OCP\IConfig; use OCP\IL10N; -use OCP\ILogger; use OCP\IPreview; use OCP\IRequest; use OCP\ISession; @@ -62,13 +41,12 @@ 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; -use OCP\Activity\IManager; -use OCP\Files\IRootFolder; -use OCP\Defaults; -use OC\Share20\Manager; /** * @group DB @@ -77,39 +55,26 @@ use OC\Share20\Manager; */ 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|MockObject */ - private $urlGenerator; - /** @var ISession|MockObject */ - private $session; - /** @var \OCP\IPreview|MockObject */ - private $previewManager; - /** @var \OCP\IConfig|MockObject */ - private $config; - /** @var \OC\Share20\Manager|MockObject */ - private $shareManager; - /** @var IUserManager|MockObject */ - private $userManager; - /** @var FederatedShareProvider|MockObject */ - private $federatedShareProvider; - /** @var IAccountManager|MockObject */ - private $accountManager; - /** @var IEventDispatcher|MockObject */ - private $eventDispatcher; - /** @var IL10N */ - private $l10n; - /** @var ISecureRandom */ - private $secureRandom; - /** @var Defaults|MockObject */ - private $defaults; + 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(); @@ -120,7 +85,9 @@ class ShareControllerTest extends \Test\TestCase { $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); @@ -131,14 +98,33 @@ class ShareControllerTest extends \Test\TestCase { $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 \OCA\Files_Sharing\Controller\ShareController( + $this->shareController = new ShareController( $this->appName, $this->createMock(IRequest::class), $this->config, $this->urlGenerator, $this->userManager, - $this->createMock(ILogger::class), $this->createMock(IManager::class), $this->shareManager, $this->session, @@ -149,7 +135,8 @@ class ShareControllerTest extends \Test\TestCase { $this->eventDispatcher, $this->l10n, $this->secureRandom, - $this->defaults + $this->defaults, + $this->publicShareTemplateFactory, ); @@ -157,9 +144,9 @@ class ShareControllerTest extends \Test\TestCase { $this->oldUser = \OC_User::getUser(); // Create a dummy user - $this->user = \OC::$server->getSecureRandom()->generate(12, ISecureRandom::CHAR_LOWER); + $this->user = Server::get(ISecureRandom::class)->generate(12, ISecureRandom::CHAR_LOWER); - \OC::$server->getUserManager()->createUser($this->user, $this->user); + Server::get(IUserManager::class)->createUser($this->user, $this->user); \OC_Util::tearDownFS(); $this->loginAsUser($this->user); } @@ -168,13 +155,13 @@ class ShareControllerTest extends \Test\TestCase { \OC_Util::tearDownFS(); \OC_User::setUserId(''); Filesystem::tearDown(); - $user = \OC::$server->getUserManager()->get($this->user); + $user = Server::get(IUserManager::class)->get($this->user); if ($user !== null) { $user->delete(); } \OC_User::setIncognitoMode(false); - \OC::$server->getSession()->set('public_link_authenticated', ''); + Server::get(ISession::class)->set('public_link_authenticated', ''); // Set old user \OC_User::setUserId($this->oldUser); @@ -182,14 +169,14 @@ class ShareControllerTest extends \Test\TestCase { parent::tearDown(); } - public function testShowShareInvalidToken() { + public function testShowShareInvalidToken(): void { $this->shareController->setToken('invalidtoken'); $this->shareManager ->expects($this->once()) ->method('getShareByToken') ->with('invalidtoken') - ->will($this->throwException(new ShareNotFound())); + ->willThrowException(new ShareNotFound()); $this->expectException(NotFoundException::class); @@ -197,10 +184,10 @@ class ShareControllerTest extends \Test\TestCase { $this->shareController->showShare(); } - public function testShowShareNotAuthenticated() { + public function testShowShareNotAuthenticated(): void { $this->shareController->setToken('validtoken'); - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(\OCP\Share\IManager::class)->newShare(); $share->setPassword('password'); $this->shareManager @@ -216,7 +203,7 @@ class ShareControllerTest extends \Test\TestCase { } - public function testShowShare() { + public function testShowShare(): void { $note = 'personal note'; $filename = 'file1.txt'; @@ -238,6 +225,7 @@ class ShareControllerTest extends \Test\TestCase { $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') @@ -251,22 +239,36 @@ class ShareControllerTest extends \Test\TestCase { ->with($owner) ->willReturn($account); - $share = \OC::$server->getShareManager()->newShare(); - $share->setId(42); - $share->setPassword('password') + /** @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"); + ->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($this->at(0)) + $this->urlGenerator->expects(self::atLeast(2)) ->method('linkToRouteAbsolute') - ->with('files_sharing.sharecontroller.downloadShare', ['token' => 'token', 'filename' => $filename]) - ->willReturn('downloadURL'); + ->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); @@ -279,19 +281,12 @@ class ShareControllerTest extends \Test\TestCase { ['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->config - ->expects($this->once()) - ->method('getAppValue') - ->with('core', 'shareapi_public_link_disclaimertext', null) - ->willReturn('My disclaimer text'); $this->userManager->method('get')->willReturnCallback(function (string $uid) use ($owner, $initiator) { if ($uid === 'ownerUID') { @@ -303,13 +298,15 @@ class ShareControllerTest extends \Test\TestCase { return null; }); - $this->eventDispatcher->expects($this->exactly(2)) - ->method('dispatchTyped') - ->with( - $this->callback(function ($event) use ($share) { + $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') @@ -321,55 +318,50 @@ class ShareControllerTest extends \Test\TestCase { ->method('getProductName') ->willReturn('Nextcloud'); - $response = $this->shareController->showShare(); - $sharedTmplParams = [ - 'owner' => 'ownerUID', - 'filename' => $filename, - 'directory_path' => "/$filename", - 'mimetype' => 'text/plain', - 'dirToken' => 'token', + // 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', - 'server2serversharing' => true, - 'protected' => 'true', - 'dir' => '', - 'downloadURL' => 'downloadURL', - 'fileSize' => '33 B', - 'nonHumanFileSize' => 33, - 'maxSizeAnimateGif' => 10, - 'previewSupported' => true, - 'previewEnabled' => true, - 'previewMaxX' => 1024, - 'previewMaxY' => 1024, - 'hideFileList' => false, - 'shareOwner' => 'ownerDisplay', - 'disclaimer' => 'My disclaimer text', - 'shareUrl' => null, - 'previewImage' => null, - 'previewURL' => 'downloadURL', - 'note' => $note, - 'hideDownload' => false, - 'showgridview' => false + 'sharePermissions' => (Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE), + 'filename' => $filename, + 'view' => $view, + 'fileId' => 111, + 'owner' => 'ownerUID', + 'ownerDisplayName' => 'ownerDisplay', + 'isFileRequest' => false, ]; - $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); + $response = $this->shareController->showShare(); + + $this->assertEquals($expectedInitialState, $initialState); + + $csp = new ContentSecurityPolicy(); $csp->addAllowedFrameDomain('\'self\''); - $expectedResponse = new PublicTemplateResponse($this->appName, 'public', $sharedTmplParams); + $expectedResponse = new PublicTemplateResponse('files', 'index'); + $expectedResponse->setParams(['pageTitle' => $filename]); $expectedResponse->setContentSecurityPolicy($csp); - $expectedResponse->setHeaderTitle($sharedTmplParams['filename']); - $expectedResponse->setHeaderDetails('shared by ' . $sharedTmplParams['shareOwner']); + $expectedResponse->setHeaderTitle($filename); + $expectedResponse->setHeaderDetails('shared by ownerDisplay'); $expectedResponse->setHeaderActions([ - new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $sharedTmplParams['downloadURL'], 0), - new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $sharedTmplParams['downloadURL'], 10, $sharedTmplParams['fileSize']), - new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $sharedTmplParams['previewURL']), - new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $sharedTmplParams['owner'], $sharedTmplParams['shareOwner'], $sharedTmplParams['filename']), + 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 testShowShareWithPrivateName() { - $note = 'personal note'; - $filename = 'file1.txt'; + public function testShowFileDropShare(): void { + $filename = 'folder1'; $this->shareController->setToken('token'); @@ -383,16 +375,15 @@ class ShareControllerTest extends \Test\TestCase { $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 = $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_LOCAL); + ->willReturn(IAccountManager::SCOPE_PUBLISHED); $account = $this->createMock(IAccount::class); $account->method('getProperty') ->with(IAccountManager::PROPERTY_DISPLAYNAME) @@ -402,24 +393,36 @@ class ShareControllerTest extends \Test\TestCase { ->with($owner) ->willReturn($account); - $share = \OC::$server->getShareManager()->newShare(); - $share->setId(42); - $share->setPassword('password') + /** @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) - ->setNote($note) - ->setTarget("/$filename"); + ->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($this->at(0)) + $this->urlGenerator->expects(self::atLeastOnce()) ->method('linkToRouteAbsolute') - ->with('files_sharing.sharecontroller.downloadShare', ['token' => 'token', 'filename' => $filename]) - ->willReturn('downloadURL'); - - $this->previewManager->method('isMimeSupported')->with('text/plain')->willReturn(true); + ->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( @@ -430,19 +433,12 @@ class ShareControllerTest extends \Test\TestCase { ['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->config - ->expects($this->once()) - ->method('getAppValue') - ->with('core', 'shareapi_public_link_disclaimertext', null) - ->willReturn('My disclaimer text'); $this->userManager->method('get')->willReturnCallback(function (string $uid) use ($owner, $initiator) { if ($uid === 'ownerUID') { @@ -454,77 +450,68 @@ class ShareControllerTest extends \Test\TestCase { return null; }); - $this->eventDispatcher->expects($this->exactly(2)) - ->method('dispatchTyped') - ->with( - $this->callback(function ($event) use ($share) { + $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') - ->will($this->returnCallback(function ($text, $parameters) { + ->willReturnCallback(function ($text, $parameters) { return vsprintf($text, $parameters); - })); - - $this->defaults->expects(self::any()) - ->method('getProductName') - ->willReturn('Nextcloud'); + }); - $response = $this->shareController->showShare(); - $sharedTmplParams = [ - 'owner' => '', - 'filename' => $filename, - 'directory_path' => "/$filename", - 'mimetype' => 'text/plain', - 'dirToken' => 'token', + // 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', - 'server2serversharing' => true, - 'protected' => 'true', - 'dir' => '', - 'downloadURL' => 'downloadURL', - 'fileSize' => '33 B', - 'nonHumanFileSize' => 33, - 'maxSizeAnimateGif' => 10, - 'previewSupported' => true, - 'previewEnabled' => true, - 'previewMaxX' => 1024, - 'previewMaxY' => 1024, - 'hideFileList' => false, - 'shareOwner' => '', + 'sharePermissions' => Constants::PERMISSION_CREATE, + 'filename' => $filename, + 'view' => 'public-file-drop', 'disclaimer' => 'My disclaimer text', - 'shareUrl' => null, - 'previewImage' => null, - 'previewURL' => 'downloadURL', - 'note' => $note, - 'hideDownload' => false, - 'showgridview' => false + 'owner' => 'ownerUID', + 'ownerDisplayName' => 'ownerDisplay', + 'isFileRequest' => false, + 'note' => 'The note', + 'label' => 'A label', ]; - $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); + $response = $this->shareController->showShare(); + + $this->assertEquals($expectedInitialState, $initialState); + + $csp = new ContentSecurityPolicy(); $csp->addAllowedFrameDomain('\'self\''); - $expectedResponse = new PublicTemplateResponse($this->appName, 'public', $sharedTmplParams); + $expectedResponse = new PublicTemplateResponse('files', 'index'); + $expectedResponse->setParams(['pageTitle' => 'A label']); $expectedResponse->setContentSecurityPolicy($csp); - $expectedResponse->setHeaderTitle($sharedTmplParams['filename']); - $expectedResponse->setHeaderDetails(''); + $expectedResponse->setHeaderTitle('A label'); + $expectedResponse->setHeaderDetails('shared by ownerDisplay'); $expectedResponse->setHeaderActions([ - new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $sharedTmplParams['downloadURL'], 0), - new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $sharedTmplParams['downloadURL'], 10, $sharedTmplParams['fileSize']), - new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $sharedTmplParams['previewURL']), - new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $sharedTmplParams['owner'], $sharedTmplParams['shareOwner'], $sharedTmplParams['filename']), + new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', 'shareUrl'), ]); $this->assertEquals($expectedResponse, $response); } - public function testShowShareHideDownload() { + public function testShowShareWithPrivateName(): void { $note = 'personal note'; $filename = 'file1.txt'; $this->shareController->setToken('token'); - $owner = $this->getMockBuilder(IUser::class)->getMock(); + $owner = $this->createMock(IUser::class); $owner->method('getDisplayName')->willReturn('ownerDisplay'); $owner->method('getUID')->willReturn('ownerUID'); $owner->method('isEnabled')->willReturn(true); @@ -534,16 +521,17 @@ class ShareControllerTest extends \Test\TestCase { $initiator->method('getUID')->willReturn('initiatorUID'); $initiator->method('isEnabled')->willReturn(true); - $file = $this->getMockBuilder('OCP\Files\File')->getMock(); + $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); + ->willReturn(IAccountManager::SCOPE_LOCAL); $account = $this->createMock(IAccount::class); $account->method('getProperty') ->with(IAccountManager::PROPERTY_DISPLAYNAME) @@ -553,26 +541,35 @@ class ShareControllerTest extends \Test\TestCase { ->with($owner) ->willReturn($account); - $share = \OC::$server->getShareManager()->newShare(); + /** @var IShare */ + $share = Server::get(Manager::class)->newShare(); $share->setId(42); $share->setPassword('password') ->setShareOwner('ownerUID') ->setSharedBy('initiatorUID') ->setNode($file) ->setNote($note) - ->setTarget("/$filename") - ->setHideDownload(true); + ->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'); - // Even if downloads are disabled the "downloadURL" parameter is - // provided to the template, as it is needed to preview audio and GIF - // files. - $this->urlGenerator->expects($this->at(0)) + $this->urlGenerator->expects(self::atLeast(2)) ->method('linkToRouteAbsolute') - ->with('files_sharing.sharecontroller.downloadShare', ['token' => 'token', 'filename' => $filename]) - ->willReturn('downloadURL'); + ->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); @@ -593,11 +590,6 @@ class ShareControllerTest extends \Test\TestCase { ->method('getShareByToken') ->with('token') ->willReturn($share); - $this->config - ->expects($this->once()) - ->method('getAppValue') - ->with('core', 'shareapi_public_link_disclaimertext', null) - ->willReturn('My disclaimer text'); $this->userManager->method('get')->willReturnCallback(function (string $uid) use ($owner, $initiator) { if ($uid === 'ownerUID') { @@ -609,13 +601,15 @@ class ShareControllerTest extends \Test\TestCase { return null; }); - $this->eventDispatcher->expects($this->exactly(2)) - ->method('dispatchTyped') - ->with( - $this->callback(function ($event) use ($share) { + $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') @@ -623,174 +617,31 @@ class ShareControllerTest extends \Test\TestCase { return vsprintf($text, $parameters); }); - $response = $this->shareController->showShare(); - $sharedTmplParams = [ - 'owner' => 'ownerUID', - 'filename' => $filename, - 'directory_path' => "/$filename", - 'mimetype' => 'text/plain', - 'dirToken' => 'token', - 'sharingToken' => 'token', - 'server2serversharing' => true, - 'protected' => 'true', - 'dir' => '', - 'downloadURL' => 'downloadURL', - 'fileSize' => '33 B', - 'nonHumanFileSize' => 33, - 'maxSizeAnimateGif' => 10, - 'previewSupported' => true, - 'previewEnabled' => true, - 'previewMaxX' => 1024, - 'previewMaxY' => 1024, - 'hideFileList' => false, - 'shareOwner' => 'ownerDisplay', - 'disclaimer' => 'My disclaimer text', - 'shareUrl' => null, - 'previewImage' => null, - 'previewURL' => 'downloadURL', - 'note' => $note, - 'hideDownload' => true, - 'showgridview' => false - ]; - - $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); - $csp->addAllowedFrameDomain('\'self\''); - $expectedResponse = new PublicTemplateResponse($this->appName, 'public', $sharedTmplParams); - $expectedResponse->setContentSecurityPolicy($csp); - $expectedResponse->setHeaderTitle($sharedTmplParams['filename']); - $expectedResponse->setHeaderDetails('shared by ' . $sharedTmplParams['shareOwner']); - $expectedResponse->setHeaderActions([]); - - $this->assertEquals($expectedResponse, $response); - } - - /** - * Checks file drop shares: - * - there must not be any header action - * - the template param "hideFileList" should be true - * - * @test - * @return void - */ - public function testShareFileDrop() { - $this->shareController->setToken('token'); - - $owner = $this->getMockBuilder(IUser::class)->getMock(); - $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); - - /* @var MockObject|Storage $storage */ - $storage = $this->getMockBuilder(Storage::class) - ->disableOriginalConstructor() - ->getMock(); - - /* @var MockObject|Folder $folder */ - $folder = $this->getMockBuilder(Folder::class) - ->disableOriginalConstructor() - ->getMock(); - $folder->method('getName')->willReturn('/fileDrop'); - $folder->method('isReadable')->willReturn(true); - $folder->method('isShareable')->willReturn(true); - $folder->method('getStorage')->willReturn($storage); - $folder->method('get')->with('')->willReturn($folder); - $folder->method('getSize')->willReturn(1337); - - $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); - - $share = \OC::$server->getShareManager()->newShare(); - $share->setId(42); - $share->setPermissions(Constants::PERMISSION_CREATE) - ->setShareOwner('ownerUID') - ->setSharedBy('initiatorUID') - ->setNode($folder) - ->setTarget('/fileDrop'); - - $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->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(); - // skip the "folder" param for tests - $responseParams = $response->getParams(); - unset($responseParams['folder']); - $response->setParams($responseParams); - $sharedTmplParams = [ - 'owner' => 'ownerUID', - 'filename' => '/fileDrop', - 'directory_path' => '/fileDrop', - 'mimetype' => null, - 'dirToken' => 'token', - 'sharingToken' => 'token', - 'server2serversharing' => true, - 'protected' => 'false', - 'dir' => null, - 'downloadURL' => '', - 'fileSize' => '1 KB', - 'nonHumanFileSize' => 1337, - 'maxSizeAnimateGif' => null, - 'previewSupported' => null, - 'previewEnabled' => null, - 'previewMaxX' => null, - 'previewMaxY' => null, - 'hideFileList' => true, - 'shareOwner' => 'ownerDisplay', - 'disclaimer' => null, - 'shareUrl' => '', - 'previewImage' => '', - 'previewURL' => '', - 'note' => '', - 'hideDownload' => false, - 'showgridview' => false - ]; - - $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy(); + $csp = new ContentSecurityPolicy(); $csp->addAllowedFrameDomain('\'self\''); - $expectedResponse = new PublicTemplateResponse($this->appName, 'public', $sharedTmplParams); + $expectedResponse = new PublicTemplateResponse('files', 'index'); + $expectedResponse->setParams(['pageTitle' => $filename]); $expectedResponse->setContentSecurityPolicy($csp); - $expectedResponse->setHeaderTitle($sharedTmplParams['filename']); - $expectedResponse->setHeaderDetails('shared by ' . $sharedTmplParams['shareOwner']); + $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'), + ]); - self::assertEquals($expectedResponse, $response); + $this->assertEquals($expectedResponse, $response); } - public function testShowShareInvalid() { - $this->expectException(\OCP\Files\NotFoundException::class); + public function testShowShareInvalid(): void { + $this->expectException(NotFoundException::class); $filename = 'file1.txt'; $this->shareController->setToken('token'); @@ -806,7 +657,7 @@ class ShareControllerTest extends \Test\TestCase { $file->method('isShareable')->willReturn(false); $file->method('isReadable')->willReturn(true); - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(\OCP\Share\IManager::class)->newShare(); $share->setId(42); $share->setPassword('password') ->setShareOwner('ownerUID') @@ -839,13 +690,13 @@ class ShareControllerTest extends \Test\TestCase { $this->shareController->showShare(); } - public function testDownloadShareWithCreateOnlyShare() { + public function testDownloadShareWithCreateOnlyShare(): void { $share = $this->getMockBuilder(IShare::class)->getMock(); $share->method('getPassword')->willReturn('password'); $share ->expects($this->once()) ->method('getPermissions') - ->willReturn(\OCP\Constants::PERMISSION_CREATE); + ->willReturn(Constants::PERMISSION_CREATE); $this->shareManager ->expects($this->once()) @@ -859,7 +710,35 @@ class ShareControllerTest extends \Test\TestCase { $this->assertEquals($expectedResponse, $response); } - public function testDisabledOwner() { + 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(); @@ -871,7 +750,7 @@ class ShareControllerTest extends \Test\TestCase { /* @var MockObject|Folder $folder */ $folder = $this->createMock(Folder::class); - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(\OCP\Share\IManager::class)->newShare(); $share->setId(42); $share->setPermissions(Constants::PERMISSION_CREATE) ->setShareOwner('ownerUID') @@ -900,7 +779,7 @@ class ShareControllerTest extends \Test\TestCase { $this->shareController->showShare(); } - public function testDisabledInitiator() { + public function testDisabledInitiator(): void { $this->shareController->setToken('token'); $owner = $this->getMockBuilder(IUser::class)->getMock(); @@ -912,7 +791,7 @@ class ShareControllerTest extends \Test\TestCase { /* @var MockObject|Folder $folder */ $folder = $this->createMock(Folder::class); - $share = \OC::$server->getShareManager()->newShare(); + $share = Server::get(\OCP\Share\IManager::class)->newShare(); $share->setId(42); $share->setPermissions(Constants::PERMISSION_CREATE) ->setShareOwner('ownerUID') diff --git a/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php b/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php index 18bda2f488d..1a678610805 100644 --- a/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareInfoControllerTest.php @@ -1,25 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2016 Roeland Jago Douma <roeland@famdouma.nl> - * - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCA\Files_Sharing\Tests\Controller; @@ -33,15 +16,13 @@ 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 { - /** @var ShareInfoController */ - private $controller; - - /** @var ShareManager|\PHPUnit\Framework\MockObject\MockObject */ - private $shareManager; + protected ShareInfoController $controller; + protected ShareManager&MockObject $shareManager; protected function setUp(): void { @@ -49,17 +30,14 @@ class ShareInfoControllerTest extends TestCase { $this->shareManager = $this->createMock(ShareManager::class); - $this->controller = $this->getMockBuilder(ShareInfoController::class) - ->setConstructorArgs([ - 'files_sharing', - $this->createMock(IRequest::class), - $this->shareManager - ]) - ->setMethods(['addROWrapper']) - ->getMock(); + $this->controller = new ShareInfoController( + 'files_sharing', + $this->createMock(IRequest::class), + $this->shareManager + ); } - public function testNoShare() { + public function testNoShare(): void { $this->shareManager->method('getShareByToken') ->with('token') ->willThrowException(new ShareNotFound()); @@ -69,7 +47,7 @@ class ShareInfoControllerTest extends TestCase { $this->assertEquals($expected, $this->controller->info('token')); } - public function testWrongPassword() { + public function testWrongPassword(): void { $share = $this->createMock(IShare::class); $share->method('getPassword') ->willReturn('sharePass'); @@ -86,7 +64,7 @@ class ShareInfoControllerTest extends TestCase { $this->assertEquals($expected, $this->controller->info('token', 'pass')); } - public function testNoReadPermissions() { + public function testNoReadPermissions(): void { $share = $this->createMock(IShare::class); $share->method('getPassword') ->willReturn('sharePass'); @@ -125,7 +103,7 @@ class ShareInfoControllerTest extends TestCase { return $file; } - public function testInfoFile() { + public function testInfoFile(): void { $file = $this->prepareFile(); $share = $this->createMock(IShare::class); @@ -157,7 +135,7 @@ class ShareInfoControllerTest extends TestCase { $this->assertEquals($expected, $this->controller->info('token', 'pass')); } - public function testInfoFileRO() { + public function testInfoFileRO(): void { $file = $this->prepareFile(); $share = $this->createMock(IShare::class); @@ -239,7 +217,7 @@ class ShareInfoControllerTest extends TestCase { return $root; } - public function testInfoFolder() { + public function testInfoFolder(): void { $file = $this->prepareFolder(); $share = $this->createMock(IShare::class); diff --git a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php index 860d5796e56..18e1bf0347b 100644 --- a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php @@ -1,45 +1,23 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author Julius Härtl <jus@bitgrid.net> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Citharel <nextcloud@tcit.fr> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_Sharing\Tests\Controller; use OCA\Files_Sharing\Controller\ShareesAPIController; use OCA\Files_Sharing\Tests\TestCase; -use OCP\AppFramework\Http; +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\IShare; use OCP\Share\IManager; +use OCP\Share\IShare; use PHPUnit\Framework\MockObject\MockObject; /** @@ -62,18 +40,19 @@ class ShareesAPIControllerTest extends TestCase { /** @var IManager|MockObject */ protected $shareManager; - /** @var ISearch|MockObject */ + /** @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); - - /** @var IConfig|MockObject $configMock */ - $configMock = $this->createMock(IConfig::class); + $this->config = $this->createMock(IConfig::class); /** @var IURLGenerator|MockObject $urlGeneratorMock */ $urlGeneratorMock = $this->createMock(IURLGenerator::class); @@ -81,145 +60,144 @@ class ShareesAPIControllerTest extends TestCase { $this->collaboratorSearch = $this->createMock(ISearch::class); $this->sharees = new ShareesAPIController( - $this->uid, 'files_sharing', $this->request, - $configMock, + $this->uid, + $this->config, $urlGeneratorMock, $this->shareManager, $this->collaboratorSearch ); } - public function dataSearch(): array { + 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', true, true, true, $noRemote, false, true, true], + [[], '', 'yes', false, true, true, true, $noRemote, false, true, true], // Test itemType [[ 'search' => '', - ], '', 'yes', true, true, true, $noRemote, false, true, true], + ], '', 'yes', false, true, true, true, $noRemote, false, true, true], [[ 'search' => 'foobar', - ], '', 'yes', true, true, true, $noRemote, false, true, true], + ], '', 'yes', false, true, true, true, $noRemote, false, true, true], [[ 'search' => 0, - ], '', 'yes', true, true, true, $noRemote, false, true, true], + ], '', 'yes', false, true, true, true, $noRemote, false, true, true], // Test itemType [[ 'itemType' => '', - ], '', 'yes', true, true, true, $noRemote, false, true, true], + ], '', 'yes', false, true, true, true, $noRemote, false, true, true], [[ 'itemType' => 'folder', - ], '', 'yes', true, true, true, $allTypes, false, true, true], + ], '', 'yes', false, true, true, true, $allTypes, false, true, true], [[ 'itemType' => 0, - ], '', 'yes', true, true , true, $noRemote, false, true, true], + ], '', 'yes', false, true, true , true, $noRemote, false, true, true], // Test shareType [[ 'itemType' => 'call', - ], '', 'yes', true, true, true, $noRemote, false, true, true], + ], '', 'yes', false, true, true, true, $noRemote, false, true, true], [[ 'itemType' => 'call', - ], '', 'yes', true, true, true, [0, 4], false, true, false], + ], '', 'yes', false, true, true, true, [0, 4], false, true, false], [[ 'itemType' => 'folder', - ], '', 'yes', true, true, true, $allTypes, false, true, true], + ], '', 'yes', false, true, true, true, $allTypes, false, true, true], [[ 'itemType' => 'folder', 'shareType' => 0, - ], '', 'yes', true, true, false, [0], false, true, true], + ], '', 'yes', false, true, true, false, [0], false, true, true], [[ 'itemType' => 'folder', 'shareType' => '0', - ], '', 'yes', true, true, false, [0], false, true, true], + ], '', 'yes', false, true, true, false, [0], false, true, true], [[ 'itemType' => 'folder', 'shareType' => 1, - ], '', 'yes', true, true, false, [1], false, true, true], + ], '', 'yes', false, true, true, false, [1], false, true, true], [[ 'itemType' => 'folder', 'shareType' => 12, - ], '', 'yes', true, true, false, [], false, true, true], + ], '', 'yes', false, true, true, false, [], false, true, true], [[ 'itemType' => 'folder', 'shareType' => 'foobar', - ], '', 'yes', true, true, true, $allTypes, false, true, true], + ], '', 'yes', false, true, true, true, $allTypes, false, true, true], [[ 'itemType' => 'folder', 'shareType' => [0, 1, 2], - ], '', 'yes', false, false, false, [0, 1], false, true, true], + ], '', 'yes', false, false, false, false, [0, 1], false, true, true], [[ 'itemType' => 'folder', 'shareType' => [0, 1], - ], '', 'yes', false, false, false, [0, 1], false, true, true], + ], '', 'yes', false, false, false, false, [0, 1], false, true, true], [[ 'itemType' => 'folder', 'shareType' => $allTypes, - ], '', 'yes', true, true, true, $allTypes, false, true, true], + ], '', 'yes', false, true, true, true, $allTypes, false, true, true], [[ 'itemType' => 'folder', 'shareType' => $allTypes, - ], '', 'yes', false, false, false, [0, 1], false, true, true], + ], '', 'yes', false, false, false, false, [0, 1], false, true, true], [[ 'itemType' => 'folder', 'shareType' => $allTypes, - ], '', 'yes', true, false, false, [0, 6], false, true, false], + ], '', 'yes', false, true, false, false, [0, 6], false, true, false], [[ 'itemType' => 'folder', 'shareType' => $allTypes, - ], '', 'yes', false, false, true, [0, 4], false, true, false], + ], '', 'yes', false, false, false, true, [0, 4], false, true, false], [[ 'itemType' => 'folder', 'shareType' => $allTypes, - ], '', 'yes', true, true, false, [0, 6, 9], false, true, false], + ], '', 'yes', false, true, true, false, [0, 6, 9], false, true, false], // Test pagination [[ 'itemType' => 'folder', 'page' => 1, - ], '', 'yes', true, true, true, $allTypes, false, true, true], + ], '', 'yes', false, true, true, true, $allTypes, false, true, true], [[ 'itemType' => 'folder', 'page' => 10, - ], '', 'yes', true, true, true, $allTypes, false, true, true], + ], '', 'yes', false, true, true, true, $allTypes, false, true, true], // Test perPage [[ 'itemType' => 'folder', 'perPage' => 1, - ], '', 'yes', true, true, true, $allTypes, false, true, true], + ], '', 'yes', false, true, true, true, $allTypes, false, true, true], [[ 'itemType' => 'folder', 'perPage' => 10, - ], '', 'yes', true, true, true, $allTypes, false, true, true], + ], '', 'yes', false, true, true, true, $allTypes, false, true, true], // Test $shareWithGroupOnly setting [[ 'itemType' => 'folder', - ], 'no', 'yes', true, true, true, $allTypes, false, true, true], + ], 'no', 'yes', false, true, true, true, $allTypes, false, true, true], [[ 'itemType' => 'folder', - ], 'yes', 'yes', true, true, true, $allTypes, true, true, true], + ], 'yes', 'yes', false, true, true, true, $allTypes, true, true, true], // Test $shareeEnumeration setting [[ 'itemType' => 'folder', - ], 'no', 'yes', true, true, true, $allTypes, false, true, true], + ], 'no', 'yes', false, true, true, true, $allTypes, false, true, true], [[ 'itemType' => 'folder', - ], 'no', 'no', true, true, true, $allTypes, false, false, true], + ], 'no', 'no', false, true, true, true, $allTypes, false, false, true], ]; } /** - * @dataProvider dataSearch * * @param array $getData * @param string $apiSetting @@ -233,21 +211,34 @@ class ShareesAPIControllerTest extends TestCase { * @param bool $allowGroupSharing * @throws OCSBadRequestException */ - public function testSearch(array $getData, string $apiSetting, string $enumSetting, bool $remoteSharingEnabled, bool $isRemoteGroupSharingEnabled, bool $emailSharingEnabled, array $shareTypes, bool $shareWithGroupOnly, bool $shareeEnumeration, bool $allowGroupSharing) { + #[\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); - $config->expects($this->exactly(1)) - ->method('getAppValue') - ->with($this->anything(), $this->anything(), $this->anything()) - ->willReturnMap([ - ['files_sharing', 'lookupServerEnabled', 'yes', 'yes'], - ]); $this->shareManager->expects($this->once()) ->method('allowGroupSharing') @@ -263,15 +254,15 @@ class ShareesAPIControllerTest extends TestCase { /** @var MockObject|ShareesAPIController $sharees */ $sharees = $this->getMockBuilder(ShareesAPIController::class) ->setConstructorArgs([ - $uid, 'files_sharing', $request, + $uid, $config, $urlGenerator, $this->shareManager, $this->collaboratorSearch ]) - ->setMethods(['isRemoteSharingAllowed', 'shareProviderExists', 'isRemoteGroupSharingAllowed']) + ->onlyMethods(['isRemoteSharingAllowed', 'isRemoteGroupSharingAllowed']) ->getMock(); $expectedShareTypes = $shareTypes; @@ -293,6 +284,10 @@ class ShareesAPIControllerTest extends TestCase { ->with($itemType) ->willReturn($isRemoteGroupSharingEnabled); + $this->shareManager->expects($this->any()) + ->method('sharingDisabledForUser') + ->with($uid) + ->willReturn($sharingDisabledForUser); $this->shareManager->expects($this->any()) ->method('shareProviderExists') @@ -304,10 +299,10 @@ class ShareesAPIControllerTest extends TestCase { } }); - $this->assertInstanceOf(Http\DataResponse::class, $sharees->search($search, $itemType, $page, $perPage, $shareType)); + $this->assertInstanceOf(DataResponse::class, $sharees->search($search, $itemType, $page, $perPage, $shareType)); } - public function dataSearchInvalid(): array { + public static function dataSearchInvalid(): array { return [ // Test invalid pagination [[ @@ -334,14 +329,14 @@ class ShareesAPIControllerTest extends TestCase { } /** - * @dataProvider dataSearchInvalid * * @param array $getData * @param string $message */ - public function testSearchInvalid($getData, $message) { - $page = isset($getData['page']) ? $getData['page'] : 1; - $perPage = isset($getData['perPage']) ? $getData['perPage'] : 200; + #[\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); @@ -358,15 +353,15 @@ class ShareesAPIControllerTest extends TestCase { /** @var MockObject|ShareesAPIController $sharees */ $sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController') ->setConstructorArgs([ - $uid, 'files_sharing', $request, + $uid, $config, $urlGenerator, $this->shareManager, $this->collaboratorSearch ]) - ->setMethods(['isRemoteSharingAllowed']) + ->onlyMethods(['isRemoteSharingAllowed']) ->getMock(); $sharees->expects($this->never()) ->method('isRemoteSharingAllowed'); @@ -382,7 +377,7 @@ class ShareesAPIControllerTest extends TestCase { } } - public function dataIsRemoteSharingAllowed() { + public static function dataIsRemoteSharingAllowed() { return [ ['file', true], ['folder', true], @@ -392,24 +387,40 @@ class ShareesAPIControllerTest extends TestCase { } /** - * @dataProvider dataIsRemoteSharingAllowed * * @param string $itemType * @param bool $expected */ - public function testIsRemoteSharingAllowed($itemType, $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() { - $this->expectException(\OCP\AppFramework\OCS\OCSBadRequestException::class); + public function testSearchNoItemType(): void { + $this->expectException(OCSBadRequestException::class); $this->expectExceptionMessage('Missing itemType'); $this->sharees->search('', null, 1, 10, [], false); } - public function dataGetPaginationLink() { + 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"'], @@ -417,14 +428,14 @@ class ShareesAPIControllerTest extends TestCase { } /** - * @dataProvider dataGetPaginationLink * * @param int $page * @param string $scriptName * @param array $params * @param array $expected */ - public function testGetPaginationLink($page, $scriptName, $params, $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetPaginationLink')] + public function testGetPaginationLink($page, $scriptName, $params, $expected): void { $this->request->expects($this->once()) ->method('getScriptName') ->willReturn($scriptName); @@ -432,7 +443,7 @@ class ShareesAPIControllerTest extends TestCase { $this->assertEquals($expected, $this->invokePrivate($this->sharees, 'getPaginationLink', [$page, $params])); } - public function dataIsV2() { + public static function dataIsV2() { return [ ['/ocs/v1.php', false], ['/ocs/v2.php', true], @@ -440,12 +451,12 @@ class ShareesAPIControllerTest extends TestCase { } /** - * @dataProvider dataIsV2 * * @param string $scriptName * @param bool $expected */ - public function testIsV2($scriptName, $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataIsV2')] + public function testIsV2($scriptName, $expected): void { $this->request->expects($this->once()) ->method('getScriptName') ->willReturn($scriptName); |