Back to index

plone3  3.1.7
testContentPublishing.py
Go to the documentation of this file.
00001 #
00002 # Tests security of content publishing operations
00003 # code inspired by Ween
00004 #
00005 
00006 from Products.CMFPlone.tests import PloneTestCase
00007 from Products.CMFPlone.tests import dummy
00008 
00009 text="""I lick my brain in silence
00010 Rather squeeze my head instead
00011 Midget man provoking violence
00012 Listen not to what I said 
00013 
00014 I said please calm it down
00015 Everything is turning brown
00016 
00017 Mutilated lips give a kiss on the wrist
00018 Of the worm like tips of tentacles expanding
00019 In my mind, I'm fine, accepting only fresh brine
00020 You can get another drop of this, yeah you wish...
00021 [repeat]
00022 
00023 Laughing lady living lover
00024 Ooo you sassy frassy lassie
00025 Find me the skull of Haile Sellase, I...
00026 Give me shoes so I can tapsy
00027 Tap all over this big world
00028 Take my hand you ugly girl """
00029 
00030 props={'description':'song by ween',
00031        'contributors':['dean ween', 'gene ween'],
00032        'effective_date':'2004-01-12',
00033        'expiration_date':'2004-12-12',
00034        'format':'text/plain',
00035        'language':'english',
00036        'rights':'ween music',
00037        'title':'mutalitated lips',
00038        'subject':['psychedelic', 'pop', '13th floor elevators']}
00039 
00040 
00041 class TestContentPublishing(PloneTestCase.PloneTestCase):
00042     """ The instant publishing drop down UI.
00043         !NOTE! CMFDefault.Document overrides setFormat and Format
00044         so it acts strangely.  This is also hardcoded to work with Document.
00045 
00046         This testcase was written to prevent collector/2914 regressions
00047 
00048         In addition, some more general tests of content_status_modify and
00049         folder_publish behaviour have been added, since this seems a logical
00050         place to keep them.
00051     """
00052 
00053     def afterSetUp(self):
00054         self.portal.acl_users._doAddUser('user1', 'secret', ['Member'], [])
00055         self.membership = self.portal.portal_membership
00056         self.createMemberarea('user1')
00057         self.workflow = self.portal.portal_workflow
00058         self.setupAuthenticator()
00059 
00060     def _checkMD(self, obj, **changes):
00061         """ check the DublinCore Metadata on obj - it must inherit from DublinCore """
00062         if changes:
00063             _orig_props = {}
00064             _orig_props.update(props)
00065             props.update(changes)
00066 
00067         self.assertEqual(obj.Title(), props['title'])
00068         self.assertEqual(obj.Description(), props['description'])
00069         self.assertEqual(obj.Subject(), tuple(props['subject']))
00070         self.assertEqual(obj.ExpirationDate(zone='UTC'),
00071                          obj._datify(props['expiration_date']).ISO())
00072         self.assertEqual(obj.EffectiveDate(zone='UTC'),
00073                          obj._datify(props['effective_date']).ISO())
00074         self.assertEqual(obj.Format(), props['format'])
00075         self.assertEqual(obj.Rights(), props['rights'])
00076         self.assertEqual(obj.Language(), props['language'])
00077         self.assertEqual(obj.Contributors(), tuple(props['contributors']))
00078 
00079         if changes:
00080             props.update(_orig_props)
00081 
00082     def testInstaPublishingDocument(self):
00083         self.folder.invokeFactory('Document', id='mollusk')
00084         mollusk=self.folder.mollusk
00085         mollusk.document_edit('plain', text, title=props['title'])
00086         self.failUnless(mollusk.CookedBody()!=text)
00087         mollusk.metadata_edit(**props)
00088         self._checkMD(mollusk)
00089         mollusk.content_status_modify(workflow_action='submit')
00090         self._checkMD(mollusk)
00091         mollusk.content_status_modify(workflow_action='retract')
00092         self._checkMD(mollusk)
00093 
00094     def testInstaPublishingTextFile(self):
00095         self.folder.invokeFactory('File', id='lyrics.txt')
00096         lyrics = self.folder['lyrics.txt']
00097         lyrics.file_edit(file=dummy.File('lyrics.txt', data=text))
00098         lyrics.metadata_edit(**props)
00099         self._checkMD(lyrics)
00100         lyrics.content_status_modify(workflow_action='submit')
00101         self._checkMD(lyrics)
00102         lyrics.content_status_modify(workflow_action='retract')
00103         self._checkMD(lyrics)
00104 
00105     def testInstaPublishingWordFile(self):
00106         self.folder.invokeFactory('File', id='lyrics.doc')
00107         lyrics = self.folder['lyrics.doc']
00108         lyrics.file_edit(file=dummy.File('lyrics.doc', data='foo'))
00109         self.failUnless(lyrics.Format()=='application/msword')
00110         lyrics.metadata_edit(description='great song')
00111         self.failUnless(lyrics.Format()=='application/msword')
00112         lyrics.content_status_modify(workflow_action='submit')
00113         self.failUnless(lyrics.Format()=='application/msword')
00114         lyrics.content_status_modify(workflow_action='retract')
00115         self.failUnless(lyrics.Format()=='application/msword')
00116 
00117     # Test the recursive behaviour of content_status_modify and folder_publish:
00118 
00119     def testPublishingSubobjects(self):
00120         self.setRoles(['Manager']) # Make sure we can publish directly
00121         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00122         self.folder.invokeFactory('Folder', id = 'f1', title = 'Folder 1')
00123         self.folder.f1.invokeFactory('Document', id = 'd2', title = 'Doc 2')
00124         self.folder.f1.invokeFactory('Folder', id = 'f2', title = 'Folder 2')
00125         paths = []
00126         for o in (self.folder.d1, self.folder.f1):
00127             paths.append('/'.join(o.getPhysicalPath()))
00128 
00129         # folder_publish requires a non-GET request
00130         self.setRequestMethod('POST')
00131         self.folder.folder_publish(workflow_action = 'publish', 
00132                                    paths = paths, 
00133                                    include_children = True)
00134         for o in (self.folder.d1, self.folder.f1, self.folder.f1.d2, self.folder.f1.f2):
00135             self.assertEqual(self.workflow.getInfoFor(o, 'review_state'),'published')
00136 
00137     def testPublishingSubobjectsAndExpireThem(self):
00138         self.setRoles(['Manager']) # Make sure we can publish directly
00139         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00140         self.folder.invokeFactory('Folder', id = 'f1', title = 'Folder 1')
00141         self.folder.f1.invokeFactory('Document', id = 'd2', title = 'Doc 2')
00142         self.folder.f1.invokeFactory('Folder', id = 'f2', title = 'Folder 2')
00143         paths = []
00144         for o in (self.folder.d1, self.folder.f1):
00145             paths.append('/'.join(o.getPhysicalPath()))
00146 
00147         # folder_publish requires a non-GET request
00148         self.setRequestMethod('POST')
00149         self.folder.folder_publish(workflow_action = 'publish', 
00150                                    paths = paths, 
00151                                    effective_date = '1/1/2001',
00152                                    expiration_date = '1/2/2001',
00153                                    include_children = True)
00154         for o in (self.folder.d1, self.folder.f1, self.folder.f1.d2, self.folder.f1.f2):
00155             self.assertEqual(self.workflow.getInfoFor(o, 'review_state'),'published')
00156             self.failUnless(self.portal.isExpired(o))
00157 
00158     def testPublishingWithoutSubobjects(self):
00159         self.setRoles(['Manager']) # Make sure we can publish directly
00160         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00161         self.folder.invokeFactory('Folder', id = 'f1', title = 'Folder 1')
00162         self.folder.f1.invokeFactory('Document', id = 'd2', title = 'Doc 2')
00163         self.folder.f1.invokeFactory('Folder', id = 'f2', title = 'Folder 2')
00164         paths = []
00165         for o in (self.folder.d1, self.folder.f1):
00166             paths.append('/'.join(o.getPhysicalPath()))
00167 
00168         # folder_publish requires a non-GET request
00169         self.setRequestMethod('POST')
00170         self.folder.folder_publish(workflow_action = 'publish', 
00171                                    paths = paths, 
00172                                    include_children = False)
00173         for o in (self.folder.d1, self.folder.f1):
00174             self.assertEqual( self.workflow.getInfoFor(o, 'review_state'), 'published')
00175         for o in (self.folder.f1.d2, self.folder.f1.f2):
00176             self.assertEqual( self.workflow.getInfoFor(o, 'review_state'), 'visible')
00177 
00178     def testPublishingNonDefaultPageLeavesFolderAlone(self):
00179         self.setRoles(['Manager']) # Make sure we can publish directly
00180         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00181         self.folder.d1.content_status_modify('publish')
00182         self.assertEqual(self.workflow.getInfoFor(self.folder, 'review_state'), 'visible')
00183         self.assertEqual(self.workflow.getInfoFor(self.folder.d1, 'review_state'), 'published')
00184 
00185     def testPublishingDefaultPagePublishesFolder(self):
00186         self.setRoles(['Manager']) # Make sure we can publish directly
00187         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00188         self.folder.setDefaultPage('d1')
00189         self.folder.d1.content_status_modify('publish')
00190         self.assertEqual(self.workflow.getInfoFor(self.folder, 'review_state'), 'published')
00191         self.assertEqual(self.workflow.getInfoFor(self.folder.d1, 'review_state'), 'published')
00192 
00193     def testPublishingDefaultPageWhenFolderCannotBePublished(self):
00194         self.setRoles(['Manager']) # Make sure we can publish directly
00195         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00196         self.folder.setDefaultPage('d1')
00197         # make parent be published already when publishing its default document 
00198         # results in an attempt to do it again
00199         self.folder.content_status_modify('publish')
00200         self.assertEqual(self.workflow.getInfoFor(self.folder, 'review_state'), 'published')
00201         self.folder.d1.content_status_modify('publish')
00202         self.assertEqual(self.workflow.getInfoFor(self.folder, 'review_state'), 'published')
00203         self.assertEqual(self.workflow.getInfoFor(self.folder.d1, 'review_state'), 'published')
00204 
00205     # test setting effective/expiration date and isExpired script
00206 
00207     def testIsExpiredWithExplicitExpiredContent(self):
00208         self.setRoles(['Manager'])
00209         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00210         self.folder.d1.content_status_modify(workflow_action = 'publish',
00211                                              effective_date = '1/1/2001',
00212                                              expiration_date = '1/2/2001')
00213         self.failUnless(self.portal.isExpired(self.folder.d1))
00214 
00215     def testIsExpiredWithImplicitExpiredContent(self):
00216         self.setRoles(['Manager'])
00217         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00218         self.folder.d1.content_status_modify(workflow_action = 'publish',
00219                                              effective_date = '1/1/2001',
00220                                              expiration_date = '1/2/2001')
00221         self.failUnless(self.folder.d1.isExpired())
00222 
00223     def testIsExpiredWithExplicitNonExpiredContent(self):
00224         self.setRoles(['Manager'])
00225         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00226         self.folder.d1.content_status_modify(workflow_action = 'publish')
00227         self.failIf(self.portal.isExpired(self.folder.d1))
00228 
00229     def testIsExpiredWithImplicitNonExpiredContent(self):
00230         self.setRoles(['Manager'])
00231         self.folder.invokeFactory('Document', id = 'd1', title = 'Doc 1')
00232         self.folder.d1.content_status_modify(workflow_action = 'publish')
00233         self.failIf(self.folder.d1.isExpired())
00234 
00235 
00236 def test_suite():
00237     from unittest import TestSuite, makeSuite
00238     suite = TestSuite()
00239     suite.addTest(makeSuite(TestContentPublishing))
00240     return suite