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 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)
Esempio n. 3
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)
Esempio n. 4
0
        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 test_pick_default_addressbook(self):
        """
        Make calendar
        """
        

        request = SimpleRequest(self.site, "GET", "/addressbooks/users/wsanchez/")
        home = yield request.locateResource("/addressbooks/users/wsanchez")

        # default property initially not present
        try:
            home.readDeadProperty(carddavxml.DefaultAddressBookURL)
        except HTTPError:
            pass
        else:
            self.fail("carddavxml.DefaultAddressBookURL is not empty")

        yield home.pickNewDefaultAddressBook(request)

        try:
            default = home.readDeadProperty(carddavxml.DefaultAddressBookURL)
        except HTTPError:
            self.fail("carddavxml.DefaultAddressBookURL is not present")
        else:
            self.assertEqual(str(default.children[0]), "/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/addressbook/")

        request._newStoreTransaction.abort()
    def test_fix_shared_default(self):
        """
        Make calendar
        """
        

        request = SimpleRequest(self.site, "GET", "/addressbooks/users/wsanchez/")
        home = yield request.locateResource("/addressbooks/users/wsanchez")

        # Create a new default adbk
        newadbk = yield request.locateResource("/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newadbk/")
        yield newadbk.createAddressBookCollection()
        home.writeDeadProperty(carddavxml.DefaultAddressBookURL(
            HRef("/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newadbk/")
        ))
        try:
            default = yield home.readProperty(carddavxml.DefaultAddressBookURL, request)
        except HTTPError:
            self.fail("carddavxml.DefaultAddressBookURL is not present")
        else:
            self.assertEqual(str(default.children[0]), "/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newadbk/")
        
        # Force the new calendar to think it is a sharee collection
        newadbk._isShareeCollection = True
        
        try:
            default = yield home.readProperty(carddavxml.DefaultAddressBookURL, request)
        except HTTPError:
            self.fail("carddavxml.DefaultAddressBookURL is not present")
        else:
            self.assertEqual(str(default.children[0]), "/addressbooks/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/addressbook/")

        request._newStoreTransaction.abort()
        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)
Esempio n. 8
0
    def test_free_busy_set_same(self):
        """
        Test that calendar-free-busy-set has the correct value and can be reset to the same.
        """

        request = SimpleRequest(self.site, "GET", "/calendars/users/user01/inbox/")
        inbox = yield request.locateResource("/calendars/users/user01/inbox/")
        self.assertTrue((yield inbox.hasProperty(caldavxml.CalendarFreeBusySet, request)))
        prop = (yield inbox.readProperty(caldavxml.CalendarFreeBusySet, request))
        self.assertEqual(prop.children[0], davxml.HRef("/calendars/__uids__/user01/calendar/"))

        newfbset = set()
        newfbset.add("/calendars/users/user01/calendar/")
        newset = caldavxml.CalendarFreeBusySet(*[davxml.HRef(url) for url in newfbset])

        yield inbox.writeProperty(newset, request)
        yield request._newStoreTransaction.commit()

        request = SimpleRequest(self.site, "GET", "/calendars/users/user01/inbox/")
        inbox = yield request.locateResource("/calendars/users/user01/inbox/")
        prop = (yield inbox.readProperty(caldavxml.CalendarFreeBusySet, request))
        self.assertEqual(prop.children[0], davxml.HRef("/calendars/__uids__/user01/calendar/"))
        yield request._newStoreTransaction.commit()
        calendar = yield request.locateResource("/calendars/__uids__/user01/calendar/")
        self.assertTrue(calendar._newStoreObject.isUsedForFreeBusy())
    def test_missing_default_vtodo_calendar(self):
        """
        Test that pickNewDefaultCalendar will create a missing default tasks calendar.
        """

        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/")
        home = yield request.locateResource("/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # default property initially not present
        try:
            inbox.readDeadProperty(customxml.ScheduleDefaultTasksURL)
        except HTTPError:
            pass
        else:
            self.fail("caldavxml.ScheduleDefaultTasksURL is not empty")

        # Forcibly remove the one we need
        yield home._newStoreHome.removeChildWithName("tasks")
        names = [calendarName for calendarName in (yield home._newStoreHome.listCalendars())]
        self.assertTrue("tasks" not in names)

        yield inbox.pickNewDefaultCalendar(request, tasks=True)

        try:
            default = inbox.readDeadProperty(customxml.ScheduleDefaultTasksURL)
        except HTTPError:
            self.fail("caldavxml.ScheduleDefaultTasksURL is not present")
        else:
            self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/tasks")

        request._newStoreTransaction.abort()
Esempio n. 10
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)
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 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)
Esempio n. 13
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 test_set_default_vevent_other(self):
        """
        Test that the default URL can be set to another VEVENT calendar
        """

        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # default property not present
        try:
            inbox.readDeadProperty(caldavxml.ScheduleDefaultCalendarURL)
        except HTTPError:
            pass
        else:
            self.fail("caldavxml.ScheduleDefaultCalendarURL is not empty")

        # Create a new default calendar
        newcalendar = yield request.locateResource("/calendars/users/wsanchez/newcalendar")
        yield newcalendar.createCalendarCollection()
        yield newcalendar.setSupportedComponents(("VEVENT",))
        request._newStoreTransaction.commit()

        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")
        yield inbox.writeProperty(caldavxml.ScheduleDefaultCalendarURL(davxml.HRef("/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newcalendar")), request)

        try:
            default = inbox.readDeadProperty(caldavxml.ScheduleDefaultCalendarURL)
        except HTTPError:
            self.fail("caldavxml.ScheduleDefaultCalendarURL is not present")
        else:
            self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newcalendar")

        request._newStoreTransaction.commit()
        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)
Esempio n. 16
0
    def test_renderPrivileges(self):
        """
        Verify that a directory listing includes children which you
        don't have access to.
        """
        request = SimpleRequest(self.site, "GET", "/")

        def setEmptyACL(resource):
            resource.setAccessControlList(davxml.ACL()) # Empty ACL = no access
            return resource

        def renderRoot(_):
            d = request.locateResource("/")
            d.addCallback(lambda r: r.render(request))

            return d

        def assertListing(response):
            data = []
            d = readStream(response.stream, lambda s: data.append(str(s)))
            d.addCallback(lambda _: self.failIf(
                'dir2/' not in "".join(data),
                "'dir2' expected in listing: %r" % (data,)
            ))
            return d

        d = request.locateResource("/dir2")
        d.addCallback(setEmptyACL)
        d.addCallback(renderRoot)
        d.addCallback(assertListing)

        return d
    def _checkPrivileges(self, resource, url, principal, privilege, allowed):
        request = SimpleRequest(self.site, "GET", "/")

        def gotResource(resource):
            d = resource.checkPrivileges(request, (privilege,), principal=davxml.Principal(principal))
            if allowed:
                def onError(f):
                    f.trap(AccessDeniedError)
                    #print(resource.readDeadProperty(davxml.ACL).toxml())
                    self.fail("%s should have %s privilege on %r" % (principal, privilege.sname(), resource))
                d.addErrback(onError)
            else:
                def onError(f):
                    f.trap(AccessDeniedError)
                def onSuccess(_):
                    #print(resource.readDeadProperty(davxml.ACL).toxml())
                    self.fail("%s should not have %s privilege on %r" % (principal, privilege.sname(), resource))
                d.addCallback(onSuccess)
                d.addErrback(onError)
            def _commit(ignore):
                maybeCommit(request)
            d.addBoth(_commit)
            return d

        d = request.locateResource(url)
        d.addCallback(gotResource)
        return d
    def test_pick_default_vtodo_calendar(self):
        """
        Test that pickNewDefaultCalendar will choose the correct tasks calendar.
        """

        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # default property initially not present
        try:
            inbox.readDeadProperty(customxml.ScheduleDefaultTasksURL)
        except HTTPError:
            pass
        else:
            self.fail("customxml.ScheduleDefaultTasksURL is not empty")

        yield inbox.pickNewDefaultCalendar(request, tasks=True)

        try:
            default = inbox.readDeadProperty(customxml.ScheduleDefaultTasksURL)
        except HTTPError:
            self.fail("customxml.ScheduleDefaultTasksURL is not present")
        else:
            self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/tasks")

        request._newStoreTransaction.abort()
    def test_fix_shared_default(self):
        """
        Make calendar
        """

        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")

        # Create a new default calendar
        newcalendar = yield request.locateResource("/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newcalendar")
        yield newcalendar.createCalendarCollection()
        inbox.writeDeadProperty(caldavxml.ScheduleDefaultCalendarURL(
            davxml.HRef("/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newcalendar")
        ))
        try:
            default = yield inbox.readProperty(caldavxml.ScheduleDefaultCalendarURL, request)
        except HTTPError:
            self.fail("caldavxml.ScheduleDefaultCalendarURL is not present")
        else:
            self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/newcalendar")

        # Force the new calendar to think it is a virtual share
        newcalendar._isShareeCollection = True

        try:
            default = yield inbox.readProperty(caldavxml.ScheduleDefaultCalendarURL, request)
        except HTTPError:
            self.fail("caldavxml.ScheduleDefaultCalendarURL is not present")
        else:
            self.assertEqual(str(default.children[0]), "/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/calendar")

        request._newStoreTransaction.abort()
Esempio n. 20
0
    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 _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 test_ExistentInbox(self):

        def _response(resource):
            if resource is None:
                self.fail("Incorrect response to GET on existent inbox.")

        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/inbox/")
        d = request.locateResource(request.uri)
        d.addCallback(_response)
Esempio n. 23
0
        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_NonExistentCalendarHome(self):

        def _response(resource):
            if resource is not None:
                self.fail("Incorrect response to GET on non-existent calendar home.")

        request = SimpleRequest(self.site, "GET", "/calendars/users/12345/")
        d = request.locateResource(request.uri)
        d.addCallback(_response)
    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_CalendarTranspProperty(self):

        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/calendar/")

        # Get calendar first
        calendar = (yield request.locateResource("/calendars/users/wsanchez/calendar/"))
        if calendar is None:
            self.fail("Incorrect response to GET on existent calendar.")

        inbox = (yield request.locateResource("/calendars/users/wsanchez/inbox/"))
        if inbox is None:
            self.fail("Incorrect response to GET on existent inbox.")
        
        # Provisioned calendar has default opaque property
        transp = (yield calendar.hasProperty(caldavxml.ScheduleCalendarTransp, request))
        self.assertTrue(transp)

        transp = (yield calendar.readProperty(caldavxml.ScheduleCalendarTransp, request))
        self.assertEqual(transp, caldavxml.ScheduleCalendarTransp(caldavxml.Opaque()))

        # Inbox property lists the default calendar
        fbset = (yield inbox.hasProperty(caldavxml.CalendarFreeBusySet, request))
        self.assertTrue(fbset)

        fbset = (yield inbox.readProperty(caldavxml.CalendarFreeBusySet, request))
        self.assertEqual(fbset, caldavxml.CalendarFreeBusySet(
            davxml.HRef.fromString("/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/calendar"),
        ))

        # Now remove the dead property to simulate the old calendar server state with
        # a calendar listed in the fbset
        yield calendar.removeDeadProperty(caldavxml.ScheduleCalendarTransp)
        fbset = (yield inbox.readProperty(caldavxml.CalendarFreeBusySet, request))
        self.assertEqual(fbset, caldavxml.CalendarFreeBusySet(
            davxml.HRef.fromString("/calendars/__uids__/6423F94A-6B76-4A3A-815B-D52CFD77935D/calendar"),
        ))

        # Calendar has opaque property derived from inbox
        transp = (yield calendar.hasProperty(caldavxml.ScheduleCalendarTransp, request))
        self.assertTrue(transp)

        transp = (yield calendar.readProperty(caldavxml.ScheduleCalendarTransp, request))
        self.assertEqual(transp, caldavxml.ScheduleCalendarTransp(caldavxml.Opaque()))

        # Now remove the dead property and the inbox fbset item to simulate the old calendar server state
        yield calendar.removeDeadProperty(caldavxml.ScheduleCalendarTransp)
        yield inbox.removeDeadProperty(caldavxml.CalendarFreeBusySet)

        # Calendar has transp property derived from inbox
        transp = (yield calendar.hasProperty(caldavxml.ScheduleCalendarTransp, request))
        self.assertTrue(transp)

        transp = (yield calendar.readProperty(caldavxml.ScheduleCalendarTransp, request))
        self.assertEqual(transp, caldavxml.ScheduleCalendarTransp(caldavxml.Transparent()))
    def test_is_default_calendar(self):
        """
        Test .isDefaultCalendar() returns the proper class or None.
        """

        # Create a new non-default calendar
        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/")
        newcalendar = yield request.locateResource("/calendars/users/wsanchez/newcalendar")
        yield newcalendar.createCalendarCollection()
        yield newcalendar.setSupportedComponents(("VEVENT",))
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")
        yield inbox.pickNewDefaultCalendar(request)
        request._newStoreTransaction.commit()

        request = SimpleRequest(self.site, "GET", "/calendars/users/wsanchez/")
        inbox = yield request.locateResource("/calendars/users/wsanchez/inbox")
        calendar = yield request.locateResource("/calendars/users/wsanchez/calendar")
        newcalendar = yield request.locateResource("/calendars/users/wsanchez/newcalendar")
        tasks = yield request.locateResource("/calendars/users/wsanchez/tasks")

        result = yield inbox.isDefaultCalendar(request, calendar)
        self.assertEqual(result, caldavxml.ScheduleDefaultCalendarURL)

        result = yield inbox.isDefaultCalendar(request, newcalendar)
        self.assertEqual(result, None)

        result = yield inbox.isDefaultCalendar(request, tasks)
        self.assertEqual(result, customxml.ScheduleDefaultTasksURL)

        request._newStoreTransaction.commit()
    def test_testImplicitSchedulingPUT_FixScheduleState(self):
        """
        Test that testImplicitSchedulingPUT will fix an old cached schedule object state by
        re-evaluating the calendar data.
        """

        request = SimpleRequest(self.site, "PUT", "/calendar/1.ics")
        calresource = yield request.locateResource("/calendar/1.ics")
        self.assertEqual(calresource.isScheduleObject, None)
        calresource.isScheduleObject = False

        calendarOld = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ORGANIZER;CN="User 02":mailto:[email protected]
ATTENDEE:mailto:[email protected]
ATTENDEE:mailto:[email protected]
END:VEVENT
END:VCALENDAR
""")

        calendarNew = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ORGANIZER;CN="User 02":mailto:[email protected]
ATTENDEE:mailto:[email protected]
ATTENDEE:mailto:[email protected]
END:VEVENT
END:VCALENDAR
""")

        calresource.exists = lambda : True
        calresource.iCalendarForUser = lambda request: succeed(calendarOld)

        scheduler = ImplicitScheduler()
        try:
            doAction, isScheduleObject = (yield scheduler.testImplicitSchedulingPUT(request, calresource, "/calendars/users/user01/calendar/1.ics", calendarNew, False))
        except:
            self.fail("Exception must not be raised")
        self.assertTrue(doAction)
        self.assertTrue(isScheduleObject)
    def test_testImplicitSchedulingPUT_NoChangeScheduleState(self):
        """
        Test that testImplicitSchedulingPUT will prevent attendees from changing the
        schedule object state.
        """

        request = SimpleRequest(self.site, "PUT", "/calendar/1.ics")
        calresource = yield request.locateResource("/calendar/1.ics")
        self.assertEqual(calresource.isScheduleObject, None)
        calresource.isScheduleObject = False

        calendarOld = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
END:VEVENT
END:VCALENDAR
""")

        calendarNew = Component.fromString("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
DTSTART:20080601T120000Z
DTEND:20080601T130000Z
ORGANIZER;CN="User 02":mailto:[email protected]
ATTENDEE:mailto:[email protected]
ATTENDEE:mailto:[email protected]
END:VEVENT
END:VCALENDAR
""")

        calresource.exists = lambda : True
        calresource.iCalendarForUser = lambda request: succeed(calendarOld)

        scheduler = ImplicitScheduler()
        try:
            yield scheduler.testImplicitSchedulingPUT(request, calresource, "/calendars/users/user01/calendar/1.ics", calendarNew, False)
        except HTTPError:
            pass
        except:
            self.fail("HTTPError exception must be raised")
        else:
            self.fail("Exception must be raised")
        request._newStoreTransaction.abort()
Esempio n. 30
0
    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)