Back to index

plone3  3.1.7
test_functional.py
Go to the documentation of this file.
00001 ################################################################################
00002 #
00003 # Copyright (c) 2002-2005, Benjamin Saller <bcsaller@ideasuite.com>, and
00004 #                              the respective authors. All rights reserved.
00005 # For a list of Archetypes contributors see docs/CREDITS.txt.
00006 #
00007 # Redistribution and use in source and binary forms, with or without
00008 # modification, are permitted provided that the following conditions are met:
00009 #
00010 # * Redistributions of source code must retain the above copyright notice, this
00011 #   list of conditions and the following disclaimer.
00012 # * Redistributions in binary form must reproduce the above copyright notice,
00013 #   this list of conditions and the following disclaimer in the documentation
00014 #   and/or other materials provided with the distribution.
00015 # * Neither the name of the author nor the names of its contributors may be used
00016 #   to endorse or promote products derived from this software without specific
00017 #   prior written permission.
00018 #
00019 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00020 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00022 # FOR A PARTICULAR PURPOSE.
00023 #
00024 ################################################################################
00025 """
00026 """
00027 
00028 import time
00029 
00030 from Products.Archetypes.tests.atsitetestcase import ATFunctionalSiteTestCase
00031 from Products.Archetypes.atapi import *
00032 from Products.Archetypes.tests.attestcase import default_user
00033 from Products.Archetypes.tests.atsitetestcase import portal_owner
00034 from Products.Archetypes.tests.utils import DummySessionDataManager
00035 
00036 from StringIO import StringIO
00037 
00038 html = """\
00039 <html>
00040 <head><title>Foo</title></head>
00041 <body>Bar</body>
00042 </html>
00043 """
00044 
00045 class TestFunctionalObjectCreation(ATFunctionalSiteTestCase):
00046     """Tests object renaming and creation"""
00047 
00048     def afterSetUp(self):
00049         # basic data
00050         # Put dummy sdm and dummy SESSION object into REQUEST
00051         if 'session_data_manager' in self.app.objectIds():
00052             self.app._delObject('session_data_manager')
00053         self.app._setObject('session_data_manager', DummySessionDataManager())
00054         sdm = self.app.session_data_manager
00055         request = self.app.REQUEST
00056         request.set('SESSION', sdm.getSessionData())
00057 
00058         self.folder_url = self.folder.absolute_url()
00059         self.folder_path = '/%s' % self.folder.absolute_url(1)
00060         self.basic_auth = '%s:secret' % default_user
00061         self.owner_auth = '%s:secret' % portal_owner
00062         # We want 401 responses, not redirects to a login page
00063         if hasattr(self.portal.aq_base, 'cookie_authentication'):
00064             self.portal._delObject('cookie_authentication')
00065 
00066         # disable portal_factory as it's a nuisance here
00067         if hasattr(self.portal.aq_base, 'portal_factory'):
00068             self.portal.portal_factory.manage_setPortalFactoryTypes(listOfTypeIds=[])
00069 
00070         # error log
00071         from Products.SiteErrorLog.SiteErrorLog import temp_logs
00072         temp_logs.clear() # clean up log
00073         self.error_log = self.portal.error_log
00074         self.error_log._ignored_exceptions = ()
00075 
00076         self.setupCTR()
00077 
00078     def setupCTR(self):
00079         #Modify the CTR to point to SimpleType
00080         ctr = self.portal.content_type_registry
00081         if ctr.getPredicate('text'):
00082             # ATCT has a predict
00083             ctr.removePredicate('text')
00084         ctr.addPredicate('text', 'major_minor' )
00085         ctr.getPredicate('text' ).edit('text', '' )
00086         ctr.assignTypeName('text', 'DDocument')
00087         ctr.reorderPredicate('text', 0)
00088 
00089         return ctr
00090 
00091     def assertStatusEqual(self, a, b, msg=''):
00092         """Helper method that uses the error log to output useful debug infos
00093         """
00094         now = time.time()
00095         if a != b:
00096             entries = self.error_log.getLogEntries()
00097             if entries:
00098                 msg = entries[0]['tb_text']
00099             else:
00100                 if not msg:
00101                     msg = 'no error log msg available'
00102                     self.failUnlessEqual(a, b)
00103         self.failUnlessEqual(a, b, msg)
00104         
00105     def test_id_change_on_initial_edit(self):
00106         """Make sure Id is taken from title on initial edit and not otherwise"""
00107         # Make our content type use auto generated ids
00108         from Products.Archetypes.examples.DDocument import DDocument
00109         DDocument._at_rename_after_creation = True
00110 
00111         auto_id='DDocument.2005-07-12.3847392'
00112 
00113         # create an object with an autogenerated id
00114         response = self.publish(self.folder_path +
00115                                 '/invokeFactory?type_name=DDocument&id=%s'%auto_id,
00116                                 self.basic_auth)
00117         self.failUnless(auto_id in self.folder.objectIds())
00118         new_obj = getattr(self.folder, auto_id)
00119 
00120         # Perform the redirect
00121         edit_form_path = self.folder_path+'/%s/base_edit'%auto_id
00122         response = self.publish(edit_form_path, self.basic_auth)
00123 
00124         # XXX now lets test if http://plone.org/collector/4487 is present
00125         if  "base_edit.cpt" in self.portal.portal_skins.archetypes.objectIds():
00126             raise AttributeError, ("test_id_change_on_initial_edit "
00127                   "is expected to fail unless  http://plone.org/collector/4487 is fixed")
00128 
00129         self.assertStatusEqual(response.getStatus(), 200) # OK
00130 
00131         #Change the title
00132         obj_title = "New Title for Object"
00133         new_id = "new-title-for-object"
00134         new_obj_path = '/%s' % new_obj.absolute_url(1)
00135         self.failUnless(new_obj.checkCreationFlag()) # object is not yet edited
00136 
00137         response = self.publish('%s/base_edit?form.submitted=1&title=%s&body=Blank' % (new_obj_path, obj_title,), self.basic_auth) # Edit object
00138         self.assertStatusEqual(response.getStatus(), 302) # OK
00139         self.failIf(new_obj.checkCreationFlag()) # object is fully created
00140         self.failUnlessEqual(new_obj.Title(),obj_title) # title is set
00141         self.failUnlessEqual(new_obj.getId(), new_id) # does id match
00142         new_title = "Second Title"
00143         response = self.publish('%s/base_edit?form.submitted=1&title=%s&body=Blank' % ('/%s' % new_obj.absolute_url(1), new_title,), self.basic_auth) # Edit object
00144         self.assertStatusEqual(response.getStatus(), 302) # OK
00145         self.failUnlessEqual(new_obj.getId(), new_id) # id shouldn't have changed
00146 
00147         del DDocument._at_rename_after_creation
00148 
00149     def test_id_change_with_non_auto_id(self):
00150         """Make sure Id is only set when original id is autogenerated"""
00151         # Make our content type use auto generated ids
00152         from Products.Archetypes.examples.DDocument import DDocument
00153         DDocument._at_rename_after_creation = True
00154     
00155         auto_id='orig_id'
00156     
00157         # create an object with an autogenerated id
00158         response = self.publish(self.folder_path +
00159                                 '/invokeFactory?type_name=DDocument&id=%s'%auto_id,
00160                                 self.basic_auth)
00161     
00162         # XXX now lets test if http://plone.org/collector/4487 is present
00163         if  "base_edit.cpt" in self.portal.portal_skins.archetypes.objectIds():
00164             raise AttributeError, ("test_id_change_with_non_auto_id "
00165                   "is expected to fail unless  http://plone.org/collector/4487 is fixed")
00166     
00167         self.failUnless(auto_id in self.folder.objectIds())
00168         new_obj = getattr(self.folder, auto_id)
00169     
00170         #Change the title
00171         obj_title = "New Title for Object"
00172         new_obj_path = '/%s' % new_obj.absolute_url(1)
00173         self.failUnless(new_obj.checkCreationFlag()) # object is not yet edited
00174     
00175         response = self.publish('%s/base_edit?form.submitted=1&title=%s&body=Blank' % (new_obj_path, obj_title,), self.basic_auth) # Edit object
00176         self.assertStatusEqual(response.getStatus(), 302) # OK
00177         self.failIf(new_obj.checkCreationFlag()) # object is fully created
00178         self.failUnlessEqual(new_obj.Title(),obj_title) # title is set
00179         self.failUnlessEqual(new_obj.getId(), auto_id) # id should not have changed
00180     
00181         del DDocument._at_rename_after_creation
00182     
00183     def test_id_change_with_without_marker(self):
00184         # Id should not be changed unless _at_rename_after_creation is set
00185         # on the class.
00186         # Make our content type use auto generated ids
00187         from Products.Archetypes.examples.DDocument import DDocument
00188         try:
00189             del DDocument._at_rename_after_creation
00190         except (AttributeError, KeyError):
00191             pass
00192     
00193         auto_id='orig_id'
00194     
00195         # create an object with an autogenerated id
00196         response = self.publish(self.folder_path +
00197                                 '/invokeFactory?type_name=DDocument&id=%s'%auto_id,
00198                                 self.basic_auth)
00199     
00200         # XXX now lets test if http://plone.org/collector/4487 is present
00201         if  "base_edit.cpt" in self.portal.portal_skins.archetypes.objectIds():
00202             raise AttributeError, ("test_id_change_with_without_marker "
00203                   "is expected to fail unless  http://plone.org/collector/4487 is fixed")
00204     
00205         self.failUnless(auto_id in self.folder.objectIds())
00206         new_obj = getattr(self.folder, auto_id)
00207     
00208         #Change the title
00209         obj_title = "New Title for Object"
00210         new_obj_path = '/%s' % new_obj.absolute_url(1)
00211         self.failUnless(new_obj.checkCreationFlag()) # object is not yet edited
00212     
00213         response = self.publish('%s/base_edit?form.submitted=1&title=%s&body=Blank' % (new_obj_path, obj_title,), self.basic_auth) # Edit object
00214         self.assertStatusEqual(response.getStatus(), 302) # OK
00215         self.failIf(new_obj.checkCreationFlag()) # object is fully created
00216         self.failUnlessEqual(new_obj.Title(),obj_title) # title is set
00217         self.failUnlessEqual(new_obj.getId(), auto_id) # id should not have changed
00218     
00219     def test_id_change_with_appended_number(self):
00220         # Make sure Id is taken from title on initial edit and not otherwise,
00221         # and that a number is appended to avoid duplicates
00222         # Make our content type use auto generated ids
00223         from Products.Archetypes.examples.DDocument import DDocument
00224         DDocument._at_rename_after_creation = True
00225     
00226         auto_id='DDocument.2005-07-12.3847392'
00227     
00228         # create an object with an autogenerated id
00229         response = self.publish(self.folder_path +
00230                                 '/invokeFactory?type_name=DDocument&id=%s'%auto_id,
00231                                 self.basic_auth)
00232         self.failUnless(auto_id in self.folder.objectIds())
00233         new_obj = getattr(self.folder, auto_id)
00234     
00235         # Perform the redirect
00236         edit_form_path = self.folder_path+'/%s/base_edit'%auto_id
00237         response = self.publish(edit_form_path, self.basic_auth)
00238     
00239         # XXX now lets test if http://plone.org/collector/4487 is present
00240         if  "base_edit.cpt" in self.portal.portal_skins.archetypes.objectIds():
00241             raise AttributeError, ("test_id_change_on_initial_edit "
00242                   "is expected to fail unless  http://plone.org/collector/4487 is fixed")
00243     
00244         self.assertStatusEqual(response.getStatus(), 200) # OK
00245     
00246         #Change the title
00247         obj_title = "New Title for Object"
00248         new_id = "new-title-for-object"
00249         new_obj_path = '/%s' % new_obj.absolute_url(1)
00250         self.failUnless(new_obj.checkCreationFlag()) # object is not yet edited
00251     
00252         response = self.publish('%s/base_edit?form.submitted=1&title=%s&body=Blank' % (new_obj_path, obj_title,), self.basic_auth) # Edit object
00253         self.assertStatusEqual(response.getStatus(), 302) # OK
00254         self.failIf(new_obj.checkCreationFlag()) # object is fully created
00255         self.failUnlessEqual(new_obj.Title(),obj_title) # title is set
00256         self.failUnlessEqual(new_obj.getId(), new_id) # does id match
00257         new_title = "Second Title"
00258         response = self.publish('%s/base_edit?form.submitted=1&title=%s&body=Blank' % ('/%s' % new_obj.absolute_url(1), new_title,), self.basic_auth) # Edit object
00259         self.assertStatusEqual(response.getStatus(), 302) # OK
00260         self.failUnlessEqual(new_obj.getId(), new_id) # id shouldn't have changed
00261         
00262         # Now do another document with the same title:
00263         auto_id='DDocument.2005-12-18.3847393'
00264     
00265         # create an object with an autogenerated id
00266         response = self.publish(self.folder_path +
00267                                 '/invokeFactory?type_name=DDocument&id=%s'%auto_id,
00268                                 self.basic_auth)
00269         self.failUnless(auto_id in self.folder.objectIds())
00270         new_obj = getattr(self.folder, auto_id)
00271     
00272         # Perform the redirect
00273         edit_form_path = self.folder_path+'/%s/base_edit'%auto_id
00274         response = self.publish(edit_form_path, self.basic_auth)
00275     
00276         self.assertStatusEqual(response.getStatus(), 200) # OK
00277     
00278         #Change the title
00279         obj_title = "New Title for Object"
00280         new_id = "new-title-for-object-1"
00281         new_obj_path = '/%s' % new_obj.absolute_url(1)
00282         self.failUnless(new_obj.checkCreationFlag()) # object is not yet edited
00283     
00284         response = self.publish('%s/base_edit?form.submitted=1&title=%s&body=Blank' % (new_obj_path, obj_title,), self.basic_auth) # Edit object
00285         self.assertStatusEqual(response.getStatus(), 302) # OK
00286         self.failIf(new_obj.checkCreationFlag()) # object is fully created
00287         self.failUnlessEqual(new_obj.Title(),obj_title) # title is set
00288         self.failUnlessEqual(new_obj.getId(), new_id) # does id match
00289         new_title = "Second Title"
00290         response = self.publish('%s/base_edit?form.submitted=1&title=%s&body=Blank' % ('/%s' % new_obj.absolute_url(1), new_title,), self.basic_auth) # Edit object
00291         self.assertStatusEqual(response.getStatus(), 302) # OK
00292         self.failUnlessEqual(new_obj.getId(), new_id) # id shouldn't have changed
00293     
00294         del DDocument._at_rename_after_creation
00295     
00296     
00297     
00298     def test_update_schema_does_not_reset_creation_flag(self):
00299         # This is functional so that we get a full request and set the flag
00300 
00301         # create an object with flag set
00302         response = self.publish(self.folder_path +
00303                               '/invokeFactory?type_name=DDocument&id=new_doc',
00304                               self.basic_auth)
00305         self.failUnless('new_doc' in self.folder.objectIds())
00306         new_obj = self.folder.new_doc
00307         self.failUnless(new_obj.checkCreationFlag()) # object is not yet edited
00308         obj_title = "New Title for Object"
00309         new_obj_path = '/%s' % new_obj.absolute_url(1)
00310         response = self.publish('%s/base_edit?form.submitted=1&title=%s&body=Blank' % (new_obj_path, obj_title,), self.basic_auth) # Edit object
00311 
00312         # now lets test if http://plone.org/collector/4487 is present
00313         if  "base_edit.cpt" in self.portal.portal_skins.archetypes.objectIds():
00314             raise AttributeError, ("test_update_schema_does_not_reset_creation_flag "
00315                   "is expected to fail unless  http://plone.org/collector/4487 is fixed")
00316 
00317         self.failIf(new_obj.checkCreationFlag()) # object is fully created
00318         # Now run the schema update
00319         req = self.app.REQUEST
00320         req.form['update_all']=True
00321         req.form['Archetypes.DDocument']=True
00322         self.portal.archetype_tool.manage_updateSchema(REQUEST=req)
00323         self.failIf(new_obj.checkCreationFlag())
00324 
00325     def test_createObjectViaWebDAV(self):
00326         # WebDAV upload should create new document without creation flag set
00327         response = self.publish(self.folder_path+'/new_html',
00328                                 env={'CONTENT_TYPE': 'text/html'},
00329                                 request_method='PUT',
00330                                 stdin=StringIO(html),
00331                                 basic=self.basic_auth)
00332 
00333         self.assertEqual(response.getStatus(), 201)
00334         self.failUnless('new_html' in self.folder.objectIds())
00335         self.assertEqual(self.folder.new_html.portal_type, 'DDocument')
00336         self.assertEqual(self.folder.new_html.getBody(), html)
00337         self.failIf(self.folder.new_html.checkCreationFlag())
00338 
00339     def test_createObjectInCodeDoesNotSetFlag(self):
00340         # Using invokeFactory from code should not set the creation flag
00341 
00342         # Functional sets the method to GET, this isn't really a functional
00343         # test but is a special case for the previous tests, so we'll unset
00344         # the REQUEST_METHOD.
00345         self.app.REQUEST.set('REQUEST_METHOD', 'nonsense')
00346 
00347         self.folder.invokeFactory('DDocument','bogus_item')
00348         self.failUnless('bogus_item' in self.folder.objectIds())
00349         self.failIf(self.folder.bogus_item.checkCreationFlag())
00350 
00351         self.app.REQUEST.set('REQUEST_METHOD','GET')
00352 
00353 
00354 def test_suite():
00355     from unittest import TestSuite, makeSuite
00356     from Testing.ZopeTestCase import FunctionalDocFileSuite as FileSuite
00357     suite = TestSuite()
00358     suite.addTest(makeSuite(TestFunctionalObjectCreation))
00359     files = (
00360         'traversal.txt',
00361         'traversal_4981.txt',
00362         'folder_marshall.txt',
00363         'reindex_sanity_plone21.txt',
00364         'webdav_operations.txt',
00365         )
00366     for file in files:
00367         suite.addTest(FileSuite(file, package="Products.Archetypes.tests",
00368                                 test_class=ATFunctionalSiteTestCase)
00369                      )
00370     return suite