Back to index

plone3  3.1.7
test_copying.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 Unittests for a copying/cutting and pasting archetypes objects.
00027 
00028 $Id: test_copying.py 7768 2007-03-18 23:38:08Z nouri $
00029 """
00030 
00031 import os
00032 
00033 import transaction
00034 from Acquisition import aq_base
00035 
00036 from AccessControl.SecurityManagement import newSecurityManager
00037 from AccessControl.SecurityManagement import noSecurityManager
00038 
00039 from Products.Archetypes.tests.atsitetestcase import ATSiteTestCase
00040 from Products.Archetypes.tests.utils import makeContent
00041 from Products.Archetypes.tests.atsitetestcase import portal_owner
00042 from Products.Archetypes.tests.atsitetestcase import portal_name
00043 from Products.Archetypes.tests.utils import PACKAGE_HOME
00044 
00045 class CutPasteCopyPasteTests(ATSiteTestCase):
00046 
00047     def test_copy_and_paste(self):
00048         ffrom = makeContent(self.folder, portal_type='SimpleFolder', id='cangucu')
00049         tourist = makeContent(ffrom, portal_type='Fact', id='tourist')
00050         fto = makeContent(self.folder, portal_type='SimpleFolder', id='london')
00051         self.failIf('tourist' not in ffrom.contentIds())
00052 
00053         #make sure we have _p_jar
00054         transaction.savepoint(optimistic=True)
00055         cb = ffrom.manage_copyObjects(ffrom.contentIds())
00056         fto.manage_pasteObjects(cb)
00057         self.failIf('tourist' not in ffrom.contentIds())
00058         self.failIf('tourist' not in fto.contentIds())
00059 
00060     def test_cut_and_paste(self):
00061         ffrom = makeContent(self.folder, portal_type='SimpleFolder', id='cangucu')
00062         tourist = makeContent(ffrom, portal_type='Fact', id='tourist')
00063         fto = makeContent(self.folder, portal_type='SimpleFolder', id='london')
00064         self.failIf('tourist' not in ffrom.contentIds())
00065 
00066         #make sure we have _p_jar
00067         transaction.savepoint(optimistic=True)
00068         cb = ffrom.manage_cutObjects(ffrom.contentIds())
00069         fto.manage_pasteObjects(cb)
00070         self.failIf('tourist' in ffrom.contentIds())
00071         self.failIf('tourist' not in fto.contentIds())
00072 
00073 class PortalCopyTests(ATSiteTestCase):
00074 
00075     def afterSetUp(self):
00076         ATSiteTestCase.afterSetUp(self)
00077         self.setRoles(['Manager',])
00078 
00079         imgpath = os.path.join(PACKAGE_HOME, os.pardir, 'tool.gif')
00080         self._image = open(imgpath).read()
00081 
00082         portal = self.portal
00083 
00084         portal.invokeFactory('DDocument', id='document')
00085         doc = portal.document
00086         doc.setBody('testdata', mimetype='text/x-rst')
00087         doc.setImage(self._image, mimetype='image/gif')
00088 
00089     def _test_doc(self, doc):
00090         bodyfield = doc.getField('body')
00091         imagefield = doc.getField('image')
00092 
00093         self.failUnlessEqual(doc.getContentType(), 'text/x-rst')
00094 
00095         self.failUnlessEqual(doc.getRawBody(), 'testdata')
00096         self.failUnless(doc.getImage().data, self._image)
00097 
00098         self.failUnless(bodyfield.getContentType(doc), 'text/x-rst')
00099 
00100     def test_created_doc(self):
00101         portal = self.portal
00102         self.failUnless(portal, 'document')
00103         doc = portal.document
00104         self._test_doc(doc)
00105 
00106     def test_clone_portal(self):
00107         app = self.app
00108         user = app.acl_users.getUserById(portal_owner).__of__(app.acl_users)
00109         newSecurityManager(None, user)
00110         app.manage_clone(self.portal, 'newportal')
00111         noSecurityManager()
00112         transaction.savepoint(optimistic=True)
00113 
00114         self.failUnless(hasattr(aq_base(app), 'newportal'))
00115         self.newportal = app.newportal
00116         # check if we really have new portal!
00117         self.failIf(aq_base(self.newportal) is aq_base(self.portal))
00118         self.failIfEqual(aq_base(self.newportal), aq_base(self.portal))
00119 
00120         self.failUnless(hasattr(aq_base(self.newportal), 'document'))
00121         doc = self.newportal.document
00122         self._test_doc(doc)
00123 
00124     def test_copy_paste_portal(self):
00125         app = self.app
00126         user = app.acl_users.getUserById('portal_owner').__of__(app.acl_users)
00127         newSecurityManager(None, user)
00128         cp = app.manage_copyObjects(ids=[portal_name])
00129         app.manage_pasteObjects(cb_copy_data=cp)
00130 
00131         noSecurityManager()
00132         transaction.savepoint(optimistic=True)
00133 
00134         self.failUnless(hasattr(aq_base(self.app), 'copy_of_%s' % portal_name))
00135         self.newportal = getattr(self.app, 'copy_of_%s' % portal_name)
00136         # check if we really have new portal!
00137         self.failIf(aq_base(self.newportal) is aq_base(self.portal))
00138         self.failIfEqual(aq_base(self.newportal), aq_base(self.portal))
00139 
00140         self.failUnless(hasattr(aq_base(self.newportal), 'document'))
00141         doc = self.newportal.document
00142         self._test_doc(doc)
00143 
00144     def test_cut_paste_portal(self):
00145         app = self.app
00146         user = app.acl_users.getUserById(portal_owner).__of__(app.acl_users)
00147         newSecurityManager(None, user)
00148         cp = app.manage_cutObjects(ids=[portal_name])
00149         app.manage_pasteObjects(cb_copy_data=cp)
00150 
00151         noSecurityManager()
00152         transaction.savepoint(optimistic=True)
00153 
00154         self.failUnless(hasattr(aq_base(self.app), portal_name))
00155         self.newportal = getattr(self.app, portal_name)
00156 
00157         self.failUnless(hasattr(aq_base(self.newportal), 'document'))
00158         doc = self.newportal.document
00159         self._test_doc(doc)
00160 
00161     def test_copy_paste_sets_ownership(self):
00162         # Copy/pasting a File should set new ownership including local roles
00163         # borrowed from CMFCore tests
00164 
00165         # First, add two users to the user folder, a member and a manager
00166         # and create a member area for the member
00167         uf = self.portal.acl_users
00168         uf._doAddUser('member', 'secret', ['Member'], [])
00169         uf._doAddUser('manager1', 'secret', ['Manager'], [])
00170         member = uf.getUser('member').__of__(uf)
00171         manager1 = uf.getUser('manager1').__of__(uf)
00172         self.portal.portal_membership.setMemberareaCreationFlag()
00173         self.portal.portal_membership.createMemberArea('member')
00174         member_area = self.portal.Members.member
00175 
00176         # Switch to the manager user context and plant a content item into
00177         # the member user's member area
00178         self.login('manager1')
00179         member_area.invokeFactory('DDocument', id='test_file')
00180 
00181         # Switch to "member" context now and try to copy and paste the
00182         # content item created by "manager1"
00183         self.login('member')
00184         cb = member_area.manage_copyObjects(['test_file'])
00185         member_area.manage_pasteObjects(cb)
00186 
00187         # Now test executable ownership and "owner" local role
00188         # "member" should have both.
00189         file_ob = member_area.copy_of_test_file
00190         self.assertEqual(aq_base(file_ob.getOwner().getId()), aq_base(member).getId())
00191         self.failUnless('Owner' in
00192                             file_ob.get_local_roles_for_userid('member'))
00193 
00194     def test_copy_paste_resets_workflow(self):
00195         # Copy/pasting a File should reset workflow to the default state
00196 
00197         # This test depends on the default wf, assume CMFDefault if plone
00198         # isn't present
00199         wf_tool = self.portal.portal_workflow
00200         if 'plone_workflow' in wf_tool.objectIds():
00201             wf_id = 'plone_workflow'
00202             def_state = 'visible'
00203         else:
00204             wf_id = 'default_workflow'
00205             def_state = 'private'
00206 
00207         wf_tool.setChainForPortalTypes(('DDocument',), (wf_id,))
00208         self.folder.invokeFactory('DDocument', id='test_file')
00209 
00210         file = self.folder.test_file
00211 
00212         self.assertEqual(wf_tool.getInfoFor(file, 'review_state'), def_state)
00213         wf_tool.doActionFor(file, 'publish')
00214         self.assertEqual(wf_tool.getInfoFor(file, 'review_state'),
00215                                                                  'published')
00216 
00217         cb = self.folder.manage_copyObjects(['test_file'])
00218         self.folder.manage_pasteObjects(cb)
00219 
00220         file_copy = self.folder.copy_of_test_file
00221         self.assertEqual(wf_tool.getInfoFor(file_copy, 'review_state'),
00222                                                                    def_state)
00223 
00224     def test_cut_paste_preserves_workflow(self):
00225         # Cut/pasting a File should preserve workflow state
00226 
00227         # This test depends on the default wf, assume CMFDefault if plone
00228         # isn't present
00229         wf_tool = self.portal.portal_workflow
00230         if 'plone_workflow' in wf_tool.objectIds():
00231             wf_id = 'plone_workflow'
00232             def_state = 'visible'
00233         else:
00234             wf_id = 'default_workflow'
00235             def_state = 'private'
00236 
00237         wf_tool.setChainForPortalTypes(('DDocument',), (wf_id,))
00238         self.folder.invokeFactory('DDocument', id='test_file')
00239         self.folder.invokeFactory('Folder', id='sub')
00240 
00241         file = self.folder.test_file
00242 
00243         self.assertEqual(wf_tool.getInfoFor(file, 'review_state'), def_state)
00244         wf_tool.doActionFor(file, 'publish')
00245         self.assertEqual(wf_tool.getInfoFor(file, 'review_state'),
00246                                                                  'published')
00247 
00248         transaction.savepoint(optimistic=True)
00249         cb = self.folder.manage_cutObjects(['test_file'])
00250         self.folder.sub.manage_pasteObjects(cb)
00251 
00252         file_copy = self.folder.sub.test_file
00253         self.assertEqual(wf_tool.getInfoFor(file_copy, 'review_state'),
00254                                                                  'published')
00255 
00256     def test_copy_handles_talkback_Items(self):
00257         # We need to ensure that the manage_after* methods are called on
00258         # subobjects of non-folderish objects
00259         doc = self.portal.document
00260         dtool = self.portal.portal_discussion
00261         cat = self.portal.portal_catalog
00262 
00263         doc.allowDiscussion('1')
00264         tb = dtool.getDiscussionFor(doc)
00265         tb.createReply(title='Stupendous', text='silly', Creator='admin')
00266 
00267         # Creating the reply should have cataloged it in manage_afterAdd
00268         results = cat(Title='Stupendous')
00269         self.assertEqual(len(results), 1)
00270 
00271         cp = self.portal.manage_copyObjects(ids=['document'])
00272         self.folder.manage_pasteObjects(cp)
00273         doc_copy = self.folder.document
00274 
00275         tb = dtool.getDiscussionFor(doc_copy)
00276         self.failUnless(tb.hasReplies(doc_copy), "Discussion not copied")
00277 
00278         # Copying doc should have cataloged the reply in manage_afterClone
00279         results = cat(Title='Stupendous')
00280         self.assertEqual(len(results), 2)
00281 
00282     # not sure where else to put this
00283     def test_delete_handles_talkback_Items(self):
00284         doc = self.portal.document
00285         dtool = self.portal.portal_discussion
00286         cat = self.portal.portal_catalog
00287 
00288         doc.allowDiscussion('1')
00289         tb = dtool.getDiscussionFor(doc)
00290         tb.createReply(title='Stupendous', text='silly', Creator='admin')
00291 
00292         # Creating the reply should have cataloged it in manage_afterAdd
00293         results = cat(Title='Stupendous')
00294         self.assertEqual(len(results), 1)
00295 
00296         self.portal.manage_delObjects(ids=['document'])
00297 
00298         # Deleting the doc should have removed the discussions from the
00299         # catalog
00300         results = cat(Title='Stupendous')
00301         self.assertEqual(len(results), 0)
00302 
00303 
00304 def test_suite():
00305     from unittest import TestSuite, makeSuite
00306     suite = TestSuite()
00307     suite.addTest(makeSuite(CutPasteCopyPasteTests))
00308     suite.addTest(makeSuite(PortalCopyTests))
00309     return suite