mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-08 06:48:51 +00:00
Monotone-Parent: bb3480fceb6cb5272d17ac7b9d0999cd0706581b
Monotone-Revision: a5bfd93a503f6042740a0ab88ca339c566d81c1f Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2010-06-01T18:14:17 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
2010-06-01 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* Tests/Integration/test-*.py: take the API changes in
|
||||
webdavlib.py into accounts with regards to XPath queries.
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
(-_privacySqlString): renamed to the new standardized
|
||||
"aclSQLListingFilter". Again, a difference is now made between
|
||||
|
||||
@@ -13,29 +13,9 @@ import vobject
|
||||
import vobject.base
|
||||
import vobject.icalendar
|
||||
import webdavlib
|
||||
import utilities
|
||||
import StringIO
|
||||
|
||||
def fetchUserInfo(login):
|
||||
client = webdavlib.WebDAVClient(hostname, port, username, password)
|
||||
resource = "/SOGo/dav/%s/" % login
|
||||
propfind = webdavlib.WebDAVPROPFIND(resource,
|
||||
["displayname",
|
||||
"{urn:ietf:params:xml:ns:caldav}calendar-user-address-set"],
|
||||
0)
|
||||
propfind.xpath_namespace = { "D": "DAV:",
|
||||
"C": "urn:ietf:params:xml:ns:caldav" }
|
||||
client.execute(propfind)
|
||||
assert(propfind.response["status"] == 207)
|
||||
name_nodes = propfind.xpath_evaluate('/D:multistatus/D:response/D:propstat/D:prop/D:displayname',
|
||||
None)
|
||||
email_nodes = propfind.xpath_evaluate('/D:multistatus/D:response/D:propstat/D:prop/C:calendar-user-address-set/D:href',
|
||||
None)
|
||||
if len(name_nodes[0].childNodes) > 0:
|
||||
displayName = name_nodes[0].childNodes[0].nodeValue
|
||||
else:
|
||||
displayName = ""
|
||||
|
||||
return (displayName, email_nodes[0].childNodes[0].nodeValue)
|
||||
import xml.etree.ElementTree
|
||||
|
||||
class CalDAVPropertiesTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@@ -58,34 +38,29 @@ class CalDAVPropertiesTest(unittest.TestCase):
|
||||
["{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp"],
|
||||
0)
|
||||
self.client.execute(propfind)
|
||||
propfind.xpath_namespace = { "D": "DAV:",
|
||||
"C": "urn:ietf:params:xml:ns:caldav" }
|
||||
propstats = propfind.xpath_evaluate('/D:multistatus/D:response/D:propstat/D:prop/C:schedule-calendar-transp')
|
||||
self.assertTrue(len(propstats) > 0,
|
||||
"schedule-calendar-transp not present in response")
|
||||
node = propstats[0]
|
||||
status = propfind.xpath_evaluate('D:status',
|
||||
node.parentNode.parentNode)[0] \
|
||||
.childNodes[0].nodeValue[9:12]
|
||||
response = propfind.response["document"].find('{DAV:}response')
|
||||
propstat = response.find('{DAV:}propstat')
|
||||
status = propstat.find('{DAV:}status').text[9:12]
|
||||
|
||||
self.assertEquals(status, "200",
|
||||
"schedule-calendar-transp marked as 'Not Found' in response")
|
||||
values = node.childNodes
|
||||
nvalues = len(values)
|
||||
self.assertEquals(nvalues, 1,
|
||||
"expected 1 value (%d received)" % nvalues)
|
||||
transp = propstat.find('{DAV:}prop/{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp')
|
||||
values = transp.getchildren()
|
||||
self.assertEquals(len(values), 1, "one and only one element expected")
|
||||
value = values[0]
|
||||
self.assertEquals(value.__class__.__name__, "Element",
|
||||
self.assertTrue(isinstance(value, xml.etree.ElementTree._ElementInterface),
|
||||
"schedule-calendar-transp must be an instance of" \
|
||||
" %s, not %s"
|
||||
% ("Element", value.__class__.__name__))
|
||||
self.assertEquals(value.namespaceURI, "urn:ietf:params:xml:ns:caldav",
|
||||
"schedule-calendar-transp must have a value in"\
|
||||
" namespace '%s', not '%s'"
|
||||
% ("urn:ietf:params:xml:ns:caldav",
|
||||
value.namespaceURI))
|
||||
self.assertTrue(value.tagName == "opaque",
|
||||
% ("_ElementInterface", transp.__class__.__name__))
|
||||
ns = value.tag[0:31]
|
||||
tag = value.tag[31:]
|
||||
self.assertTrue(ns == "{urn:ietf:params:xml:ns:caldav}",
|
||||
"schedule-calendar-transp must have a value in"\
|
||||
" namespace '%s', not '%s'"
|
||||
% ("urn:ietf:params:xml:ns:caldav", ns))
|
||||
self.assertTrue(tag == "opaque",
|
||||
"schedule-calendar-transp must be 'opaque' on new" \
|
||||
" collections, not '%s'" % value.tagName)
|
||||
" collections, not '%s'" % tag)
|
||||
|
||||
## PROPPATCH
|
||||
newValueNode = "{urn:ietf:params:xml:ns:caldav}thisvaluedoesnotexist"
|
||||
@@ -123,9 +98,10 @@ class CalDAVITIPDelegationTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = webdavlib.WebDAVClient(hostname, port,
|
||||
username, password)
|
||||
(self.user_name, self.user_email) = fetchUserInfo(username)
|
||||
(self.attendee1_name, self.attendee1_email) = fetchUserInfo(attendee1)
|
||||
(self.attendee1_delegate_name, self.attendee1_delegate_email) = fetchUserInfo(attendee1_delegate)
|
||||
utility = utilities.TestUtility(self, self.client)
|
||||
(self.user_name, self.user_email) = utility.fetchUserInfo(username)
|
||||
(self.attendee1_name, self.attendee1_email) = utility.fetchUserInfo(attendee1)
|
||||
(self.attendee1_delegate_name, self.attendee1_delegate_email) = utility.fetchUserInfo(attendee1_delegate)
|
||||
|
||||
self.user_calendar = "/SOGo/dav/%s/Calendar/personal/" % username
|
||||
self.attendee1_calendar = "/SOGo/dav/%s/Calendar/personal/" % attendee1
|
||||
|
||||
@@ -102,7 +102,8 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
|
||||
def __init__(self, arg):
|
||||
DAVAclTest.__init__(self, arg)
|
||||
self.acl_utility = utilities.TestCalendarACLUtility(self.client,
|
||||
self.acl_utility = utilities.TestCalendarACLUtility(self,
|
||||
self.client,
|
||||
self.resource)
|
||||
|
||||
def setUp(self):
|
||||
@@ -195,31 +196,21 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
" (received '%d')"
|
||||
% (filename, exp_status, delete.response["status"]))
|
||||
|
||||
def _currentUserPrivilegeSet(self, resource, expectFailure = False):
|
||||
def _currentUserPrivilegeSet(self, resource, expStatus = 207):
|
||||
propfind = webdavlib.WebDAVPROPFIND(resource,
|
||||
["{DAV:}current-user-privilege-set"],
|
||||
0)
|
||||
self.subscriber_client.execute(propfind)
|
||||
if expectFailure:
|
||||
expStatus = 403
|
||||
else:
|
||||
expStatus = 207
|
||||
self.assertEquals(propfind.response["status"], expStatus,
|
||||
"unexected status code when reading privileges:"
|
||||
+ " %s instead of %d"
|
||||
% (propfind.response["status"], expStatus))
|
||||
|
||||
privileges = []
|
||||
if not expectFailure:
|
||||
propfind.xpath_namespace = { "D": "DAV:" }
|
||||
response_nodes = propfind.xpath_evaluate("/D:multistatus/D:response/D:propstat/D:prop/D:current-user-privilege-set/D:privilege")
|
||||
if expStatus < 300:
|
||||
response_nodes = propfind.response["document"].findall("{DAV:}response/{DAV:}propstat/{DAV:}prop/{DAV:}current-user-privilege-set/{DAV:}privilege")
|
||||
for node in response_nodes:
|
||||
privilegeNode = node.childNodes[0]
|
||||
tagName = privilegeNode.tagName
|
||||
indexColon = tagName.find(":")
|
||||
if indexColon > -1:
|
||||
tagName = tagName[indexColon+1:]
|
||||
privileges.append("{%s}%s" % (privilegeNode.namespaceURI, tagName))
|
||||
privileges.extend([x.tag for x in node.getchildren()])
|
||||
|
||||
return privileges
|
||||
|
||||
@@ -259,10 +250,12 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
'{urn:ietf:params:xml:ns:caldav}schedule-respond-vtodo']
|
||||
expectedPrivileges.extend(extraPrivileges)
|
||||
if rights.has_key("d"):
|
||||
extraPrivileges = ["{DAV:}unbind"]
|
||||
expectedPrivileges.extend(extraPrivileges)
|
||||
privileges = self._currentUserPrivilegeSet(self.resource,
|
||||
len(expectedPrivileges) == 0)
|
||||
expectedPrivileges.append("{DAV:}unbind")
|
||||
if len(expectedPrivileges) == 0:
|
||||
expStatus = 404
|
||||
else:
|
||||
expStatus = 207
|
||||
privileges = self._currentUserPrivilegeSet(self.resource, expStatus)
|
||||
self._comparePrivilegeSets(expectedPrivileges, privileges)
|
||||
|
||||
def _testEventDAVAcl(self, event_class, right):
|
||||
@@ -271,10 +264,10 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
url = "%s%s-%s.ics" % (self.resource, icsClass, suffix)
|
||||
|
||||
if right is None:
|
||||
expectFailure = True
|
||||
expStatus = 403
|
||||
expectedPrivileges = None
|
||||
else:
|
||||
expectFailure = False
|
||||
expStatus = 207
|
||||
expectedPrivileges = ['{DAV:}read-current-user-privilege-set',
|
||||
'{urn:inverse:params:xml:ns:inverse-dav}view-date-and-time',
|
||||
'{DAV:}read']
|
||||
@@ -290,22 +283,27 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
'{DAV:}write']
|
||||
expectedPrivileges.extend(extraPrivileges)
|
||||
|
||||
privileges = self._currentUserPrivilegeSet(url, expectFailure)
|
||||
if not expectFailure:
|
||||
privileges = self._currentUserPrivilegeSet(url, expStatus)
|
||||
if expStatus < 300:
|
||||
self._comparePrivilegeSets(expectedPrivileges, privileges)
|
||||
|
||||
def _testRights(self, rights):
|
||||
self.acl_utility.setupRights(subscriber_username, rights)
|
||||
self._testCreate(rights)
|
||||
self._testCollectionDAVAcl(rights)
|
||||
self._testEventRight("pu", rights)
|
||||
self._testEventRight("pr", rights)
|
||||
self._testEventRight("co", rights)
|
||||
if rights.has_key("pu") \
|
||||
or rights.has_key("pr") \
|
||||
or rights.has_key("co"):
|
||||
self._testEventRight("pu", rights)
|
||||
self._testEventRight("pr", rights)
|
||||
self._testEventRight("co", rights)
|
||||
self._testDelete(rights)
|
||||
|
||||
def _testCreate(self, rights):
|
||||
if rights.has_key("c") and rights["c"]:
|
||||
exp_code = 201
|
||||
elif len(rights) == 0:
|
||||
exp_code = 404
|
||||
else:
|
||||
exp_code = 403
|
||||
self._putEvent(self.subscriber_client, "creation-test.ics", "PUBLIC",
|
||||
@@ -314,6 +312,8 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
def _testDelete(self, rights):
|
||||
if rights.has_key("d") and rights["d"]:
|
||||
exp_code = 204
|
||||
elif len(rights) == 0:
|
||||
exp_code = 404
|
||||
else:
|
||||
exp_code = 403
|
||||
self._deleteEvent(self.subscriber_client, "public-event.ics",
|
||||
@@ -373,32 +373,25 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
return task
|
||||
|
||||
def _calendarDataInMultistatus(self, query, filename,
|
||||
response_tag = "D:response"):
|
||||
response_tag = "{DAV:}response"):
|
||||
event = None
|
||||
|
||||
query.xpath_namespace = { "D": "DAV:",
|
||||
"C": "urn:ietf:params:xml:ns:caldav" }
|
||||
response_nodes = query.xpath_evaluate("/D:multistatus/%s" % response_tag)
|
||||
response_nodes = query.response["document"].findall("%s" % response_tag)
|
||||
for response_node in response_nodes:
|
||||
href_node = query.xpath_evaluate("D:href", response_node)[0]
|
||||
href = href_node.childNodes[0].nodeValue
|
||||
href_node = response_node.find("{DAV:}href")
|
||||
href = href_node.text
|
||||
if href.endswith(filename):
|
||||
propstat_nodes = query.xpath_evaluate("D:propstat", response_node)
|
||||
for propstat_node in propstat_nodes:
|
||||
status_node = query.xpath_evaluate("D:status",
|
||||
propstat_node)[0]
|
||||
status = status_node.childNodes[0].nodeValue
|
||||
data_nodes = query.xpath_evaluate("D:prop/C:calendar-data",
|
||||
propstat_node)
|
||||
propstat_node = response_node.find("{DAV:}propstat")
|
||||
if propstat_node is not None:
|
||||
status_node = propstat_node.find("{DAV:}status")
|
||||
status = status_node.text
|
||||
if status.endswith("200 OK"):
|
||||
if (len(data_nodes) > 0
|
||||
and len(data_nodes[0].childNodes) > 0):
|
||||
event = data_nodes[0].childNodes[0].nodeValue
|
||||
else:
|
||||
if not (status.endswith("404 Resource Not Found")
|
||||
or status.endswith("404 Not Found")):
|
||||
self.fail("%s: unexpected status code: '%s'"
|
||||
% (filename, status))
|
||||
data_node = propstat_node.find("{DAV:}prop/{urn:ietf:params:xml:ns:caldav}calendar-data")
|
||||
event = data_node.text
|
||||
elif not (status.endswith("404 Resource Not Found")
|
||||
or status.endswith("404 Not Found")):
|
||||
self.fail("%s: unexpected status code: '%s'"
|
||||
% (filename, status))
|
||||
|
||||
return event
|
||||
|
||||
@@ -411,11 +404,11 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
["{urn:ietf:params:xml:ns:caldav}calendar-data"],
|
||||
1)
|
||||
self.subscriber_client.execute(propfind)
|
||||
if propfind.response["status"] != 403:
|
||||
if propfind.response["status"] != 404:
|
||||
event = self._calendarDataInMultistatus(propfind, filename)
|
||||
|
||||
return event
|
||||
|
||||
|
||||
def _multigetEvent(self, event_class):
|
||||
event = None
|
||||
|
||||
@@ -425,7 +418,7 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
["{urn:ietf:params:xml:ns:caldav}calendar-data"],
|
||||
[ url ])
|
||||
self.subscriber_client.execute(multiget)
|
||||
if multiget.response["status"] != 403:
|
||||
if multiget.response["status"] != 404:
|
||||
event = self._calendarDataInMultistatus(multiget, url)
|
||||
|
||||
return event
|
||||
@@ -438,9 +431,9 @@ class DAVCalendarAclTest(DAVAclTest):
|
||||
sync_query = webdavlib.WebDAVSyncQuery(self.resource, None,
|
||||
["{urn:ietf:params:xml:ns:caldav}calendar-data"])
|
||||
self.subscriber_client.execute(sync_query)
|
||||
if sync_query.response["status"] != 403:
|
||||
if sync_query.response["status"] != 404:
|
||||
event = self._calendarDataInMultistatus(sync_query, url,
|
||||
"D:sync-response")
|
||||
"{DAV:}sync-response")
|
||||
|
||||
return event
|
||||
|
||||
@@ -660,7 +653,8 @@ END:VCARD""" }
|
||||
|
||||
def __init__(self, arg):
|
||||
DAVAclTest.__init__(self, arg)
|
||||
self.acl_utility = utilities.TestAddressBookACLUtility(self.client,
|
||||
self.acl_utility = utilities.TestAddressBookACLUtility(self,
|
||||
self.client,
|
||||
self.resource)
|
||||
|
||||
def setUp(self):
|
||||
@@ -777,4 +771,3 @@ END:VCARD""" }
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ class iCalTest(unittest.TestCase):
|
||||
propfind = webdavlib.WebDAVPROPFIND(resource,
|
||||
["{DAV:}principal-collection-set"],
|
||||
0)
|
||||
propfind.xpath_namespace = { "D": "DAV:" }
|
||||
client.execute(propfind)
|
||||
self.assertEquals(propfind.response["status"], 207)
|
||||
headers = propfind.response["headers"]
|
||||
@@ -28,7 +27,6 @@ class iCalTest(unittest.TestCase):
|
||||
["{DAV:}principal-collection-set"],
|
||||
0)
|
||||
client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"
|
||||
propfind.xpath_namespace = { "D": "DAV:" }
|
||||
client.execute(propfind)
|
||||
self.assertEquals(propfind.response["status"], 207)
|
||||
headers = propfind.response["headers"]
|
||||
@@ -50,7 +48,6 @@ class iCalTest(unittest.TestCase):
|
||||
proppatch = webdavlib.WebDAVPROPPATCH(resource, props)
|
||||
client = webdavlib.WebDAVClient(hostname, port, username, password)
|
||||
client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"
|
||||
proppatch.xpath_namespace = { "D": "DAV:" }
|
||||
client.execute(proppatch)
|
||||
self.assertEquals(proppatch.response["status"], 207,
|
||||
"failure (%s) setting '%s' permission for '%s' on %s's calendars"
|
||||
@@ -63,11 +60,10 @@ class iCalTest(unittest.TestCase):
|
||||
["{DAV:}group-membership"], 0)
|
||||
client = webdavlib.WebDAVClient(hostname, port, username, password)
|
||||
client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"
|
||||
propfind.xpath_namespace = { "D": "DAV:" }
|
||||
client.execute(propfind)
|
||||
|
||||
hrefs = propfind.xpath_evaluate("/D:multistatus/D:response/D:propstat/D:prop/D:group-membership/D:href")
|
||||
members = [x.childNodes[0].nodeValue for x in hrefs]
|
||||
hrefs = propfind.response["document"].findall("{DAV:}response/{DAV:}propstat/{DAV:}prop/{DAV:}group-membership/{DAV:}href")
|
||||
members = [x.text for x in hrefs]
|
||||
|
||||
return members
|
||||
|
||||
@@ -77,12 +73,11 @@ class iCalTest(unittest.TestCase):
|
||||
propfind = webdavlib.WebDAVPROPFIND(resource, [prop], 0)
|
||||
client = webdavlib.WebDAVClient(hostname, port, username, password)
|
||||
client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"
|
||||
propfind.xpath_namespace = { "D": "DAV:", "n1": "http://calendarserver.org/ns/" }
|
||||
client.execute(propfind)
|
||||
|
||||
hrefs = propfind.xpath_evaluate("/D:multistatus/D:response/D:propstat/D:prop/n1:calendar-proxy-%s-for/D:href"
|
||||
hrefs = propfind.response["document"].findall("{DAV:}response/{DAV:}propstat/{DAV:}prop/{http://calendarserver.org/ns/}calendar-proxy-%s-for/{DAV:}href"
|
||||
% perm)
|
||||
members = [x.childNodes[0].nodeValue[len("/SOGo/dav/"):-1] for x in hrefs]
|
||||
members = [x.text[len("/SOGo/dav/"):-1] for x in hrefs]
|
||||
|
||||
return members
|
||||
|
||||
@@ -123,7 +118,7 @@ class iCalTest(unittest.TestCase):
|
||||
% (users[1], perm, users[0], proxyFor))
|
||||
|
||||
def _testMapping(self, client, perm, resource, rights):
|
||||
dav_utility = utilities.TestCalendarACLUtility(client, resource)
|
||||
dav_utility = utilities.TestCalendarACLUtility(self, client, resource)
|
||||
dav_utility.setupRights(subscriber_username, rights)
|
||||
|
||||
membership = self._getMembership(subscriber_username)
|
||||
@@ -142,7 +137,8 @@ class iCalTest(unittest.TestCase):
|
||||
client = webdavlib.WebDAVClient(hostname, port, username, password)
|
||||
client.user_agent = "DAVKit/4.0.1 (730); CalendarStore/4.0.1 (973); iCal/4.0.1 (1374); Mac OS X/10.6.2 (10C540)"
|
||||
personal_resource = "/SOGo/dav/%s/Calendar/personal/" % username
|
||||
dav_utility = utilities.TestCalendarACLUtility(client,
|
||||
dav_utility = utilities.TestCalendarACLUtility(self,
|
||||
client,
|
||||
personal_resource)
|
||||
dav_utility.setupRights(subscriber_username, {})
|
||||
dav_utility.subscribe([subscriber_username])
|
||||
@@ -153,7 +149,8 @@ class iCalTest(unittest.TestCase):
|
||||
client.execute(delete)
|
||||
mkcol = webdavlib.WebDAVMKCOL(other_resource)
|
||||
client.execute(mkcol)
|
||||
dav_utility = utilities.TestCalendarACLUtility(client,
|
||||
dav_utility = utilities.TestCalendarACLUtility(self,
|
||||
client,
|
||||
other_resource)
|
||||
dav_utility.setupRights(subscriber_username, {})
|
||||
dav_utility.subscribe([subscriber_username])
|
||||
@@ -181,7 +178,7 @@ class iCalTest(unittest.TestCase):
|
||||
|
||||
## we test the unsubscription
|
||||
# unsubscribed from personal, subscribed to 'test-calendar-proxy2'
|
||||
dav_utility = utilities.TestCalendarACLUtility(client,
|
||||
dav_utility = utilities.TestCalendarACLUtility(self, client,
|
||||
personal_resource)
|
||||
dav_utility.unsubscribe([subscriber_username])
|
||||
membership = self._getMembership(subscriber_username)
|
||||
@@ -190,7 +187,7 @@ class iCalTest(unittest.TestCase):
|
||||
"'%s' must have write access to %s's calendars"
|
||||
% (subscriber_username, username))
|
||||
# unsubscribed from personal, unsubscribed from 'test-calendar-proxy2'
|
||||
dav_utility = utilities.TestCalendarACLUtility(client,
|
||||
dav_utility = utilities.TestCalendarACLUtility(self, client,
|
||||
other_resource)
|
||||
dav_utility.unsubscribe([subscriber_username])
|
||||
membership = self._getMembership(subscriber_username)
|
||||
|
||||
@@ -17,10 +17,8 @@ def fetchUserEmail(login):
|
||||
propfind = webdavlib.WebDAVPROPFIND(resource,
|
||||
["{urn:ietf:params:xml:ns:caldav}calendar-user-address-set"],
|
||||
0)
|
||||
propfind.xpath_namespace = { "D": "DAV:",
|
||||
"C": "urn:ietf:params:xml:ns:caldav" }
|
||||
client.execute(propfind)
|
||||
nodes = propfind.xpath_evaluate('/D:multistatus/D:response/D:propstat/D:prop/C:calendar-user-address-set/D:href',
|
||||
nodes = propfind.xpath_evaluate('{DAV:}response/{DAV:}propstat/{DAV:}prop/C:calendar-user-address-set/{DAV:}href',
|
||||
None)
|
||||
|
||||
return nodes[0].childNodes[0].nodeValue
|
||||
@@ -225,7 +223,7 @@ class DAVMailCollectionTest():
|
||||
self.client.execute(propfind)
|
||||
key = property.replace("{urn:schemas:httpmail:}", "a:")
|
||||
key = key.replace("{urn:schemas:mailheader:}", "a:")
|
||||
tmp = propfind.xpath_evaluate("/D:multistatus/D:response/D:propstat/D:prop")
|
||||
tmp = propfind.xpath_evaluate("{DAV:}response/{DAV:}propstat/{DAV:}prop")
|
||||
prop = tmp[0].firstChild;
|
||||
result = None
|
||||
|
||||
@@ -319,11 +317,9 @@ class DAVMailCollectionTest():
|
||||
self.assertEquals(query.response["status"], 207,
|
||||
"filter %s:\n\tunexpected status: %d"
|
||||
% (filter[0], query.response["status"]))
|
||||
query.xpath_namespace = { "D": "DAV:",
|
||||
"I": "urn:inverse:params:xml:ns:inverse-dav" }
|
||||
response_nodes = query.xpath_evaluate("/D:multistatus/D:response")
|
||||
response_nodes = query.xpath_evaluate("{DAV:}response")
|
||||
for response_node in response_nodes:
|
||||
href_node = query.xpath_evaluate("D:href", response_node)[0]
|
||||
href_node = query.xpath_evaluate("{DAV:}href", response_node)[0]
|
||||
href = href_node.childNodes[0].nodeValue
|
||||
received_count = received_count + 1
|
||||
self.assertTrue(expected_hrefs.has_key(href),
|
||||
@@ -345,12 +341,10 @@ class DAVMailCollectionTest():
|
||||
self.assertEquals(query.response["status"], 207,
|
||||
"sortOrder %s:\n\tunexpected status: %d"
|
||||
% (sortOrder[0], query.response["status"]))
|
||||
query.xpath_namespace = { "D": "DAV:",
|
||||
"I": "urn:inverse:params:xml:ns:inverse-dav" }
|
||||
response_nodes = query.xpath_evaluate("/D:multistatus/D:response")
|
||||
response_nodes = query.response["document"].findall("{DAV:}response")
|
||||
for response_node in response_nodes:
|
||||
href_node = query.xpath_evaluate("D:href", response_node)[0]
|
||||
href = href_node.childNodes[0].nodeValue
|
||||
href_node = response_node.find("{DAV:}href")
|
||||
href = href_node.text
|
||||
self.assertEquals(expected_hrefs[received_count], href,
|
||||
"sortOrder %s:\n\tunexpected href: %s (expecting: %s)"
|
||||
% (sortOrder[0], href,
|
||||
|
||||
@@ -11,7 +11,7 @@ class WebDAVTest(unittest.TestCase):
|
||||
unittest.TestCase.__init__(self, arg)
|
||||
self.client = webdavlib.WebDAVClient(hostname, port,
|
||||
username, password)
|
||||
self.dav_utility = utilities.TestUtility(self.client)
|
||||
self.dav_utility = utilities.TestUtility(self, self.client)
|
||||
|
||||
def testPrincipalCollectionSet(self):
|
||||
"""property: 'principal-collection-set' on collection object"""
|
||||
@@ -19,12 +19,11 @@ class WebDAVTest(unittest.TestCase):
|
||||
propfind = webdavlib.WebDAVPROPFIND(resource,
|
||||
["{DAV:}principal-collection-set"],
|
||||
0)
|
||||
propfind.xpath_namespace = { "D": "DAV:" }
|
||||
self.client.execute(propfind)
|
||||
self.assertEquals(propfind.response["status"], 207)
|
||||
nodes = propfind.xpath_evaluate('/D:multistatus/D:response/D:propstat/D:prop/D:principal-collection-set/D:href',
|
||||
None)
|
||||
responseHref = nodes[0].childNodes[0].nodeValue
|
||||
nodes = propfind.response["document"] \
|
||||
.findall('{DAV:}response/{DAV:}propstat/{DAV:}prop/{DAV:}principal-collection-set/{DAV:}href')
|
||||
responseHref = nodes[0].text
|
||||
if responseHref[0:4] == "http":
|
||||
self.assertEquals("http://%s/SOGo/dav/" % hostname, responseHref,
|
||||
"{DAV:}principal-collection-set returned %s instead of 'http../SOGo/dav/'"
|
||||
@@ -40,12 +39,11 @@ class WebDAVTest(unittest.TestCase):
|
||||
propfind = webdavlib.WebDAVPROPFIND(resource,
|
||||
["{DAV:}principal-collection-set"],
|
||||
0)
|
||||
propfind.xpath_namespace = { "D": "DAV:" }
|
||||
self.client.execute(propfind)
|
||||
self.assertEquals(propfind.response["status"], 207)
|
||||
nodes = propfind.xpath_evaluate('/D:multistatus/D:response/D:propstat/D:prop/D:principal-collection-set/D:href',
|
||||
None)
|
||||
responseHref = nodes[0].childNodes[0].nodeValue
|
||||
node = propfind.response["document"] \
|
||||
.find('{DAV:}response/{DAV:}propstat/{DAV:}prop/{DAV:}principal-collection-set/{DAV:}href')
|
||||
responseHref = node.text
|
||||
expectedHref = '/SOGo/dav/'
|
||||
if responseHref[0:4] == "http":
|
||||
self.assertEquals("http://%s%s" % (hostname, expectedHref), responseHref,
|
||||
@@ -61,19 +59,15 @@ class WebDAVTest(unittest.TestCase):
|
||||
propfind = webdavlib.WebDAVPROPFIND(resource,
|
||||
["{DAV:}displayname", "{DAV:}resourcetype"],
|
||||
1)
|
||||
propfind.xpath_namespace = { "D": "DAV:" }
|
||||
self.client.execute(propfind)
|
||||
self.assertEquals(propfind.response["status"], 207)
|
||||
|
||||
nodes = propfind.xpath_evaluate('/D:multistatus/D:response',
|
||||
None)
|
||||
nodes = propfind.response["document"].findall('{DAV:}response')
|
||||
for node in nodes:
|
||||
responseHref = propfind.xpath_evaluate('D:href', node)[0].childNodes[0].nodeValue
|
||||
responseHref = node.find('{DAV:}href').text
|
||||
hasSlash = responseHref[-1] == '/'
|
||||
resourcetypes = \
|
||||
propfind.xpath_evaluate('D:propstat/D:prop/D:resourcetype',
|
||||
node)[0].childNodes
|
||||
isCollection = len(resourcetypes) > 0
|
||||
resourcetype = node.find('{DAV:}propstat/{DAV:}prop/{DAV:}resourcetype')
|
||||
isCollection = len(resourcetype.getchildren()) > 0
|
||||
if isCollection:
|
||||
self.assertEquals(hasSlash, resourceWithSlash,
|
||||
"failure with href '%s' while querying '%s'"
|
||||
@@ -108,14 +102,11 @@ class WebDAVTest(unittest.TestCase):
|
||||
["displayname"], matches)
|
||||
self.client.execute(query)
|
||||
self.assertEquals(query.response["status"], 207)
|
||||
response = query.xpath_evaluate('/D:multistatus/D:response')[0]
|
||||
href = query.xpath_evaluate('D:href', response)[0]
|
||||
self.assertEquals("/SOGo/dav/%s/" % username,
|
||||
href.childNodes[0].nodeValue)
|
||||
displayname = query.xpath_evaluate('/D:multistatus/D:response' \
|
||||
+ '/D:propstat/D:prop' \
|
||||
+ '/D:displayname')[0]
|
||||
value = displayname.nodeValue
|
||||
response = query.response["document"].findall('{DAV:}response')[0]
|
||||
href = response.find('{DAV:}href').text
|
||||
self.assertEquals("/SOGo/dav/%s/" % username, href)
|
||||
displayname = response.find('{DAV:}propstat/{DAV:}prop/{DAV:}displayname')
|
||||
value = displayname.text
|
||||
if value is None:
|
||||
value = ""
|
||||
self.assertEquals(userInfo[0], value)
|
||||
@@ -126,60 +117,38 @@ class WebDAVTest(unittest.TestCase):
|
||||
resource = '/SOGo/dav/%s/' % username
|
||||
userInfo = self.dav_utility.fetchUserInfo(username)
|
||||
|
||||
query_props = {"owner": { "href": resource,
|
||||
"displayname": userInfo[0]},
|
||||
"principal-collection-set": { "href": "/SOGo/dav/",
|
||||
"displayname": "SOGo"}}
|
||||
query_props = {"{DAV:}owner": { "{DAV:}href": resource,
|
||||
"{DAV:}displayname": userInfo[0]},
|
||||
"{DAV:}principal-collection-set": { "{DAV:}href": "/SOGo/dav/",
|
||||
"{DAV:}displayname": "SOGo"}}
|
||||
query = webdavlib.WebDAVExpandProperty(resource, query_props.keys(),
|
||||
["displayname"])
|
||||
self.client.execute(query)
|
||||
self.assertEquals(query.response["status"], 207)
|
||||
|
||||
topResponse = query.xpath_evaluate('/D:multistatus/D:response')[0]
|
||||
topHref = query.xpath_evaluate('D:href', topResponse)[0]
|
||||
self.assertEquals(resource, topHref.childNodes[0].nodeValue)
|
||||
topResponse = query.response["document"].find('{DAV:}response')
|
||||
topHref = topResponse.find('{DAV:}href')
|
||||
self.assertEquals(resource, topHref.text)
|
||||
for query_prop in query_props.keys():
|
||||
propResponse = query.xpath_evaluate('D:propstat/D:prop/D:%s'
|
||||
% query_prop, topResponse)[0]
|
||||
|
||||
|
||||
# <?xml version="1.0" encoding="utf-8"?>
|
||||
# <D:multistatus xmlns:D="DAV:">
|
||||
# <D:response>
|
||||
# <D:href>/SOGo/dav/wsourdeau/</D:href>
|
||||
# <D:propstat>
|
||||
# <D:prop>
|
||||
# <D:owner>
|
||||
# <D:response>
|
||||
# <D:href>/SOGo/dav/wsourdeau/</D:href>
|
||||
# <D:propstat>
|
||||
# <D:prop>
|
||||
# <D:displayname>Wolfgang Sourdeau</D:displayname>
|
||||
# </D:prop>
|
||||
# <D:status>HTTP/1.1 200 OK</D:status>
|
||||
# </D:propstat>
|
||||
# </D:response>
|
||||
# </D:owner>
|
||||
propHref = query.xpath_evaluate('D:response/D:href',
|
||||
propResponse)[0]
|
||||
self.assertEquals(query_props[query_prop]["href"],
|
||||
propHref.childNodes[0].nodeValue,
|
||||
propResponse = topResponse.find('{DAV:}propstat/{DAV:}prop/%s'
|
||||
% query_prop)
|
||||
propHref = propResponse.find('{DAV:}response/{DAV:}href')
|
||||
self.assertEquals(query_props[query_prop]["{DAV:}href"],
|
||||
propHref.text,
|
||||
"'%s', href mismatch: exp. '%s', got '%s'"
|
||||
% (query_prop,
|
||||
query_props[query_prop]["href"],
|
||||
propHref.childNodes[0].nodeValue))
|
||||
propDisplayname = query.xpath_evaluate('D:response/D:propstat/D:prop/D:displayname',
|
||||
propResponse)[0]
|
||||
if len(propDisplayname.childNodes) > 0:
|
||||
displayName = propDisplayname.childNodes[0].nodeValue
|
||||
else:
|
||||
query_props[query_prop]["{DAV:}href"],
|
||||
propHref.text))
|
||||
propDisplayname = propResponse.find('{DAV:}response/{DAV:}propstat/{DAV:}prop/{DAV:}displayname')
|
||||
displayName = propDisplayname.text
|
||||
if displayName is None:
|
||||
displayName = ""
|
||||
self.assertEquals(query_props[query_prop]["displayname"],
|
||||
self.assertEquals(query_props[query_prop]["{DAV:}displayname"],
|
||||
displayName,
|
||||
"'%s', displayname mismatch: exp. '%s', got '%s'"
|
||||
% (query_prop,
|
||||
query_props[query_prop]["displayname"],
|
||||
propDisplayname.nodeValue))
|
||||
query_props[query_prop]["{DAV:}displayname"],
|
||||
propDisplayname))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -43,10 +43,10 @@ class WebdavSyncTest(unittest.TestCase):
|
||||
self.assertEquals(query1.response["status"], 207,
|
||||
("query1: invalid status code: %d (!= 207)"
|
||||
% query1.response["status"]))
|
||||
token_node = query1.xpath_evaluate("/D:multistatus/D:sync-token")[0]
|
||||
token_node = query1.response["document"].find("{DAV:}sync-token")
|
||||
# Implicit "assertion": we expect SOGo to return a token node, with a
|
||||
# non-empty numerical value. Anything else will trigger an exception
|
||||
token = int(token_node.childNodes[0].nodeValue)
|
||||
token = int(token_node.text)
|
||||
|
||||
self.assertTrue(token > 0)
|
||||
self.assertTrue(token <= int(query1.start))
|
||||
@@ -55,8 +55,8 @@ class WebdavSyncTest(unittest.TestCase):
|
||||
query2 = webdavlib.WebDAVSyncQuery(resource, "1234", [ "getetag" ])
|
||||
self.client.execute(query2)
|
||||
self.assertEquals(query2.response["status"], 403)
|
||||
cond_nodes = query2.xpath_evaluate("/D:error/D:valid-sync-token")
|
||||
self.assertTrue(len(cond_nodes) > 0,
|
||||
cond_nodes = query2.response["document"].find("{DAV:}valid-sync-token")
|
||||
self.assertTrue(cond_nodes is not None,
|
||||
"expected 'valid-sync-token' condition error")
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
import unittest
|
||||
import webdavlib
|
||||
|
||||
class TestUtility(unittest.TestCase):
|
||||
def __init__(self, client):
|
||||
class TestUtility():
|
||||
def __init__(self, test, client, resource = None):
|
||||
self.test = test
|
||||
self.client = client
|
||||
self.userInfo = {}
|
||||
|
||||
@@ -15,26 +16,26 @@ class TestUtility(unittest.TestCase):
|
||||
["displayname",
|
||||
"{urn:ietf:params:xml:ns:caldav}calendar-user-address-set"],
|
||||
0)
|
||||
propfind.xpath_namespace = { "D": "DAV:",
|
||||
"C": "urn:ietf:params:xml:ns:caldav" }
|
||||
self.client.execute(propfind)
|
||||
assert(propfind.response["status"] == 207)
|
||||
name_nodes = propfind.xpath_evaluate('/D:multistatus/D:response/D:propstat/D:prop/D:displayname',
|
||||
None)
|
||||
email_nodes = propfind.xpath_evaluate('/D:multistatus/D:response/D:propstat/D:prop/C:calendar-user-address-set/D:href',
|
||||
None)
|
||||
self.test.assertEquals(propfind.response["status"], 207)
|
||||
common_tree = "{DAV:}response/{DAV:}propstat/{DAV:}prop"
|
||||
name_nodes = propfind.response["document"] \
|
||||
.findall('%s/{DAV:}displayname' % common_tree)
|
||||
email_nodes = propfind.response["document"] \
|
||||
.findall('%s/{urn:ietf:params:xml:ns:caldav}calendar-user-address-set/{DAV:}href'
|
||||
% common_tree)
|
||||
|
||||
if len(name_nodes[0].childNodes) > 0:
|
||||
displayName = name_nodes[0].childNodes[0].nodeValue
|
||||
if len(name_nodes[0].text) > 0:
|
||||
displayName = name_nodes[0].text
|
||||
else:
|
||||
displayName = ""
|
||||
self.userInfo[login] = (displayName, email_nodes[0].childNodes[0].nodeValue)
|
||||
self.userInfo[login] = (displayName, email_nodes[0].text)
|
||||
|
||||
return self.userInfo[login]
|
||||
|
||||
class TestACLUtility(TestUtility):
|
||||
def __init__(self, client, resource):
|
||||
TestUtility.__init__(self, client)
|
||||
def __init__(self, test, client, resource):
|
||||
TestUtility.__init__(self, test, client, resource)
|
||||
self.resource = resource
|
||||
|
||||
def _subscriptionOperation(self, subscribers, operation):
|
||||
@@ -48,10 +49,10 @@ class TestACLUtility(TestUtility):
|
||||
post = webdavlib.HTTPPOST(self.resource, subscribeQuery)
|
||||
post.content_type = "application/xml; charset=\"utf-8\""
|
||||
self.client.execute(post)
|
||||
self.assertEquals(post.response["status"], 204,
|
||||
"subscribtion failure to '%s' for '%s' (status: %d)"
|
||||
% (self.resource, "', '".join(subscribers),
|
||||
post.response["status"]))
|
||||
self.test.assertEquals(post.response["status"], 204,
|
||||
"subscribtion failure to '%s' for '%s' (status: %d)"
|
||||
% (self.resource, "', '".join(subscribers),
|
||||
post.response["status"]))
|
||||
|
||||
def subscribe(self, subscribers=None):
|
||||
self._subscriptionOperation(subscribers, "subscribe")
|
||||
@@ -75,9 +76,9 @@ class TestACLUtility(TestUtility):
|
||||
post = webdavlib.HTTPPOST(self.resource, aclQuery)
|
||||
post.content_type = "application/xml; charset=\"utf-8\""
|
||||
self.client.execute(post)
|
||||
self.assertEquals(post.response["status"], 204,
|
||||
"rights modification: failure to set '%s' (status: %d)"
|
||||
% (rights_str, post.response["status"]))
|
||||
self.test.assertEquals(post.response["status"], 204,
|
||||
"rights modification: failure to set '%s' (status: %d)"
|
||||
% (rights_str, post.response["status"]))
|
||||
|
||||
# Calendar:
|
||||
# rights:
|
||||
|
||||
Reference in New Issue
Block a user