[Zope3-checkins]
SVN: Zope3/branches/mkerrin-webdav/src/zope/app/dav/
Added tests for the COPY method. These tests highlighted some
Michael Kerrin
michael.kerrin at openapp.biz
Fri Jan 13 06:50:09 EST 2006
Log message for revision 41295:
Added tests for the COPY method. These tests highlighted some
bugs which have being fixed.
Also fixed a few tests for the widgets.
Changed:
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/copy.py
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/ifhandler.py
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/locking.py
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/propfind.py
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_common_if.py
A Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_copy.py
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_mkcol.py
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_propfind.py
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_widget.py
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/unitfixtures.py
U Zope3/branches/mkerrin-webdav/src/zope/app/dav/widget.py
-=-
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/copy.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/copy.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/copy.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -19,7 +19,6 @@
from urlparse import urlsplit
-from zope.publisher.interfaces import NotFound
from zope.app import zapi
from zope.app.copypastemove.interfaces import IObjectMover, IObjectCopier
from zope.app.publication.http import MethodNotAllowed
@@ -27,6 +26,8 @@
from zope.app.traversing.api import traverse, getRoot
from zope.app.traversing.interfaces import TraversalError
+from interfaces import IIfHeader
+
class COPY(object):
def __init__(self, context, request):
self.context = context
@@ -61,7 +62,7 @@
elif overwrite == 'f':
overwrite = False
else:
- self.requset.response.setStatus(400)
+ self.request.response.setStatus(400)
return ''
# find destination if it exists and if it
@@ -70,9 +71,6 @@
try:
destob = traverse(getRoot(self.context), destpath)
exists = True
- except NotFound:
- destob = None
- exists = False
except TraversalError:
destob = None
exists = False
@@ -80,21 +78,24 @@
if destob is not None and not overwrite:
self.request.response.setStatus(412)
return ''
+ elif destob is not None and destob is self.context:
+ self.request.response.setStatus(403)
+ return ''
elif destob is not None:
ifparser = zapi.queryMultiAdapter((destob, self.request), IIfHeader)
if ifparser is not None and not ifparser():
self.request.response.setStatus(423)
return ''
+
# we need to delete this object
- raise NotImplementedError, "please delete the destination object"
+ parent = destob.__parent__
+ del parent[destob.__name__]
# check parent
parentpath = destpath.split('/')
destname = parentpath.pop()
try:
parent = traverse(getRoot(self.context), parentpath)
- except NotFound:
- parent = None
except TraversalError:
parent = None
if parent is None:
@@ -102,7 +103,6 @@
return ''
if not copier.copyableTo(parent):
- # XXX - should this be 405 ???
self.request.response.setStatus(409)
return ''
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/ifhandler.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/ifhandler.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/ifhandler.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -109,13 +109,14 @@
def __call__(self):
ifhdr = self.request.getHeader('if', None)
- if ifhdr is None:
- return True
lockable = ILockable(self.context)
if not lockable.locked():
return True
+ if ifhdr is None:
+ return False
+
lockinfo = lockable.getLockInfo()
tags = self.ifParser(ifhdr)
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/locking.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/locking.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/locking.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -107,9 +107,6 @@
def getDepth(self):
return self._depth
- def setDepth(self, depth):
- self._depth = depth
-
def getTimeout(self):
timeoutheader = self.request.getHeader('timeout', 'infinity')
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/propfind.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/propfind.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/propfind.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -188,8 +188,15 @@
if not iface:
for name in props:
if self.oprops:
+ status = 200
el = self.oprops.renderProperty(ns, ns_prefix, name)
- re.addPropertyByStatus(ns, ns_prefix, el, 200)
+ if el is None:
+ # We can't add a None property in the MultiStatus
+ # utility so add an empty property registered has
+ # a 404 stats not found property.
+ status = 404
+ el = re.createEmptyElement(ns, ns_prefix, name)
+ re.addPropertyByStatus(ns, ns_prefix, el, status)
else:
el = re.createEmptyElement(ns, ns_prefix, name)
re.addPropertyByStatus(ns, ns_prefix, el, 404)
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_common_if.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_common_if.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_common_if.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -143,6 +143,13 @@
# context not locked -> true
self.assertEqual(ifparser(), True)
+ def test_on_locked_file_no_header(self):
+ request = TestRequest()
+ context = File('some content', 'text/plain')
+ lockinfo = self._lockcontent(context)
+ ifparser = IfParser(context, request)
+ self.assertEqual(ifparser(), False)
+
def test_on_locked_file_no_token(self):
request = TestRequest(**{'IF': '(<%s>)' % self.token})
context = File('some content', 'text/plain')
Added: Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_copy.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_copy.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_copy.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -0,0 +1,266 @@
+##############################################################################
+#
+# Copyright (c) 2005 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 Copying
+
+$Id$
+"""
+import unittest
+
+from zope.interface import Interface
+from zope.publisher.browser import TestRequest
+from zope.publisher.interfaces.http import IHTTPRequest
+from zope.security.testing import Principal, Participation
+from zope.security.management import newInteraction, endInteraction, \
+ queryInteraction
+from zope.app.testing import ztapi
+from zope.app.traversing.api import traverse
+from zope.app.traversing.interfaces import TraversalError
+from zope.app.component.testing import PlacefulSetup
+
+from zope.app.locking.interfaces import ILockable, ILockStorage
+from zope.app.locking.storage import PersistentLockStorage
+from zope.app.locking.adapter import LockingAdapterFactory
+from zope.app.keyreference.interfaces import IKeyReference
+from zope.app.copypastemove import ObjectCopier
+from zope.app.copypastemove.interfaces import IObjectCopier
+
+from zope.app.dav.copy import COPY
+from zope.app.dav.interfaces import IIfHeader
+from zope.app.dav.ifhandler import IfParser
+
+from test_locking import FakeKeyReference
+from unitfixtures import File, Folder, ConstraintFolder
+
+class TestDAVCopy(PlacefulSetup, unittest.TestCase):
+
+ def setUp(self):
+ PlacefulSetup.setUp(self)
+ PlacefulSetup.buildFolders(self)
+
+ ztapi.provideAdapter(Interface, IObjectCopier, ObjectCopier)
+
+ # locking
+ ztapi.provideAdapter(Interface, IKeyReference, FakeKeyReference)
+ ztapi.provideAdapter(Interface, ILockable, LockingAdapterFactory)
+
+ storage = self.storage = PersistentLockStorage()
+ ztapi.provideUtility(ILockStorage, storage)
+
+ ztapi.provideAdapter((Interface, IHTTPRequest), IIfHeader, IfParser)
+
+ def tearDown(self):
+ PlacefulSetup.tearDown(self)
+ del self.storage
+
+ def test_copy_file(self):
+ root = self.rootFolder
+ container = traverse(root, 'folder1')
+ content = 'this is some content'
+ file = File('bla', 'text/plain', content, container)
+ container['bla'] = file
+ file = traverse(container, 'bla')
+
+ self.assertRaises(TraversalError, traverse, container, 'copy_bla')
+
+ request = TestRequest('/folder1/bla',
+ environ = {'REQUEST_METHOD': 'COPY',
+ 'DESTINATION': '/folder1/copy_bla'})
+ response = request.response
+ copier = COPY(file, request)
+ copier.COPY()
+ # check for 201 status since the new file will be created.
+ self.assertEqual(response.getStatus(), 201)
+ newfile = traverse(container, 'copy_bla')
+ self.assertEqual(newfile.data, content)
+
+ def test_copy_file_overwrite(self):
+ root = self.rootFolder
+ container = traverse(root, 'folder1')
+ file = File('bla', 'text/plain', 'this is some content', container)
+ container['bla'] = file
+ file = traverse(container, 'bla')
+
+ copy_file = File('copy_bla', 'text/plain', 'this is the second file',
+ container)
+ container['copy_bla'] = copy_file
+
+ request = TestRequest('/folder1/bla',
+ environ = {'REQUEST_METHOD': 'COPY',
+ 'DESTINATION': '/folder1/copy_bla',
+ 'OVERWRITE': 'T'})
+ response = request.response
+ copier = COPY(file, request)
+ copier.COPY()
+ # check for 204 status since the no file is created.
+ self.assertEqual(response.getStatus(), 204)
+ newfile = traverse(container, 'copy_bla')
+ self.assertEqual(newfile.data, 'this is some content')
+
+ def test_copy_file_no_overwrite(self):
+ root = self.rootFolder
+ container = traverse(root, 'folder1')
+ file = File('bla', 'text/plain', 'this is some content', container)
+ container['bla'] = file
+ file = traverse(container, 'bla')
+
+ copy_file = File('copy_bla', 'text/plain', 'this is the second file',
+ container)
+ container['copy_bla'] = copy_file
+
+ request = TestRequest('/folder1/bla',
+ environ = {'REQUEST_METHOD': 'COPY',
+ 'DESTINATION': '/folder1/copy_bla',
+ 'OVERWRITE': 'F'})
+ response = request.response
+ copier = COPY(file, request)
+ copier.COPY()
+
+ # 412 - precondition failed since overwrite is False.
+ self.assertEqual(response.getStatus(), 412)
+ newfile = traverse(container, 'copy_bla')
+ self.assertEqual(newfile.data, 'this is the second file')
+
+ def test_invalid_copy_request(self):
+ root = self.rootFolder
+ container = traverse(root, 'folder1')
+ content = 'this is some content'
+ file = File('bla', 'text/plain', content, container)
+ container['bla'] = file
+ file = traverse(container, 'bla')
+
+ request = TestRequest('/folder1/bla',
+ environ = {'REQUEST_METHOD': 'COPY',
+ 'DESTINATION': '/blafolder/copy_bla',
+ 'OVERWRITE': 'X'})
+ response = request.response
+ copier = COPY(file, request)
+ copier.COPY()
+ # check for 201 status since the new file will be created.
+ self.assertEqual(response.getStatus(), 400)
+
+ # now test a missing destination header.
+ request = TestRequest('/folder1/bla',
+ environ = {'REQUEST_METHOD': 'COPY',
+ 'OVERWRITE': 'T'})
+ response = request.response
+ copier = COPY(file, request)
+ copier.COPY()
+ # check for 201 status since the new file will be created.
+ self.assertEqual(response.getStatus(), 400)
+
+ def test_no_destination_parent(self):
+ root = self.rootFolder
+ container = traverse(root, 'folder1')
+ content = 'this is some content'
+ file = File('bla', 'text/plain', content, container)
+ container['bla'] = file
+ file = traverse(container, 'bla')
+
+ self.assertRaises(TraversalError, traverse, container, 'copy_bla')
+
+ request = TestRequest('/folder1/bla',
+ environ = {'REQUEST_METHOD': 'COPY',
+ 'DESTINATION': '/blafolder/copy_bla'})
+ response = request.response
+ copier = COPY(file, request)
+ copier.COPY()
+ # check for 201 status since the new file will be created.
+ self.assertEqual(response.getStatus(), 409)
+
+ def test_destination_file_locked(self):
+ root = self.rootFolder
+ container = traverse(root, 'folder1')
+ file = File('bla', 'text/plain', 'this is some content', container)
+ container['bla'] = file
+ file = traverse(container, 'bla')
+
+ dest_file = File('copy_bla', 'text/plain', 'this is the second file',
+ container)
+ container['copy_bla'] = dest_file
+ dest_file = traverse(container, 'copy_bla')
+
+ # now lock dest_file
+ mparticipation = Participation(Principal('michael'))
+ if queryInteraction():
+ endInteraction()
+ newInteraction(mparticipation)
+ lockable = ILockable(dest_file)
+ lockable.lock()
+ endInteraction()
+
+ request = TestRequest('/folder1/bla',
+ environ = {'REQUEST_METHOD': 'COPY',
+ 'DESTINATION': '/folder1/copy_bla',
+ 'OVERWRITE': 'T'})
+ response = request.response
+
+ copier = COPY(file, request)
+ copier.COPY()
+
+ # 423 - locked
+ self.assertEqual(response.getStatus(), 423)
+ newfile = traverse(container, 'copy_bla')
+ self.assertEqual(newfile.data, 'this is the second file')
+
+ def test_not_copyableTo(self):
+ root = self.rootFolder
+ container = traverse(root, 'folder1')
+ file = File('bla', 'text/plain', 'this is some content', container)
+ container['bla'] = file
+ file = traverse(container, 'bla')
+
+ # the ConstraintFolder only allows implementations of IFolder to be
+ # added to it - so by copying a file into this folder we should get
+ # a conflict and hence a 409 response status.
+ folder = ConstraintFolder()
+ root['nofilefolder'] = folder
+
+ request = TestRequest('/folder1/bla',
+ environ = {'REQUEST_METHOD': 'COPY',
+ 'DESTINATION': '/nofilefolder/bla',
+ 'OVERWRITE': 'T'})
+ response = request.response
+ copier = COPY(file, request)
+ copier.COPY()
+
+ # conflict - a resource can't be created at the destination.
+ self.assertEqual(response.getStatus(), 409)
+
+ def test_source_dest_same(self):
+ root = self.rootFolder
+ container = traverse(root, 'folder1')
+ file = File('bla', 'text/plain', 'this is some content', container)
+ container['bla'] = file
+ file = traverse(container, 'bla')
+
+ request = TestRequest('/folder1/bla',
+ environ = {'REQUEST_METHOD': 'COPY',
+ 'DESTINATION': '/folder1/bla',
+ })
+ response = request.response
+ copier = COPY(file, request)
+ copier.COPY()
+
+ # 403 (Forbidden) _ The source and destination URIs are the same.
+ self.assertEqual(response.getStatus(), 403)
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(TestDAVCopy),
+ ))
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest = 'test_suite')
Property changes on: Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_copy.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_mkcol.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_mkcol.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_mkcol.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -30,7 +30,8 @@
from zope.app.http.put import NullResource
from zope.app.dav import mkcol
-from zope.app.dav.tests.test_propfind import _createRequest, File
+from zope.app.dav.tests.test_propfind import _createRequest
+from unitfixtures import File
class TestPlacefulMKCOL(PlacefulSetup, TestCase):
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_propfind.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_propfind.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_propfind.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -500,6 +500,44 @@
%s</prop>''' % expect
self._checkPropfind(zpt, req, expect)
+ def test_propfind_opaque_without_property(self):
+ # test opaque properties when requested property is not in the current
+ # opaque annotation
+ root = self.rootFolder
+ zpt = traverse(root, 'zpt')
+ oprops = IDAVOpaqueNamespaces(zpt)
+ oprops[u'http://foo/bar'] = {u'egg': '<egg>spam</egg>'}
+
+ ## self._checkPropfind(zpt, req, expect)
+ body = '''<?xml version="1.0" ?>
+ <propfind xmlns="DAV:">
+ <prop xmlns:foo="http://foo/bar"><foo:srambleegg /></prop>
+ </propfind>
+ '''
+ depth = '0'
+ request = _createRequest(body = body,
+ headers = {'Content-type': 'text/xml',
+ 'Depth': depth})
+ resource_url = zapi.absoluteURL(zpt, request)
+ resp = '''<?xml version="1.0" encoding="utf-8"?>
+ <multistatus xmlns="DAV:"><response>
+ <href>%(resource_url)s</href>
+ <propstat>
+ <prop xmlns:a0="http://foo/bar"><srambleegg xmlns="a0"/>
+ </prop>
+ <status>HTTP/1.1 404 Not Found</status>
+ </propstat></response></multistatus>
+ ''' % {'resource_url': resource_url}
+
+ pfind = propfind.PROPFIND(zpt, request)
+ pfind.PROPFIND()
+
+ self.assertEqual(request.response.getStatus(), 207)
+ self.assertEqual(pfind.getDepth(), depth)
+ s1 = normalize_xml(request.response.consumeBody())
+ s2 = normalize_xml(resp)
+ self.assertEqual(s1, s2)
+
def test_propfind_opaque_simple(self):
root = self.rootFolder
zpt = traverse(root, 'zpt')
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_widget.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_widget.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/test_widget.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -11,18 +11,19 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""
+"""XXX - the tests in this file should be made a lot clearer.
+
$Id$
"""
__docformat__ = 'restructuredtext'
-from datetime import datetime
+import datetime
from xml.dom import minidom
from unittest import TestSuite, main, makeSuite, TestCase
from zope.interface import Interface, implements
from zope.interface.verify import verifyClass
-from zope.schema import Text, Datetime, List
+from zope.schema import Text, Datetime, Date, List, Tuple
from zope.schema import ValidationError
from zope.publisher.browser import TestRequest
from zope.testing.doctest import DocTestSuite
@@ -32,7 +33,7 @@
from zope.app.dav.interfaces import IDAVWidget
from zope.app.dav.widget import DAVWidget, TextDAVWidget, DatetimeDAVWidget, \
- XMLEmptyElementListDAVWidget
+ DateDAVWidget, XMLEmptyElementListDAVWidget, TupleDAVWidget
class DAVWidgetTest(placelesssetup.PlacelessSetup, TestCase):
@@ -62,10 +63,6 @@
def test_widget_input(self):
content = self.test_content
- # try multiple bad content
- bad_contents = self.test_bad_contents
- if not isinstance(bad_contents, list):
- bad_contents = [bad_contents]
self.failIf(self._widget.hasInput())
self._widget.setRenderedValue(content)
@@ -73,11 +70,11 @@
self.assert_(self._widget.hasValidInput())
self.assertEqual(self._widget.getInputValue(), content)
- for bad_content in bad_contents:
- self._widget.setRenderedValue(bad_content)
- self.assert_(self._widget.hasInput())
- self.failIf(self._widget.hasValidInput())
- self.assertRaises(WidgetInputError, self._widget.getInputValue)
+ def _test_widget_bad_input(self, propel):
+ self._widget.setProperty(propel)
+ self.assert_(self._widget.hasInput())
+ self.failIf(self._widget.hasValidInput())
+ self.assertRaises(WidgetInputError, self._widget.getInputValue)
def test_widget_apply_content(self):
content = self.test_content
@@ -92,27 +89,65 @@
_WidgetFactory = TextDAVWidget
test_content = u'This is some text content'
- test_bad_contents = 10
-
class DatetimeDAVWidgetTest(DAVWidgetTest):
_WidgetFactory = DatetimeDAVWidget
_FieldFactory = Datetime
- test_content = datetime.fromtimestamp(1131234842)
- test_bad_contents = [10, u'This is bad content']
+ test_content = datetime.datetime.fromtimestamp(1131234842)
def test_widget_input(self):
- date = datetime(1999, 12, 31, 23, 59, 59)
+ date = datetime.datetime(1999, 12, 31, 23, 59, 59)
+ # date.strftime = '1999-12-31 23:59:59Z'
+
doc = minidom.Document()
propel = doc.createElement('foo')
- # date.strftime = '1999-12-31 23:59:59Z'
propel.appendChild(doc.createTextNode(date.strftime('%F')))
self._widget.setProperty(propel)
- ## self._widget._value == date
- ## TypeError: can't compare offset-naive and offset-aware datetimes
+ value = self._widget.getInputValue()
+ fmt = '%y%m%d-000000'
+ self.assertEqual(date.strftime(fmt), value.strftime(fmt))
+ doc = minidom.Document()
+ propel = doc.createElement('foo')
+ propel.appendChild(
+ doc.createTextNode(date.strftime('%a, %d %b %Y %H:%M:%S')))
+ self._widget.setProperty(propel)
+ value = self._widget.getInputValue()
+ fmt = '%y%m%d-%H%M%S'
+ self.assertEqual(date.strftime(fmt), value.strftime(fmt))
+ def test_widget_bad_input(self):
+ doc = minidom.Document()
+ propel = doc.createElement('foo')
+ propel.appendChild(doc.createTextNode('invalid datetime content'))
+ super(DatetimeDAVWidgetTest, self)._test_widget_bad_input(propel)
+
+
+class DateDAVWidgetTest(DAVWidgetTest):
+ _WidgetFactory = DateDAVWidget
+ _FieldFactory = Date
+
+ test_content = datetime.date.fromtimestamp(1131234842)
+
+ def test_widget_input(self):
+ dateinst = datetime.datetime(1999, 12, 31, 23, 59, 59).date()
+ doc = minidom.Document()
+ propel = doc.createElement('foo')
+ # date.strftime = '1999-12-31 23:59:59Z'
+ propel.appendChild(doc.createTextNode(dateinst.strftime('%F')))
+ self._widget.setProperty(propel)
+
+ value = self._widget.getInputValue()
+ self.assertEqual(value, dateinst)
+
+ def test_widget_bad_input(self):
+ doc = minidom.Document()
+ propel = doc.createElement('foo')
+ propel.appendChild(doc.createTextNode('invalid date content'))
+ super(DateDAVWidgetTest, self)._test_widget_bad_input(propel)
+
+
class XMLEmptyElementListDAVWidgetTest(DAVWidgetTest):
_WidgetFactory = XMLEmptyElementListDAVWidget
_FieldFactory = List
@@ -121,11 +156,21 @@
test_bad_contents = [10, u'hello']
+class TupleDAVWidgetTest(DAVWidgetTest):
+ _WidgetFactory = TupleDAVWidget
+ _FieldFactory = Tuple
+
+ test_content = (u'hello', u'there')
+ test_bad_contents = [10, u'hello']
+
+
def test_suite():
return TestSuite((
makeSuite(TextDAVWidgetTest),
makeSuite(DatetimeDAVWidgetTest),
+ makeSuite(DateDAVWidgetTest),
makeSuite(XMLEmptyElementListDAVWidgetTest),
+ makeSuite(TupleDAVWidgetTest),
DocTestSuite('zope.app.dav.widget'),
))
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/unitfixtures.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/unitfixtures.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/tests/unitfixtures.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -19,13 +19,15 @@
from BTrees.OOBTree import OOBTree
from persistent import Persistent
-from zope.interface import implements
+from zope.interface import Interface, implements
from zope.app.filerepresentation.interfaces import IWriteFile
from zope.app.filerepresentation.interfaces import IReadDirectory
from zope.app.container.interfaces import IReadContainer
+from zope.app.container.constraints import ItemTypePrecondition
from zope.app.annotation.interfaces import IAnnotatable
from zope.app.file.interfaces import IFile
+from zope.app.folder.folder import Folder as ZopeFolder
import zope.app.location
@@ -41,7 +43,7 @@
self.data = OOBTree()
if level in (0, 1):
self._setUp()
- else:
+ elif level > 0:
self.data['last'] = File('last', 'text/plain', 'blablabla', self)
def _setUp(self):
@@ -57,6 +59,19 @@
return tuple(items)
+class INoFileContainer(Interface):
+ """Don't allow any File's within this folder
+ """
+
+ def __setitem__(name, object):
+ """Add a directory to object to this folder."""
+ __setitem__.precondition = ItemTypePrecondition(IReadDirectory)
+
+
+class ConstraintFolder(ZopeFolder):
+ implements(INoFileContainer)
+
+
class File(zope.app.location.Location, Persistent):
implements(IWriteFile, IFile)
Modified: Zope3/branches/mkerrin-webdav/src/zope/app/dav/widget.py
===================================================================
--- Zope3/branches/mkerrin-webdav/src/zope/app/dav/widget.py 2006-01-13 04:13:46 UTC (rev 41294)
+++ Zope3/branches/mkerrin-webdav/src/zope/app/dav/widget.py 2006-01-13 11:50:08 UTC (rev 41295)
@@ -48,6 +48,8 @@
self._xmldoc = minidom.Document()
# field value
self._value = self._missing_value
+ # input value has a xml dom node
+ self._xmldom_value = self._missing_value
self._error = None
@@ -62,13 +64,15 @@
self.ns_prefix = ns_prefix
def setRenderedValue(self, value):
+ # don't use this
self._value = value
def applyChanges(self, content):
return super(DAVWidget, self).applyChanges(content)
def hasInput(self):
- return self._value is not self._missing_value
+ return self._value is not self._missing_value or \
+ self._xmldom_value is not self._missing_value
def _getAndValidateInput(self):
"""get the input value contained within this widget in a valid format
@@ -79,7 +83,10 @@
if not self.hasInput():
raise MissingInputError(self.name, self.label, None)
- value = self._value
+ if self._xmldom_value is not self._missing_value:
+ value = self._setFieldValue(self._xmldom_value)
+ else:
+ value = self._value
# allow missing values only for non-required fields
if value == field.missing_value: ## and not field.required:
@@ -105,7 +112,8 @@
try:
value = self._getAndValidateInput()
except ConversionError, error:
- self._error = error
+ self._error = WidgetInputError(
+ self.context.__name__, self.label, error)
raise self._error
except ValidationError, error:
self._error = WidgetInputError(
@@ -163,7 +171,7 @@
return text
def setProperty(self, propel):
- self._value = self._setFieldValue(propel)
+ self._xmldom_value = propel # self._setFieldValue(propel)
class TextDAVWidget(DAVWidget):
More information about the Zope3-Checkins
mailing list