def test_Quota_DELETE(self): """ Quota change on DELETE """ dst_uri = "/dst" def checkPUTResult(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("Incorrect response code for PUT (%s != %s)" % (response.code, responsecode.CREATED)) def doDelete(_ignore): def checkDELETEResult(response): response = IResponse(response) if response.code != responsecode.NO_CONTENT: self.fail("Incorrect response code for PUT (%s != %s)" % (response.code, responsecode.NO_CONTENT)) return self.checkQuota(0) request = SimpleRequest(self.site, "DELETE", dst_uri) return self.send(request, checkDELETEResult) d = self.checkQuota(100) d.addCallback(doDelete) return d request = SimpleRequest(self.site, "PUT", dst_uri) request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), "data", "quota_100.txt"), "rb")) return self.send(request, checkPUTResult)
def test_Quota_Bad_Adjustment(self): """ Quota adjustment too much """ dst_uri = "/dst" def checkPUTResult(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("Incorrect response code for PUT (%s != %s)" % (response.code, responsecode.CREATED)) def doBadAdjustment(_ignore): def checkAdjustmentResult(_ignore): return self.checkQuota(100) d = self.site.resource.quotaSizeAdjust(None, -200) d.addCallback(checkAdjustmentResult) return d d = self.checkQuota(100) d.addCallback(doBadAdjustment) return d request = SimpleRequest(self.site, "PUT", dst_uri) request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), "data", "quota_100.txt"), "rb")) return self.send(request, checkPUTResult)
def addEventsDir(testCase, eventsDir, uri): """ Add events to a L{HomeTestCase} from a directory. @param testCase: The test case to add events to. @type testCase: L{HomeTestCase} @param eventsDir: A directory full of events. @type eventsDir: L{FilePath} @param uri: The URI-path of the calendar to insert events into. @type uri: C{str} @return: a L{Deferred} which fires with the number of added calendar object resources. """ count = 0 for child in eventsDir.children(): count += 1 if child.basename().split(".")[-1] != "ics": continue request = SimpleRequest(testCase.site, "PUT", uri + "/" + child.basename()) request.stream = MemoryStream(child.getContent()) yield testCase.send(request) returnValue(count)
def do_report(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCOL failed: %s" % (response.code,)) # Add vCards to addressbook # We're cheating by simply copying the files in for filename in os.listdir(self.vcards_dir): if os.path.splitext(filename)[1] != ".vcf": continue path = os.path.join(self.vcards_dir, filename) shutil.copy(path, addressbook_path) # Delete the index because we cheated index_path = os.path.join(addressbook_path, db_basename) if os.path.isfile(index_path): os.remove(index_path) request = SimpleRequest(self.site, "REPORT", addressbook_uri) request.stream = MemoryStream(query.toxml()) def do_test(response): response = IResponse(response) if response.code != responsecode.MULTI_STATUS: self.fail("REPORT failed: %s" % (response.code,)) return davXMLFromStream(response.stream).addCallback(got_xml) return self.send(request, do_test)
def do_report(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code,)) # Add holiday events to calendar # We're cheating by simply copying the files in for filename in os.listdir(self.holidays_dir): if os.path.splitext(filename)[1] != ".ics": continue path = os.path.join(self.holidays_dir, filename) shutil.copy(path, calendar_path) # Delete the index because we cheated index_path = os.path.join(calendar_path, db_basename) if os.path.isfile(index_path): os.remove(index_path) request = SimpleRequest(self.site, "REPORT", calendar_uri) request.stream = MemoryStream(query.toxml()) def do_test(response): response = IResponse(response) if response.code != responsecode.OK: self.fail("REPORT failed: %s" % (response.code,)) return Component.fromIStream(response.stream).addCallback(got_calendar) return self.send(request, do_test, calendar_path)
def mkcalendar_cb(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code,)) if not calPath.isdir(): self.fail("MKCALENDAR did not create a collection") ds = [] c = 0 for stream, response_code in work: def put_cb(response, stream=stream, response_code=response_code): response = IResponse(response) if response.code != response_code: self.fail("Incorrect response to %s: %s (!= %s)" % (what, response.code, response_code)) dst_uri = "/".join([calendar_uri, "dst%d.ics" % (c,)]) request = SimpleRequest(self.site, "PUT", dst_uri) request.headers.setHeader("if-none-match", "*") request.headers.setHeader("content-type", MimeType("text", "calendar")) request.stream = stream ds.append(self.send(request, put_cb)) c += 1 return DeferredList(ds)
def _simple_PROPPATCH(self, patch, prop, expected_code, what): def check_result(response): response = IResponse(response) if response.code != responsecode.MULTI_STATUS: self.fail("Incorrect response code for PROPPATCH (%s != %s)" % (response.code, responsecode.MULTI_STATUS)) return davXMLFromStream(response.stream).addCallback(check_xml) def check_xml(doc): response = doc.root_element.childOfType(davxml.Response) propstat = response.childOfType(davxml.PropertyStatus) self.failUnless( response.childOfType(davxml.HRef) == "/", "Incorrect response URI: %s != /" % (response.childOfType(davxml.HRef),) ) self.failIf( propstat.childOfType(davxml.PropertyContainer).childOfType(prop) is None, "Not a %s in PROPPATCH property status: %s" % (prop.sname(), propstat.toxml()) ) self.failUnless( propstat.childOfType(davxml.Status).code == expected_code, "Incorrect status code for PROPPATCH %s: %s != %s" % (what, propstat.childOfType(davxml.Status).code, expected_code) ) request = SimpleRequest(self.site, "PROPPATCH", "/") request.stream = MemoryStream(patch.toxml()) return self.send(request, check_result)
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) container = response.childOfType(davxml.PropertyStatus).childOfType(davxml.PropertyContainer) # # Check CalDAV:supported-calendar-component-set # supported_components = container.childOfType(caldavxml.SupportedCalendarComponentSet) if supported_components: self.fail("CalDAV:supported-calendar-component-set element was returned; but should be hidden.") # # Check CalDAV:supported-calendar-data # supported_calendar = container.childOfType(caldavxml.SupportedCalendarData) if supported_calendar: self.fail("CalDAV:supported-calendar-data elementwas returned; but should be hidden.") # # Check DAV:supported-report-set # supported_reports = container.childOfType(davxml.SupportedReportSet) if supported_reports: self.fail("DAV:supported-report-set element was returned; but should be hidden..") return davXMLFromStream(response.stream).addCallback(got_xml) query = davxml.PropertyFind( davxml.AllProperties(), ) request = SimpleRequest( self.site, "PROPFIND", calendar_uri, headers=http_headers.Headers({"Depth":"0"}), ) request.stream = MemoryStream(query.toxml()) return self.send(request, propfind_cb)
def work(): for code in ( responsecode.CREATED, responsecode.PRECONDITION_FAILED, responsecode.NO_CONTENT, responsecode.PRECONDITION_FAILED, responsecode.NO_CONTENT, responsecode.CREATED, ): def checkResult(response, code=code): response = IResponse(response) if response.code != code: self.fail("Incorrect response code for PUT (%s != %s)" % (response.code, code)) def onError(f): f.trap(HTTPError) return checkResult(f.value.response) request = SimpleRequest(self.site, "PUT", dst_uri) request.stream = FileStream(file(__file__, "rb")) if code == responsecode.CREATED: if os.path.isfile(dst_path): os.remove(dst_path) request.headers.setHeader("if-none-match", ("*",)) elif code == responsecode.PRECONDITION_FAILED: request.headers.setHeader("if-none-match", ("*",)) yield (request, (checkResult, onError))
def mkcalendar_cb(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code,)) def put_cb(response): response = IResponse(response) if response.code != responsecode.FORBIDDEN: self.fail("Incorrect response to dot file PUT: %s" % (response.code,)) stream = self.dataPath.child( "Holidays").child( "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics" ).open() try: calendar = str(Component.fromStream(stream)) finally: stream.close() event_uri = "/".join([calendar_uri, ".event.ics"]) request = SimpleRequest(self.site, "PUT", event_uri) request.headers.setHeader("content-type", MimeType("text", "calendar")) request.stream = MemoryStream(calendar) return self.send(request, put_cb)
def work(): for method in ("GET", "REPORT"): if method == "GET": ok = responsecode.OK elif method == "REPORT": ok = responsecode.MULTI_STATUS else: raise AssertionError("We shouldn't be here. (method = %r)" % (method,)) for name, code in ( ("none" , responsecode.FORBIDDEN), ("read" , ok), ("read-write" , ok), ("unlock" , responsecode.FORBIDDEN), ("all" , ok), ): path = os.path.join(self.docroot, name) request = SimpleRequest(self.site, method, "/" + name) if method == "REPORT": request.stream = MemoryStream(element.PrincipalPropertySearch().toxml()) _add_auth_header(request) def test(response, code=code, path=path): if response.code != code: return self.oops(request, response, code, method, name) yield (request, test)
def _doPOST(self, body, resultcode = responsecode.OK): request = SimpleRequest(self.site, "POST", "/calendar/") request.headers.setHeader("content-type", MimeType("text", "xml")) request.stream = MemoryStream(body) response = (yield self.send(request, None)) self.assertEqual(response.code, resultcode) returnValue(response)
def work(): for which in (davxml.AllProperties(), davxml.PropertyName()): query = davxml.PropertyFind(which) request = SimpleRequest(self.site, "PROPFIND", "/") request.headers.setHeader("depth", "0") request.stream = MemoryStream(query.toxml()) yield (request, check_result(which))
def test_free_busy_set_prop(self): """ Test for PROPFIND on Inbox with missing calendar-free-busy-set property. """ inbox_uri = "/inbox/" 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) == inbox_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:calendar-free-busy-set # free_busy_set = container.childOfType(caldavxml.CalendarFreeBusySet) if not free_busy_set: self.fail("Expected CalDAV:calendar-free-busy-set element; but got none.") if not free_busy_set.children: self.fail("Expected non-empty CalDAV:calendar-free-busy-set element.") return davXMLFromStream(response.stream).addCallback(got_xml) query = davxml.PropertyFind( davxml.PropertyContainer( caldavxml.CalendarFreeBusySet(), ), ) request = SimpleRequest( self.site, "PROPFIND", inbox_uri, headers=http_headers.Headers({"Depth": "0"}), ) request.stream = MemoryStream(query.toxml()) return self.send(request, propfind_cb)
def test_REPORT_no_body(self): """ REPORT request with no body """ def do_test(response): response = IResponse(response) if response.code != responsecode.BAD_REQUEST: self.fail("Unexpected response code for REPORT with no body: %s" % (response.code,)) request = SimpleRequest(self.site, "REPORT", "/") request.stream = MemoryStream("") return self.send(request, do_test)
def test_PUT_no_parent(self): """ PUT with no parent """ dst_uri = "/put/no/parent" def checkResult(response): response = IResponse(response) if response.code != responsecode.CONFLICT: self.fail("Incorrect response code for PUT with no parent (%s != %s)" % (response.code, responsecode.CONFLICT)) request = SimpleRequest(self.site, "PUT", dst_uri) request.stream = FileStream(file(__file__, "rb")) return self.send(request, checkResult)
def test_Quota_PUT(self): """ Quota change on PUT """ dst_uri = "/dst" def checkResult(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("Incorrect response code for PUT (%s != %s)" % (response.code, responsecode.CREATED)) return self.checkQuota(100) request = SimpleRequest(self.site, "PUT", dst_uri) request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), "data", "quota_100.txt"), "rb")) return self.send(request, checkResult)
def work(): dst_uri = "/dst" for name in os.listdir(self.docroot): if name == "dst": continue path = os.path.join(self.docroot, name) # Can't really PUT something you can't read if not os.path.isfile(path): continue def do_test(response): checkResult(response, path) request = SimpleRequest(self.site, "PUT", dst_uri) request.stream = FileStream(file(path, "rb")) yield (request, do_test)
def test_REPORT_unknown(self): """ Unknown/bogus report type """ def do_test(response): response = IResponse(response) if response.code != responsecode.FORBIDDEN: self.fail("Unexpected response code for unknown REPORT: %s" % (response.code,)) class GoofyReport (davxml.WebDAVUnknownElement): namespace = "GOOFY:" name = "goofy-report" def __init__(self): super(GoofyReport, self).__init__() request = SimpleRequest(self.site, "REPORT", "/") request.stream = MemoryStream(GoofyReport().toxml()) return self.send(request, do_test)
def test_Quota_PUT(self): """ Quota change on PUT """ dst_uri = "/dst" self.site.resource.setQuotaRoot(None, 90) def checkResult(response): response = IResponse(response) if response.code != responsecode.INSUFFICIENT_STORAGE_SPACE: self.fail("Incorrect response code for PUT (%s != %s)" % (response.code, responsecode.INSUFFICIENT_STORAGE_SPACE)) return self.checkQuota(0) request = SimpleRequest(self.site, "PUT", dst_uri) request.stream = FileStream(file(os.path.join(os.path.dirname(__file__), "data", "quota_100.txt"), "rb")) return self.send(request, checkResult)
def work(): for name, code in ( ("none" , responsecode.FORBIDDEN), ("read" , responsecode.FORBIDDEN), ("read-write" , responsecode.MULTI_STATUS), ("unlock" , responsecode.FORBIDDEN), ("all" , responsecode.MULTI_STATUS), ): path = os.path.join(self.docroot, name) request = SimpleRequest(self.site, "PROPPATCH", "/" + name) request.stream = MemoryStream( element.WebDAVDocument(element.PropertyUpdate()).toxml() ) _add_auth_header(request) def test(response, code=code, path=path): if response.code != code: return self.oops(request, response, code, "PROPPATCH", name) yield (request, test)
def mkcalendar_cb(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code,)) c = 0 for stream, response_code in work: dst_uri = "/".join([calendar_uri, "dst%d.ics" % (c,)]) request = SimpleRequest(self.site, "PUT", dst_uri) request.headers.setHeader("if-none-match", "*") request.headers.setHeader("content-type", MimeType("text", "calendar")) request.stream = stream response = yield self.send(request) response = IResponse(response) if response.code != response_code: self.fail("Incorrect response to %s: %s (!= %s)" % (what, response.code, response_code)) c += 1
def test_MKCOL_invalid_body(self): """ MKCOL request with invalid request body (Any body at all is invalid in our implementation; there is no such thing as a valid body.) """ path, uri = self.mkdtemp("collection") rmdir(path) def check_result(response): response = IResponse(response) if response.code != responsecode.UNSUPPORTED_MEDIA_TYPE: self.fail("MKCOL response %s != %s" % (response.code, responsecode.UNSUPPORTED_MEDIA_TYPE)) if os.path.isdir(path): self.fail("MKCOL incorrectly created directory %s" % (path,)) request = SimpleRequest(self.site, "MKCOL", uri) request.stream = MemoryStream("This is not a valid MKCOL request body.") return self.send(request, check_result)
def free_busy_query(self, calendar_uri, query, got_calendar): request = SimpleRequest(self.site, "MKCALENDAR", calendar_uri) response = yield self.send(request) response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code,)) yield addEventsDir(self, FilePath(self.holidays_dir), calendar_uri) request = SimpleRequest(self.site, "REPORT", calendar_uri) request.stream = MemoryStream(query.toxml()) response = yield self.send(request) response = IResponse(response) if response.code != responsecode.OK: self.fail("REPORT failed: %s" % (response.code,)) result = yield Component.fromIStream(response.stream).addCallback( got_calendar ) returnValue(result)
def calendar_query(self, calendar_uri, query, got_xml): response = yield self.send(SimpleRequest(self.site, "MKCALENDAR", calendar_uri)) response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code,)) # Add holiday events to calendar yield addEventsDir(self, FilePath(self.holidays_dir), calendar_uri) request = SimpleRequest(self.site, "REPORT", calendar_uri) request.stream = MemoryStream(query.toxml()) response = yield self.send(request) response = IResponse(response) if response.code != responsecode.MULTI_STATUS: self.fail("REPORT failed: %s" % (response.code,)) returnValue( (yield davXMLFromStream(response.stream).addCallback(got_xml)) )
def do_report(response): if not no_init: response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code,)) if data: for filename, icaldata in data.iteritems(): path = os.path.join(calendar_path, filename + ".ics") f = open(path, "w") f.write(icaldata) f.close() else: # Add holiday events to calendar # We're cheating by simply copying the files in for filename in os.listdir(self.holidays_dir): if os.path.splitext(filename)[1] != ".ics": continue path = os.path.join(self.holidays_dir, filename) shutil.copy(path, calendar_path) # Delete the index because we cheated index_path = os.path.join(calendar_path, db_basename) if os.path.isfile(index_path): os.remove(index_path) request = SimpleRequest(self.site, "REPORT", calendar_uri) request.stream = MemoryStream(query.toxml()) def do_test(response): response = IResponse(response) if response.code != responsecode.MULTI_STATUS: self.fail("REPORT failed: %s" % (response.code,)) return davXMLFromStream(response.stream).addCallback(got_xml) return self.send(request, do_test)
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", "VTODO", "VFREEBUSY")) 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 != "text/calendar": 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( davxml.GETETag(), caldavxml.SupportedCalendarData(), caldavxml.SupportedCalendarComponentSet(), davxml.SupportedReportSet(), ), ) request = SimpleRequest(self.site, "PROPFIND", calendar_uri) request.stream = MemoryStream(query.toxml()) return self.send(request, propfind_cb)
def test_PROPPATCH_basic(self): """ PROPPATCH """ # FIXME: # Do PROPFIND to make sure it's still there # Test nonexistant resource # Test None namespace in property def check_patch_response(response): response = IResponse(response) if response.code != responsecode.MULTI_STATUS: self.fail("Incorrect response code for PROPFIND (%s != %s)" % (response.code, responsecode.MULTI_STATUS)) content_type = response.headers.getHeader("content-type") if content_type not in (http_headers.MimeType("text", "xml"), http_headers.MimeType("application", "xml")): self.fail("Incorrect content-type for PROPPATCH response (%r not in %r)" % (content_type, (http_headers.MimeType("text", "xml"), http_headers.MimeType("application", "xml")))) return davXMLFromStream(response.stream).addCallback(check_patch_xml) def check_patch_xml(doc): multistatus = doc.root_element if not isinstance(multistatus, davxml.MultiStatus): self.fail("PROPFIND response XML root element is not multistatus: %r" % (multistatus,)) # Requested a property change one resource, so there should be exactly one response response = multistatus.childOfType(davxml.Response) # Should have a response description (its contents are arbitrary) response.childOfType(davxml.ResponseDescription) # Requested property change was on / self.failUnless( response.childOfType(davxml.HRef) == "/", "Incorrect response URI: %s != /" % (response.childOfType(davxml.HRef),) ) # Requested one property change, so there should be exactly one property status propstat = response.childOfType(davxml.PropertyStatus) # And the contained property should be a SpiffyProperty self.failIf( propstat.childOfType(davxml.PropertyContainer).childOfType(SpiffyProperty) is None, "Not a SpiffyProperty in PROPPATCH property status: %s" % (propstat.toxml()) ) # And the status should be 200 self.failUnless( propstat.childOfType(davxml.Status).code == responsecode.OK, "Incorrect status code for PROPPATCH of property %s: %s != %s" % (propstat.childOfType(davxml.PropertyContainer).toxml(), propstat.childOfType(davxml.Status).code, responsecode.OK) ) patch = davxml.PropertyUpdate( davxml.Set( davxml.PropertyContainer( SpiffyProperty.fromString("This is a spiffy resource.") ) ) ) request = SimpleRequest(self.site, "PROPPATCH", "/") request.stream = MemoryStream(patch.toxml()) return self.send(request, check_patch_response)
def test_PROPFIND_basic(self): """ PROPFIND request """ def check_result(response): response = IResponse(response) if response.code != responsecode.MULTI_STATUS: self.fail("Incorrect response code for PROPFIND (%s != %s)" % (response.code, responsecode.MULTI_STATUS)) content_type = response.headers.getHeader("content-type") if content_type not in (http_headers.MimeType("text", "xml"), http_headers.MimeType("application", "xml")): self.fail("Incorrect content-type for PROPFIND response (%r not in %r)" % (content_type, (http_headers.MimeType("text", "xml"), http_headers.MimeType("application", "xml")))) return davXMLFromStream(response.stream).addCallback(check_xml) def check_xml(doc): multistatus = doc.root_element if not isinstance(multistatus, davxml.MultiStatus): self.fail("PROPFIND response XML root element is not multistatus: %r" % (multistatus,)) for response in multistatus.childrenOfType(davxml.PropertyStatusResponse): if response.childOfType(davxml.HRef) == "/": 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("PROPFIND failed (status %s) to locate live properties: %s" % (status.code, properties)) properties_to_find = [p.qname() for p in self.liveProperties()] for property in properties: qname = property.qname() if qname in properties_to_find: properties_to_find.remove(qname) else: self.fail("PROPFIND found property we didn't ask for: %r" % (property,)) if properties_to_find: self.fail("PROPFIND failed to find properties: %r" % (properties_to_find,)) break else: self.fail("No response for URI /") query = davxml.PropertyFind(davxml.PropertyContainer(*self.liveProperties())) request = SimpleRequest(self.site, "PROPFIND", "/") depth = "1" if depth is not None: request.headers.setHeader("depth", depth) request.stream = MemoryStream(query.toxml()) return self.send(request, check_result)
def test_make_calendar_with_props(self): """ Make calendar with properties (CalDAV-access-09, section 5.3.1.2) """ uri = "/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 = SimpleRequest(self.site, "MKCALENDAR", uri) request.stream = MemoryStream(mk.toxml()) return self.send(request, do_test)