def mkcalendar_cb(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code, )) def propfind_cb(response): response = IResponse(response) if response.code != responsecode.MULTI_STATUS: self.fail("Incorrect response to PROPFIND: %s" % (response.code, )) def got_xml(doc): if not isinstance(doc.root_element, davxml.MultiStatus): self.fail( "PROPFIND response XML root element is not multistatus: %r" % (doc.root_element, )) response = doc.root_element.childOfType(davxml.Response) href = response.childOfType(davxml.HRef) self.failUnless(str(href) == calendar_uri) for propstat in response.childrenOfType( davxml.PropertyStatus): status = propstat.childOfType(davxml.Status) if status.code != responsecode.OK: self.fail( "Unable to read requested properties (%s): %r" % (status, propstat.childOfType( davxml.PropertyContainer).toxml())) container = propstat.childOfType(davxml.PropertyContainer) # # Check CalDAV:supported-calendar-component-set # supported_components = container.childOfType( caldavxml.SupportedCalendarComponentSet) if not supported_components: self.fail( "Expected CalDAV:supported-calendar-component-set element; but got none." ) supported = set(("VEVENT", )) for component in supported_components.children: if component.type in supported: supported.remove(component.type) if supported: self.fail( "Expected supported calendar component types: %s" % (tuple(supported), )) # # Check CalDAV:supported-calendar-data # supported_calendar = container.childOfType( caldavxml.SupportedCalendarData) if not supported_calendar: self.fail( "Expected CalDAV:supported-calendar-data element; but got none." ) for calendar in supported_calendar.children: if calendar.content_type not in ( "text/calendar", "application/calendar+json"): self.fail( "Expected a text/calendar calendar-data type restriction" ) if calendar.version != "2.0": self.fail( "Expected a version 2.0 calendar-data restriction" ) # # Check DAV:supported-report-set # supported_reports = container.childOfType( davxml.SupportedReportSet) if not supported_reports: self.fail( "Expected DAV:supported-report-set element; but got none." ) cal_query = False cal_multiget = False cal_freebusy = False for supported in supported_reports.childrenOfType( davxml.SupportedReport): report = supported.childOfType(davxml.Report) if report.childOfType( caldavxml.CalendarQuery) is not None: cal_query = True if report.childOfType( caldavxml.CalendarMultiGet) is not None: cal_multiget = True if report.childOfType( caldavxml.FreeBusyQuery) is not None: cal_freebusy = True if not cal_query: self.fail( "Expected CalDAV:CalendarQuery element; but got none." ) if not cal_multiget: self.fail( "Expected CalDAV:CalendarMultiGet element; but got none." ) if not cal_freebusy: self.fail( "Expected CalDAV:FreeBusyQuery element; but got none." ) return davXMLFromStream(response.stream).addCallback(got_xml) query = davxml.PropertyFind( davxml.PropertyContainer( caldavxml.SupportedCalendarData(), caldavxml.SupportedCalendarComponentSet(), davxml.SupportedReportSet(), ), ) request = SimpleStoreRequest( self, "PROPFIND", calendar_uri, headers=http_headers.Headers({"Depth": "0"}), authPrincipal=self.authPrincipal, ) request.stream = MemoryStream(query.toxml()) return self.send(request, propfind_cb)
def getSupportedComponentSet(self): return caldavxml.SupportedCalendarComponentSet(*[ caldavxml.CalendarComponent(name=item) for item in allowedSchedulingComponents ])
def test_make_calendar_with_props(self): """ Make calendar with properties (CalDAV-access-09, section 5.3.1.2) """ uri = "/calendars/users/user01/calendar_prop/" path = os.path.join(self.docroot, uri[1:]) if os.path.exists(path): rmdir(path) @inlineCallbacks def do_test(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code, )) resource = (yield request.locateResource(uri)) if not resource.isCalendarCollection(): self.fail("MKCALENDAR made non-calendar collection") for qname, value in ( (davxml.DisplayName.qname(), "Lisa's Events"), (caldavxml.CalendarDescription.qname(), "Calendar restricted to events."), ): stored = yield resource.readProperty(qname, None) stored = str(stored) if stored != value: self.fail( "MKCALENDAR failed to set property %s: %s != %s" % (qname, stored, value)) supported_components = yield resource.readProperty( caldavxml.SupportedCalendarComponentSet, None) supported_components = supported_components.children if len(supported_components) != 1: self.fail( "MKCALENDAR failed to set property %s: len(%s) != 1" % (caldavxml.SupportedCalendarComponentSet.qname(), supported_components)) if supported_components[0] != caldavxml.CalendarComponent( name="VEVENT"): self.fail("MKCALENDAR failed to set property %s: %s != %s" % (caldavxml.SupportedCalendarComponentSet.qname(), supported_components[0].toxml(), caldavxml.CalendarComponent(name="VEVENT").toxml())) tz = (yield resource.readProperty(caldavxml.CalendarTimeZone, None)) tz = tz.calendar() self.failUnless(tz.resourceType() == "VTIMEZONE") self.failUnless( tuple(tz.subcomponents())[0].propertyValue("TZID") == "US-Eastern") mk = caldavxml.MakeCalendar( davxml.Set( davxml.PropertyContainer( davxml.DisplayName("Lisa's Events"), caldavxml.CalendarDescription( "Calendar restricted to events."), # FIXME: lang=en caldavxml.SupportedCalendarComponentSet( caldavxml.CalendarComponent(name="VEVENT")), caldavxml.CalendarTimeZone("""BEGIN:VCALENDAR PRODID:-//Example Corp.//CalDAV Client//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:US-Eastern LAST-MODIFIED:19870101T000000Z BEGIN:STANDARD DTSTART:19671029T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZOFFSETFROM:-0400 TZOFFSETTO:-0500 TZNAME:Eastern Standard Time (US & Canada) END:STANDARD BEGIN:DAYLIGHT DTSTART:19870405T020000 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 TZOFFSETFROM:-0500 TZOFFSETTO:-0400 TZNAME:Eastern Daylight Time (US & Canada) END:DAYLIGHT END:VTIMEZONE END:VCALENDAR """)))) request = SimpleStoreRequest(self, "MKCALENDAR", uri, authPrincipal=self.authPrincipal) request.stream = MemoryStream(mk.toxml()) return self.send(request, do_test)
def setUp(self): """ Set up two stores to migrate between. """ yield super(HomeMigrationTests, self).setUp() yield self.buildStoreAndDirectory( extraUids=( u"home1", u"home2", u"home3", u"home_defaults", u"home_no_splits", u"home_splits", u"home_splits_shared", ) ) self.sqlStore = self.store # Add some files to the file store. self.filesPath = CachingFilePath(self.mktemp()) self.filesPath.createDirectory() fileStore = self.fileStore = CommonDataStore( self.filesPath, {"push": StubNotifierFactory()}, self.directory, True, True ) self.upgrader = UpgradeToDatabaseStep(self.fileStore, self.sqlStore) requirements = CommonTests.requirements extras = deriveValue(self, "extraRequirements", lambda t: {}) requirements = self.mergeRequirements(requirements, extras) yield populateCalendarsFrom(requirements, fileStore) md5s = CommonTests.md5s yield resetCalendarMD5s(md5s, fileStore) self.filesPath.child("calendars").child( "__uids__").child("ho").child("me").child("home1").child( ".some-extra-data").setContent("some extra data") requirements = ABCommonTests.requirements yield populateAddressBooksFrom(requirements, fileStore) md5s = ABCommonTests.md5s yield resetAddressBookMD5s(md5s, fileStore) self.filesPath.child("addressbooks").child( "__uids__").child("ho").child("me").child("home1").child( ".some-extra-data").setContent("some extra data") # Add some properties we want to check get migrated over txn = self.fileStore.newTransaction() home = yield txn.calendarHomeWithUID("home_defaults") cal = yield home.calendarWithName("calendar_1") props = cal.properties() props[PropertyName.fromElement(caldavxml.SupportedCalendarComponentSet)] = caldavxml.SupportedCalendarComponentSet( caldavxml.CalendarComponent(name="VEVENT"), caldavxml.CalendarComponent(name="VTODO"), ) props[PropertyName.fromElement(element.ResourceType)] = element.ResourceType( element.Collection(), caldavxml.Calendar(), ) props[PropertyName.fromElement(customxml.GETCTag)] = customxml.GETCTag.fromString("foobar") inbox = yield home.calendarWithName("inbox") props = inbox.properties() props[PropertyName.fromElement(customxml.CalendarAvailability)] = customxml.CalendarAvailability.fromString(str(self.av1)) props[PropertyName.fromElement(caldavxml.ScheduleDefaultCalendarURL)] = caldavxml.ScheduleDefaultCalendarURL( element.HRef.fromString("/calendars/__uids__/home_defaults/calendar_1"), ) yield txn.commit()