diff options
Diffstat (limited to 'tests/lib/Encryption')
-rw-r--r-- | tests/lib/Encryption/DecryptAllTest.php | 137 | ||||
-rw-r--r-- | tests/lib/Encryption/EncryptionWrapperTest.php | 53 | ||||
-rw-r--r-- | tests/lib/Encryption/Keys/StorageTest.php | 159 | ||||
-rw-r--r-- | tests/lib/Encryption/ManagerTest.php | 149 | ||||
-rw-r--r-- | tests/lib/Encryption/UpdateTest.php | 227 | ||||
-rw-r--r-- | tests/lib/Encryption/UtilTest.php | 123 |
6 files changed, 409 insertions, 439 deletions
diff --git a/tests/lib/Encryption/DecryptAllTest.php b/tests/lib/Encryption/DecryptAllTest.php index f33f88eb214..979e12e03b3 100644 --- a/tests/lib/Encryption/DecryptAllTest.php +++ b/tests/lib/Encryption/DecryptAllTest.php @@ -1,22 +1,9 @@ <?php + /** - * @author Björn Schießle <schiessle@owncloud.com> - * - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace Test\Encryption; @@ -26,7 +13,7 @@ use OC\Encryption\Exceptions\DecryptionFailedException; use OC\Encryption\Manager; use OC\Files\FileInfo; use OC\Files\View; -use OCP\Files\Storage; +use OCP\Files\Storage\IStorage; use OCP\IUserManager; use OCP\UserInterface; use Symfony\Component\Console\Formatter\OutputFormatterInterface; @@ -52,16 +39,16 @@ class DecryptAllTest extends TestCase { /** @var \PHPUnit\Framework\MockObject\MockObject | View */ protected $view; - /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */ + /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */ protected $inputInterface; - /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */ + /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */ protected $outputInterface; - /** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\UserInterface */ + /** @var \PHPUnit\Framework\MockObject\MockObject|UserInterface */ protected $userInterface; - /** @var DecryptAll */ + /** @var DecryptAll */ protected $instance; protected function setUp(): void { @@ -77,12 +64,15 @@ class DecryptAllTest extends TestCase { ->disableOriginalConstructor()->getMock(); $this->outputInterface = $this->getMockBuilder(OutputInterface::class) ->disableOriginalConstructor()->getMock(); + $this->outputInterface->expects($this->any())->method('isDecorated') + ->willReturn(false); $this->userInterface = $this->getMockBuilder(UserInterface::class) ->disableOriginalConstructor()->getMock(); /* We need format method to return a string */ $outputFormatter = $this->createMock(OutputFormatterInterface::class); $outputFormatter->method('format')->willReturn('foo'); + $outputFormatter->method('isDecorated')->willReturn(false); $this->outputInterface->expects($this->any())->method('getFormatter') ->willReturn($outputFormatter); @@ -93,7 +83,7 @@ class DecryptAllTest extends TestCase { $this->invokePrivate($this->instance, 'output', [$this->outputInterface]); } - public function dataDecryptAll() { + public static function dataDecryptAll(): array { return [ [true, 'user1', true], [false, 'user1', true], @@ -104,12 +94,12 @@ class DecryptAllTest extends TestCase { } /** - * @dataProvider dataDecryptAll * @param bool $prepareResult * @param string $user * @param bool $userExistsChecked */ - public function testDecryptAll($prepareResult, $user, $userExistsChecked) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataDecryptAll')] + public function testDecryptAll($prepareResult, $user, $userExistsChecked): void { if ($userExistsChecked) { $this->userManager->expects($this->once())->method('userExists')->willReturn(true); } else { @@ -124,7 +114,7 @@ class DecryptAllTest extends TestCase { $this->view ] ) - ->setMethods(['prepareEncryptionModules', 'decryptAllUsersFiles']) + ->onlyMethods(['prepareEncryptionModules', 'decryptAllUsersFiles']) ->getMock(); $instance->expects($this->once()) @@ -146,7 +136,7 @@ class DecryptAllTest extends TestCase { /** * test decrypt all call with a user who doesn't exists */ - public function testDecryptAllWrongUser() { + public function testDecryptAllWrongUser(): void { $this->userManager->expects($this->once())->method('userExists')->willReturn(false); $this->outputInterface->expects($this->once())->method('writeln') ->with('User "user1" does not exist. Please check the username and try again'); @@ -156,7 +146,7 @@ class DecryptAllTest extends TestCase { ); } - public function dataTrueFalse() { + public static function dataTrueFalse(): array { return [ [true], [false], @@ -164,10 +154,10 @@ class DecryptAllTest extends TestCase { } /** - * @dataProvider dataTrueFalse * @param bool $success */ - public function testPrepareEncryptionModules($success) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTrueFalse')] + public function testPrepareEncryptionModules($success): void { $user = 'user1'; $dummyEncryptionModule = $this->getMockBuilder('OCP\Encryption\IEncryptionModule') @@ -196,10 +186,8 @@ class DecryptAllTest extends TestCase { ); } - /** - * @dataProvider dataTestDecryptAllUsersFiles - */ - public function testDecryptAllUsersFiles($user) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestDecryptAllUsersFiles')] + public function testDecryptAllUsersFiles($user): void { /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject | $instance */ $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') ->setConstructorArgs( @@ -209,7 +197,7 @@ class DecryptAllTest extends TestCase { $this->view ] ) - ->setMethods(['decryptUsersFiles']) + ->onlyMethods(['decryptUsersFiles']) ->getMock(); $this->invokePrivate($instance, 'input', [$this->inputInterface]); @@ -222,12 +210,16 @@ class DecryptAllTest extends TestCase { $this->userInterface->expects($this->any()) ->method('getUsers') ->willReturn(['user1', 'user2']); + $calls = [ + 'user1', + 'user2', + ]; $instance->expects($this->exactly(2)) ->method('decryptUsersFiles') - ->withConsecutive( - ['user1'], - ['user2'], - ); + ->willReturnCallback(function ($user) use (&$calls): void { + $expected = array_shift($calls); + $this->assertEquals($expected, $user); + }); } else { $instance->expects($this->once()) ->method('decryptUsersFiles') @@ -237,14 +229,14 @@ class DecryptAllTest extends TestCase { $this->invokePrivate($instance, 'decryptAllUsersFiles', [$user]); } - public function dataTestDecryptAllUsersFiles() { + public static function dataTestDecryptAllUsersFiles(): array { return [ ['user1'], [''] ]; } - public function testDecryptUsersFiles() { + public function testDecryptUsersFiles(): void { /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject $instance */ $instance = $this->getMockBuilder('OC\Encryption\DecryptAll') ->setConstructorArgs( @@ -254,35 +246,39 @@ class DecryptAllTest extends TestCase { $this->view ] ) - ->setMethods(['decryptFile']) + ->onlyMethods(['decryptFile']) ->getMock(); - $storage = $this->getMockBuilder(Storage::class) + $storage = $this->getMockBuilder(IStorage::class) ->disableOriginalConstructor()->getMock(); - $sharedStorage = $this->getMockBuilder(Storage::class) + $sharedStorage = $this->getMockBuilder(IStorage::class) ->disableOriginalConstructor()->getMock(); - $sharedStorage->expects($this->once())->method('instanceOfStorage') - ->with('OCA\Files_Sharing\SharedStorage')->willReturn(true); + $sharedStorage->expects($this->once()) + ->method('instanceOfStorage') + ->with('OCA\Files_Sharing\SharedStorage') + ->willReturn(true); $this->view->expects($this->exactly(2)) ->method('getDirectoryContent') - ->withConsecutive( - ['/user1/files'], - ['/user1/files/foo'] - ) - ->willReturnOnConsecutiveCalls( + ->willReturnMap([ [ - new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type' => 'dir'], null), - new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type' => 'file', 'encrypted' => true], null), - new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type' => 'file', 'encrypted' => true], null), + '/user1/files', '', null, + [ + new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type' => 'dir'], null), + new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type' => 'file', 'encrypted' => true], null), + new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type' => 'file', 'encrypted' => true], null), + ], ], [ - new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type' => 'file', 'encrypted' => true], null) - ] - ); + '/user1/files/foo', '', null, + [ + new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type' => 'file', 'encrypted' => true], null) + ], + ], + ]); $this->view->expects($this->any())->method('is_dir') ->willReturnCallback( @@ -294,16 +290,21 @@ class DecryptAllTest extends TestCase { } ); + $calls = [ + '/user1/files/bar', + '/user1/files/foo/subfile', + ]; $instance->expects($this->exactly(2)) ->method('decryptFile') - ->withConsecutive( - ['/user1/files/bar'], - ['/user1/files/foo/subfile'], - ); + ->willReturnCallback(function ($path) use (&$calls): void { + $expected = array_shift($calls); + $this->assertEquals($expected, $path); + }); /* We need format method to return a string */ $outputFormatter = $this->createMock(OutputFormatterInterface::class); + $outputFormatter->method('isDecorated')->willReturn(false); $outputFormatter->method('format')->willReturn('foo'); $output = $this->createMock(OutputInterface::class); @@ -315,10 +316,8 @@ class DecryptAllTest extends TestCase { $this->invokePrivate($instance, 'decryptUsersFiles', ['user1', $progressBar, '']); } - /** - * @dataProvider dataTrueFalse - */ - public function testDecryptFile($isEncrypted) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTrueFalse')] + public function testDecryptFile($isEncrypted): void { $path = 'test.txt'; /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject $instance */ @@ -330,7 +329,7 @@ class DecryptAllTest extends TestCase { $this->view ] ) - ->setMethods(['getTimestamp']) + ->onlyMethods(['getTimestamp']) ->getMock(); $fileInfo = $this->createMock(FileInfo::class); @@ -358,7 +357,7 @@ class DecryptAllTest extends TestCase { ); } - public function testDecryptFileFailure() { + public function testDecryptFileFailure(): void { $path = 'test.txt'; /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject $instance */ @@ -370,7 +369,7 @@ class DecryptAllTest extends TestCase { $this->view ] ) - ->setMethods(['getTimestamp']) + ->onlyMethods(['getTimestamp']) ->getMock(); @@ -385,7 +384,7 @@ class DecryptAllTest extends TestCase { $this->view->expects($this->once()) ->method('copy') ->with($path, $path . '.decrypted.42') - ->willReturnCallback(function () { + ->willReturnCallback(function (): void { throw new DecryptionFailedException(); }); diff --git a/tests/lib/Encryption/EncryptionWrapperTest.php b/tests/lib/Encryption/EncryptionWrapperTest.php index 8c357e2a50d..58bf5aff005 100644 --- a/tests/lib/Encryption/EncryptionWrapperTest.php +++ b/tests/lib/Encryption/EncryptionWrapperTest.php @@ -1,44 +1,35 @@ <?php + /** - * @author Björn Schießle <schiessle@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace Test\Encryption; use OC\Encryption\EncryptionWrapper; use OC\Encryption\Manager; +use OC\Files\Storage\Wrapper\Encryption; use OC\Memcache\ArrayCache; -use OCP\Files\Storage; +use OCA\Files_Trashbin\Storage; +use OCP\Files\Mount\IMountPoint; +use OCP\Files\Storage\IDisableEncryptionStorage; +use OCP\Files\Storage\IStorage; use Psr\Log\LoggerInterface; use Test\TestCase; class EncryptionWrapperTest extends TestCase { - /** @var EncryptionWrapper */ + /** @var EncryptionWrapper */ private $instance; - /** @var \PHPUnit\Framework\MockObject\MockObject | LoggerInterface */ + /** @var \PHPUnit\Framework\MockObject\MockObject | LoggerInterface */ private $logger; - /** @var \PHPUnit\Framework\MockObject\MockObject | \OC\Encryption\Manager */ + /** @var \PHPUnit\Framework\MockObject\MockObject | \OC\Encryption\Manager */ private $manager; - /** @var \PHPUnit\Framework\MockObject\MockObject | \OC\Memcache\ArrayCache */ + /** @var \PHPUnit\Framework\MockObject\MockObject|ArrayCache */ private $arrayCache; protected function setUp(): void { @@ -52,11 +43,9 @@ class EncryptionWrapperTest extends TestCase { } - /** - * @dataProvider provideWrapStorage - */ - public function testWrapStorage($expectedWrapped, $wrappedStorages) { - $storage = $this->getMockBuilder(Storage::class) + #[\PHPUnit\Framework\Attributes\DataProvider('provideWrapStorage')] + public function testWrapStorage($expectedWrapped, $wrappedStorages): void { + $storage = $this->getMockBuilder(IStorage::class) ->disableOriginalConstructor() ->getMock(); @@ -68,7 +57,7 @@ class EncryptionWrapperTest extends TestCase { ]); } - $mount = $this->getMockBuilder('OCP\Files\Mount\IMountPoint') + $mount = $this->getMockBuilder(IMountPoint::class) ->disableOriginalConstructor() ->getMock(); @@ -76,19 +65,19 @@ class EncryptionWrapperTest extends TestCase { $this->assertEquals( $expectedWrapped, - $returnedStorage->instanceOfStorage('OC\Files\Storage\Wrapper\Encryption'), + $returnedStorage->instanceOfStorage(Encryption::class), 'Asserted that the storage is (not) wrapped with encryption' ); } - public function provideWrapStorage() { + public static function provideWrapStorage(): array { return [ // Wrap when not wrapped or not wrapped with storage [true, []], - [true, ['OCA\Files_Trashbin\Storage']], + [true, [Storage::class]], // Do not wrap shared storages - [false, [Storage\IDisableEncryptionStorage::class]], + [false, [IDisableEncryptionStorage::class]], ]; } } diff --git a/tests/lib/Encryption/Keys/StorageTest.php b/tests/lib/Encryption/Keys/StorageTest.php index d1c0257cc6e..333d8d8ce21 100644 --- a/tests/lib/Encryption/Keys/StorageTest.php +++ b/tests/lib/Encryption/Keys/StorageTest.php @@ -1,29 +1,15 @@ <?php /** - * ownCloud - * - * @copyright (C) 2015 ownCloud, Inc. - * - * @author Bjoern Schiessle <schiessle@owncloud.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Encryption\Keys; use OC\Encryption\Keys\Storage; +use OC\Encryption\Util; use OC\Files\View; use OCP\IConfig; use OCP\Security\ICrypto; @@ -51,8 +37,9 @@ class StorageTest extends TestCase { protected function setUp(): void { parent::setUp(); - $this->util = $this->getMockBuilder('OC\Encryption\Util') + $this->util = $this->getMockBuilder(Util::class) ->disableOriginalConstructor() + ->onlyMethods(array_diff(get_class_methods(Util::class), ['getFileKeyDir'])) ->getMock(); $this->view = $this->getMockBuilder(View::class) @@ -76,8 +63,8 @@ class StorageTest extends TestCase { $this->storage = new Storage($this->view, $this->util, $this->crypto, $this->config); } - public function testSetFileKey() { - $this->config->method('getSystemValue') + public function testSetFileKey(): void { + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); $this->util->expects($this->any()) @@ -102,8 +89,8 @@ class StorageTest extends TestCase { ); } - public function testSetFileOld() { - $this->config->method('getSystemValue') + public function testSetFileOld(): void { + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.0'); $this->util->expects($this->any()) @@ -128,7 +115,7 @@ class StorageTest extends TestCase { ); } - public function dataTestGetFileKey() { + public static function dataTestGetFileKey() { return [ ['/files/foo.txt', '/files/foo.txt', true, 'key'], ['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', true, 'key'], @@ -137,15 +124,15 @@ class StorageTest extends TestCase { } /** - * @dataProvider dataTestGetFileKey * * @param string $path * @param string $strippedPartialName * @param bool $originalKeyExists * @param string $expectedKeyContent */ - public function testGetFileKey($path, $strippedPartialName, $originalKeyExists, $expectedKeyContent) { - $this->config->method('getSystemValue') + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestGetFileKey')] + public function testGetFileKey($path, $strippedPartialName, $originalKeyExists, $expectedKeyContent): void { + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); $this->util->expects($this->any()) @@ -171,13 +158,10 @@ class StorageTest extends TestCase { if (!$originalKeyExists) { $this->view->expects($this->exactly(2)) ->method('file_exists') - ->withConsecutive( - [$this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')], - [$this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey')], - )->willReturnOnConsecutiveCalls( - $originalKeyExists, - true, - ); + ->willReturnMap([ + ['/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey', $originalKeyExists], + ['/user1/files_encryption/keys' . $path . '/encModule/fileKey', true], + ]); $this->view->expects($this->once()) ->method('file_get_contents') @@ -200,8 +184,8 @@ class StorageTest extends TestCase { ); } - public function testSetFileKeySystemWide() { - $this->config->method('getSystemValue') + public function testSetFileKeySystemWide(): void { + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -232,8 +216,8 @@ class StorageTest extends TestCase { ); } - public function testGetFileKeySystemWide() { - $this->config->method('getSystemValue') + public function testGetFileKeySystemWide(): void { + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -260,8 +244,8 @@ class StorageTest extends TestCase { ); } - public function testSetSystemUserKey() { - $this->config->method('getSystemValue') + public function testSetSystemUserKey(): void { + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -280,8 +264,8 @@ class StorageTest extends TestCase { ); } - public function testSetUserKey() { - $this->config->method('getSystemValue') + public function testSetUserKey(): void { + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -300,8 +284,8 @@ class StorageTest extends TestCase { ); } - public function testGetSystemUserKey() { - $this->config->method('getSystemValue') + public function testGetSystemUserKey(): void { + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -323,8 +307,8 @@ class StorageTest extends TestCase { ); } - public function testGetUserKey() { - $this->config->method('getSystemValue') + public function testGetUserKey(): void { + $this->config->method('getSystemValueString') ->with('version') ->willReturn('20.0.0.2'); @@ -346,7 +330,7 @@ class StorageTest extends TestCase { ); } - public function testDeleteUserKey() { + public function testDeleteUserKey(): void { $this->view->expects($this->once()) ->method('file_exists') ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey')) @@ -361,7 +345,7 @@ class StorageTest extends TestCase { ); } - public function testDeleteSystemUserKey() { + public function testDeleteSystemUserKey(): void { $this->view->expects($this->once()) ->method('file_exists') ->with($this->equalTo('/files_encryption/encModule/shareKey_56884')) @@ -376,7 +360,7 @@ class StorageTest extends TestCase { ); } - public function testDeleteFileKeySystemWide() { + public function testDeleteFileKeySystemWide(): void { $this->util->expects($this->any()) ->method('getUidAndFilename') ->willReturn(['user1', '/files/foo.txt']); @@ -400,7 +384,7 @@ class StorageTest extends TestCase { ); } - public function testDeleteFileKey() { + public function testDeleteFileKey(): void { $this->util->expects($this->any()) ->method('getUidAndFilename') ->willReturn(['user1', '/files/foo.txt']); @@ -424,10 +408,8 @@ class StorageTest extends TestCase { ); } - /** - * @dataProvider dataProviderCopyRename - */ - public function testRenameKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataProviderCopyRename')] + public function testRenameKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void { $this->view->expects($this->any()) ->method('file_exists') ->willReturn(true); @@ -455,10 +437,8 @@ class StorageTest extends TestCase { $this->storage->renameKeys($source, $target); } - /** - * @dataProvider dataProviderCopyRename - */ - public function testCopyKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataProviderCopyRename')] + public function testCopyKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void { $this->view->expects($this->any()) ->method('file_exists') ->willReturn(true); @@ -495,7 +475,7 @@ class StorageTest extends TestCase { return [$parts[1], '/' . implode('/', array_slice($parts, 2))]; } - public function dataProviderCopyRename() { + public static function dataProviderCopyRename() { return [ ['/user1/files/source.txt', '/user1/files/target.txt', false, false, '/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'], @@ -526,14 +506,14 @@ class StorageTest extends TestCase { } /** - * @dataProvider dataTestGetPathToKeys * * @param string $path * @param boolean $systemWideMountPoint * @param string $storageRoot * @param string $expected */ - public function testGetPathToKeys($path, $systemWideMountPoint, $storageRoot, $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestGetPathToKeys')] + public function testGetPathToKeys($path, $systemWideMountPoint, $storageRoot, $expected): void { $this->invokePrivate($this->storage, 'root_dir', [$storageRoot]); $this->util->expects($this->any()) @@ -548,7 +528,7 @@ class StorageTest extends TestCase { ); } - public function dataTestGetPathToKeys() { + public static function dataTestGetPathToKeys() { return [ ['/user1/files/source.txt', false, '', '/user1/files_encryption/keys/files/source.txt/'], ['/user1/files/source.txt', true, '', '/files_encryption/keys/files/source.txt/'], @@ -557,7 +537,7 @@ class StorageTest extends TestCase { ]; } - public function testKeySetPreparation() { + public function testKeySetPreparation(): void { $this->view->expects($this->any()) ->method('file_exists') ->willReturn(false); @@ -583,48 +563,15 @@ class StorageTest extends TestCase { $this->assertSame($expected, $args[0]); } - /** - * @dataProvider dataTestGetFileKeyDir - * - * @param bool $isSystemWideMountPoint - * @param string $storageRoot - * @param string $expected - */ - public function testGetFileKeyDir($isSystemWideMountPoint, $storageRoot, $expected) { - $path = '/user1/files/foo/bar.txt'; - $owner = 'user1'; - $relativePath = '/foo/bar.txt'; - - $this->invokePrivate($this->storage, 'root_dir', [$storageRoot]); - - $this->util->expects($this->once())->method('isSystemWideMountPoint') - ->willReturn($isSystemWideMountPoint); - $this->util->expects($this->once())->method('getUidAndFilename') - ->with($path)->willReturn([$owner, $relativePath]); - - $this->assertSame($expected, - $this->invokePrivate($this->storage, 'getFileKeyDir', ['OC_DEFAULT_MODULE', $path]) - ); - } - - public function dataTestGetFileKeyDir() { - return [ - [false, '', '/user1/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], - [true, '', '/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], - [false, 'newStorageRoot', '/newStorageRoot/user1/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], - [true, 'newStorageRoot', '/newStorageRoot/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], - ]; - } - /** - * @dataProvider dataTestBackupUserKeys * @param bool $createBackupDir */ - public function testBackupUserKeys($createBackupDir) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestBackupUserKeys')] + public function testBackupUserKeys($createBackupDir): void { $storage = $this->getMockBuilder('OC\Encryption\Keys\Storage') ->setConstructorArgs([$this->view, $this->util, $this->crypto, $this->config]) - ->setMethods(['getTimestamp']) + ->onlyMethods(['getTimestamp']) ->getMock(); $storage->expects($this->any())->method('getTimestamp')->willReturn('1234567'); @@ -633,11 +580,15 @@ class StorageTest extends TestCase { ->with('user1/files_encryption/backup')->willReturn(!$createBackupDir); if ($createBackupDir) { + $calls = [ + 'user1/files_encryption/backup', + 'user1/files_encryption/backup/test.encryptionModule.1234567', + ]; $this->view->expects($this->exactly(2))->method('mkdir') - ->withConsecutive( - ['user1/files_encryption/backup'], - ['user1/files_encryption/backup/test.encryptionModule.1234567'], - ); + ->willReturnCallback(function ($path) use (&$calls): void { + $expected = array_shift($calls); + $this->assertEquals($expected, $path); + }); } else { $this->view->expects($this->once())->method('mkdir') ->with('user1/files_encryption/backup/test.encryptionModule.1234567'); @@ -652,7 +603,7 @@ class StorageTest extends TestCase { $this->assertTrue($storage->backupUserKeys('encryptionModule', 'test', 'user1')); } - public function dataTestBackupUserKeys() { + public static function dataTestBackupUserKeys() { return [ [true], [false] ]; diff --git a/tests/lib/Encryption/ManagerTest.php b/tests/lib/Encryption/ManagerTest.php index 79d2c216080..e9b6ddae8a0 100644 --- a/tests/lib/Encryption/ManagerTest.php +++ b/tests/lib/Encryption/ManagerTest.php @@ -1,7 +1,14 @@ <?php +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ namespace Test\Encryption; +use OC\Encryption\Exceptions\ModuleAlreadyExistsException; +use OC\Encryption\Exceptions\ModuleDoesNotExistsException; use OC\Encryption\Manager; use OC\Encryption\Util; use OC\Files\View; @@ -45,16 +52,16 @@ class ManagerTest extends TestCase { $this->manager = new Manager($this->config, $this->logger, $this->l10n, $this->view, $this->util, $this->arrayCache); } - public function testManagerIsDisabled() { + public function testManagerIsDisabled(): void { $this->assertFalse($this->manager->isEnabled()); } - public function testManagerIsDisabledIfEnabledButNoModules() { + public function testManagerIsDisabledIfEnabledButNoModules(): void { $this->config->expects($this->any())->method('getAppValue')->willReturn(true); $this->assertFalse($this->manager->isEnabled()); } - public function testManagerIsDisabledIfDisabledButModules() { + public function testManagerIsDisabledIfDisabledButModules(): void { $this->config->expects($this->any())->method('getAppValue')->willReturn(false); $em = $this->createMock(IEncryptionModule::class); $em->expects($this->any())->method('getId')->willReturn('id'); @@ -65,8 +72,8 @@ class ManagerTest extends TestCase { $this->assertFalse($this->manager->isEnabled()); } - public function testManagerIsEnabled() { - $this->config->expects($this->any())->method('getSystemValue')->willReturn(true); + public function testManagerIsEnabled(): void { + $this->config->expects($this->any())->method('getSystemValueBool')->willReturn(true); $this->config->expects($this->any())->method('getAppValue')->willReturn('yes'); $this->assertTrue($this->manager->isEnabled()); } @@ -83,14 +90,14 @@ class ManagerTest extends TestCase { /** * @depends testModuleRegistration */ - public function testModuleReRegistration($manager) { - $this->expectException(\OC\Encryption\Exceptions\ModuleAlreadyExistsException::class); + public function testModuleReRegistration($manager): void { + $this->expectException(ModuleAlreadyExistsException::class); $this->expectExceptionMessage('Id "ID0" already used by encryption module "TestDummyModule0"'); $this->addNewEncryptionModule($manager, 0); } - public function testModuleUnRegistration() { + public function testModuleUnRegistration(): void { $this->config->expects($this->any())->method('getAppValue')->willReturn(true); $this->addNewEncryptionModule($this->manager, 0); $this->assertCount(1, $this->manager->getEncryptionModules()); @@ -100,8 +107,8 @@ class ManagerTest extends TestCase { } - public function testGetEncryptionModuleUnknown() { - $this->expectException(\OC\Encryption\Exceptions\ModuleDoesNotExistsException::class); + public function testGetEncryptionModuleUnknown(): void { + $this->expectException(ModuleDoesNotExistsException::class); $this->expectExceptionMessage('Module with ID: unknown does not exist.'); $this->config->expects($this->any())->method('getAppValue')->willReturn(true); @@ -110,7 +117,7 @@ class ManagerTest extends TestCase { $this->manager->getEncryptionModule('unknown'); } - public function testGetEncryptionModuleEmpty() { + public function testGetEncryptionModuleEmpty(): void { global $defaultId; $defaultId = null; @@ -134,7 +141,7 @@ class ManagerTest extends TestCase { $this->assertEquals('ID1', $this->manager->getEncryptionModule()->getId()); } - public function testGetEncryptionModule() { + public function testGetEncryptionModule(): void { global $defaultId; $defaultId = null; @@ -159,7 +166,7 @@ class ManagerTest extends TestCase { $this->assertEquals('ID0', $this->manager->getDefaultEncryptionModuleId()); } - public function testSetDefaultEncryptionModule() { + public function testSetDefaultEncryptionModule(): void { global $defaultId; $defaultId = null; @@ -193,63 +200,63 @@ class ManagerTest extends TestCase { $this->assertEquals('ID1', $this->manager->getDefaultEncryptionModuleId()); } -// /** -// * @expectedException \OC\Encryption\Exceptions\ModuleAlreadyExistsException -// * @expectedExceptionMessage Id "0" already used by encryption module "TestDummyModule0" -// */ -// public function testModuleRegistration() { -// $config = $this->createMock(IConfig::class); -// $config->expects($this->any())->method('getSystemValue')->willReturn(true); -// $em = $this->createMock(IEncryptionModule::class); -// $em->expects($this->any())->method('getId')->willReturn(0); -// $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); -// $m = new Manager($config); -// $m->registerEncryptionModule($em); -// $this->assertTrue($m->isEnabled()); -// $m->registerEncryptionModule($em); -// } -// -// public function testModuleUnRegistration() { -// $config = $this->createMock(IConfig::class); -// $config->expects($this->any())->method('getSystemValue')->willReturn(true); -// $em = $this->createMock(IEncryptionModule::class); -// $em->expects($this->any())->method('getId')->willReturn(0); -// $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); -// $m = new Manager($config); -// $m->registerEncryptionModule($em); -// $this->assertTrue($m->isEnabled()); -// $m->unregisterEncryptionModule($em); -// $this->assertFalse($m->isEnabled()); -// } -// -// /** -// * @expectedException \OC\Encryption\Exceptions\ModuleDoesNotExistsException -// * @expectedExceptionMessage Module with ID: unknown does not exist. -// */ -// public function testGetEncryptionModuleUnknown() { -// $config = $this->createMock(IConfig::class); -// $config->expects($this->any())->method('getSystemValue')->willReturn(true); -// $em = $this->createMock(IEncryptionModule::class); -// $em->expects($this->any())->method('getId')->willReturn(0); -// $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); -// $m = new Manager($config); -// $m->registerEncryptionModule($em); -// $this->assertTrue($m->isEnabled()); -// $m->getEncryptionModule('unknown'); -// } -// -// public function testGetEncryptionModule() { -// $config = $this->createMock(IConfig::class); -// $config->expects($this->any())->method('getSystemValue')->willReturn(true); -// $em = $this->createMock(IEncryptionModule::class); -// $em->expects($this->any())->method('getId')->willReturn(0); -// $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); -// $m = new Manager($config); -// $m->registerEncryptionModule($em); -// $this->assertTrue($m->isEnabled()); -// $en0 = $m->getEncryptionModule(0); -// $this->assertEquals(0, $en0->getId()); -// } + // /** + // * @expectedException \OC\Encryption\Exceptions\ModuleAlreadyExistsException + // * @expectedExceptionMessage Id "0" already used by encryption module "TestDummyModule0" + // */ + // public function testModuleRegistration() { + // $config = $this->createMock(IConfig::class); + // $config->expects($this->any())->method('getSystemValueBool')->willReturn(true); + // $em = $this->createMock(IEncryptionModule::class); + // $em->expects($this->any())->method('getId')->willReturn(0); + // $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); + // $m = new Manager($config); + // $m->registerEncryptionModule($em); + // $this->assertTrue($m->isEnabled()); + // $m->registerEncryptionModule($em); + // } + // + // public function testModuleUnRegistration() { + // $config = $this->createMock(IConfig::class); + // $config->expects($this->any())->method('getSystemValueBool')->willReturn(true); + // $em = $this->createMock(IEncryptionModule::class); + // $em->expects($this->any())->method('getId')->willReturn(0); + // $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); + // $m = new Manager($config); + // $m->registerEncryptionModule($em); + // $this->assertTrue($m->isEnabled()); + // $m->unregisterEncryptionModule($em); + // $this->assertFalse($m->isEnabled()); + // } + // + // /** + // * @expectedException \OC\Encryption\Exceptions\ModuleDoesNotExistsException + // * @expectedExceptionMessage Module with ID: unknown does not exist. + // */ + // public function testGetEncryptionModuleUnknown() { + // $config = $this->createMock(IConfig::class); + // $config->expects($this->any())->method('getSystemValueBool')->willReturn(true); + // $em = $this->createMock(IEncryptionModule::class); + // $em->expects($this->any())->method('getId')->willReturn(0); + // $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); + // $m = new Manager($config); + // $m->registerEncryptionModule($em); + // $this->assertTrue($m->isEnabled()); + // $m->getEncryptionModule('unknown'); + // } + // + // public function testGetEncryptionModule() { + // $config = $this->createMock(IConfig::class); + // $config->expects($this->any())->method('getSystemValueBool')->willReturn(true); + // $em = $this->createMock(IEncryptionModule::class); + // $em->expects($this->any())->method('getId')->willReturn(0); + // $em->expects($this->any())->method('getDisplayName')->willReturn('TestDummyModule0'); + // $m = new Manager($config); + // $m->registerEncryptionModule($em); + // $this->assertTrue($m->isEnabled()); + // $en0 = $m->getEncryptionModule(0); + // $this->assertEquals(0, $en0->getId()); + // } protected function addNewEncryptionModule(Manager $manager, $id) { $encryptionModule = $this->createMock(IEncryptionModule::class); @@ -259,7 +266,7 @@ class ManagerTest extends TestCase { $encryptionModule->expects($this->any()) ->method('getDisplayName') ->willReturn('TestDummyModule' . $id); - /** @var \OCP\Encryption\IEncryptionModule $encryptionModule */ + /** @var IEncryptionModule $encryptionModule */ $manager->registerEncryptionModule('ID' . $id, 'TestDummyModule' . $id, function () use ($encryptionModule) { return $encryptionModule; }); diff --git a/tests/lib/Encryption/UpdateTest.php b/tests/lib/Encryption/UpdateTest.php index df7d137f0b6..04ca224c0a1 100644 --- a/tests/lib/Encryption/UpdateTest.php +++ b/tests/lib/Encryption/UpdateTest.php @@ -1,107 +1,105 @@ <?php + +declare(strict_types=1); + /** - * @author Björn Schießle <schiessle@owncloud.com> - * - * @copyright Copyright (c) 2015, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace Test\Encryption; +use OC\Encryption\File; use OC\Encryption\Update; use OC\Encryption\Util; -use OC\Files\Mount\Manager; use OC\Files\View; +use OCP\Encryption\IEncryptionModule; +use OCP\Files\File as OCPFile; +use OCP\Files\Folder; +use OCP\IUser; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\LoggerInterface; use Test\TestCase; -use OC\Encryption\File; -use OCP\Encryption\IEncryptionModule; class UpdateTest extends TestCase { - /** @var \OC\Encryption\Update */ - private $update; - - /** @var string */ - private $uid; - - /** @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject */ - private $view; - - /** @var Util | \PHPUnit\Framework\MockObject\MockObject */ - private $util; - - /** @var \OC\Files\Mount\Manager | \PHPUnit\Framework\MockObject\MockObject */ - private $mountManager; - - /** @var \OC\Encryption\Manager | \PHPUnit\Framework\MockObject\MockObject */ - private $encryptionManager; - - /** @var \OCP\Encryption\IEncryptionModule | \PHPUnit\Framework\MockObject\MockObject */ - private $encryptionModule; - - /** @var \OC\Encryption\File | \PHPUnit\Framework\MockObject\MockObject */ - private $fileHelper; - - /** @var \PHPUnit\Framework\MockObject\MockObject|LoggerInterface */ - private $logger; + private string $uid; + private View&MockObject $view; + private Util&MockObject $util; + private \OC\Encryption\Manager&MockObject $encryptionManager; + private IEncryptionModule&MockObject $encryptionModule; + private File&MockObject $fileHelper; + private LoggerInterface&MockObject $logger; protected function setUp(): void { parent::setUp(); $this->view = $this->createMock(View::class); $this->util = $this->createMock(Util::class); - $this->mountManager = $this->createMock(Manager::class); $this->encryptionManager = $this->createMock(\OC\Encryption\Manager::class); $this->fileHelper = $this->createMock(File::class); $this->encryptionModule = $this->createMock(IEncryptionModule::class); $this->logger = $this->createMock(LoggerInterface::class); $this->uid = 'testUser1'; + } + + private function getUserMock(string $uid): IUser&MockObject { + $user = $this->createMock(IUser::class); + $user->expects(self::any()) + ->method('getUID') + ->willReturn($uid); + return $user; + } + + private function getFileMock(string $path, string $owner): OCPFile&MockObject { + $node = $this->createMock(OCPFile::class); + $node->expects(self::atLeastOnce()) + ->method('getPath') + ->willReturn($path); + $node->expects(self::any()) + ->method('getOwner') + ->willReturn($this->getUserMock($owner)); - $this->update = new Update( - $this->view, - $this->util, - $this->mountManager, - $this->encryptionManager, - $this->fileHelper, - $this->logger, - $this->uid); + return $node; + } + + private function getFolderMock(string $path, string $owner): Folder&MockObject { + $node = $this->createMock(Folder::class); + $node->expects(self::atLeastOnce()) + ->method('getPath') + ->willReturn($path); + $node->expects(self::any()) + ->method('getOwner') + ->willReturn($this->getUserMock($owner)); + + return $node; } /** - * @dataProvider dataTestUpdate * * @param string $path * @param boolean $isDir * @param array $allFiles * @param integer $numberOfFiles */ - public function testUpdate($path, $isDir, $allFiles, $numberOfFiles) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestUpdate')] + public function testUpdate($path, $isDir, $allFiles, $numberOfFiles): void { + $updateMock = $this->getUpdateMock(['getOwnerPath']); + $updateMock->expects($this->once())->method('getOwnerPath') + ->willReturnCallback(fn (OCPFile|Folder $node) => '/user/' . $node->getPath()); + $this->encryptionManager->expects($this->once()) ->method('getEncryptionModule') ->willReturn($this->encryptionModule); - $this->view->expects($this->once()) - ->method('is_dir') - ->willReturn($isDir); - if ($isDir) { $this->util->expects($this->once()) ->method('getAllFiles') ->willReturn($allFiles); + $node = $this->getFolderMock($path, 'user'); + } else { + $node = $this->getFileMock($path, 'user'); } $this->fileHelper->expects($this->exactly($numberOfFiles)) @@ -112,15 +110,10 @@ class UpdateTest extends TestCase { ->method('update') ->willReturn(true); - $this->update->update($path); + $updateMock->update($node); } - /** - * data provider for testUpdate() - * - * @return array - */ - public function dataTestUpdate() { + public static function dataTestUpdate(): array { return [ ['/user/files/foo', true, ['/user/files/foo/file1.txt', '/user/files/foo/file1.txt'], 2], ['/user/files/test.txt', false, [], 1], @@ -128,106 +121,70 @@ class UpdateTest extends TestCase { } /** - * @dataProvider dataTestPostRename * * @param string $source * @param string $target - * @param boolean $encryptionEnabled */ - public function testPostRename($source, $target, $encryptionEnabled) { - $updateMock = $this->getUpdateMock(['update', 'getOwnerPath']); + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestPostRename')] + public function testPostRename($source, $target): void { + $updateMock = $this->getUpdateMock(['update','getOwnerPath']); - $this->encryptionManager->expects($this->once()) - ->method('isEnabled') - ->willReturn($encryptionEnabled); + $sourceNode = $this->getFileMock($source, 'user'); + $targetNode = $this->getFileMock($target, 'user'); - if (dirname($source) === dirname($target) || $encryptionEnabled === false) { + if (dirname($source) === dirname($target)) { $updateMock->expects($this->never())->method('getOwnerPath'); $updateMock->expects($this->never())->method('update'); } else { - $updateMock->expects($this->once()) - ->method('getOwnerPath') - ->willReturnCallback(function ($path) use ($target) { - $this->assertSame( - $target, - $path, - 'update needs to be executed for the target destination'); - return ['owner', $path]; - }); - $updateMock->expects($this->once())->method('update'); + $updateMock->expects($this->once())->method('update') + ->willReturnCallback(fn (OCPFile|Folder $node) => $this->assertSame( + $target, + $node->getPath(), + 'update needs to be executed for the target destination' + )); } - $updateMock->postRename(['oldpath' => $source, 'newpath' => $target]); + $updateMock->postRename($sourceNode, $targetNode); } - /** - * test data for testPostRename() - * - * @return array - */ - public function dataTestPostRename() { + public static function dataTestPostRename(): array { return [ - ['/test.txt', '/testNew.txt', true], - ['/test.txt', '/testNew.txt', false], - ['/folder/test.txt', '/testNew.txt', true], - ['/folder/test.txt', '/testNew.txt', false], - ['/folder/test.txt', '/testNew.txt', true], - ['/test.txt', '/folder/testNew.txt', false], + ['/test.txt', '/testNew.txt'], + ['/folder/test.txt', '/testNew.txt'], + ['/test.txt', '/folder/testNew.txt'], ]; } - - /** - * @dataProvider dataTestPostRestore - * - * @param boolean $encryptionEnabled - */ - public function testPostRestore($encryptionEnabled) { + public function testPostRestore(): void { $updateMock = $this->getUpdateMock(['update']); - $this->encryptionManager->expects($this->once()) - ->method('isEnabled') - ->willReturn($encryptionEnabled); + $updateMock->expects($this->once())->method('update') + ->willReturnCallback(fn (OCPFile|Folder $node) => $this->assertSame( + '/folder/test.txt', + $node->getPath(), + 'update needs to be executed for the target destination' + )); - if ($encryptionEnabled) { - $updateMock->expects($this->once())->method('update'); - } else { - $updateMock->expects($this->never())->method('update'); - } - - $updateMock->postRestore(['filePath' => '/folder/test.txt']); - } - - /** - * test data for testPostRestore() - * - * @return array - */ - public function dataTestPostRestore() { - return [ - [true], - [false], - ]; + $updateMock->postRestore($this->getFileMock('/folder/test.txt', 'user')); } /** * create mock of the update method * - * @param array$methods methods which should be set - * @return \OC\Encryption\Update | \PHPUnit\Framework\MockObject\MockObject + * @param array $methods methods which should be set */ - protected function getUpdateMock($methods) { - return $this->getMockBuilder('\OC\Encryption\Update') + protected function getUpdateMock(array $methods): Update&MockObject { + return $this->getMockBuilder(Update::class) ->setConstructorArgs( [ - $this->view, $this->util, - $this->mountManager, $this->encryptionManager, $this->fileHelper, $this->logger, $this->uid ] - )->setMethods($methods)->getMock(); + ) + ->onlyMethods($methods) + ->getMock(); } } diff --git a/tests/lib/Encryption/UtilTest.php b/tests/lib/Encryption/UtilTest.php index 8d800cf6f34..d1fefee872a 100644 --- a/tests/lib/Encryption/UtilTest.php +++ b/tests/lib/Encryption/UtilTest.php @@ -1,7 +1,13 @@ <?php +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ namespace Test\Encryption; +use OC\Encryption\Exceptions\EncryptionHeaderKeyExistsException; use OC\Encryption\Util; use OC\Files\View; use OCP\Encryption\IEncryptionModule; @@ -13,9 +19,10 @@ use Test\TestCase; class UtilTest extends TestCase { /** * block size will always be 8192 for a PHP stream + * * @see https://bugs.php.net/bug.php?id=21641 */ - protected int $headerSize = 8192; + protected static int $headerSize = 8192; /** @var \PHPUnit\Framework\MockObject\MockObject */ protected $view; @@ -48,15 +55,13 @@ class UtilTest extends TestCase { ); } - /** - * @dataProvider providesHeadersForEncryptionModule - */ - public function testGetEncryptionModuleId($expected, $header) { + #[\PHPUnit\Framework\Attributes\DataProvider('providesHeadersForEncryptionModule')] + public function testGetEncryptionModuleId($expected, $header): void { $id = $this->util->getEncryptionModuleId($header); $this->assertEquals($expected, $id); } - public function providesHeadersForEncryptionModule() { + public static function providesHeadersForEncryptionModule(): array { return [ ['', []], ['', ['1']], @@ -64,10 +69,8 @@ class UtilTest extends TestCase { ]; } - /** - * @dataProvider providesHeaders - */ - public function testCreateHeader($expected, $header, $moduleId) { + #[\PHPUnit\Framework\Attributes\DataProvider('providesHeaders')] + public function testCreateHeader($expected, $header, $moduleId): void { $em = $this->createMock(IEncryptionModule::class); $em->expects($this->any())->method('getId')->willReturn($moduleId); @@ -75,18 +78,18 @@ class UtilTest extends TestCase { $this->assertEquals($expected, $result); } - public function providesHeaders() { + public static function providesHeaders(): array { return [ - [str_pad('HBEGIN:oc_encryption_module:0:HEND', $this->headerSize, '-', STR_PAD_RIGHT) + [str_pad('HBEGIN:oc_encryption_module:0:HEND', self::$headerSize, '-', STR_PAD_RIGHT) , [], '0'], - [str_pad('HBEGIN:oc_encryption_module:0:custom_header:foo:HEND', $this->headerSize, '-', STR_PAD_RIGHT) + [str_pad('HBEGIN:oc_encryption_module:0:custom_header:foo:HEND', self::$headerSize, '-', STR_PAD_RIGHT) , ['custom_header' => 'foo'], '0'], ]; } - public function testCreateHeaderFailed() { - $this->expectException(\OC\Encryption\Exceptions\EncryptionHeaderKeyExistsException::class); + public function testCreateHeaderFailed(): void { + $this->expectException(EncryptionHeaderKeyExistsException::class); $header = ['header1' => 1, 'header2' => 2, 'oc_encryption_module' => 'foo']; @@ -97,10 +100,8 @@ class UtilTest extends TestCase { $this->util->createHeader($header, $em); } - /** - * @dataProvider providePathsForTestIsExcluded - */ - public function testIsExcluded($path, $keyStorageRoot, $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('providePathsForTestIsExcluded')] + public function testIsExcluded($path, $keyStorageRoot, $expected): void { $this->config->expects($this->once()) ->method('getAppValue') ->with('core', 'encryption_key_storage_root', '') @@ -115,7 +116,7 @@ class UtilTest extends TestCase { ); } - public function providePathsForTestIsExcluded() { + public static function providePathsForTestIsExcluded(): array { return [ ['/files_encryption', '', true], ['files_encryption/foo.txt', '', true], @@ -138,16 +139,14 @@ class UtilTest extends TestCase { return false; } - /** - * @dataProvider dataTestIsFile - */ - public function testIsFile($path, $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestIsFile')] + public function testIsFile($path, $expected): void { $this->assertSame($expected, $this->util->isFile($path) ); } - public function dataTestIsFile() { + public static function dataTestIsFile(): array { return [ ['/user/files/test.txt', true], ['/user/files', true], @@ -160,17 +159,17 @@ class UtilTest extends TestCase { } /** - * @dataProvider dataTestStripPartialFileExtension * * @param string $path * @param string $expected */ - public function testStripPartialFileExtension($path, $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestStripPartialFileExtension')] + public function testStripPartialFileExtension($path, $expected): void { $this->assertSame($expected, $this->util->stripPartialFileExtension($path)); } - public function dataTestStripPartialFileExtension() { + public static function dataTestStripPartialFileExtension(): array { return [ ['/foo/test.txt', '/foo/test.txt'], ['/foo/test.txt.part', '/foo/test.txt'], @@ -178,4 +177,72 @@ class UtilTest extends TestCase { ['/foo/test.txt.ocTransferId7567.part', '/foo/test.txt'], ]; } + + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestParseRawHeader')] + public function testParseRawHeader($rawHeader, $expected): void { + $result = $this->util->parseRawHeader($rawHeader); + $this->assertSameSize($expected, $result); + foreach ($result as $key => $value) { + $this->assertArrayHasKey($key, $expected); + $this->assertSame($expected[$key], $value); + } + } + + public static function dataTestParseRawHeader(): array { + return [ + [str_pad('HBEGIN:oc_encryption_module:0:HEND', self::$headerSize, '-', STR_PAD_RIGHT) + , [Util::HEADER_ENCRYPTION_MODULE_KEY => '0']], + [str_pad('HBEGIN:oc_encryption_module:0:custom_header:foo:HEND', self::$headerSize, '-', STR_PAD_RIGHT) + , ['custom_header' => 'foo', Util::HEADER_ENCRYPTION_MODULE_KEY => '0']], + [str_pad('HelloWorld', self::$headerSize, '-', STR_PAD_RIGHT), []], + ['', []], + [str_pad('HBEGIN:oc_encryption_module:0', self::$headerSize, '-', STR_PAD_RIGHT) + , []], + [str_pad('oc_encryption_module:0:HEND', self::$headerSize, '-', STR_PAD_RIGHT) + , []], + ]; + } + + /** + * + * @param bool $isSystemWideMountPoint + * @param string $storageRoot + * @param string $expected + */ + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestGetFileKeyDir')] + public function testGetFileKeyDir($isSystemWideMountPoint, $storageRoot, $expected): void { + $path = '/user1/files/foo/bar.txt'; + $owner = 'user1'; + $relativePath = '/foo/bar.txt'; + + $util = $this->getMockBuilder(Util::class) + ->onlyMethods(['isSystemWideMountPoint', 'getUidAndFilename', 'getKeyStorageRoot']) + ->setConstructorArgs([ + $this->view, + $this->userManager, + $this->groupManager, + $this->config + ]) + ->getMock(); + + $util->expects($this->once())->method('getKeyStorageRoot') + ->willReturn($storageRoot); + $util->expects($this->once())->method('isSystemWideMountPoint') + ->willReturn($isSystemWideMountPoint); + $util->expects($this->once())->method('getUidAndFilename') + ->with($path)->willReturn([$owner, $relativePath]); + + $this->assertSame($expected, + $util->getFileKeyDir('OC_DEFAULT_MODULE', $path) + ); + } + + public static function dataTestGetFileKeyDir(): array { + return [ + [false, '', '/user1/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], + [true, '', '/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], + [false, 'newStorageRoot', '/newStorageRoot/user1/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], + [true, 'newStorageRoot', '/newStorageRoot/files_encryption/keys/foo/bar.txt/OC_DEFAULT_MODULE/'], + ]; + } } |