diff options
Diffstat (limited to 'tests/lib/Files/Cache')
-rw-r--r-- | tests/lib/Files/Cache/CacheTest.php | 277 | ||||
-rw-r--r-- | tests/lib/Files/Cache/FileAccessTest.php | 438 | ||||
-rw-r--r-- | tests/lib/Files/Cache/HomeCacheTest.php | 40 | ||||
-rw-r--r-- | tests/lib/Files/Cache/LocalRootScannerTest.php | 27 | ||||
-rw-r--r-- | tests/lib/Files/Cache/MoveFromCacheTraitTest.php | 20 | ||||
-rw-r--r-- | tests/lib/Files/Cache/PropagatorTest.php | 22 | ||||
-rw-r--r-- | tests/lib/Files/Cache/ScannerTest.php | 96 | ||||
-rw-r--r-- | tests/lib/Files/Cache/SearchBuilderTest.php | 44 | ||||
-rw-r--r-- | tests/lib/Files/Cache/UpdaterLegacyTest.php | 54 | ||||
-rw-r--r-- | tests/lib/Files/Cache/UpdaterTest.php | 68 | ||||
-rw-r--r-- | tests/lib/Files/Cache/WatcherTest.php | 40 | ||||
-rw-r--r-- | tests/lib/Files/Cache/Wrapper/CacheJailTest.php | 141 | ||||
-rw-r--r-- | tests/lib/Files/Cache/Wrapper/CachePermissionsMaskTest.php | 28 |
13 files changed, 949 insertions, 346 deletions
diff --git a/tests/lib/Files/Cache/CacheTest.php b/tests/lib/Files/Cache/CacheTest.php index 7f8e1af1577..383962b7224 100644 --- a/tests/lib/Files/Cache/CacheTest.php +++ b/tests/lib/Files/Cache/CacheTest.php @@ -1,22 +1,30 @@ <?php + /** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; -use Doctrine\DBAL\Platforms\MySqlPlatform; use OC\Files\Cache\Cache; +use OC\Files\Cache\CacheEntry; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; +use OC\Files\Storage\Temporary; +use OC\User\User; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Cache\ICacheEntry; use OCP\Files\Search\ISearchComparison; +use OCP\IDBConnection; +use OCP\ITagManager; use OCP\IUser; +use OCP\IUserManager; +use OCP\Server; -class LongId extends \OC\Files\Storage\Temporary { - public function getId() { +class LongId extends Temporary { + public function getId(): string { return 'long:' . str_repeat('foo', 50) . parent::getId(); } } @@ -30,28 +38,47 @@ class LongId extends \OC\Files\Storage\Temporary { */ class CacheTest extends \Test\TestCase { /** - * @var \OC\Files\Storage\Temporary $storage ; + * @var Temporary $storage ; */ protected $storage; /** - * @var \OC\Files\Storage\Temporary $storage2 ; + * @var Temporary $storage2 ; */ protected $storage2; /** - * @var \OC\Files\Cache\Cache $cache + * @var Cache $cache */ protected $cache; /** - * @var \OC\Files\Cache\Cache $cache2 + * @var Cache $cache2 */ protected $cache2; - public function testGetNumericId() { + protected function setUp(): void { + parent::setUp(); + + $this->storage = new Temporary([]); + $this->storage2 = new Temporary([]); + $this->cache = new Cache($this->storage); + $this->cache2 = new Cache($this->storage2); + $this->cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); + $this->cache2->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); + } + + protected function tearDown(): void { + if ($this->cache) { + $this->cache->clear(); + } + + parent::tearDown(); + } + + public function testGetNumericId(): void { $this->assertNotNull($this->cache->getNumericStorageId()); } - public function testSimple() { + public function testSimple(): void { $file1 = 'foo'; $file2 = 'foo/bar'; $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; @@ -97,33 +124,56 @@ class CacheTest extends \Test\TestCase { $this->assertEquals($cacheData1, $this->cache->get($id1)); } - public function testPartial() { + public function testCacheEntryGetters(): void { + $file1 = 'foo'; + $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/file']; + + $id1 = $this->cache->put($file1, $data1); + $entry = $this->cache->get($file1); + + $this->assertEquals($entry->getId(), $id1); + $this->assertEquals($entry->getStorageId(), $this->cache->getNumericStorageId()); + $this->assertEquals($entry->getPath(), 'foo'); + $this->assertEquals($entry->getName(), 'foo'); + $this->assertEquals($entry->getMimeType(), 'foo/file'); + $this->assertEquals($entry->getMimePart(), 'foo'); + $this->assertEquals($entry->getSize(), 100); + $this->assertEquals($entry->getMTime(), 50); + $this->assertEquals($entry->getStorageMTime(), 50); + $this->assertEquals($entry->getEtag(), null); + $this->assertEquals($entry->getPermissions(), 0); + $this->assertEquals($entry->isEncrypted(), false); + $this->assertEquals($entry->getMetadataEtag(), null); + $this->assertEquals($entry->getCreationTime(), null); + $this->assertEquals($entry->getUploadTime(), null); + $this->assertEquals($entry->getUnencryptedSize(), 100); + } + + public function testPartial(): void { $file1 = 'foo'; $this->cache->put($file1, ['size' => 10]); - $this->assertEquals(['size' => 10], $this->cache->get($file1)); + $this->assertEquals(new CacheEntry(['size' => 10]), $this->cache->get($file1)); $this->cache->put($file1, ['mtime' => 15]); - $this->assertEquals(['size' => 10, 'mtime' => 15], $this->cache->get($file1)); + $this->assertEquals(new CacheEntry(['size' => 10, 'mtime' => 15]), $this->cache->get($file1)); $this->cache->put($file1, ['size' => 12]); - $this->assertEquals(['size' => 12, 'mtime' => 15], $this->cache->get($file1)); + $this->assertEquals(new CacheEntry(['size' => 12, 'mtime' => 15]), $this->cache->get($file1)); } - /** - * @dataProvider folderDataProvider - */ - public function testFolder($folder) { + #[\PHPUnit\Framework\Attributes\DataProvider('folderDataProvider')] + public function testFolder($folder): void { if (strpos($folder, 'F09F9890')) { // 4 byte UTF doesn't work on mysql - $params = \OC::$server->get(\OC\DB\Connection::class)->getParams(); - if (\OC::$server->getDatabaseConnection()->getDatabasePlatform() instanceof MySqlPlatform && $params['charset'] !== 'utf8mb4') { + $params = Server::get(\OC\DB\Connection::class)->getParams(); + if (Server::get(IDBConnection::class)->getDatabaseProvider() === IDBConnection::PLATFORM_MYSQL && $params['charset'] !== 'utf8mb4') { $this->markTestSkipped('MySQL doesn\'t support 4 byte UTF-8'); } } $file2 = $folder . '/bar'; $file3 = $folder . '/foo'; - $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; $fileData = []; $fileData['bar'] = ['size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file']; $fileData['foo'] = ['size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file']; @@ -162,8 +212,8 @@ class CacheTest extends \Test\TestCase { $this->assertFalse($this->cache->inCache($folder . '/bar')); } - public function testRemoveRecursive() { - $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + public function testRemoveRecursive(): void { + $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; $fileData = ['size' => 1000, 'mtime' => 20, 'mimetype' => 'text/plain']; $folders = ['folder', 'folder/subfolder', 'folder/sub2', 'folder/sub2/sub3']; $files = ['folder/foo.txt', 'folder/bar.txt', 'folder/subfolder/asd.txt', 'folder/sub2/qwerty.txt', 'folder/sub2/sub3/foo.txt']; @@ -181,7 +231,7 @@ class CacheTest extends \Test\TestCase { } } - public function folderDataProvider() { + public static function folderDataProvider(): array { return [ ['folder'], // that was too easy, try something harder @@ -195,11 +245,11 @@ class CacheTest extends \Test\TestCase { ]; } - public function testEncryptedFolder() { + public function testEncryptedFolder(): void { $file1 = 'folder'; $file2 = 'folder/bar'; $file3 = 'folder/foo'; - $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; $fileData = []; $fileData['bar'] = ['size' => 1000, 'encrypted' => 1, 'mtime' => 20, 'mimetype' => 'foo/file']; $fileData['foo'] = ['size' => 20, 'encrypted' => 1, 'mtime' => 25, 'mimetype' => 'foo/file']; @@ -238,15 +288,14 @@ class CacheTest extends \Test\TestCase { $this->assertFalse($this->cache->inCache('folder/bar')); } - public function testRootFolderSizeForNonHomeStorage() { + public function testRootFolderSizeForNonHomeStorage(): void { $dir1 = 'knownsize'; $dir2 = 'unknownsize'; $fileData = []; - $fileData[''] = ['size' => -1, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory']; - $fileData[$dir1] = ['size' => 1000, 'mtime' => 20, 'mimetype' => 'httpd/unix-directory']; - $fileData[$dir2] = ['size' => -1, 'mtime' => 25, 'mimetype' => 'httpd/unix-directory']; + $fileData[''] = ['size' => -1, 'mtime' => 20, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; + $fileData[$dir1] = ['size' => 1000, 'mtime' => 20, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; + $fileData[$dir2] = ['size' => -1, 'mtime' => 25, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; - $this->cache->put('', $fileData['']); $this->cache->put($dir1, $fileData[$dir1]); $this->cache->put($dir2, $fileData[$dir2]); @@ -265,17 +314,17 @@ class CacheTest extends \Test\TestCase { $this->assertFalse($this->cache->inCache($dir2)); } - public function testStatus() { - $this->assertEquals(\OC\Files\Cache\Cache::NOT_FOUND, $this->cache->getStatus('foo')); + public function testStatus(): void { + $this->assertEquals(Cache::NOT_FOUND, $this->cache->getStatus('foo')); $this->cache->put('foo', ['size' => -1]); - $this->assertEquals(\OC\Files\Cache\Cache::PARTIAL, $this->cache->getStatus('foo')); + $this->assertEquals(Cache::PARTIAL, $this->cache->getStatus('foo')); $this->cache->put('foo', ['size' => -1, 'mtime' => 20, 'mimetype' => 'foo/file']); - $this->assertEquals(\OC\Files\Cache\Cache::SHALLOW, $this->cache->getStatus('foo')); + $this->assertEquals(Cache::SHALLOW, $this->cache->getStatus('foo')); $this->cache->put('foo', ['size' => 10]); - $this->assertEquals(\OC\Files\Cache\Cache::COMPLETE, $this->cache->getStatus('foo')); + $this->assertEquals(Cache::COMPLETE, $this->cache->getStatus('foo')); } - public function putWithAllKindOfQuotesData() { + public static function putWithAllKindOfQuotesData(): array { return [ ['`backtick`'], ['´forward´'], @@ -284,11 +333,11 @@ class CacheTest extends \Test\TestCase { } /** - * @dataProvider putWithAllKindOfQuotesData * @param $fileName */ - public function testPutWithAllKindOfQuotes($fileName) { - $this->assertEquals(\OC\Files\Cache\Cache::NOT_FOUND, $this->cache->get($fileName)); + #[\PHPUnit\Framework\Attributes\DataProvider('putWithAllKindOfQuotesData')] + public function testPutWithAllKindOfQuotes($fileName): void { + $this->assertEquals(Cache::NOT_FOUND, $this->cache->get($fileName)); $this->cache->put($fileName, ['size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file', 'etag' => $fileName]); $cacheEntry = $this->cache->get($fileName); @@ -296,7 +345,7 @@ class CacheTest extends \Test\TestCase { $this->assertEquals($fileName, $cacheEntry['path']); } - public function testSearch() { + public function testSearch(): void { $file1 = 'folder'; $file2 = 'folder/foobar'; $file3 = 'folder/foo'; @@ -313,7 +362,6 @@ class CacheTest extends \Test\TestCase { $this->assertEquals(1, count($this->cache->search('foo'))); $this->assertEquals(1, count($this->cache->search('%folder%'))); $this->assertEquals(1, count($this->cache->search('folder%'))); - $this->assertEquals(3, count($this->cache->search('%'))); // case insensitive search should match the same files $this->assertEquals(2, count($this->cache->search('%Foo%'))); @@ -325,11 +373,11 @@ class CacheTest extends \Test\TestCase { $this->assertEquals(2, count($this->cache->searchByMime('foo/file'))); } - public function testSearchQueryByTag() { + public function testSearchQueryByTag(): void { $userId = static::getUniqueID('user'); - \OC::$server->getUserManager()->createUser($userId, $userId); + Server::get(IUserManager::class)->createUser($userId, $userId); static::loginAsUser($userId); - $user = new \OC\User\User($userId, null, \OC::$server->getEventDispatcher()); + $user = new User($userId, null, Server::get(IEventDispatcher::class)); $file1 = 'folder'; $file2 = 'folder/foobar'; @@ -349,7 +397,7 @@ class CacheTest extends \Test\TestCase { $id4 = $this->cache->put($file4, $fileData['foo2']); $id5 = $this->cache->put($file5, $fileData['foo3']); - $tagManager = \OC::$server->getTagManager()->load('files', [], false, $userId); + $tagManager = Server::get(ITagManager::class)->load('files', [], false, $userId); $this->assertTrue($tagManager->tagAs($id1, 'tag1')); $this->assertTrue($tagManager->tagAs($id1, 'tag2')); $this->assertTrue($tagManager->tagAs($id2, 'tag2')); @@ -374,7 +422,7 @@ class CacheTest extends \Test\TestCase { $tagManager->delete('tag2'); static::logout(); - $user = \OC::$server->getUserManager()->get($userId); + $user = Server::get(IUserManager::class)->get($userId); if ($user !== null) { try { $user->delete(); @@ -383,7 +431,7 @@ class CacheTest extends \Test\TestCase { } } - public function testSearchByQuery() { + public function testSearchByQuery(): void { $file1 = 'folder'; $file2 = 'folder/foobar'; $file3 = 'folder/foo'; @@ -412,7 +460,7 @@ class CacheTest extends \Test\TestCase { new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN_EQUAL, 'size', 100), 10, 0, [], $user))); } - public function movePathProvider() { + public static function movePathProvider(): array { return [ ['folder/foo', 'folder/foobar', ['1', '2']], ['folder/foo', 'foo', ['1', '2']], @@ -420,12 +468,10 @@ class CacheTest extends \Test\TestCase { ]; } - /** - * @dataProvider movePathProvider - */ - public function testMove($sourceFolder, $targetFolder, $children) { + #[\PHPUnit\Framework\Attributes\DataProvider('movePathProvider')] + public function testMove($sourceFolder, $targetFolder, $children): void { $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/bar']; - $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; // create folders foreach ([$sourceFolder, $targetFolder] as $current) { @@ -458,7 +504,24 @@ class CacheTest extends \Test\TestCase { } } - public function testGetIncomplete() { + public function testMoveFromCache(): void { + $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/bar']; + $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; + + $this->cache2->put('folder', $folderData); + $this->cache2->put('folder/sub', $data); + + + $this->cache->moveFromCache($this->cache2, 'folder', 'targetfolder'); + + $this->assertFalse($this->cache2->inCache('folder')); + $this->assertFalse($this->cache2->inCache('folder/sub')); + + $this->assertTrue($this->cache->inCache('targetfolder')); + $this->assertTrue($this->cache->inCache('targetfolder/sub')); + } + + public function testGetIncomplete(): void { $file1 = 'folder1'; $file2 = 'folder2'; $file3 = 'folder3'; @@ -475,13 +538,13 @@ class CacheTest extends \Test\TestCase { $this->assertEquals($file3, $this->cache->getIncomplete()); } - public function testNonExisting() { + public function testNonExisting(): void { $this->assertFalse($this->cache->get('foo.txt')); $this->assertFalse($this->cache->get(-1)); $this->assertEquals([], $this->cache->getFolderContents('foo')); } - public function testGetById() { + public function testGetById(): void { $storageId = $this->storage->getId(); $data = ['size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file']; $id = $this->cache->put('foo', $data); @@ -489,10 +552,10 @@ class CacheTest extends \Test\TestCase { if (strlen($storageId) > 64) { $storageId = md5($storageId); } - $this->assertEquals([$storageId, 'foo'], \OC\Files\Cache\Cache::getById($id)); + $this->assertEquals([$storageId, 'foo'], Cache::getById($id)); } - public function testStorageMTime() { + public function testStorageMTime(): void { $data = ['size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file']; $this->cache->put('foo', $data); $cachedData = $this->cache->get('foo'); @@ -509,19 +572,20 @@ class CacheTest extends \Test\TestCase { $this->assertEquals(25, $cachedData['mtime']); } - public function testLongId() { + public function testLongId(): void { $storage = new LongId([]); $cache = $storage->getCache(); + $cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); $storageId = $storage->getId(); $data = ['size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file']; $id = $cache->put('foo', $data); - $this->assertEquals([md5($storageId), 'foo'], \OC\Files\Cache\Cache::getById($id)); + $this->assertEquals([md5($storageId), 'foo'], Cache::getById($id)); } /** * this test show the bug resulting if we have no normalizer installed */ - public function testWithoutNormalizer() { + public function testWithoutNormalizer(): void { // folder name "Schön" with U+00F6 (normalized) $folderWith00F6 = "\x53\x63\x68\xc3\xb6\x6e"; @@ -529,10 +593,10 @@ class CacheTest extends \Test\TestCase { $folderWith0308 = "\x53\x63\x68\x6f\xcc\x88\x6e"; /** - * @var \OC\Files\Cache\Cache | \PHPUnit\Framework\MockObject\MockObject $cacheMock + * @var Cache|\PHPUnit\Framework\MockObject\MockObject $cacheMock */ $cacheMock = $this->getMockBuilder(Cache::class) - ->setMethods(['normalize']) + ->onlyMethods(['normalize']) ->setConstructorArgs([$this->storage]) ->getMock(); @@ -540,7 +604,7 @@ class CacheTest extends \Test\TestCase { ->method('normalize') ->willReturnArgument(0); - $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + $data = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; // put root folder $this->assertFalse($cacheMock->get('folder')); @@ -567,7 +631,7 @@ class CacheTest extends \Test\TestCase { /** * this test shows that there is no bug if we use the normalizer */ - public function testWithNormalizer() { + public function testWithNormalizer(): void { if (!class_exists('Patchwork\PHP\Shim\Normalizer')) { $this->markTestSkipped('The 3rdparty Normalizer extension is not available.'); return; @@ -579,7 +643,7 @@ class CacheTest extends \Test\TestCase { // folder name "Schön" with U+0308 (un-normalized) $folderWith0308 = "\x53\x63\x68\x6f\xcc\x88\x6e"; - $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + $data = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; // put root folder $this->assertFalse($this->cache->get('folder')); @@ -603,7 +667,7 @@ class CacheTest extends \Test\TestCase { $this->assertEquals(1, count($this->cache->getFolderContents('folder'))); } - public function bogusPathNamesProvider() { + public static function bogusPathNamesProvider(): array { return [ ['/bogus.txt', 'bogus.txt'], ['//bogus.txt', 'bogus.txt'], @@ -614,16 +678,11 @@ class CacheTest extends \Test\TestCase { /** * Test bogus paths with leading or doubled slashes - * - * @dataProvider bogusPathNamesProvider */ - public function testBogusPaths($bogusPath, $fixedBogusPath) { - $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; - - // put root folder - $this->assertFalse($this->cache->get('')); - $parentId = $this->cache->put('', $data); - $this->assertGreaterThan(0, $parentId); + #[\PHPUnit\Framework\Attributes\DataProvider('bogusPathNamesProvider')] + public function testBogusPaths($bogusPath, $fixedBogusPath): void { + $data = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; + $parentId = $this->cache->getId(''); $this->assertGreaterThan(0, $this->cache->put($bogusPath, $data)); @@ -639,7 +698,7 @@ class CacheTest extends \Test\TestCase { $this->assertEquals($newData, $newDataFromBogus); } - public function testNoReuseOfFileId() { + public function testNoReuseOfFileId(): void { $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain']; $this->cache->put('somefile.txt', $data1); $info = $this->cache->get('somefile.txt'); @@ -652,7 +711,7 @@ class CacheTest extends \Test\TestCase { $this->assertNotEquals($fileId, $fileId2); } - public function escapingProvider() { + public static function escapingProvider(): array { return [ ['foo'], ['o%'], @@ -662,9 +721,9 @@ class CacheTest extends \Test\TestCase { /** * @param string $name - * @dataProvider escapingProvider */ - public function testEscaping($name) { + #[\PHPUnit\Framework\Attributes\DataProvider('escapingProvider')] + public function testEscaping($name): void { $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain']; $this->cache->put($name, $data); $this->assertTrue($this->cache->inCache($name)); @@ -677,7 +736,7 @@ class CacheTest extends \Test\TestCase { $this->assertTrue($this->cache->inCache($name . 'asd')); $this->cache->remove($name . 'asd'); $this->assertFalse($this->cache->inCache($name . 'asd')); - $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; $this->cache->put($name, $folderData); $this->cache->put('other', $folderData); $childs = ['asd', 'bar', 'foo', 'sub/folder']; @@ -700,31 +759,30 @@ class CacheTest extends \Test\TestCase { } } - public function testExtended() { - $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; - $this->cache->put("", $folderData); + public function testExtended(): void { + $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'creation_time' => 20]; - $id1 = $this->cache->put("foo1", $data); + $id1 = $this->cache->put('foo1', $data); $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'upload_time' => 30]; - $this->cache->put("foo2", $data); + $this->cache->put('foo2', $data); $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'metadata_etag' => 'foo']; - $this->cache->put("foo3", $data); + $this->cache->put('foo3', $data); $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain']; - $id4 = $this->cache->put("foo4", $data); + $id4 = $this->cache->put('foo4', $data); $entry = $this->cache->get($id1); $this->assertEquals(20, $entry->getCreationTime()); $this->assertEquals(0, $entry->getUploadTime()); $this->assertEquals(null, $entry->getMetadataEtag()); - $entries = $this->cache->getFolderContents(""); + $entries = $this->cache->getFolderContents(''); $this->assertCount(4, $entries); - $this->assertEquals("foo1", $entries[0]->getName()); - $this->assertEquals("foo2", $entries[1]->getName()); - $this->assertEquals("foo3", $entries[2]->getName()); - $this->assertEquals("foo4", $entries[3]->getName()); + $this->assertEquals('foo1', $entries[0]->getName()); + $this->assertEquals('foo2', $entries[1]->getName()); + $this->assertEquals('foo3', $entries[2]->getName()); + $this->assertEquals('foo4', $entries[3]->getName()); $this->assertEquals(20, $entries[0]->getCreationTime()); $this->assertEquals(0, $entries[0]->getUploadTime()); @@ -749,11 +807,11 @@ class CacheTest extends \Test\TestCase { $this->assertEquals(25, $entry->getUploadTime()); $this->assertEquals(null, $entry->getMetadataEtag()); - $this->cache->put("sub", $folderData); + $this->cache->put('sub', $folderData); - $this->cache->move("foo1", "sub/foo1"); + $this->cache->move('foo1', 'sub/foo1'); - $entries = $this->cache->getFolderContents("sub"); + $entries = $this->cache->getFolderContents('sub'); $this->assertCount(1, $entries); $this->assertEquals(20, $entries[0]->getCreationTime()); @@ -767,23 +825,6 @@ class CacheTest extends \Test\TestCase { $this->assertEquals(25, $entry->getUploadTime()); $this->assertEquals(null, $entry->getMetadataEtag()); - $this->cache->remove("sub"); - } - - protected function tearDown(): void { - if ($this->cache) { - $this->cache->clear(); - } - - parent::tearDown(); - } - - protected function setUp(): void { - parent::setUp(); - - $this->storage = new \OC\Files\Storage\Temporary([]); - $this->storage2 = new \OC\Files\Storage\Temporary([]); - $this->cache = new \OC\Files\Cache\Cache($this->storage); - $this->cache2 = new \OC\Files\Cache\Cache($this->storage2); + $this->cache->remove('sub'); } } diff --git a/tests/lib/Files/Cache/FileAccessTest.php b/tests/lib/Files/Cache/FileAccessTest.php new file mode 100644 index 00000000000..59fa2494ea8 --- /dev/null +++ b/tests/lib/Files/Cache/FileAccessTest.php @@ -0,0 +1,438 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace Test\Files\Cache; + +use OC\Files\Cache\CacheEntry; +use OC\Files\Cache\FileAccess; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use Psr\Log\LoggerInterface; +use Test\TestCase; + +/** + * @group DB + */ +class FileAccessTest extends TestCase { + private IDBConnection $dbConnection; + private FileAccess $fileAccess; + + protected function setUp(): void { + parent::setUp(); + + // Setup the actual database connection (assume the database is configured properly in PHPUnit setup) + $this->dbConnection = \OCP\Server::get(IDBConnection::class); + + // Ensure FileAccess is instantiated with the real connection + $this->fileAccess = new FileAccess( + $this->dbConnection, + \OCP\Server::get(\OC\SystemConfig::class), + \OCP\Server::get(LoggerInterface::class), + \OCP\Server::get(\OC\FilesMetadata\FilesMetadataManager::class), + \OCP\Server::get(\OCP\Files\IMimeTypeLoader::class) + ); + + // Clear and prepare `filecache` table for tests + $queryBuilder = $this->dbConnection->getQueryBuilder()->runAcrossAllShards(); + $queryBuilder->delete('filecache')->executeStatement(); + + // Clean up potential leftovers from other tests + $queryBuilder = $this->dbConnection->getQueryBuilder(); + $queryBuilder->delete('mounts')->executeStatement(); + + + $this->setUpTestDatabaseForGetDistinctMounts(); + $this->setUpTestDatabaseForGetByAncestorInStorage(); + } + + private function setUpTestDatabaseForGetDistinctMounts(): void { + $queryBuilder = $this->dbConnection->getQueryBuilder(); + + // Insert test data + $queryBuilder->insert('mounts') + ->values([ + 'storage_id' => $queryBuilder->createNamedParameter(1, IQueryBuilder::PARAM_INT), + 'root_id' => $queryBuilder->createNamedParameter(10, IQueryBuilder::PARAM_INT), + 'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass1'), + 'mount_point' => $queryBuilder->createNamedParameter('/files'), + 'user_id' => $queryBuilder->createNamedParameter('test'), + ]) + ->executeStatement(); + + $queryBuilder->insert('mounts') + ->values([ + 'storage_id' => $queryBuilder->createNamedParameter(3, IQueryBuilder::PARAM_INT), + 'root_id' => $queryBuilder->createNamedParameter(30, IQueryBuilder::PARAM_INT), + 'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass1'), + 'mount_point' => $queryBuilder->createNamedParameter('/documents'), + 'user_id' => $queryBuilder->createNamedParameter('test'), + ]) + ->executeStatement(); + + $queryBuilder->insert('mounts') + ->values([ + 'storage_id' => $queryBuilder->createNamedParameter(4, IQueryBuilder::PARAM_INT), + 'root_id' => $queryBuilder->createNamedParameter(31, IQueryBuilder::PARAM_INT), + 'mount_provider_class' => $queryBuilder->createNamedParameter('TestProviderClass2'), + 'mount_point' => $queryBuilder->createNamedParameter('/foobar'), + 'user_id' => $queryBuilder->createNamedParameter('test'), + ]) + ->executeStatement(); + } + + /** + * Test that getDistinctMounts returns all mounts without filters + */ + public function testGetDistinctMountsWithoutFilters(): void { + $result = iterator_to_array($this->fileAccess->getDistinctMounts([], false)); + + $this->assertCount(3, $result); + + $this->assertEquals([ + 'storage_id' => 1, + 'root_id' => 10, + 'overridden_root' => 10, + ], $result[0]); + + $this->assertEquals([ + 'storage_id' => 3, + 'root_id' => 30, + 'overridden_root' => 30, + ], $result[1]); + + $this->assertEquals([ + 'storage_id' => 4, + 'root_id' => 31, + 'overridden_root' => 31, + ], $result[2]); + } + + /** + * Test that getDistinctMounts applies filtering by mount providers + */ + public function testGetDistinctMountsWithMountProviderFilter(): void { + $result = iterator_to_array($this->fileAccess->getDistinctMounts(['TestProviderClass1'], false)); + + $this->assertCount(2, $result); + + $this->assertEquals([ + 'storage_id' => 1, + 'root_id' => 10, + 'overridden_root' => 10, + ], $result[0]); + + $this->assertEquals([ + 'storage_id' => 3, + 'root_id' => 30, + 'overridden_root' => 30, + ], $result[1]); + } + + /** + * Test that getDistinctMounts rewrites home directory paths + */ + public function testGetDistinctMountsWithRewriteHomeDirectories(): void { + // Add additional test data for a home directory mount + $queryBuilder = $this->dbConnection->getQueryBuilder(); + $queryBuilder->insert('mounts') + ->values([ + 'storage_id' => $queryBuilder->createNamedParameter(4, IQueryBuilder::PARAM_INT), + 'root_id' => $queryBuilder->createNamedParameter(40, IQueryBuilder::PARAM_INT), + 'mount_provider_class' => $queryBuilder->createNamedParameter(\OC\Files\Mount\LocalHomeMountProvider::class), + 'mount_point' => $queryBuilder->createNamedParameter('/home/user'), + 'user_id' => $queryBuilder->createNamedParameter('test'), + ]) + ->executeStatement(); + + // Add a mount that is mounted in the home directory + $queryBuilder = $this->dbConnection->getQueryBuilder(); + $queryBuilder->insert('mounts') + ->values([ + 'storage_id' => $queryBuilder->createNamedParameter(5, IQueryBuilder::PARAM_INT), + 'root_id' => $queryBuilder->createNamedParameter(41, IQueryBuilder::PARAM_INT), + 'mount_provider_class' => $queryBuilder->createNamedParameter('TestMountProvider3'), + 'mount_point' => $queryBuilder->createNamedParameter('/test/files/foobar'), + 'user_id' => $queryBuilder->createNamedParameter('test'), + ]) + ->executeStatement(); + + // Simulate adding a "files" directory to the filecache table + $queryBuilder = $this->dbConnection->getQueryBuilder()->runAcrossAllShards(); + $queryBuilder->delete('filecache')->executeStatement(); + $queryBuilder = $this->dbConnection->getQueryBuilder(); + $queryBuilder->insert('filecache') + ->values([ + 'fileid' => $queryBuilder->createNamedParameter(99, IQueryBuilder::PARAM_INT), + 'storage' => $queryBuilder->createNamedParameter(4, IQueryBuilder::PARAM_INT), + 'parent' => $queryBuilder->createNamedParameter(40), + 'name' => $queryBuilder->createNamedParameter('files'), + 'path' => $queryBuilder->createNamedParameter('files'), + 'path_hash' => $queryBuilder->createNamedParameter(md5('files')), + ]) + ->executeStatement(); + + $result = iterator_to_array($this->fileAccess->getDistinctMounts()); + + $this->assertCount(2, $result); + + $this->assertEquals([ + 'storage_id' => 4, + 'root_id' => 40, + 'overridden_root' => 99, + ], $result[0]); + + $this->assertEquals([ + 'storage_id' => 5, + 'root_id' => 41, + 'overridden_root' => 41, + ], $result[1]); + } + + private function setUpTestDatabaseForGetByAncestorInStorage(): void { + // prepare `filecache` table for tests + $queryBuilder = $this->dbConnection->getQueryBuilder(); + + $queryBuilder->insert('filecache') + ->values([ + 'fileid' => 1, + 'parent' => 0, + 'path' => $queryBuilder->createNamedParameter('files'), + 'path_hash' => $queryBuilder->createNamedParameter(md5('files')), + 'storage' => $queryBuilder->createNamedParameter(1), + 'name' => $queryBuilder->createNamedParameter('files'), + 'mimetype' => 1, + 'encrypted' => 0, + ]) + ->executeStatement(); + + $queryBuilder->insert('filecache') + ->values([ + 'fileid' => 2, + 'parent' => 1, + 'path' => $queryBuilder->createNamedParameter('files/documents'), + 'path_hash' => $queryBuilder->createNamedParameter(md5('files/documents')), + 'storage' => $queryBuilder->createNamedParameter(1), + 'name' => $queryBuilder->createNamedParameter('documents'), + 'mimetype' => 2, + 'encrypted' => 1, + ]) + ->executeStatement(); + + $queryBuilder->insert('filecache') + ->values([ + 'fileid' => 3, + 'parent' => 1, + 'path' => $queryBuilder->createNamedParameter('files/photos'), + 'path_hash' => $queryBuilder->createNamedParameter(md5('files/photos')), + 'storage' => $queryBuilder->createNamedParameter(1), + 'name' => $queryBuilder->createNamedParameter('photos'), + 'mimetype' => 3, + 'encrypted' => 1, + ]) + ->executeStatement(); + + $queryBuilder->insert('filecache') + ->values([ + 'fileid' => 4, + 'parent' => 3, + 'path' => $queryBuilder->createNamedParameter('files/photos/endtoendencrypted'), + 'path_hash' => $queryBuilder->createNamedParameter(md5('files/photos/endtoendencrypted')), + 'storage' => $queryBuilder->createNamedParameter(1), + 'name' => $queryBuilder->createNamedParameter('endtoendencrypted'), + 'mimetype' => 4, + 'encrypted' => 0, + ]) + ->executeStatement(); + + $queryBuilder->insert('filecache') + ->values([ + 'fileid' => 5, + 'parent' => 1, + 'path' => $queryBuilder->createNamedParameter('files/serversideencrypted'), + 'path_hash' => $queryBuilder->createNamedParameter(md5('files/serversideencrypted')), + 'storage' => $queryBuilder->createNamedParameter(1), + 'name' => $queryBuilder->createNamedParameter('serversideencrypted'), + 'mimetype' => 4, + 'encrypted' => 1, + ]) + ->executeStatement(); + + $queryBuilder->insert('filecache') + ->values([ + 'fileid' => 6, + 'parent' => 0, + 'path' => $queryBuilder->createNamedParameter('files/storage2'), + 'path_hash' => $queryBuilder->createNamedParameter(md5('files/storage2')), + 'storage' => $queryBuilder->createNamedParameter(2), + 'name' => $queryBuilder->createNamedParameter('storage2'), + 'mimetype' => 5, + 'encrypted' => 0, + ]) + ->executeStatement(); + + $queryBuilder->insert('filecache') + ->values([ + 'fileid' => 7, + 'parent' => 6, + 'path' => $queryBuilder->createNamedParameter('files/storage2/file'), + 'path_hash' => $queryBuilder->createNamedParameter(md5('files/storage2/file')), + 'storage' => $queryBuilder->createNamedParameter(2), + 'name' => $queryBuilder->createNamedParameter('file'), + 'mimetype' => 6, + 'encrypted' => 0, + ]) + ->executeStatement(); + } + + /** + * Test fetching files by ancestor in storage. + */ + public function testGetByAncestorInStorage(): void { + $generator = $this->fileAccess->getByAncestorInStorage( + 1, // storageId + 1, // rootId + 0, // lastFileId + 10, // maxResults + [], // mimeTypes + true, // include end-to-end encrypted files + true, // include server-side encrypted files + ); + + $result = iterator_to_array($generator); + + $this->assertCount(4, $result); + + $paths = array_map(fn (CacheEntry $entry) => $entry->getPath(), $result); + $this->assertEquals([ + 'files/documents', + 'files/photos', + 'files/photos/endtoendencrypted', + 'files/serversideencrypted', + ], $paths); + } + + /** + * Test filtering by mime types. + */ + public function testGetByAncestorInStorageWithMimeTypes(): void { + $generator = $this->fileAccess->getByAncestorInStorage( + 1, + 1, + 0, + 10, + [2], // Only include documents (mimetype=2) + true, + true, + ); + + $result = iterator_to_array($generator); + + $this->assertCount(1, $result); + $this->assertEquals('files/documents', $result[0]->getPath()); + } + + /** + * Test excluding end-to-end encrypted files. + */ + public function testGetByAncestorInStorageWithoutEndToEndEncrypted(): void { + $generator = $this->fileAccess->getByAncestorInStorage( + 1, + 1, + 0, + 10, + [], + false, // exclude end-to-end encrypted files + true, + ); + + $result = iterator_to_array($generator); + + $this->assertCount(3, $result); + $paths = array_map(fn (CacheEntry $entry) => $entry->getPath(), $result); + $this->assertEquals(['files/documents', 'files/photos', 'files/serversideencrypted'], $paths); + } + + /** + * Test excluding server-side encrypted files. + */ + public function testGetByAncestorInStorageWithoutServerSideEncrypted(): void { + $generator = $this->fileAccess->getByAncestorInStorage( + 1, + 1, + 0, + 10, + [], + true, + false, // exclude server-side encrypted files + ); + + $result = iterator_to_array($generator); + + $this->assertCount(1, $result); + $this->assertEquals('files/photos/endtoendencrypted', $result[0]->getPath()); + } + + /** + * Test max result limits. + */ + public function testGetByAncestorInStorageWithMaxResults(): void { + $generator = $this->fileAccess->getByAncestorInStorage( + 1, + 1, + 0, + 1, // Limit to 1 result + [], + true, + true, + ); + + $result = iterator_to_array($generator); + + $this->assertCount(1, $result); + $this->assertEquals('files/documents', $result[0]->getPath()); + } + + /** + * Test rootId filter + */ + public function testGetByAncestorInStorageWithRootIdFilter(): void { + $generator = $this->fileAccess->getByAncestorInStorage( + 1, + 3, // Filter by rootId + 0, + 10, + [], + true, + true, + ); + + $result = iterator_to_array($generator); + + $this->assertCount(1, $result); + $this->assertEquals('files/photos/endtoendencrypted', $result[0]->getPath()); + } + + /** + * Test rootId filter + */ + public function testGetByAncestorInStorageWithStorageFilter(): void { + $generator = $this->fileAccess->getByAncestorInStorage( + 2, // Filter by storage + 6, // and by rootId + 0, + 10, + [], + true, + true, + ); + + $result = iterator_to_array($generator); + + $this->assertCount(1, $result); + $this->assertEquals('files/storage2/file', $result[0]->getPath()); + } +} diff --git a/tests/lib/Files/Cache/HomeCacheTest.php b/tests/lib/Files/Cache/HomeCacheTest.php index aacb91c675e..86fda615fd7 100644 --- a/tests/lib/Files/Cache/HomeCacheTest.php +++ b/tests/lib/Files/Cache/HomeCacheTest.php @@ -1,31 +1,27 @@ <?php + /** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; -class DummyUser extends \OC\User\User { - /** - * @var string $home - */ - private $home; - - /** - * @var string $uid - */ - private $uid; +use OC\Files\Storage\Home; +use OC\User\User; +use OCP\ITempManager; +use OCP\Server; +class DummyUser extends User { /** * @param string $uid * @param string $home */ - public function __construct($uid, $home) { - $this->home = $home; - $this->uid = $uid; + public function __construct( + private $uid, + private $home, + ) { } /** @@ -62,15 +58,15 @@ class HomeCacheTest extends \Test\TestCase { private $cache; /** - * @var \OC\User\User $user + * @var User $user */ private $user; protected function setUp(): void { parent::setUp(); - $this->user = new DummyUser('foo', \OC::$server->getTempManager()->getTemporaryFolder()); - $this->storage = new \OC\Files\Storage\Home(['user' => $this->user]); + $this->user = new DummyUser('foo', Server::get(ITempManager::class)->getTemporaryFolder()); + $this->storage = new Home(['user' => $this->user]); $this->cache = $this->storage->getCache(); } @@ -79,7 +75,7 @@ class HomeCacheTest extends \Test\TestCase { * that have an unknown size. This makes sure that quota calculation still * works as it's based on the "files" folder size. */ - public function testRootFolderSizeIgnoresUnknownUpdate() { + public function testRootFolderSizeIgnoresUnknownUpdate(): void { $dir1 = 'files/knownsize'; $dir2 = 'files/unknownsize'; $fileData = []; @@ -111,7 +107,7 @@ class HomeCacheTest extends \Test\TestCase { $this->assertFalse($this->cache->inCache($dir2)); } - public function testRootFolderSizeIsFilesSize() { + public function testRootFolderSizeIsFilesSize(): void { $dir1 = 'files'; $afile = 'test.txt'; $fileData = []; diff --git a/tests/lib/Files/Cache/LocalRootScannerTest.php b/tests/lib/Files/Cache/LocalRootScannerTest.php index 0a85f000dbc..727da2ed698 100644 --- a/tests/lib/Files/Cache/LocalRootScannerTest.php +++ b/tests/lib/Files/Cache/LocalRootScannerTest.php @@ -2,28 +2,15 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2020 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; use OC\Files\Storage\LocalRootStorage; +use OCP\ITempManager; +use OCP\Server; use Test\TestCase; /** @@ -36,11 +23,11 @@ class LocalRootScannerTest extends TestCase { protected function setUp(): void { parent::setUp(); - $folder = \OC::$server->getTempManager()->getTemporaryFolder(); + $folder = Server::get(ITempManager::class)->getTemporaryFolder(); $this->storage = new LocalRootStorage(['datadir' => $folder]); } - public function testDontScanUsers() { + public function testDontScanUsers(): void { $this->storage->mkdir('foo'); $this->storage->mkdir('foo/bar'); @@ -48,7 +35,7 @@ class LocalRootScannerTest extends TestCase { $this->assertFalse($this->storage->getCache()->inCache('foo')); } - public function testDoScanAppData() { + public function testDoScanAppData(): void { $this->storage->mkdir('appdata_foo'); $this->storage->mkdir('appdata_foo/bar'); diff --git a/tests/lib/Files/Cache/MoveFromCacheTraitTest.php b/tests/lib/Files/Cache/MoveFromCacheTraitTest.php index 6e1430d146b..d580cdca4b9 100644 --- a/tests/lib/Files/Cache/MoveFromCacheTraitTest.php +++ b/tests/lib/Files/Cache/MoveFromCacheTraitTest.php @@ -1,16 +1,19 @@ <?php + /** - * Copyright (c) 2016 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; +use OC\Files\Cache\Cache; use OC\Files\Cache\MoveFromCacheTrait; +use OC\Files\Storage\Temporary; +use OCP\Files\Cache\ICacheEntry; -class FallBackCrossCacheMoveCache extends \OC\Files\Cache\Cache { +class FallBackCrossCacheMoveCache extends Cache { use MoveFromCacheTrait; } @@ -23,9 +26,12 @@ class MoveFromCacheTraitTest extends CacheTest { protected function setUp(): void { parent::setUp(); - $this->storage = new \OC\Files\Storage\Temporary([]); - $this->storage2 = new \OC\Files\Storage\Temporary([]); + $this->storage = new Temporary([]); + $this->storage2 = new Temporary([]); $this->cache = new FallBackCrossCacheMoveCache($this->storage); $this->cache2 = new FallBackCrossCacheMoveCache($this->storage2); + + $this->cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); + $this->cache2->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); } } diff --git a/tests/lib/Files/Cache/PropagatorTest.php b/tests/lib/Files/Cache/PropagatorTest.php index c1822c90282..2ab213e9567 100644 --- a/tests/lib/Files/Cache/PropagatorTest.php +++ b/tests/lib/Files/Cache/PropagatorTest.php @@ -1,9 +1,9 @@ <?php + /** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; @@ -17,7 +17,7 @@ use Test\TestCase; * @group DB */ class PropagatorTest extends TestCase { - /** @var IStorage */ + /** @var IStorage */ private $storage; protected function setUp(): void { @@ -39,7 +39,7 @@ class PropagatorTest extends TestCase { return array_combine($paths, $values); } - public function testEtagPropagation() { + public function testEtagPropagation(): void { $paths = ['', 'foo', 'foo/bar']; $oldInfos = $this->getFileInfos($paths); $this->storage->getPropagator()->propagateChange('foo/bar/file.txt', time()); @@ -50,7 +50,7 @@ class PropagatorTest extends TestCase { } } - public function testTimePropagation() { + public function testTimePropagation(): void { $paths = ['', 'foo', 'foo/bar']; $oldTime = time() - 200; $targetTime = time() - 100; @@ -70,7 +70,7 @@ class PropagatorTest extends TestCase { $this->assertEquals($now, $newInfos['']->getMTime()); } - public function testSizePropagation() { + public function testSizePropagation(): void { $paths = ['', 'foo', 'foo/bar']; $oldInfos = $this->getFileInfos($paths); $this->storage->getPropagator()->propagateChange('foo/bar/file.txt', time(), 10); @@ -81,7 +81,7 @@ class PropagatorTest extends TestCase { } } - public function testSizePropagationNoNegative() { + public function testSizePropagationNoNegative(): void { $paths = ['', 'foo', 'foo/bar']; $oldInfos = $this->getFileInfos($paths); $this->storage->getPropagator()->propagateChange('foo/bar/file.txt', time(), -100); @@ -92,7 +92,7 @@ class PropagatorTest extends TestCase { } } - public function testBatchedPropagation() { + public function testBatchedPropagation(): void { $this->storage->mkdir('foo/baz'); $this->storage->mkdir('asd'); $this->storage->file_put_contents('asd/file.txt', 'bar'); @@ -123,7 +123,7 @@ class PropagatorTest extends TestCase { foreach ($oldInfos as $i => $oldInfo) { if ($oldInfo->getPath() !== 'foo/baz') { - $this->assertNotEquals($oldInfo->getEtag(), $newInfos[$i]->getEtag()); + $this->assertNotEquals($oldInfo->getEtag(), $newInfos[$i]->getEtag(), "etag for {$oldInfo->getPath()} not updated"); } } diff --git a/tests/lib/Files/Cache/ScannerTest.php b/tests/lib/Files/Cache/ScannerTest.php index e4c052f6025..123c13893f7 100644 --- a/tests/lib/Files/Cache/ScannerTest.php +++ b/tests/lib/Files/Cache/ScannerTest.php @@ -1,9 +1,9 @@ <?php + /** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; @@ -15,6 +15,8 @@ use OC\Files\Cache\Scanner; use OC\Files\Storage\Storage; use OC\Files\Storage\Temporary; use OCP\Files\Cache\IScanner; +use OCP\IDBConnection; +use OCP\Server; use Test\TestCase; /** @@ -43,7 +45,7 @@ class ScannerTest extends TestCase { parent::tearDown(); } - public function testFile() { + public function testFile(): void { $data = "dummy file data\n"; $this->storage->file_put_contents('foo.txt', $data); $this->scanner->scanFile('foo.txt'); @@ -64,11 +66,11 @@ class ScannerTest extends TestCase { $this->assertEquals($cachedData['mimetype'], 'image/png'); } - public function testFile4Byte() { + public function testFile4Byte(): void { $data = "dummy file data\n"; $this->storage->file_put_contents('foo🙈.txt', $data); - if (OC::$server->getDatabaseConnection()->supports4ByteText()) { + if (Server::get(IDBConnection::class)->supports4ByteText()) { $this->assertNotNull($this->scanner->scanFile('foo🙈.txt')); $this->assertTrue($this->cache->inCache('foo🙈.txt'), true); @@ -82,7 +84,7 @@ class ScannerTest extends TestCase { } } - public function testFileInvalidChars() { + public function testFileInvalidChars(): void { $data = "dummy file data\n"; $this->storage->file_put_contents("foo\nbar.txt", $data); @@ -99,7 +101,7 @@ class ScannerTest extends TestCase { $this->storage->file_put_contents('folder/bar.txt', $textData); } - public function testFolder() { + public function testFolder(): void { $this->fillTestFolders(); $this->scanner->scan(''); @@ -121,7 +123,7 @@ class ScannerTest extends TestCase { $this->assertEquals($cachedDataFolder2['size'], $cachedDataText2['size']); } - public function testShallow() { + public function testShallow(): void { $this->fillTestFolders(); $this->scanner->scan('', IScanner::SCAN_SHALLOW); @@ -149,7 +151,7 @@ class ScannerTest extends TestCase { $this->assertNotEquals($cachedDataFolder['size'], -1); } - public function testBackgroundScan() { + public function testBackgroundScan(): void { $this->fillTestFolders(); $this->storage->mkdir('folder2'); $this->storage->file_put_contents('folder2/bar.txt', 'foobar'); @@ -171,7 +173,7 @@ class ScannerTest extends TestCase { $this->assertFalse($this->cache->getIncomplete()); } - public function testBackgroundScanOnlyRecurseIncomplete() { + public function testBackgroundScanOnlyRecurseIncomplete(): void { $this->fillTestFolders(); $this->storage->mkdir('folder2'); $this->storage->file_put_contents('folder2/bar.txt', 'foobar'); @@ -197,7 +199,7 @@ class ScannerTest extends TestCase { $this->assertFalse($this->cache->getIncomplete()); } - public function testBackgroundScanNestedIncompleteFolders() { + public function testBackgroundScanNestedIncompleteFolders(): void { $this->storage->mkdir('folder'); $this->scanner->backgroundScan(); @@ -235,7 +237,7 @@ class ScannerTest extends TestCase { $this->assertEquals(6, $this->cache->get('folder/subfolder2')['size']); } - public function testReuseExisting() { + public function testReuseExisting(): void { $this->fillTestFolders(); $this->scanner->scan(''); @@ -274,7 +276,7 @@ class ScannerTest extends TestCase { $this->assertEquals($oldData['size'], $newData['size']); } - public function testRemovedFile() { + public function testRemovedFile(): void { $this->fillTestFolders(); $this->scanner->scan(''); @@ -284,7 +286,7 @@ class ScannerTest extends TestCase { $this->assertFalse($this->cache->inCache('foo.txt')); } - public function testRemovedFolder() { + public function testRemovedFolder(): void { $this->fillTestFolders(); $this->scanner->scan(''); @@ -295,7 +297,7 @@ class ScannerTest extends TestCase { $this->assertFalse($this->cache->inCache('folder/bar.txt')); } - public function testScanRemovedFile() { + public function testScanRemovedFile(): void { $this->fillTestFolders(); $this->scanner->scan(''); @@ -305,7 +307,7 @@ class ScannerTest extends TestCase { $this->assertFalse($this->cache->inCache('folder/bar.txt')); } - public function testETagRecreation() { + public function testETagRecreation(): void { $this->fillTestFolders(); $this->scanner->scan('folder/bar.txt'); @@ -331,14 +333,14 @@ class ScannerTest extends TestCase { $this->assertNotEmpty($newData0['etag']); } - public function testRepairParent() { + public function testRepairParent(): void { $this->fillTestFolders(); $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $oldFolderId = $this->cache->getId('folder'); // delete the folder without removing the children - $query = OC::$server->getDatabaseConnection()->getQueryBuilder(); + $query = Server::get(IDBConnection::class)->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($oldFolderId))); $query->execute(); @@ -357,14 +359,14 @@ class ScannerTest extends TestCase { $this->assertEquals($newFolderId, $cachedData['parent']); } - public function testRepairParentShallow() { + public function testRepairParentShallow(): void { $this->fillTestFolders(); $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('folder/bar.txt')); $oldFolderId = $this->cache->getId('folder'); // delete the folder without removing the children - $query = OC::$server->getDatabaseConnection()->getQueryBuilder(); + $query = Server::get(IDBConnection::class)->getQueryBuilder(); $query->delete('filecache') ->where($query->expr()->eq('fileid', $query->createNamedParameter($oldFolderId))); $query->execute(); @@ -384,18 +386,18 @@ class ScannerTest extends TestCase { } /** - * @dataProvider dataTestIsPartialFile * * @param string $path * @param bool $expected */ - public function testIsPartialFile($path, $expected) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataTestIsPartialFile')] + public function testIsPartialFile($path, $expected): void { $this->assertSame($expected, $this->scanner->isPartialFile($path) ); } - public function dataTestIsPartialFile() { + public static function dataTestIsPartialFile(): array { return [ ['foo.txt.part', true], ['/sub/folder/foo.txt.part', true], @@ -404,4 +406,48 @@ class ScannerTest extends TestCase { ['/sub/folder/foo.txt', false], ]; } + + public function testNoETagUnscannedFolder(): void { + $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(): void { + $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..ee097044e3b 100644 --- a/tests/lib/Files/Cache/SearchBuilderTest.php +++ b/tests/lib/Files/Cache/SearchBuilderTest.php @@ -1,22 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; @@ -30,6 +16,9 @@ use OCP\Files\IMimeTypeLoader; use OCP\Files\Search\ISearchBinaryOperator; use OCP\Files\Search\ISearchComparison; use OCP\Files\Search\ISearchOperator; +use OCP\FilesMetadata\IFilesMetadataManager; +use OCP\IDBConnection; +use OCP\Server; use Test\TestCase; /** @@ -39,9 +28,12 @@ class SearchBuilderTest extends TestCase { /** @var IQueryBuilder */ private $builder; - /** @var IMimeTypeLoader|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IMimeTypeLoader&\PHPUnit\Framework\MockObject\MockObject */ private $mimetypeLoader; + /** @var IFilesMetadataManager&\PHPUnit\Framework\MockObject\MockObject */ + private $filesMetadataManager; + /** @var SearchBuilder */ private $searchBuilder; @@ -50,8 +42,9 @@ class SearchBuilderTest extends TestCase { protected function setUp(): void { parent::setUp(); - $this->builder = \OC::$server->getDatabaseConnection()->getQueryBuilder(); + $this->builder = Server::get(IDBConnection::class)->getQueryBuilder(); $this->mimetypeLoader = $this->createMock(IMimeTypeLoader::class); + $this->filesMetadataManager = $this->createMock(IFilesMetadataManager::class); $this->mimetypeLoader->expects($this->any()) ->method('getId') @@ -75,7 +68,7 @@ class SearchBuilderTest extends TestCase { [6, 'image'] ]); - $this->searchBuilder = new SearchBuilder($this->mimetypeLoader); + $this->searchBuilder = new SearchBuilder($this->mimetypeLoader, $this->filesMetadataManager); $this->numericStorageId = 10000; $this->builder->select(['fileid']) @@ -86,7 +79,7 @@ class SearchBuilderTest extends TestCase { protected function tearDown(): void { parent::tearDown(); - $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder(); + $builder = Server::get(IDBConnection::class)->getQueryBuilder(); $builder->delete('filecache') ->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->numericStorageId, IQueryBuilder::PARAM_INT))); @@ -119,7 +112,7 @@ class SearchBuilderTest extends TestCase { $data['mimetype'] = 1; } - $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder(); + $builder = Server::get(IDBConnection::class)->getQueryBuilder(); $values = []; foreach ($data as $key => $value) { @@ -144,7 +137,7 @@ class SearchBuilderTest extends TestCase { return $rows; } - public function comparisonProvider() { + public static function comparisonProvider(): array { return [ [new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125), [1]], [new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125), [0]], @@ -154,6 +147,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) @@ -184,12 +178,12 @@ class SearchBuilderTest extends TestCase { } /** - * @dataProvider comparisonProvider * * @param ISearchOperator $operator * @param array $fileIds */ - public function testComparison(ISearchOperator $operator, array $fileIds) { + #[\PHPUnit\Framework\Attributes\DataProvider('comparisonProvider')] + public function testComparison(ISearchOperator $operator, array $fileIds): void { $fileId = []; $fileId[] = $this->addCacheEntry([ 'path' => 'foobar', diff --git a/tests/lib/Files/Cache/UpdaterLegacyTest.php b/tests/lib/Files/Cache/UpdaterLegacyTest.php index be0390db15e..c71fac2d2dc 100644 --- a/tests/lib/Files/Cache/UpdaterLegacyTest.php +++ b/tests/lib/Files/Cache/UpdaterLegacyTest.php @@ -1,16 +1,22 @@ <?php + /** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; +use OC\Files\Cache\Cache; +use OC\Files\Cache\Scanner; use OC\Files\Filesystem as Filesystem; +use OC\Files\Storage\Storage; +use OC\Files\Storage\Temporary; use OC\Files\View; use OCP\Files\Mount\IMountManager; +use OCP\IUserManager; +use OCP\Server; /** * Class UpdaterLegacyTest @@ -21,17 +27,17 @@ use OCP\Files\Mount\IMountManager; */ class UpdaterLegacyTest extends \Test\TestCase { /** - * @var \OC\Files\Storage\Storage $storage + * @var Storage $storage */ private $storage; /** - * @var \OC\Files\Cache\Scanner $scanner + * @var Scanner $scanner */ private $scanner; /** - * @var \OC\Files\Cache\Cache $cache + * @var Cache $cache */ private $cache; @@ -40,7 +46,7 @@ class UpdaterLegacyTest extends \Test\TestCase { protected function setUp(): void { parent::setUp(); - $this->storage = new \OC\Files\Storage\Temporary([]); + $this->storage = new Temporary([]); $textData = "dummy file data\n"; $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo/logo.png'); $this->storage->mkdir('folder'); @@ -57,13 +63,13 @@ class UpdaterLegacyTest extends \Test\TestCase { self::$user = $this->getUniqueID(); } - \OC::$server->getUserManager()->createUser(self::$user, 'password'); + Server::get(IUserManager::class)->createUser(self::$user, 'NotAnEasyPassword123456+'); $this->loginAsUser(self::$user); Filesystem::init(self::$user, '/' . self::$user . '/files'); /** @var IMountManager $manager */ - $manager = \OC::$server->get(IMountManager::class); + $manager = Server::get(IMountManager::class); $manager->removeMount('/' . self::$user); Filesystem::mount($this->storage, [], '/' . self::$user . '/files'); @@ -77,7 +83,7 @@ class UpdaterLegacyTest extends \Test\TestCase { } $result = false; - $user = \OC::$server->getUserManager()->get(self::$user); + $user = Server::get(IUserManager::class)->get(self::$user); if ($user !== null) { $result = $user->delete(); } @@ -87,7 +93,7 @@ class UpdaterLegacyTest extends \Test\TestCase { parent::tearDown(); } - public function testWrite() { + public function testWrite(): void { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo/logo.png'); $this->cache->put('foo.txt', ['mtime' => 100, 'storage_mtime' => 150]); @@ -122,8 +128,8 @@ class UpdaterLegacyTest extends \Test\TestCase { $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $mtime); } - public function testWriteWithMountPoints() { - $storage2 = new \OC\Files\Storage\Temporary([]); + public function testWriteWithMountPoints(): void { + $storage2 = new Temporary([]); $storage2->getScanner()->scan(''); //initialize etags $cache2 = $storage2->getCache(); Filesystem::mount($storage2, [], '/' . self::$user . '/files/folder/substorage'); @@ -148,7 +154,7 @@ class UpdaterLegacyTest extends \Test\TestCase { $this->assertNotSame($oldEtag, $cachedData['etag']); } - public function testDelete() { + public function testDelete(): void { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo/logo.png'); $rootCachedData = $this->cache->get(''); @@ -183,8 +189,8 @@ class UpdaterLegacyTest extends \Test\TestCase { $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); } - public function testDeleteWithMountPoints() { - $storage2 = new \OC\Files\Storage\Temporary([]); + public function testDeleteWithMountPoints(): void { + $storage2 = new Temporary([]); $cache2 = $storage2->getCache(); Filesystem::mount($storage2, [], '/' . self::$user . '/files/folder/substorage'); Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); @@ -209,7 +215,7 @@ class UpdaterLegacyTest extends \Test\TestCase { $this->assertGreaterThanOrEqual($folderCachedData['mtime'], $cachedData['mtime']); } - public function testRename() { + public function testRename(): void { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo/logo.png'); $rootCachedData = $this->cache->get(''); @@ -231,7 +237,7 @@ class UpdaterLegacyTest extends \Test\TestCase { $this->assertNotSame($rootCachedData['etag'], $cachedData['etag']); } - public function testRenameExtension() { + public function testRenameExtension(): void { $fooCachedData = $this->cache->get('foo.txt'); $this->assertEquals('text/plain', $fooCachedData['mimetype']); Filesystem::rename('foo.txt', 'foo.abcd'); @@ -239,8 +245,8 @@ class UpdaterLegacyTest extends \Test\TestCase { $this->assertEquals('application/octet-stream', $fooCachedData['mimetype']); } - public function testRenameWithMountPoints() { - $storage2 = new \OC\Files\Storage\Temporary([]); + public function testRenameWithMountPoints(): void { + $storage2 = new Temporary([]); $cache2 = $storage2->getCache(); Filesystem::mount($storage2, [], '/' . self::$user . '/files/folder/substorage'); Filesystem::file_put_contents('folder/substorage/foo.txt', 'asd'); @@ -262,17 +268,17 @@ 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() { + public function testTouch(): void { $rootCachedData = $this->cache->get(''); $fooCachedData = $this->cache->get('foo.txt'); Filesystem::touch('foo.txt'); diff --git a/tests/lib/Files/Cache/UpdaterTest.php b/tests/lib/Files/Cache/UpdaterTest.php index 7e0f6866793..65c47cb9ae6 100644 --- a/tests/lib/Files/Cache/UpdaterTest.php +++ b/tests/lib/Files/Cache/UpdaterTest.php @@ -1,15 +1,21 @@ <?php + /** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; +use OC\Files\Cache\Cache; use OC\Files\Filesystem; +use OC\Files\ObjectStore\ObjectStoreStorage; +use OC\Files\ObjectStore\StorageObjectStore; +use OC\Files\Storage\Storage; use OC\Files\Storage\Temporary; +use OC\Files\View; +use OCP\Files\Storage\IStorage; /** * Class UpdaterTest @@ -20,17 +26,17 @@ use OC\Files\Storage\Temporary; */ class UpdaterTest extends \Test\TestCase { /** - * @var \OC\Files\Storage\Storage + * @var Storage */ protected $storage; /** - * @var \OC\Files\Cache\Cache + * @var Cache */ protected $cache; /** - * @var \OC\Files\View + * @var View */ protected $view; @@ -54,7 +60,7 @@ class UpdaterTest extends \Test\TestCase { parent::tearDown(); } - public function testNewFile() { + public function testNewFile(): void { $this->storage->file_put_contents('foo.txt', 'bar'); $this->assertFalse($this->cache->inCache('foo.txt')); @@ -66,7 +72,7 @@ class UpdaterTest extends \Test\TestCase { $this->assertEquals('text/plain', $cached['mimetype']); } - public function testUpdatedFile() { + public function testUpdatedFile(): void { $this->storage->file_put_contents('foo.txt', 'bar'); $this->updater->update('foo.txt'); @@ -85,7 +91,7 @@ class UpdaterTest extends \Test\TestCase { $this->assertEquals(6, $cached['size']); } - public function testParentSize() { + public function testParentSize(): void { $this->storage->getScanner()->scan(''); $parentCached = $this->cache->get(''); @@ -122,7 +128,7 @@ class UpdaterTest extends \Test\TestCase { $this->assertEquals(0, $parentCached['size']); } - public function testMove() { + public function testMove(): void { $this->storage->file_put_contents('foo.txt', 'qwerty'); $this->updater->update('foo.txt'); @@ -147,7 +153,7 @@ class UpdaterTest extends \Test\TestCase { $this->assertEquals($cached['fileid'], $cachedTarget['fileid']); } - public function testMoveNonExistingOverwrite() { + public function testMoveNonExistingOverwrite(): void { $this->storage->file_put_contents('bar.txt', 'qwerty'); $this->updater->update('bar.txt'); @@ -165,7 +171,7 @@ class UpdaterTest extends \Test\TestCase { $this->assertEquals($cached['fileid'], $cachedTarget['fileid']); } - public function testUpdateStorageMTime() { + public function testUpdateStorageMTime(): void { $this->storage->mkdir('sub'); $this->storage->mkdir('sub2'); $this->storage->file_put_contents('sub/foo.txt', 'qwerty'); @@ -206,7 +212,7 @@ class UpdaterTest extends \Test\TestCase { $this->assertNotEquals($testmtime, $cachedTargetParent['mtime'], 'target folder mtime changed, not from storage'); } - public function testNewFileDisabled() { + public function testNewFileDisabled(): void { $this->storage->file_put_contents('foo.txt', 'bar'); $this->assertFalse($this->cache->inCache('foo.txt')); @@ -216,7 +222,7 @@ class UpdaterTest extends \Test\TestCase { $this->assertFalse($this->cache->inCache('foo.txt')); } - public function testMoveCrossStorage() { + public function testMoveCrossStorage(): void { $storage2 = new Temporary([]); $cache2 = $storage2->getCache(); Filesystem::mount($storage2, [], '/bar'); @@ -247,7 +253,7 @@ class UpdaterTest extends \Test\TestCase { $this->assertEquals($cached['fileid'], $cachedTarget['fileid']); } - public function testMoveFolderCrossStorage() { + public function testMoveFolderCrossStorage(): void { $storage2 = new Temporary([]); $cache2 = $storage2->getCache(); Filesystem::mount($storage2, [], '/bar'); @@ -302,4 +308,34 @@ class UpdaterTest extends \Test\TestCase { $this->assertEquals($old['mimetype'], $new['mimetype']); } } + + public static function changeExtensionProvider(): array { + return [ + [new Temporary()], + [new ObjectStoreStorage(['objectstore' => new StorageObjectStore(new Temporary())])] + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('changeExtensionProvider')] + public function testChangeExtension(IStorage $storage) { + $updater = $storage->getUpdater(); + $cache = $storage->getCache(); + $storage->file_put_contents('foo', 'qwerty'); + $updater->update('foo'); + + $bareCached = $cache->get('foo'); + $this->assertEquals('application/octet-stream', $bareCached->getMimeType()); + + $storage->rename('foo', 'foo.txt'); + $updater->renameFromStorage($storage, 'foo', 'foo.txt'); + + $cached = $cache->get('foo.txt'); + $this->assertEquals('text/plain', $cached->getMimeType()); + + $storage->rename('foo.txt', 'foo.md'); + $updater->renameFromStorage($storage, 'foo.txt', 'foo.md'); + + $cachedTarget = $cache->get('foo.md'); + $this->assertEquals('text/markdown', $cachedTarget->getMimeType()); + } } diff --git a/tests/lib/Files/Cache/WatcherTest.php b/tests/lib/Files/Cache/WatcherTest.php index 509b9d6ba2a..6d0a8e0886b 100644 --- a/tests/lib/Files/Cache/WatcherTest.php +++ b/tests/lib/Files/Cache/WatcherTest.php @@ -1,13 +1,17 @@ <?php + /** - * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache; +use OC\Files\Cache\Watcher; +use OC\Files\Storage\Storage; +use OC\Files\Storage\Temporary; + /** * Class WatcherTest * @@ -17,7 +21,7 @@ namespace Test\Files\Cache; */ class WatcherTest extends \Test\TestCase { /** - * @var \OC\Files\Storage\Storage[] $storages + * @var Storage[] $storages */ private $storages = []; @@ -41,11 +45,11 @@ class WatcherTest extends \Test\TestCase { /** * @medium */ - public function testWatcher() { + public function testWatcher(): void { $storage = $this->getTestStorage(); $cache = $storage->getCache(); $updater = $storage->getWatcher(); - $updater->setPolicy(\OC\Files\Cache\Watcher::CHECK_ONCE); + $updater->setPolicy(Watcher::CHECK_ONCE); //set the mtime to the past so it can detect an mtime change $cache->put('', ['storage_mtime' => 10]); @@ -82,11 +86,11 @@ class WatcherTest extends \Test\TestCase { /** * @medium */ - public function testFileToFolder() { + public function testFileToFolder(): void { $storage = $this->getTestStorage(); $cache = $storage->getCache(); $updater = $storage->getWatcher(); - $updater->setPolicy(\OC\Files\Cache\Watcher::CHECK_ONCE); + $updater->setPolicy(Watcher::CHECK_ONCE); //set the mtime to the past so it can detect an mtime change $cache->put('', ['storage_mtime' => 10]); @@ -103,7 +107,7 @@ class WatcherTest extends \Test\TestCase { $storage = $this->getTestStorage(); $cache = $storage->getCache(); $updater = $storage->getWatcher(); - $updater->setPolicy(\OC\Files\Cache\Watcher::CHECK_ONCE); + $updater->setPolicy(Watcher::CHECK_ONCE); //set the mtime to the past so it can detect an mtime change $cache->put('foo.txt', ['storage_mtime' => 10]); @@ -117,7 +121,7 @@ class WatcherTest extends \Test\TestCase { $this->assertTrue($cache->inCache('foo.txt/bar.txt')); } - public function testPolicyNever() { + public function testPolicyNever(): void { $storage = $this->getTestStorage(); $cache = $storage->getCache(); $updater = $storage->getWatcher(); @@ -125,7 +129,7 @@ class WatcherTest extends \Test\TestCase { //set the mtime to the past so it can detect an mtime change $cache->put('foo.txt', ['storage_mtime' => 10]); - $updater->setPolicy(\OC\Files\Cache\Watcher::CHECK_NEVER); + $updater->setPolicy(Watcher::CHECK_NEVER); $storage->file_put_contents('foo.txt', 'q'); $this->assertFalse($updater->checkUpdate('foo.txt')); @@ -135,7 +139,7 @@ class WatcherTest extends \Test\TestCase { $this->assertFalse($updater->checkUpdate('foo.txt')); } - public function testPolicyOnce() { + public function testPolicyOnce(): void { $storage = $this->getTestStorage(); $cache = $storage->getCache(); $updater = $storage->getWatcher(); @@ -143,7 +147,7 @@ class WatcherTest extends \Test\TestCase { //set the mtime to the past so it can detect an mtime change $cache->put('foo.txt', ['storage_mtime' => 10]); - $updater->setPolicy(\OC\Files\Cache\Watcher::CHECK_ONCE); + $updater->setPolicy(Watcher::CHECK_ONCE); $storage->file_put_contents('foo.txt', 'q'); $this->assertTrue($updater->checkUpdate('foo.txt')); @@ -153,7 +157,7 @@ class WatcherTest extends \Test\TestCase { $this->assertFalse($updater->checkUpdate('foo.txt')); } - public function testPolicyAlways() { + public function testPolicyAlways(): void { $storage = $this->getTestStorage(); $cache = $storage->getCache(); $updater = $storage->getWatcher(); @@ -161,7 +165,7 @@ class WatcherTest extends \Test\TestCase { //set the mtime to the past so it can detect an mtime change $cache->put('foo.txt', ['storage_mtime' => 10]); - $updater->setPolicy(\OC\Files\Cache\Watcher::CHECK_ALWAYS); + $updater->setPolicy(Watcher::CHECK_ALWAYS); $storage->file_put_contents('foo.txt', 'q'); $this->assertTrue($updater->checkUpdate('foo.txt')); @@ -173,10 +177,10 @@ class WatcherTest extends \Test\TestCase { /** * @param bool $scan - * @return \OC\Files\Storage\Storage + * @return Storage */ private function getTestStorage($scan = true) { - $storage = new \OC\Files\Storage\Temporary([]); + $storage = new Temporary([]); $textData = "dummy file data\n"; $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo/logo.png'); $storage->mkdir('folder'); diff --git a/tests/lib/Files/Cache/Wrapper/CacheJailTest.php b/tests/lib/Files/Cache/Wrapper/CacheJailTest.php index 4c3dce74087..8ac3492fbd2 100644 --- a/tests/lib/Files/Cache/Wrapper/CacheJailTest.php +++ b/tests/lib/Files/Cache/Wrapper/CacheJailTest.php @@ -1,19 +1,23 @@ <?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. + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache\Wrapper; +use OC\Files\Cache\Cache; use OC\Files\Cache\Wrapper\CacheJail; +use OC\Files\Cache\Wrapper\CacheWrapper; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; +use OC\Files\Storage\Wrapper\Jail; use OC\User\User; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Cache\ICacheEntry; use OCP\Files\Search\ISearchComparison; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Test\Files\Cache\CacheTest; /** @@ -25,23 +29,25 @@ use Test\Files\Cache\CacheTest; */ class CacheJailTest extends CacheTest { /** - * @var \OC\Files\Cache\Cache $sourceCache + * @var Cache $sourceCache */ protected $sourceCache; protected function setUp(): void { parent::setUp(); - $this->storage->mkdir('foo'); + $this->storage->mkdir('jail'); $this->sourceCache = $this->cache; - $this->cache = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, 'foo'); + $this->cache = new CacheJail($this->sourceCache, 'jail'); + $this->cache->insert('', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); } - public function testSearchOutsideJail() { + public function testSearchOutsideJail(): void { $this->storage->getScanner()->scan(''); - $file1 = 'foo/foobar'; + $file1 = 'jail/foobar'; $file2 = 'folder/foobar'; $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; + $this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); $this->sourceCache->put($file1, $data1); $this->sourceCache->put($file2, $data1); @@ -52,20 +58,20 @@ class CacheJailTest extends CacheTest { $this->assertEquals('foobar', $result[0]['path']); $result = $this->cache->search('%foo%'); - $this->assertCount(2, $result); + $this->assertCount(1, $result); usort($result, function ($a, $b) { return $a['path'] <=> $b['path']; }); - $this->assertEquals('', $result[0]['path']); - $this->assertEquals('foobar', $result[1]['path']); + $this->assertEquals('foobar', $result[0]['path']); } - public function testSearchMimeOutsideJail() { + public function testSearchMimeOutsideJail(): void { $this->storage->getScanner()->scan(''); - $file1 = 'foo/foobar'; + $file1 = 'jail/foobar'; $file2 = 'folder/foobar'; $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; + $this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); $this->sourceCache->put($file1, $data1); $this->sourceCache->put($file2, $data1); @@ -76,35 +82,37 @@ class CacheJailTest extends CacheTest { $this->assertEquals('foobar', $result[0]['path']); } - public function testSearchQueryOutsideJail() { + public function testSearchQueryOutsideJail(): void { $this->storage->getScanner()->scan(''); - $file1 = 'foo/foobar'; + $file1 = 'jail/foobar'; $file2 = 'folder/foobar'; $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; + + $this->sourceCache->insert('folder', ['size' => 0, 'mtime' => 0, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]); $this->sourceCache->put($file1, $data1); $this->sourceCache->put($file2, $data1); - $user = new User('foo', null, $this->createMock(EventDispatcherInterface::class)); + $user = new User('foo', null, $this->createMock(IEventDispatcher::class)); $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), 10, 0, [], $user); $result = $this->cache->searchQuery($query); $this->assertCount(1, $result); $this->assertEquals('foobar', $result[0]['path']); - $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foo'), 10, 0, [], $user); + $query = new SearchQuery(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'jail'), 10, 0, [], $user); $result = $this->cache->searchQuery($query); $this->assertCount(1, $result); $this->assertEquals('', $result[0]['path']); } - public function testClearKeepEntriesOutsideJail() { - $file1 = 'foo/foobar'; - $file2 = 'foo/foobar/asd'; + public function testClearKeepEntriesOutsideJail(): void { + $file1 = 'jail/foobar'; + $file2 = 'jail/foobar/asd'; $file3 = 'folder/foobar'; - $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; - $this->sourceCache->put('foo', $data1); + $this->sourceCache->put('folder', $data1); $this->sourceCache->put($file1, $data1); $this->sourceCache->put($file2, $data1); $this->sourceCache->put($file3, $data1); @@ -115,27 +123,27 @@ class CacheJailTest extends CacheTest { $this->assertTrue($this->sourceCache->inCache('folder/foobar')); } - public function testGetById() { - $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; - $id = $this->sourceCache->put('foo/bar', $data1); + public function testGetById(): void { + $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; + $id = $this->sourceCache->put('jail/bar', $data1); // path from jailed foo of foo/bar is bar $path = $this->cache->getPathById($id); $this->assertEquals('bar', $path); // path from jailed '' of foo/bar is foo/bar - $this->cache = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, ''); + $this->cache = new CacheJail($this->sourceCache, ''); $path = $this->cache->getPathById($id); - $this->assertEquals('foo/bar', $path); + $this->assertEquals('jail/bar', $path); } - public function testGetIncomplete() { + public function testGetIncomplete(): void { //not supported $this->addToAssertionCount(1); } - public function testMoveFromJail() { - $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + public function testMoveFromJail(): void { + $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; $this->sourceCache->put('source', $folderData); $this->sourceCache->put('source/foo', $folderData); @@ -150,8 +158,8 @@ class CacheJailTest extends CacheTest { $this->assertTrue($this->sourceCache->inCache('target/foo/bar')); } - public function testMoveToJail() { - $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + public function testMoveToJail(): void { + $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; $this->sourceCache->put('source', $folderData); $this->sourceCache->put('source/foo', $folderData); @@ -166,8 +174,8 @@ class CacheJailTest extends CacheTest { $this->assertTrue($this->sourceCache->inCache('target/foo/bar')); } - public function testMoveBetweenJail() { - $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory']; + public function testMoveBetweenJail(): void { + $folderData = ['size' => 100, 'mtime' => 50, 'mimetype' => ICacheEntry::DIRECTORY_MIMETYPE]; $this->sourceCache->put('source', $folderData); $this->sourceCache->put('source/foo', $folderData); @@ -183,39 +191,78 @@ class CacheJailTest extends CacheTest { $this->assertTrue($this->sourceCache->inCache('target/foo/bar')); } - public function testSearchNested() { + public function testSearchNested(): void { $this->storage->getScanner()->scan(''); - $file1 = 'foo'; - $file2 = 'foo/bar'; - $file3 = 'foo/bar/asd'; + $file1 = 'jail'; + $file2 = 'jail/bar'; + $file3 = 'jail/bar/asd'; $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; $this->sourceCache->put($file1, $data1); $this->sourceCache->put($file2, $data1); $this->sourceCache->put($file3, $data1); - $nested = new \OC\Files\Cache\Wrapper\CacheJail($this->cache, 'bar'); + $nested = new CacheJail($this->cache, 'bar'); $result = $nested->search('%asd%'); $this->assertCount(1, $result); $this->assertEquals('asd', $result[0]['path']); } - public function testRootJail() { + public function testRootJail(): void { $this->storage->getScanner()->scan(''); - $file1 = 'foo'; - $file2 = 'foo/bar'; - $file3 = 'foo/bar/asd'; + $file1 = 'jail'; + $file2 = 'jail/bar'; + $file3 = 'jail/bar/asd'; $data1 = ['size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder']; $this->sourceCache->put($file1, $data1); $this->sourceCache->put($file2, $data1); $this->sourceCache->put($file3, $data1); - $nested = new \OC\Files\Cache\Wrapper\CacheJail($this->sourceCache, ''); + $nested = new CacheJail($this->sourceCache, ''); $result = $nested->search('%asd%'); $this->assertCount(1, $result); - $this->assertEquals('foo/bar/asd', $result[0]['path']); + $this->assertEquals('jail/bar/asd', $result[0]['path']); + } + + public function testWatcher(): void { + $storage = new Jail([ + 'storage' => $this->storage, + 'root' => 'jail' + ]); + $storage->getScanner()->scan(''); + $storage->file_put_contents('bar', 'asd'); + + $this->assertFalse($this->cache->inCache('bar')); + $storage->getWatcher()->update('bar', ['mimetype' => 'text/plain']); + $this->assertTrue($this->cache->inCache('bar')); + } + + public function testWatcherAfterInnerWatcher(): void { + $storage = new Jail([ + 'storage' => $this->storage, + 'root' => 'jail' + ]); + $storage->getScanner()->scan(''); + $storage->file_put_contents('bar', 'asd'); + + // let the underlying storage create it's watcher first + $this->storage->getWatcher(); + + $this->assertFalse($this->cache->inCache('bar')); + $storage->getWatcher()->update('bar', ['mimetype' => 'text/plain']); + $this->assertTrue($this->cache->inCache('bar')); + } + + public function testUnJailedRoot(): void { + $jail1 = new CacheJail($this->sourceCache, 'foo'); + $jail2 = new CacheJail($jail1, 'bar'); + $this->assertEquals('foo/bar', $jail2->getGetUnjailedRoot()); + + $middleWrapper = new CacheWrapper($jail1); + $jail3 = new CacheJail($middleWrapper, 'bar'); + $this->assertEquals('foo/bar', $jail3->getGetUnjailedRoot()); } } diff --git a/tests/lib/Files/Cache/Wrapper/CachePermissionsMaskTest.php b/tests/lib/Files/Cache/Wrapper/CachePermissionsMaskTest.php index 20c20974c07..4fbeafc9270 100644 --- a/tests/lib/Files/Cache/Wrapper/CachePermissionsMaskTest.php +++ b/tests/lib/Files/Cache/Wrapper/CachePermissionsMaskTest.php @@ -1,13 +1,15 @@ <?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. + * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\Cache\Wrapper; +use OC\Files\Cache\Cache; +use OC\Files\Cache\Wrapper\CachePermissionsMask; use OCP\Constants; use Test\Files\Cache\CacheTest; @@ -20,7 +22,7 @@ use Test\Files\Cache\CacheTest; */ class CachePermissionsMaskTest extends CacheTest { /** - * @var \OC\Files\Cache\Cache $sourceCache + * @var Cache $sourceCache */ protected $sourceCache; @@ -32,10 +34,10 @@ class CachePermissionsMaskTest extends CacheTest { } protected function getMaskedCached($mask) { - return new \OC\Files\Cache\Wrapper\CachePermissionsMask($this->sourceCache, $mask); + return new CachePermissionsMask($this->sourceCache, $mask); } - public function maskProvider() { + public static function maskProvider(): array { return [ [Constants::PERMISSION_ALL], [Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE], @@ -45,10 +47,10 @@ class CachePermissionsMaskTest extends CacheTest { } /** - * @dataProvider maskProvider * @param int $mask */ - public function testGetMasked($mask) { + #[\PHPUnit\Framework\Attributes\DataProvider('maskProvider')] + public function testGetMasked($mask): void { $cache = $this->getMaskedCached($mask); $data = ['size' => 100, 'mtime' => 50, 'mimetype' => 'text/plain', 'permissions' => Constants::PERMISSION_ALL]; $this->sourceCache->put('foo', $data); @@ -62,10 +64,10 @@ class CachePermissionsMaskTest extends CacheTest { } /** - * @dataProvider maskProvider * @param int $mask */ - public function testGetFolderContentMasked($mask) { + #[\PHPUnit\Framework\Attributes\DataProvider('maskProvider')] + public function testGetFolderContentMasked($mask): void { $this->storage->mkdir('foo'); $this->storage->file_put_contents('foo/bar', 'asd'); $this->storage->file_put_contents('foo/asd', 'bar'); @@ -81,10 +83,10 @@ class CachePermissionsMaskTest extends CacheTest { } /** - * @dataProvider maskProvider * @param int $mask */ - public function testSearchMasked($mask) { + #[\PHPUnit\Framework\Attributes\DataProvider('maskProvider')] + public function testSearchMasked($mask): void { $this->storage->mkdir('foo'); $this->storage->file_put_contents('foo/bar', 'asd'); $this->storage->file_put_contents('foo/foobar', 'bar'); |