예제 #1
0
    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)
예제 #2
0
    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)
예제 #7
0
파일: test_prop.py 프로젝트: jrossi/twext
    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)
예제 #8
0
        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)
예제 #9
0
파일: test_put.py 프로젝트: jrossi/twext
        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)
예제 #11
0
        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)
예제 #12
0
    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)
예제 #13
0
파일: test_prop.py 프로젝트: jrossi/twext
        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))
예제 #14
0
    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)
예제 #15
0
파일: test_report.py 프로젝트: jrossi/twext
    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)
예제 #16
0
파일: test_put.py 프로젝트: jrossi/twext
    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)
예제 #17
0
    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)
예제 #18
0
파일: test_put.py 프로젝트: jrossi/twext
        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)
예제 #19
0
파일: test_report.py 프로젝트: jrossi/twext
    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)
예제 #20
0
    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)
예제 #21
0
        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
예제 #23
0
    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))
        )
예제 #26
0
        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)
예제 #27
0
        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)
예제 #28
0
파일: test_prop.py 프로젝트: jrossi/twext
    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)
예제 #29
0
파일: test_prop.py 프로젝트: jrossi/twext
    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)