[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/dav/ Merged
isarsprint-dav-work changes r27855:28053 into the trunk;
this adds opaque properties and PROPPATCH support.
Martijn Pieters
mj at zopatista.com
Wed Oct 13 05:59:49 EDT 2004
Log message for revision 28056:
Merged isarsprint-dav-work changes r27855:28053 into the trunk; this adds opaque properties and PROPPATCH support.
Changed:
U Zope3/trunk/src/zope/app/dav/configure.zcml
A Zope3/trunk/src/zope/app/dav/opaquenamespaces.py
U Zope3/trunk/src/zope/app/dav/propfind.py
A Zope3/trunk/src/zope/app/dav/proppatch.py
A Zope3/trunk/src/zope/app/dav/tests/test_doctests.py
U Zope3/trunk/src/zope/app/dav/tests/test_propfind.py
A Zope3/trunk/src/zope/app/dav/tests/test_proppatch.py
A Zope3/trunk/src/zope/app/dav/tests/unitfixtures.py
-=-
Modified: Zope3/trunk/src/zope/app/dav/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/dav/configure.zcml 2004-10-13 09:49:58 UTC (rev 28055)
+++ Zope3/trunk/src/zope/app/dav/configure.zcml 2004-10-13 09:59:47 UTC (rev 28056)
@@ -11,6 +11,14 @@
allowed_attributes="PROPFIND setDepth getDepth" />
<view
+ for="*"
+ name="PROPPATCH"
+ type="zope.publisher.interfaces.http.IHTTPRequest"
+ factory=".proppatch.PROPPATCH"
+ permission="zope.ManageContent"
+ allowed_attributes="PROPPATCH" />
+
+ <view
for="zope.app.http.interfaces.INullResource"
name="MKCOL"
type="zope.publisher.interfaces.http.IHTTPRequest"
@@ -99,7 +107,23 @@
for="*"
permission="zope.Public"
factory=".adapter.DAVSchemaAdapter" />
-
+
+ <!-- XXX: This interface needs to be split up so we can apply seperate
+ permissions for reading and writing -->
+ <adapter
+ factory=".opaquenamespaces.DAVOpaqueNamespacesAdapter"
+ provides=".opaquenamespaces.IDAVOpaqueNamespaces"
+ for="zope.app.annotation.interfaces.IAnnotatable"
+ trusted="true"
+ />
+
+ <class class=".opaquenamespaces.DAVOpaqueNamespacesAdapter">
+ <require
+ permission="zope.ManageContent"
+ interface=".opaquenamespaces.IDAVOpaqueNamespaces"
+ />
+ </class>
+
<dav:provideInterface
for="http://purl.org/dc/1.1"
interface="zope.app.dublincore.interfaces.IZopeDublinCore" />
Copied: Zope3/trunk/src/zope/app/dav/opaquenamespaces.py (from rev 28054, Zope3/branches/isarsprint-dav-work/src/zope/app/dav/opaquenamespaces.py)
Modified: Zope3/trunk/src/zope/app/dav/propfind.py
===================================================================
--- Zope3/trunk/src/zope/app/dav/propfind.py 2004-10-13 09:49:58 UTC (rev 28055)
+++ Zope3/trunk/src/zope/app/dav/propfind.py 2004-10-13 09:59:47 UTC (rev 28056)
@@ -19,12 +19,11 @@
from zope.schema import getFieldNamesInOrder
from zope.app import zapi
from zope.app.container.interfaces import IReadContainer
-from zope.app.dav.interfaces import IDAVWidget
from zope.app.form.utility import setUpWidgets
-from interfaces import IDAVNamespace
+from interfaces import IDAVWidget, IDAVNamespace
+from opaquenamespaces import IDAVOpaqueNamespaces
-
class PROPFIND(object):
"""PROPFIND handler for all objects"""
@@ -49,169 +48,92 @@
self._depth = depth.lower()
def PROPFIND(self):
- request = self.request
- resource_url = str(zapi.getView(self.context, 'absolute_url', request))
- if IReadContainer.providedBy(self.context):
- resource_url = resource_url + '/'
- data = request.bodyFile
- data.seek(0)
- response = ''
- body = ''
-
if self.content_type not in ['text/xml', 'application/xml']:
- request.response.setStatus(400)
- return body
-
+ self.request.response.setStatus(400)
+ return ''
if self.getDepth() not in ['0', '1', 'infinity']:
- request.response.setStatus(400)
- return body
+ self.request.response.setStatus(400)
+ return ''
- xmldoc = minidom.parse(data)
- response = minidom.Document()
- ms = response.createElement('multistatus')
+ resource_url = str(zapi.getView(self.context, 'absolute_url',
+ self.request))
+ if IReadContainer.providedBy(self.context):
+ resource_url += '/'
+
+ self.request.bodyFile.seek(0)
+ xmldoc = minidom.parse(self.request.bodyFile)
+ resp = minidom.Document()
+ ms = resp.createElement('multistatus')
ms.setAttribute('xmlns', self.default_ns)
- response.appendChild(ms)
- re = response.createElement('response')
- ms.appendChild(re)
- href = response.createElement('href')
- re.appendChild(href)
- r_url = response.createTextNode(resource_url)
- href.appendChild(r_url)
+ resp.appendChild(ms)
+ ms.appendChild(resp.createElement('response'))
+ ms.lastChild.appendChild(resp.createElement('href'))
+ ms.lastChild.lastChild.appendChild(resp.createTextNode(resource_url))
+
_avail_props = {}
- # TODO: For now, list the propnames for the all namespaces
- # but later on, we need to list *all* propnames from *all* known
- # namespaces that this object has.
+ # List all *registered* DAV interface namespaces and their properties
for ns, iface in zapi.getUtilitiesFor(IDAVNamespace):
- _avail_props[ns] = getFieldNamesInOrder(iface)
+ _avail_props[ns] = getFieldNamesInOrder(iface)
+ # List all opaque DAV namespaces and the properties we know of
+ for ns, oprops in IDAVOpaqueNamespaces(self.context, {}).items():
+ _avail_props[ns] = oprops.keys()
+
propname = xmldoc.getElementsByTagNameNS(self.default_ns, 'propname')
if propname:
- self._handlePropname(response, re, _avail_props)
+ self._handlePropname(resp, _avail_props)
+ else:
+ source = xmldoc.getElementsByTagNameNS(self.default_ns, 'prop')
+ self._handlePropvalues(source, resp, _avail_props)
- source = xmldoc.getElementsByTagNameNS(self.default_ns, 'prop')
- _props = {}
- if not source and not propname:
- _props = self._handleAllprop(_avail_props, _props)
-
- if source and not propname:
- _props = self._handleProp(source, _props)
-
- avail, not_avail = self._propertyResolver(_props)
-
- if avail:
- pstat = response.createElement('propstat')
- re.appendChild(pstat)
- prop = response.createElement('prop')
- pstat.appendChild(prop)
- status = response.createElement('status')
- pstat.appendChild(status)
- text = response.createTextNode('HTTP/1.1 200 OK')
- status.appendChild(text)
- count = 0
- for ns in avail.keys():
- attr_name = 'a%s' % count
- if ns is not None and ns != self.default_ns:
- count += 1
- prop.setAttribute('xmlns:%s' % attr_name, ns)
- iface = _props[ns]['iface']
- adapter = iface(self.context, None)
- initial = {}
- for name in avail.get(ns):
- value = getattr(adapter, name, None)
- if value is not None:
- initial[name] = value
- setUpWidgets(self, iface, IDAVWidget,
- ignoreStickyValues=True, initial=initial,
- names=avail.get(ns))
- for p in avail.get(ns):
- el = response.createElement('%s' % p )
- if ns is not None and ns != self.default_ns:
- el.setAttribute('xmlns', attr_name)
- prop.appendChild(el)
- value = getattr(self, p+'_widget')()
- if isinstance(value, (unicode, str)):
- # Get the widget value here
- value = response.createTextNode(value)
- el.appendChild(value)
- else:
- if zapi.isinstance(value, minidom.Node):
- el.appendChild(value)
- else:
- # Try to string-ify
- value = str(getattr(self, p+'_widget'))
- # Get the widget value here
- value = response.createTextNode(value)
- el.appendChild(value)
-
- if not_avail:
- pstat = response.createElement('propstat')
- re.appendChild(pstat)
- prop = response.createElement('prop')
- pstat.appendChild(prop)
- status = response.createElement('status')
- pstat.appendChild(status)
- text = response.createTextNode('HTTP/1.1 404 Not Found')
- status.appendChild(text)
- count = 0
- for ns in not_avail.keys():
- attr_name = 'a%s' % count
- if ns is not None and ns != self.default_ns:
- count += 1
- prop.setAttribute('xmlns:%s' % attr_name, ns)
- for p in not_avail.get(ns):
- el = response.createElement('%s' % p )
- prop.appendChild(el)
- if ns is not None and ns != self.default_ns:
- el.setAttribute('xmlns', attr_name)
-
self._depthRecurse(ms)
- body = response.toxml().encode('utf-8')
- request.response.setBody(body)
- request.response.setStatus(207)
+ body = resp.toxml().encode('utf-8')
+ self.request.response.setBody(body)
+ self.request.response.setStatus(207)
return body
def _depthRecurse(self, ms):
depth = self.getDepth()
- if depth == '1':
- subdepth = '0'
- if depth == 'infinity':
- subdepth = 'infinity'
- if depth != '0':
- if IReadContainer.providedBy(self.context):
- for id, obj in self.context.items():
- pfind = zapi.queryView(obj, 'PROPFIND', self.request, None)
- if pfind is not None:
- pfind.setDepth(subdepth)
- value = pfind.PROPFIND()
- parsed = minidom.parseString(value)
- responses = parsed.getElementsByTagNameNS(
- self.default_ns, 'response')
- for r in responses:
- ms.appendChild(r)
+ if depth == '0' or not IReadContainer.providedBy(self.context):
+ return
+ subdepth = (depth == '1') and '0' or 'infinity'
+ for id, obj in self.context.items():
+ pfind = zapi.queryView(obj, 'PROPFIND', self.request, None)
+ if pfind is None:
+ continue
+ pfind.setDepth(subdepth)
+ value = pfind.PROPFIND()
+ parsed = minidom.parseString(value)
+ responses = parsed.getElementsByTagNameNS(
+ self.default_ns, 'response')
+ for r in responses:
+ ms.appendChild(ms.ownerDocument.importNode(r, True))
- def _handleProp(self, source, _props):
+ def _handleProp(self, source):
+ props = {}
source = source[0]
childs = [e for e in source.childNodes
if e.nodeType == e.ELEMENT_NODE]
for node in childs:
ns = node.namespaceURI
iface = zapi.queryUtility(IDAVNamespace, ns)
- value = _props.get(ns, {'iface': iface, 'props': []})
+ value = props.get(ns, {'iface': iface, 'props': []})
value['props'].append(node.localName)
- _props[ns] = value
- return _props
+ props[ns] = value
+ return props
- def _handleAllprop(self, _avail_props, _props):
+ def _handleAllprop(self, _avail_props):
+ props = {}
for ns in _avail_props.keys():
iface = zapi.queryUtility(IDAVNamespace, ns)
- _props[ns] = {'iface': iface, 'props': _avail_props.get(ns)}
- return _props
+ props[ns] = {'iface': iface, 'props': _avail_props.get(ns)}
+ return props
- def _handlePropname(self, response, re, _avail_props):
- pstat = response.createElement('propstat')
- re.appendChild(pstat)
- prop = response.createElement('prop')
- pstat.appendChild(prop)
+ def _handlePropname(self, resp, _avail_props):
+ re = resp.lastChild.lastChild
+ re.appendChild(resp.createElement('propstat'))
+ prop = resp.createElement('prop')
+ re.lastChild.appendChild(prop)
count = 0
for ns in _avail_props.keys():
attr_name = 'a%s' % count
@@ -219,25 +141,42 @@
count += 1
prop.setAttribute('xmlns:%s' % attr_name, ns)
for p in _avail_props.get(ns):
- el = response.createElement(p)
+ el = resp.createElement(p)
prop.appendChild(el)
if ns is not None and ns != self.default_ns:
el.setAttribute('xmlns', attr_name)
- status = response.createElement('status')
- pstat.appendChild(status)
- text = response.createTextNode('HTTP/1.1 200 OK')
- status.appendChild(text)
+ re.lastChild.appendChild(resp.createElement('status'))
+ re.lastChild.lastChild.appendChild(
+ resp.createTextNode('HTTP/1.1 200 OK'))
+ def _handlePropvalues(self, source, resp, _avail_props):
+ if not source:
+ _props = self._handleAllprop(_avail_props)
+ else:
+ _props = self._handleProp(source)
+
+ avail, not_avail = self._propertyResolver(_props)
+ if avail:
+ self._renderAvail(avail, resp, _props)
+ if not_avail:
+ self._renderNotAvail(not_avail, resp)
+
def _propertyResolver(self, _props):
avail = {}
not_avail = {}
+ oprops = IDAVOpaqueNamespaces(self.context, {})
for ns in _props.keys():
iface = _props[ns]['iface']
for p in _props[ns]['props']:
- if _props[ns]['iface'] is None:
- l = not_avail.get(ns, [])
- l.append(p)
- not_avail[ns] = l
+ if iface is None:
+ if oprops.get(ns, {}).get(p):
+ l = avail.get(ns, [])
+ l.append(p)
+ avail[ns] = l
+ else:
+ l = not_avail.get(ns, [])
+ l.append(p)
+ not_avail[ns] = l
continue
adapter = iface(self.context, None)
if adapter is None:
@@ -255,3 +194,76 @@
not_avail[ns] = l
return avail, not_avail
+
+ def _renderAvail(self, avail, resp, _props):
+ re = resp.lastChild.lastChild
+ re.appendChild(resp.createElement('propstat'))
+ prop = resp.createElement('prop')
+ re.lastChild.appendChild(prop)
+ re.lastChild.appendChild(resp.createElement('status'))
+ re.lastChild.lastChild.appendChild(
+ resp.createTextNode('HTTP/1.1 200 OK'))
+ count = 0
+ for ns in avail.keys():
+ attr_name = 'a%s' % count
+ if ns is not None and ns != self.default_ns:
+ count += 1
+ prop.setAttribute('xmlns:%s' % attr_name, ns)
+ iface = _props[ns]['iface']
+
+ if not iface:
+ # The opaque properties case, hand it off
+ oprops = IDAVOpaqueNamespaces(self.context, {})
+ for name in avail.get(ns):
+ oprops.renderProperty(ns, attr_name, name, prop)
+ continue
+
+ # The registered namespace case
+ initial = {}
+ adapter = iface(self.context, None)
+ for name in avail.get(ns):
+ value = getattr(adapter, name, None)
+ if value is not None:
+ initial[name] = value
+ setUpWidgets(self, iface, IDAVWidget,
+ ignoreStickyValues=True, initial=initial,
+ names=avail.get(ns))
+
+ for p in avail.get(ns):
+ el = resp.createElement('%s' % p )
+ if ns is not None and ns != self.default_ns:
+ el.setAttribute('xmlns', attr_name)
+ prop.appendChild(el)
+ value = getattr(self, p+'_widget')()
+
+ if isinstance(value, (unicode, str)):
+ # Get the widget value here
+ el.appendChild(resp.createTextNode(value))
+ else:
+ if zapi.isinstance(value, minidom.Node):
+ el.appendChild(value)
+ else:
+ # Try to string-ify
+ value = str(getattr(self, p+'_widget'))
+ # Get the widget value here
+ el.appendChild(resp.createTextNode(value))
+
+ def _renderNotAvail(self, not_avail, resp):
+ re = resp.lastChild.lastChild
+ re.appendChild(resp.createElement('propstat'))
+ prop = resp.createElement('prop')
+ re.lastChild.appendChild(prop)
+ re.lastChild.appendChild(resp.createElement('status'))
+ re.lastChild.lastChild.appendChild(
+ resp.createTextNode('HTTP/1.1 404 Not Found'))
+ count = 0
+ for ns in not_avail.keys():
+ attr_name = 'a%s' % count
+ if ns is not None and ns != self.default_ns:
+ count += 1
+ prop.setAttribute('xmlns:%s' % attr_name, ns)
+ for p in not_avail.get(ns):
+ el = resp.createElement('%s' % p )
+ prop.appendChild(el)
+ if ns is not None and ns != self.default_ns:
+ el.setAttribute('xmlns', attr_name)
Copied: Zope3/trunk/src/zope/app/dav/proppatch.py (from rev 28054, Zope3/branches/isarsprint-dav-work/src/zope/app/dav/proppatch.py)
Property changes on: Zope3/trunk/src/zope/app/dav/proppatch.py
___________________________________________________________________
Name: svn:keywords
+ id
Name: svn:eol-style
+ native
Added: Zope3/trunk/src/zope/app/dav/tests/test_doctests.py
===================================================================
--- Zope3/trunk/src/zope/app/dav/tests/test_doctests.py 2004-10-13 09:49:58 UTC (rev 28055)
+++ Zope3/trunk/src/zope/app/dav/tests/test_doctests.py 2004-10-13 09:59:47 UTC (rev 28056)
@@ -0,0 +1,27 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test makeDOMStandalone utility
+
+$Id: test_adapter.py 27505 2004-09-12 14:46:41Z philikon $
+"""
+import unittest
+from zope.testing.doctestunit import DocTestSuite
+
+def test_suite():
+ return unittest.TestSuite((
+ DocTestSuite('zope.app.dav.opaquenamespaces'),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Modified: Zope3/trunk/src/zope/app/dav/tests/test_propfind.py
===================================================================
--- Zope3/trunk/src/zope/app/dav/tests/test_propfind.py 2004-10-13 09:49:58 UTC (rev 28055)
+++ Zope3/trunk/src/zope/app/dav/tests/test_propfind.py 2004-10-13 09:59:47 UTC (rev 28056)
@@ -22,6 +22,8 @@
from zope.interface import Interface, implements, directlyProvides
from zope.publisher.interfaces.http import IHTTPRequest
+from zope.publisher.http import status_reasons
+
from zope.pagetemplate.tests.util import normalize_xml
from zope.schema import getFieldNamesInOrder
from zope.schema.interfaces import IText, ITextLine, IDatetime, ISequence
@@ -30,11 +32,10 @@
from zope.app.tests import ztapi
from zope.app.traversing.api import traverse
+from zope.app.container.interfaces import IReadContainer
from zope.publisher.browser import TestRequest
-from zope.app.filerepresentation.interfaces import IWriteFile
from zope.app.site.tests.placefulsetup import PlacefulSetup
from zope.app.traversing.browser import AbsoluteURL
-from zope.app.container.interfaces import IReadContainer
from zope.app.dublincore.interfaces import IZopeDublinCore
from zope.app.dublincore.annotatableadapter import ZDCAnnotatableAdapter
from zope.app.annotation.interfaces import IAnnotatable, IAnnotations
@@ -45,50 +46,14 @@
from zope.app.dav.interfaces import IDAVNamespace
from zope.app.dav.interfaces import IDAVWidget
from zope.app.dav.widget import TextDAVWidget, SequenceDAVWidget
+from zope.app.dav.opaquenamespaces import DAVOpaqueNamespacesAdapter
+from zope.app.dav.opaquenamespaces import IDAVOpaqueNamespaces
+from unitfixtures import File, Folder, FooZPT
+
import zope.app.location
-class Folder(zope.app.location.Location):
- implements(IReadContainer)
-
- def __init__(self, name, level=0, parent=None):
- self.name = self.__name__ = name
- self.level=level
- self.__parent__ = parent
-
- def items(self):
- if self.level == 2:
- return (('last', File('last', 'text/plain', 'blablabla', self)),)
- result = []
- for i in range(1, 3):
- result.append((str(i),
- File(str(i), 'text/plain', 'blablabla', self)))
- result.append(('sub1',
- Folder('sub1', level=self.level+1, parent=self)))
- return tuple(result)
-
-class File(zope.app.location.Location):
-
- implements(IWriteFile)
-
- def __init__(self, name, content_type, data, parent=None):
- self.name = self.__name__ = name
- self.content_type = content_type
- self.data = data
- self.__parent__ = parent
-
- def write(self, data):
- self.data = data
-
-class FooZPT(zope.app.location.Location):
-
- implements(IAnnotatable)
-
- def getSource(self):
- return 'bla bla bla'
-
-
def _createRequest(body=None, headers=None, skip_headers=None):
if body is None:
body = '''<?xml version="1.0" ?>
@@ -144,6 +109,8 @@
ztapi.provideAdapter(IAnnotatable, IAnnotations, AttributeAnnotations)
ztapi.provideAdapter(IAnnotatable, IZopeDublinCore,
ZDCAnnotatableAdapter)
+ ztapi.provideAdapter(IAnnotatable, IDAVOpaqueNamespaces,
+ DAVOpaqueNamespacesAdapter)
utils = zapi.getGlobalService('Utilities')
directlyProvides(IDAVSchema, IDAVNamespace)
utils.provideUtility(IDAVNamespace, IDAVSchema, 'DAV:')
@@ -252,239 +219,112 @@
# Check HTTP Response
self.assertEqual(request.response.getStatus(), 400)
self.assertEqual(pfind.getDepth(), 'full')
-
- def test_davpropdctitle(self):
- root = self.rootFolder
- zpt = traverse(root, 'zpt')
- dc = IZopeDublinCore(zpt)
- dc.title = u'Test Title'
+
+ def _checkPropfind(self, obj, req, expect, depth='0', resp=None):
body = '''<?xml version="1.0" ?>
- <propfind xmlns="DAV:">
- <prop xmlns:DC="http://www.purl.org/dc/1.1">
- <DC:title />
- </prop>
- </propfind>
- '''
-
- request = _createRequest(body=body,
- headers={'Content-type':'text/xml',
- 'Depth':'0'})
-
- resource_url = str(zapi.getView(zpt, 'absolute_url', request))
- expect = '''<?xml version="1.0" ?>
- <multistatus xmlns="DAV:">
- <response>
- <href>%(resource_url)s</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0">Test Title</title>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- </multistatus>
- ''' % {'resource_url':resource_url}
-
- pfind = propfind.PROPFIND(zpt, request)
+ <propfind xmlns="DAV:">%s</propfind>
+ ''' % req
+ request = _createRequest(body=body, headers={
+ 'Content-type': 'text/xml', 'Depth': depth})
+ resource_url = str(zapi.getView(obj, 'absolute_url', request))
+ if IReadContainer.providedBy(obj):
+ resource_url += '/'
+ if resp is None:
+ resp = '''<?xml version="1.0" ?>
+ <multistatus xmlns="DAV:"><response>
+ <href>%%(resource_url)s</href>
+ <propstat>%s
+ <status>HTTP/1.1 200 OK</status>
+ </propstat></response></multistatus>
+ '''
+ expect = resp % expect
+ expect = expect % {'resource_url': resource_url}
+ pfind = propfind.PROPFIND(obj, request)
pfind.PROPFIND()
# Check HTTP Response
self.assertEqual(request.response.getStatus(), 207)
- self.assertEqual(pfind.getDepth(), '0')
+ self.assertEqual(pfind.getDepth(), depth)
s1 = normalize_xml(request.response._body)
s2 = normalize_xml(expect)
self.assertEqual(s1, s2)
-
+
+ def test_davpropdctitle(self):
+ root = self.rootFolder
+ zpt = traverse(root, 'zpt')
+ dc = IZopeDublinCore(zpt)
+ dc.title = u'Test Title'
+ req = '''<prop xmlns:DC="http://www.purl.org/dc/1.1">
+ <DC:title />
+ </prop>'''
+
+ expect = '''<prop xmlns:a0="http://www.purl.org/dc/1.1">
+ <title xmlns="a0">Test Title</title></prop>'''
+ self._checkPropfind(zpt, req, expect)
+
def test_davpropdccreated(self):
root = self.rootFolder
zpt = traverse(root, 'zpt')
dc = IZopeDublinCore(zpt)
dc.created = datetime.utcnow()
- body = '''<?xml version="1.0" ?>
- <propfind xmlns="DAV:">
- <prop xmlns:DC="http://www.purl.org/dc/1.1">
- <DC:created />
- </prop>
- </propfind>
- '''
+ req = '''<prop xmlns:DC="http://www.purl.org/dc/1.1">
+ <DC:created /></prop>'''
+ expect = '''<prop xmlns:a0="http://www.purl.org/dc/1.1">
+ <created xmlns="a0">%s</created></prop>''' % dc.created
+ self._checkPropfind(zpt, req, expect)
- request = _createRequest(body=body,
- headers={'Content-type':'text/xml',
- 'Depth':'0'})
-
- resource_url = str(zapi.getView(zpt, 'absolute_url', request))
- expect = '''<?xml version="1.0" ?>
- <multistatus xmlns="DAV:">
- <response>
- <href>%(resource_url)s</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <created xmlns="a0">%(created)s</created>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- </multistatus>
- ''' % {'resource_url':resource_url,
- 'created': dc.created }
-
- pfind = propfind.PROPFIND(zpt, request)
- pfind.PROPFIND()
- # Check HTTP Response
- self.assertEqual(request.response.getStatus(), 207)
- self.assertEqual(pfind.getDepth(), '0')
- s1 = normalize_xml(request.response._body)
- s2 = normalize_xml(expect)
- self.assertEqual(s1, s2)
-
def test_davpropdcsubjects(self):
root = self.rootFolder
zpt = traverse(root, 'zpt')
dc = IZopeDublinCore(zpt)
dc.subjects = (u'Bla', u'Ble', u'Bli')
- body = '''<?xml version="1.0" ?>
- <propfind xmlns="DAV:">
- <prop xmlns:DC="http://www.purl.org/dc/1.1">
- <DC:subjects />
- </prop>
- </propfind>
- '''
+ req = '''<prop xmlns:DC="http://www.purl.org/dc/1.1">
+ <DC:subjects /></prop>'''
- request = _createRequest(body=body,
- headers={'Content-type':'text/xml',
- 'Depth':'0'})
+ expect = '''<prop xmlns:a0="http://www.purl.org/dc/1.1">
+ <subjects xmlns="a0">%s</subjects></prop>''' % u', '.join(dc.subjects)
+ self._checkPropfind(zpt, req, expect)
- resource_url = str(zapi.getView(zpt, 'absolute_url', request))
- expect = '''<?xml version="1.0" ?>
- <multistatus xmlns="DAV:">
- <response>
- <href>%(resource_url)s</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <subjects xmlns="a0">%(subjects)s</subjects>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- </multistatus>
- ''' % {'resource_url':resource_url,
- 'subjects': u', '.join(dc.subjects) }
-
- pfind = propfind.PROPFIND(zpt, request)
- pfind.PROPFIND()
- # Check HTTP Response
- self.assertEqual(request.response.getStatus(), 207)
- self.assertEqual(pfind.getDepth(), '0')
- s1 = normalize_xml(request.response._body)
- s2 = normalize_xml(expect)
- self.assertEqual(s1, s2)
-
def test_davpropname(self):
root = self.rootFolder
zpt = traverse(root, 'zpt')
- body = '''<?xml version="1.0" ?>
- <propfind xmlns="DAV:">
- <propname/>
- </propfind>
- '''
+ oprops = IDAVOpaqueNamespaces(zpt)
+ oprops[u'http://foo/bar'] = {u'egg': '<egg>spam</egg>'}
+ req = '''<propname/>'''
- request = _createRequest(body=body,
- headers={'Content-type':'text/xml',
- 'Depth':'0'})
-
- resource_url = str(zapi.getView(zpt, 'absolute_url', request))
- props_xml = ''
+ expect = ''
props = getFieldNamesInOrder(IZopeDublinCore)
for p in props:
- props_xml += '<%s xmlns="a0"/>' % p
+ expect += '<%s xmlns="a0"/>' % p
+ expect += '<egg xmlns="a1"/>'
props = getFieldNamesInOrder(IDAVSchema)
for p in props:
- props_xml += '<%s/>' % p
- expect = '''<?xml version="1.0" ?>
- <multistatus xmlns="DAV:">
- <response>
- <href>%(resource_url)s</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- %(props_xml)s
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- </multistatus>
- ''' % {'resource_url':resource_url,
- 'props_xml':props_xml}
+ expect += '<%s/>' % p
+ expect = '''
+ <prop xmlns:a0="http://www.purl.org/dc/1.1" xmlns:a1="http://foo/bar">
+ %s</prop>''' % expect
+ self._checkPropfind(zpt, req, expect)
- pfind = propfind.PROPFIND(zpt, request)
- pfind.PROPFIND()
- # Check HTTP Response
- self.assertEqual(request.response.getStatus(), 207)
- self.assertEqual(pfind.getDepth(), '0')
- s1 = normalize_xml(request.response._body)
- s2 = normalize_xml(expect)
- self.assertEqual(s1, s2)
-
def test_davpropnamefolderdepth0(self):
root = self.rootFolder
folder = traverse(root, 'folder')
- body = '''<?xml version="1.0" ?>
- <propfind xmlns="DAV:">
- <propname/>
- </propfind>
- '''
+ req = '''<propname/>'''
- request = _createRequest(body=body,
- headers={'Content-type':'text/xml',
- 'Depth':'0'})
-
- resource_url = str(zapi.getView(folder, 'absolute_url', request))
- resource_url = "%s/" % resource_url
- props_xml = ''
+ expect = ''
props = getFieldNamesInOrder(IZopeDublinCore)
for p in props:
- props_xml += '<%s xmlns="a0"/>' % p
+ expect += '<%s xmlns="a0"/>' % p
props = getFieldNamesInOrder(IDAVSchema)
for p in props:
- props_xml += '<%s/>' % p
- expect = '''<?xml version="1.0" ?>
- <multistatus xmlns="DAV:">
- <response>
- <href>%(resource_url)s</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- %(props_xml)s
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- </multistatus>
- ''' % {'resource_url':resource_url,
- 'props_xml':props_xml}
+ expect += '<%s/>' % p
+ expect = '''<prop xmlns:a0="http://www.purl.org/dc/1.1">
+ %s</prop>''' % expect
+ self._checkPropfind(folder, req, expect)
- pfind = propfind.PROPFIND(folder, request)
-
- pfind.PROPFIND()
- # Check HTTP Response
- self.assertEqual(request.response.getStatus(), 207)
- self.assertEqual(pfind.getDepth(), '0')
- s1 = normalize_xml(request.response._body)
- s2 = normalize_xml(expect)
- self.assertEqual(s1, s2)
-
def test_davpropnamefolderdepth1(self):
root = self.rootFolder
folder = traverse(root, 'folder')
- body = '''<?xml version="1.0" ?>
- <propfind xmlns="DAV:">
- <propname/>
- </propfind>
- '''
+ req = '''<propname/>'''
- request = _createRequest(body=body,
- headers={'Content-type':'text/xml',
- 'Depth':'1'})
-
- resource_url = str(zapi.getView(folder, 'absolute_url', request))
- resource_url = "%s/" % resource_url
props_xml = ''
props = getFieldNamesInOrder(IZopeDublinCore)
for p in props:
@@ -493,152 +333,24 @@
for p in props:
props_xml += '<%s/>' % p
- expect = '''<?xml version="1.0" ?>
- <multistatus xmlns="DAV:">
- <response>
- <href>http://127.0.0.1/folder/</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/1</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/2</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/sub1/</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- </multistatus>'''
+ expect = ''
+ for p in ('', '1', '2', 'sub1/'):
+ expect += '''
+ <response><href>%(path)s</href>
+ <propstat><prop xmlns:a0="http://www.purl.org/dc/1.1">
+ %(props_xml)s</prop><status>HTTP/1.1 200 OK</status>
+ </propstat></response>
+ ''' % {'path': '%(resource_url)s' + p, 'props_xml': props_xml}
+ resp = '''<?xml version="1.0" ?>
+ <multistatus xmlns="DAV:">%s</multistatus>'''
+ self._checkPropfind(folder, req, expect, depth='1', resp=resp)
- pfind = propfind.PROPFIND(folder, request)
-
- pfind.PROPFIND()
- # Check HTTP Response
- self.assertEqual(request.response.getStatus(), 207)
- self.assertEqual(pfind.getDepth(), '1')
- s1 = normalize_xml(request.response._body)
- s2 = normalize_xml(expect)
- self.assertEqual(s1, s2)
-
def test_davpropnamefolderdepthinfinity(self):
root = self.rootFolder
folder = traverse(root, 'folder')
- body = '''<?xml version="1.0" ?>
- <propfind xmlns="DAV:">
- <propname/>
- </propfind>
- '''
+ req = '''<propname/>'''
- request = _createRequest(body=body,
- headers={'Content-type':'text/xml',
- 'Depth':'infinity'})
-
- resource_url = str(zapi.getView(folder, 'absolute_url', request))
- resource_url = "%s/" % resource_url
props_xml = ''
props = getFieldNamesInOrder(IZopeDublinCore)
for p in props:
@@ -647,252 +359,47 @@
for p in props:
props_xml += '<%s/>' % p
- expect = '''<?xml version="1.0" ?>
- <multistatus xmlns="DAV:">
- <response>
- <href>http://127.0.0.1/folder/</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/1</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/2</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/sub1/</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/sub1/1</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/sub1/2</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/sub1/sub1/</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- <response>
- <href>http://127.0.0.1/folder/sub1/sub1/last</href>
- <propstat>
- <prop xmlns:a0="http://www.purl.org/dc/1.1">
- <title xmlns="a0"/>
- <description xmlns="a0"/>
- <created xmlns="a0"/>
- <modified xmlns="a0"/>
- <effective xmlns="a0"/>
- <expires xmlns="a0"/>
- <creators xmlns="a0"/>
- <subjects xmlns="a0"/>
- <publisher xmlns="a0"/>
- <contributors xmlns="a0"/>
- <creationdate/>
- <displayname/>
- <source/>
- <getcontentlanguage/>
- <getcontentlength/>
- <getcontenttype/>
- <getetag/>
- <getlastmodified/>
- <resourcetype/>
- <lockdiscovery/>
- <supportedlock/>
- </prop>
- <status>HTTP/1.1 200 OK</status>
- </propstat>
- </response>
- </multistatus>'''
+ expect = ''
+ for p in ('', '1', '2', 'sub1/', 'sub1/1', 'sub1/2', 'sub1/sub1/',
+ 'sub1/sub1/last'):
+ expect += '''
+ <response><href>%(path)s</href>
+ <propstat><prop xmlns:a0="http://www.purl.org/dc/1.1">
+ %(props_xml)s</prop><status>HTTP/1.1 200 OK</status>
+ </propstat></response>
+ ''' % {'path': '%(resource_url)s' + p, 'props_xml': props_xml}
- pfind = propfind.PROPFIND(folder, request)
+ resp = '''<?xml version="1.0" ?>
+ <multistatus xmlns="DAV:">%s</multistatus>'''
+ self._checkPropfind(folder, req, expect, depth='infinity', resp=resp)
+
+ def test_propfind_opaque_simple(self):
+ root = self.rootFolder
+ zpt = traverse(root, 'zpt')
+ oprops = IDAVOpaqueNamespaces(zpt)
+ oprops[u'http://foo/bar'] = {u'egg': '<egg>spam</egg>'}
+ req = '<prop xmlns:foo="http://foo/bar"><foo:egg /></prop>'
- pfind.PROPFIND()
- # Check HTTP Response
- self.assertEqual(request.response.getStatus(), 207)
- self.assertEqual(pfind.getDepth(), 'infinity')
- s1 = normalize_xml(request.response._body)
- s2 = normalize_xml(expect)
- self.assertEqual(s1, s2)
+ expect = '''<prop xmlns:a0="http://foo/bar"><egg xmlns="a0">spam</egg>
+ </prop>'''
+ self._checkPropfind(zpt, req, expect)
+ def test_propfind_opaque_complex(self):
+ root = self.rootFolder
+ zpt = traverse(root, 'zpt')
+ oprops = IDAVOpaqueNamespaces(zpt)
+ oprops[u'http://foo/bar'] = {u'egg':
+ '<egg xmlns:bacon="http://bacon">\n'
+ ' <bacon:pork>crispy</bacon:pork>\n'
+ '</egg>\n'}
+ req = '<prop xmlns:foo="http://foo/bar"><foo:egg /></prop>'
+
+ expect = '''<prop xmlns:a0="http://foo/bar">
+ <egg xmlns="a0" xmlns:bacon="http://bacon">
+ <bacon:pork>crispy</bacon:pork>
+ </egg></prop>'''
+ self._checkPropfind(zpt, req, expect)
+
def test_suite():
return TestSuite((
makeSuite(TestPlacefulPROPFIND),
Copied: Zope3/trunk/src/zope/app/dav/tests/test_proppatch.py (from rev 28054, Zope3/branches/isarsprint-dav-work/src/zope/app/dav/tests/test_proppatch.py)
Copied: Zope3/trunk/src/zope/app/dav/tests/unitfixtures.py (from rev 28054, Zope3/branches/isarsprint-dav-work/src/zope/app/dav/tests/unitfixtures.py)
Property changes on: Zope3/trunk/src/zope/app/dav/tests/unitfixtures.py
___________________________________________________________________
Name: svn:keywords
+ id
Name: svn:eol-style
+ native
More information about the Zope3-Checkins
mailing list