Seperate query classes from xml classes to allow specifying more information in the query

This commit is contained in:
Robin Appelman 2018-01-25 14:48:02 +01:00
commit 5ad4d24b89
17 changed files with 509 additions and 112 deletions

View file

@ -26,6 +26,7 @@ use Sabre\DAV\INode;
use Sabre\DAV\SimpleFile;
use SearchDAV\Backend\ISearchBackend;
use SearchDAV\Backend\SearchResult;
use SearchDAV\Query\Query;
use SearchDAV\XML\BasicSearch;
use SearchDAV\Backend\SearchPropertyDefinition;
@ -47,7 +48,7 @@ class DummyBackend implements ISearchBackend {
];
}
public function search(BasicSearch $query) {
public function search(Query $query) {
return [
new SearchResult(new SimpleFile('foo.txt', 'foobar', 'text/plain'), '/bar/foo.txt')
];

View file

@ -50,12 +50,12 @@ class QueryParserTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals([
new Scope('/container1/', 'infinity')
], $search->from);
$this->assertEquals(new Operator(Operator::OPERATION_GREATER_THAN, [
$this->assertEquals(new Operator(\SearchDAV\Query\Operator::OPERATION_GREATER_THAN, [
'{DAV:}getcontentlength',
new Literal(10000)
]), $search->where);
$this->assertEquals([
new Order('{DAV:}getcontentlength', Order::ASC)
new Order('{DAV:}getcontentlength', \SearchDAV\Query\Order::ASC)
], $search->orderBy);
}
@ -75,12 +75,12 @@ class QueryParserTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals([
new Scope('/container1/', 'infinity')
], $search->from);
$this->assertEquals(new Operator(Operator::OPERATION_GREATER_THAN, [
$this->assertEquals(new Operator(\SearchDAV\Query\Operator::OPERATION_GREATER_THAN, [
'{DAV:}getcontentlength',
new Literal(10000)
]), $search->where);
$this->assertEquals([
new Order('{DAV:}getcontentlength', Order::DESC)
new Order('{DAV:}getcontentlength', \SearchDAV\Query\Order::DESC)
], $search->orderBy);
}
@ -101,7 +101,7 @@ class QueryParserTest extends \PHPUnit_Framework_TestCase {
new Scope('/container1/', 'infinity'),
new Scope('/container2/', 1),
], $search->from);
$this->assertEquals(new Operator(Operator::OPERATION_IS_COLLECTION, []), $search->where);
$this->assertEquals(new Operator(\SearchDAV\Query\Operator::OPERATION_IS_COLLECTION, []), $search->where);
$this->assertEquals([], $search->orderBy);
}

View file

@ -34,6 +34,7 @@ use SearchDAV\Backend\ISearchBackend;
use SearchDAV\Backend\SearchPropertyDefinition;
use SearchDAV\Backend\SearchResult;
use SearchDAV\DAV\SearchPlugin;
use SearchDAV\Query\Query;
use SearchDAV\XML\BasicSearch;
use SearchDAV\XML\Limit;
use SearchDAV\XML\Literal;
@ -275,19 +276,20 @@ class SearchPluginTest extends \PHPUnit_Framework_TestCase {
->method('isValidScope')
->willReturn(true);
$query = new BasicSearch();
$query->orderBy = [
new Order('{DAV:}getcontentlength', Order::ASC)
$lengthProp = new SearchPropertyDefinition('{DAV:}getcontentlength', true, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER);
$orderBy = [
new \SearchDAV\Query\Order($lengthProp, \SearchDAV\Query\Order::ASC)
];
$query->select = ['{DAV:}getcontentlength'];
$query->from = [
$select = [$lengthProp];
$from = [
new Scope('/container1/', 'infinity', '/container1/')
];
$query->where = new Operator(Operator::OPERATION_GREATER_THAN, [
'{DAV:}getcontentlength',
$where = new \SearchDAV\Query\Operator(\SearchDAV\Query\Operator::OPERATION_GREATER_THAN, [
$lengthProp,
new Literal(10000)
]);
$query->limit = new Limit();
$limit = new Limit();
$query = new Query($select, $from, $where, $orderBy, $limit);
$this->searchBackend->expects($this->once())
->method('search')
@ -299,6 +301,12 @@ class SearchPluginTest extends \PHPUnit_Framework_TestCase {
)
]);
$this->searchBackend->expects($this->any())
->method('getPropertyDefinitionsForScope')
->willReturn([
$lengthProp
]);
$plugin->searchHandler($request, $response);
$parser = new Service();
@ -439,4 +447,39 @@ class SearchPluginTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals(new SupportedQueryGrammar(), $propFind->get('{DAV:}supported-query-grammar-set'));
}
public function testSearchQueryInvalidWhere() {
$this->searchBackend->expects($this->any())
->method('getArbiterPath')
->willReturn('foo');
$plugin = new SearchPlugin($this->searchBackend);
$server = new Server();
$plugin->initialize($server);
$request = new Request('SEARCH', '/index.php/foo', [
'Content-Type' => 'text/xml'
]);
$request->setBaseUrl('/index.php');
$request->setBody(fopen(__DIR__ . '/invalidwhere.xml', 'r'));
$response = new Response();
$this->searchBackend->expects($this->any())
->method('isValidScope')
->willReturn(true);
$this->searchBackend->expects($this->never())
->method('search');
$this->searchBackend->expects($this->once())
->method('getPropertyDefinitionsForScope')
->willReturn([
new SearchPropertyDefinition('{http://ns.nextcloud.com:}fileid', false, true, true, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
]);
$plugin->searchHandler($request, $response);
$this->assertEquals(400, $response->getStatus());
}
}

32
tests/invalidwhere.xml Normal file
View file

@ -0,0 +1,32 @@
<?xml version="1.0"?>
<d:searchrequest xmlns:d="DAV:" xmlns:oc="http://ns.nextcloud.com">
<d:basicsearch>
<d:select>
<d:prop>
<d:getcontentlength/>
</d:prop>
</d:select>
<d:from>
<d:scope>
<d:href>/container1/</d:href>
<d:depth>infinity</d:depth>
</d:scope>
</d:from>
<d:where>
<d:gt>
<d:prop>
<oc:fileid/>
</d:prop>
<d:literal>5</d:literal>
</d:gt>
</d:where>
<d:orderby>
<d:order>
<d:prop>
<d:getcontentlength/>
</d:prop>
<d:ascending/>
</d:order>
</d:orderby>
</d:basicsearch>
</d:searchrequest>