aboutsummaryrefslogtreecommitdiffstats
path: root/apps/encryption/tests/KeyManagerTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/encryption/tests/KeyManagerTest.php')
-rw-r--r--apps/encryption/tests/KeyManagerTest.php708
1 files changed, 708 insertions, 0 deletions
diff --git a/apps/encryption/tests/KeyManagerTest.php b/apps/encryption/tests/KeyManagerTest.php
new file mode 100644
index 00000000000..3fe76fc4f59
--- /dev/null
+++ b/apps/encryption/tests/KeyManagerTest.php
@@ -0,0 +1,708 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+namespace OCA\Encryption\Tests;
+
+use OC\Files\FileInfo;
+use OC\Files\View;
+use OCA\Encryption\Crypto\Crypt;
+use OCA\Encryption\Crypto\Encryption;
+use OCA\Encryption\Exceptions\PrivateKeyMissingException;
+use OCA\Encryption\Exceptions\PublicKeyMissingException;
+use OCA\Encryption\KeyManager;
+use OCA\Encryption\Session;
+use OCA\Encryption\Util;
+use OCP\Encryption\Keys\IStorage;
+use OCP\Files\Cache\ICache;
+use OCP\Files\Storage\IStorage as FilesIStorage;
+use OCP\IConfig;
+use OCP\IUserSession;
+use OCP\Lock\ILockingProvider;
+use OCP\Lock\LockedException;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Log\LoggerInterface;
+use Test\TestCase;
+
+class KeyManagerTest extends TestCase {
+
+ protected KeyManager $instance;
+
+ protected string $userId;
+ protected string $systemKeyId;
+ protected IStorage&MockObject $keyStorageMock;
+ protected Crypt&MockObject $cryptMock;
+ protected IUserSession&MockObject $userMock;
+ protected Session&MockObject $sessionMock;
+ protected LoggerInterface&MockObject $logMock;
+ protected Util&MockObject $utilMock;
+ protected IConfig&MockObject $configMock;
+ protected ILockingProvider&MockObject $lockingProviderMock;
+
+ protected function setUp(): void {
+ parent::setUp();
+ $this->userId = 'user1';
+ $this->systemKeyId = 'systemKeyId';
+ $this->keyStorageMock = $this->createMock(IStorage::class);
+ $this->cryptMock = $this->getMockBuilder(Crypt::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->configMock = $this->createMock(IConfig::class);
+ $this->configMock->expects($this->any())
+ ->method('getAppValue')
+ ->willReturn($this->systemKeyId);
+ $this->userMock = $this->createMock(IUserSession::class);
+ $this->sessionMock = $this->getMockBuilder(Session::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->logMock = $this->createMock(LoggerInterface::class);
+ $this->utilMock = $this->getMockBuilder(Util::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->lockingProviderMock = $this->createMock(ILockingProvider::class);
+
+ $this->instance = new KeyManager(
+ $this->keyStorageMock,
+ $this->cryptMock,
+ $this->configMock,
+ $this->userMock,
+ $this->sessionMock,
+ $this->logMock,
+ $this->utilMock,
+ $this->lockingProviderMock
+ );
+ }
+
+ public function testDeleteShareKey(): void {
+ $this->keyStorageMock->expects($this->any())
+ ->method('deleteFileKey')
+ ->with($this->equalTo('/path'), $this->equalTo('keyId.shareKey'))
+ ->willReturn(true);
+
+ $this->assertTrue(
+ $this->instance->deleteShareKey('/path', 'keyId')
+ );
+ }
+
+ public function testGetPrivateKey(): void {
+ $this->keyStorageMock->expects($this->any())
+ ->method('getUserKey')
+ ->with($this->equalTo($this->userId), $this->equalTo('privateKey'))
+ ->willReturn('privateKey');
+
+
+ $this->assertSame('privateKey',
+ $this->instance->getPrivateKey($this->userId)
+ );
+ }
+
+ public function testGetPublicKey(): void {
+ $this->keyStorageMock->expects($this->any())
+ ->method('getUserKey')
+ ->with($this->equalTo($this->userId), $this->equalTo('publicKey'))
+ ->willReturn('publicKey');
+
+
+ $this->assertSame('publicKey',
+ $this->instance->getPublicKey($this->userId)
+ );
+ }
+
+ public function testRecoveryKeyExists(): void {
+ $this->keyStorageMock->expects($this->any())
+ ->method('getSystemUserKey')
+ ->with($this->equalTo($this->systemKeyId . '.publicKey'))
+ ->willReturn('recoveryKey');
+
+
+ $this->assertTrue($this->instance->recoveryKeyExists());
+ }
+
+ public function testCheckRecoveryKeyPassword(): void {
+ $this->keyStorageMock->expects($this->any())
+ ->method('getSystemUserKey')
+ ->with($this->equalTo($this->systemKeyId . '.privateKey'))
+ ->willReturn('recoveryKey');
+ $this->cryptMock->expects($this->any())
+ ->method('decryptPrivateKey')
+ ->with($this->equalTo('recoveryKey'), $this->equalTo('pass'))
+ ->willReturn('decryptedRecoveryKey');
+
+ $this->assertTrue($this->instance->checkRecoveryPassword('pass'));
+ }
+
+ public function testSetPublicKey(): void {
+ $this->keyStorageMock->expects($this->any())
+ ->method('setUserKey')
+ ->with(
+ $this->equalTo($this->userId),
+ $this->equalTo('publicKey'),
+ $this->equalTo('key'))
+ ->willReturn(true);
+
+
+ $this->assertTrue(
+ $this->instance->setPublicKey($this->userId, 'key')
+ );
+ }
+
+ public function testSetPrivateKey(): void {
+ $this->keyStorageMock->expects($this->any())
+ ->method('setUserKey')
+ ->with(
+ $this->equalTo($this->userId),
+ $this->equalTo('privateKey'),
+ $this->equalTo('key'))
+ ->willReturn(true);
+
+
+ $this->assertTrue(
+ $this->instance->setPrivateKey($this->userId, 'key')
+ );
+ }
+
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataTestUserHasKeys')]
+ public function testUserHasKeys($key, $expected): void {
+ $this->keyStorageMock->expects($this->exactly(2))
+ ->method('getUserKey')
+ ->with($this->equalTo($this->userId), $this->anything())
+ ->willReturn($key);
+
+
+ $this->assertSame($expected,
+ $this->instance->userHasKeys($this->userId)
+ );
+ }
+
+ public static function dataTestUserHasKeys(): array {
+ return [
+ ['key', true],
+ ['', false]
+ ];
+ }
+
+
+ public function testUserHasKeysMissingPrivateKey(): void {
+ $this->expectException(PrivateKeyMissingException::class);
+
+ $this->keyStorageMock->expects($this->exactly(2))
+ ->method('getUserKey')
+ ->willReturnCallback(function ($uid, $keyID, $encryptionModuleId) {
+ if ($keyID === 'privateKey') {
+ return '';
+ }
+ return 'key';
+ });
+
+ $this->instance->userHasKeys($this->userId);
+ }
+
+
+ public function testUserHasKeysMissingPublicKey(): void {
+ $this->expectException(PublicKeyMissingException::class);
+
+ $this->keyStorageMock->expects($this->exactly(2))
+ ->method('getUserKey')
+ ->willReturnCallback(function ($uid, $keyID, $encryptionModuleId) {
+ if ($keyID === 'publicKey') {
+ return '';
+ }
+ return 'key';
+ });
+
+ $this->instance->userHasKeys($this->userId);
+ }
+
+ /**
+ * @param bool $useMasterKey
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataTestInit')]
+ public function testInit($useMasterKey): void {
+ /** @var KeyManager&MockObject $instance */
+ $instance = $this->getMockBuilder(KeyManager::class)
+ ->setConstructorArgs(
+ [
+ $this->keyStorageMock,
+ $this->cryptMock,
+ $this->configMock,
+ $this->userMock,
+ $this->sessionMock,
+ $this->logMock,
+ $this->utilMock,
+ $this->lockingProviderMock
+ ]
+ )->onlyMethods(['getMasterKeyId', 'getMasterKeyPassword', 'getSystemPrivateKey', 'getPrivateKey'])
+ ->getMock();
+
+ $this->utilMock->expects($this->once())->method('isMasterKeyEnabled')
+ ->willReturn($useMasterKey);
+
+ $sessionSetStatusCalls = [];
+ $this->sessionMock->expects($this->exactly(2))
+ ->method('setStatus')
+ ->willReturnCallback(function (string $status) use (&$sessionSetStatusCalls): void {
+ $sessionSetStatusCalls[] = $status;
+ });
+
+ $instance->expects($this->any())->method('getMasterKeyId')->willReturn('masterKeyId');
+ $instance->expects($this->any())->method('getMasterKeyPassword')->willReturn('masterKeyPassword');
+ $instance->expects($this->any())->method('getSystemPrivateKey')->with('masterKeyId')->willReturn('privateMasterKey');
+ $instance->expects($this->any())->method('getPrivateKey')->with($this->userId)->willReturn('privateUserKey');
+
+ if ($useMasterKey) {
+ $this->cryptMock->expects($this->once())->method('decryptPrivateKey')
+ ->with('privateMasterKey', 'masterKeyPassword', 'masterKeyId')
+ ->willReturn('key');
+ } else {
+ $this->cryptMock->expects($this->once())->method('decryptPrivateKey')
+ ->with('privateUserKey', 'pass', $this->userId)
+ ->willReturn('key');
+ }
+
+ $this->sessionMock->expects($this->once())->method('setPrivateKey')
+ ->with('key');
+
+ $this->assertTrue($instance->init($this->userId, 'pass'));
+ self::assertEquals([
+ Session::INIT_EXECUTED,
+ Session::INIT_SUCCESSFUL,
+ ], $sessionSetStatusCalls);
+ }
+
+ public static function dataTestInit(): array {
+ return [
+ [true],
+ [false]
+ ];
+ }
+
+
+ public function testSetRecoveryKey(): void {
+ $this->keyStorageMock->expects($this->exactly(2))
+ ->method('setSystemUserKey')
+ ->willReturn(true);
+ $this->cryptMock->expects($this->any())
+ ->method('encryptPrivateKey')
+ ->with($this->equalTo('privateKey'), $this->equalTo('pass'))
+ ->willReturn('decryptedPrivateKey');
+
+
+ $this->assertTrue(
+ $this->instance->setRecoveryKey('pass',
+ ['publicKey' => 'publicKey', 'privateKey' => 'privateKey'])
+ );
+ }
+
+ public function testSetSystemPrivateKey(): void {
+ $this->keyStorageMock->expects($this->exactly(1))
+ ->method('setSystemUserKey')
+ ->with($this->equalTo('keyId.privateKey'), $this->equalTo('key'))
+ ->willReturn(true);
+
+
+ $this->assertTrue(
+ $this->instance->setSystemPrivateKey('keyId', 'key')
+ );
+ }
+
+ public function testGetSystemPrivateKey(): void {
+ $this->keyStorageMock->expects($this->exactly(1))
+ ->method('getSystemUserKey')
+ ->with($this->equalTo('keyId.privateKey'))
+ ->willReturn('systemPrivateKey');
+
+
+ $this->assertSame('systemPrivateKey',
+ $this->instance->getSystemPrivateKey('keyId')
+ );
+ }
+
+ public function testGetEncryptedFileKey(): void {
+ $this->keyStorageMock->expects($this->once())
+ ->method('getFileKey')
+ ->with('/', 'fileKey')
+ ->willReturn(true);
+
+ $this->assertTrue($this->instance->getEncryptedFileKey('/'));
+ }
+
+ public static function dataTestGetFileKey(): array {
+ return [
+ ['user1', false, 'privateKey', 'legacyKey', 'multiKeyDecryptResult'],
+ ['user1', false, 'privateKey', '', 'multiKeyDecryptResult'],
+ ['user1', false, false, 'legacyKey', ''],
+ ['user1', false, false, '', ''],
+ ['user1', true, 'privateKey', 'legacyKey', 'multiKeyDecryptResult'],
+ ['user1', true, 'privateKey', '', 'multiKeyDecryptResult'],
+ ['user1', true, false, 'legacyKey', ''],
+ ['user1', true, false, '', ''],
+ [null, false, 'privateKey', 'legacyKey', 'multiKeyDecryptResult'],
+ [null, false, 'privateKey', '', 'multiKeyDecryptResult'],
+ [null, false, false, 'legacyKey', ''],
+ [null, false, false, '', ''],
+ [null, true, 'privateKey', 'legacyKey', 'multiKeyDecryptResult'],
+ [null, true, 'privateKey', '', 'multiKeyDecryptResult'],
+ [null, true, false, 'legacyKey', ''],
+ [null, true, false, '', ''],
+ ];
+ }
+
+ /**
+ *
+ * @param $uid
+ * @param $isMasterKeyEnabled
+ * @param $privateKey
+ * @param $expected
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataTestGetFileKey')]
+ public function testGetFileKey($uid, $isMasterKeyEnabled, $privateKey, $encryptedFileKey, $expected): void {
+ $path = '/foo.txt';
+
+ if ($isMasterKeyEnabled) {
+ $expectedUid = 'masterKeyId';
+ $this->configMock->expects($this->any())->method('getSystemValue')->with('secret')
+ ->willReturn('password');
+ } elseif (!$uid) {
+ $expectedUid = 'systemKeyId';
+ } else {
+ $expectedUid = $uid;
+ }
+
+ $this->invokePrivate($this->instance, 'masterKeyId', ['masterKeyId']);
+
+ $this->keyStorageMock->expects($this->exactly(2))
+ ->method('getFileKey')
+ ->willReturnMap([
+ [$path, 'fileKey', 'OC_DEFAULT_MODULE', $encryptedFileKey],
+ [$path, $expectedUid . '.shareKey', 'OC_DEFAULT_MODULE', 'fileKey'],
+ ]);
+
+ $this->utilMock->expects($this->any())->method('isMasterKeyEnabled')
+ ->willReturn($isMasterKeyEnabled);
+
+ if (is_null($uid)) {
+ $this->keyStorageMock->expects($this->once())
+ ->method('getSystemUserKey')
+ ->willReturn(true);
+ $this->cryptMock->expects($this->once())
+ ->method('decryptPrivateKey')
+ ->willReturn($privateKey);
+ } else {
+ $this->keyStorageMock->expects($this->never())
+ ->method('getSystemUserKey');
+ $this->sessionMock->expects($this->once())->method('getPrivateKey')->willReturn($privateKey);
+ }
+
+ if (!empty($encryptedFileKey)) {
+ $this->cryptMock->expects($this->never())
+ ->method('multiKeyDecrypt');
+ if ($privateKey) {
+ $this->cryptMock->expects($this->once())
+ ->method('multiKeyDecryptLegacy')
+ ->willReturn('multiKeyDecryptResult');
+ } else {
+ $this->cryptMock->expects($this->never())
+ ->method('multiKeyDecryptLegacy');
+ }
+ } else {
+ $this->cryptMock->expects($this->never())
+ ->method('multiKeyDecryptLegacy');
+ if ($privateKey) {
+ $this->cryptMock->expects($this->once())
+ ->method('multiKeyDecrypt')
+ ->willReturn('multiKeyDecryptResult');
+ } else {
+ $this->cryptMock->expects($this->never())
+ ->method('multiKeyDecrypt');
+ }
+ }
+
+ $this->assertSame($expected,
+ $this->instance->getFileKey($path, $uid, null)
+ );
+ }
+
+ public function testDeletePrivateKey(): void {
+ $this->keyStorageMock->expects($this->once())
+ ->method('deleteUserKey')
+ ->with('user1', 'privateKey')
+ ->willReturn(true);
+
+ $this->assertTrue(self::invokePrivate($this->instance,
+ 'deletePrivateKey',
+ [$this->userId]));
+ }
+
+ public function testDeleteAllFileKeys(): void {
+ $this->keyStorageMock->expects($this->once())
+ ->method('deleteAllFileKeys')
+ ->willReturn(true);
+
+ $this->assertTrue($this->instance->deleteAllFileKeys('/'));
+ }
+
+ /**
+ * test add public share key and or recovery key to the list of public keys
+ *
+ *
+ * @param array $accessList
+ * @param array $publicKeys
+ * @param string $uid
+ * @param array $expectedKeys
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataTestAddSystemKeys')]
+ public function testAddSystemKeys($accessList, $publicKeys, $uid, $expectedKeys): void {
+ $publicShareKeyId = 'publicShareKey';
+ $recoveryKeyId = 'recoveryKey';
+
+ $this->keyStorageMock->expects($this->any())
+ ->method('getSystemUserKey')
+ ->willReturnCallback(function ($keyId, $encryptionModuleId) {
+ return $keyId;
+ });
+
+ $this->utilMock->expects($this->any())
+ ->method('isRecoveryEnabledForUser')
+ ->willReturnCallback(function ($uid) {
+ if ($uid === 'user1') {
+ return true;
+ }
+ return false;
+ });
+
+ // set key IDs
+ self::invokePrivate($this->instance, 'publicShareKeyId', [$publicShareKeyId]);
+ self::invokePrivate($this->instance, 'recoveryKeyId', [$recoveryKeyId]);
+
+ $result = $this->instance->addSystemKeys($accessList, $publicKeys, $uid);
+
+ foreach ($expectedKeys as $expected) {
+ $this->assertArrayHasKey($expected, $result);
+ }
+
+ $this->assertSameSize($expectedKeys, $result);
+ }
+
+ /**
+ * data provider for testAddSystemKeys()
+ *
+ * @return array
+ */
+ public static function dataTestAddSystemKeys(): array {
+ return [
+ [['public' => true],[], 'user1', ['publicShareKey', 'recoveryKey']],
+ [['public' => false], [], 'user1', ['recoveryKey']],
+ [['public' => true],[], 'user2', ['publicShareKey']],
+ [['public' => false], [], 'user2', []],
+ ];
+ }
+
+ public function testGetMasterKeyId(): void {
+ $this->assertSame('systemKeyId', $this->instance->getMasterKeyId());
+ }
+
+ public function testGetPublicMasterKey(): void {
+ $this->keyStorageMock->expects($this->once())->method('getSystemUserKey')
+ ->with('systemKeyId.publicKey', Encryption::ID)
+ ->willReturn(true);
+
+ $this->assertTrue(
+ $this->instance->getPublicMasterKey()
+ );
+ }
+
+ public function testGetMasterKeyPassword(): void {
+ $this->configMock->expects($this->once())->method('getSystemValue')->with('secret')
+ ->willReturn('password');
+
+ $this->assertSame('password',
+ $this->invokePrivate($this->instance, 'getMasterKeyPassword', [])
+ );
+ }
+
+
+ public function testGetMasterKeyPasswordException(): void {
+ $this->expectException(\Exception::class);
+
+ $this->configMock->expects($this->once())->method('getSystemValue')->with('secret')
+ ->willReturn('');
+
+ $this->invokePrivate($this->instance, 'getMasterKeyPassword', []);
+ }
+
+ /**
+ * @param $masterKey
+ */
+ #[\PHPUnit\Framework\Attributes\DataProvider('dataTestValidateMasterKey')]
+ public function testValidateMasterKey($masterKey): void {
+ /** @var KeyManager&MockObject $instance */
+ $instance = $this->getMockBuilder(KeyManager::class)
+ ->setConstructorArgs(
+ [
+ $this->keyStorageMock,
+ $this->cryptMock,
+ $this->configMock,
+ $this->userMock,
+ $this->sessionMock,
+ $this->logMock,
+ $this->utilMock,
+ $this->lockingProviderMock
+ ]
+ )->onlyMethods(['getPublicMasterKey', 'setSystemPrivateKey', 'getMasterKeyPassword'])
+ ->getMock();
+
+ $this->utilMock->expects($this->once())->method('isMasterKeyEnabled')
+ ->willReturn(true);
+
+ $instance->expects($this->once())->method('getPublicMasterKey')
+ ->willReturn($masterKey);
+
+ $instance->expects($this->any())->method('getMasterKeyPassword')->willReturn('masterKeyPassword');
+ $this->cryptMock->expects($this->any())->method('generateHeader')->willReturn('header');
+
+ if (empty($masterKey)) {
+ $this->cryptMock->expects($this->once())->method('createKeyPair')
+ ->willReturn(['publicKey' => 'public', 'privateKey' => 'private']);
+ $this->keyStorageMock->expects($this->once())->method('setSystemUserKey')
+ ->with('systemKeyId.publicKey', 'public', Encryption::ID);
+ $this->cryptMock->expects($this->once())->method('encryptPrivateKey')
+ ->with('private', 'masterKeyPassword', 'systemKeyId')
+ ->willReturn('EncryptedKey');
+ $this->lockingProviderMock->expects($this->once())
+ ->method('acquireLock');
+ $instance->expects($this->once())->method('setSystemPrivateKey')
+ ->with('systemKeyId', 'headerEncryptedKey');
+ } else {
+ $this->cryptMock->expects($this->never())->method('createKeyPair');
+ $this->keyStorageMock->expects($this->never())->method('setSystemUserKey');
+ $this->cryptMock->expects($this->never())->method('encryptPrivateKey');
+ $instance->expects($this->never())->method('setSystemPrivateKey');
+ }
+
+ $instance->validateMasterKey();
+ }
+
+ public function testValidateMasterKeyLocked(): void {
+ /** @var KeyManager&MockObject $instance */
+ $instance = $this->getMockBuilder(KeyManager::class)
+ ->setConstructorArgs([
+ $this->keyStorageMock,
+ $this->cryptMock,
+ $this->configMock,
+ $this->userMock,
+ $this->sessionMock,
+ $this->logMock,
+ $this->utilMock,
+ $this->lockingProviderMock
+ ])
+ ->onlyMethods(['getPublicMasterKey', 'getPrivateMasterKey', 'setSystemPrivateKey', 'getMasterKeyPassword'])
+ ->getMock();
+
+ $this->utilMock->expects($this->once())->method('isMasterKeyEnabled')
+ ->willReturn(true);
+
+ $instance->expects($this->once())->method('getPublicMasterKey')
+ ->willReturn('');
+ $instance->expects($this->once())->method('getPrivateMasterKey')
+ ->willReturn('');
+
+ $instance->expects($this->any())->method('getMasterKeyPassword')->willReturn('masterKeyPassword');
+ $this->cryptMock->expects($this->any())->method('generateHeader')->willReturn('header');
+
+ $this->lockingProviderMock->expects($this->once())
+ ->method('acquireLock')
+ ->willThrowException(new LockedException('encryption-generateMasterKey'));
+
+ $this->expectException(LockedException::class);
+ $instance->validateMasterKey();
+ }
+
+ public static function dataTestValidateMasterKey(): array {
+ return [
+ ['masterKey'],
+ ['']
+ ];
+ }
+
+ public function testGetVersionWithoutFileInfo(): void {
+ $view = $this->getMockBuilder(View::class)
+ ->disableOriginalConstructor()->getMock();
+ $view->expects($this->once())
+ ->method('getFileInfo')
+ ->with('/admin/files/myfile.txt')
+ ->willReturn(false);
+
+ /** @var View $view */
+ $this->assertSame(0, $this->instance->getVersion('/admin/files/myfile.txt', $view));
+ }
+
+ public function testGetVersionWithFileInfo(): void {
+ $view = $this->getMockBuilder(View::class)
+ ->disableOriginalConstructor()->getMock();
+ $fileInfo = $this->getMockBuilder(FileInfo::class)
+ ->disableOriginalConstructor()->getMock();
+ $fileInfo->expects($this->once())
+ ->method('getEncryptedVersion')
+ ->willReturn(1337);
+ $view->expects($this->once())
+ ->method('getFileInfo')
+ ->with('/admin/files/myfile.txt')
+ ->willReturn($fileInfo);
+
+ /** @var View $view */
+ $this->assertSame(1337, $this->instance->getVersion('/admin/files/myfile.txt', $view));
+ }
+
+ public function testSetVersionWithFileInfo(): void {
+ $view = $this->getMockBuilder(View::class)
+ ->disableOriginalConstructor()->getMock();
+ $cache = $this->getMockBuilder(ICache::class)
+ ->disableOriginalConstructor()->getMock();
+ $cache->expects($this->once())
+ ->method('update')
+ ->with(123, ['encrypted' => 5, 'encryptedVersion' => 5]);
+ $storage = $this->getMockBuilder(FilesIStorage::class)
+ ->disableOriginalConstructor()->getMock();
+ $storage->expects($this->once())
+ ->method('getCache')
+ ->willReturn($cache);
+ $fileInfo = $this->getMockBuilder(FileInfo::class)
+ ->disableOriginalConstructor()->getMock();
+ $fileInfo->expects($this->once())
+ ->method('getStorage')
+ ->willReturn($storage);
+ $fileInfo->expects($this->once())
+ ->method('getId')
+ ->willReturn(123);
+ $view->expects($this->once())
+ ->method('getFileInfo')
+ ->with('/admin/files/myfile.txt')
+ ->willReturn($fileInfo);
+
+ /** @var View $view */
+ $this->instance->setVersion('/admin/files/myfile.txt', 5, $view);
+ }
+
+ public function testSetVersionWithoutFileInfo(): void {
+ $view = $this->getMockBuilder(View::class)
+ ->disableOriginalConstructor()->getMock();
+ $view->expects($this->once())
+ ->method('getFileInfo')
+ ->with('/admin/files/myfile.txt')
+ ->willReturn(false);
+
+ /** @var View $view */
+ $this->instance->setVersion('/admin/files/myfile.txt', 5, $view);
+ }
+
+ public function testBackupUserKeys(): void {
+ $this->keyStorageMock->expects($this->once())->method('backupUserKeys')
+ ->with('OC_DEFAULT_MODULE', 'test', 'user1');
+ $this->instance->backupUserKeys('test', 'user1');
+ }
+}