diff options
Diffstat (limited to 'apps/dav/tests/unit/Files/FileSearchBackendTest.php')
-rw-r--r-- | apps/dav/tests/unit/Files/FileSearchBackendTest.php | 243 |
1 files changed, 138 insertions, 105 deletions
diff --git a/apps/dav/tests/unit/Files/FileSearchBackendTest.php b/apps/dav/tests/unit/Files/FileSearchBackendTest.php index dec5db1b1b0..c6d6f85347b 100644 --- a/apps/dav/tests/unit/Files/FileSearchBackendTest.php +++ b/apps/dav/tests/unit/Files/FileSearchBackendTest.php @@ -1,38 +1,21 @@ <?php + +declare(strict_types=1); /** - * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.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 OCA\DAV\Tests\Files; + +namespace OCA\DAV\Tests\unit\Files; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchQuery; use OC\Files\View; -use OCA\DAV\Connector\Sabre\CachingTree; use OCA\DAV\Connector\Sabre\Directory; use OCA\DAV\Connector\Sabre\File; use OCA\DAV\Connector\Sabre\FilesPlugin; +use OCA\DAV\Connector\Sabre\ObjectTree; +use OCA\DAV\Connector\Sabre\Server; use OCA\DAV\Files\FileSearchBackend; use OCP\Files\FileInfo; use OCP\Files\Folder; @@ -40,37 +23,28 @@ use OCP\Files\IRootFolder; use OCP\Files\Search\ISearchBinaryOperator; use OCP\Files\Search\ISearchComparison; use OCP\Files\Search\ISearchQuery; +use OCP\FilesMetadata\IFilesMetadataManager; use OCP\IUser; use OCP\Share\IManager; +use PHPUnit\Framework\MockObject\MockObject; use SearchDAV\Backend\SearchPropertyDefinition; use SearchDAV\Query\Limit; +use SearchDAV\Query\Literal; +use SearchDAV\Query\Operator; use SearchDAV\Query\Query; +use SearchDAV\Query\Scope; use Test\TestCase; class FileSearchBackendTest extends TestCase { - /** @var CachingTree|\PHPUnit\Framework\MockObject\MockObject */ - private $tree; - - /** @var IUser */ - private $user; - - /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */ - private $rootFolder; - - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ - private $shareManager; - - /** @var View|\PHPUnit\Framework\MockObject\MockObject */ - private $view; - - /** @var Folder|\PHPUnit\Framework\MockObject\MockObject */ - private $searchFolder; - - /** @var FileSearchBackend */ - private $search; - - /** @var Directory|\PHPUnit\Framework\MockObject\MockObject */ - private $davFolder; + private ObjectTree&MockObject $tree; + private Server&MockObject $server; + private IUser&MockObject $user; + private IRootFolder&MockObject $rootFolder; + private IManager&MockObject $shareManager; + private View&MockObject $view; + private Folder&MockObject $searchFolder; + private Directory&MockObject $davFolder; + private FileSearchBackend $search; protected function setUp(): void { parent::setUp(); @@ -80,28 +54,23 @@ class FileSearchBackendTest extends TestCase { ->method('getUID') ->willReturn('test'); - $this->tree = $this->getMockBuilder(CachingTree::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->view = $this->getMockBuilder(View::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->view->expects($this->any()) - ->method('getRelativePath') - ->willReturnArgument(0); - + $this->tree = $this->createMock(ObjectTree::class); + $this->server = $this->createMock(Server::class); + $this->view = $this->createMock(View::class); $this->rootFolder = $this->createMock(IRootFolder::class); - $this->shareManager = $this->createMock(IManager::class); - $this->searchFolder = $this->createMock(Folder::class); - $fileInfo = $this->createMock(FileInfo::class); - $this->davFolder = $this->createMock(Directory::class); + $this->view->expects($this->any()) + ->method('getRoot') + ->willReturn(''); + + $this->view->expects($this->any()) + ->method('getRelativePath') + ->willReturnArgument(0); + $this->davFolder->expects($this->any()) ->method('getFileInfo') ->willReturn($fileInfo); @@ -110,10 +79,12 @@ class FileSearchBackendTest extends TestCase { ->method('get') ->willReturn($this->searchFolder); - $this->search = new FileSearchBackend($this->tree, $this->user, $this->rootFolder, $this->shareManager, $this->view); + $filesMetadataManager = $this->createMock(IFilesMetadataManager::class); + + $this->search = new FileSearchBackend($this->server, $this->tree, $this->user, $this->rootFolder, $this->shareManager, $this->view, $filesMetadataManager); } - public function testSearchFilename() { + public function testSearchFilename(): void { $this->tree->expects($this->any()) ->method('getNodeForPath') ->willReturn($this->davFolder); @@ -132,17 +103,17 @@ class FileSearchBackendTest extends TestCase { $this->user )) ->willReturn([ - new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path') + new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path'), ]); - $query = $this->getBasicQuery(\SearchDAV\Query\Operator::OPERATION_EQUAL, '{DAV:}displayname', 'foo'); + $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, '{DAV:}displayname', 'foo'); $result = $this->search->search($query); $this->assertCount(1, $result); $this->assertEquals('/files/test/test/path', $result[0]->href); } - public function testSearchMimetype() { + public function testSearchMimetype(): void { $this->tree->expects($this->any()) ->method('getNodeForPath') ->willReturn($this->davFolder); @@ -161,17 +132,17 @@ class FileSearchBackendTest extends TestCase { $this->user )) ->willReturn([ - new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path') + new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path'), ]); - $query = $this->getBasicQuery(\SearchDAV\Query\Operator::OPERATION_EQUAL, '{DAV:}getcontenttype', 'foo'); + $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, '{DAV:}getcontenttype', 'foo'); $result = $this->search->search($query); $this->assertCount(1, $result); $this->assertEquals('/files/test/test/path', $result[0]->href); } - public function testSearchSize() { + public function testSearchSize(): void { $this->tree->expects($this->any()) ->method('getNodeForPath') ->willReturn($this->davFolder); @@ -190,17 +161,17 @@ class FileSearchBackendTest extends TestCase { $this->user )) ->willReturn([ - new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path') + new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path'), ]); - $query = $this->getBasicQuery(\SearchDAV\Query\Operator::OPERATION_GREATER_THAN, FilesPlugin::SIZE_PROPERTYNAME, 10); + $query = $this->getBasicQuery(Operator::OPERATION_GREATER_THAN, FilesPlugin::SIZE_PROPERTYNAME, 10); $result = $this->search->search($query); $this->assertCount(1, $result); $this->assertEquals('/files/test/test/path', $result[0]->href); } - public function testSearchMtime() { + public function testSearchMtime(): void { $this->tree->expects($this->any()) ->method('getNodeForPath') ->willReturn($this->davFolder); @@ -219,17 +190,17 @@ class FileSearchBackendTest extends TestCase { $this->user )) ->willReturn([ - new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path') + new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path'), ]); - $query = $this->getBasicQuery(\SearchDAV\Query\Operator::OPERATION_GREATER_THAN, '{DAV:}getlastmodified', 10); + $query = $this->getBasicQuery(Operator::OPERATION_GREATER_THAN, '{DAV:}getlastmodified', 10); $result = $this->search->search($query); $this->assertCount(1, $result); $this->assertEquals('/files/test/test/path', $result[0]->href); } - public function testSearchIsCollection() { + public function testSearchIsCollection(): void { $this->tree->expects($this->any()) ->method('getNodeForPath') ->willReturn($this->davFolder); @@ -248,10 +219,10 @@ class FileSearchBackendTest extends TestCase { $this->user )) ->willReturn([ - new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path') + new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path'), ]); - $query = $this->getBasicQuery(\SearchDAV\Query\Operator::OPERATION_IS_COLLECTION, 'yes'); + $query = $this->getBasicQuery(Operator::OPERATION_IS_COLLECTION, 'yes'); $result = $this->search->search($query); $this->assertCount(1, $result); @@ -259,7 +230,7 @@ class FileSearchBackendTest extends TestCase { } - public function testSearchInvalidProp() { + public function testSearchInvalidProp(): void { $this->expectException(\InvalidArgumentException::class); $this->tree->expects($this->any()) @@ -269,25 +240,25 @@ class FileSearchBackendTest extends TestCase { $this->searchFolder->expects($this->never()) ->method('search'); - $query = $this->getBasicQuery(\SearchDAV\Query\Operator::OPERATION_EQUAL, '{DAV:}getetag', 'foo'); + $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, '{DAV:}getetag', 'foo'); $this->search->search($query); } - private function getBasicQuery($type, $property, $value = null) { - $scope = new \SearchDAV\Query\Scope('/', 'infinite'); + private function getBasicQuery(string $type, string $property, int|string|null $value = null) { + $scope = new Scope('/', 'infinite'); $scope->path = '/'; $from = [$scope]; $orderBy = []; $select = []; if (is_null($value)) { - $where = new \SearchDAV\Query\Operator( + $where = new Operator( $type, - [new \SearchDAV\Query\Literal($property)] + [new Literal($property)] ); } else { - $where = new \SearchDAV\Query\Operator( + $where = new Operator( $type, - [new SearchPropertyDefinition($property, true, true, true), new \SearchDAV\Query\Literal($value)] + [new SearchPropertyDefinition($property, true, true, true), new Literal($value)] ); } $limit = new Limit(); @@ -296,7 +267,7 @@ class FileSearchBackendTest extends TestCase { } - public function testSearchNonFolder() { + public function testSearchNonFolder(): void { $this->expectException(\InvalidArgumentException::class); $davNode = $this->createMock(File::class); @@ -305,11 +276,11 @@ class FileSearchBackendTest extends TestCase { ->method('getNodeForPath') ->willReturn($davNode); - $query = $this->getBasicQuery(\SearchDAV\Query\Operator::OPERATION_EQUAL, '{DAV:}displayname', 'foo'); + $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, '{DAV:}displayname', 'foo'); $this->search->search($query); } - public function testSearchLimitOwnerBasic() { + public function testSearchLimitOwnerBasic(): void { $this->tree->expects($this->any()) ->method('getNodeForPath') ->willReturn($this->davFolder); @@ -321,11 +292,11 @@ class FileSearchBackendTest extends TestCase { ->willReturnCallback(function ($query) use (&$receivedQuery) { $receivedQuery = $query; return [ - new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path') + new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path'), ]; }); - $query = $this->getBasicQuery(\SearchDAV\Query\Operator::OPERATION_EQUAL, FilesPlugin::OWNER_ID_PROPERTYNAME, $this->user->getUID()); + $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, FilesPlugin::OWNER_ID_PROPERTYNAME, $this->user->getUID()); $this->search->search($query); $this->assertNotNull($receivedQuery); @@ -338,7 +309,7 @@ class FileSearchBackendTest extends TestCase { $this->assertEmpty($operator->getArguments()); } - public function testSearchLimitOwnerNested() { + public function testSearchLimitOwnerNested(): void { $this->tree->expects($this->any()) ->method('getNodeForPath') ->willReturn($this->davFolder); @@ -350,22 +321,22 @@ class FileSearchBackendTest extends TestCase { ->willReturnCallback(function ($query) use (&$receivedQuery) { $receivedQuery = $query; return [ - new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path') + new \OC\Files\Node\Folder($this->rootFolder, $this->view, '/test/path'), ]; }); - $query = $this->getBasicQuery(\SearchDAV\Query\Operator::OPERATION_EQUAL, FilesPlugin::OWNER_ID_PROPERTYNAME, $this->user->getUID()); - $query->where = new \SearchDAV\Query\Operator( - \SearchDAV\Query\Operator::OPERATION_AND, + $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, FilesPlugin::OWNER_ID_PROPERTYNAME, $this->user->getUID()); + $query->where = new Operator( + Operator::OPERATION_AND, [ - new \SearchDAV\Query\Operator( - \SearchDAV\Query\Operator::OPERATION_EQUAL, - [new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), new \SearchDAV\Query\Literal('image/png')] + new Operator( + Operator::OPERATION_EQUAL, + [new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), new Literal('image/png')] + ), + new Operator( + Operator::OPERATION_EQUAL, + [new SearchPropertyDefinition(FilesPlugin::OWNER_ID_PROPERTYNAME, true, true, true), new Literal($this->user->getUID())] ), - new \SearchDAV\Query\Operator( - \SearchDAV\Query\Operator::OPERATION_EQUAL, - [new SearchPropertyDefinition(FilesPlugin::OWNER_ID_PROPERTYNAME, true, true, true), new \SearchDAV\Query\Literal($this->user->getUID())] - ) ] ); $this->search->search($query); @@ -385,4 +356,66 @@ class FileSearchBackendTest extends TestCase { $this->assertEquals(ISearchBinaryOperator::OPERATOR_AND, $operator->getType()); $this->assertEmpty($operator->getArguments()); } + + public function testSearchOperatorLimit(): void { + $this->tree->expects($this->any()) + ->method('getNodeForPath') + ->willReturn($this->davFolder); + + $innerOperator = new Operator( + Operator::OPERATION_EQUAL, + [new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), new Literal('image/png')] + ); + // 5 child operators + $level1Operator = new Operator( + Operator::OPERATION_AND, + [ + $innerOperator, + $innerOperator, + $innerOperator, + $innerOperator, + $innerOperator, + ] + ); + // 5^2 = 25 child operators + $level2Operator = new Operator( + Operator::OPERATION_AND, + [ + $level1Operator, + $level1Operator, + $level1Operator, + $level1Operator, + $level1Operator, + ] + ); + // 5^3 = 125 child operators + $level3Operator = new Operator( + Operator::OPERATION_AND, + [ + $level2Operator, + $level2Operator, + $level2Operator, + $level2Operator, + $level2Operator, + ] + ); + + $query = $this->getBasicQuery(Operator::OPERATION_EQUAL, FilesPlugin::OWNER_ID_PROPERTYNAME, $this->user->getUID()); + $query->where = $level3Operator; + $this->expectException(\InvalidArgumentException::class); + $this->search->search($query); + } + + public function testPreloadPropertyFor(): void { + $node1 = $this->createMock(File::class); + $node2 = $this->createMock(Directory::class); + $nodes = [$node1, $node2]; + $requestProperties = ['{DAV:}getcontenttype', '{DAV:}getlastmodified']; + + $this->server->expects($this->once()) + ->method('emit') + ->with('preloadProperties', [$nodes, $requestProperties]); + + $this->search->preloadPropertyFor($nodes, $requestProperties); + } } |