diff options
author | Georg Ehrke <developer@georgehrke.com> | 2017-04-25 19:26:47 +0200 |
---|---|---|
committer | Georg Ehrke <developer@georgehrke.com> | 2017-04-28 20:21:36 +0200 |
commit | 8d00458b568185dfb405c79f38930bc4a64855ff (patch) | |
tree | 37611e9e97a18f373c21129618714ec896df9df0 /apps | |
parent | c76633bb8aabff7f160d1b5cd0b7f2a259d009a7 (diff) | |
download | nextcloud-server-8d00458b568185dfb405c79f38930bc4a64855ff.tar.gz nextcloud-server-8d00458b568185dfb405c79f38930bc4a64855ff.zip |
unit test custom calendar search
Signed-off-by: Georg Ehrke <developer@georgehrke.com>
Diffstat (limited to 'apps')
-rw-r--r-- | apps/dav/lib/CalDAV/CalDavBackend.php | 50 | ||||
-rw-r--r-- | apps/dav/lib/Migration/BuildCalendarSearchIndexBackgroundJob.php | 2 | ||||
-rw-r--r-- | apps/dav/tests/unit/CalDAV/CalDavBackendTest.php | 132 |
3 files changed, 162 insertions, 22 deletions
diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 80dc27c20d0..a2b7a2e83b2 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -1,11 +1,13 @@ <?php /** * @copyright Copyright (c) 2016, ownCloud, Inc. + * @copyright Copyright (c) 2017 Georg Ehrke * * @author Joas Schilling <coding@schilljs.com> * @author Stefan Weil <sw@weilnetz.de> * @author Thomas Citharel <tcit@tcit.fr> * @author Thomas Müller <thomas.mueller@tmit.eu> + * @author Georg Ehrke <oc.list@georgehrke.com> * * @license AGPL-3.0 * @@ -1256,51 +1258,57 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $compExpr = call_user_func_array([$query->expr(), 'orX'], $compExpressions); } - $propExpressions = []; + if (!isset($filters['props'])) { + $filters['props'] = []; + } + if (!isset($filters['params'])) { + $filters['params'] = []; + } + + $propParamExpressions = []; foreach($filters['props'] as $prop) { - $propExpressions[] = $query->expr()->andX( + $propParamExpressions[] = $query->expr()->andX( $query->expr()->eq('i.name', $query->createNamedParameter($prop)), $query->expr()->isNull('i.parameter') ); } - - if (count($propExpressions) === 1) { - $propExpr = $propExpressions[0]; - } else { - $propExpr = call_user_func_array([$query->expr(), 'orX'], $propExpressions); - } - - $paramExpressions = []; foreach($filters['params'] as $param) { - $paramExpressions[] = $query->expr()->andX( + $propParamExpressions[] = $query->expr()->andX( $query->expr()->eq('i.name', $query->createNamedParameter($param['property'])), $query->expr()->eq('i.parameter', $query->createNamedParameter($param['parameter'])) ); } - if (count($paramExpressions) === 1) { - $paramExpr = $paramExpressions[0]; + if (count($propParamExpressions) === 1) { + $propParamExpr = $propParamExpressions[0]; } else { - $paramExpr = call_user_func_array([$query->expr(), 'orX'], $paramExpressions); + $propParamExpr = call_user_func_array([$query->expr(), 'orX'], $propParamExpressions); } - $offset = 0; - $query->select(['c.calendarid', 'c.uri']) ->from('calendarobjects_properties', 'i') ->join('i', 'calendarobjects', 'c', $query->expr()->eq('i.objectid', 'c.id')) ->where($calExpr) ->andWhere($compExpr) - ->andWhere($query->expr()->orX($propExpr, $paramExpr)) - ->andWhere($query->expr()->like('i.value', $query->createNamedParameter($filters['search-term']))) - ->setFirstResult($offset) - ->setMaxResults($limit); + ->andWhere($propParamExpr) + ->andWhere($query->expr()->iLike('i.value', + $query->createNamedParameter('%'.$this->db->escapeLikeParameter($filters['search-term']).'%'))); + + if ($offset) { + $query->setFirstResult($offset); + } + if ($limit) { + $query->setMaxResults($limit); + } $stmt = $query->execute(); $result = []; while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $result[] = $uriMapper[$row['calendarid']] . '/' . $row['uri']; + $path = $uriMapper[$row['calendarid']] . '/' . $row['uri']; + if (!in_array($path, $result)) { + $result[] = $path; + } } return $result; diff --git a/apps/dav/lib/Migration/BuildCalendarSearchIndexBackgroundJob.php b/apps/dav/lib/Migration/BuildCalendarSearchIndexBackgroundJob.php index c80289c1b30..a4fa2c63e02 100644 --- a/apps/dav/lib/Migration/BuildCalendarSearchIndexBackgroundJob.php +++ b/apps/dav/lib/Migration/BuildCalendarSearchIndexBackgroundJob.php @@ -93,7 +93,7 @@ class BuildCalendarSearchIndexBackgroundJob extends QueuedJob { $startTime = $this->timeFactory->getTime(); $query = $this->db->getQueryBuilder(); - $query->select(['id', 'calendarid', 'objecturi', 'calendardata']) + $query->select(['id', 'calendarid', 'uri', 'calendardata']) ->from('calendarobjects') ->where($query->expr()->lte('id', $query->createNamedParameter($stopAt))) ->andWhere($query->expr()->gt('id', $query->createNamedParameter($offset))) diff --git a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php index 5adda30c19d..dc531b5a64a 100644 --- a/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php +++ b/apps/dav/tests/unit/CalDAV/CalDavBackendTest.php @@ -1,10 +1,12 @@ <?php /** * @copyright Copyright (c) 2016, ownCloud, Inc. + * @copyright Copyright (c) 2017 Georg Ehrke * * @author Joas Schilling <coding@schilljs.com> * @author Thomas Citharel <tcit@tcit.fr> * @author Thomas Müller <thomas.mueller@tmit.eu> + * @author Georg Ehrke <oc.list@georgehrke.com> * * @license AGPL-3.0 * @@ -489,4 +491,134 @@ EOD; 'unknown class -> private' => [CalDavBackend::CLASSIFICATION_PRIVATE, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:VERTRAULICH\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"], ]; } + + public function testCalendarSearch() { + $calendarId = $this->createTestCalendar(); + + $uri = static::getUniqueID('calobj'); + $calData = <<<EOD +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:ownCloud Calendar +BEGIN:VEVENT +CREATED;VALUE=DATE-TIME:20130910T125139Z +UID:47d15e3ec8 +LAST-MODIFIED;VALUE=DATE-TIME:20130910T125139Z +DTSTAMP;VALUE=DATE-TIME:20130910T125139Z +SUMMARY:Test Event +DTSTART;VALUE=DATE-TIME:20130912T130000Z +DTEND;VALUE=DATE-TIME:20130912T140000Z +CLASS:PUBLIC +END:VEVENT +END:VCALENDAR +EOD; + + $this->backend->createCalendarObject($calendarId, $uri, $calData); + + $search1 = $this->backend->calendarSearch(self::UNIT_TEST_USER, [ + 'comps' => [ + 'VEVENT', + 'VTODO' + ], + 'props' => [ + 'SUMMARY', + 'LOCATION' + ], + 'search-term' => 'Test', + ]); + $this->assertEquals(count($search1), 1); + + + // update the card + $calData = <<<'EOD' +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:ownCloud Calendar +BEGIN:VEVENT +CREATED;VALUE=DATE-TIME:20130910T125139Z +UID:47d15e3ec8 +LAST-MODIFIED;VALUE=DATE-TIME:20130910T125139Z +DTSTAMP;VALUE=DATE-TIME:20130910T125139Z +SUMMARY:123 Event +DTSTART;VALUE=DATE-TIME:20130912T130000Z +DTEND;VALUE=DATE-TIME:20130912T140000Z +ATTENDEE;CN=test:mailto:foo@bar.com +END:VEVENT +END:VCALENDAR +EOD; + $this->backend->updateCalendarObject($calendarId, $uri, $calData); + + $search2 = $this->backend->calendarSearch(self::UNIT_TEST_USER, [ + 'comps' => [ + 'VEVENT', + 'VTODO' + ], + 'props' => [ + 'SUMMARY', + 'LOCATION' + ], + 'search-term' => 'Test', + ]); + $this->assertEquals(count($search2), 0); + + $search3 = $this->backend->calendarSearch(self::UNIT_TEST_USER, [ + 'comps' => [ + 'VEVENT', + 'VTODO' + ], + 'props' => [ + 'SUMMARY', + 'LOCATION' + ], + 'params' => [ + [ + 'property' => 'ATTENDEE', + 'parameter' => 'CN' + ] + ], + 'search-term' => 'Test', + ]); + $this->assertEquals(count($search3), 1); + + // t matches both summary and attendee's CN, but we want unique results + $search4 = $this->backend->calendarSearch(self::UNIT_TEST_USER, [ + 'comps' => [ + 'VEVENT', + 'VTODO' + ], + 'props' => [ + 'SUMMARY', + 'LOCATION' + ], + 'params' => [ + [ + 'property' => 'ATTENDEE', + 'parameter' => 'CN' + ] + ], + 'search-term' => 't', + ]); + $this->assertEquals(count($search4), 1); + + $this->backend->deleteCalendarObject($calendarId, $uri); + + $search5 = $this->backend->calendarSearch(self::UNIT_TEST_USER, [ + 'comps' => [ + 'VEVENT', + 'VTODO' + ], + 'props' => [ + 'SUMMARY', + 'LOCATION' + ], + 'params' => [ + [ + 'property' => 'ATTENDEE', + 'parameter' => 'CN' + ] + ], + 'search-term' => 't', + ]); + $this->assertEquals(count($search5), 0); + } } |