From 3e8d3546721b17ac926a9d9469ef1715b1df511e Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 21 Aug 2009 14:06:28 +0000 Subject: [PATCH] Monotone-Parent: 8bc28439e37a30c502ed66d8e945e84b978841b0 Monotone-Revision: efb15318c83fe427840ce7814c65d5a7c2518a07 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2009-08-21T14:06:28 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 5 +++++ Tests/test-davacl.py | 44 +++++++++++++++++------------------------ Tests/test-wedavsync.py | 12 ++--------- Tests/webdavlib.py | 18 +++++++++++++++-- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index d31e25f59..19ef05e1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-08-21 Wolfgang Sourdeau + + * Tests/webdavlib.py (WebDAVQuery.xpath_evaluate): new method to + facilitate xpath evaluation from tests. + 2009-08-20 Cyril Robert * UI/Common/UIxParentFolderActions.m (createFolderAction): Mantis 2040: diff --git a/Tests/test-davacl.py b/Tests/test-davacl.py index d2068816a..eabf3edf3 100755 --- a/Tests/test-davacl.py +++ b/Tests/test-davacl.py @@ -5,7 +5,6 @@ from config import hostname, port, username, password, subscriber_username, subs import sys import unittest import webdavlib -import xml.xpath import time # TODO: @@ -27,11 +26,11 @@ 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) - xpath_context = xml.xpath.CreateContext(propfind.response["document"]) - xpath_context.setNamespaces({ "D": "DAV:", - "C": "urn:ietf:params:xml:ns:caldav" }) - nodes = xml.xpath.Evaluate('/D:multistatus/D:response/D:propstat/D:prop/C:calendar-user-address-set/D:href', None, xpath_context) + nodes = propfind.xpath_evaluate('/D:multistatus/D:response/D:propstat/D:prop/C:calendar-user-address-set/D:href', + None) return nodes[0].childNodes[0].nodeValue @@ -59,12 +58,6 @@ class DAVAclTest(unittest.TestCase): def rightsToSOGoRights(self, rights): self.fail("subclass must implement this method") - def xpath_query(self, query, top_node): - xpath_context = xml.xpath.CreateContext(top_node) - xpath_context.setNamespaces({ "D": "DAV:", - "C": "urn:ietf:params:xml:ns:caldav" }) - return xml.xpath.Evaluate(query, None, xpath_context) - def setupRights(self, rights): rights_str = "".join(["<%s/>" % x for x in self.rightsToSOGoRights(rights) ]) aclQuery = """ @@ -284,23 +277,24 @@ class DAVCalendarAclTest(DAVAclTest): return event - def _calendarDataInMultistatus(self, top_node, filename, + def _calendarDataInMultistatus(self, query, filename, response_tag = "D:response"): event = None - response_nodes = self.xpath_query("/D:multistatus/%s" % response_tag, - top_node) + query.xpath_namespace = { "D": "DAV:", + "C": "urn:ietf:params:xml:ns:caldav" } + response_nodes = query.xpath_evaluate("/D:multistatus/%s" % response_tag) for response_node in response_nodes: - href_node = self.xpath_query("D:href", response_node)[0] + href_node = query.xpath_evaluate("D:href", response_node)[0] href = href_node.childNodes[0].nodeValue if href.endswith(filename): - propstat_nodes = self.xpath_query("D:propstat", response_node) + propstat_nodes = query.xpath_evaluate("D:propstat", response_node) for propstat_node in propstat_nodes: - status_node = self.xpath_query("D:status", - propstat_node)[0] + status_node = query.xpath_evaluate("D:status", + propstat_node)[0] status = status_node.childNodes[0].nodeValue - data_nodes = self.xpath_query("D:prop/C:calendar-data", - propstat_node) + data_nodes = query.xpath_evaluate("D:prop/C:calendar-data", + propstat_node) if status.endswith("200 OK"): if (len(data_nodes) > 0 and len(data_nodes[0].childNodes) > 0): @@ -323,8 +317,7 @@ class DAVCalendarAclTest(DAVAclTest): 1) self.subscriber_client.execute(propfind) if propfind.response["status"] != 403: - event = self._calendarDataInMultistatus(propfind.response["document"], - filename) + event = self._calendarDataInMultistatus(propfind, filename) return event @@ -338,8 +331,7 @@ class DAVCalendarAclTest(DAVAclTest): [ url ]) self.subscriber_client.execute(multiget) if multiget.response["status"] != 403: - event = self._calendarDataInMultistatus(multiget.response["document"], - url) + event = self._calendarDataInMultistatus(multiget, url) return event @@ -352,8 +344,8 @@ class DAVCalendarAclTest(DAVAclTest): ["{urn:ietf:params:xml:ns:caldav}calendar-data"]) self.subscriber_client.execute(sync_query) if sync_query.response["status"] != 403: - event = self._calendarDataInMultistatus(sync_query.response["document"], - url, "D:sync-response") + event = self._calendarDataInMultistatus(sync_query, url, + "D:sync-response") return event diff --git a/Tests/test-wedavsync.py b/Tests/test-wedavsync.py index f0ccf7200..46b96559d 100755 --- a/Tests/test-wedavsync.py +++ b/Tests/test-wedavsync.py @@ -5,7 +5,6 @@ from config import hostname, port, username, password import sys import unittest import webdavlib -import xml.xpath import time resource = '/SOGo/dav/%s/Calendar/test-webdavsync/' % username @@ -19,11 +18,6 @@ class WebdavSyncTest(unittest.TestCase): delete = webdavlib.WebDAVDELETE(resource) self.client.execute(delete) - def _xpath_query(self, query, top_node): - xpath_context = xml.xpath.CreateContext(top_node) - xpath_context.setNamespaces({ "D": "DAV:" }) - return xml.xpath.Evaluate(query, None, xpath_context) - def test(self): # missing tests: # invalid tokens: negative, non-numeric, > current timestamp @@ -49,8 +43,7 @@ class WebdavSyncTest(unittest.TestCase): self.assertEquals(query1.response["status"], 207, ("query1: invalid status code: %d (!= 207)" % query1.response["status"])) - token_node = self._xpath_query("/D:multistatus/D:sync-token", - query1.response["document"])[0] + token_node = query1.xpath_evaluate("/D:multistatus/D:sync-token")[0] # 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) @@ -62,8 +55,7 @@ class WebdavSyncTest(unittest.TestCase): query2 = webdavlib.WebDAVSyncQuery(resource, "1234", [ "getetag" ]) self.client.execute(query2) self.assertEquals(query2.response["status"], 403) - cond_nodes = self._xpath_query("/D:error/D:valid-sync-token", - query2.response["document"]) + cond_nodes = query2.xpath_evaluate("/D:error/D:valid-sync-token") self.assertTrue(len(cond_nodes) > 0, "expected 'valid-sync-token' condition error") diff --git a/Tests/webdavlib.py b/Tests/webdavlib.py index 1a837c1e7..963fe8358 100644 --- a/Tests/webdavlib.py +++ b/Tests/webdavlib.py @@ -1,11 +1,15 @@ +import cStringIO import httplib import M2Crypto.httpslib import time import xml.sax.saxutils import xml.dom.ext.reader.Sax2 +import xml.xpath import sys class WebDAVClient: + user_agent = "Mozilla/5.0" + def __init__(self, hostname, port, username, password, forcessl = False): if port == "443" or forcessl: self.conn = M2Crypto.httpslib.HTTPSConnection(hostname, int(port), @@ -17,7 +21,7 @@ class WebDAVClient: .encode('base64')[:-1]) def _prepare_headers(self, query, body): - headers = { "User-Agent": "Mozilla/5.0", + headers = { "User-Agent": self.user_agent, "authorization": "Basic %s" % self.simpleauth_hash } if body is not None: headers["content-length"] = len(body) @@ -89,6 +93,7 @@ class WebDAVQuery(HTTPQuery): self.ns_mgr = _WD_XMLNS_MGR() self.top_node = None self.xml_response = None + self.xpath_namespace = { "D": "DAV:" } def render(self): if self.top_node is not None: @@ -118,9 +123,18 @@ class WebDAVQuery(HTTPQuery): and (headers["content-type"].startswith("application/xml") or headers["content-type"].startswith("text/xml")) and int(headers["content-length"]) > 0): - dom_response = xml.dom.ext.reader.Sax2.FromXml(self.response["body"]) + reader = xml.dom.ext.reader.Sax2.Reader() + stream = cStringIO.StringIO(self.response["body"]) + dom_response = reader.fromStream(stream) self.response["document"] = dom_response.documentElement + def xpath_evaluate(self, query, top_node = None): + if top_node is None: + top_node = self.response["document"] + xpath_context = xml.xpath.CreateContext(top_node) + xpath_context.setNamespaces(self.xpath_namespace) + return xml.xpath.Evaluate(query, None, xpath_context) + class WebDAVMKCOL(WebDAVQuery): method = "MKCOL"