aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Files
diff options
context:
space:
mode:
authorJohn Molakvoæ <skjnldsv@users.noreply.github.com>2024-03-15 13:03:34 +0100
committerGitHub <noreply@github.com>2024-03-15 13:03:34 +0100
commit9338ef36ded767f2c35b7ec575b351859420ed09 (patch)
tree65c53c6a36f300859dc22b2d423275bcf2911367 /tests/lib/Files
parent6b09a79227a5dc98aa4620c6e5e15b610a06c806 (diff)
parentdf1cd1ba7e6e1f6e66a2b3229b5c082f1b81162e (diff)
downloadnextcloud-server-9338ef36ded767f2c35b7ec575b351859420ed09.tar.gz
nextcloud-server-9338ef36ded767f2c35b7ec575b351859420ed09.zip
Merge branch 'master' into refactor/OC-Server-getShareManager
Signed-off-by: John Molakvoæ <skjnldsv@users.noreply.github.com>
Diffstat (limited to 'tests/lib/Files')
-rw-r--r--tests/lib/Files/Cache/ScannerTest.php44
-rw-r--r--tests/lib/Files/Cache/SearchBuilderTest.php1
-rw-r--r--tests/lib/Files/Cache/UpdaterLegacyTest.php4
-rw-r--r--tests/lib/Files/Config/UserMountCacheTest.php62
-rw-r--r--tests/lib/Files/EtagTest.php2
-rw-r--r--tests/lib/Files/FileInfoTest.php18
-rw-r--r--tests/lib/Files/FilesystemTest.php6
-rw-r--r--tests/lib/Files/Mount/CacheMountProviderTest.php108
-rw-r--r--tests/lib/Files/Node/FileTest.php25
-rw-r--r--tests/lib/Files/Node/FolderTest.php46
-rw-r--r--tests/lib/Files/Node/HookConnectorTest.php19
-rw-r--r--tests/lib/Files/Node/IntegrationTest.php10
-rw-r--r--tests/lib/Files/Node/NodeTest.php22
-rw-r--r--tests/lib/Files/Node/RootTest.php29
-rw-r--r--tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php4
-rw-r--r--tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php38
-rw-r--r--tests/lib/Files/ObjectStore/S3Test.php19
-rw-r--r--tests/lib/Files/ObjectStore/SwiftTest.php4
-rw-r--r--tests/lib/Files/Search/QueryOptimizer/CombinedTests.php191
-rw-r--r--tests/lib/Files/Search/QueryOptimizer/FlattenNestedBoolTest.php42
-rw-r--r--tests/lib/Files/Search/QueryOptimizer/MergeDistributiveOperationsTest.php160
-rw-r--r--tests/lib/Files/Search/QueryOptimizer/OrEqualsToInTest.php120
-rw-r--r--tests/lib/Files/Search/SearchIntegrationTest.php44
-rw-r--r--tests/lib/Files/Storage/CommonTest.php51
-rw-r--r--tests/lib/Files/Storage/LocalTest.php11
-rw-r--r--tests/lib/Files/Storage/Storage.php5
-rw-r--r--tests/lib/Files/Storage/Wrapper/EncryptionTest.php70
-rw-r--r--tests/lib/Files/Storage/Wrapper/KnownMtimeTest.php70
-rw-r--r--tests/lib/Files/Stream/EncryptionTest.php14
-rw-r--r--tests/lib/Files/Type/LoaderTest.php11
-rw-r--r--tests/lib/Files/ViewTest.php9
31 files changed, 1083 insertions, 176 deletions
diff --git a/tests/lib/Files/Cache/ScannerTest.php b/tests/lib/Files/Cache/ScannerTest.php
index e4c052f6025..22d458a4a9b 100644
--- a/tests/lib/Files/Cache/ScannerTest.php
+++ b/tests/lib/Files/Cache/ScannerTest.php
@@ -404,4 +404,48 @@ class ScannerTest extends TestCase {
['/sub/folder/foo.txt', false],
];
}
+
+ public function testNoETagUnscannedFolder() {
+ $this->fillTestFolders();
+
+ $this->scanner->scan('');
+
+ $oldFolderEntry = $this->cache->get('folder');
+ // create a new file in a folder by keeping the mtime unchanged, but mark the folder as unscanned
+ $this->storage->file_put_contents('folder/new.txt', 'foo');
+ $this->storage->touch('folder', $oldFolderEntry->getMTime());
+ $this->cache->update($oldFolderEntry->getId(), ['size' => -1]);
+
+ $this->scanner->scan('');
+
+ $this->cache->inCache('folder/new.txt');
+
+ $newFolderEntry = $this->cache->get('folder');
+ $this->assertNotEquals($newFolderEntry->getEtag(), $oldFolderEntry->getEtag());
+ }
+
+ public function testNoETagUnscannedSubFolder() {
+ $this->fillTestFolders();
+ $this->storage->mkdir('folder/sub');
+
+ $this->scanner->scan('');
+
+ $oldFolderEntry1 = $this->cache->get('folder');
+ $oldFolderEntry2 = $this->cache->get('folder/sub');
+ // create a new file in a folder by keeping the mtime unchanged, but mark the folder as unscanned
+ $this->storage->file_put_contents('folder/sub/new.txt', 'foo');
+ $this->storage->touch('folder/sub', $oldFolderEntry1->getMTime());
+
+ // we only mark the direct parent as unscanned, which is the current "notify" behavior
+ $this->cache->update($oldFolderEntry2->getId(), ['size' => -1]);
+
+ $this->scanner->scan('');
+
+ $this->cache->inCache('folder/new.txt');
+
+ $newFolderEntry1 = $this->cache->get('folder');
+ $this->assertNotEquals($newFolderEntry1->getEtag(), $oldFolderEntry1->getEtag());
+ $newFolderEntry2 = $this->cache->get('folder/sub');
+ $this->assertNotEquals($newFolderEntry2->getEtag(), $oldFolderEntry2->getEtag());
+ }
}
diff --git a/tests/lib/Files/Cache/SearchBuilderTest.php b/tests/lib/Files/Cache/SearchBuilderTest.php
index 5eb1a0252f0..45fa17bd227 100644
--- a/tests/lib/Files/Cache/SearchBuilderTest.php
+++ b/tests/lib/Files/Cache/SearchBuilderTest.php
@@ -154,6 +154,7 @@ class SearchBuilderTest extends TestCase {
[new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', 'foo%'), [0, 1]],
[new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'image/jpg'), [0]],
[new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', 'image/%'), [0, 1]],
+ [new SearchComparison(ISearchComparison::COMPARE_IN, 'mimetype', ['image/jpg', 'image/png']), [0, 1]],
[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50),
new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125)
diff --git a/tests/lib/Files/Cache/UpdaterLegacyTest.php b/tests/lib/Files/Cache/UpdaterLegacyTest.php
index be0390db15e..ad6e7cff123 100644
--- a/tests/lib/Files/Cache/UpdaterLegacyTest.php
+++ b/tests/lib/Files/Cache/UpdaterLegacyTest.php
@@ -262,14 +262,14 @@ class UpdaterLegacyTest extends \Test\TestCase {
$this->assertIsString($cachedData['etag']);
$this->assertNotSame($oldEtag, $cachedData['etag']);
// rename can cause mtime change - invalid assert
-// $this->assertEquals($mtime, $cachedData['mtime']);
+ // $this->assertEquals($mtime, $cachedData['mtime']);
$cachedData = $view->getFileInfo('folder');
$this->assertIsString($folderCachedData['etag']);
$this->assertIsString($cachedData['etag']);
$this->assertNotSame($oldEtag, $cachedData['etag']);
// rename can cause mtime change - invalid assert
-// $this->assertEquals($mtime, $cachedData['mtime']);
+ // $this->assertEquals($mtime, $cachedData['mtime']);
}
public function testTouch() {
diff --git a/tests/lib/Files/Config/UserMountCacheTest.php b/tests/lib/Files/Config/UserMountCacheTest.php
index ccad4671ae9..9e910f4f47f 100644
--- a/tests/lib/Files/Config/UserMountCacheTest.php
+++ b/tests/lib/Files/Config/UserMountCacheTest.php
@@ -11,8 +11,8 @@ namespace Test\Files\Config;
use OC\DB\QueryBuilder\Literal;
use OC\Files\Mount\MountPoint;
use OC\Files\Storage\Storage;
-use OCP\Cache\CappedMemoryCache;
use OC\User\Manager;
+use OCP\Cache\CappedMemoryCache;
use OCP\Diagnostics\IEventLogger;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Config\ICachedMountInfo;
@@ -84,8 +84,8 @@ class UserMountCacheTest extends TestCase {
}
}
- private function getStorage($storageId) {
- $rootId = $this->createCacheEntry('', $storageId);
+ private function getStorage($storageId, $rootInternalPath = '') {
+ $rootId = $this->createCacheEntry($rootInternalPath, $storageId);
$storageCache = $this->getMockBuilder('\OC\Files\Cache\Storage')
->disableOriginalConstructor()
@@ -118,6 +118,10 @@ class UserMountCacheTest extends TestCase {
$this->invokePrivate($this->cache, 'mountsForUsers', [new CappedMemoryCache()]);
}
+ private function keyForMount(MountPoint $mount): string {
+ return $mount->getStorageRootId().'::'.$mount->getMountPoint();
+ }
+
public function testNewMounts() {
$user = $this->userManager->get('u1');
@@ -131,9 +135,9 @@ class UserMountCacheTest extends TestCase {
$cachedMounts = $this->cache->getMountsForUser($user);
$this->assertCount(1, $cachedMounts);
- $cachedMount = $cachedMounts[0];
+ $cachedMount = $cachedMounts[$this->keyForMount($mount)];
$this->assertEquals('/asd/', $cachedMount->getMountPoint());
- $this->assertEquals($user, $cachedMount->getUser());
+ $this->assertEquals($user->getUID(), $cachedMount->getUser()->getUID());
$this->assertEquals($storage->getCache()->getId(''), $cachedMount->getRootId());
$this->assertEquals($storage->getStorageCache()->getNumericId(), $cachedMount->getStorageId());
}
@@ -155,9 +159,9 @@ class UserMountCacheTest extends TestCase {
$cachedMounts = $this->cache->getMountsForUser($user);
$this->assertCount(1, $cachedMounts);
- $cachedMount = $cachedMounts[0];
+ $cachedMount = $cachedMounts[$this->keyForMount($mount)];
$this->assertEquals('/asd/', $cachedMount->getMountPoint());
- $this->assertEquals($user, $cachedMount->getUser());
+ $this->assertEquals($user->getUID(), $cachedMount->getUser()->getUID());
$this->assertEquals($storage->getCache()->getId(''), $cachedMount->getRootId());
$this->assertEquals($storage->getStorageCache()->getNumericId(), $cachedMount->getStorageId());
}
@@ -200,7 +204,7 @@ class UserMountCacheTest extends TestCase {
$cachedMounts = $this->cache->getMountsForUser($user);
$this->assertCount(1, $cachedMounts);
- $cachedMount = $cachedMounts[0];
+ $cachedMount = $cachedMounts[$this->keyForMount($mount)];
$this->assertEquals('/foo/', $cachedMount->getMountPoint());
}
@@ -223,7 +227,7 @@ class UserMountCacheTest extends TestCase {
$cachedMounts = $this->cache->getMountsForUser($user);
$this->assertCount(1, $cachedMounts);
- $cachedMount = $cachedMounts[0];
+ $cachedMount = $cachedMounts[$this->keyForMount($mount)];
$this->assertEquals(1, $cachedMount->getMountId());
}
@@ -233,7 +237,7 @@ class UserMountCacheTest extends TestCase {
$user3 = $this->userManager->get('u3');
[$storage1, $id1] = $this->getStorage(1);
- [$storage2, $id2] = $this->getStorage(2);
+ [$storage2, $id2] = $this->getStorage(2, 'foo/bar');
$mount1 = new MountPoint($storage1, '/foo/');
$mount2 = new MountPoint($storage2, '/bar/');
@@ -248,15 +252,17 @@ class UserMountCacheTest extends TestCase {
$cachedMounts = $this->cache->getMountsForUser($user1);
$this->assertCount(2, $cachedMounts);
- $this->assertEquals('/foo/', $cachedMounts[0]->getMountPoint());
- $this->assertEquals($user1, $cachedMounts[0]->getUser());
- $this->assertEquals($id1, $cachedMounts[0]->getRootId());
- $this->assertEquals(1, $cachedMounts[0]->getStorageId());
-
- $this->assertEquals('/bar/', $cachedMounts[1]->getMountPoint());
- $this->assertEquals($user1, $cachedMounts[1]->getUser());
- $this->assertEquals($id2, $cachedMounts[1]->getRootId());
- $this->assertEquals(2, $cachedMounts[1]->getStorageId());
+ $this->assertEquals('/foo/', $cachedMounts[$this->keyForMount($mount1)]->getMountPoint());
+ $this->assertEquals($user1->getUID(), $cachedMounts[$this->keyForMount($mount1)]->getUser()->getUID());
+ $this->assertEquals($id1, $cachedMounts[$this->keyForMount($mount1)]->getRootId());
+ $this->assertEquals(1, $cachedMounts[$this->keyForMount($mount1)]->getStorageId());
+ $this->assertEquals('', $cachedMounts[$this->keyForMount($mount1)]->getRootInternalPath());
+
+ $this->assertEquals('/bar/', $cachedMounts[$this->keyForMount($mount2)]->getMountPoint());
+ $this->assertEquals($user1->getUID(), $cachedMounts[$this->keyForMount($mount2)]->getUser()->getUID());
+ $this->assertEquals($id2, $cachedMounts[$this->keyForMount($mount2)]->getRootId());
+ $this->assertEquals(2, $cachedMounts[$this->keyForMount($mount2)]->getStorageId());
+ $this->assertEquals('foo/bar', $cachedMounts[$this->keyForMount($mount2)]->getRootInternalPath());
$cachedMounts = $this->cache->getMountsForUser($user3);
$this->assertEmpty($cachedMounts);
@@ -282,12 +288,12 @@ class UserMountCacheTest extends TestCase {
$this->assertCount(2, $cachedMounts);
$this->assertEquals('/bar/', $cachedMounts[0]->getMountPoint());
- $this->assertEquals($user1, $cachedMounts[0]->getUser());
+ $this->assertEquals($user1->getUID(), $cachedMounts[0]->getUser()->getUID());
$this->assertEquals($id2, $cachedMounts[0]->getRootId());
$this->assertEquals(2, $cachedMounts[0]->getStorageId());
$this->assertEquals('/bar/', $cachedMounts[1]->getMountPoint());
- $this->assertEquals($user2, $cachedMounts[1]->getUser());
+ $this->assertEquals($user2->getUID(), $cachedMounts[1]->getUser()->getUID());
$this->assertEquals($id2, $cachedMounts[1]->getRootId());
$this->assertEquals(2, $cachedMounts[1]->getStorageId());
}
@@ -312,12 +318,12 @@ class UserMountCacheTest extends TestCase {
$this->assertCount(2, $cachedMounts);
$this->assertEquals('/bar/', $cachedMounts[0]->getMountPoint());
- $this->assertEquals($user1, $cachedMounts[0]->getUser());
+ $this->assertEquals($user1->getUID(), $cachedMounts[0]->getUser()->getUID());
$this->assertEquals($id2, $cachedMounts[0]->getRootId());
$this->assertEquals(2, $cachedMounts[0]->getStorageId());
$this->assertEquals('/bar/', $cachedMounts[1]->getMountPoint());
- $this->assertEquals($user2, $cachedMounts[1]->getUser());
+ $this->assertEquals($user2->getUID(), $cachedMounts[1]->getUser()->getUID());
$this->assertEquals($id2, $cachedMounts[1]->getRootId());
$this->assertEquals(2, $cachedMounts[1]->getStorageId());
}
@@ -372,7 +378,7 @@ class UserMountCacheTest extends TestCase {
$this->assertCount(1, $cachedMounts);
$this->assertEquals('/foo/', $cachedMounts[0]->getMountPoint());
- $this->assertEquals($user1, $cachedMounts[0]->getUser());
+ $this->assertEquals($user1->getUID(), $cachedMounts[0]->getUser()->getUID());
$this->assertEquals($rootId, $cachedMounts[0]->getRootId());
$this->assertEquals(2, $cachedMounts[0]->getStorageId());
}
@@ -394,7 +400,7 @@ class UserMountCacheTest extends TestCase {
$this->assertCount(1, $cachedMounts);
$this->assertEquals('/foo/', $cachedMounts[0]->getMountPoint());
- $this->assertEquals($user1, $cachedMounts[0]->getUser());
+ $this->assertEquals($user1->getUID(), $cachedMounts[0]->getUser()->getUID());
$this->assertEquals($rootId, $cachedMounts[0]->getRootId());
$this->assertEquals(2, $cachedMounts[0]->getStorageId());
$this->assertEquals('foo/bar', $cachedMounts[0]->getInternalPath());
@@ -427,7 +433,7 @@ class UserMountCacheTest extends TestCase {
$this->assertCount(1, $cachedMounts);
$this->assertEquals('/', $cachedMounts[0]->getMountPoint());
- $this->assertEquals($user1, $cachedMounts[0]->getUser());
+ $this->assertEquals($user1->getUID(), $cachedMounts[0]->getUser()->getUID());
$this->assertEquals($folderId, $cachedMounts[0]->getRootId());
$this->assertEquals(2, $cachedMounts[0]->getStorageId());
$this->assertEquals('foo', $cachedMounts[0]->getRootInternalPath());
@@ -521,7 +527,7 @@ class UserMountCacheTest extends TestCase {
$cachedMounts = $this->cache->getMountsForUser($user1);
$this->assertCount(1, $cachedMounts);
- $this->assertEquals('', $cachedMounts[0]->getMountProvider());
+ $this->assertEquals('', $cachedMounts[$this->keyForMount($mount1)]->getMountProvider());
$mount1 = new MountPoint($storage1, '/foo/', null, null, null, null, 'dummy');
$this->cache->registerMounts($user1, [$mount1], ['dummy']);
@@ -530,6 +536,6 @@ class UserMountCacheTest extends TestCase {
$cachedMounts = $this->cache->getMountsForUser($user1);
$this->assertCount(1, $cachedMounts);
- $this->assertEquals('dummy', $cachedMounts[0]->getMountProvider());
+ $this->assertEquals('dummy', $cachedMounts[$this->keyForMount($mount1)]->getMountProvider());
}
}
diff --git a/tests/lib/Files/EtagTest.php b/tests/lib/Files/EtagTest.php
index b9583a6ac7c..a71bfa1e572 100644
--- a/tests/lib/Files/EtagTest.php
+++ b/tests/lib/Files/EtagTest.php
@@ -9,8 +9,8 @@
namespace Test\Files;
use OC\Files\Filesystem;
-use OCP\EventDispatcher\IEventDispatcher;
use OCA\Files_Sharing\AppInfo\Application;
+use OCP\EventDispatcher\IEventDispatcher;
use Psr\Log\LoggerInterface;
/**
diff --git a/tests/lib/Files/FileInfoTest.php b/tests/lib/Files/FileInfoTest.php
index fd2b506beb9..98f51aed67d 100644
--- a/tests/lib/Files/FileInfoTest.php
+++ b/tests/lib/Files/FileInfoTest.php
@@ -9,6 +9,8 @@
namespace Test\Files;
use OC\Files\FileInfo;
+use OC\Files\Mount\HomeMountPoint;
+use OC\Files\Mount\MountPoint;
use OC\Files\Storage\Home;
use OC\Files\Storage\Temporary;
use OCP\IConfig;
@@ -33,19 +35,27 @@ class FileInfoTest extends TestCase {
->willReturn('foo');
$user->method('getHome')
->willReturn('foo');
+ $storage = new Home(['user' => $user]);
$fileInfo = new FileInfo(
'',
- new Home(['user' => $user]),
- '', [], null);
+ $storage,
+ '',
+ [],
+ new HomeMountPoint($user, $storage, '/foo/files')
+ );
$this->assertFalse($fileInfo->isMounted());
}
public function testIsMountedNonHomeStorage() {
+ $storage = new Temporary();
$fileInfo = new FileInfo(
'',
- new Temporary(),
- '', [], null);
+ $storage,
+ '',
+ [],
+ new MountPoint($storage, '/foo/files/bar')
+ );
$this->assertTrue($fileInfo->isMounted());
}
}
diff --git a/tests/lib/Files/FilesystemTest.php b/tests/lib/Files/FilesystemTest.php
index 96fcab77474..5473f164cef 100644
--- a/tests/lib/Files/FilesystemTest.php
+++ b/tests/lib/Files/FilesystemTest.php
@@ -325,14 +325,14 @@ class FilesystemTest extends \Test\TestCase {
$rootView->mkdir('/' . $user);
$rootView->mkdir('/' . $user . '/files');
-// \OC\Files\Filesystem::file_put_contents('/foo', 'foo');
+ // \OC\Files\Filesystem::file_put_contents('/foo', 'foo');
\OC\Files\Filesystem::mkdir('/bar');
-// \OC\Files\Filesystem::file_put_contents('/bar//foo', 'foo');
+ // \OC\Files\Filesystem::file_put_contents('/bar//foo', 'foo');
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile();
file_put_contents($tmpFile, 'foo');
$fh = fopen($tmpFile, 'r');
-// \OC\Files\Filesystem::file_put_contents('/bar//foo', $fh);
+ // \OC\Files\Filesystem::file_put_contents('/bar//foo', $fh);
}
/**
diff --git a/tests/lib/Files/Mount/CacheMountProviderTest.php b/tests/lib/Files/Mount/CacheMountProviderTest.php
new file mode 100644
index 00000000000..d142e5fc3c2
--- /dev/null
+++ b/tests/lib/Files/Mount/CacheMountProviderTest.php
@@ -0,0 +1,108 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2023 Daniel Kesselberg <mail@danielkesselberg.de>
+ *
+ * @author Daniel Kesselberg <mail@danielkesselberg.de>
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * 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/>
+ *
+ */
+
+namespace Test\Files\Mount;
+
+use OC\Files\Mount\CacheMountProvider;
+use OC\Files\Storage\StorageFactory;
+use OCP\Files\Storage\IStorageFactory;
+use OCP\IConfig;
+use OCP\IUser;
+use Test\TestCase;
+
+class CacheMountProviderTestStream {
+ public static $statCounter = 0;
+ public static $mkdirCounter = 0;
+
+ public $context;
+
+ public function mkdir(string $path, int $mode, int $options): bool {
+ self::$mkdirCounter++;
+ return true;
+ }
+
+ public function url_stat(string $path, int $flags): array|false {
+ self::$statCounter++;
+ return false;
+ }
+}
+
+class CacheMountProviderTest extends TestCase {
+ private IConfig $config;
+ private IUser $user;
+ private IStorageFactory $storageFactory;
+
+ protected function setUp(): void {
+ $this->config = $this->createMock(IConfig::class);
+ $this->user = $this->createMock(IUser::class);
+ $this->storageFactory = new StorageFactory();
+ stream_wrapper_register('cachemountprovidertest', CacheMountProviderTestStream::class);
+ }
+
+ protected function tearDown(): void {
+ stream_wrapper_unregister('cachemountprovidertest');
+ }
+
+ public function testGetMountsForUser(): void {
+ $provider = new CacheMountProvider($this->config);
+
+ $this->assertCount(0, $provider->getMountsForUser($this->user, $this->storageFactory));
+ }
+
+ public function testGetMountsForUserCacheDir(): void {
+ $this->config->expects($this->exactly(1))
+ ->method('getSystemValueString')
+ ->willReturnMap([
+ ['cache_path', '', 'cachemountprovidertest:////cache_path'],
+ ]);
+ $this->user->method('getUID')
+ ->willReturn('bob');
+
+ $provider = new CacheMountProvider($this->config);
+ $mounts = $provider->getMountsForUser($this->user, $this->storageFactory);
+
+ $this->assertCount(2, $mounts);
+ $this->assertEquals(1, CacheMountProviderTestStream::$statCounter);
+ $this->assertEquals(2, CacheMountProviderTestStream::$mkdirCounter);
+
+ $cacheMountProvider = $mounts[0];
+ $this->assertEquals('/bob/cache/', $cacheMountProvider->getMountPoint());
+
+ $cacheStorage = $cacheMountProvider->getStorage();
+ $this->assertEquals('local::cachemountprovidertest://cache_path/bob/', $cacheStorage->getId());
+
+ $uploadsMountProvider = $mounts[1];
+ $this->assertEquals('/bob/uploads/', $uploadsMountProvider->getMountPoint());
+
+ $uploadsStorage = $uploadsMountProvider->getStorage();
+ $this->assertEquals('local::cachemountprovidertest://cache_path/bob/uploads/', $uploadsStorage->getId());
+
+ $cacheStorage->mkdir('foobar');
+ $this->assertEquals(3, CacheMountProviderTestStream::$mkdirCounter);
+
+ $uploadsStorage->mkdir('foobar');
+ $this->assertEquals(4, CacheMountProviderTestStream::$mkdirCounter);
+ }
+}
diff --git a/tests/lib/Files/Node/FileTest.php b/tests/lib/Files/Node/FileTest.php
index 218e2531727..b245f5e2db5 100644
--- a/tests/lib/Files/Node/FileTest.php
+++ b/tests/lib/Files/Node/FileTest.php
@@ -39,7 +39,7 @@ class FileTest extends NodeTest {
public function testGetContent() {
/** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */
$root = $this->getMockBuilder('\OC\Files\Node\Root')
- ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$hook = function ($file) {
@@ -69,7 +69,7 @@ class FileTest extends NodeTest {
/** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */
$root = $this->getMockBuilder('\OC\Files\Node\Root')
- ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
@@ -88,7 +88,7 @@ class FileTest extends NodeTest {
public function testPutContent() {
/** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */
$root = $this->getMockBuilder('\OC\Files\Node\Root')
- ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
@@ -115,7 +115,7 @@ class FileTest extends NodeTest {
/** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */
$root = $this->getMockBuilder('\OC\Files\Node\Root')
- ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$this->view->expects($this->once())
@@ -130,7 +130,7 @@ class FileTest extends NodeTest {
public function testGetMimeType() {
/** @var \OC\Files\Node\Root|\PHPUnit\Framework\MockObject\MockObject $root */
$root = $this->getMockBuilder('\OC\Files\Node\Root')
- ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$this->view->expects($this->once())
@@ -154,7 +154,8 @@ class FileTest extends NodeTest {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$hook = function ($file) {
@@ -190,7 +191,8 @@ class FileTest extends NodeTest {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$hooksCalled = 0;
$hook = function ($file) use (&$hooksCalled) {
@@ -230,7 +232,8 @@ class FileTest extends NodeTest {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$hook = function ($file) {
throw new \Exception('Hooks are not supposed to be called');
@@ -256,7 +259,8 @@ class FileTest extends NodeTest {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$hook = function () {
throw new \Exception('Hooks are not supposed to be called');
@@ -282,7 +286,8 @@ class FileTest extends NodeTest {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$hook = function () {
throw new \Exception('Hooks are not supposed to be called');
diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php
index 0bcf69c5c13..a219222d008 100644
--- a/tests/lib/Files/Node/FolderTest.php
+++ b/tests/lib/Files/Node/FolderTest.php
@@ -68,7 +68,7 @@ class FolderTest extends NodeTest {
* @var \OC\Files\View | \PHPUnit\Framework\MockObject\MockObject $view
*/
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
@@ -101,7 +101,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
@@ -120,7 +120,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
@@ -140,7 +140,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
@@ -158,7 +158,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
@@ -182,7 +182,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
@@ -209,7 +209,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->method('getUser')
->willReturn($this->user);
@@ -226,7 +226,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
@@ -253,7 +253,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->method('getUser')
->willReturn($this->user);
@@ -270,7 +270,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->method('getUser')
->willReturn($this->user);
@@ -287,7 +287,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->method('getUser')
->willReturn($this->user);
@@ -328,7 +328,7 @@ class FolderTest extends NodeTest {
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
->setMethods(['getUser', 'getMountsIn', 'getMount'])
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
@@ -368,7 +368,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->method('getUser')
->willReturn($this->user);
@@ -408,7 +408,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
@@ -478,7 +478,7 @@ class FolderTest extends NodeTest {
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
->setMethods(['getMountsIn', 'getMount'])
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$storage = $this->createMock(\OC\Files\Storage\Storage::class);
$mount = new MountPoint($storage, '/bar');
@@ -525,7 +525,7 @@ class FolderTest extends NodeTest {
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
->setMethods(['getMountsIn', 'getMount'])
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$storage = $this->createMock(\OC\Files\Storage\Storage::class);
$mount = new MountPoint($storage, '/bar');
@@ -568,7 +568,7 @@ class FolderTest extends NodeTest {
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
->setMethods(['getMountsIn', 'getMount'])
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$storage = $this->createMock(\OC\Files\Storage\Storage::class);
$mount = new MountPoint($storage, '/bar');
@@ -610,7 +610,7 @@ class FolderTest extends NodeTest {
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
->setMethods(['getMountsIn', 'getMount'])
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$storage = $this->createMock(\OC\Files\Storage\Storage::class);
$mount1 = new MountPoint($storage, '/bar');
@@ -672,7 +672,7 @@ class FolderTest extends NodeTest {
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
->setMethods(['getUser', 'getMountsIn', 'getMount'])
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$view->expects($this->any())
@@ -697,7 +697,7 @@ class FolderTest extends NodeTest {
/** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */
$root = $this->getMockBuilder(Root::class)
->setMethods(['getUser', 'getMountsIn', 'getMount'])
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
/** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\FileInfo $folderInfo */
$folderInfo = $this->getMockBuilder(FileInfo::class)
@@ -762,7 +762,7 @@ class FolderTest extends NodeTest {
/** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */
$root = $this->getMockBuilder(Root::class)
->setMethods(['getUser', 'getMountsIn', 'getMount'])
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
/** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\FileInfo $folderInfo */
$folderInfo = $this->getMockBuilder(FileInfo::class)
@@ -826,7 +826,7 @@ class FolderTest extends NodeTest {
/** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\Node\Root $root */
$root = $this->getMockBuilder(Root::class)
->setMethods(['getUser', 'getMountsIn', 'getMount'])
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
/** @var \PHPUnit\Framework\MockObject\MockObject|\OC\Files\FileInfo $folderInfo */
$folderInfo = $this->getMockBuilder(FileInfo::class)
@@ -910,7 +910,7 @@ class FolderTest extends NodeTest {
$manager = $this->createMock(Manager::class);
$view = $this->getRootViewMock();
$root = $this->getMockBuilder(Root::class)
- ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$manager, $view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
$root->expects($this->any())
->method('getUser')
diff --git a/tests/lib/Files/Node/HookConnectorTest.php b/tests/lib/Files/Node/HookConnectorTest.php
index 0501c175a5f..c64052ad172 100644
--- a/tests/lib/Files/Node/HookConnectorTest.php
+++ b/tests/lib/Files/Node/HookConnectorTest.php
@@ -13,6 +13,7 @@ use OC\Files\Node\HookConnector;
use OC\Files\Node\Root;
use OC\Files\Storage\Temporary;
use OC\Files\View;
+use OC\Memcache\ArrayCache;
use OCP\EventDispatcher\GenericEvent as APIGenericEvent;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Events\Node\AbstractNodeEvent;
@@ -30,6 +31,7 @@ use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Files\Events\Node\NodeTouchedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\Files\Node;
+use OCP\ICacheFactory;
use OCP\IUserManager;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
@@ -51,6 +53,8 @@ class HookConnectorTest extends TestCase {
/** @var IEventDispatcher */
protected $eventDispatcher;
+ private LoggerInterface $logger;
+
/** @var View */
private $view;
@@ -67,6 +71,11 @@ class HookConnectorTest extends TestCase {
// this will setup the FS
$this->loginAsUser($this->userId);
$this->registerMount($this->userId, new Temporary(), '/' . $this->userId . '/files/');
+ $cacheFactory = $this->createMock(ICacheFactory::class);
+ $cacheFactory->method('createLocal')
+ ->willReturnCallback(function () {
+ return new ArrayCache();
+ });
$this->view = new View();
$this->root = new Root(
Filesystem::getMountManager(),
@@ -75,9 +84,11 @@ class HookConnectorTest extends TestCase {
\OC::$server->getUserMountCache(),
$this->createMock(LoggerInterface::class),
$this->createMock(IUserManager::class),
- $this->createMock(IEventDispatcher::class)
+ $this->createMock(IEventDispatcher::class),
+ $cacheFactory,
);
$this->eventDispatcher = \OC::$server->query(IEventDispatcher::class);
+ $this->logger = \OC::$server->query(LoggerInterface::class);
}
protected function tearDown(): void {
@@ -143,7 +154,7 @@ class HookConnectorTest extends TestCase {
* @dataProvider viewToNodeProvider
*/
public function testViewToNode(callable $operation, $expectedHook, $expectedLegacyEvent, $expectedEvent) {
- $connector = new HookConnector($this->root, $this->view, $this->eventDispatcher);
+ $connector = new HookConnector($this->root, $this->view, $this->eventDispatcher, $this->logger);
$connector->viewToNode();
$hookCalled = false;
/** @var Node $hookNode */
@@ -212,7 +223,7 @@ class HookConnectorTest extends TestCase {
* @dataProvider viewToNodeProviderCopyRename
*/
public function testViewToNodeCopyRename(callable $operation, $expectedHook, $expectedLegacyEvent, $expectedEvent) {
- $connector = new HookConnector($this->root, $this->view, $this->eventDispatcher);
+ $connector = new HookConnector($this->root, $this->view, $this->eventDispatcher, $this->logger);
$connector->viewToNode();
$hookCalled = false;
/** @var Node $hookSourceNode */
@@ -267,7 +278,7 @@ class HookConnectorTest extends TestCase {
}
public function testPostDeleteMeta() {
- $connector = new HookConnector($this->root, $this->view, $this->eventDispatcher);
+ $connector = new HookConnector($this->root, $this->view, $this->eventDispatcher, $this->logger);
$connector->viewToNode();
$hookCalled = false;
/** @var Node $hookNode */
diff --git a/tests/lib/Files/Node/IntegrationTest.php b/tests/lib/Files/Node/IntegrationTest.php
index 5ef5a134e1b..dacc65ad4d1 100644
--- a/tests/lib/Files/Node/IntegrationTest.php
+++ b/tests/lib/Files/Node/IntegrationTest.php
@@ -11,8 +11,10 @@ namespace Test\Files\Node;
use OC\Files\Node\Root;
use OC\Files\Storage\Temporary;
use OC\Files\View;
+use OC\Memcache\ArrayCache;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Mount\IMountManager;
+use OCP\ICacheFactory;
use OCP\IUserManager;
use Psr\Log\LoggerInterface;
use Test\Traits\UserTrait;
@@ -52,6 +54,11 @@ class IntegrationTest extends \Test\TestCase {
$user = $this->createUser($this->getUniqueID('user'), '');
$this->loginAsUser($user->getUID());
+ $cacheFactory = $this->createMock(ICacheFactory::class);
+ $cacheFactory->method('createLocal')
+ ->willReturnCallback(function () {
+ return new ArrayCache();
+ });
$this->view = new View();
$this->root = new Root(
@@ -61,7 +68,8 @@ class IntegrationTest extends \Test\TestCase {
\OC::$server->getUserMountCache(),
$this->createMock(LoggerInterface::class),
$this->createMock(IUserManager::class),
- $this->createMock(IEventDispatcher::class)
+ $this->createMock(IEventDispatcher::class),
+ $cacheFactory,
);
$storage = new Temporary([]);
$subStorage = new Temporary([]);
diff --git a/tests/lib/Files/Node/NodeTest.php b/tests/lib/Files/Node/NodeTest.php
index b63d287a191..85a7f8a82f3 100644
--- a/tests/lib/Files/Node/NodeTest.php
+++ b/tests/lib/Files/Node/NodeTest.php
@@ -11,12 +11,14 @@ namespace Test\Files\Node;
use OC\Files\FileInfo;
use OC\Files\Mount\Manager;
use OC\Files\View;
+use OC\Memcache\ArrayCache;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\IRootFolder;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\Files\Storage;
+use OCP\ICacheFactory;
use OCP\IUser;
use OCP\IUserManager;
use Psr\Log\LoggerInterface;
@@ -43,6 +45,8 @@ abstract class NodeTest extends \Test\TestCase {
protected $userManager;
/** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */
protected $eventDispatcher;
+ /** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */
+ protected $cacheFactory;
protected function setUp(): void {
parent::setUp();
@@ -63,8 +67,13 @@ abstract class NodeTest extends \Test\TestCase {
$this->logger = $this->createMock(LoggerInterface::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+ $this->cacheFactory = $this->createMock(ICacheFactory::class);
+ $this->cacheFactory->method('createLocal')
+ ->willReturnCallback(function () {
+ return new ArrayCache();
+ });
$this->root = $this->getMockBuilder('\OC\Files\Node\Root')
- ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->eventDispatcher])
+ ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->getMock();
}
@@ -174,7 +183,8 @@ abstract class NodeTest extends \Test\TestCase {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$root->listen('\OC\Files', 'preDelete', $preListener);
@@ -422,7 +432,8 @@ abstract class NodeTest extends \Test\TestCase {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$root->listen('\OC\Files', 'preTouch', $preListener);
$root->listen('\OC\Files', 'postTouch', $postListener);
@@ -481,8 +492,7 @@ abstract class NodeTest extends \Test\TestCase {
$parentNode = new \OC\Files\Node\Folder($this->root, $this->view, '/bar');
$newNode = $this->createTestNode($this->root, $this->view, '/bar/asd');
- $this->root->expects($this->exactly(2))
- ->method('get')
+ $this->root->method('get')
->willReturnMap([
['/bar/asd', $newNode],
['/bar', $parentNode]
@@ -600,7 +610,7 @@ abstract class NodeTest extends \Test\TestCase {
public function testMoveCopyHooks($operationMethod, $viewMethod, $preHookName, $postHookName) {
/** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject $root */
$root = $this->getMockBuilder('\OC\Files\Node\Root')
- ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher])
+ ->setConstructorArgs([$this->manager, $this->view, $this->user, $this->userMountCache, $this->logger, $this->userManager, $this->eventDispatcher, $this->cacheFactory])
->setMethods(['get'])
->getMock();
diff --git a/tests/lib/Files/Node/RootTest.php b/tests/lib/Files/Node/RootTest.php
index aab658c3c36..d9abe2955b1 100644
--- a/tests/lib/Files/Node/RootTest.php
+++ b/tests/lib/Files/Node/RootTest.php
@@ -8,12 +8,14 @@
namespace Test\Files\Node;
-use OCP\Cache\CappedMemoryCache;
use OC\Files\FileInfo;
use OC\Files\Mount\Manager;
use OC\Files\Node\Folder;
use OC\Files\View;
+use OC\Memcache\ArrayCache;
+use OCP\Cache\CappedMemoryCache;
use OCP\EventDispatcher\IEventDispatcher;
+use OCP\ICacheFactory;
use OCP\IUser;
use OCP\IUserManager;
use Psr\Log\LoggerInterface;
@@ -36,6 +38,8 @@ class RootTest extends \Test\TestCase {
private $userManager;
/** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */
private $eventDispatcher;
+ /** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */
+ protected $cacheFactory;
protected function setUp(): void {
parent::setUp();
@@ -50,6 +54,11 @@ class RootTest extends \Test\TestCase {
$this->logger = $this->createMock(LoggerInterface::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+ $this->cacheFactory = $this->createMock(ICacheFactory::class);
+ $this->cacheFactory->method('createLocal')
+ ->willReturnCallback(function () {
+ return new ArrayCache();
+ });
}
/**
@@ -82,7 +91,8 @@ class RootTest extends \Test\TestCase {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$view->expects($this->once())
@@ -114,7 +124,8 @@ class RootTest extends \Test\TestCase {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$view->expects($this->once())
@@ -138,7 +149,8 @@ class RootTest extends \Test\TestCase {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$root->get('/../foo');
@@ -156,7 +168,8 @@ class RootTest extends \Test\TestCase {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$root->get('/bar/foo');
@@ -170,7 +183,8 @@ class RootTest extends \Test\TestCase {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$user = $this->createMock(IUser::class);
$user
@@ -211,7 +225,8 @@ class RootTest extends \Test\TestCase {
$this->userMountCache,
$this->logger,
$this->userManager,
- $this->eventDispatcher
+ $this->eventDispatcher,
+ $this->cacheFactory,
);
$this->userManager
->expects($this->once())
diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php b/tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php
index b85f6289c94..9c398131535 100644
--- a/tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php
+++ b/tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php
@@ -30,7 +30,7 @@ use OCP\Files\ObjectStore\IObjectStore;
* Allow overwriting the object store instance for test purposes
*/
class ObjectStoreStorageOverwrite extends ObjectStoreStorage {
- public function setObjectStore(IObjectStore $objectStore) {
+ public function setObjectStore(IObjectStore $objectStore): void {
$this->objectStore = $objectStore;
}
@@ -38,7 +38,7 @@ class ObjectStoreStorageOverwrite extends ObjectStoreStorage {
return $this->objectStore;
}
- public function setValidateWrites(bool $validate) {
+ public function setValidateWrites(bool $validate): void {
$this->validateWrites = $validate;
}
}
diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php b/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php
index 1bebaf6c4ba..2f835747077 100644
--- a/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php
+++ b/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php
@@ -237,4 +237,42 @@ class ObjectStoreStorageTest extends Storage {
$this->assertEquals('2', $this->instance->file_get_contents('b/target/sub/2.txt'));
$this->assertEquals('3', $this->instance->file_get_contents('b/target/sub/3.txt'));
}
+
+ public function testCopyPreservesPermissions() {
+ $cache = $this->instance->getCache();
+
+ $this->instance->file_put_contents('test.txt', 'foo');
+ $this->assertTrue($cache->inCache('test.txt'));
+
+ $cache->update($cache->getId('test.txt'), ['permissions' => \OCP\Constants::PERMISSION_READ]);
+ $this->assertEquals(\OCP\Constants::PERMISSION_READ, $this->instance->getPermissions('test.txt'));
+
+ $this->assertTrue($this->instance->copy('test.txt', 'new.txt'));
+
+ $this->assertTrue($cache->inCache('new.txt'));
+ $this->assertEquals(\OCP\Constants::PERMISSION_READ, $this->instance->getPermissions('new.txt'));
+ }
+
+ /**
+ * Test that copying files will drop permissions like local storage does
+ * TODO: Drop this and fix local storage
+ */
+ public function testCopyGrantsPermissions() {
+ $config['objectstore'] = $this->objectStorage;
+ $config['handleCopiesAsOwned'] = true;
+ $instance = new ObjectStoreStorageOverwrite($config);
+
+ $cache = $instance->getCache();
+
+ $instance->file_put_contents('test.txt', 'foo');
+ $this->assertTrue($cache->inCache('test.txt'));
+
+ $cache->update($cache->getId('test.txt'), ['permissions' => \OCP\Constants::PERMISSION_READ]);
+ $this->assertEquals(\OCP\Constants::PERMISSION_READ, $instance->getPermissions('test.txt'));
+
+ $this->assertTrue($instance->copy('test.txt', 'new.txt'));
+
+ $this->assertTrue($cache->inCache('new.txt'));
+ $this->assertEquals(\OCP\Constants::PERMISSION_ALL, $instance->getPermissions('new.txt'));
+ }
}
diff --git a/tests/lib/Files/ObjectStore/S3Test.php b/tests/lib/Files/ObjectStore/S3Test.php
index fd451dc3c01..c8333ca1ea3 100644
--- a/tests/lib/Files/ObjectStore/S3Test.php
+++ b/tests/lib/Files/ObjectStore/S3Test.php
@@ -106,29 +106,30 @@ class S3Test extends ObjectStoreTest {
}
public function assertNoUpload($objectUrn) {
+ /** @var \OC\Files\ObjectStore\S3 */
$s3 = $this->getInstance();
$s3client = $s3->getConnection();
$uploads = $s3client->listMultipartUploads([
'Bucket' => $s3->getBucket(),
'Prefix' => $objectUrn,
]);
- $this->assertArrayNotHasKey('Uploads', $uploads);
+ $this->assertArrayNotHasKey('Uploads', $uploads, 'Assert is not uploaded');
}
public function testEmptyUpload() {
$s3 = $this->getInstance();
$emptyStream = fopen("php://memory", "r");
- fwrite($emptyStream, null);
+ fwrite($emptyStream, '');
$s3->writeObject('emptystream', $emptyStream);
$this->assertNoUpload('emptystream');
- $this->assertTrue($s3->objectExists('emptystream'));
+ $this->assertTrue($s3->objectExists('emptystream'), 'Object exists on S3');
$thrown = false;
try {
- self::assertFalse($s3->readObject('emptystream'));
+ self::assertFalse($s3->readObject('emptystream'), 'Reading empty stream object should return false');
} catch (\Exception $e) {
// An exception is expected here since 0 byte files are wrapped
// to be read from an empty memory stream in the ObjectStoreStorage
@@ -163,20 +164,20 @@ class S3Test extends ObjectStoreTest {
$s3->writeObject('testfilesizes', $sourceStream);
$this->assertNoUpload('testfilesizes');
- self::assertTrue($s3->objectExists('testfilesizes'));
+ self::assertTrue($s3->objectExists('testfilesizes'), 'Object exists on S3');
$result = $s3->readObject('testfilesizes');
// compare first 100 bytes
- self::assertEquals(str_repeat('A', 100), fread($result, 100));
+ self::assertEquals(str_repeat('A', 100), fread($result, 100), 'Compare first 100 bytes');
- // compare 100 bytes
+ // compare last 100 bytes
fseek($result, $size - 100);
- self::assertEquals(str_repeat('A', 100), fread($result, 100));
+ self::assertEquals(str_repeat('A', 100), fread($result, 100), 'Compare last 100 bytes');
// end of file reached
fseek($result, $size);
- self::assertTrue(feof($result));
+ self::assertTrue(feof($result), 'End of file reached');
$this->assertNoUpload('testfilesizes');
}
diff --git a/tests/lib/Files/ObjectStore/SwiftTest.php b/tests/lib/Files/ObjectStore/SwiftTest.php
index 1ea55a84628..bebfba0c8a4 100644
--- a/tests/lib/Files/ObjectStore/SwiftTest.php
+++ b/tests/lib/Files/ObjectStore/SwiftTest.php
@@ -38,4 +38,8 @@ class SwiftTest extends ObjectStoreTest {
return new Swift($config['arguments']);
}
+
+ public function testFseekSize() {
+ $this->markTestSkipped('Swift does not support seeking at the moment');
+ }
}
diff --git a/tests/lib/Files/Search/QueryOptimizer/CombinedTests.php b/tests/lib/Files/Search/QueryOptimizer/CombinedTests.php
new file mode 100644
index 00000000000..c5abd5603da
--- /dev/null
+++ b/tests/lib/Files/Search/QueryOptimizer/CombinedTests.php
@@ -0,0 +1,191 @@
+<?php
+
+namespace Test\Files\Search\QueryOptimizer;
+
+use OC\Files\Search\QueryOptimizer\QueryOptimizer;
+use OC\Files\Search\SearchBinaryOperator;
+use OC\Files\Search\SearchComparison;
+use OCP\Files\Search\ISearchBinaryOperator;
+use OCP\Files\Search\ISearchComparison;
+use Test\TestCase;
+
+class CombinedTests extends TestCase {
+ private QueryOptimizer $optimizer;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->optimizer = new QueryOptimizer();
+ }
+
+ public function testBasicOrOfAnds() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ ])
+ ]
+ );
+ $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 1 and path eq "bar") or (storage eq 1 and path eq "asd"))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+
+ $this->assertEquals('(storage eq 1 and path in ["foo","bar","asd"])', $operator->__toString());
+ }
+
+ public function testComplexSearchPattern1() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 2),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "201"),
+ new SearchComparison(ISearchComparison::COMPARE_LIKE, "path", "201/%"),
+ ]),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 3),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "301"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 4),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "401"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 3),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "302"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 4),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "402"),
+ ]),
+ ]
+ );
+ $this->assertEquals('((storage eq 1) or (storage eq 2 and (path eq "201" or path like "201\/%")) or (storage eq 3 and path eq "301") or (storage eq 4 and path eq "401") or (storage eq 3 and path eq "302") or (storage eq 4 and path eq "402"))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+
+ $this->assertEquals('(storage eq 1 or (storage eq 2 and (path eq "201" or path like "201\/%")) or (storage eq 3 and path in ["301","302"]) or (storage eq 4 and path in ["401","402"]))', $operator->__toString());
+ }
+
+ public function testComplexSearchPattern2() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 2),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "201"),
+ new SearchComparison(ISearchComparison::COMPARE_LIKE, "path", "201/%"),
+ ]),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 3),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "301"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 4),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "401"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 3),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "302"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 4),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "402"),
+ ]),
+ ]
+ );
+ $this->assertEquals('(storage eq 1 or (storage eq 2 and (path eq "201" or path like "201\/%")) or (storage eq 3 and path eq "301") or (storage eq 4 and path eq "401") or (storage eq 3 and path eq "302") or (storage eq 4 and path eq "402"))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+
+ $this->assertEquals('(storage eq 1 or (storage eq 2 and (path eq "201" or path like "201\/%")) or (storage eq 3 and path in ["301","302"]) or (storage eq 4 and path in ["401","402"]))', $operator->__toString());
+ }
+
+ public function testApplySearchConstraints1() {
+ $operator = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "mimetype", "image/png"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "mimetype", "image/jpeg"),
+ ]),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "files"),
+ new SearchComparison(ISearchComparison::COMPARE_LIKE, "path", "files/%"),
+ ]),
+ ]),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 2),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 3),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "files/301"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 3),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "files/302"),
+ ]),
+ ]),
+ ]);
+ $this->assertEquals('(((mimetype eq "image\/png" or mimetype eq "image\/jpeg")) and ((storage eq 1 and (path eq "files" or path like "files\/%")) or storage eq 2 or (storage eq 3 and path eq "files\/301") or (storage eq 3 and path eq "files\/302")))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+
+ $this->assertEquals('(mimetype in ["image\/png","image\/jpeg"] and ((storage eq 1 and (path eq "files" or path like "files\/%")) or storage eq 2 or (storage eq 3 and path in ["files\/301","files\/302"])))', $operator->__toString());
+ }
+
+ public function testApplySearchConstraints2() {
+ $operator = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "mimetype", "image/png"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "mimetype", "image/jpeg"),
+ ]),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "files"),
+ new SearchComparison(ISearchComparison::COMPARE_LIKE, "path", "files/%"),
+ ]),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 2),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 3),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "files/301"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 3),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "files/302"),
+ ]),
+ ]),
+ ]);
+ $this->assertEquals('(((mimetype eq "image\/png" or mimetype eq "image\/jpeg")) and ((storage eq 1 and (path eq "files" or path like "files\/%")) or (storage eq 2) or (storage eq 3 and path eq "files\/301") or (storage eq 3 and path eq "files\/302")))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+
+ $this->assertEquals('(mimetype in ["image\/png","image\/jpeg"] and ((storage eq 1 and (path eq "files" or path like "files\/%")) or storage eq 2 or (storage eq 3 and path in ["files\/301","files\/302"])))', $operator->__toString());
+ }
+}
diff --git a/tests/lib/Files/Search/QueryOptimizer/FlattenNestedBoolTest.php b/tests/lib/Files/Search/QueryOptimizer/FlattenNestedBoolTest.php
new file mode 100644
index 00000000000..a21f2a19b90
--- /dev/null
+++ b/tests/lib/Files/Search/QueryOptimizer/FlattenNestedBoolTest.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Test\Files\Search\QueryOptimizer;
+
+use OC\Files\Search\QueryOptimizer\FlattenNestedBool;
+use OC\Files\Search\QueryOptimizer\FlattenSingleArgumentBinaryOperation;
+use OC\Files\Search\SearchBinaryOperator;
+use OC\Files\Search\SearchComparison;
+use OCP\Files\Search\ISearchBinaryOperator;
+use OCP\Files\Search\ISearchComparison;
+use Test\TestCase;
+
+class FlattenNestedBoolTest extends TestCase {
+ private $optimizer;
+ private $simplifier;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->optimizer = new FlattenNestedBool();
+ $this->simplifier = new FlattenSingleArgumentBinaryOperation();
+ }
+
+ public function testOrs() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ ])
+ ]
+ );
+ $this->assertEquals('(path eq "foo" or (path eq "bar" or path eq "asd"))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('(path eq "foo" or path eq "bar" or path eq "asd")', $operator->__toString());
+ }
+}
diff --git a/tests/lib/Files/Search/QueryOptimizer/MergeDistributiveOperationsTest.php b/tests/lib/Files/Search/QueryOptimizer/MergeDistributiveOperationsTest.php
new file mode 100644
index 00000000000..4c7ecc9d46f
--- /dev/null
+++ b/tests/lib/Files/Search/QueryOptimizer/MergeDistributiveOperationsTest.php
@@ -0,0 +1,160 @@
+<?php
+
+namespace Test\Files\Search\QueryOptimizer;
+
+use OC\Files\Search\QueryOptimizer\FlattenSingleArgumentBinaryOperation;
+use OC\Files\Search\QueryOptimizer\MergeDistributiveOperations;
+use OC\Files\Search\SearchBinaryOperator;
+use OC\Files\Search\SearchComparison;
+use OCP\Files\Search\ISearchBinaryOperator;
+use OCP\Files\Search\ISearchComparison;
+use Test\TestCase;
+
+class MergeDistributiveOperationsTest extends TestCase {
+ private $optimizer;
+ private $simplifier;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->optimizer = new MergeDistributiveOperations();
+ $this->simplifier = new FlattenSingleArgumentBinaryOperation();
+ }
+
+ public function testBasicOrOfAnds() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ ])
+ ]
+ );
+ $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 1 and path eq "bar") or (storage eq 1 and path eq "asd"))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('(storage eq 1 and (path eq "foo" or path eq "bar" or path eq "asd"))', $operator->__toString());
+ }
+
+ public function testDontTouchIfNotSame() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 2),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 3),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ ])
+ ]
+ );
+ $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 2 and path eq "bar") or (storage eq 3 and path eq "asd"))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 2 and path eq "bar") or (storage eq 3 and path eq "asd"))', $operator->__toString());
+ }
+
+ public function testMergePartial() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 2),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ ])
+ ]
+ );
+ $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 1 and path eq "bar") or (storage eq 2 and path eq "asd"))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('((storage eq 1 and (path eq "foo" or path eq "bar")) or (storage eq 2 and path eq "asd"))', $operator->__toString());
+ }
+
+ public function testOptimizeInside() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_AND,
+ [
+ new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ ])
+ ]
+ ),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "mimetype", "text")
+ ]
+ );
+ $this->assertEquals('(((storage eq 1 and path eq "foo") or (storage eq 1 and path eq "bar") or (storage eq 1 and path eq "asd")) and mimetype eq "text")', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('((storage eq 1 and (path eq "foo" or path eq "bar" or path eq "asd")) and mimetype eq "text")', $operator->__toString());
+ }
+
+ public function testMoveInnerOperations() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ ]),
+ new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "storage", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, "size", "100"),
+ ])
+ ]
+ );
+ $this->assertEquals('((storage eq 1 and path eq "foo") or (storage eq 1 and path eq "bar") or (storage eq 1 and path eq "asd" and size gt "100"))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('(storage eq 1 and (path eq "foo" or path eq "bar" or (path eq "asd" and size gt "100")))', $operator->__toString());
+ }
+}
diff --git a/tests/lib/Files/Search/QueryOptimizer/OrEqualsToInTest.php b/tests/lib/Files/Search/QueryOptimizer/OrEqualsToInTest.php
new file mode 100644
index 00000000000..3d3160079cd
--- /dev/null
+++ b/tests/lib/Files/Search/QueryOptimizer/OrEqualsToInTest.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Test\Files\Search\QueryOptimizer;
+
+use OC\Files\Search\QueryOptimizer\FlattenSingleArgumentBinaryOperation;
+use OC\Files\Search\QueryOptimizer\OrEqualsToIn;
+use OC\Files\Search\SearchBinaryOperator;
+use OC\Files\Search\SearchComparison;
+use OCP\Files\Search\ISearchBinaryOperator;
+use OCP\Files\Search\ISearchComparison;
+use Test\TestCase;
+
+class OrEqualsToInTest extends TestCase {
+ private $optimizer;
+ private $simplifier;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->optimizer = new OrEqualsToIn();
+ $this->simplifier = new FlattenSingleArgumentBinaryOperation();
+ }
+
+ public function testOrs() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ ]
+ );
+ $this->assertEquals('(path eq "foo" or path eq "bar" or path eq "asd")', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('path in ["foo","bar","asd"]', $operator->__toString());
+ }
+
+ public function testOrsMultipleFields() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "fileid", 1),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "fileid", 2),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "mimetype", "asd"),
+ ]
+ );
+ $this->assertEquals('(path eq "foo" or path eq "bar" or fileid eq 1 or fileid eq 2 or mimetype eq "asd")', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('(path in ["foo","bar"] or fileid in [1,2] or mimetype eq "asd")', $operator->__toString());
+ }
+
+ public function testPreserveHints() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ ]
+ );
+ foreach ($operator->getArguments() as $argument) {
+ $argument->setQueryHint(ISearchComparison::HINT_PATH_EQ_HASH, false);
+ }
+ $this->assertEquals('(path eq "foo" or path eq "bar" or path eq "asd")', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('path in ["foo","bar","asd"]', $operator->__toString());
+ $this->assertEquals(false, $operator->getQueryHint(ISearchComparison::HINT_PATH_EQ_HASH, true));
+ }
+
+ public function testOrSomeEq() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ new SearchComparison(ISearchComparison::COMPARE_LIKE, "path", "foo%"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ ]
+ );
+ $this->assertEquals('(path eq "foo" or path like "foo%" or path eq "bar")', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('(path in ["foo","bar"] or path like "foo%")', $operator->__toString());
+ }
+
+ public function testOrsInside() {
+ $operator = new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_AND,
+ [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "mimetype", "text"),
+ new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "foo"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "bar"),
+ new SearchComparison(ISearchComparison::COMPARE_EQUAL, "path", "asd"),
+ ]
+ )
+ ]
+ );
+ $this->assertEquals('(mimetype eq "text" and (path eq "foo" or path eq "bar" or path eq "asd"))', $operator->__toString());
+
+ $this->optimizer->processOperator($operator);
+ $this->simplifier->processOperator($operator);
+
+ $this->assertEquals('(mimetype eq "text" and path in ["foo","bar","asd"])', $operator->__toString());
+ }
+}
diff --git a/tests/lib/Files/Search/SearchIntegrationTest.php b/tests/lib/Files/Search/SearchIntegrationTest.php
new file mode 100644
index 00000000000..74018a597d9
--- /dev/null
+++ b/tests/lib/Files/Search/SearchIntegrationTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Test\Files\Search;
+
+use OC\Files\Search\SearchBinaryOperator;
+use OC\Files\Search\SearchComparison;
+use OC\Files\Search\SearchQuery;
+use OC\Files\Storage\Temporary;
+use OCP\Files\Search\ISearchBinaryOperator;
+use OCP\Files\Search\ISearchComparison;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class SearchIntegrationTest extends TestCase {
+ private $cache;
+ private $storage;
+
+ protected function setUp(): void {
+ parent::setUp();
+
+ $this->storage = new Temporary([]);
+ $this->cache = $this->storage->getCache();
+ $this->storage->getScanner()->scan('');
+ }
+
+
+ public function testThousandAndOneFilters() {
+ $id = $this->cache->put("file10", ['size' => 1, 'mtime' => 50, 'mimetype' => 'foo/folder']);
+
+ $comparisons = [];
+ for($i = 1; $i <= 1001; $i++) {
+ $comparisons[] = new SearchComparison(ISearchComparison::COMPARE_EQUAL, "name", "file$i");
+ }
+ $operator = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $comparisons);
+ $query = new SearchQuery($operator, 10, 0, []);
+
+ $results = $this->cache->searchQuery($query);
+
+ $this->assertCount(1, $results);
+ $this->assertEquals($id, $results[0]->getId());
+ }
+}
diff --git a/tests/lib/Files/Storage/CommonTest.php b/tests/lib/Files/Storage/CommonTest.php
index 0900765c510..3740289df95 100644
--- a/tests/lib/Files/Storage/CommonTest.php
+++ b/tests/lib/Files/Storage/CommonTest.php
@@ -24,6 +24,7 @@ namespace Test\Files\Storage;
use OC\Files\Storage\Wrapper\Jail;
use OC\Files\Storage\Wrapper\Wrapper;
+use OCP\Files\InvalidPathException;
use PHPUnit\Framework\MockObject\MockObject;
/**
@@ -39,22 +40,66 @@ class CommonTest extends Storage {
*/
private $tmpDir;
+ private array $invalidCharsBackup;
+
protected function setUp(): void {
parent::setUp();
$this->tmpDir = \OC::$server->getTempManager()->getTemporaryFolder();
$this->instance = new \OC\Files\Storage\CommonTest(['datadir' => $this->tmpDir]);
+ $this->invalidCharsBackup = \OC::$server->getConfig()->getSystemValue('forbidden_chars', []);
}
protected function tearDown(): void {
\OC_Helper::rmdirr($this->tmpDir);
+ \OC::$server->getConfig()->setSystemValue('forbidden_chars', $this->invalidCharsBackup);
parent::tearDown();
}
+ /**
+ * @dataProvider dataVerifyPath
+ */
+ public function testVerifyPath(string $filename, array $additionalChars, bool $throws) {
+ /** @var \OC\Files\Storage\CommonTest|MockObject $instance */
+ $instance = $this->getMockBuilder(\OC\Files\Storage\CommonTest::class)
+ ->onlyMethods(['copyFromStorage', 'rmdir', 'unlink'])
+ ->setConstructorArgs([['datadir' => $this->tmpDir]])
+ ->getMock();
+ $instance->method('copyFromStorage')
+ ->willThrowException(new \Exception('copy'));
+
+ \OC::$server->getConfig()->setSystemValue('forbidden_chars', $additionalChars);
+
+ if ($throws) {
+ $this->expectException(InvalidPathException::class);
+ } else {
+ $this->expectNotToPerformAssertions();
+ }
+ $instance->verifyPath('/', $filename);
+ }
+
+ public function dataVerifyPath(): array {
+ return [
+ // slash is always forbidden
+ 'invalid slash' => ['a/b.txt', [], true],
+ // backslash is also forbidden
+ 'invalid backslash' => ['a\\b.txt', [], true],
+ // by default colon is not forbidden
+ 'valid name' => ['a: b.txt', [], false],
+ // colon can be added to the list of forbidden character
+ 'invalid custom character' => ['a: b.txt', [':'], true],
+ // make sure to not split the list entries as they migh contain Unicode sequences
+ // in this example the "face in clouds" emoji contains the clouds emoji so only having clouds is ok
+ 'valid unicode sequence' => ['🌫️.txt', ['πŸ˜Άβ€πŸŒ«οΈ'], false],
+ // This is the reverse: clouds are forbidden -> so is also the face in the clouds emoji
+ 'valid unicode sequence' => ['πŸ˜Άβ€πŸŒ«οΈ.txt', ['🌫️'], true],
+ ];
+ }
+
public function testMoveFromStorageWrapped() {
/** @var \OC\Files\Storage\CommonTest|MockObject $instance */
$instance = $this->getMockBuilder(\OC\Files\Storage\CommonTest::class)
- ->setMethods(['copyFromStorage', 'rmdir', 'unlink'])
+ ->onlyMethods(['copyFromStorage', 'rmdir', 'unlink'])
->setConstructorArgs([['datadir' => $this->tmpDir]])
->getMock();
$instance->method('copyFromStorage')
@@ -72,7 +117,7 @@ class CommonTest extends Storage {
public function testMoveFromStorageJailed() {
/** @var \OC\Files\Storage\CommonTest|MockObject $instance */
$instance = $this->getMockBuilder(\OC\Files\Storage\CommonTest::class)
- ->setMethods(['copyFromStorage', 'rmdir', 'unlink'])
+ ->onlyMethods(['copyFromStorage', 'rmdir', 'unlink'])
->setConstructorArgs([['datadir' => $this->tmpDir]])
->getMock();
$instance->method('copyFromStorage')
@@ -95,7 +140,7 @@ class CommonTest extends Storage {
public function testMoveFromStorageNestedJail() {
/** @var \OC\Files\Storage\CommonTest|MockObject $instance */
$instance = $this->getMockBuilder(\OC\Files\Storage\CommonTest::class)
- ->setMethods(['copyFromStorage', 'rmdir', 'unlink'])
+ ->onlyMethods(['copyFromStorage', 'rmdir', 'unlink'])
->setConstructorArgs([['datadir' => $this->tmpDir]])
->getMock();
$instance->method('copyFromStorage')
diff --git a/tests/lib/Files/Storage/LocalTest.php b/tests/lib/Files/Storage/LocalTest.php
index e324d2b28db..1190a2b2da0 100644
--- a/tests/lib/Files/Storage/LocalTest.php
+++ b/tests/lib/Files/Storage/LocalTest.php
@@ -139,4 +139,15 @@ class LocalTest extends Storage {
umask($oldMask);
$this->assertTrue($this->instance->isUpdatable('test.txt'));
}
+
+ public function testUnavailableExternal() {
+ $this->expectException(\OCP\Files\StorageNotAvailableException::class);
+ $this->instance = new \OC\Files\Storage\Local(['datadir' => $this->tmpDir . '/unexist', 'isExternal' => true]);
+ }
+
+ public function testUnavailableNonExternal() {
+ $this->instance = new \OC\Files\Storage\Local(['datadir' => $this->tmpDir . '/unexist']);
+ // no exception thrown
+ $this->assertNotNull($this->instance);
+ }
}
diff --git a/tests/lib/Files/Storage/Storage.php b/tests/lib/Files/Storage/Storage.php
index a646fd5fd0b..63b3dfc5a98 100644
--- a/tests/lib/Files/Storage/Storage.php
+++ b/tests/lib/Files/Storage/Storage.php
@@ -94,12 +94,13 @@ abstract class Storage extends \Test\TestCase {
$dirEntry = $content[0];
unset($dirEntry['scan_permissions']);
unset($dirEntry['etag']);
+ $this->assertLessThanOrEqual(1, abs($dirEntry['mtime'] - $this->instance->filemtime($directory)));
+ unset($dirEntry['mtime']);
+ unset($dirEntry['storage_mtime']);
$this->assertEquals([
'name' => $directory,
'mimetype' => $this->instance->getMimeType($directory),
- 'mtime' => $this->instance->filemtime($directory),
'size' => -1,
- 'storage_mtime' => $this->instance->filemtime($directory),
'permissions' => $this->instance->getPermissions($directory),
], $dirEntry);
diff --git a/tests/lib/Files/Storage/Wrapper/EncryptionTest.php b/tests/lib/Files/Storage/Wrapper/EncryptionTest.php
index 11be0c60fbd..be5f191c6eb 100644
--- a/tests/lib/Files/Storage/Wrapper/EncryptionTest.php
+++ b/tests/lib/Files/Storage/Wrapper/EncryptionTest.php
@@ -422,9 +422,9 @@ class EncryptionTest extends Storage {
* @param boolean $renameKeysReturn
*/
public function testRename($source,
- $target,
- $encryptionEnabled,
- $renameKeysReturn) {
+ $target,
+ $encryptionEnabled,
+ $renameKeysReturn) {
if ($encryptionEnabled) {
$this->keyStore
->expects($this->once())
@@ -601,19 +601,19 @@ class EncryptionTest extends Storage {
$this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
]
)
- ->setMethods(['getCache','readFirstBlock', 'parseRawHeader'])
+ ->setMethods(['getCache', 'readFirstBlock'])
->getMock();
- $instance->expects($this->once())->method('getCache')->willReturn($cache);
+ $instance->method('getCache')->willReturn($cache);
- $instance->expects($this->once())->method(('parseRawHeader'))
+ $util->method('parseRawHeader')
->willReturn([Util::HEADER_ENCRYPTION_MODULE_KEY => 'OC_DEFAULT_MODULE']);
if ($strippedPathExists) {
- $instance->expects($this->once())->method('readFirstBlock')
+ $instance->method('readFirstBlock')
->with($strippedPath)->willReturn('');
} else {
- $instance->expects($this->once())->method('readFirstBlock')
+ $instance->method('readFirstBlock')
->with($path)->willReturn('');
}
@@ -679,11 +679,13 @@ class EncryptionTest extends Storage {
$this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
]
)
- ->setMethods(['readFirstBlock', 'parseRawHeader', 'getCache'])
+ ->setMethods(['readFirstBlock', 'getCache'])
->getMock();
- $instance->expects($this->any())->method(('parseRawHeader'))->willReturn($header);
- $instance->expects($this->once())->method('getCache')->willReturn($cache);
+ $instance->method('readFirstBlock')->willReturn('');
+
+ $util->method(('parseRawHeader'))->willReturn($header);
+ $instance->method('getCache')->willReturn($cache);
$result = $this->invokePrivate($instance, 'getHeader', ['test.txt']);
$this->assertSameSize($expected, $result);
@@ -702,44 +704,6 @@ class EncryptionTest extends Storage {
];
}
- /**
- * @dataProvider dataTestParseRawHeader
- */
- public function testParseRawHeader($rawHeader, $expected) {
- $instance = new \OC\Files\Storage\Wrapper\Encryption(
- [
- 'storage' => $this->sourceStorage,
- 'root' => 'foo',
- 'mountPoint' => '/',
- 'mount' => $this->mount
- ],
- $this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
-
- );
-
- $result = $this->invokePrivate($instance, 'parseRawHeader', [$rawHeader]);
- $this->assertSameSize($expected, $result);
- foreach ($result as $key => $value) {
- $this->assertArrayHasKey($key, $expected);
- $this->assertSame($expected[$key], $value);
- }
- }
-
- public function dataTestParseRawHeader() {
- return [
- [str_pad('HBEGIN:oc_encryption_module:0:HEND', $this->headerSize, '-', STR_PAD_RIGHT)
- , [Util::HEADER_ENCRYPTION_MODULE_KEY => '0']],
- [str_pad('HBEGIN:oc_encryption_module:0:custom_header:foo:HEND', $this->headerSize, '-', STR_PAD_RIGHT)
- , ['custom_header' => 'foo', Util::HEADER_ENCRYPTION_MODULE_KEY => '0']],
- [str_pad('HelloWorld', $this->headerSize, '-', STR_PAD_RIGHT), []],
- ['', []],
- [str_pad('HBEGIN:oc_encryption_module:0', $this->headerSize, '-', STR_PAD_RIGHT)
- , []],
- [str_pad('oc_encryption_module:0:HEND', $this->headerSize, '-', STR_PAD_RIGHT)
- , []],
- ];
- }
-
public function dataCopyBetweenStorage() {
return [
[true, true, true],
@@ -826,10 +790,10 @@ class EncryptionTest extends Storage {
->method('isEnabled')
->willReturn($encryptionEnabled);
// FIXME can not overwrite the return after definition
-// $this->mount->expects($this->at(0))
-// ->method('getOption')
-// ->with('encrypt', true)
-// ->willReturn($mountPointEncryptionEnabled);
+ // $this->mount->expects($this->at(0))
+ // ->method('getOption')
+ // ->with('encrypt', true)
+ // ->willReturn($mountPointEncryptionEnabled);
global $mockedMountPointEncryptionEnabled;
$mockedMountPointEncryptionEnabled = $mountPointEncryptionEnabled;
diff --git a/tests/lib/Files/Storage/Wrapper/KnownMtimeTest.php b/tests/lib/Files/Storage/Wrapper/KnownMtimeTest.php
new file mode 100644
index 00000000000..0a1691f9e70
--- /dev/null
+++ b/tests/lib/Files/Storage/Wrapper/KnownMtimeTest.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace lib\Files\Storage\Wrapper;
+
+use OC\Files\Storage\Temporary;
+use OC\Files\Storage\Wrapper\KnownMtime;
+use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Clock\ClockInterface;
+use Test\Files\Storage\Storage;
+
+/**
+ * @group DB
+ */
+class KnownMtimeTest extends Storage {
+ /** @var Temporary */
+ private $sourceStorage;
+
+ /** @var ClockInterface|MockObject */
+ private $clock;
+ private int $fakeTime = 0;
+
+ protected function setUp(): void {
+ parent::setUp();
+ $this->fakeTime = 0;
+ $this->sourceStorage = new Temporary([]);
+ $this->clock = $this->createMock(ClockInterface::class);
+ $this->clock->method('now')->willReturnCallback(function () {
+ if ($this->fakeTime) {
+ return new \DateTimeImmutable("@{$this->fakeTime}");
+ } else {
+ return new \DateTimeImmutable();
+ }
+ });
+ $this->instance = $this->getWrappedStorage();
+ }
+
+ protected function tearDown(): void {
+ $this->sourceStorage->cleanUp();
+ parent::tearDown();
+ }
+
+ protected function getWrappedStorage() {
+ return new KnownMtime([
+ 'storage' => $this->sourceStorage,
+ 'clock' => $this->clock,
+ ]);
+ }
+
+ public function testNewerKnownMtime() {
+ $future = time() + 1000;
+ $this->fakeTime = $future;
+
+ $this->instance->file_put_contents('foo.txt', 'bar');
+
+ // fuzzy match since the clock might have ticked
+ $this->assertLessThan(2, abs(time() - $this->sourceStorage->filemtime('foo.txt')));
+ $this->assertEquals($this->sourceStorage->filemtime('foo.txt'), $this->sourceStorage->stat('foo.txt')['mtime']);
+ $this->assertEquals($this->sourceStorage->filemtime('foo.txt'), $this->sourceStorage->getMetaData('foo.txt')['mtime']);
+
+ $this->assertEquals($future, $this->instance->filemtime('foo.txt'));
+ $this->assertEquals($future, $this->instance->stat('foo.txt')['mtime']);
+ $this->assertEquals($future, $this->instance->getMetaData('foo.txt')['mtime']);
+ }
+}
diff --git a/tests/lib/Files/Stream/EncryptionTest.php b/tests/lib/Files/Stream/EncryptionTest.php
index 8cdb379512a..3d45ff2fc3c 100644
--- a/tests/lib/Files/Stream/EncryptionTest.php
+++ b/tests/lib/Files/Stream/EncryptionTest.php
@@ -78,13 +78,13 @@ class EncryptionTest extends \Test\TestCase {
* @dataProvider dataProviderStreamOpen()
*/
public function testStreamOpen($isMasterKeyUsed,
- $mode,
- $fullPath,
- $fileExists,
- $expectedSharePath,
- $expectedSize,
- $expectedUnencryptedSize,
- $expectedReadOnly) {
+ $mode,
+ $fullPath,
+ $fileExists,
+ $expectedSharePath,
+ $expectedSize,
+ $expectedUnencryptedSize,
+ $expectedReadOnly) {
// build mocks
$encryptionModuleMock = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule')
->disableOriginalConstructor()->getMock();
diff --git a/tests/lib/Files/Type/LoaderTest.php b/tests/lib/Files/Type/LoaderTest.php
index fd3ec552dd2..ea016f9eded 100644
--- a/tests/lib/Files/Type/LoaderTest.php
+++ b/tests/lib/Files/Type/LoaderTest.php
@@ -23,15 +23,14 @@ namespace Test\Files\Type;
use OC\Files\Type\Loader;
use OCP\IDBConnection;
+use Test\TestCase;
-class LoaderTest extends \Test\TestCase {
- /** @var IDBConnection */
- protected $db;
- /** @var Loader */
- protected $loader;
+class LoaderTest extends TestCase {
+ protected IDBConnection $db;
+ protected Loader $loader;
protected function setUp(): void {
- $this->db = \OC::$server->getDatabaseConnection();
+ $this->db = \OC::$server->get(IDBConnection::class);
$this->loader = new Loader($this->db);
}
diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php
index a0323293605..818c69ed355 100644
--- a/tests/lib/Files/ViewTest.php
+++ b/tests/lib/Files/ViewTest.php
@@ -7,7 +7,6 @@
namespace Test\Files;
-use OCP\Cache\CappedMemoryCache;
use OC\Files\Cache\Watcher;
use OC\Files\Filesystem;
use OC\Files\Mount\MountPoint;
@@ -16,6 +15,8 @@ use OC\Files\Storage\Common;
use OC\Files\Storage\Storage;
use OC\Files\Storage\Temporary;
use OC\Files\View;
+use OC\Share20\ShareDisableChecker;
+use OCP\Cache\CappedMemoryCache;
use OCP\Constants;
use OCP\Files\Config\IMountProvider;
use OCP\Files\FileInfo;
@@ -297,7 +298,7 @@ class ViewTest extends \Test\TestCase {
*/
public function testRemoveSharePermissionWhenSharingDisabledForUser($excludeGroups, $excludeGroupsList, $expectedShareable) {
// Reset sharing disabled for users cache
- self::invokePrivate(\OC::$server->get(IShareManager::class), 'sharingDisabledForUsersCache', [new CappedMemoryCache()]);
+ self::invokePrivate(\OC::$server->get(ShareDisableChecker::class), 'sharingDisabledForUsersCache', [new CappedMemoryCache()]);
$config = \OC::$server->getConfig();
$oldExcludeGroupsFlag = $config->getAppValue('core', 'shareapi_exclude_groups', 'no');
@@ -322,7 +323,7 @@ class ViewTest extends \Test\TestCase {
$config->setAppValue('core', 'shareapi_exclude_groups_list', $oldExcludeGroupsList);
// Reset sharing disabled for users cache
- self::invokePrivate(\OC::$server->get(IShareManager::class), 'sharingDisabledForUsersCache', [new CappedMemoryCache()]);
+ self::invokePrivate(\OC::$server->get(ShareDisableChecker::class), 'sharingDisabledForUsersCache', [new CappedMemoryCache()]);
}
public function testCacheIncompleteFolder() {
@@ -1690,8 +1691,6 @@ class ViewTest extends \Test\TestCase {
->setSharedBy($this->user)
->setShareType(IShare::TYPE_USER)
->setPermissions(\OCP\Constants::PERMISSION_READ)
- ->setId(42)
- ->setProviderId('foo')
->setNode($shareDir);
$shareManager->createShare($share);