Back to index

plone3  3.1.7
test_workflow.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """Workflow tool xml adapter and setup handler unit tests.
00014 
00015 $Id: test_workflow.py 76996 2007-06-24 00:18:49Z hannosch $
00016 """
00017 
00018 import unittest
00019 import Testing
00020 
00021 from OFS.Folder import Folder
00022 from zope.interface import implements
00023 
00024 from Products.GenericSetup.testing import BodyAdapterTestCase
00025 from Products.GenericSetup.tests.common import BaseRegistryTests
00026 from Products.GenericSetup.tests.common import DummyExportContext
00027 from Products.GenericSetup.tests.common import DummyImportContext
00028 
00029 from Products.CMFCore.interfaces import IConfigurableWorkflowTool
00030 from Products.CMFCore.testing import DummyWorkflow
00031 from Products.CMFCore.testing import ExportImportZCMLLayer
00032 
00033 _WORKFLOWTOOL_BODY = """\
00034 <?xml version="1.0"?>
00035 <object name="portal_workflow" meta_type="CMF Workflow Tool">
00036  <property name="title"></property>
00037  <object name="foo_workflow" meta_type="Dummy Workflow"/>
00038  <bindings>
00039   <default>
00040    <bound-workflow workflow_id="foo_workflow"/>
00041   </default>
00042   <type type_id="Foo Type"/>
00043  </bindings>
00044 </object>
00045 """
00046 
00047 _EMPTY_TOOL_EXPORT = """\
00048 <?xml version="1.0"?>
00049 <object name="portal_workflow" meta_type="Dummy Workflow Tool">
00050  <property name="title"></property>
00051  <bindings>
00052   <default/>
00053  </bindings>
00054 </object>
00055 """
00056 
00057 _BINDINGS_TOOL_EXPORT = """\
00058 <?xml version="1.0"?>
00059 <object name="portal_workflow" meta_type="Dummy Workflow Tool">
00060  <bindings>
00061   <default>
00062    <bound-workflow workflow_id="non_dcworkflow_0"/>
00063    <bound-workflow workflow_id="non_dcworkflow_1"/>
00064   </default>
00065   <type type_id="sometype">
00066    <bound-workflow workflow_id="non_dcworkflow_2"/>
00067   </type>
00068   <type type_id="anothertype">
00069    <bound-workflow workflow_id="non_dcworkflow_3"/>
00070   </type>
00071  </bindings>
00072 </object>
00073 """
00074 
00075 _NORMAL_TOOL_EXPORT = """\
00076 <?xml version="1.0"?>
00077 <object name="portal_workflow" meta_type="Dummy Workflow Tool">
00078  <property name="title"></property>
00079  <object name="Non-DCWorkflow" meta_type="Dummy Workflow"/>
00080  <bindings>
00081   <default/>
00082  </bindings>
00083 </object>
00084 """
00085 
00086 _FRAGMENT_IMPORT = """\
00087 <?xml version="1.0"?>
00088 <object name="portal_workflow">
00089  <bindings>
00090   <type type_id="sometype" remove=""/>
00091  </bindings>
00092 </object>
00093 """
00094 
00095 
00096 class DummyWorkflowTool(Folder):
00097 
00098     implements(IConfigurableWorkflowTool)
00099 
00100     meta_type = 'Dummy Workflow Tool'
00101 
00102     def __init__(self, id='portal_workflow'):
00103         Folder.__init__(self, id)
00104         self._default_chain = ()
00105         self._chains_by_type = {}
00106 
00107     def getWorkflowIds(self):
00108         return self.objectIds()
00109 
00110     def getWorkflowById(self, workflow_id):
00111         return self._getOb(workflow_id)
00112 
00113     def getDefaultChain(self):
00114         return self._default_chain
00115 
00116     def setDefaultChain(self, chain):
00117         chain = chain.replace(',', ' ')
00118         self._default_chain = tuple(chain.split())
00119 
00120     def listChainOverrides(self):
00121         return sorted(self._chains_by_type.items())
00122 
00123     def setChainForPortalTypes(self, pt_names, chain, verify=True):
00124         if chain is None:
00125             for pt_name in pt_names:
00126                 if pt_name in self._chains_by_type:
00127                     del self._chains_by_type[pt_name]
00128             return
00129 
00130         chain = chain.replace(',', ' ')
00131         chain = tuple(chain.split())
00132 
00133         for pt_name in pt_names:
00134             self._chains_by_type[pt_name] = chain
00135 
00136 
00137 class WorkflowToolXMLAdapterTests(BodyAdapterTestCase):
00138 
00139     layer = ExportImportZCMLLayer
00140 
00141     def _getTargetClass(self):
00142         from Products.CMFCore.exportimport.workflow \
00143                 import WorkflowToolXMLAdapter
00144 
00145         return WorkflowToolXMLAdapter
00146 
00147     def _populate(self, obj):
00148         obj._setObject('foo_workflow', DummyWorkflow('foo_workflow'))
00149         obj.setDefaultChain('foo_workflow')
00150         obj.setChainForPortalTypes(('Foo Type',), '', verify=False)
00151 
00152     def setUp(self):
00153         from Products.CMFCore.WorkflowTool import WorkflowTool
00154 
00155         BodyAdapterTestCase.setUp(self)
00156         self._obj = WorkflowTool()
00157         self._BODY = _WORKFLOWTOOL_BODY
00158 
00159 
00160 class _WorkflowSetup(BaseRegistryTests):
00161 
00162     def _initSite(self):
00163         self.root.site = Folder(id='site')
00164         site = self.root.site
00165         self.root.site.portal_workflow = DummyWorkflowTool()
00166         return site
00167 
00168 
00169 class exportWorkflowToolTests(_WorkflowSetup):
00170 
00171     layer = ExportImportZCMLLayer
00172 
00173     def test_empty(self):
00174         from Products.CMFCore.exportimport.workflow import exportWorkflowTool
00175 
00176         site = self._initSite()
00177         context = DummyExportContext(site)
00178         exportWorkflowTool(context)
00179 
00180         self.assertEqual(len(context._wrote), 1)
00181         filename, text, content_type = context._wrote[0]
00182         self.assertEqual(filename, 'workflows.xml')
00183         self._compareDOM(text, _EMPTY_TOOL_EXPORT)
00184         self.assertEqual(content_type, 'text/xml')
00185 
00186     def test_normal(self):
00187         from Products.CMFCore.exportimport.workflow import exportWorkflowTool
00188 
00189         WF_ID_NON = 'non_dcworkflow'
00190         WF_TITLE_NON = 'Non-DCWorkflow'
00191 
00192         site = self._initSite()
00193         wf_tool = site.portal_workflow
00194         nondcworkflow = DummyWorkflow(WF_TITLE_NON)
00195         nondcworkflow.title = WF_TITLE_NON
00196         wf_tool._setObject(WF_ID_NON, nondcworkflow)
00197 
00198         context = DummyExportContext(site)
00199         exportWorkflowTool(context)
00200 
00201         self.assertEqual(len(context._wrote), 2)
00202         filename, text, content_type = context._wrote[0]
00203         self.assertEqual(filename, 'workflows.xml')
00204         self._compareDOM(text, _NORMAL_TOOL_EXPORT)
00205         self.assertEqual(content_type, 'text/xml')
00206 
00207 
00208 class importWorkflowToolTests(_WorkflowSetup):
00209 
00210     layer = ExportImportZCMLLayer
00211 
00212     _BINDINGS_TOOL_EXPORT = _BINDINGS_TOOL_EXPORT
00213     _EMPTY_TOOL_EXPORT = _EMPTY_TOOL_EXPORT
00214     _FRAGMENT_IMPORT = _FRAGMENT_IMPORT
00215 
00216     def test_empty_default_purge(self):
00217         from Products.CMFCore.exportimport.workflow import importWorkflowTool
00218 
00219         WF_ID_NON = 'non_dcworkflow_%s'
00220         WF_TITLE_NON = 'Non-DCWorkflow #%s'
00221 
00222         site = self._initSite()
00223         wf_tool = site.portal_workflow
00224 
00225         for i in range(4):
00226             nondcworkflow = DummyWorkflow(WF_TITLE_NON % i)
00227             nondcworkflow.title = WF_TITLE_NON % i
00228             wf_tool._setObject(WF_ID_NON % i, nondcworkflow)
00229 
00230         wf_tool._default_chain = (WF_ID_NON % 1,)
00231         wf_tool._chains_by_type['sometype'] = (WF_ID_NON % 2,)
00232         self.assertEqual(len(wf_tool.objectIds()), 4)
00233 
00234         context = DummyImportContext(site)
00235         context._files['workflows.xml'] = self._EMPTY_TOOL_EXPORT
00236         importWorkflowTool(context)
00237 
00238         self.assertEqual(len(wf_tool.objectIds()), 0)
00239         self.assertEqual(len(wf_tool._default_chain), 0)
00240         self.assertEqual(len(wf_tool._chains_by_type), 0)
00241 
00242     def test_empty_explicit_purge(self):
00243         from Products.CMFCore.exportimport.workflow import importWorkflowTool
00244 
00245         WF_ID_NON = 'non_dcworkflow_%s'
00246         WF_TITLE_NON = 'Non-DCWorkflow #%s'
00247 
00248         site = self._initSite()
00249         wf_tool = site.portal_workflow
00250 
00251         for i in range(4):
00252             nondcworkflow = DummyWorkflow(WF_TITLE_NON % i)
00253             nondcworkflow.title = WF_TITLE_NON % i
00254             wf_tool._setObject(WF_ID_NON % i, nondcworkflow)
00255 
00256         wf_tool._default_chain = (WF_ID_NON % 1,)
00257         wf_tool._chains_by_type['sometype'] = (WF_ID_NON % 2,)
00258         self.assertEqual(len(wf_tool.objectIds()), 4)
00259 
00260         context = DummyImportContext(site, True)
00261         context._files['workflows.xml'] = self._EMPTY_TOOL_EXPORT
00262         importWorkflowTool(context)
00263 
00264         self.assertEqual(len(wf_tool.objectIds()), 0)
00265         self.assertEqual(len(wf_tool._default_chain), 0)
00266         self.assertEqual(len(wf_tool._chains_by_type), 0)
00267 
00268     def test_empty_skip_purge(self):
00269         from Products.CMFCore.exportimport.workflow import importWorkflowTool
00270 
00271         WF_ID_NON = 'non_dcworkflow_%s'
00272         WF_TITLE_NON = 'Non-DCWorkflow #%s'
00273 
00274         site = self._initSite()
00275         wf_tool = site.portal_workflow
00276 
00277         for i in range(4):
00278             nondcworkflow = DummyWorkflow(WF_TITLE_NON % i)
00279             nondcworkflow.title = WF_TITLE_NON % i
00280             wf_tool._setObject(WF_ID_NON % i, nondcworkflow)
00281 
00282         wf_tool._default_chain = (WF_ID_NON % 1,)
00283         wf_tool._chains_by_type['sometype'] = (WF_ID_NON % 2,)
00284         self.assertEqual(len(wf_tool.objectIds()), 4)
00285 
00286         context = DummyImportContext(site, False)
00287         context._files['typestool.xml'] = self._EMPTY_TOOL_EXPORT
00288         importWorkflowTool(context)
00289 
00290         self.assertEqual(len(wf_tool.objectIds()), 4)
00291         self.assertEqual(len(wf_tool._default_chain), 1)
00292         self.assertEqual(wf_tool._default_chain[0], WF_ID_NON % 1)
00293         self.assertEqual(len(wf_tool._chains_by_type), 1)
00294         self.assertEqual(wf_tool._chains_by_type['sometype'],
00295                          (WF_ID_NON % 2,))
00296 
00297     def test_bindings_skip_purge(self):
00298         from Products.CMFCore.exportimport.workflow import importWorkflowTool
00299 
00300         WF_ID_NON = 'non_dcworkflow_%s'
00301         WF_TITLE_NON = 'Non-DCWorkflow #%s'
00302 
00303         site = self._initSite()
00304         wf_tool = site.portal_workflow
00305 
00306         for i in range(4):
00307             nondcworkflow = DummyWorkflow(WF_TITLE_NON % i)
00308             nondcworkflow.title = WF_TITLE_NON % i
00309             wf_tool._setObject(WF_ID_NON % i, nondcworkflow)
00310 
00311         wf_tool._default_chain = (WF_ID_NON % 1,)
00312         wf_tool._chains_by_type['sometype'] = (WF_ID_NON % 2,)
00313         self.assertEqual(len(wf_tool.objectIds()), 4)
00314 
00315         context = DummyImportContext(site, False)
00316         context._files['workflows.xml'] = self._BINDINGS_TOOL_EXPORT
00317         importWorkflowTool(context)
00318 
00319         self.assertEqual(len(wf_tool.objectIds()), 4)
00320         self.assertEqual(len(wf_tool._default_chain), 2)
00321         self.assertEqual(wf_tool._default_chain[0], WF_ID_NON % 0)
00322         self.assertEqual(wf_tool._default_chain[1], WF_ID_NON % 1)
00323         self.assertEqual(len(wf_tool._chains_by_type), 2)
00324         self.assertEqual(wf_tool._chains_by_type['sometype'],
00325                          (WF_ID_NON % 2,))
00326         self.assertEqual(wf_tool._chains_by_type['anothertype'],
00327                          (WF_ID_NON % 3,))
00328 
00329     def test_fragment_skip_purge(self):
00330         from Products.CMFCore.exportimport.workflow import importWorkflowTool
00331 
00332         WF_ID_NON = 'non_dcworkflow_%s'
00333         WF_TITLE_NON = 'Non-DCWorkflow #%s'
00334 
00335         site = self._initSite()
00336         wf_tool = site.portal_workflow
00337 
00338         for i in range(4):
00339             nondcworkflow = DummyWorkflow(WF_TITLE_NON % i)
00340             nondcworkflow.title = WF_TITLE_NON % i
00341             wf_tool._setObject(WF_ID_NON % i, nondcworkflow)
00342 
00343         wf_tool._default_chain = (WF_ID_NON % 1,)
00344         wf_tool._chains_by_type['sometype'] = (WF_ID_NON % 2,)
00345         self.assertEqual(len(wf_tool.objectIds()), 4)
00346 
00347         context = DummyImportContext(site, False)
00348         context._files['workflows.xml'] = self._FRAGMENT_IMPORT
00349         importWorkflowTool(context)
00350 
00351         self.assertEqual(len(wf_tool.objectIds()), 4)
00352         self.assertEqual(len(wf_tool._default_chain), 1)
00353         self.assertEqual(wf_tool._default_chain[0], WF_ID_NON % 1)
00354         self.assertEqual(len(wf_tool._chains_by_type), 0)
00355 
00356 
00357 def test_suite():
00358     return unittest.TestSuite((
00359         unittest.makeSuite(WorkflowToolXMLAdapterTests),
00360         unittest.makeSuite(exportWorkflowToolTests),
00361         unittest.makeSuite(importWorkflowToolTests),
00362         ))
00363 
00364 if __name__ == '__main__':
00365     from Products.CMFCore.testing import run
00366     run(test_suite())