From dc63df90588da0c0aecb0e446a9fbdb94afbd41c Mon Sep 17 00:00:00 2001 From: Conrad Hoffmann Date: Wed, 31 Aug 2022 12:09:00 +0200 Subject: [PATCH] carddav: evaluate recurrence in match helper The match helper will now properly return recurring events if any of their recurrences fall into the queried time range. A test for this was added as well. --- caldav/match.go | 14 ++++++++++++-- caldav/match_test.go | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/caldav/match.go b/caldav/match.go index b881183..948b33c 100644 --- a/caldav/match.go +++ b/caldav/match.go @@ -127,9 +127,19 @@ func matchPropFilter(filter PropFilter, comp *ical.Component) (bool, error) { func matchCompTimeRange(start, end time.Time, comp *ical.Component) (bool, error) { // See https://datatracker.ietf.org/doc/html/rfc4791#section-9.9 - // TODO handle "infinity" values in query - // TODO handle recurring events + // evaluate recurring components + rset, err := comp.RecurrenceSet(start.Location()) + if err != nil { + return false, err + } + if rset != nil { + // TODO we can only set inclusive to true or false, but really the + // start time is inclusive while the end time is not :/ + return len(rset.Between(start, end, true)) > 0, nil + } + // TODO handle "infinity" values in query + // TODO handle more than just events if comp.Name != ical.CompEvent { return false, nil } diff --git a/caldav/match_test.go b/caldav/match_test.go index e911846..73114bb 100644 --- a/caldav/match_test.go +++ b/caldav/match_test.go @@ -253,6 +253,24 @@ END:VCALENDAR`) addrs: []CalendarObject{event1, event2, event3, todo1}, want: []CalendarObject{event1}, }, + { + // Query a time range that only returns a result if recurrence is properly evaluated. + name: "recurring events in time range", + query: &CalendarQuery{ + CompFilter: CompFilter{ + Name: "VCALENDAR", + Comps: []CompFilter{ + CompFilter{ + Name: "VEVENT", + Start: toDate(t, "20060103T000000Z"), + End: toDate(t, "20060104T000000Z"), + }, + }, + }, + }, + addrs: []CalendarObject{event1, event2, event3, todo1}, + want: []CalendarObject{event2}, + }, // TODO add more examples } { t.Run(tc.name, func(t *testing.T) {