diff options
Diffstat (limited to 'apps/files_sharing/tests/Controller/ShareControllerTest.php')
-rw-r--r-- | apps/files_sharing/tests/Controller/ShareControllerTest.php | 668 |
1 files changed, 253 insertions, 415 deletions
diff --git a/apps/files_sharing/tests/Controller/ShareControllerTest.php b/apps/files_sharing/tests/Controller/ShareControllerTest.php index 3a73862bf77..011210aff42 100644 --- a/apps/files_sharing/tests/Controller/ShareControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareControllerTest.php @@ -1,37 +1,9 @@ <?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; @@ -41,22 +13,25 @@ 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\IPreview; @@ -66,7 +41,9 @@ 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; @@ -77,41 +54,27 @@ use PHPUnit\Framework\MockObject\MockObject; * @package OCA\Files_Sharing\Controllers */ class ShareControllerTest extends \Test\TestCase { - /** @var string */ - private $user; - /** @var string */ - private $oldUser; - - /** @var string */ - private $appName = 'files_sharing'; - /** @var ShareController */ - private $shareController; - /** @var IURLGenerator|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; - /** @var IPublicShareTemplateFactory|MockObject */ - private $publicShareTemplateFactory; + + 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(); @@ -122,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); @@ -149,10 +114,12 @@ class ShareControllerTest extends \Test\TestCase { $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, @@ -177,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); } @@ -188,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); @@ -202,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); @@ -217,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 @@ -236,7 +203,7 @@ class ShareControllerTest extends \Test\TestCase { } - public function testShowShare() { + public function testShowShare(): void { $note = 'personal note'; $filename = 'file1.txt'; @@ -258,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') @@ -271,29 +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->exactly(3)) + $this->urlGenerator->expects(self::atLeast(2)) ->method('linkToRouteAbsolute') - ->withConsecutive( - ['files_sharing.sharecontroller.downloadShare', ['token' => 'token', 'filename' => $filename]], - ['files_sharing.sharecontroller.showShare', ['token' => 'token']], - ['files_sharing.PublicPreview.getPreview', ['token' => 'token', 'x' => 200, 'y' => 200, 'file' => '/'.$filename]], - )->willReturnOnConsecutiveCalls( - 'downloadURL', - 'shareUrl', - 'previewImage', - ); + ->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); @@ -306,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') { @@ -330,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') @@ -348,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' => 'shareUrl', - 'previewImage' => 'previewImage', - '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'); @@ -410,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) @@ -429,31 +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->exactly(3)) + $this->urlGenerator->expects(self::atLeastOnce()) ->method('linkToRouteAbsolute') - ->withConsecutive( - ['files_sharing.sharecontroller.downloadShare', ['token' => 'token', 'filename' => $filename]], - ['files_sharing.sharecontroller.showShare', ['token' => 'token']], - ['files_sharing.PublicPreview.getPreview', ['token' => 'token', 'x' => 200, 'y' => 200, 'file' => '/'.$filename]], - )->willReturnOnConsecutiveCalls( - 'downloadURL', - 'shareUrl', - 'previewImage', - ); - - $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( @@ -464,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') { @@ -488,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' => 'shareUrl', - 'previewImage' => 'previewImage', - '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); @@ -568,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) @@ -587,33 +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->exactly(3)) + $this->urlGenerator->expects(self::atLeast(2)) ->method('linkToRouteAbsolute') - ->withConsecutive( - ['files_sharing.sharecontroller.downloadShare', ['token' => 'token', 'filename' => $filename]], - ['files_sharing.sharecontroller.showShare', ['token' => 'token']], - ['files_sharing.PublicPreview.getPreview', ['token' => 'token', 'x' => 200, 'y' => 200, 'file' => '/'.$filename]], - )->willReturnOnConsecutiveCalls( - 'downloadURL', - 'shareUrl', - 'previewImage', - ); + ->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); @@ -634,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') { @@ -650,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') @@ -664,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' => 'shareUrl', - 'previewImage' => 'previewImage', - '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'); @@ -847,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') @@ -880,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()) @@ -900,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(); @@ -912,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') @@ -941,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(); @@ -953,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') |