Skip to content

Commit 9a42d6c

Browse files
committed
fixup! fix(caldav): Expand recurring events for principal calendar search
1 parent 7afe609 commit 9a42d6c

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

apps/dav/tests/unit/Search/EventsSearchProviderTest.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,76 @@ public function testSearchSince(): void {
827827
$this->assertEquals('1780297200', $result0Data['attributes']['createdAt']);
828828
}
829829

830+
public function testSearchSinceOnlyDefaultsUntilToMaxDate(): void {
831+
// No until: expanding recurrences still needs a concrete upper bound,
832+
// so it defaults to CalDavBackend::MAX_DATE (effectively unbounded)
833+
// instead of guessing a caller's intent.
834+
$user = $this->createMock(IUser::class);
835+
$user->method('getUID')->willReturn('john.doe');
836+
$query = $this->createMock(ISearchQuery::class);
837+
$query->method('getFilter')->willReturnCallback(function ($name) {
838+
return match ($name) {
839+
'term' => new StringFilter('search term'),
840+
'since' => new DateTimeFilter('2026-05-15'),
841+
default => null,
842+
};
843+
});
844+
$query->method('getLimit')->willReturn(5);
845+
$query->method('getCursor')->willReturn(20);
846+
$this->appManager->method('isEnabledForUser')->willReturn(true);
847+
$this->l10n->method('t')->willReturnArgument(0);
848+
$this->backend->method('getCalendarsForUser')->willReturn([]);
849+
$this->backend->method('getSubscriptionsForUser')->willReturn([]);
850+
851+
$since = new \DateTimeImmutable('2026-05-15 00:00:00');
852+
$this->backend->expects($this->once())
853+
->method('searchPrincipalUri')
854+
->with('principals/users/john.doe', 'search term', ['VEVENT'],
855+
['SUMMARY', 'LOCATION', 'DESCRIPTION', 'ATTENDEE', 'ORGANIZER', 'CATEGORIES'],
856+
['ATTENDEE' => ['CN'], 'ORGANIZER' => ['CN']],
857+
['limit' => 5, 'offset' => 20, 'timerange' => [
858+
'start' => $since,
859+
'end' => new \DateTimeImmutable(CalDavBackend::MAX_DATE, $since->getTimezone()),
860+
]])
861+
->willReturn([]);
862+
863+
$this->provider->search($user, $query);
864+
}
865+
866+
public function testSearchUntilOnlyDefaultsSinceToEpoch(): void {
867+
// No since: the lower bound defaults to the Unix epoch (effectively
868+
// unbounded into the past) for the same reason.
869+
$user = $this->createMock(IUser::class);
870+
$user->method('getUID')->willReturn('john.doe');
871+
$query = $this->createMock(ISearchQuery::class);
872+
$query->method('getFilter')->willReturnCallback(function ($name) {
873+
return match ($name) {
874+
'term' => new StringFilter('search term'),
875+
'until' => new DateTimeFilter('2026-06-14'),
876+
default => null,
877+
};
878+
});
879+
$query->method('getLimit')->willReturn(5);
880+
$query->method('getCursor')->willReturn(20);
881+
$this->appManager->method('isEnabledForUser')->willReturn(true);
882+
$this->l10n->method('t')->willReturnArgument(0);
883+
$this->backend->method('getCalendarsForUser')->willReturn([]);
884+
$this->backend->method('getSubscriptionsForUser')->willReturn([]);
885+
886+
$this->backend->expects($this->once())
887+
->method('searchPrincipalUri')
888+
->with('principals/users/john.doe', 'search term', ['VEVENT'],
889+
['SUMMARY', 'LOCATION', 'DESCRIPTION', 'ATTENDEE', 'ORGANIZER', 'CATEGORIES'],
890+
['ATTENDEE' => ['CN'], 'ORGANIZER' => ['CN']],
891+
['limit' => 5, 'offset' => 20, 'timerange' => [
892+
'start' => new \DateTimeImmutable('@0'),
893+
'end' => new \DateTimeImmutable('2026-06-14 00:00:00'),
894+
]])
895+
->willReturn([]);
896+
897+
$this->provider->search($user, $query);
898+
}
899+
830900
public function testSearchDropsInvalidRowsWithoutStallingCursor(): void {
831901
// A row that resolves to no in-range occurrence must not prevent the
832902
// cursor from advancing, or pagination would keep repeating the same

0 commit comments

Comments
 (0)