Skip to content

Commit

Permalink
fix(dav): expand recurrences when searching
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
  • Loading branch information
st3iny committed Sep 26, 2023
1 parent efde16a commit ab0a39d
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
13 changes: 12 additions & 1 deletion apps/dav/lib/CalDAV/CalDavBackend.php
Expand Up @@ -20,6 +20,7 @@
* @author Thomas Citharel <nextcloud@tcit.fr>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vinicius Cubas Brand <vinicius@eita.org.br>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* @license AGPL-3.0
*
Expand Down Expand Up @@ -1938,8 +1939,18 @@ public function search(array $calendarInfo, $pattern, array $searchProperties,
});
$result->closeCursor();

return array_map(function ($o) {
return array_map(function ($o) use ($options) {
$calendarData = Reader::read($o['calendardata']);

// Expand recurrences if an explicit time range is requested
if ($calendarData instanceof VCalendar
&& isset($options['timerange']['start'], $options['timerange']['end'])) {
$calendarData = $calendarData->expand(
$options['timerange']['start'],
$options['timerange']['end'],
);
}

$comps = $calendarData->getComponents();
$objects = [];
$timezones = [];
Expand Down
69 changes: 69 additions & 0 deletions apps/dav/tests/unit/CalDAV/CalDavBackendTest.php
Expand Up @@ -32,7 +32,9 @@

namespace OCA\DAV\Tests\unit\CalDAV;

use DateInterval;
use DateTime;
use DateTimeImmutable;
use DateTimeZone;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CalDAV\Calendar;
Expand Down Expand Up @@ -1420,4 +1422,71 @@ public function testPruneOutdatedSyncTokens(): void {
// Check that no crash occurs when prune is called without current changes
$deleted = $this->backend->pruneOutdatedSyncTokens(1);
}

public function testSearchAndExpandRecurrences() {
$calendarId = $this->createTestCalendar();
$calendarInfo = [
'id' => $calendarId,
'principaluri' => 'user1',
'{http://owncloud.org/ns}owner-principal' => 'user1',
];

$calData = <<<'EOD'
BEGIN:VCALENDAR
PRODID:-//IDN nextcloud.com//Calendar app 4.5.0-alpha.2//EN
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
CREATED:20230921T133401Z
DTSTAMP:20230921T133448Z
LAST-MODIFIED:20230921T133448Z
SEQUENCE:2
UID:7b7d5d12-683c-48ce-973a-b3e1cb0bae2a
DTSTART;VALUE=DATE:20230912
DTEND;VALUE=DATE:20230913
STATUS:CONFIRMED
SUMMARY:Daily Event
RRULE:FREQ=DAILY
END:VEVENT
END:VCALENDAR
EOD;
$uri = static::getUniqueID('calobj');
$this->backend->createCalendarObject($calendarId, $uri, $calData);

$start = new DateTimeImmutable('2023-09-20T00:00:00Z');
$end = $start->add(new DateInterval('P14D'));

$results = $this->backend->search(
$calendarInfo,
'',
[],
[
'timerange' => [
'start' => $start,
'end' => $end,
]
],
null,
null,
);

$this->assertCount(1, $results);
$this->assertCount(14, $results[0]['objects']);
foreach ($results as $result) {
foreach ($result['objects'] as $object) {
$this->assertEquals($object['UID'][0], '7b7d5d12-683c-48ce-973a-b3e1cb0bae2a');
$this->assertEquals($object['SUMMARY'][0], 'Daily Event');
$this->assertGreaterThanOrEqual(
$start->getTimestamp(),
$object['DTSTART'][0]->getTimestamp(),
'Recurrence starting before requested start',
);
$this->assertLessThanOrEqual(
$end->getTimestamp(),
$object['DTSTART'][0]->getTimestamp(),
'Recurrence starting after requested end',
);
}
}
}
}

0 comments on commit ab0a39d

Please sign in to comment.