def test_calendar_query_bogus_timezone_id(self): """ Partial retrieval of events by time range. (CalDAV-access-09, section 7.6.1) """ TimezoneCache.create() self.addCleanup(TimezoneCache.clear) calendar_properties = ( davxml.GETETag(), caldavxml.CalendarData(), ) query_timerange = caldavxml.TimeRange( start="%04d1001T000000Z" % (DateTime.getToday().getYear(), ), end="%04d1101T000000Z" % (DateTime.getToday().getYear(), ), ) query = caldavxml.CalendarQuery( davxml.PropertyContainer(*calendar_properties), caldavxml.Filter( caldavxml.ComponentFilter( caldavxml.ComponentFilter( query_timerange, name="VEVENT", ), name="VCALENDAR", ), ), caldavxml.TimeZoneID.fromString("bogus"), ) result = yield self.calendar_query( query, got_xml=None, expected_code=responsecode.FORBIDDEN) self.assertTrue("valid-timezone" in result)
def supportedReports(self): result = super(CalDAVResource, self).supportedReports() result.append(davxml.Report(caldavxml.CalendarQuery(), )) result.append(davxml.Report(caldavxml.CalendarMultiGet(), )) # free-busy report not allowed if config.EnableSyncReport: # Only allowed on calendar/inbox/addressbook collections result.append(davxml.Report(davxml.SyncCollection(), )) return result
def test_calendar_query_timezone(self): """ Partial retrieval of events by time range. (CalDAV-access-09, section 7.6.1) """ TimezoneCache.create() self.addCleanup(TimezoneCache.clear) tzid1 = "Etc/GMT+1" tz1 = Component(None, pycalendar=readVTZ(tzid1)) calendar_properties = ( davxml.GETETag(), caldavxml.CalendarData(), ) query_timerange = caldavxml.TimeRange( start="%04d1001T000000Z" % (DateTime.getToday().getYear(), ), end="%04d1101T000000Z" % (DateTime.getToday().getYear(), ), ) query = caldavxml.CalendarQuery( davxml.PropertyContainer(*calendar_properties), caldavxml.Filter( caldavxml.ComponentFilter( caldavxml.ComponentFilter( query_timerange, name="VEVENT", ), name="VCALENDAR", ), ), caldavxml.TimeZone.fromCalendar(tz1), ) def got_xml(doc): if not isinstance(doc.root_element, davxml.MultiStatus): self.fail( "REPORT response XML root element is not multistatus: %r" % (doc.root_element, )) return self.calendar_query(query, got_xml)
def test_calendar_query_wrong_timezone_elements(self): """ Partial retrieval of events by time range. (CalDAV-access-09, section 7.6.1) """ TimezoneCache.create() self.addCleanup(TimezoneCache.clear) tzid1 = "Etc/GMT+1" tz1 = Component(None, pycalendar=readVTZ(tzid1)) calendar_properties = ( davxml.GETETag(), caldavxml.CalendarData(), ) query_timerange = caldavxml.TimeRange( start="%04d1001T000000Z" % (DateTime.getToday().getYear(), ), end="%04d1101T000000Z" % (DateTime.getToday().getYear(), ), ) query = caldavxml.CalendarQuery( davxml.PropertyContainer(*calendar_properties), caldavxml.Filter( caldavxml.ComponentFilter( caldavxml.ComponentFilter( query_timerange, name="VEVENT", ), name="VCALENDAR", ), ), caldavxml.TimeZone.fromCalendar(tz1), ) query.children += (caldavxml.TimeZoneID.fromString(tzid1), ) result = yield self.calendar_query( query, got_xml=None, expected_code=responsecode.BAD_REQUEST) self.assertTrue("Only one of" in result)
def test_calendar_query_time_range(self): """ Partial retrieval of events by time range. (CalDAV-access-09, section 7.6.1) """ calendar_properties = ( davxml.GETETag(), caldavxml.CalendarData( caldavxml.CalendarComponent( caldavxml.AllProperties(), caldavxml.CalendarComponent( caldavxml.Property(name="X-ABC-GUID"), caldavxml.Property(name="UID"), caldavxml.Property(name="DTSTART"), caldavxml.Property(name="DTEND"), caldavxml.Property(name="DURATION"), caldavxml.Property(name="EXDATE"), caldavxml.Property(name="EXRULE"), caldavxml.Property(name="RDATE"), caldavxml.Property(name="RRULE"), caldavxml.Property(name="LOCATION"), caldavxml.Property(name="SUMMARY"), name="VEVENT", ), caldavxml.CalendarComponent( caldavxml.AllProperties(), caldavxml.AllComponents(), name="VTIMEZONE", ), name="VCALENDAR", ), ), ) query_timerange = caldavxml.TimeRange( start="%04d1001T000000Z" % (DateTime.getToday().getYear(), ), end="%04d1101T000000Z" % (DateTime.getToday().getYear(), ), ) query = caldavxml.CalendarQuery( davxml.PropertyContainer(*calendar_properties), caldavxml.Filter( caldavxml.ComponentFilter( caldavxml.ComponentFilter( query_timerange, name="VEVENT", ), name="VCALENDAR", ), ), ) def got_xml(doc): if not isinstance(doc.root_element, davxml.MultiStatus): self.fail( "REPORT response XML root element is not multistatus: %r" % (doc.root_element, )) for response in doc.root_element.childrenOfType( davxml.PropertyStatusResponse): properties_to_find = [p.qname() for p in calendar_properties] for propstat in response.childrenOfType(davxml.PropertyStatus): status = propstat.childOfType(davxml.Status) properties = propstat.childOfType( davxml.PropertyContainer).children if status.code != responsecode.OK: self.fail( "REPORT failed (status %s) to locate properties: %r" % (status.code, properties)) for property in properties: qname = property.qname() if qname in properties_to_find: properties_to_find.remove(qname) else: self.fail( "REPORT found property we didn't ask for: %r" % (property, )) if isinstance(property, caldavxml.CalendarData): cal = property.calendar() instances = cal.expandTimeRanges( query_timerange.end) vevents = [ x for x in cal.subcomponents() if x.name() == "VEVENT" ] if not TimeRange(query_timerange).matchinstance( vevents[0], instances): self.fail( "REPORT property %r returned calendar %s outside of request time range %r" % (property, property.calendar, query_timerange)) return self.calendar_query(query, got_xml)
def simple_event_query(self, event_filter, uids, withData=True): props = (davxml.GETETag(), ) if withData: props += (caldavxml.CalendarData(), ) query = caldavxml.CalendarQuery( davxml.PropertyContainer(*props), caldavxml.Filter( caldavxml.ComponentFilter( caldavxml.ComponentFilter( event_filter, name="VEVENT", ), name="VCALENDAR", ), ), ) def got_xml(doc): if not isinstance(doc.root_element, davxml.MultiStatus): self.fail( "REPORT response XML root element is not multistatus: %r" % (doc.root_element, )) for response in doc.root_element.childrenOfType( davxml.PropertyStatusResponse): for propstat in response.childrenOfType(davxml.PropertyStatus): status = propstat.childOfType(davxml.Status) if status.code != responsecode.OK: self.fail( "REPORT failed (status %s) to locate properties: %r" % (status.code, propstat)) properties = propstat.childOfType( davxml.PropertyContainer).children for property in properties: qname = property.qname() if qname == (davxml.dav_namespace, "getetag"): continue if qname != (caldavxml.caldav_namespace, "calendar-data"): self.fail( "Response included unexpected property %r" % (property, )) result_calendar = property.calendar() if result_calendar is None: self.fail( "Invalid response CalDAV:calendar-data: %r" % (property, )) uid = result_calendar.resourceUID() if uid in uids: uids.remove(uid) else: self.fail("Got calendar for unexpected UID %r" % (uid, )) original_filename = file( os.path.join(self.holidays_dir, uid + ".ics")) original_calendar = ical.Component.fromStream( original_filename) self.assertEqual(result_calendar, original_calendar) return self.calendar_query(query, got_xml)