Back to index

plone3  3.1.7
testWebDAV.py
Go to the documentation of this file.
00001 
00002 from Products.CMFPlone.tests import PloneTestCase
00003 
00004 from Products.CMFPlone.tests import dummy
00005 from Products.CMFPlone.tests.PloneTestCase import default_user
00006 from Products.CMFPlone.tests.PloneTestCase import default_password
00007 
00008 from Products.CMFCore.utils import getToolByName
00009 
00010 from StringIO import StringIO
00011 
00012 html = """\
00013 <html>
00014 <head><title>Foo</title></head>
00015 <body>Bar</body>
00016 </html>
00017 """
00018 
00019 
00020 class TestDAVProperties(PloneTestCase.PloneTestCase):
00021 
00022     def testPropertiesToolTitle(self):
00023         ptool = getToolByName(self.portal, 'portal_properties')
00024         psets = dict(ptool.propertysheets.items())
00025         self.failUnless('webdav' in psets.keys())
00026         default = psets['webdav']
00027         items = dict(default.propertyItems())
00028         self.failUnless('displayname' in items.keys())
00029         self.assertEquals(items['displayname'], self.portal.title)
00030 
00031 
00032 class TestDAVMetadata(PloneTestCase.FunctionalTestCase):
00033     # Confirms fix for http://dev.plone.org/plone/ticket/3217
00034     # The fix itself is in CMFDefault.Document, not Plone.
00035 
00036     def afterSetUp(self):
00037         self.basic_auth = '%s:%s' % (default_user, default_password)
00038         self.folder_path = self.folder.absolute_url(1)
00039 
00040     def testDocumentMetadata(self):
00041         response = self.publish(self.folder_path+'/doc',
00042                                 env={'CONTENT_TYPE': 'text/html'},
00043                                 request_method='PUT',
00044                                 stdin=StringIO(html),
00045                                 basic=self.basic_auth)
00046         self.assertEqual(response.getStatus(), 201)
00047         doc = self.folder.doc
00048         self.assertEqual(doc.Title(), 'Foo')
00049         self.assertEqual(doc.EditableBody(), 'Bar')
00050         self.assertEqual(doc.Format(), 'text/html')
00051         # Remaining elements should contain the defaults
00052         self.assertEqual(doc.Description(), '')
00053         self.assertEqual(doc.Subject(), ())
00054         self.assertEqual(doc.Contributors(), ())
00055         self.assertEqual(doc.EffectiveDate(), 'None')
00056         self.assertEqual(doc.ExpirationDate(), 'None')
00057         self.assertEqual(doc.Language(), '')
00058         self.assertEqual(doc.Rights(), '')
00059 
00060 
00061 class TestPUTObjects(PloneTestCase.FunctionalTestCase):
00062     # PUT objects into Plone including special cases like index_html.
00063     # Confirms fix for http://dev.plone.org/plone/ticket/1375
00064 
00065     def afterSetUp(self):
00066         self.basic_auth = '%s:%s' % (default_user, default_password)
00067         self.portal_path = self.portal.absolute_url(1)
00068         self.folder_path = self.folder.absolute_url(1)
00069 
00070     def testPUTDocument(self):
00071         # Create a new document via FTP/DAV
00072         response = self.publish(self.folder_path+'/new_html',
00073                                 env={'CONTENT_TYPE': 'text/html'},
00074                                 request_method='PUT',
00075                                 stdin=StringIO(html),
00076                                 basic=self.basic_auth)
00077 
00078         self.assertEqual(response.getStatus(), 201)
00079         self.failUnless('new_html' in self.folder.objectIds())
00080         self.assertEqual(self.folder.new_html.portal_type, 'Document')
00081         self.assertEqual(self.folder.new_html.EditableBody(), html)
00082 
00083     def testPUTTextDocumentRSTNoContentType(self):
00084         # Create a new document via FTP/DAV, some clients do not send
00085         # a proper Content-Type header.
00086         response = self.publish(self.folder_path+'/test.rst',
00087                                 env={'CONTENT_LENGTH':'0'},
00088                                 request_method='PUT',
00089                                 stdin=StringIO(),
00090                                 basic=self.basic_auth)
00091 
00092         self.assertEqual(response.getStatus(), 201)
00093         self.failUnless('test.rst' in self.folder.objectIds())
00094         self.assertEqual(self.folder['test.rst'].portal_type, 'Document')
00095         self.assertEqual(self.folder['test.rst'].EditableBody(), '')
00096 
00097     def testPUTTextDocumentTXTNoContentType(self):
00098         # Create a new document via FTP/DAV, some clients do not send
00099         # a proper Content-Type header.
00100         response = self.publish(self.folder_path+'/test.txt',
00101                                 env={'CONTENT_LENGTH':'0'},
00102                                 request_method='PUT',
00103                                 stdin=StringIO(),
00104                                 basic=self.basic_auth)
00105 
00106         self.assertEqual(response.getStatus(), 201)
00107         self.failUnless('test.txt' in self.folder.objectIds())
00108         self.assertEqual(self.folder['test.txt'].portal_type, 'Document')
00109         self.assertEqual(self.folder['test.txt'].EditableBody(), '')
00110 
00111     def testPUTTextDocumentININoContentType(self):
00112         # Create a new document via FTP/DAV, some clients do not send
00113         # a proper Content-Type header.
00114         response = self.publish(self.folder_path+'/test.ini',
00115                                 env={'CONTENT_LENGTH':'0'},
00116                                 request_method='PUT',
00117                                 stdin=StringIO(),
00118                                 basic=self.basic_auth)
00119 
00120         self.assertEqual(response.getStatus(), 201)
00121         self.failUnless('test.ini' in self.folder.objectIds())
00122         self.assertEqual(self.folder['test.ini'].portal_type, 'Document')
00123         self.assertEqual(self.folder['test.ini'].EditableBody(), '')
00124 
00125     def testPUTIndexHtmlDocument(self):
00126         # Create an index_html document via FTP/DAV
00127         response = self.publish(self.folder_path+'/index_html',
00128                                 env={'CONTENT_TYPE': 'text/html'},
00129                                 request_method='PUT',
00130                                 stdin=StringIO(html),
00131                                 basic=self.basic_auth)
00132 
00133         self.assertEqual(response.getStatus(), 201)
00134         self.failUnless('index_html' in self.folder.objectIds())
00135         self.assertEqual(self.folder.index_html.portal_type, 'Document')
00136         self.assertEqual(self.folder.index_html.EditableBody(), html)
00137         self.assertEqual(self.folder._getOb('index_html').EditableBody(), html)
00138 
00139     def testPUTImage(self):
00140         # Create a new image via FTP/DAV
00141         response = self.publish(self.folder_path+'/new_image',
00142                                 env={'CONTENT_TYPE': 'image/gif'},
00143                                 request_method='PUT',
00144                                 stdin=StringIO(dummy.GIF),
00145                                 basic=self.basic_auth)
00146 
00147         self.assertEqual(response.getStatus(), 201)
00148         self.failUnless('new_image' in self.folder.objectIds())
00149         self.assertEqual(self.folder.new_image.portal_type, 'Image')
00150         self.assertEqual(str(self.folder.new_image.getImage().data), dummy.GIF)
00151 
00152     def testPUTImageGIFNoContentType(self):
00153         # Create a new image via FTP/DAV, some clients do not send a
00154         # proper Content-Type header.  Note we are uploading a GIF
00155         # image, but the content_type_registry only looks at the
00156         # extension. We just send a GIF image so that PIL doesn't
00157         # complain.
00158         response = self.publish(self.folder_path+'/test.gif',
00159                                 env={'CONTENT_LENGTH':len(dummy.GIF)},
00160                                 request_method='PUT',
00161                                 stdin=StringIO(dummy.GIF),
00162                                 basic=self.basic_auth)
00163 
00164         self.assertEqual(response.getStatus(), 201)
00165         self.failUnless('test.gif' in self.folder.objectIds())
00166         self.assertEqual(self.folder['test.gif'].portal_type, 'Image')
00167         self.assertEqual(str(self.folder['test.gif'].getImage().data), dummy.GIF)
00168 
00169     def testPUTImageJPGNoContentType(self):
00170         # Create a new image via FTP/DAV, some clients do not send a
00171         # proper Content-Type header.  Note we are uploading a GIF
00172         # image, but the content_type_registry only looks at the
00173         # extension. We just send a GIF image so that PIL doesn't
00174         # complain.
00175         response = self.publish(self.folder_path+'/test.jpg',
00176                                 env={'CONTENT_LENGTH':len(dummy.GIF)},
00177                                 request_method='PUT',
00178                                 stdin=StringIO(dummy.GIF),
00179                                 basic=self.basic_auth)
00180 
00181         self.assertEqual(response.getStatus(), 201)
00182         self.failUnless('test.jpg' in self.folder.objectIds())
00183         self.assertEqual(self.folder['test.jpg'].portal_type, 'Image')
00184         self.assertEqual(str(self.folder['test.jpg'].getImage().data), dummy.GIF)
00185 
00186     def testPUTImagePNGNoContentType(self):
00187         # Create a new image via FTP/DAV, some clients do not send a
00188         # proper Content-Type header.  Note we are uploading a GIF
00189         # image, but the content_type_registry only looks at the
00190         # extension. We just send a GIF image so that PIL doesn't
00191         # complain.
00192         response = self.publish(self.folder_path+'/test.png',
00193                                 env={'CONTENT_LENGTH':len(dummy.GIF)},
00194                                 request_method='PUT',
00195                                 stdin=StringIO(dummy.GIF),
00196                                 basic=self.basic_auth)
00197 
00198         self.assertEqual(response.getStatus(), 201)
00199         self.failUnless('test.png' in self.folder.objectIds())
00200         self.assertEqual(self.folder['test.png'].portal_type, 'Image')
00201         self.assertEqual(str(self.folder['test.png'].getImage().data), dummy.GIF)
00202 
00203     def testPUTImageTIFFNoContentType(self):
00204         # Create a new image via FTP/DAV, some clients do not send a
00205         # proper Content-Type header.  Note we are uploading a GIF
00206         # image, but the content_type_registry only looks at the
00207         # extension. We just send a GIF image so that PIL doesn't
00208         # complain.
00209         response = self.publish(self.folder_path+'/test.tiff',
00210                                 env={'CONTENT_LENGTH':len(dummy.GIF)},
00211                                 request_method='PUT',
00212                                 stdin=StringIO(dummy.GIF),
00213                                 basic=self.basic_auth)
00214 
00215         self.assertEqual(response.getStatus(), 201)
00216         self.failUnless('test.tiff' in self.folder.objectIds())
00217         self.assertEqual(self.folder['test.tiff'].portal_type, 'Image')
00218         self.assertEqual(str(self.folder['test.tiff'].getImage().data), dummy.GIF)
00219 
00220     def testPUTImageICONoContentType(self):
00221         # Create a new image via FTP/DAV, some clients do not send a
00222         # proper Content-Type header.  Note we are uploading a GIF
00223         # image, but the content_type_registry only looks at the
00224         # extension. We just send a GIF image so that PIL doesn't
00225         # complain.
00226         response = self.publish(self.folder_path+'/test.ico',
00227                                 env={'CONTENT_LENGTH':len(dummy.GIF)},
00228                                 request_method='PUT',
00229                                 stdin=StringIO(dummy.GIF),
00230                                 basic=self.basic_auth)
00231 
00232         self.assertEqual(response.getStatus(), 201)
00233         self.failUnless('test.ico' in self.folder.objectIds())
00234         self.assertEqual(
00235             self.folder['test.ico'].portal_type, 'Image', 
00236             'If you are on a Mac and this fails, please see: http://plone.org/documentation/error/unittest to fix.')
00237         self.assertEqual(str(self.folder['test.ico'].getImage().data), dummy.GIF)
00238 
00239     def testPUTIndexHtmlImage(self):
00240         # Create a new image named index_html via FTP/DAV
00241         response = self.publish(self.folder_path+'/index_html',
00242                                 env={'CONTENT_TYPE': 'image/gif'},
00243                                 request_method='PUT',
00244                                 stdin=StringIO(dummy.GIF),
00245                                 basic=self.basic_auth)
00246 
00247         self.assertEqual(response.getStatus(), 201)
00248         self.failUnless('index_html' in self.folder.objectIds())
00249         self.assertEqual(self.folder.index_html.portal_type, 'Image')
00250         self.assertEqual(str(self.folder.index_html.getImage().data), dummy.GIF)
00251 
00252     def testPUTDocumentIntoPortal(self):
00253         # Create a new document in the portal via FTP/DAV
00254         self.setRoles(['Manager'])
00255 
00256         response = self.publish(self.portal_path+'/new_html',
00257                                 env={'CONTENT_TYPE': 'text/html'},
00258                                 request_method='PUT',
00259                                 stdin=StringIO(html),
00260                                 basic=self.basic_auth)
00261 
00262         self.assertEqual(response.getStatus(), 201)
00263         self.failUnless('new_html' in self.portal.objectIds())
00264         self.assertEqual(self.portal.new_html.portal_type, 'Document')
00265         self.assertEqual(self.portal.new_html.EditableBody(), html)
00266 
00267     def testPUTIndexHtmlDocumentIntoPortal(self):
00268         # Create an index_html document in the portal via FTP/DAV
00269         self.setRoles(['Manager'])
00270 
00271         response = self.publish(self.portal_path+'/index_html',
00272                                 env={'CONTENT_TYPE': 'text/html'},
00273                                 request_method='PUT',
00274                                 stdin=StringIO(html),
00275                                 basic=self.basic_auth)
00276 
00277         self.assertEqual(response.getStatus(), 201)
00278         self.failUnless('index_html' in self.portal.objectIds())
00279         self.assertEqual(self.portal.index_html.portal_type, 'Document')
00280         self.assertEqual(self.portal.index_html.EditableBody(), html)
00281         self.assertEqual(self.portal._getOb('index_html').EditableBody(), html)
00282 
00283 
00284 class TestDAVOperations(PloneTestCase.FunctionalTestCase):
00285 
00286     def afterSetUp(self):
00287         self.loginAsPortalOwner()
00288         self.basic_auth = '%s:%s' % (PloneTestCase.portal_owner, PloneTestCase.default_password)
00289         self.portal_path = self.portal.absolute_url(1)
00290         self.folder_path = self.folder.absolute_url(1)
00291 
00292     def test_document_propfind_index_html_exist_folder(self):
00293         self.folder.invokeFactory('Folder', 'sub')
00294         self.folder.sub.invokeFactory('Document', 'index_html')
00295         self.failUnless('index_html' in self.folder.sub.objectIds())
00296 
00297         # Do a PROPFIND on folder/index_html, this needs to result in a 207
00298         response = self.publish(self.folder_path + '/sub/index_html',
00299                                 request_method='PROPFIND',
00300                                 env={'HTTP_DEPTH': '0'},
00301                                 stdin=StringIO(),
00302                                 basic=self.basic_auth)
00303 
00304         self.assertEqual(response.getStatus(), 207, response.getBody())
00305 
00306     def test_document_propfind_index_html_non_exist_folder(self):
00307         self.folder.invokeFactory('Folder', 'sub')
00308         self.failIf('index_html' in self.folder.sub.objectIds())
00309 
00310         # Do a PROPFIND on folder/index_html, this needs to result in a NotFound.
00311         response = self.publish(self.folder_path + '/sub/index_html',
00312                                 request_method='PROPFIND',
00313                                 env={'HTTP_DEPTH': '0'},
00314                                 stdin=StringIO(),
00315                                 basic=self.basic_auth)
00316 
00317         self.assertEqual(response.getStatus(), 404, response.getBody())
00318 
00319     def test_document_propfind_index_html_exist_portal(self):
00320         if 'index_html' not in self.portal.objectIds():
00321             self.portal.invokeFactory('Document', 'index_html')
00322 
00323         self.failUnless('index_html' in self.portal.objectIds())
00324 
00325         # Do a PROPFIND on folder/index_html, this needs to result in a 207
00326         response = self.publish(self.portal_path + '/index_html',
00327                                 request_method='PROPFIND',
00328                                 env={'HTTP_DEPTH': '0'},
00329                                 stdin=StringIO(),
00330                                 basic=self.basic_auth)
00331 
00332         self.assertEqual(response.getStatus(), 207, response.getBody())
00333 
00334     def test_document_propfind_index_html_non_exist_portal(self):
00335         if 'index_html' in self.portal.objectIds():
00336             self.portal.manage_delObjects('index_html')
00337 
00338         self.failIf('index_html' in self.portal.objectIds())
00339 
00340         # Do a PROPFIND on portal/index_html, this needs to result in a NotFound.
00341         response = self.publish(self.portal_path + '/index_html',
00342                                 request_method='PROPFIND',
00343                                 env={'HTTP_DEPTH': '0'},
00344                                 stdin=StringIO(),
00345                                 basic=self.basic_auth)
00346 
00347         self.assertEqual(response.getStatus(), 404, response.getBody())
00348 
00349     def test_propfind_portal_root_index_html_exists(self):
00350         if 'index_html' not in self.portal.objectIds():
00351             self.portal.invokeFactory('Document', 'index_html')
00352 
00353         self.failUnless('index_html' in self.portal.objectIds())
00354 
00355         # Do a PROPFIND on portal, this needs to result in a 207
00356         response = self.publish(self.portal_path,
00357                                 request_method='PROPFIND',
00358                                 env={'HTTP_DEPTH': '0'},
00359                                 stdin=StringIO(),
00360                                 basic=self.basic_auth)
00361 
00362         self.assertEqual(response.getStatus(), 207, response.getBody())
00363 
00364     def test_propfind_portal_root_index_html_not_exists(self):
00365         if 'index_html' in self.portal.objectIds():
00366             self.portal.manage_delObjects('index_html')
00367 
00368         self.failIf('index_html' in self.portal.objectIds())
00369 
00370         # Do a PROPFIND on portal, this needs to result in a 207
00371         response = self.publish(self.portal_path,
00372                                 request_method='PROPFIND',
00373                                 env={'HTTP_DEPTH': '0'},
00374                                 stdin=StringIO(),
00375                                 basic=self.basic_auth)
00376 
00377         self.assertEqual(response.getStatus(), 207, response.getBody())
00378 
00379     def test_propfind_folder_index_html_exists(self):
00380         if 'index_html' not in self.folder.objectIds():
00381             self.folder.invokeFactory('Document', 'index_html')
00382 
00383         self.failUnless('index_html' in self.folder.objectIds())
00384 
00385         # Do a PROPFIND on folder, this needs to result in a 207
00386         response = self.publish(self.folder_path,
00387                                 request_method='PROPFIND',
00388                                 env={'HTTP_DEPTH': '0'},
00389                                 stdin=StringIO(),
00390                                 basic=self.basic_auth)
00391 
00392         self.assertEqual(response.getStatus(), 207, response.getBody())
00393 
00394     def test_propfind_folder_index_html_not_exists(self):
00395         if 'index_html' in self.folder.objectIds():
00396             self.folder.manage_delObjects('index_html')
00397 
00398         self.failIf('index_html' in self.folder.objectIds())
00399 
00400         # Do a PROPFIND on folder, this needs to result in a 207
00401         response = self.publish(self.folder_path,
00402                                 request_method='PROPFIND',
00403                                 env={'HTTP_DEPTH': '0'},
00404                                 stdin=StringIO(),
00405                                 basic=self.basic_auth)
00406 
00407         self.assertEqual(response.getStatus(), 207, response.getBody())
00408 
00409 
00410 def test_suite():
00411     from unittest import TestSuite, makeSuite
00412 
00413     suite = TestSuite()
00414     suite.addTest(makeSuite(TestDAVProperties))
00415     # DISABLED the metadata test, this is not yet implemented in ATCT
00416     ##suite.addTest(makeSuite(TestDAVMetadata))
00417     suite.addTest(makeSuite(TestPUTObjects))
00418     suite.addTest(makeSuite(TestDAVOperations))
00419     return suite