diff options
Diffstat (limited to 'apps/sharebymail/tests/ShareByMailProviderTest.php')
-rw-r--r-- | apps/sharebymail/tests/ShareByMailProviderTest.php | 1105 |
1 files changed, 718 insertions, 387 deletions
diff --git a/apps/sharebymail/tests/ShareByMailProviderTest.php b/apps/sharebymail/tests/ShareByMailProviderTest.php index 1f9034950b7..8f70516f12c 100644 --- a/apps/sharebymail/tests/ShareByMailProviderTest.php +++ b/apps/sharebymail/tests/ShareByMailProviderTest.php @@ -1,44 +1,24 @@ <?php + +declare(strict_types=1); /** - * @copyright Copyright (c) 2016 Bjoern Schiessle <bjoern@schiessle.org> - * - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Calviño Sánchez <danxuliu@gmail.com> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Joas Schilling <coding@schilljs.com> - * @author John Molakvoæ <skjnldsv@protonmail.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Nicolas SIMIDE <2083596+dems54@users.noreply.github.com> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Stephan Müller <mail@stephanmueller.eu> - * - * @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\ShareByMail\Tests; +use DateTime; use OC\Mail\Message; +use OC\Share20\Share; use OCA\ShareByMail\Settings\SettingsManager; use OCA\ShareByMail\ShareByMailProvider; +use OCP\Activity\IManager as IActivityManager; +use OCP\Constants; use OCP\Defaults; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\File; use OCP\Files\IRootFolder; +use OCP\Files\Node; use OCP\IConfig; use OCP\IDBConnection; use OCP\IL10N; @@ -51,8 +31,14 @@ use OCP\Mail\IMessage; use OCP\Security\Events\GenerateSecurePasswordEvent; use OCP\Security\IHasher; use OCP\Security\ISecureRandom; +use OCP\Security\PasswordContext; +use OCP\Server; +use OCP\Share\Exceptions\ShareNotFound; +use OCP\Share\IAttributes; use OCP\Share\IManager; use OCP\Share\IShare; +use OCP\Util; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; @@ -63,80 +49,52 @@ use Test\TestCase; * @group DB */ class ShareByMailProviderTest extends TestCase { - /** @var IConfig */ - private $config; - - /** @var IDBConnection */ - private $connection; - - /** @var IManager | \PHPUnit\Framework\MockObject\MockObject */ - private $shareManager; - - /** @var IL10N | \PHPUnit\Framework\MockObject\MockObject */ - private $l; - - /** @var LoggerInterface | \PHPUnit\Framework\MockObject\MockObject */ - private $logger; - /** @var IRootFolder | \PHPUnit\Framework\MockObject\MockObject */ - private $rootFolder; - - /** @var IUserManager | \PHPUnit\Framework\MockObject\MockObject */ - private $userManager; - - /** @var ISecureRandom | \PHPUnit\Framework\MockObject\MockObject */ - private $secureRandom; - - /** @var IMailer | \PHPUnit\Framework\MockObject\MockObject */ - private $mailer; - - /** @var IURLGenerator | \PHPUnit\Framework\MockObject\MockObject */ - private $urlGenerator; - - /** @var IShare | \PHPUnit\Framework\MockObject\MockObject */ - private $share; - - /** @var \OCP\Activity\IManager | \PHPUnit\Framework\MockObject\MockObject */ - private $activityManager; - - /** @var SettingsManager | \PHPUnit\Framework\MockObject\MockObject */ - private $settingsManager; - - /** @var Defaults|\PHPUnit\Framework\MockObject\MockObject */ - private $defaults; - - /** @var IHasher | \PHPUnit\Framework\MockObject\MockObject */ - private $hasher; - - /** @var IEventDispatcher */ - private $eventDispatcher; + private IDBConnection $connection; + + private IL10N&MockObject $l; + private IShare&MockObject $share; + private IConfig&MockObject $config; + private IMailer&MockObject $mailer; + private IHasher&MockObject $hasher; + private Defaults&MockObject $defaults; + private IManager&MockObject $shareManager; + private LoggerInterface&MockObject $logger; + private IRootFolder&MockObject $rootFolder; + private IUserManager&MockObject $userManager; + private ISecureRandom&MockObject $secureRandom; + private IURLGenerator&MockObject $urlGenerator; + private SettingsManager&MockObject $settingsManager; + private IActivityManager&MockObject $activityManager; + private IEventDispatcher&MockObject $eventDispatcher; protected function setUp(): void { parent::setUp(); - $this->config = $this->getMockBuilder(IConfig::class)->getMock(); - $this->connection = \OC::$server->getDatabaseConnection(); + $this->connection = Server::get(IDBConnection::class); - $this->l = $this->getMockBuilder(IL10N::class)->getMock(); + $this->l = $this->createMock(IL10N::class); $this->l->method('t') ->willReturnCallback(function ($text, $parameters = []) { return vsprintf($text, $parameters); }); - $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); - $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock(); - $this->userManager = $this->getMockBuilder(IUserManager::class)->getMock(); - $this->secureRandom = $this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock(); - $this->mailer = $this->getMockBuilder('\OCP\Mail\IMailer')->getMock(); - $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock(); - $this->share = $this->getMockBuilder(IShare::class)->getMock(); - $this->activityManager = $this->getMockBuilder('OCP\Activity\IManager')->getMock(); - $this->settingsManager = $this->getMockBuilder(SettingsManager::class)->disableOriginalConstructor()->getMock(); + $this->config = $this->createMock(IConfig::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->rootFolder = $this->createMock('OCP\Files\IRootFolder'); + $this->userManager = $this->createMock(IUserManager::class); + $this->secureRandom = $this->createMock('\OCP\Security\ISecureRandom'); + $this->mailer = $this->createMock('\OCP\Mail\IMailer'); + $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->share = $this->createMock(IShare::class); + $this->activityManager = $this->createMock('OCP\Activity\IManager'); + $this->settingsManager = $this->createMock(SettingsManager::class); $this->defaults = $this->createMock(Defaults::class); - $this->hasher = $this->getMockBuilder(IHasher::class)->getMock(); - $this->eventDispatcher = $this->getMockBuilder(IEventDispatcher::class)->getMock(); - $this->shareManager = $this->getMockBuilder(IManager::class)->getMock(); + $this->hasher = $this->createMock(IHasher::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); + $this->shareManager = $this->createMock(IManager::class); $this->userManager->expects($this->any())->method('userExists')->willReturn(true); + $this->config->expects($this->any())->method('getAppValue')->with('core', 'enforce_strict_email_check')->willReturn('yes'); } /** @@ -146,9 +104,9 @@ class ShareByMailProviderTest extends TestCase { * @return \PHPUnit\Framework\MockObject\MockObject | ShareByMailProvider */ private function getInstance(array $mockedMethods = []) { - $instance = $this->getMockBuilder('OCA\ShareByMail\ShareByMailProvider') - ->setConstructorArgs( - [ + if (!empty($mockedMethods)) { + return $this->getMockBuilder(ShareByMailProvider::class) + ->setConstructorArgs([ $this->config, $this->connection, $this->secureRandom, @@ -163,13 +121,10 @@ class ShareByMailProviderTest extends TestCase { $this->defaults, $this->hasher, $this->eventDispatcher, - $this->shareManager - ] - ); - - if (!empty($mockedMethods)) { - $instance->setMethods($mockedMethods); - return $instance->getMock(); + $this->shareManager, + ]) + ->onlyMethods($mockedMethods) + ->getMock(); } return new ShareByMailProvider( @@ -187,53 +142,67 @@ class ShareByMailProviderTest extends TestCase { $this->defaults, $this->hasher, $this->eventDispatcher, - $this->shareManager + $this->shareManager, ); } protected function tearDown(): void { - $this->connection->getQueryBuilder()->delete('share')->execute(); + $this->connection + ->getQueryBuilder() + ->delete('share') + ->executeStatement(); parent::tearDown(); } - public function testCreate() { + public function testCreate(): void { $expectedShare = $this->createMock(IShare::class); - $share = $this->getMockBuilder(IShare::class)->getMock(); + $share = $this->createMock(IShare::class); $share->expects($this->any())->method('getSharedWith')->willReturn('user1'); - $node = $this->getMockBuilder(File::class)->getMock(); + $node = $this->createMock(File::class); $node->expects($this->any())->method('getName')->willReturn('filename'); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'sendPassword']); + $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'sendEmail', 'sendPassword']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42); $instance->expects($this->once())->method('createShareActivity')->with($share); $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare']); $instance->expects($this->once())->method('createShareObject')->with(['rawShare'])->willReturn($expectedShare); - $instance->expects($this->any())->method('sendPassword')->willReturn(true); $share->expects($this->any())->method('getNode')->willReturn($node); - $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false); - $this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true); + + // As share api link password is not enforced, the password will not be generated. + $this->shareManager->expects($this->once())->method('shareApiLinkEnforcePassword')->willReturn(false); + $this->settingsManager->expects($this->never())->method('sendPasswordByMail'); + + // Mail notification is triggered by the share manager. + $instance->expects($this->never())->method('sendEmail'); + $instance->expects($this->never())->method('sendPassword'); $this->assertSame($expectedShare, $instance->create($share)); } - public function testCreateSendPasswordByMailWithoutEnforcedPasswordProtection() { + public function testCreateSendPasswordByMailWithoutEnforcedPasswordProtection(): void { $expectedShare = $this->createMock(IShare::class); - $share = $this->getMockBuilder(IShare::class)->getMock(); + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('filename'); + + $share = $this->createMock(IShare::class); $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@examplelölöl.com'); $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false); $share->expects($this->any())->method('getSharedBy')->willReturn('owner'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); - $node = $this->getMockBuilder(File::class)->getMock(); - $node->expects($this->any())->method('getName')->willReturn('filename'); - - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']); + // Assume the mail address is valid. + $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); + $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42); $instance->expects($this->once())->method('createShareActivity')->with($share); @@ -246,32 +215,45 @@ class ShareByMailProviderTest extends TestCase { $this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true); $instance->expects($this->never())->method('autoGeneratePassword'); - $this->mailer->expects($this->never())->method('send'); + // No password is set and no password sent via talk is requested + $instance->expects($this->once())->method('sendEmail')->with($share, ['receiver@examplelölöl.com']); + $instance->expects($this->never())->method('sendPassword'); + $instance->expects($this->never())->method('sendPasswordToOwner'); + // The manager sends the mail notification. + // For the sake of testing simplicity, we will handle it ourselves. $this->assertSame($expectedShare, $instance->create($share)); + $instance->sendMailNotification($share); } - public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithPermanentPassword() { + public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithPermanentPassword(): void { $expectedShare = $this->createMock(IShare::class); - $share = $this->getMockBuilder(IShare::class)->getMock(); + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('filename'); + + $share = $this->createMock(IShare::class); $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com'); $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false); $share->expects($this->any())->method('getSharedBy')->willReturn('owner'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); - $node = $this->getMockBuilder(File::class)->getMock(); - $node->expects($this->any())->method('getName')->willReturn('filename'); + // Assume the mail address is valid. + $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']); + $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42); $instance->expects($this->once())->method('createShareActivity')->with($share); - $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare']); - $instance->expects($this->once())->method('createShareObject')->with(['rawShare'])->willReturn($expectedShare); + $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']); + $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare); $share->expects($this->any())->method('getNode')->willReturn($node); - $share->expects($this->once())->method('getPassword')->willReturn('password'); + $share->expects($this->any())->method('getPassword')->willReturn('password'); $this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed'); $share->expects($this->once())->method('setPassword')->with('passwordHashed'); @@ -281,60 +263,86 @@ class ShareByMailProviderTest extends TestCase { $this->config->expects($this->once())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false); $instance->expects($this->never())->method('autoGeneratePassword'); + // A password is set but no password sent via talk has been requested + $instance->expects($this->once())->method('sendEmail')->with($share, ['receiver@example.com']); + $instance->expects($this->once())->method('sendPassword')->with($share, 'password'); + $instance->expects($this->never())->method('sendPasswordToOwner'); + $this->assertSame($expectedShare, $instance->create($share)); + $instance->sendMailNotification($share); } - public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithoutPermanentPassword() { + public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithoutPermanentPassword(): void { $expectedShare = $this->createMock(IShare::class); - $share = $this->getMockBuilder(IShare::class)->getMock(); + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('filename'); + + $share = $this->createMock(IShare::class); $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com'); $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false); $share->expects($this->any())->method('getSharedBy')->willReturn('owner'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); - $node = $this->getMockBuilder(File::class)->getMock(); - $node->expects($this->any())->method('getName')->willReturn('filename'); + // Assume the mail address is valid. + $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']); + $instance = $this->getInstance([ + 'getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', + 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', + 'sendEmail', 'sendPassword', 'sendPasswordToOwner', + ]); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42); $instance->expects($this->once())->method('createShareActivity')->with($share); - $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare']); - $instance->expects($this->once())->method('createShareObject')->with(['rawShare'])->willReturn($expectedShare); + $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']); + $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare); $share->expects($this->any())->method('getNode')->willReturn($node); - $share->expects($this->once())->method('getPassword')->willReturn('password'); + $share->expects($this->any())->method('getPassword')->willReturn('password'); $this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed'); $share->expects($this->once())->method('setPassword')->with('passwordHashed'); - // The given password (but not the autogenerated password) should be - // mailed to the receiver of the share because permanent passwords are enforced. + // No password is generated, so no emails need to be sent + // aside from the main email notification. $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false); $instance->expects($this->never())->method('autoGeneratePassword'); - $this->config->expects($this->any())->method('getSystemValue')->withConsecutive( - ['sharing.enable_mail_link_password_expiration'], - ['sharing.enable_mail_link_password_expiration'], - ['sharing.mail_link_password_expiration_interval'] - )->willReturnOnConsecutiveCalls( - true, - true, - 3600 - ); + $this->config->expects($this->once())->method('getSystemValue') + ->with('sharing.enable_mail_link_password_expiration') + ->willReturn(true); + + // No password has been set and no password sent via talk has been requested, + // but password has been enforced for the whole instance and will be generated. + $instance->expects($this->once())->method('sendEmail')->with($share, ['receiver@example.com']); + $instance->expects($this->never())->method('sendPassword'); + $instance->expects($this->never())->method('sendPasswordToOwner'); $this->assertSame($expectedShare, $instance->create($share)); + $instance->sendMailNotification($share); } - public function testCreateSendPasswordByMailWithEnforcedPasswordProtectionWithPermanentPassword() { + public function testCreateSendPasswordByMailWithEnforcedPasswordProtectionWithPermanentPassword(): void { $expectedShare = $this->createMock(IShare::class); - $share = $this->getMockBuilder(IShare::class)->getMock(); + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('filename'); + + $share = $this->createMock(IShare::class); $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com'); $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false); $share->expects($this->any())->method('getSharedBy')->willReturn('owner'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); - $node = $this->getMockBuilder(File::class)->getMock(); - $node->expects($this->any())->method('getName')->willReturn('filename'); + $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) + ->willReturn('https://example.com/file.txt'); $this->secureRandom->expects($this->once()) ->method('generate') @@ -342,18 +350,21 @@ class ShareByMailProviderTest extends TestCase { ->willReturn('autogeneratedPassword'); $this->eventDispatcher->expects($this->once()) ->method('dispatchTyped') - ->with(new GenerateSecurePasswordEvent()); + ->with(new GenerateSecurePasswordEvent(PasswordContext::SHARING)); + + // Assume the mail address is valid. + $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'createPasswordSendActivity']); + $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'createPasswordSendActivity', 'sendPasswordToOwner']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42); $instance->expects($this->once())->method('createShareActivity')->with($share); - $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare']); - $instance->expects($this->once())->method('createShareObject')->with(['rawShare'])->willReturn($expectedShare); - $share->expects($this->any())->method('getNode')->willReturn($node); + $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'autogeneratedPassword']); + $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'autogeneratedPassword'])->willReturn($expectedShare); - $share->expects($this->once())->method('getPassword')->willReturn(null); + // Initially not set, but will be set by the autoGeneratePassword method. + $share->expects($this->exactly(3))->method('getPassword')->willReturnOnConsecutiveCalls(null, 'autogeneratedPassword', 'autogeneratedPassword'); $this->hasher->expects($this->once())->method('hash')->with('autogeneratedPassword')->willReturn('autogeneratedPasswordHashed'); $share->expects($this->once())->method('setPassword')->with('autogeneratedPasswordHashed'); @@ -363,41 +374,79 @@ class ShareByMailProviderTest extends TestCase { $this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true); $message = $this->createMock(IMessage::class); - $message->expects($this->once())->method('setTo')->with(['receiver@example.com']); - $this->mailer->expects($this->once())->method('createMessage')->willReturn($message); - $this->mailer->expects($this->once())->method('createEMailTemplate')->with('sharebymail.RecipientPasswordNotification', [ - 'filename' => 'filename', - 'password' => 'autogeneratedPassword', - 'initiator' => 'owner', - 'initiatorEmail' => null, - 'shareWith' => 'receiver@example.com', - ]); - $this->mailer->expects($this->once())->method('send'); + $message->expects($this->exactly(2))->method('setTo')->with(['receiver@example.com']); + $this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message); + $calls = [ + [ + 'sharebymail.RecipientNotification', + [ + 'filename' => 'filename', + 'link' => 'https://example.com/file.txt', + 'initiator' => 'owner', + 'expiration' => null, + 'shareWith' => 'receiver@example.com', + 'note' => '', + ], + ], + [ + 'sharebymail.RecipientPasswordNotification', + [ + 'filename' => 'filename', + 'password' => 'autogeneratedPassword', + 'initiator' => 'owner', + 'initiatorEmail' => null, + 'shareWith' => 'receiver@example.com', + ], + ], + ]; + $this->mailer->expects($this->exactly(2)) + ->method('createEMailTemplate') + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return $this->createMock(IEMailTemplate::class); + }); + + // Main email notification is sent as well as the password + // to the recipient because shareApiLinkEnforcePassword is enabled. + $this->mailer->expects($this->exactly(2))->method('send'); + $instance->expects($this->never())->method('sendPasswordToOwner'); $this->assertSame($expectedShare, $instance->create($share)); + $instance->sendMailNotification($share); } - public function testCreateSendPasswordByMailWithPasswordAndWithEnforcedPasswordProtectionWithPermanentPassword() { + public function testCreateSendPasswordByMailWithPasswordAndWithEnforcedPasswordProtectionWithPermanentPassword(): void { $expectedShare = $this->createMock(IShare::class); - $share = $this->getMockBuilder(IShare::class)->getMock(); + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('filename'); + + $share = $this->createMock(IShare::class); $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com'); $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false); $share->expects($this->any())->method('getSharedBy')->willReturn('owner'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); - $node = $this->getMockBuilder(File::class)->getMock(); - $node->expects($this->any())->method('getName')->willReturn('filename'); + $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) + ->willReturn('https://example.com/file.txt'); - $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']); + // Assume the mail address is valid. + $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); + + $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendPasswordToOwner']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42); $instance->expects($this->once())->method('createShareActivity')->with($share); - $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare']); - $instance->expects($this->once())->method('createShareObject')->with(['rawShare'])->willReturn($expectedShare); - $share->expects($this->any())->method('getNode')->willReturn($node); + $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']); + $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare); - $share->expects($this->once())->method('getPassword')->willReturn('password'); + $share->expects($this->exactly(3))->method('getPassword')->willReturn('password'); $this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed'); $share->expects($this->once())->method('setPassword')->with('passwordHashed'); @@ -409,41 +458,86 @@ class ShareByMailProviderTest extends TestCase { $instance->expects($this->never())->method('autoGeneratePassword'); $message = $this->createMock(IMessage::class); - $message->expects($this->once())->method('setTo')->with(['receiver@example.com']); - $this->mailer->expects($this->once())->method('createMessage')->willReturn($message); - $this->mailer->expects($this->once())->method('createEMailTemplate')->with('sharebymail.RecipientPasswordNotification', [ - 'filename' => 'filename', - 'password' => 'password', - 'initiator' => 'owner', - 'initiatorEmail' => null, - 'shareWith' => 'receiver@example.com', - ]); - $this->mailer->expects($this->once())->method('send'); + $message->expects($this->exactly(2))->method('setTo')->with(['receiver@example.com']); + $this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message); + + $calls = [ + [ + 'sharebymail.RecipientNotification', + [ + 'filename' => 'filename', + 'link' => 'https://example.com/file.txt', + 'initiator' => 'owner', + 'expiration' => null, + 'shareWith' => 'receiver@example.com', + 'note' => '', + ], + ], + [ + 'sharebymail.RecipientPasswordNotification', + [ + 'filename' => 'filename', + 'password' => 'password', + 'initiator' => 'owner', + 'initiatorEmail' => null, + 'shareWith' => 'receiver@example.com', + ], + ], + ]; + $this->mailer->expects($this->exactly(2)) + ->method('createEMailTemplate') + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return $this->createMock(IEMailTemplate::class); + }); + + // Main email notification is sent as well as the password + // to the recipient because the password is set. + $this->mailer->expects($this->exactly(2))->method('send'); + $instance->expects($this->never())->method('sendPasswordToOwner'); $this->assertSame($expectedShare, $instance->create($share)); + $instance->sendMailNotification($share); } - public function testCreateSendPasswordByTalkWithEnforcedPasswordProtectionWithPermanentPassword() { + public function testCreateSendPasswordByTalkWithEnforcedPasswordProtectionWithPermanentPassword(): void { $expectedShare = $this->createMock(IShare::class); - $share = $this->getMockBuilder(IShare::class)->getMock(); + // The owner of the share. + $owner = $this->createMock(IUser::class); + $this->userManager->expects($this->any())->method('get')->with('owner')->willReturn($owner); + $owner->expects($this->any())->method('getEMailAddress')->willReturn('owner@example.com'); + $owner->expects($this->any())->method('getDisplayName')->willReturn('owner'); + + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('filename'); + + $share = $this->createMock(IShare::class); $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com'); $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(true); $share->expects($this->any())->method('getSharedBy')->willReturn('owner'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); - $node = $this->getMockBuilder(File::class)->getMock(); - $node->expects($this->any())->method('getName')->willReturn('filename'); + $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) + ->willReturn('https://example.com/file.txt'); + + // Assume the mail address is valid. + $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']); $instance->expects($this->once())->method('getSharedWith')->willReturn([]); $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42); $instance->expects($this->once())->method('createShareActivity')->with($share); - $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare']); - $instance->expects($this->once())->method('createShareObject')->with(['rawShare'])->willReturn($expectedShare); - $share->expects($this->any())->method('getNode')->willReturn($node); + $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'autogeneratedPassword']); + $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'autogeneratedPassword'])->willReturn($expectedShare); - $share->expects($this->once())->method('getPassword')->willReturn(null); + $share->expects($this->exactly(4))->method('getPassword')->willReturnOnConsecutiveCalls(null, 'autogeneratedPassword', 'autogeneratedPassword', 'autogeneratedPassword'); $this->hasher->expects($this->once())->method('hash')->with('autogeneratedPassword')->willReturn('autogeneratedPasswordHashed'); $share->expects($this->once())->method('setPassword')->with('autogeneratedPasswordHashed'); @@ -454,31 +548,129 @@ class ShareByMailProviderTest extends TestCase { $instance->expects($this->once())->method('autoGeneratePassword')->with($share)->willReturn('autogeneratedPassword'); $message = $this->createMock(IMessage::class); - $message->expects($this->once())->method('setTo')->with(['owner@example.com' => 'Owner display name']); - $this->mailer->expects($this->once())->method('createMessage')->willReturn($message); - $this->mailer->expects($this->once())->method('createEMailTemplate')->with('sharebymail.OwnerPasswordNotification', [ - 'filename' => 'filename', - 'password' => 'autogeneratedPassword', - 'initiator' => 'Owner display name', - 'initiatorEmail' => 'owner@example.com', - 'shareWith' => 'receiver@example.com', - ]); - $this->mailer->expects($this->once())->method('send'); + $setToCalls = [ + [['receiver@example.com']], + [['owner@example.com' => 'owner']], + ]; + $message->expects($this->exactly(2)) + ->method('setTo') + ->willReturnCallback(function () use (&$setToCalls, $message) { + $expected = array_shift($setToCalls); + $this->assertEquals($expected, func_get_args()); + return $message; + }); + $this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message); - $user = $this->createMock(IUser::class); - $this->userManager->expects($this->once())->method('get')->with('owner')->willReturn($user); - $user->expects($this->once())->method('getDisplayName')->willReturn('Owner display name'); - $user->expects($this->once())->method('getEMailAddress')->willReturn('owner@example.com'); + $calls = [ + [ + 'sharebymail.RecipientNotification', + [ + 'filename' => 'filename', + 'link' => 'https://example.com/file.txt', + 'initiator' => 'owner', + 'expiration' => null, + 'shareWith' => 'receiver@example.com', + 'note' => '', + ], + ], + [ + 'sharebymail.OwnerPasswordNotification', + [ + 'filename' => 'filename', + 'password' => 'autogeneratedPassword', + 'initiator' => 'owner', + 'initiatorEmail' => 'owner@example.com', + 'shareWith' => 'receiver@example.com', + ], + ], + ]; + $this->mailer->expects($this->exactly(2)) + ->method('createEMailTemplate') + ->willReturnCallback(function () use (&$calls) { + $expected = array_shift($calls); + $this->assertEquals($expected, func_get_args()); + return $this->createMock(IEMailTemplate::class); + }); + + // Main email notification is sent as well as the password to owner + // because the password is set and SendPasswordByTalk is enabled. + $this->mailer->expects($this->exactly(2))->method('send'); $this->assertSame($expectedShare, $instance->create($share)); + $instance->sendMailNotification($share); } + // If attributes is set to multiple emails, use them as BCC + public function sendNotificationToMultipleEmails() { + $expectedShare = $this->createMock(IShare::class); - public function testCreateFailed() { + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('filename'); + + $share = $this->createMock(IShare::class); + $share->expects($this->any())->method('getSharedWith')->willReturn(''); + $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false); + $share->expects($this->any())->method('getSharedBy')->willReturn('owner'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); + + $attributes = $this->createMock(IAttributes::class); + $share->expects($this->any())->method('getAttributes')->willReturn($attributes); + $attributes->expects($this->any())->method('getAttribute')->with('shareWith', 'emails')->willReturn([ + 'receiver1@example.com', + 'receiver2@example.com', + 'receiver3@example.com', + ]); + + // Assume the mail address is valid. + $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); + + $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']); + + $instance->expects($this->once())->method('getSharedWith')->willReturn([]); + $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42); + $instance->expects($this->once())->method('createShareActivity')->with($share); + $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']); + $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare); + $share->expects($this->any())->method('getNode')->willReturn($node); + + $share->expects($this->any())->method('getPassword')->willReturn('password'); + $this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed'); + $share->expects($this->once())->method('setPassword')->with('passwordHashed'); + + // The given password (but not the autogenerated password) should not be + // mailed to the receiver of the share because permanent passwords are not enforced. + $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false); + $this->config->expects($this->once())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false); + $instance->expects($this->never())->method('autoGeneratePassword'); + + // A password is set but no password sent via talk has been requested + $instance->expects($this->once())->method('sendEmail') + ->with($share, ['receiver1@example.com', 'receiver2@example.com', 'receiver3@example.com']); + $instance->expects($this->once())->method('sendPassword')->with($share, 'password'); + $instance->expects($this->never())->method('sendPasswordToOwner'); + + + $message = $this->createMock(IMessage::class); + $message->expects($this->never())->method('setTo'); + $message->expects($this->exactly(2))->method('setBcc')->with(['receiver1@example.com', 'receiver2@example.com', 'receiver3@example.com']); + $this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message); + + // Main email notification is sent as well as the password + // to recipients because the password is set. + $this->mailer->expects($this->exactly(2))->method('send'); + + $this->assertSame($expectedShare, $instance->create($share)); + $instance->sendMailNotification($share); + } + + public function testCreateFailed(): void { $this->expectException(\Exception::class); $this->share->expects($this->once())->method('getSharedWith')->willReturn('user1'); - $node = $this->getMockBuilder('OCP\Files\Node')->getMock(); + $node = $this->createMock('OCP\Files\Node'); $node->expects($this->any())->method('getName')->willReturn('fileName'); $this->share->expects($this->any())->method('getNode')->willReturn($node); @@ -494,40 +686,15 @@ class ShareByMailProviderTest extends TestCase { ); } - public function testCreateMailShare() { + public function testCreateMailShare(): void { $this->share->expects($this->any())->method('getToken')->willReturn('token'); $this->share->expects($this->once())->method('setToken')->with('token'); $this->share->expects($this->any())->method('getSharedBy')->willReturn('validby@valid.com'); $this->share->expects($this->any())->method('getSharedWith')->willReturn('validwith@valid.com'); $this->share->expects($this->any())->method('getNote')->willReturn('Check this!'); - $node = $this->getMockBuilder('OCP\Files\Node')->getMock(); - $node->expects($this->any())->method('getName')->willReturn('fileName'); - $this->share->expects($this->any())->method('getNode')->willReturn($node); - - $instance = $this->getInstance(['generateToken', 'addShareToDB', 'sendMailNotification']); - - $instance->expects($this->once())->method('generateToken')->willReturn('token'); - $instance->expects($this->once())->method('addShareToDB')->willReturn(42); - $instance->expects($this->once())->method('sendMailNotification'); - $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') - ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']); - $instance->expects($this->once())->method('sendMailNotification'); - - $this->assertSame(42, - $this->invokePrivate($instance, 'createMailShare', [$this->share]) - ); - } + $this->share->expects($this->any())->method('getMailSend')->willReturn(true); - - public function testCreateMailShareFailed() { - $this->expectException(\OCP\HintException::class); - - $this->share->expects($this->any())->method('getToken')->willReturn('token'); - $this->share->expects($this->once())->method('setToken')->with('token'); - $this->share->expects($this->any())->method('getSharedBy')->willReturn('validby@valid.com'); - $this->share->expects($this->any())->method('getSharedWith')->willReturn('validwith@valid.com'); - $this->share->expects($this->any())->method('getNote')->willReturn('Check this!'); - $node = $this->getMockBuilder('OCP\Files\Node')->getMock(); + $node = $this->createMock('OCP\Files\Node'); $node->expects($this->any())->method('getName')->willReturn('fileName'); $this->share->expects($this->any())->method('getNode')->willReturn($node); @@ -535,22 +702,16 @@ class ShareByMailProviderTest extends TestCase { $instance->expects($this->once())->method('generateToken')->willReturn('token'); $instance->expects($this->once())->method('addShareToDB')->willReturn(42); - $instance->expects($this->once())->method('sendMailNotification'); - $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') - ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']); - $instance->expects($this->once())->method('sendMailNotification') - ->willReturnCallback( - function () { - throw new \Exception('should be converted to a hint exception'); - } - ); + + // The manager handle the mail sending + $instance->expects($this->never())->method('sendMailNotification'); $this->assertSame(42, $this->invokePrivate($instance, 'createMailShare', [$this->share]) ); } - public function testGenerateToken() { + public function testGenerateToken(): void { $instance = $this->getInstance(); $this->secureRandom->expects($this->once())->method('generate')->willReturn('token'); @@ -560,7 +721,7 @@ class ShareByMailProviderTest extends TestCase { ); } - public function testAddShareToDB() { + public function testAddShareToDB(): void { $itemSource = 11; $itemType = 'file'; $shareWith = 'user@server.com'; @@ -623,7 +784,7 @@ class ShareByMailProviderTest extends TestCase { $this->assertSame($expiration->getTimestamp(), \DateTime::createFromFormat('Y-m-d H:i:s', $result[0]['expiration'])->getTimestamp()); } - public function testUpdate() { + public function testUpdate(): void { $itemSource = 11; $itemType = 'file'; $shareWith = 'user@server.com'; @@ -643,6 +804,8 @@ class ShareByMailProviderTest extends TestCase { $this->share->expects($this->once())->method('getSharedBy')->willReturn($sharedBy); $this->share->expects($this->any())->method('getNote')->willReturn($note); $this->share->expects($this->atLeastOnce())->method('getId')->willReturn($id); + $this->share->expects($this->atLeastOnce())->method('getNodeId')->willReturn($itemSource); + $this->share->expects($this->once())->method('getSharedWith')->willReturn($shareWith); $this->assertSame($this->share, $instance->update($this->share) @@ -669,7 +832,7 @@ class ShareByMailProviderTest extends TestCase { $this->assertSame($note, $result[0]['note']); } - public function dataUpdateSendPassword() { + public static function dataUpdateSendPassword(): array { return [ ['password', 'hashed', 'hashed new', false, false, true], ['', 'hashed', 'hashed new', false, false, false], @@ -681,30 +844,21 @@ class ShareByMailProviderTest extends TestCase { ]; } - /** - * @dataProvider dataUpdateSendPassword - * - * @param string|null plainTextPassword - * @param string originalPassword - * @param string newPassword - * @param string originalSendPasswordByTalk - * @param string newSendPasswordByTalk - * @param bool sendMail - */ - public function testUpdateSendPassword($plainTextPassword, string $originalPassword, string $newPassword, $originalSendPasswordByTalk, $newSendPasswordByTalk, bool $sendMail) { - $node = $this->getMockBuilder(File::class)->getMock(); + #[\PHPUnit\Framework\Attributes\DataProvider('dataUpdateSendPassword')] + public function testUpdateSendPassword(?string $plainTextPassword, string $originalPassword, string $newPassword, bool $originalSendPasswordByTalk, bool $newSendPasswordByTalk, bool $sendMail): void { + $node = $this->createMock(File::class); $node->expects($this->any())->method('getName')->willReturn('filename'); $this->settingsManager->method('sendPasswordByMail')->willReturn(true); - $originalShare = $this->getMockBuilder(IShare::class)->getMock(); + $originalShare = $this->createMock(IShare::class); $originalShare->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com'); $originalShare->expects($this->any())->method('getNode')->willReturn($node); $originalShare->expects($this->any())->method('getId')->willReturn(42); $originalShare->expects($this->any())->method('getPassword')->willReturn($originalPassword); $originalShare->expects($this->any())->method('getSendPasswordByTalk')->willReturn($originalSendPasswordByTalk); - $share = $this->getMockBuilder(IShare::class)->getMock(); + $share = $this->createMock(IShare::class); $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com'); $share->expects($this->any())->method('getNode')->willReturn($node); $share->expects($this->any())->method('getId')->willReturn(42); @@ -732,7 +886,7 @@ class ShareByMailProviderTest extends TestCase { ); } - public function testDelete() { + public function testDelete(): void { $instance = $this->getInstance(['removeShareFromTable', 'createShareActivity']); $this->share->expects($this->once())->method('getId')->willReturn(42); $instance->expects($this->once())->method('removeShareFromTable')->with(42); @@ -740,7 +894,7 @@ class ShareByMailProviderTest extends TestCase { $instance->delete($this->share); } - public function testGetShareById() { + public function testGetShareById(): void { $instance = $this->getInstance(['createShareObject']); $itemSource = 11; @@ -751,7 +905,7 @@ class ShareByMailProviderTest extends TestCase { $permissions = 1; $token = 'token'; - $this->createDummyShare($itemType, $itemSource, $shareWith, "user1wrong", "user2wrong", $permissions, $token); + $this->createDummyShare($itemType, $itemSource, $shareWith, 'user1wrong', 'user2wrong', $permissions, $token); $id2 = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token); $instance->expects($this->once())->method('createShareObject') @@ -770,8 +924,8 @@ class ShareByMailProviderTest extends TestCase { } - public function testGetShareByIdFailed() { - $this->expectException(\OCP\Share\Exceptions\ShareNotFound::class); + public function testGetShareByIdFailed(): void { + $this->expectException(ShareNotFound::class); $instance = $this->getInstance(['createShareObject']); @@ -788,7 +942,7 @@ class ShareByMailProviderTest extends TestCase { $instance->getShareById($id + 1); } - public function testGetShareByPath() { + public function testGetShareByPath(): void { $itemSource = 11; $itemType = 'file'; $shareWith = 'user@server.com'; @@ -797,7 +951,7 @@ class ShareByMailProviderTest extends TestCase { $permissions = 1; $token = 'token'; - $node = $this->getMockBuilder('OCP\Files\Node')->getMock(); + $node = $this->createMock(Node::class); $node->expects($this->once())->method('getId')->willReturn($itemSource); @@ -823,7 +977,7 @@ class ShareByMailProviderTest extends TestCase { $this->assertInstanceOf('OCP\Share\IShare', $result[0]); } - public function testGetShareByToken() { + public function testGetShareByToken(): void { $itemSource = 11; $itemType = 'file'; $shareWith = 'user@server.com'; @@ -853,8 +1007,8 @@ class ShareByMailProviderTest extends TestCase { } - public function testGetShareByTokenFailed() { - $this->expectException(\OCP\Share\Exceptions\ShareNotFound::class); + public function testGetShareByTokenFailed(): void { + $this->expectException(ShareNotFound::class); $itemSource = 11; @@ -868,7 +1022,7 @@ class ShareByMailProviderTest extends TestCase { $instance = $this->getInstance(['createShareObject']); $idMail = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token); - $idPublic = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, "token2", '', IShare::TYPE_LINK); + $idPublic = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, 'token2', '', IShare::TYPE_LINK); $this->assertTrue($idMail !== $idPublic); @@ -877,7 +1031,7 @@ class ShareByMailProviderTest extends TestCase { ); } - public function testRemoveShareFromTable() { + public function testRemoveShareFromTable(): void { $itemSource = 11; $itemType = 'file'; $shareWith = 'user@server.com'; @@ -915,7 +1069,7 @@ class ShareByMailProviderTest extends TestCase { $this->assertEmpty($after); } - public function testUserDeleted() { + public function testUserDeleted(): void { $itemSource = 11; $itemType = 'file'; $shareWith = 'user@server.com'; @@ -954,7 +1108,7 @@ class ShareByMailProviderTest extends TestCase { $this->assertSame($id, (int)$after[0]['id']); } - public function testGetRawShare() { + public function testGetRawShare(): void { $itemSource = 11; $itemType = 'file'; $shareWith = 'user@server.com'; @@ -980,8 +1134,8 @@ class ShareByMailProviderTest extends TestCase { } - public function testGetRawShareFailed() { - $this->expectException(\OCP\Share\Exceptions\ShareNotFound::class); + public function testGetRawShareFailed(): void { + $this->expectException(ShareNotFound::class); $itemSource = 11; $itemType = 'file'; @@ -1025,19 +1179,19 @@ class ShareByMailProviderTest extends TestCase { return (int)$id; } - public function testGetSharesInFolder() { - $userManager = \OC::$server->getUserManager(); - $rootFolder = \OC::$server->getRootFolder(); + public function testGetSharesInFolder(): void { + $userManager = Server::get(IUserManager::class); + $rootFolder = Server::get(IRootFolder::class); $this->shareManager->expects($this->any()) ->method('newShare') - ->willReturn(new \OC\Share20\Share($rootFolder, $userManager)); + ->willReturn(new Share($rootFolder, $userManager)); $provider = $this->getInstance(['sendMailNotification', 'createShareActivity']); $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $u1 = $userManager->createUser('testFed', md5(time())); - $u2 = $userManager->createUser('testFed2', md5(time())); + $u1 = $userManager->createUser('testFed', md5((string)time())); + $u2 = $userManager->createUser('testFed2', md5((string)time())); $folder1 = $rootFolder->getUserFolder($u1->getUID())->newFolder('foo'); $file1 = $folder1->newFile('bar1'); @@ -1047,7 +1201,7 @@ class ShareByMailProviderTest extends TestCase { $share1->setSharedWith('user@server.com') ->setSharedBy($u1->getUID()) ->setShareOwner($u1->getUID()) - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file1); $provider->create($share1); @@ -1055,7 +1209,7 @@ class ShareByMailProviderTest extends TestCase { $share2->setSharedWith('user@server.com') ->setSharedBy($u2->getUID()) ->setShareOwner($u1->getUID()) - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($file2); $provider->create($share2); @@ -1072,19 +1226,19 @@ class ShareByMailProviderTest extends TestCase { $u2->delete(); } - public function testGetAccessList() { - $userManager = \OC::$server->getUserManager(); - $rootFolder = \OC::$server->getRootFolder(); + public function testGetAccessList(): void { + $userManager = Server::get(IUserManager::class); + $rootFolder = Server::get(IRootFolder::class); $this->shareManager->expects($this->any()) ->method('newShare') - ->willReturn(new \OC\Share20\Share($rootFolder, $userManager)); + ->willReturn(new Share($rootFolder, $userManager)); $provider = $this->getInstance(['sendMailNotification', 'createShareActivity']); $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true); - $u1 = $userManager->createUser('testFed', md5(time())); - $u2 = $userManager->createUser('testFed2', md5(time())); + $u1 = $userManager->createUser('testFed', md5((string)time())); + $u2 = $userManager->createUser('testFed2', md5((string)time())); $folder = $rootFolder->getUserFolder($u1->getUID())->newFolder('foo'); @@ -1099,7 +1253,7 @@ class ShareByMailProviderTest extends TestCase { $share1->setSharedWith('user@server.com') ->setSharedBy($u1->getUID()) ->setShareOwner($u1->getUID()) - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder); $share1 = $provider->create($share1); @@ -1107,7 +1261,7 @@ class ShareByMailProviderTest extends TestCase { $share2->setSharedWith('user2@server.com') ->setSharedBy($u2->getUID()) ->setShareOwner($u1->getUID()) - ->setPermissions(\OCP\Constants::PERMISSION_READ) + ->setPermissions(Constants::PERMISSION_READ) ->setNode($folder); $share2 = $provider->create($share2); @@ -1140,7 +1294,7 @@ class ShareByMailProviderTest extends TestCase { $u2->delete(); } - public function testSendMailNotificationWithSameUserAndUserEmail() { + public function testSendMailNotificationWithSameUserAndUserEmail(): void { $provider = $this->getInstance(); $user = $this->createMock(IUser::class); $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(true); @@ -1169,19 +1323,134 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('addHeading') - ->with('Mrs. Owner User shared »file.txt« with you'); + ->with('Mrs. Owner User shared file.txt with you'); $template ->expects($this->once()) - ->method('addBodyText') + ->method('addBodyButton') ->with( - 'Mrs. Owner User shared »file.txt« with you. Click the button below to open it.', - 'Mrs. Owner User shared »file.txt« with you.' + 'Open file.txt', + 'https://example.com/file.txt' + ); + $message + ->expects($this->once()) + ->method('setTo') + ->with(['john@doe.com']); + $this->defaults + ->expects($this->once()) + ->method('getName') + ->willReturn('UnitTestCloud'); + $message + ->expects($this->once()) + ->method('setFrom') + ->with([ + Util::getDefaultEmailAddress('UnitTestCloud') => 'Mrs. Owner User via UnitTestCloud' + ]); + $user + ->expects($this->once()) + ->method('getEMailAddress') + ->willReturn('owner@example.com'); + $message + ->expects($this->once()) + ->method('setReplyTo') + ->with(['owner@example.com' => 'Mrs. Owner User']); + $this->defaults + ->expects($this->exactly(2)) + ->method('getSlogan') + ->willReturn('Testing like 1990'); + $template + ->expects($this->once()) + ->method('addFooter') + ->with('UnitTestCloud - Testing like 1990'); + $template + ->expects($this->once()) + ->method('setSubject') + ->with('Mrs. Owner User shared file.txt with you'); + $message + ->expects($this->once()) + ->method('useTemplate') + ->with($template); + + $this->mailer->expects($this->once()) + ->method('validateMailAddress') + ->willReturn(true); + $this->mailer + ->expects($this->once()) + ->method('send') + ->with($message); + + $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) + ->willReturn('https://example.com/file.txt'); + + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('file.txt'); + + $share = $this->createMock(IShare::class); + $share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser'); + $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); + + self::invokePrivate( + $provider, + 'sendMailNotification', + [$share] + ); + } + + public function testSendMailNotificationWithSameUserAndUserEmailAndNote(): void { + $provider = $this->getInstance(); + $user = $this->createMock(IUser::class); + $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(true); + $this->userManager + ->expects($this->once()) + ->method('get') + ->with('OwnerUser') + ->willReturn($user); + $user + ->expects($this->once()) + ->method('getDisplayName') + ->willReturn('Mrs. Owner User'); + $message = $this->createMock(Message::class); + $this->mailer + ->expects($this->once()) + ->method('createMessage') + ->willReturn($message); + $template = $this->createMock(IEMailTemplate::class); + $this->mailer + ->expects($this->once()) + ->method('createEMailTemplate') + ->willReturn($template); + $template + ->expects($this->once()) + ->method('addHeader'); + $template + ->expects($this->once()) + ->method('addHeading') + ->with('Mrs. Owner User shared file.txt with you'); + + $this->urlGenerator->expects($this->once())->method('imagePath') + ->with('core', 'caldav/description.png') + ->willReturn('core/img/caldav/description.png'); + $this->urlGenerator->expects($this->once())->method('getAbsoluteURL') + ->with('core/img/caldav/description.png') + ->willReturn('https://example.com/core/img/caldav/description.png'); + $template + ->expects($this->once()) + ->method('addBodyListItem') + ->with( + 'This is a note to the recipient', + 'Note:', + 'https://example.com/core/img/caldav/description.png', + 'This is a note to the recipient' ); $template ->expects($this->once()) ->method('addBodyButton') ->with( - 'Open »file.txt«', + 'Open file.txt', 'https://example.com/file.txt' ); $message @@ -1196,7 +1465,7 @@ class ShareByMailProviderTest extends TestCase { ->expects($this->once()) ->method('setFrom') ->with([ - \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'Mrs. Owner User via UnitTestCloud' + Util::getDefaultEmailAddress('UnitTestCloud') => 'Mrs. Owner User via UnitTestCloud' ]); $user ->expects($this->once()) @@ -1217,30 +1486,43 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('setSubject') - ->with('Mrs. Owner User shared »file.txt« with you'); + ->with('Mrs. Owner User shared file.txt with you'); $message ->expects($this->once()) ->method('useTemplate') ->with($template); + + $this->mailer->expects($this->once()) + ->method('validateMailAddress') + ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') ->with($message); + $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) + ->willReturn('https://example.com/file.txt'); + + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('file.txt'); + + $share = $this->createMock(IShare::class); + $share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser'); + $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn('This is a note to the recipient'); + $share->expects($this->any())->method('getToken')->willReturn('token'); + self::invokePrivate( $provider, 'sendMailNotification', - [ - 'file.txt', - 'https://example.com/file.txt', - 'OwnerUser', - 'john@doe.com', - null, - '' - ]); + [$share] + ); } - public function testSendMailNotificationWithSameUserAndUserEmailAndNote() { + public function testSendMailNotificationWithSameUserAndUserEmailAndExpiration(): void { $provider = $this->getInstance(); $user = $this->createMock(IUser::class); $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(true); @@ -1269,19 +1551,33 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('addHeading') - ->with('Mrs. Owner User shared »file.txt« with you'); + ->with('Mrs. Owner User shared file.txt with you'); + + $expiration = new DateTime('2001-01-01'); + $this->l->expects($this->once()) + ->method('l') + ->with('date', $expiration, ['width' => 'medium']) + ->willReturn('2001-01-01'); + $this->urlGenerator->expects($this->once())->method('imagePath') + ->with('core', 'caldav/time.png') + ->willReturn('core/img/caldav/time.png'); + $this->urlGenerator->expects($this->once())->method('getAbsoluteURL') + ->with('core/img/caldav/time.png') + ->willReturn('https://example.com/core/img/caldav/time.png'); $template - ->expects($this->exactly(2)) - ->method('addBodyText') - ->withConsecutive( - ['This is a note to the recipient', 'This is a note to the recipient'], - ['Mrs. Owner User shared »file.txt« with you. Click the button below to open it.', 'Mrs. Owner User shared »file.txt« with you.'], + ->expects($this->once()) + ->method('addBodyListItem') + ->with( + 'This share is valid until 2001-01-01 at midnight', + 'Expiration:', + 'https://example.com/core/img/caldav/time.png', ); + $template ->expects($this->once()) ->method('addBodyButton') ->with( - 'Open »file.txt«', + 'Open file.txt', 'https://example.com/file.txt' ); $message @@ -1296,7 +1592,7 @@ class ShareByMailProviderTest extends TestCase { ->expects($this->once()) ->method('setFrom') ->with([ - \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'Mrs. Owner User via UnitTestCloud' + Util::getDefaultEmailAddress('UnitTestCloud') => 'Mrs. Owner User via UnitTestCloud' ]); $user ->expects($this->once()) @@ -1317,30 +1613,44 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('setSubject') - ->with('Mrs. Owner User shared »file.txt« with you'); + ->with('Mrs. Owner User shared file.txt with you'); $message ->expects($this->once()) ->method('useTemplate') ->with($template); + + $this->mailer->expects($this->once()) + ->method('validateMailAddress') + ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') ->with($message); + $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) + ->willReturn('https://example.com/file.txt'); + + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('file.txt'); + + $share = $this->createMock(IShare::class); + $share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser'); + $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getExpirationDate')->willReturn($expiration); + $share->expects($this->any())->method('getToken')->willReturn('token'); + self::invokePrivate( $provider, 'sendMailNotification', - [ - 'file.txt', - 'https://example.com/file.txt', - 'OwnerUser', - 'john@doe.com', - null, - 'This is a note to the recipient' - ]); + [$share] + ); } - public function testSendMailNotificationWithDifferentUserAndNoUserEmail() { + public function testSendMailNotificationWithDifferentUserAndNoUserEmail(): void { $provider = $this->getInstance(); $initiatorUser = $this->createMock(IUser::class); $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(true); @@ -1369,19 +1679,12 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('addHeading') - ->with('Mr. Initiator User shared »file.txt« with you'); - $template - ->expects($this->once()) - ->method('addBodyText') - ->with( - 'Mr. Initiator User shared »file.txt« with you. Click the button below to open it.', - 'Mr. Initiator User shared »file.txt« with you.' - ); + ->with('Mr. Initiator User shared file.txt with you'); $template ->expects($this->once()) ->method('addBodyButton') ->with( - 'Open »file.txt«', + 'Open file.txt', 'https://example.com/file.txt' ); $message @@ -1396,7 +1699,7 @@ class ShareByMailProviderTest extends TestCase { ->expects($this->once()) ->method('setFrom') ->with([ - \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'Mr. Initiator User via UnitTestCloud' + Util::getDefaultEmailAddress('UnitTestCloud') => 'Mr. Initiator User via UnitTestCloud' ]); $message ->expects($this->never()) @@ -1408,29 +1711,43 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('setSubject') - ->with('Mr. Initiator User shared »file.txt« with you'); + ->with('Mr. Initiator User shared file.txt with you'); $message ->expects($this->once()) ->method('useTemplate') ->with($template); + + $this->mailer->expects($this->once()) + ->method('validateMailAddress') + ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') ->with($message); + $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) + ->willReturn('https://example.com/file.txt'); + + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('file.txt'); + + $share = $this->createMock(IShare::class); + $share->expects($this->any())->method('getSharedBy')->willReturn('InitiatorUser'); + $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); + self::invokePrivate( $provider, 'sendMailNotification', - [ - 'file.txt', - 'https://example.com/file.txt', - 'InitiatorUser', - 'john@doe.com', - null, - ]); + [$share] + ); } - public function testSendMailNotificationWithSameUserAndUserEmailAndReplyToDesactivate() { + public function testSendMailNotificationWithSameUserAndUserEmailAndReplyToDesactivate(): void { $provider = $this->getInstance(); $user = $this->createMock(IUser::class); $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(false); @@ -1459,19 +1776,12 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('addHeading') - ->with('Mrs. Owner User shared »file.txt« with you'); - $template - ->expects($this->once()) - ->method('addBodyText') - ->with( - 'Mrs. Owner User shared »file.txt« with you. Click the button below to open it.', - 'Mrs. Owner User shared »file.txt« with you.' - ); + ->with('Mrs. Owner User shared file.txt with you'); $template ->expects($this->once()) ->method('addBodyButton') ->with( - 'Open »file.txt«', + 'Open file.txt', 'https://example.com/file.txt' ); $message @@ -1486,12 +1796,12 @@ class ShareByMailProviderTest extends TestCase { ->expects($this->once()) ->method('setFrom') ->with([ - \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'UnitTestCloud' + Util::getDefaultEmailAddress('UnitTestCloud') => 'UnitTestCloud' ]); + // Since replyToInitiator is false, we never get the initiator email address $user - ->expects($this->once()) - ->method('getEMailAddress') - ->willReturn('owner@example.com'); + ->expects($this->never()) + ->method('getEMailAddress'); $message ->expects($this->never()) ->method('setReplyTo'); @@ -1502,29 +1812,43 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('setSubject') - ->with('Mrs. Owner User shared »file.txt« with you'); + ->with('Mrs. Owner User shared file.txt with you'); $message ->expects($this->once()) ->method('useTemplate') ->with($template); + + $this->mailer->expects($this->once()) + ->method('validateMailAddress') + ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') ->with($message); + $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) + ->willReturn('https://example.com/file.txt'); + + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('file.txt'); + + $share = $this->createMock(IShare::class); + $share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser'); + $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); + self::invokePrivate( $provider, 'sendMailNotification', - [ - 'file.txt', - 'https://example.com/file.txt', - 'OwnerUser', - 'john@doe.com', - null, - ]); + [$share] + ); } - public function testSendMailNotificationWithDifferentUserAndNoUserEmailAndReplyToDesactivate() { + public function testSendMailNotificationWithDifferentUserAndNoUserEmailAndReplyToDesactivate(): void { $provider = $this->getInstance(); $initiatorUser = $this->createMock(IUser::class); $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(false); @@ -1553,19 +1877,12 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('addHeading') - ->with('Mr. Initiator User shared »file.txt« with you'); - $template - ->expects($this->once()) - ->method('addBodyText') - ->with( - 'Mr. Initiator User shared »file.txt« with you. Click the button below to open it.', - 'Mr. Initiator User shared »file.txt« with you.' - ); + ->with('Mr. Initiator User shared file.txt with you'); $template ->expects($this->once()) ->method('addBodyButton') ->with( - 'Open »file.txt«', + 'Open file.txt', 'https://example.com/file.txt' ); $message @@ -1580,7 +1897,7 @@ class ShareByMailProviderTest extends TestCase { ->expects($this->once()) ->method('setFrom') ->with([ - \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'UnitTestCloud' + Util::getDefaultEmailAddress('UnitTestCloud') => 'UnitTestCloud' ]); $message ->expects($this->never()) @@ -1592,25 +1909,39 @@ class ShareByMailProviderTest extends TestCase { $template ->expects($this->once()) ->method('setSubject') - ->with('Mr. Initiator User shared »file.txt« with you'); + ->with('Mr. Initiator User shared file.txt with you'); $message ->expects($this->once()) ->method('useTemplate') ->with($template); + + $this->mailer->expects($this->once()) + ->method('validateMailAddress') + ->willReturn(true); $this->mailer ->expects($this->once()) ->method('send') ->with($message); + $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute') + ->with('files_sharing.sharecontroller.showShare', ['token' => 'token']) + ->willReturn('https://example.com/file.txt'); + + $node = $this->createMock(File::class); + $node->expects($this->any())->method('getName')->willReturn('file.txt'); + + $share = $this->createMock(IShare::class); + $share->expects($this->any())->method('getSharedBy')->willReturn('InitiatorUser'); + $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com'); + $share->expects($this->any())->method('getNode')->willReturn($node); + $share->expects($this->any())->method('getId')->willReturn(42); + $share->expects($this->any())->method('getNote')->willReturn(''); + $share->expects($this->any())->method('getToken')->willReturn('token'); + self::invokePrivate( $provider, 'sendMailNotification', - [ - 'file.txt', - 'https://example.com/file.txt', - 'InitiatorUser', - 'john@doe.com', - null, - ]); + [$share] + ); } } |