[CMF-checkins] SVN: CMF/branches/tseaver-viewification/ Resync with
the trunk.
Tres Seaver
tseaver at palladion.com
Fri Dec 2 13:15:45 EST 2005
Log message for revision 40498:
Resync with the trunk.
Changed:
U CMF/branches/tseaver-viewification/CHANGES.txt
U CMF/branches/tseaver-viewification/CMFActionIcons/DEPENDENCIES.txt
U CMF/branches/tseaver-viewification/CMFActionIcons/__init__.py
U CMF/branches/tseaver-viewification/CMFActionIcons/exportimport.py
U CMF/branches/tseaver-viewification/CMFActionIcons/profiles/actionicons/skins.xml
U CMF/branches/tseaver-viewification/CMFCalendar/DEPENDENCIES.txt
U CMF/branches/tseaver-viewification/CMFCalendar/__init__.py
U CMF/branches/tseaver-viewification/CMFCalendar/profiles/default/skins.xml
U CMF/branches/tseaver-viewification/CMFCalendar/profiles/default/typestool.xml
U CMF/branches/tseaver-viewification/CMFCalendar/setuphandlers.py
U CMF/branches/tseaver-viewification/CMFCore/DEPENDENCIES.txt
U CMF/branches/tseaver-viewification/CMFCore/DirectoryView.py
U CMF/branches/tseaver-viewification/CMFCore/PortalContent.py
U CMF/branches/tseaver-viewification/CMFCore/TypesTool.py
U CMF/branches/tseaver-viewification/CMFCore/WorkflowTool.py
U CMF/branches/tseaver-viewification/CMFCore/__init__.py
U CMF/branches/tseaver-viewification/CMFCore/browser/configure.zcml
A CMF/branches/tseaver-viewification/CMFCore/browser/typeinfo.py
U CMF/branches/tseaver-viewification/CMFCore/configure.zcml
D CMF/branches/tseaver-viewification/CMFCore/dtml/addWorkflow.dtml
U CMF/branches/tseaver-viewification/CMFCore/exportimport/actions.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/cachingpolicymgr.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/catalog.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/configure.zcml
U CMF/branches/tseaver-viewification/CMFCore/exportimport/contenttyperegistry.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/cookieauth.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/mailhost.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/properties.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/skins.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/four/
A CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/one/
U CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_actions.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_cachingpolicymgr.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_catalog.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_content.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_contenttyperegistry.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_cookieauth.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_mailhost.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_properties.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_skins.py
U CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_typeinfo.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_workflow.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/three/
A CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/two/
U CMF/branches/tseaver-viewification/CMFCore/exportimport/typeinfo.py
A CMF/branches/tseaver-viewification/CMFCore/exportimport/workflow.py
U CMF/branches/tseaver-viewification/CMFCore/interfaces/_tools.py
U CMF/branches/tseaver-viewification/CMFCore/tests/base/testcase.py
U CMF/branches/tseaver-viewification/CMFCore/tests/test_ActionInformation.py
U CMF/branches/tseaver-viewification/CMFCore/tests/test_CachingPolicyManager.py
U CMF/branches/tseaver-viewification/CMFCore/tests/test_TypesTool.py
U CMF/branches/tseaver-viewification/CMFCore/tests/test_WorkflowTool.py
D CMF/branches/tseaver-viewification/CMFCore/www/addTypeInfo.zpt
U CMF/branches/tseaver-viewification/CMFDefault/DEPENDENCIES.txt
U CMF/branches/tseaver-viewification/CMFDefault/MetadataTool.py
U CMF/branches/tseaver-viewification/CMFDefault/__init__.py
U CMF/branches/tseaver-viewification/CMFDefault/browser/tests/linkviews.txt
U CMF/branches/tseaver-viewification/CMFDefault/dtml/metadataElementPolicies.dtml
U CMF/branches/tseaver-viewification/CMFDefault/dtml/metadataProperties.dtml
U CMF/branches/tseaver-viewification/CMFDefault/factory.py
U CMF/branches/tseaver-viewification/CMFDefault/profiles/default/catalog.xml
U CMF/branches/tseaver-viewification/CMFDefault/profiles/default/export_steps.xml
U CMF/branches/tseaver-viewification/CMFDefault/profiles/default/import_steps.xml
A CMF/branches/tseaver-viewification/CMFDefault/profiles/default/skins/
U CMF/branches/tseaver-viewification/CMFDefault/profiles/default/skins.xml
U CMF/branches/tseaver-viewification/CMFDefault/profiles/default/toolset.xml
U CMF/branches/tseaver-viewification/CMFDefault/profiles/default/typestool.xml
U CMF/branches/tseaver-viewification/CMFDefault/profiles/default/workflows.xml
U CMF/branches/tseaver-viewification/CMFDefault/setuphandlers.py
U CMF/branches/tseaver-viewification/CMFDefault/tests/test_DefaultWorkflow.py
U CMF/branches/tseaver-viewification/CMFDefault/tests/test_DiscussionReply.py
U CMF/branches/tseaver-viewification/CMFDefault/tests/test_Image.py
U CMF/branches/tseaver-viewification/CMFDefault/tests/test_MetadataTool.py
U CMF/branches/tseaver-viewification/CMFDefault/tests/test_Portal.py
U CMF/branches/tseaver-viewification/CMFDefault/tests/test_join.py
D CMF/branches/tseaver-viewification/CMFSetup/
U CMF/branches/tseaver-viewification/CMFTopic/DEPENDENCIES.txt
U CMF/branches/tseaver-viewification/CMFTopic/Topic.py
U CMF/branches/tseaver-viewification/CMFTopic/__init__.py
A CMF/branches/tseaver-viewification/CMFTopic/configure.zcml
A CMF/branches/tseaver-viewification/CMFTopic/exportimport.py
U CMF/branches/tseaver-viewification/CMFTopic/profiles/default/skins.xml
U CMF/branches/tseaver-viewification/CMFTopic/profiles/default/typestool.xml
U CMF/branches/tseaver-viewification/CMFTopic/profiles/default/workflows.xml
U CMF/branches/tseaver-viewification/CMFTopic/tests/test_DateC.py
A CMF/branches/tseaver-viewification/CMFTopic/tests/test_exportimport.py
A CMF/branches/tseaver-viewification/CMFTopic/xml/
U CMF/branches/tseaver-viewification/CMFUid/DEPENDENCIES.txt
U CMF/branches/tseaver-viewification/CMFUid/__init__.py
U CMF/branches/tseaver-viewification/DCWorkflow/DCWorkflow.py
U CMF/branches/tseaver-viewification/DCWorkflow/DEPENDENCIES.txt
D CMF/branches/tseaver-viewification/DCWorkflow/Default.py
A CMF/branches/tseaver-viewification/DCWorkflow/Extensions/
U CMF/branches/tseaver-viewification/DCWorkflow/__init__.py
A CMF/branches/tseaver-viewification/DCWorkflow/browser/
A CMF/branches/tseaver-viewification/DCWorkflow/configure.zcml
A CMF/branches/tseaver-viewification/DCWorkflow/exportimport.py
A CMF/branches/tseaver-viewification/DCWorkflow/interfaces.py
A CMF/branches/tseaver-viewification/DCWorkflow/profiles/
U CMF/branches/tseaver-viewification/DCWorkflow/tests/test_DCWorkflow.py
A CMF/branches/tseaver-viewification/DCWorkflow/tests/test_exportimport.py
U CMF/branches/tseaver-viewification/DCWorkflow/tests/test_guard.py
U CMF/branches/tseaver-viewification/DCWorkflow/utils.py
A CMF/branches/tseaver-viewification/DCWorkflow/xml/
U CMF/branches/tseaver-viewification/GenericSetup/CHANGES.txt
U CMF/branches/tseaver-viewification/GenericSetup/DEPENDENCIES.txt
U CMF/branches/tseaver-viewification/GenericSetup/MailHost/configure.zcml
U CMF/branches/tseaver-viewification/GenericSetup/MailHost/exportimport.py
U CMF/branches/tseaver-viewification/GenericSetup/MailHost/tests/test_exportimport.py
A CMF/branches/tseaver-viewification/GenericSetup/OFSP/
U CMF/branches/tseaver-viewification/GenericSetup/PluginIndexes/tests/test_exportimport.py
A CMF/branches/tseaver-viewification/GenericSetup/PythonScripts/
U CMF/branches/tseaver-viewification/GenericSetup/ZCTextIndex/tests/test_exportimport.py
U CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/configure.zcml
U CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/exportimport.py
U CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/tests/test_exportimport.py
U CMF/branches/tseaver-viewification/GenericSetup/__init__.py
A CMF/branches/tseaver-viewification/GenericSetup/bbb/
A CMF/branches/tseaver-viewification/GenericSetup/browser/
U CMF/branches/tseaver-viewification/GenericSetup/configure.zcml
U CMF/branches/tseaver-viewification/GenericSetup/content.py
U CMF/branches/tseaver-viewification/GenericSetup/context.py
U CMF/branches/tseaver-viewification/GenericSetup/interfaces.py
U CMF/branches/tseaver-viewification/GenericSetup/registry.py
U CMF/branches/tseaver-viewification/GenericSetup/testing.py
U CMF/branches/tseaver-viewification/GenericSetup/tests/common.py
U CMF/branches/tseaver-viewification/GenericSetup/tests/test_context.py
U CMF/branches/tseaver-viewification/GenericSetup/tests/test_registry.py
U CMF/branches/tseaver-viewification/GenericSetup/tool.py
U CMF/branches/tseaver-viewification/GenericSetup/utils.py
-=-
Modified: CMF/branches/tseaver-viewification/CHANGES.txt
===================================================================
--- CMF/branches/tseaver-viewification/CHANGES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CHANGES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -2,6 +2,29 @@
New Features
+ - CMFDefault.MetadataTool: support arbitrary additional schemas.
+ The "stock" DublinCore-specific API is still accessible, implemented
+ via a special "DCMI" subobject.
+
+ - WorkflowTool and DCWorkflow: Improved add form for workflow objects.
+ Presettings can now be loaded from workflow settings in setup profiles.
+ This replaces the feature that did allow to load presettings from the
+ oldstyle workflow factories registry.
+
+ - WorkflowTool: Switched to generic plug-in mechanism for workflows.
+ Any class registered for IWorkflowDefinition can now be used in the
+ WorkflowTool.
+
+ - DCWorkflow: Added 'revision2' profile.
+ This replaces the hardcoded 'Revision 2' default workflow.
+
+ - CMFActionIcons, CMFCalendar, CMFDefault, CMFTopic, CMFUid:
+ use the new 'for_' argument in GenericSetup's profile registry API
+ to indicate that profiles are intended for CMFCore's ISiteRoot sites.
+
+ - CMFTopic: added specialized GenericSetup support for topics, to
+ allow capturing criteria in a single XML file.
+
- CMFDefault and CMFTopic: Split off CMFTopic profile.
CMFTopic support is now configured by an optional extension profile.
CMFDefault no longer depends on CMFTopic.
@@ -20,7 +43,7 @@
- ActionsTool: Improved add form for 'CMF Action' objects.
Presettings can now be loaded from Action settings in setup profiles.
- - CMFSetup and GenericSetup: Added catalog tool setup handlers.
+ - CMFCore and GenericSetup: Added catalog tool setup handlers.
This includes node adapters for PluginIndexes, ZCTextIndex and ZCatalog.
Support for additional indexes can be added by providing INodeExporter
and INodeImporter adapters. All indexes are cleared by this handler, so
@@ -64,7 +87,7 @@
- Replaced user messages by MassageIDs to improve the i18n support.
- - CMFDefault CMFSetup profile: Added CMF BTree Folder to the list of
+ - CMFDefault GenericSetup profile: Added CMF BTree Folder to the list of
automatically instantiated types in the types tool.
(http://www.zope.org/Collectors/CMF/371)
@@ -94,9 +117,6 @@
Bug Fixes
- - CMFSetup: fixed empty attribute parsing when an encoding is
- defined.
-
- ActionProviderBase: getActionObject did stumble over newstyle Actions.
- CMFCore.exportimport.content: Ensure that BODYFILE in our "faux"
@@ -140,6 +160,11 @@
Others
+ - CMFSetup and GenericSetup: Removed obsolete CMFSetup product.
+ Added __module_aliases__ to support setup tools created with CMFSetup.
+
+ - DCWorkflow: Removed hardcoded default workflows.
+
- Workflow: Removed deprecated WorkflowInformation and getActionsFor.
- CMFCore and GenericSetup: Moved mechanisms for content export / import
Modified: CMF/branches/tseaver-viewification/CMFActionIcons/DEPENDENCIES.txt
===================================================================
--- CMF/branches/tseaver-viewification/CMFActionIcons/DEPENDENCIES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFActionIcons/DEPENDENCIES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,4 +1,4 @@
-Zope >= 2.8.2
+Zope >= 2.8.5
Five >= 1.2
CMFCore
GenericSetup
Modified: CMF/branches/tseaver-viewification/CMFActionIcons/__init__.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFActionIcons/__init__.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFActionIcons/__init__.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -21,6 +21,7 @@
try:
from Products.CMFSetup import EXTENSION
from Products.CMFSetup import profile_registry
+ from Products.CMFCore.interfaces import ISiteRoot
has_profile_registry = True
except ImportError:
has_profile_registry = False
@@ -44,4 +45,6 @@
'Adds action icon tool / settings.',
'profiles/actionicons',
'CMFActionIcons',
- EXTENSION)
+ EXTENSION,
+ for_=ISiteRoot,
+ )
Modified: CMF/branches/tseaver-viewification/CMFActionIcons/exportimport.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFActionIcons/exportimport.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFActionIcons/exportimport.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -24,11 +24,11 @@
from Products.CMFCore.utils import getToolByName
-from Products.CMFSetup.utils import CONVERTER
-from Products.CMFSetup.utils import DEFAULT
-from Products.CMFSetup.utils import ExportConfiguratorBase
-from Products.CMFSetup.utils import ImportConfiguratorBase
-from Products.CMFSetup.utils import KEY
+from Products.GenericSetup.utils import CONVERTER
+from Products.GenericSetup.utils import DEFAULT
+from Products.GenericSetup.utils import ExportConfiguratorBase
+from Products.GenericSetup.utils import ImportConfiguratorBase
+from Products.GenericSetup.utils import KEY
from permissions import ManagePortal
@@ -75,6 +75,7 @@
return 'Action icons tool settings exported.'
+
class ActionIconsToolExportConfigurator(ExportConfiguratorBase):
""" Synthesize XML description of cc properties.
"""
@@ -100,6 +101,7 @@
InitializeClass(ActionIconsToolExportConfigurator)
+
class ActionIconsToolImportConfigurator(ImportConfiguratorBase):
def _getImportMapping(self):
@@ -115,4 +117,7 @@
},
}
+ def _convertToInteger(self, val):
+ return int(val.strip())
+
InitializeClass(ActionIconsToolImportConfigurator)
Modified: CMF/branches/tseaver-viewification/CMFActionIcons/profiles/actionicons/skins.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFActionIcons/profiles/actionicons/skins.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFActionIcons/profiles/actionicons/skins.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,8 +1,8 @@
<?xml version="1.0"?>
-<skins-tool>
- <skin-directory id="actionicons"
- directory="CMFActionIcons/skins/actionicons"/>
- <skin-path id="*">
+<object name="portal_skins" meta_type="CMF Skins Tool">
+ <object name="actionicons" meta_type="Filesystem Directory View"
+ directory="CMFActionIcons/skins/actionicons"/>
+ <skin-path name="*">
<layer name="actionicons" insert-before="zpt_content"/>
</skin-path>
-</skins-tool>
+</object>
Modified: CMF/branches/tseaver-viewification/CMFCalendar/DEPENDENCIES.txt
===================================================================
--- CMF/branches/tseaver-viewification/CMFCalendar/DEPENDENCIES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCalendar/DEPENDENCIES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,4 +1,4 @@
-Zope >= 2.8.2
+Zope >= 2.8.5
Five >= 1.2
CMFCore
CMFDefault
Modified: CMF/branches/tseaver-viewification/CMFCalendar/__init__.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCalendar/__init__.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCalendar/__init__.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -19,6 +19,7 @@
import utils
from Products.CMFCore import utils
+from Products.CMFCore.interfaces import ISiteRoot
from Products.CMFCore.DirectoryView import registerDirectory
from Products.GenericSetup import EXTENSION
from Products.GenericSetup import profile_registry
@@ -62,4 +63,6 @@
'Adds calendar support.',
'profiles/default',
'CMFCalendar',
- EXTENSION)
+ EXTENSION,
+ for_=ISiteRoot,
+ )
Modified: CMF/branches/tseaver-viewification/CMFCalendar/profiles/default/skins.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFCalendar/profiles/default/skins.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCalendar/profiles/default/skins.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,8 +1,8 @@
<?xml version="1.0"?>
-<skins-tool>
- <skin-directory id="zpt_calendar"
- directory="CMFCalendar/skins/zpt_calendar"/>
- <skin-path id="*">
+<object name="portal_skins" meta_type="CMF Skins Tool">
+ <object name="zpt_calendar" meta_type="Filesystem Directory View"
+ directory="CMFCalendar/skins/zpt_calendar"/>
+ <skin-path name="*">
<layer name="zpt_calendar" insert-before="zpt_content"/>
</skin-path>
-</skins-tool>
+</object>
Modified: CMF/branches/tseaver-viewification/CMFCalendar/profiles/default/typestool.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFCalendar/profiles/default/typestool.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCalendar/profiles/default/typestool.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,4 +1,4 @@
<?xml version="1.0"?>
-<types-tool>
- <type id="Event"/>
-</types-tool>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <object name="Event" meta_type="Factory-based Type Information"/>
+</object>
Modified: CMF/branches/tseaver-viewification/CMFCalendar/setuphandlers.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCalendar/setuphandlers.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCalendar/setuphandlers.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -32,15 +32,19 @@
# Set up a MetadataTool element policy for events
try:
_ = str # MetadataTool ist not aware of MessageIDs
- mdtool.addElementPolicy(
+ mdtool.DCMI.addElementPolicy(
element='Subject',
content_type='Event',
is_required=0,
supply_default=0,
default_value='',
enforce_vocabulary=0,
- allowed_vocabulary=(_('Appointment'), _('Convention'),
- _('Meeting'), _('Social Event'), _('Work')),
+ allowed_vocabulary=(_('Appointment'),
+ _('Convention'),
+ _('Meeting'),
+ _('Social Event'),
+ _('Work'),
+ ),
REQUEST=None)
except MetadataError:
pass
Modified: CMF/branches/tseaver-viewification/CMFCore/DEPENDENCIES.txt
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/DEPENDENCIES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/DEPENDENCIES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,3 +1,3 @@
-Zope >= 2.8.2
+Zope >= 2.8.5
Five >= 1.2
GenericSetup
Modified: CMF/branches/tseaver-viewification/CMFCore/DirectoryView.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/DirectoryView.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/DirectoryView.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -31,9 +31,11 @@
from OFS.Folder import Folder
from OFS.ObjectManager import bad_id
from zLOG import LOG, ERROR
+from zope.interface import implements
from FSMetadata import FSMetadata
from FSObject import BadFile
+from interfaces import IDirectoryView
from permissions import AccessContentsInformation
from permissions import ManagePortal
from utils import _dtmldir
@@ -390,15 +392,19 @@
listFolderHierarchy(subob, subpath, rval, adding_meta_type)
-class DirectoryView (Persistent):
+class DirectoryView(Persistent):
+
""" Directory views mount filesystem directories.
"""
+
+ implements(IDirectoryView)
+
meta_type = 'Filesystem Directory View'
_dirpath = None
_properties = None
_objects = ()
- def __init__(self, id, dirpath, fullname=None, properties=None):
+ def __init__(self, id, dirpath='', fullname=None, properties=None):
if properties:
# Since props come from the filesystem, this should be
# safe.
@@ -424,7 +430,7 @@
if info is not None:
# update the directory view with a corrected path
self._dirpath = dirpath
- else:
+ elif self._dirpath:
from warnings import warn
warn('DirectoryView %s refers to a non-existing path %s'
% (self.id, dirpath), UserWarning)
@@ -443,10 +449,13 @@
InitializeClass(DirectoryView)
-class DirectoryViewSurrogate (Folder):
+class DirectoryViewSurrogate(Folder):
+
""" Folderish DirectoryView.
"""
+ implements(IDirectoryView)
+
meta_type = 'Filesystem Directory View'
all_meta_types = ()
_isDirectoryView = 1
Modified: CMF/branches/tseaver-viewification/CMFCore/PortalContent.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/PortalContent.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/PortalContent.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -69,7 +69,6 @@
# The security for FTP methods aren't set up by default in our
# superclasses... :(
security.declareProtected(FTPAccess, 'manage_FTPstat')
- security.declareProtected(FTPAccess, 'manage_FTPget')
security.declareProtected(FTPAccess, 'manage_FTPlist')
def failIfLocked(self):
Modified: CMF/branches/tseaver-viewification/CMFCore/TypesTool.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/TypesTool.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/TypesTool.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -17,7 +17,6 @@
from sys import exc_info
from warnings import warn
-from xml.dom.minidom import parseString
import Products
from AccessControl import ClassSecurityInfo
@@ -39,8 +38,6 @@
def MessageID(val, domain): # XXX performance?
return MessageFactory(domain)(val)
-from Products.GenericSetup.interfaces import INodeImporter
-
from ActionProviderBase import ActionProviderBase
from exceptions import AccessControl_Unauthorized
from exceptions import BadRequest
@@ -68,9 +65,8 @@
class TypeInformation(SimpleItemWithProperties, ActionProviderBase):
+ """ Base class for information about a content type.
"""
- Base class for information about a content type.
- """
_isTypeInformation = 1
@@ -454,14 +450,12 @@
class FactoryTypeInformation(TypeInformation):
+ """ Portal content factory.
"""
- Portal content factory.
- """
implements(ITypeInformation)
__implements__ = z2ITypeInformation
- meta_type = 'Factory-based Type Information'
security = ClassSecurityInfo()
_properties = (TypeInformation._basic_properties + (
@@ -563,14 +557,12 @@
class ScriptableTypeInformation( TypeInformation ):
+ """ Invokes a script rather than a factory to create the content.
"""
- Invokes a script rather than a factory to create the content.
- """
implements(ITypeInformation)
__implements__ = z2ITypeInformation
- meta_type = 'Scriptable Type Information'
security = ClassSecurityInfo()
_properties = (TypeInformation._basic_properties + (
@@ -619,86 +611,6 @@
InitializeClass( ScriptableTypeInformation )
-_addTypeInfo_template = PageTemplateFile('addTypeInfo.zpt', _wwwdir)
-
-def manage_addFactoryTIForm(dispatcher, REQUEST):
- """ Get the add form for factory-based type infos.
- """
- template = _addTypeInfo_template.__of__(dispatcher)
- meta_type = FactoryTypeInformation.meta_type
- return template(add_meta_type=meta_type,
- profiles=_getProfileInfo(dispatcher, meta_type))
-
-def manage_addScriptableTIForm(dispatcher, REQUEST):
- """ Get the add form for scriptable type infos.
- """
- template = _addTypeInfo_template.__of__(dispatcher)
- meta_type = ScriptableTypeInformation.meta_type
- return template(add_meta_type=meta_type,
- profiles=_getProfileInfo(dispatcher, meta_type))
-
-def _getProfileInfo(dispatcher, meta_type):
- profiles = []
- stool = getToolByName(dispatcher, 'portal_setup', None)
- if stool:
- for info in stool.listContextInfos():
- type_ids = []
- context = stool._getImportContext(info['id'])
- filenames = context.listDirectory('types')
- if filenames is None:
- continue
- for filename in filenames:
- body = context.readDataFile(filename, subdir='types')
- if body is None:
- continue
- root = parseString(body).documentElement
- if root.getAttribute('meta_type') == meta_type:
- type_id = root.getAttribute('name')
- type_ids.append(type_id)
- if not type_ids:
- continue
- type_ids.sort()
- profiles.append({'id': info['id'],
- 'title': info['title'],
- 'type_ids': tuple(type_ids)})
- return tuple(profiles)
-
-def manage_addTypeInfo(dispatcher, add_meta_type, id, settings_id='',
- REQUEST=None):
- """Add a new TypeInformation object of type 'add_meta_type' with ID 'id'.
- """
- settings_node = None
- if settings_id:
- stool = getToolByName(dispatcher, 'portal_setup', None)
- if stool:
- profile_id, type_id = settings_id.split('/')
- context = stool._getImportContext(profile_id)
- filenames = context.listDirectory('types')
- for filename in filenames or ():
- body = context.readDataFile(filename, subdir='types')
- if body is not None:
- root = parseString(body).documentElement
- if root.getAttribute('name') != type_id:
- continue
- if root.getAttribute('meta_type') == add_meta_type:
- settings_node = root
- if not id:
- id = type_id
- break
- for mt in Products.meta_types:
- if mt['name'] == add_meta_type:
- klass = mt['instance']
- break
- else:
- raise ValueError('Meta type %s is not a type class.' % add_meta_type)
- obj = klass(id)
- if settings_node:
- INodeImporter(obj).importNode(settings_node)
- dispatcher._setObject(id, obj)
-
- if REQUEST:
- return dispatcher.manage_main(dispatcher, REQUEST)
-
allowedTypes = [
'Script (Python)',
'Python Method',
@@ -710,9 +622,8 @@
class TypesTool(UniqueObject, IFAwareObjectManager, Folder,
ActionProviderBase):
+ """ Provides a configurable registry of portal content types.
"""
- Provides a configurable registry of portal content types.
- """
implements(ITypesTool)
__implements__ = (z2ITypesTool, ActionProviderBase.__implements__)
Modified: CMF/branches/tseaver-viewification/CMFCore/WorkflowTool.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/WorkflowTool.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/WorkflowTool.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -23,9 +23,11 @@
from Globals import InitializeClass
from Globals import PersistentMapping
from OFS.Folder import Folder
+from OFS.ObjectManager import IFAwareObjectManager
from zope.interface import implements
from ActionProviderBase import ActionProviderBase
+from interfaces import IWorkflowDefinition
from interfaces import IWorkflowTool
from interfaces.portal_workflow import portal_workflow as z2IWorkflowTool
from permissions import ManagePortal
@@ -40,7 +42,8 @@
_marker = [] # Create a new marker object.
-class WorkflowTool(UniqueObject, Folder, ActionProviderBase):
+class WorkflowTool(UniqueObject, IFAwareObjectManager, Folder,
+ ActionProviderBase):
""" Mediator tool, mapping workflow objects
"""
@@ -50,6 +53,7 @@
id = 'portal_workflow'
meta_type = 'CMF Workflow Tool'
+ _product_interfaces = (IWorkflowDefinition,)
_chains_by_type = None # PersistentMapping
_default_chain = ('default_workflow',)
@@ -69,37 +73,6 @@
security.declareProtected( ManagePortal, 'manage_overview' )
manage_overview = DTMLFile( 'explainWorkflowTool', _dtmldir )
- _manage_addWorkflowForm = DTMLFile('addWorkflow', _dtmldir)
-
- security.declareProtected( ManagePortal, 'manage_addWorkflowForm')
- def manage_addWorkflowForm(self, REQUEST):
-
- """ Form for adding workflows.
- """
- wft = []
- for key in _workflow_factories.keys():
- wft.append(key)
- wft.sort()
- return self._manage_addWorkflowForm(REQUEST, workflow_types=wft)
-
- security.declareProtected( ManagePortal, 'manage_addWorkflow')
- def manage_addWorkflow(self, workflow_type, id, RESPONSE=None):
-
- """ Adds a workflow from the registered types.
- """
- factory = _workflow_factories[workflow_type]
- ob = factory(id)
- self._setObject(id, ob)
- if RESPONSE is not None:
- RESPONSE.redirect(self.absolute_url() +
- '/manage_main?management_view=Contents')
-
- def all_meta_types(self):
- return (
- {'name': 'Workflow',
- 'action': 'manage_addWorkflowForm',
- 'permission': ManagePortal },)
-
_manage_selectWorkflows = DTMLFile('selectWorkflows', _dtmldir)
security.declareProtected( ManagePortal, 'manage_selectWorkflows')
@@ -426,8 +399,7 @@
self._default_chain = tuple(ids)
security.declareProtected( ManagePortal, 'setChainForPortalTypes')
- def setChainForPortalTypes(self, pt_names, chain):
-
+ def setChainForPortalTypes(self, pt_names, chain, verify=True):
""" Set a chain for a specific portal type.
"""
cbt = self._chains_by_type
@@ -437,12 +409,12 @@
if isinstance(chain, basestring):
chain = [ wf.strip() for wf in chain.split(',') if wf.strip() ]
- ti = self._listTypeInfo()
- for t in ti:
- id = t.getId()
- if id in pt_names:
- cbt[id] = tuple(chain)
+ ti_ids = [ t.getId() for t in self._listTypeInfo() ]
+ for type_id in pt_names:
+ if verify and not (type_id in ti_ids):
+ continue
+ cbt[type_id] = tuple(chain)
security.declareProtected( ManagePortal, 'updateRoleMappings')
def updateRoleMappings(self, REQUEST=None):
@@ -464,11 +436,11 @@
security.declarePrivate('getWorkflowById')
def getWorkflowById(self, wf_id):
-
""" Retrieve a given workflow.
"""
wf = getattr(self, wf_id, None)
- if getattr(wf, '_isAWorkflow', 0):
+ if getattr(wf, '_isAWorkflow', False) or \
+ IWorkflowDefinition.providedBy(wf):
return wf
else:
return None
@@ -651,29 +623,3 @@
ob.reindexObjectSecurity()
InitializeClass(WorkflowTool)
-
-
-_workflow_factories = {}
-
-def _makeWorkflowFactoryKey(factory, id=None, title=None):
- # The factory should take one argument, id.
- if id is None:
- id = getattr(factory, 'id', '') or getattr(factory, 'meta_type', '')
- if title is None:
- title = getattr(factory, 'title', '')
- key = id
- if title:
- key = key + ' (%s)' % title
- return key
-
-def addWorkflowFactory(factory, id=None, title=None):
- key = _makeWorkflowFactoryKey( factory, id, title )
- _workflow_factories[key] = factory
-
-def _removeWorkflowFactory( factory, id=None, title=None ):
- """ Make teardown in unitcase cleaner. """
- key = _makeWorkflowFactoryKey( factory, id, title )
- try:
- del _workflow_factories[key]
- except KeyError:
- pass
Modified: CMF/branches/tseaver-viewification/CMFCore/__init__.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/__init__.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/__init__.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -36,7 +36,6 @@
from interfaces import IAction
from interfaces import IActionCategory
-from interfaces import ITypeInformation
from permissions import AddPortalFolders
from permissions import ManagePortal
@@ -97,7 +96,7 @@
utils.initializeBasesPhase2(z_tool_bases, context)
context.registerClass(
- DirectoryView.DirectoryViewSurrogate,
+ DirectoryView.DirectoryView,
constructors=(('manage_addDirectoryViewForm',
DirectoryView.manage_addDirectoryViewForm),
DirectoryView.manage_addDirectoryView,
@@ -143,24 +142,10 @@
visibility=None,
interfaces=(IAction,))
- context.registerClass(
- TypesTool.FactoryTypeInformation,
- permission=ManagePortal,
- constructors=(TypesTool.manage_addFactoryTIForm,
- TypesTool.manage_addTypeInfo),
- icon='images/typeinfo.gif',
- visibility=None,
- interfaces=(ITypeInformation,))
-
- context.registerClass(
- TypesTool.ScriptableTypeInformation,
- permission=ManagePortal,
- constructors=(TypesTool.manage_addScriptableTIForm,
- TypesTool.manage_addTypeInfo),
- icon='images/typeinfo.gif',
- visibility=None,
- interfaces=(ITypeInformation,))
-
+ utils.registerIcon(TypesTool.FactoryTypeInformation,
+ 'images/typeinfo.gif', globals())
+ utils.registerIcon(TypesTool.ScriptableTypeInformation,
+ 'images/typeinfo.gif', globals())
utils.registerIcon(FSDTMLMethod.FSDTMLMethod,
'images/fsdtml.gif', globals())
utils.registerIcon(FSPythonScript.FSPythonScript,
Modified: CMF/branches/tseaver-viewification/CMFCore/browser/configure.zcml
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/browser/configure.zcml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/browser/configure.zcml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,9 +1,34 @@
<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:browser="http://namespaces.zope.org/browser"
- i18n_domain="cmf"
- >
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ xmlns:five="http://namespaces.zope.org/five"
+ i18n_domain="cmf"
+ >
+ <five:traversable class="Products.CMFCore.WorkflowTool.WorkflowTool"/>
+
+ <five:traversable class="Products.CMFCore.TypesTool.TypesTool"/>
+
+ <configure package="Products.GenericSetup.browser">
+
+ <browser:page
+ for="zope.app.container.interfaces.IAdding"
+ name="addFactoryTypeInformation.html"
+ template="addWithPresettings.pt"
+ class="Products.CMFCore.browser.typeinfo.FactoryTypeInformationAddView"
+ permission="cmf.ManagePortal"
+ />
+
+ <browser:page
+ for="zope.app.container.interfaces.IAdding"
+ name="addScriptableTypeInformation.html"
+ template="addWithPresettings.pt"
+ class="Products.CMFCore.browser.typeinfo.ScriptableTypeInformationAddView"
+ permission="cmf.ManagePortal"
+ />
+
+ </configure>
+
<!-- Set up default menus as action categories. -->
<browser:menu
id="object"
Copied: CMF/branches/tseaver-viewification/CMFCore/browser/typeinfo.py (from rev 40492, CMF/trunk/CMFCore/browser/typeinfo.py)
Modified: CMF/branches/tseaver-viewification/CMFCore/configure.zcml
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/configure.zcml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/configure.zcml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,12 +1,26 @@
<configure
- xmlns="http://namespaces.zope.org/zope">
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:five="http://namespaces.zope.org/five"
+ >
- <include
- package=".browser"
+ <include package=".browser"/>
+
+ <include package=".exportimport"/>
+
+ <five:registerClass
+ class=".TypesTool.FactoryTypeInformation"
+ meta_type="Factory-based Type Information"
+ addview="addFactoryTypeInformation.html"
+ permission="cmf.ManagePortal"
+ global="False"
/>
- <include
- package=".exportimport"
+ <five:registerClass
+ class=".TypesTool.ScriptableTypeInformation"
+ meta_type="Scriptable Type Information"
+ addview="addScriptableTypeInformation.html"
+ permission="cmf.ManagePortal"
+ global="False"
/>
</configure>
Deleted: CMF/branches/tseaver-viewification/CMFCore/dtml/addWorkflow.dtml
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/dtml/addWorkflow.dtml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/dtml/addWorkflow.dtml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,44 +0,0 @@
-<dtml-let form_title="'Add workflow'">
-<dtml-var manage_page_header>
-<dtml-var manage_form_title>
-</dtml-let>
-
-<form action="manage_addWorkflow" method="POST">
-<table cellspacing="0" cellpadding="2" border="0">
- <tr>
- <td align="left" valign="top">
- <div class="form-label">
- Id
- </div>
- </td>
- <td align="left" valign="top">
- <input type="text" name="id" size="40" />
- </td>
- </tr>
- <tr>
- <td align="left" valign="top">
- <div class="form-label">
- Type
- </label></div>
- </td>
- <td align="left" valign="top">
- <dtml-in workflow_types>
- <input type="radio" name="workflow_type" value="&dtml-sequence-item;">
- &dtml-sequence-item;<br />
- </dtml-in>
- </td>
- </tr>
- <tr>
- <td align="left" valign="top">
- </td>
- <td align="left" valign="top">
- <div class="form-element">
- <input class="form-element" type="submit" name="submit"
- value=" Add " />
- </div>
- </td>
- </tr>
-</table>
-</form>
-
-<dtml-var manage_page_footer>
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/actions.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/actions.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/actions.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,11 +15,15 @@
$Id$
"""
+from zope.app import zapi
+
+from Products.GenericSetup.interfaces import IBody
from Products.GenericSetup.interfaces import PURGE, UPDATE
from Products.GenericSetup.utils import I18NURI
from Products.GenericSetup.utils import NodeAdapterBase
from Products.GenericSetup.utils import ObjectManagerHelpers
from Products.GenericSetup.utils import PropertyManagerHelpers
+from Products.GenericSetup.utils import XMLAdapterBase
from Products.CMFCore.interfaces import IAction
from Products.CMFCore.interfaces import IActionCategory
@@ -29,6 +33,7 @@
import ActionProvider as z2IActionProvider
from Products.CMFCore.utils import getToolByName
+_FILENAME = 'actions.xml'
_SPECIAL_PROVIDERS = ('portal_actions', 'portal_types', 'portal_workflow')
@@ -84,13 +89,15 @@
self._initProperties(node, mode)
-class ActionsToolNodeAdapter(NodeAdapterBase, ObjectManagerHelpers):
+class ActionsToolXMLAdapter(XMLAdapterBase, ObjectManagerHelpers):
- """Node im- and exporter for ActionsTool.
+ """XML im- and exporter for ActionsTool.
"""
__used_for__ = IActionsTool
+ _LOGGER_ID = 'actions'
+
def exportNode(self, doc):
"""Export the object as a DOM node.
"""
@@ -99,6 +106,8 @@
node.setAttribute('xmlns:i18n', I18NURI)
node.appendChild(self._extractProviders())
node.appendChild(self._extractObjects())
+
+ self._logger.info('Actions tool exported.')
return node
def importNode(self, node, mode=PURGE):
@@ -111,6 +120,8 @@
self._initObjects(node, mode)
self._initProviders(node, mode)
+ self._logger.info('Actions tool imported.')
+
def _extractProviders(self):
fragment = self._doc.createDocumentFragment()
for provider_id in self.context.listActionProviders():
@@ -222,3 +233,40 @@
parent.appendChild(newnode)
self._initObjects(fragment, UPDATE)
+
+
+def importActionProviders(context):
+ """Import actions tool.
+ """
+ site = context.getSite()
+ logger = context.getLogger('actions')
+ tool = getToolByName(site, 'portal_actions')
+
+ body = context.readDataFile(_FILENAME)
+ if body is None:
+ logger.info('Nothing to import.')
+ return
+
+ importer = zapi.queryMultiAdapter((tool, context), IBody)
+ if importer is None:
+ logger.warning('Import adapter misssing.')
+ return
+
+ importer.body = body
+
+def exportActionProviders(context):
+ """Export actions tool.
+ """
+ site = context.getSite()
+ logger = context.getLogger('actions')
+ tool = getToolByName(site, 'portal_actions', None)
+ if tool is None:
+ logger.info('Nothing to export.')
+ return
+
+ exporter = zapi.queryMultiAdapter((tool, context), IBody)
+ if exporter is None:
+ logger.warning('Export adapter misssing.')
+ return
+
+ context.writeDataFile(_FILENAME, exporter.body, exporter.mime_type)
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/cachingpolicymgr.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/cachingpolicymgr.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/cachingpolicymgr.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,20 +10,27 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Caching policy manager node adapters.
+"""Caching policy manager xml adapters and setup handlers.
$Id$
"""
+from zope.app import zapi
+
+from Products.GenericSetup.interfaces import IBody
from Products.GenericSetup.interfaces import INodeExporter
from Products.GenericSetup.interfaces import INodeImporter
from Products.GenericSetup.interfaces import PURGE
from Products.GenericSetup.utils import NodeAdapterBase
+from Products.GenericSetup.utils import XMLAdapterBase
from Products.CMFCore.interfaces import ICachingPolicy
from Products.CMFCore.interfaces import ICachingPolicyManager
+from Products.CMFCore.utils import getToolByName
+_FILENAME = 'cachingpolicymgr.xml'
+
class CachingPolicyNodeAdapter(NodeAdapterBase):
"""Node im- and exporter for CachingPolicy.
@@ -107,19 +114,23 @@
self.context.__init__(**info)
-class CachingPolicyManagerNodeAdapter(NodeAdapterBase):
+class CachingPolicyManagerXMLAdapter(XMLAdapterBase):
- """Node im- and exporter for CachingPolicyManager.
+ """XML im- and exporter for CachingPolicyManager.
"""
__used_for__ = ICachingPolicyManager
+ _LOGGER_ID = 'cachingpolicies'
+
def exportNode(self, doc):
"""Export the object as a DOM node.
"""
self._doc = doc
node = self._getObjectNode('object')
node.appendChild(self._extractCachingPolicies())
+
+ self._logger.info('Caching policy manager exported.')
return node
def importNode(self, node, mode=PURGE):
@@ -130,6 +141,8 @@
self._initCachingPolicies(node, mode)
+ self._logger.info('Caching policy manager imported.')
+
def _extractCachingPolicies(self):
fragment = self._doc.createDocumentFragment()
for policy_id, policy in self.context.listPolicies():
@@ -155,3 +168,40 @@
policy = self.context._policies[policy_id]
INodeImporter(policy).importNode(child, mode)
+
+
+def importCachingPolicyManager(context):
+ """Import caching policy manager settings from an XML file.
+ """
+ site = context.getSite()
+ logger = context.getLogger('cachingpolicies')
+ tool = getToolByName(site, 'caching_policy_manager')
+
+ body = context.readDataFile(_FILENAME)
+ if body is None:
+ logger.info('Nothing to import.')
+ return
+
+ importer = zapi.queryMultiAdapter((tool, context), IBody)
+ if importer is None:
+ logger.warning('Import adapter misssing.')
+ return
+
+ importer.body = body
+
+def exportCachingPolicyManager(context):
+ """Export caching policy manager settings as an XML file.
+ """
+ site = context.getSite()
+ logger = context.getLogger('cachingpolicies')
+ tool = getToolByName(site, 'caching_policy_manager', None)
+ if tool is None:
+ logger.info('Nothing to export.')
+ return
+
+ exporter = zapi.queryMultiAdapter((tool, context), IBody)
+ if exporter is None:
+ logger.warning('Export adapter misssing.')
+ return
+
+ context.writeDataFile(_FILENAME, exporter.body, exporter.mime_type)
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/catalog.py (from rev 40492, CMF/trunk/CMFCore/exportimport/catalog.py)
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/configure.zcml
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/configure.zcml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/configure.zcml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,7 +1,5 @@
<configure
xmlns="http://namespaces.zope.org/zope"
- xmlns:five="http://namespaces.zope.org/five"
- i18n_domain="cmf"
>
<adapter
@@ -29,18 +27,13 @@
/>
<adapter
- factory=".actions.ActionsToolNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeExporter"
- for="Products.CMFCore.interfaces.IActionsTool"
+ factory=".actions.ActionsToolXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.CMFCore.interfaces.IActionsTool
+ Products.GenericSetup.interfaces.ISetupContext"
/>
<adapter
- factory=".actions.ActionsToolNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeImporter"
- for="Products.CMFCore.interfaces.IActionsTool"
- />
-
- <adapter
factory=".cachingpolicymgr.CachingPolicyNodeAdapter"
provides="Products.GenericSetup.interfaces.INodeExporter"
for="Products.CMFCore.interfaces.ICachingPolicy"
@@ -53,18 +46,13 @@
/>
<adapter
- factory=".cachingpolicymgr.CachingPolicyManagerNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeExporter"
- for="Products.CMFCore.interfaces.ICachingPolicyManager"
+ factory=".cachingpolicymgr.CachingPolicyManagerXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.CMFCore.interfaces.ICachingPolicyManager
+ Products.GenericSetup.interfaces.ISetupContext"
/>
<adapter
- factory=".cachingpolicymgr.CachingPolicyManagerNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeImporter"
- for="Products.CMFCore.interfaces.ICachingPolicyManager"
- />
-
- <adapter
factory=".content.StructureFolderWalkingAdapter"
provides="Products.GenericSetup.interfaces.IFilesystemExporter"
for="Products.CMFCore.interfaces.IFolderish"
@@ -77,51 +65,64 @@
/>
<adapter
- factory=".contenttyperegistry.ContentTypeRegistryNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeExporter"
- for="Products.CMFCore.interfaces.IContentTypeRegistry"
+ factory=".contenttyperegistry.ContentTypeRegistryXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.CMFCore.interfaces.IContentTypeRegistry
+ Products.GenericSetup.interfaces.ISetupContext"
/>
<adapter
- factory=".contenttyperegistry.ContentTypeRegistryNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeImporter"
- for="Products.CMFCore.interfaces.IContentTypeRegistry"
+ factory=".cookieauth.CookieCrumblerXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.CMFCore.interfaces.ICookieCrumbler
+ Products.GenericSetup.interfaces.ISetupContext"
/>
<adapter
- factory=".cookieauth.CookieCrumblerNodeAdapter"
+ factory=".properties.PropertiesXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.CMFCore.interfaces.ISiteRoot
+ Products.GenericSetup.interfaces.ISetupContext"
+ />
+
+ <adapter
+ factory=".skins.DirectoryViewNodeAdapter"
provides="Products.GenericSetup.interfaces.INodeExporter"
- for="Products.CMFCore.interfaces.ICookieCrumbler"
+ for="Products.CMFCore.interfaces.IDirectoryView"
/>
<adapter
- factory=".cookieauth.CookieCrumblerNodeAdapter"
+ factory=".skins.DirectoryViewNodeAdapter"
provides="Products.GenericSetup.interfaces.INodeImporter"
- for="Products.CMFCore.interfaces.ICookieCrumbler"
+ for="Products.CMFCore.interfaces.IDirectoryView"
/>
<adapter
- factory=".properties.PropertiesNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeExporter"
- for="Products.CMFCore.interfaces.ISiteRoot"
+ factory=".skins.SkinsToolXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.CMFCore.interfaces.ISkinsTool
+ Products.GenericSetup.interfaces.ISetupContext"
/>
<adapter
- factory=".properties.PropertiesNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeImporter"
- for="Products.CMFCore.interfaces.ISiteRoot"
+ factory=".typeinfo.TypeInformationXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.CMFCore.interfaces.ITypeInformation
+ Products.GenericSetup.interfaces.ISetupContext"
/>
<adapter
- factory=".typeinfo.TypeInformationNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeExporter"
- for="Products.CMFCore.interfaces.ITypeInformation"
+ factory=".typeinfo.TypesToolXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.CMFCore.interfaces.ITypesTool
+ Products.GenericSetup.interfaces.ISetupContext"
/>
<adapter
- factory=".typeinfo.TypeInformationNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeImporter"
- for="Products.CMFCore.interfaces.ITypeInformation"
+ factory=".workflow.WorkflowToolXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.CMFCore.interfaces.IWorkflowTool
+ Products.GenericSetup.interfaces.ISetupContext"
/>
</configure>
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/contenttyperegistry.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/contenttyperegistry.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/contenttyperegistry.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,30 +10,40 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Content type registry node adapters.
+"""Content type registry xml adapters and setup handlers.
$Id$
"""
+from zope.app import zapi
+
+from Products.GenericSetup.interfaces import IBody
from Products.GenericSetup.interfaces import PURGE
-from Products.GenericSetup.utils import NodeAdapterBase
+from Products.GenericSetup.utils import XMLAdapterBase
from Products.CMFCore.interfaces import IContentTypeRegistry
+from Products.CMFCore.utils import getToolByName
+_FILENAME = 'contenttyperegistry.xml'
-class ContentTypeRegistryNodeAdapter(NodeAdapterBase):
- """Node im- and exporter for ContentTypeRegistry.
+class ContentTypeRegistryXMLAdapter(XMLAdapterBase):
+
+ """XML im- and exporter for ContentTypeRegistry.
"""
__used_for__ = IContentTypeRegistry
+ _LOGGER_ID = 'contenttypes'
+
def exportNode(self, doc):
"""Export the object as a DOM node.
"""
self._doc = doc
node = self._getObjectNode('object')
node.appendChild(self._extractPredicates())
+
+ self._logger.info('Content type registry exported.')
return node
def importNode(self, node, mode=PURGE):
@@ -44,6 +54,8 @@
self._initPredicates(node, mode)
+ self._logger.info('Content type registry imported.')
+
def _extractPredicates(self):
fragment = self._doc.createDocumentFragment()
for predicate_id, info in self.context.listPredicates():
@@ -97,3 +109,40 @@
if cracker is not None:
return cracker(predicate)
return () # XXX: raise?
+
+
+def importContentTypeRegistry(context):
+ """Import content type registry settings from an XML file.
+ """
+ site = context.getSite()
+ logger = context.getLogger('contenttypes')
+ tool = getToolByName(site, 'content_type_registry')
+
+ body = context.readDataFile(_FILENAME)
+ if body is None:
+ logger.info('Nothing to import.')
+ return
+
+ importer = zapi.queryMultiAdapter((tool, context), IBody)
+ if importer is None:
+ logger.warning('Import adapter misssing.')
+ return
+
+ importer.body = body
+
+def exportContentTypeRegistry(context):
+ """Export content type registry settings as an XML file.
+ """
+ site = context.getSite()
+ logger = context.getLogger('contenttypes')
+ tool = getToolByName(site, 'content_type_registry', None)
+ if tool is None:
+ logger.info('Nothing to export.')
+ return
+
+ exporter = zapi.queryMultiAdapter((tool, context), IBody)
+ if exporter is None:
+ logger.warning('Export adapter misssing.')
+ return
+
+ context.writeDataFile(_FILENAME, exporter.body, exporter.mime_type)
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/cookieauth.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/cookieauth.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/cookieauth.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,31 +10,41 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Cookie crumbler node adapters.
+"""Cookie crumbler xml adapters and setup handlers.
$Id$
"""
+from zope.app import zapi
+
+from Products.GenericSetup.interfaces import IBody
from Products.GenericSetup.interfaces import PURGE
-from Products.GenericSetup.utils import NodeAdapterBase
from Products.GenericSetup.utils import PropertyManagerHelpers
+from Products.GenericSetup.utils import XMLAdapterBase
from Products.CMFCore.interfaces import ICookieCrumbler
+from Products.CMFCore.utils import getToolByName
+_FILENAME = 'cookieauth.xml'
-class CookieCrumblerNodeAdapter(NodeAdapterBase, PropertyManagerHelpers):
- """Node im- and exporter for CookieCrumbler.
+class CookieCrumblerXMLAdapter(XMLAdapterBase, PropertyManagerHelpers):
+
+ """XML im- and exporter for CookieCrumbler.
"""
__used_for__ = ICookieCrumbler
+ _LOGGER_ID = 'cookies'
+
def exportNode(self, doc):
"""Export the object as a DOM node.
"""
self._doc = doc
node = self._getObjectNode('object')
node.appendChild(self._extractProperties())
+
+ self._logger.info('Cookie crumbler exported.')
return node
def importNode(self, node, mode=PURGE):
@@ -44,3 +54,42 @@
self._purgeProperties()
self._initProperties(node, mode)
+
+ self._logger.info('Cookie crumbler imported.')
+
+
+def importCookieCrumbler(context):
+ """Import cookie crumbler settings from an XML file.
+ """
+ site = context.getSite()
+ logger = context.getLogger('cookies')
+ tool = getToolByName(site, 'cookie_authentication')
+
+ body = context.readDataFile(_FILENAME)
+ if body is None:
+ logger.info('Nothing to import.')
+ return
+
+ importer = zapi.queryMultiAdapter((tool, context), IBody)
+ if importer is None:
+ logger.warning('Import adapter misssing.')
+ return
+
+ importer.body = body
+
+def exportCookieCrumbler(context):
+ """Export cookie crumbler settings as an XML file.
+ """
+ site = context.getSite()
+ logger = context.getLogger('cookies')
+ tool = getToolByName(site, 'cookie_authentication', None)
+ if tool is None:
+ logger.info('Nothing to export.')
+ return
+
+ exporter = zapi.queryMultiAdapter((tool, context), IBody)
+ if exporter is None:
+ logger.warning('Export adapter misssing.')
+ return
+
+ context.writeDataFile(_FILENAME, exporter.body, exporter.mime_type)
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/mailhost.py (from rev 40492, CMF/trunk/CMFCore/exportimport/mailhost.py)
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/properties.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/properties.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/properties.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,31 +10,40 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Site properties node adapters.
+"""Site properties xml adapters and setup handlers.
$Id$
"""
+from zope.app import zapi
+
+from Products.GenericSetup.interfaces import IBody
from Products.GenericSetup.interfaces import PURGE
-from Products.GenericSetup.utils import NodeAdapterBase
from Products.GenericSetup.utils import PropertyManagerHelpers
+from Products.GenericSetup.utils import XMLAdapterBase
from Products.CMFCore.interfaces import ISiteRoot
+_FILENAME = 'properties.xml'
-class PropertiesNodeAdapter(NodeAdapterBase, PropertyManagerHelpers):
- """Node im- and exporter for properties.
+class PropertiesXMLAdapter(XMLAdapterBase, PropertyManagerHelpers):
+
+ """XML im- and exporter for properties.
"""
__used_for__ = ISiteRoot
+ _LOGGER_ID = 'properties'
+
def exportNode(self, doc):
"""Export the object as a DOM node.
"""
self._doc = doc
node = self._doc.createElement('site')
node.appendChild(self._extractProperties())
+
+ self._logger.info('Site properties exported.')
return node
def importNode(self, node, mode=PURGE):
@@ -44,3 +53,37 @@
self._purgeProperties()
self._initProperties(node, mode)
+
+ self._logger.info('Site properties imported.')
+
+
+def importSiteProperties(context):
+ """ Import site properties from an XML file.
+ """
+ site = context.getSite()
+ logger = context.getLogger('properties')
+
+ body = context.readDataFile(_FILENAME)
+ if body is None:
+ logger.info('Nothing to import.')
+ return
+
+ importer = zapi.queryMultiAdapter((site, context), IBody)
+ if importer is None:
+ logger.warning('Import adapter misssing.')
+ return
+
+ importer.body = body
+
+def exportSiteProperties(context):
+ """ Export site properties as an XML file.
+ """
+ site = context.getSite()
+ logger = context.getLogger('properties')
+
+ exporter = zapi.queryMultiAdapter((site, context), IBody)
+ if exporter is None:
+ logger.warning('Export adapter misssing.')
+ return
+
+ context.writeDataFile(_FILENAME, exporter.body, exporter.mime_type)
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/skins.py (from rev 40492, CMF/trunk/CMFCore/exportimport/skins.py)
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/four (from rev 40492, CMF/trunk/CMFCore/exportimport/tests/four)
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/one (from rev 40492, CMF/trunk/CMFCore/exportimport/tests/one)
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_actions.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_actions.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_actions.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -20,11 +20,26 @@
import Zope2
Zope2.startup()
+import Products
+from Acquisition import Implicit
+from Acquisition import aq_parent
+from OFS.Folder import Folder
+from OFS.OrderedFolder import OrderedFolder
+from Products.Five import zcml
+from zope.interface import implements
+
+from Products.CMFCore.ActionProviderBase import ActionProviderBase
+from Products.CMFCore.interfaces import IActionsTool
+from Products.CMFCore.interfaces.portal_actions \
+ import ActionProvider as IActionProvider
from Products.CMFCore.tests.base.dummy import DummySite
from Products.CMFCore.tests.base.testcase import PlacelessSetup
+from Products.GenericSetup.testing import BodyAdapterTestCase
from Products.GenericSetup.testing import NodeAdapterTestCase
+from Products.GenericSetup.tests.common import BaseRegistryTests
+from Products.GenericSetup.tests.common import DummyExportContext
+from Products.GenericSetup.tests.common import DummyImportContext
-
_ACTION_XML = """\
<object name="foo_action" meta_type="CMF Action">
<property name="title">Foo</property>
@@ -52,7 +67,8 @@
</object>
"""
-_ACTIONSTOOL_XML = """\
+_ACTIONSTOOL_BODY = """\
+<?xml version="1.0"?>
<object name="portal_actions" meta_type="CMF Actions Tool"
xmlns:i18n="http://xml.zope.org/namespaces/i18n">
<action-provider name="portal_actions"/>
@@ -71,9 +87,166 @@
</object>
"""
+_EMPTY_EXPORT = """\
+<?xml version="1.0"?>
+<object meta_type="CMF Actions Tool" name="portal_actions" \
+xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions"/>
+</object>
+"""
-class ActionNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+_NORMAL_EXPORT = """\
+<?xml version="1.0"?>
+<object meta_type="CMF Actions Tool" name="portal_actions" \
+xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions"/>
+ <action-provider name="portal_foo">
+ <action action_id="foo"
+ title="Foo"
+ url_expr="string:${object_url}/foo"
+ condition_expr="python:1"
+ category="dummy"
+ visible="True"/>
+ </action-provider>
+ <action-provider name="portal_bar">
+ <action action_id="bar"
+ title="Bar"
+ url_expr="string:${object_url}/bar"
+ condition_expr="python:0"
+ category="dummy"
+ visible="False">
+ <permission>Manage portal</permission>
+ </action>
+ </action-provider>
+</object>
+"""
+_NEWSYTLE_EXPORT = """\
+<?xml version="1.0"?>
+<object meta_type="CMF Actions Tool" name="portal_actions" \
+xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions"/>
+ <object name="dummy" meta_type="CMF Action Category">
+ <property name="title"></property>
+ <object name="foo" meta_type="CMF Action">
+ <property name="title">Foo</property>
+ <property name="description"></property>
+ <property name="url_expr">string:${object_url}/foo</property>
+ <property name="icon_expr"></property>
+ <property name="available_expr">python:1</property>
+ <property name="permissions"></property>
+ <property name="visible">True</property>
+ </object>
+ <object name="bar" meta_type="CMF Action">
+ <property name="title">Bar</property>
+ <property name="description"></property>
+ <property name="url_expr">string:${object_url}/bar</property>
+ <property name="icon_expr"></property>
+ <property name="available_expr">python:0</property>
+ <property name="permissions">
+ <element value="Manage portal"/>
+ </property>
+ <property name="visible">False</property>
+ </object>
+ </object>
+</object>
+"""
+
+_I18N_IMPORT = """\
+<?xml version="1.0"?>
+<object meta_type="CMF Actions Tool" name="portal_actions" \
+xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions"/>
+ <object name="dummy" meta_type="CMF Action Category">
+ <property name="title"></property>
+ <object name="foo" meta_type="CMF Action" i18n:domain="foo_domain">
+ <property name="title" i18n:translate="">Foo</property>
+ <property name="description" i18n:translate=""></property>
+ <property name="url_expr">string:${object_url}/foo</property>
+ <property name="icon_expr"></property>
+ <property name="available_expr">python:1</property>
+ <property name="permissions"></property>
+ <property name="visible">True</property>
+ </object>
+ </object>
+</object>
+"""
+
+_INSERT_IMPORT = """\
+<?xml version="1.0"?>
+<actions-tool xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <object name="dummy">
+ <object name="spam" meta_type="CMF Action" insert-before="*">
+ <property name="title">Spam</property>
+ <property name="description"></property>
+ <property name="url_expr">string:${object_url}/spam</property>
+ <property name="icon_expr">string:spam_icon.png</property>
+ <property name="available_expr"></property>
+ <property name="permissions">
+ <element value="View" /></property>
+ <property name="visible">True</property>
+ </object>
+ <object name="foo" insert-after="*">
+ <property name="icon_expr">string:foo_icon.png</property>
+ </object>
+ </object>
+</actions-tool>
+"""
+
+_REMOVE_IMPORT = """\
+<?xml version="1.0"?>
+<actions-tool xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider id="portal_actions" remove="">
+ </action-provider>
+ <action-provider id="not_existing" remove="">
+ </action-provider>
+ <action-provider id="portal_bar" remove="">
+ </action-provider>
+</actions-tool>
+"""
+
+
+class DummyTool(OrderedFolder, ActionProviderBase):
+
+ __implements__ = IActionProvider
+
+
+class DummyUser(Implicit):
+
+ def getId(self):
+ return 'dummy'
+
+
+class DummyMembershipTool(DummyTool):
+
+ def isAnonymousUser(self):
+ return False
+
+ def getAuthenticatedMember(self):
+ return DummyUser().__of__(aq_parent(self))
+
+
+class DummyActionsTool(DummyTool):
+
+ implements(IActionsTool)
+ id = 'portal_actions'
+ meta_type = 'CMF Actions Tool'
+
+ def __init__(self):
+ self._providers = []
+
+ def addActionProvider(self, provider_name):
+ self._providers.append(provider_name)
+
+ def listActionProviders(self):
+ return self._providers[:]
+
+ def deleteActionProvider(self, provider_name):
+ self._providers = [ x for x in self._providers if x != provider_name ]
+
+
+class ActionNodeAdapterTests(NodeAdapterTestCase):
+
def _getTargetClass(self):
from Products.CMFCore.exportimport.actions import ActionNodeAdapter
@@ -101,20 +274,17 @@
self.assertEqual(obj.visible, True)
def setUp(self):
+ import Products.CMFCore.exportimport
from Products.CMFCore.ActionInformation import Action
- import Products.CMFCore.exportimport
- import Products.Five
- from Products.Five import zcml
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
self._obj = Action('foo_action')
self._XML = _ACTION_XML
-class ActionCategoryNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class ActionCategoryNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.CMFCore.exportimport.actions \
@@ -132,26 +302,23 @@
self.assertEqual(obj.title, '')
def setUp(self):
+ import Products.CMFCore.exportimport
from Products.CMFCore.ActionInformation import ActionCategory
- import Products.CMFCore.exportimport
- import Products.Five
- from Products.Five import zcml
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
self._obj = ActionCategory('foo_category')
self._XML = _ACTIONCATEGORY_XML
-class ActionsToolNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class ActionsToolXMLAdapterTests(BodyAdapterTestCase):
def _getTargetClass(self):
from Products.CMFCore.exportimport.actions \
- import ActionsToolNodeAdapter
+ import ActionsToolXMLAdapter
- return ActionsToolNodeAdapter
+ return ActionsToolXMLAdapter
def _populate(self, obj):
from Products.CMFCore.ActionInformation import Action
@@ -169,26 +336,280 @@
self.assertEqual(obj.action_providers[0], 'portal_actions')
def setUp(self):
+ import Products.CMFCore.exportimport
from Products.CMFCore.ActionsTool import ActionsTool
- import Products.CMFCore.exportimport
- import Products.Five
- from Products.Five import zcml
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ BodyAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
site = DummySite('site')
site._setObject('portal_actions', ActionsTool('portal_actions'))
self._obj = site.portal_actions
- self._XML = _ACTIONSTOOL_XML
+ self._BODY = _ACTIONSTOOL_BODY
+class _ActionSetup(PlacelessSetup, BaseRegistryTests):
+
+ def _initSite(self, foo=2, bar=2):
+ self.root.site = Folder(id='site')
+ site = self.root.site
+ site.portal_membership = DummyMembershipTool()
+
+ site.portal_actions = DummyActionsTool()
+ site.portal_actions.addActionProvider('portal_actions')
+
+ if foo > 0:
+ site.portal_foo = DummyTool()
+
+ if foo > 1:
+ site.portal_foo.addAction(id='foo',
+ name='Foo',
+ action='foo',
+ condition='python:1',
+ permission=(),
+ category='dummy',
+ visible=1)
+ site.portal_actions.addActionProvider('portal_foo')
+
+ if bar > 0:
+ site.portal_bar = DummyTool()
+
+ if bar > 1:
+ site.portal_bar.addAction(id='bar',
+ name='Bar',
+ action='bar',
+ condition='python:0',
+ permission=('Manage portal',),
+ category='dummy',
+ visible=0)
+ site.portal_actions.addActionProvider('portal_bar')
+
+ return site
+
+ def setUp(self):
+ PlacelessSetup.setUp(self)
+ BaseRegistryTests.setUp(self)
+ zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
+
+ def tearDown(self):
+ BaseRegistryTests.tearDown(self)
+ PlacelessSetup.tearDown(self)
+
+
+class exportActionProvidersTests(_ActionSetup):
+
+ def test_unchanged(self):
+ from Products.CMFCore.exportimport.actions \
+ import exportActionProviders
+
+ site = self._initSite(0, 0)
+ context = DummyExportContext(site)
+ exportActionProviders(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'actions.xml')
+ self._compareDOM(text, _EMPTY_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_normal(self):
+ from Products.CMFCore.exportimport.actions \
+ import exportActionProviders
+
+ site = self._initSite()
+ context = DummyExportContext(site)
+ exportActionProviders(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'actions.xml')
+ self._compareDOM(text, _NORMAL_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+
+class importActionProvidersTests(_ActionSetup):
+
+ def test_empty_default_purge(self):
+ from Products.CMFCore.exportimport.actions \
+ import importActionProviders
+
+ site = self._initSite(2, 0)
+ atool = site.portal_actions
+
+ self.assertEqual(len(atool.listActionProviders()), 2)
+ self.failUnless('portal_foo' in atool.listActionProviders())
+ self.failUnless('portal_actions' in atool.listActionProviders())
+
+ context = DummyImportContext(site)
+ context._files['actions.xml'] = _EMPTY_EXPORT
+ importActionProviders(context)
+
+ self.assertEqual(len(atool.listActionProviders()), 1)
+ self.failIf('portal_foo' in atool.listActionProviders())
+ self.failUnless('portal_actions' in atool.listActionProviders())
+ self.assertEqual(len(atool.objectIds()), 0)
+
+ def test_empty_explicit_purge(self):
+ from Products.CMFCore.exportimport.actions \
+ import importActionProviders
+
+ site = self._initSite(2, 0)
+ atool = site.portal_actions
+
+ self.assertEqual(len(atool.listActionProviders()), 2)
+ self.failUnless('portal_foo' in atool.listActionProviders())
+ self.failUnless('portal_actions' in atool.listActionProviders())
+
+ context = DummyImportContext(site, True)
+ context._files['actions.xml'] = _EMPTY_EXPORT
+ importActionProviders(context)
+
+ self.assertEqual(len(atool.listActionProviders()), 1)
+ self.failIf('portal_foo' in atool.listActionProviders())
+ self.failUnless('portal_actions' in atool.listActionProviders())
+ self.assertEqual(len(atool.objectIds()), 0)
+
+ def test_empty_skip_purge(self):
+ from Products.CMFCore.exportimport.actions \
+ import importActionProviders
+
+ site = self._initSite(2, 0)
+ atool = site.portal_actions
+
+ self.assertEqual(len(atool.listActionProviders()), 2)
+ self.failUnless('portal_foo' in atool.listActionProviders())
+ self.failUnless('portal_actions' in atool.listActionProviders())
+
+ context = DummyImportContext(site, False)
+ context._files['actions.xml'] = _EMPTY_EXPORT
+ importActionProviders(context)
+
+ self.assertEqual(len(atool.listActionProviders()), 2)
+ self.failUnless('portal_foo' in atool.listActionProviders())
+ self.failUnless('portal_actions' in atool.listActionProviders())
+
+ def test_normal(self):
+ from Products.CMFCore.exportimport.actions \
+ import exportActionProviders
+ from Products.CMFCore.exportimport.actions \
+ import importActionProviders
+
+ site = self._initSite(1, 1)
+ atool = site.portal_actions
+ foo = site.portal_foo
+ bar = site.portal_bar
+
+ self.assertEqual(len(atool.listActionProviders()), 1)
+ self.failIf('portal_foo' in atool.listActionProviders())
+ self.failIf(foo.listActions())
+ self.failIf('portal_bar' in atool.listActionProviders())
+ self.failIf(bar.listActions())
+ self.failUnless('portal_actions' in atool.listActionProviders())
+
+ context = DummyImportContext(site)
+ context._files['actions.xml'] = _NORMAL_EXPORT
+ importActionProviders(context)
+
+ self.assertEqual(len(atool.listActionProviders()), 1)
+ self.failIf('portal_foo' in atool.listActionProviders())
+ self.failUnless('portal_actions' in atool.listActionProviders())
+
+ self.assertEqual(len(atool.objectIds()), 1)
+ self.failUnless('dummy' in atool.objectIds())
+ self.assertEqual(len(atool.dummy.objectIds()) , 2)
+ self.failUnless('foo' in atool.dummy.objectIds())
+ self.failUnless('bar' in atool.dummy.objectIds())
+ self.failIf(foo.listActions())
+ self.failIf(bar.listActions())
+
+ # complete the roundtrip
+ context = DummyExportContext(site)
+ exportActionProviders(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'actions.xml')
+ self._compareDOM(text, _NEWSYTLE_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_i18n(self):
+ from Products.CMFCore.exportimport.actions \
+ import exportActionProviders
+ from Products.CMFCore.exportimport.actions \
+ import importActionProviders
+
+ site = self._initSite(0, 0)
+ atool = site.portal_actions
+
+ context = DummyImportContext(site)
+ context._files['actions.xml'] = _I18N_IMPORT
+ importActionProviders(context)
+
+ self.assertEqual(len(atool.listActionProviders()), 1)
+ self.assertEqual(atool.objectIds(), ['dummy'])
+ self.assertEqual(atool.dummy.objectIds(), ['foo'])
+ self.assertEqual(atool.dummy.foo.i18n_domain, 'foo_domain')
+
+ # complete the roundtrip
+ context = DummyExportContext(site)
+ exportActionProviders(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'actions.xml')
+ self._compareDOM(text, _I18N_IMPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_insert_skip_purge(self):
+ from Products.CMFCore.exportimport.actions \
+ import importActionProviders
+
+ site = self._initSite(0, 0)
+ atool = site.portal_actions
+
+ context = DummyImportContext(site)
+ context._files['actions.xml'] = _NEWSYTLE_EXPORT
+ importActionProviders(context)
+
+ self.assertEqual(len(atool.listActionProviders()), 1)
+ self.assertEqual(atool.objectIds(), ['dummy'])
+ self.assertEqual(atool.dummy.objectIds(), ['foo', 'bar'])
+ self.assertEqual(atool.dummy.foo.icon_expr, '')
+
+ context = DummyImportContext(site, False)
+ context._files['actions.xml'] = _INSERT_IMPORT
+ importActionProviders(context)
+
+ self.assertEqual(len(atool.listActionProviders()), 1)
+ self.assertEqual(atool.objectIds(), ['dummy'])
+ self.assertEqual(atool.dummy.objectIds(), ['spam', 'bar', 'foo'])
+ self.assertEqual(atool.dummy.foo.icon_expr, 'string:foo_icon.png')
+
+ def test_remove_skip_purge(self):
+ from Products.CMFCore.exportimport.actions \
+ import importActionProviders
+
+ site = self._initSite(2, 2)
+ atool = site.portal_actions
+
+ self.assertEqual(atool.listActionProviders(),
+ ['portal_actions', 'portal_foo', 'portal_bar'])
+
+ context = DummyImportContext(site, False)
+ context._files['actions.xml'] = _REMOVE_IMPORT
+ importActionProviders(context)
+
+ self.assertEqual(atool.listActionProviders(), ['portal_foo'])
+
+
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(ActionNodeAdapterTests),
unittest.makeSuite(ActionCategoryNodeAdapterTests),
- unittest.makeSuite(ActionsToolNodeAdapterTests),
+ unittest.makeSuite(ActionsToolXMLAdapterTests),
+ unittest.makeSuite(exportActionProvidersTests),
+ unittest.makeSuite(importActionProvidersTests),
))
if __name__ == '__main__':
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_cachingpolicymgr.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_cachingpolicymgr.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_cachingpolicymgr.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,7 +10,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Caching policy manager node adapter unit tests.
+"""Caching policy manager xml adapter and setup handler unit tests.
$Id$
"""
@@ -18,9 +18,17 @@
import unittest
import Testing
-from Products.CMFCore.tests.base.testcase import PlacelessSetup
+import Products
+from OFS.Folder import Folder
+from Products.Five import zcml
+
+from Products.GenericSetup.testing import BodyAdapterTestCase
from Products.GenericSetup.testing import NodeAdapterTestCase
+from Products.GenericSetup.tests.common import BaseRegistryTests
+from Products.GenericSetup.tests.common import DummyExportContext
+from Products.GenericSetup.tests.common import DummyImportContext
+from Products.CMFCore.tests.base.testcase import PlacelessSetup
_CP_XML = """\
<caching-policy name="foo_policy" enable_304s="False" etag_func=""
@@ -30,7 +38,8 @@
proxy_revalidate="False" public="False" vary=""/>
"""
-_CPM_XML = """\
+_CPM_BODY = """\
+<?xml version="1.0"?>
<object name="caching_policy_manager" meta_type="CMF Caching Policy Manager">
<caching-policy name="foo_policy" enable_304s="False" etag_func=""
last_modified="True" max_age_secs="600" mtime_func="object/modified"
@@ -42,7 +51,7 @@
"""
-class CachingPolicyNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class CachingPolicyNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.CMFCore.exportimport.cachingpolicymgr \
@@ -51,27 +60,23 @@
return CachingPolicyNodeAdapter
def setUp(self):
+ import Products.CMFCore.exportimport
from Products.CMFCore.CachingPolicyManager import CachingPolicy
- import Products.CMFCore.exportimport
- import Products.Five
- from Products.Five import zcml
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
self._obj = CachingPolicy('foo_policy', max_age_secs=0)
self._XML = _CP_XML
-class CachingPolicyManagerNodeAdapterTests(PlacelessSetup,
- NodeAdapterTestCase):
+class CachingPolicyManagerXMLAdapterTests(BodyAdapterTestCase):
def _getTargetClass(self):
from Products.CMFCore.exportimport.cachingpolicymgr \
- import CachingPolicyManagerNodeAdapter
+ import CachingPolicyManagerXMLAdapter
- return CachingPolicyManagerNodeAdapter
+ return CachingPolicyManagerXMLAdapter
def _populate(self, obj):
obj.addPolicy('foo_policy',
@@ -79,23 +84,161 @@
'object/modified', 600, 0, 0, 0, '', '')
def setUp(self):
+ import Products.CMFCore.exportimport
from Products.CMFCore.CachingPolicyManager import CachingPolicyManager
- import Products.CMFCore.exportimport
- import Products.Five
- from Products.Five import zcml
+ BodyAdapterTestCase.setUp(self)
+ zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
+
+ self._obj = CachingPolicyManager()
+ self._BODY = _CPM_BODY
+
+
+class _CachingPolicyManagerSetup(PlacelessSetup, BaseRegistryTests):
+
+ POLICY_ID = 'policy_id'
+ PREDICATE = "python:object.getId() == 'foo'"
+ MTIME_FUNC = "object/modified"
+ MAX_AGE_SECS = 60
+ VARY = "Test"
+ ETAG_FUNC = "object/getETag"
+ S_MAX_AGE_SECS = 120
+ PRE_CHECK = 42
+ POST_CHECK = 43
+
+ _EMPTY_EXPORT = """\
+<?xml version="1.0"?>
+<object name="caching_policy_manager" meta_type="CMF Caching Policy Manager"/>
+"""
+
+ _WITH_POLICY_EXPORT = """\
+<?xml version="1.0"?>
+<object name="caching_policy_manager" meta_type="CMF Caching Policy Manager">
+ <caching-policy name="%s" enable_304s="True"
+ etag_func="%s" last_modified="False" max_age_secs="%d"
+ mtime_func="%s" must_revalidate="True" no_cache="True"
+ no_store="True" no_transform="True" post_check="%d" pre_check="%d"
+ predicate="%s" private="True"
+ proxy_revalidate="True" public="True" s_max_age_secs="%d" vary="%s"/>
+</object>
+""" % (POLICY_ID, ETAG_FUNC, MAX_AGE_SECS, MTIME_FUNC, POST_CHECK, PRE_CHECK,
+ PREDICATE, S_MAX_AGE_SECS, VARY)
+
+ def _initSite(self, with_policy=False):
+ from Products.CMFCore.CachingPolicyManager import CachingPolicyManager
+
+ self.root.site = Folder(id='site')
+ site = self.root.site
+ mgr = CachingPolicyManager()
+ site._setObject( mgr.getId(), mgr )
+
+ if with_policy:
+ mgr.addPolicy( policy_id=self.POLICY_ID
+ , predicate=self.PREDICATE
+ , mtime_func=self.MTIME_FUNC
+ , max_age_secs=self.MAX_AGE_SECS
+ , no_cache=True
+ , no_store=True
+ , must_revalidate=True
+ , vary=self.VARY
+ , etag_func=self.ETAG_FUNC
+ , s_max_age_secs=self.S_MAX_AGE_SECS
+ , proxy_revalidate=True
+ , public=True
+ , private=True
+ , no_transform=True
+ , enable_304s=True
+ , last_modified=False
+ , pre_check=self.PRE_CHECK
+ , post_check=self.POST_CHECK
+ )
+
+ return site
+
+ def setUp(self):
PlacelessSetup.setUp(self)
+ BaseRegistryTests.setUp(self)
zcml.load_config('meta.zcml', Products.Five)
zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
- self._obj = CachingPolicyManager()
- self._XML = _CPM_XML
+ def tearDown(self):
+ BaseRegistryTests.tearDown(self)
+ PlacelessSetup.tearDown(self)
+class exportCachingPolicyManagerTests(_CachingPolicyManagerSetup):
+
+ def test_empty(self):
+ from Products.CMFCore.exportimport.cachingpolicymgr \
+ import exportCachingPolicyManager
+
+ site = self._initSite(with_policy=False)
+ context = DummyExportContext(site)
+ exportCachingPolicyManager(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'cachingpolicymgr.xml')
+ self._compareDOM(text, self._EMPTY_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_with_policy(self):
+ from Products.CMFCore.exportimport.cachingpolicymgr \
+ import exportCachingPolicyManager
+
+ site = self._initSite(with_policy=True)
+ context = DummyExportContext(site)
+ exportCachingPolicyManager(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'cachingpolicymgr.xml')
+ self._compareDOM(text, self._WITH_POLICY_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+
+class importCachingPolicyManagerTests(_CachingPolicyManagerSetup):
+
+ def test_normal(self):
+ from Products.CMFCore.exportimport.cachingpolicymgr \
+ import importCachingPolicyManager
+
+ site = self._initSite(with_policy=False)
+ cpm = site.caching_policy_manager
+ self.assertEqual(len(cpm.listPolicies()), 0)
+
+ context = DummyImportContext(site)
+ context._files['cachingpolicymgr.xml'] = self._WITH_POLICY_EXPORT
+ importCachingPolicyManager(context)
+
+ self.assertEqual(len(cpm.listPolicies()), 1)
+ policy_id, policy = cpm.listPolicies()[0]
+ self.assertEqual(policy.getPolicyId(), self.POLICY_ID)
+ self.assertEqual(policy.getPredicate(), self.PREDICATE)
+ self.assertEqual(policy.getMTimeFunc(), self.MTIME_FUNC)
+ self.assertEqual(policy.getVary(), self.VARY)
+ self.assertEqual(policy.getETagFunc(), self.ETAG_FUNC)
+ self.assertEqual(policy.getMaxAgeSecs(), self.MAX_AGE_SECS)
+ self.assertEqual(policy.getSMaxAgeSecs(), self.S_MAX_AGE_SECS)
+ self.assertEqual(policy.getPreCheck(), self.PRE_CHECK)
+ self.assertEqual(policy.getPostCheck(), self.POST_CHECK)
+ self.assertEqual(policy.getLastModified(), False)
+ self.assertEqual(policy.getNoCache(), True)
+ self.assertEqual(policy.getNoStore(), True)
+ self.assertEqual(policy.getMustRevalidate(), True)
+ self.assertEqual(policy.getProxyRevalidate(), True)
+ self.assertEqual(policy.getNoTransform(), True)
+ self.assertEqual(policy.getPublic(), True)
+ self.assertEqual(policy.getPrivate(), True)
+ self.assertEqual(policy.getEnable304s(), True)
+
+
def test_suite():
return unittest.TestSuite((
unittest.makeSuite(CachingPolicyNodeAdapterTests),
- unittest.makeSuite(CachingPolicyManagerNodeAdapterTests),
+ unittest.makeSuite(CachingPolicyManagerXMLAdapterTests),
+ unittest.makeSuite(exportCachingPolicyManagerTests),
+ unittest.makeSuite(importCachingPolicyManagerTests),
))
if __name__ == '__main__':
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_catalog.py (from rev 40492, CMF/trunk/CMFCore/exportimport/tests/test_catalog.py)
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_content.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_content.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_content.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -26,7 +26,6 @@
from Products.GenericSetup.tests.common import DummyExportContext
from Products.GenericSetup.tests.common import DummyImportContext
-from conformance import ConformsToIFilesystemExporter
from conformance import ConformsToIFilesystemImporter
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_contenttyperegistry.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_contenttyperegistry.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_contenttyperegistry.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,7 +10,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Content type registry node adapter unit tests.
+"""Content type registry xml adapter and setup handler unit tests.
$Id$
"""
@@ -18,11 +18,26 @@
import unittest
import Testing
+import Products
+from OFS.Folder import Folder
+from Products.Five import zcml
+
+from Products.GenericSetup.testing import BodyAdapterTestCase
+from Products.GenericSetup.tests.common import BaseRegistryTests
+from Products.GenericSetup.tests.common import DummyExportContext
+from Products.GenericSetup.tests.common import DummyImportContext
+
from Products.CMFCore.tests.base.testcase import PlacelessSetup
-from Products.GenericSetup.testing import NodeAdapterTestCase
+_TEST_PREDICATES = (
+ ('plain_text', 'major_minor', ('text', 'plain,javascript'), 'File'),
+ ('stylesheets', 'extension', ('css,xsl,xslt',), 'Text File'),
+ ('images', 'mimetype_regex', ('image/.*',), 'Image'),
+ ('logfiles', 'name_regex', ('error_log-.*',), 'Log File'),
+)
-_CTR_XML = """\
+_CTR_BODY = """\
+<?xml version="1.0"?>
<object name="content_type_registry" meta_type="Content Type Registry">
<predicate name="foo_predicate" content_type_name="Foo Type"
predicate_type="major_minor">
@@ -45,14 +60,13 @@
"""
-class ContentTypeRegistryNodeAdapterTests(PlacelessSetup,
- NodeAdapterTestCase):
+class ContentTypeRegistryXMLAdapterTests(BodyAdapterTestCase):
def _getTargetClass(self):
from Products.CMFCore.exportimport.contenttyperegistry \
- import ContentTypeRegistryNodeAdapter
+ import ContentTypeRegistryXMLAdapter
- return ContentTypeRegistryNodeAdapter
+ return ContentTypeRegistryXMLAdapter
def _populate(self, obj):
obj.addPredicate('foo_predicate', 'major_minor')
@@ -69,22 +83,176 @@
obj.assignTypeName('foobar_predicate', 'Foobar Type')
def setUp(self):
+ import Products.CMFCore.exportimport
from Products.CMFCore.ContentTypeRegistry import ContentTypeRegistry
- import Products.CMFCore.exportimport
- import Products.Five
- from Products.Five import zcml
+ BodyAdapterTestCase.setUp(self)
+ zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
+
+ self._obj = ContentTypeRegistry()
+ self._BODY = _CTR_BODY
+
+
+class _ContentTypeRegistrySetup(PlacelessSetup, BaseRegistryTests):
+
+ MAJOR_MINOR_ID = _TEST_PREDICATES[0][0]
+ MAJOR = _TEST_PREDICATES[0][2][0]
+ MINOR = _TEST_PREDICATES[0][2][1]
+ MAJOR_MINOR_TYPENAME = _TEST_PREDICATES[0][3]
+ EXTENSION_ID = _TEST_PREDICATES[1][0]
+ EXTENSIONS = _TEST_PREDICATES[1][2][0]
+ EXTENSION_TYPENAME = _TEST_PREDICATES[1][3]
+ MIMETYPE_REGEX_ID = _TEST_PREDICATES[2][0]
+ MIMETYPE_REGEX = _TEST_PREDICATES[2][2][0]
+ MIMETYPE_REGEX_TYPENAME = _TEST_PREDICATES[2][3]
+ NAME_REGEX_ID = _TEST_PREDICATES[3][0]
+ NAME_REGEX = _TEST_PREDICATES[3][2][0]
+ NAME_REGEX_TYPENAME = _TEST_PREDICATES[3][3]
+
+ _EMPTY_EXPORT = """\
+<?xml version="1.0"?>
+<object name="content_type_registry" meta_type="Content Type Registry"/>
+"""
+
+ _WITH_POLICY_EXPORT = """\
+<?xml version="1.0"?>
+<object name="content_type_registry" meta_type="Content Type Registry">
+ <predicate name="%s" content_type_name="%s"
+ predicate_type="major_minor">
+ <argument value="%s"/>
+ <argument value="%s"/>
+ </predicate>
+ <predicate name="%s" content_type_name="%s"
+ predicate_type="extension">
+ <argument value="%s"/>
+ </predicate>
+ <predicate name="%s" content_type_name="%s"
+ predicate_type="mimetype_regex">
+ <argument value="%s"/>
+ </predicate>
+ <predicate name="%s" content_type_name="%s"
+ predicate_type="name_regex">
+ <argument value="%s"/>
+ </predicate>
+</object>
+""" % (MAJOR_MINOR_ID,
+ MAJOR_MINOR_TYPENAME,
+ MAJOR,
+ MINOR,
+ EXTENSION_ID,
+ EXTENSION_TYPENAME,
+ EXTENSIONS,
+ MIMETYPE_REGEX_ID,
+ MIMETYPE_REGEX_TYPENAME,
+ MIMETYPE_REGEX,
+ NAME_REGEX_ID,
+ NAME_REGEX_TYPENAME,
+ NAME_REGEX,
+ )
+
+ def _initSite(self, mit_predikat=False):
+ from Products.CMFCore.ContentTypeRegistry import ContentTypeRegistry
+
+ self.root.site = Folder(id='site')
+ site = self.root.site
+ ctr = ContentTypeRegistry()
+ site._setObject( ctr.getId(), ctr )
+
+ if mit_predikat:
+ for (predicate_id, predicate_type, edit_args, content_type_name
+ ) in _TEST_PREDICATES:
+ ctr.addPredicate(predicate_id, predicate_type)
+ predicate = ctr.getPredicate(predicate_id)
+ predicate.edit(*edit_args)
+ ctr.assignTypeName(predicate_id, content_type_name)
+
+ return site
+
+ def setUp(self):
PlacelessSetup.setUp(self)
+ BaseRegistryTests.setUp(self)
zcml.load_config('meta.zcml', Products.Five)
zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
- self._obj = ContentTypeRegistry()
- self._XML = _CTR_XML
+ def tearDown(self):
+ BaseRegistryTests.tearDown(self)
+ PlacelessSetup.tearDown(self)
+class exportContentTypeRegistryTests(_ContentTypeRegistrySetup):
+
+ def test_empty(self):
+ from Products.CMFCore.exportimport.contenttyperegistry \
+ import exportContentTypeRegistry
+
+ site = self._initSite(mit_predikat=False)
+ context = DummyExportContext(site)
+ exportContentTypeRegistry(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'contenttyperegistry.xml')
+ self._compareDOM(text, self._EMPTY_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_with_policy(self):
+ from Products.CMFCore.exportimport.contenttyperegistry \
+ import exportContentTypeRegistry
+
+ site = self._initSite(mit_predikat=True)
+ context = DummyExportContext(site)
+ exportContentTypeRegistry(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'contenttyperegistry.xml')
+ self._compareDOM(text, self._WITH_POLICY_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+
+class importContentTypeRegistryTests(_ContentTypeRegistrySetup):
+
+ def test_normal(self):
+ from Products.CMFCore.exportimport.contenttyperegistry \
+ import importContentTypeRegistry
+
+ site = self._initSite(mit_predikat=False)
+ ctr = site.content_type_registry
+ self.assertEqual(len(ctr.listPredicates()), 0)
+
+ context = DummyImportContext(site)
+ context._files['contenttyperegistry.xml'] = self._WITH_POLICY_EXPORT
+ importContentTypeRegistry(context)
+
+ self.assertEqual(len(ctr.listPredicates()), len(_TEST_PREDICATES))
+ predicate_id, (predicate, content_type_name) = ctr.listPredicates()[0]
+ self.assertEqual(predicate_id, self.MAJOR_MINOR_ID)
+ self.assertEqual(predicate.PREDICATE_TYPE, 'major_minor')
+ self.assertEqual(content_type_name, self.MAJOR_MINOR_TYPENAME)
+ self.assertEqual(predicate.major, self.MAJOR.split(','))
+ self.assertEqual(predicate.minor, self.MINOR.split(','))
+ predicate_id, (predicate, content_type_name) = ctr.listPredicates()[1]
+ self.assertEqual(predicate_id, self.EXTENSION_ID)
+ self.assertEqual(predicate.PREDICATE_TYPE, 'extension')
+ self.assertEqual(content_type_name, self.EXTENSION_TYPENAME)
+ self.assertEqual(predicate.extensions, self.EXTENSIONS.split(','))
+ predicate_id, (predicate, content_type_name) = ctr.listPredicates()[2]
+ self.assertEqual(predicate_id, self.MIMETYPE_REGEX_ID)
+ self.assertEqual(predicate.PREDICATE_TYPE, 'mimetype_regex')
+ self.assertEqual(content_type_name, self.MIMETYPE_REGEX_TYPENAME)
+ self.assertEqual(predicate.pattern.pattern, self.MIMETYPE_REGEX)
+ predicate_id, (predicate, content_type_name) = ctr.listPredicates()[3]
+ self.assertEqual(predicate_id, self.NAME_REGEX_ID)
+ self.assertEqual(predicate.PREDICATE_TYPE, 'name_regex')
+ self.assertEqual(content_type_name, self.NAME_REGEX_TYPENAME)
+ self.assertEqual(predicate.pattern.pattern, self.NAME_REGEX)
+
+
def test_suite():
return unittest.TestSuite((
- unittest.makeSuite(ContentTypeRegistryNodeAdapterTests),
+ unittest.makeSuite(ContentTypeRegistryXMLAdapterTests),
+ unittest.makeSuite(exportContentTypeRegistryTests),
+ unittest.makeSuite(importContentTypeRegistryTests),
))
if __name__ == '__main__':
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_cookieauth.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_cookieauth.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_cookieauth.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,7 +10,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Cookie crumbler node adapter unit tests.
+"""Cookie crumbler xml adapter and setup handler unit tests.
$Id$
"""
@@ -18,11 +18,36 @@
import unittest
import Testing
+import Products
+from OFS.Folder import Folder
+from Products.Five import zcml
+
+from Products.GenericSetup.testing import BodyAdapterTestCase
+from Products.GenericSetup.tests.common import BaseRegistryTests
+from Products.GenericSetup.tests.common import DummyExportContext
+from Products.GenericSetup.tests.common import DummyImportContext
+
+from Products.CMFCore.CookieCrumbler import CookieCrumbler
from Products.CMFCore.tests.base.testcase import PlacelessSetup
-from Products.GenericSetup.testing import NodeAdapterTestCase
+_COOKIECRUMBLER_BODY = """\
+<?xml version="1.0"?>
+<object name="foo_cookiecrumbler" meta_type="Cookie Crumbler">
+ <property name="auth_cookie">__ac</property>
+ <property name="name_cookie">__ac_name</property>
+ <property name="pw_cookie">__ac_password</property>
+ <property name="persist_cookie">__ac_persistent</property>
+ <property name="auto_login_page">login_form</property>
+ <property name="logout_page">logged_out</property>
+ <property name="unauth_page"></property>
+ <property name="local_cookie_path">False</property>
+ <property name="cache_header_value">private</property>
+ <property name="log_username">True</property>
+</object>
+"""
-_COOKIECRUMBLER_XML = """\
+_DEFAULT_EXPORT = """\
+<?xml version="1.0"?>
<object name="foo_cookiecrumbler" meta_type="Cookie Crumbler">
<property name="auth_cookie">__ac</property>
<property name="name_cookie">__ac_name</property>
@@ -37,32 +62,135 @@
</object>
"""
+_CHANGED_EXPORT = """\
+<?xml version="1.0"?>
+<object name="foo_cookiecrumbler" meta_type="Cookie Crumbler">
+ <property name="auth_cookie">value1</property>
+ <property name="name_cookie">value3</property>
+ <property name="pw_cookie">value5</property>
+ <property name="persist_cookie">value4</property>
+ <property name="auto_login_page">value6</property>
+ <property name="logout_page">value8</property>
+ <property name="unauth_page">value7</property>
+ <property name="local_cookie_path">True</property>
+ <property name="cache_header_value">value2</property>
+ <property name="log_username">False</property>
+</object>
+"""
-class CookieCrumblerNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class CookieCrumblerXMLAdapterTests(BodyAdapterTestCase):
+
def _getTargetClass(self):
from Products.CMFCore.exportimport.cookieauth \
- import CookieCrumblerNodeAdapter
+ import CookieCrumblerXMLAdapter
- return CookieCrumblerNodeAdapter
+ return CookieCrumblerXMLAdapter
def setUp(self):
+ import Products.CMFCore.exportimport
from Products.CMFCore.CookieCrumbler import CookieCrumbler
- import Products.CMFCore.exportimport
- import Products.Five
- from Products.Five import zcml
+ BodyAdapterTestCase.setUp(self)
+ zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
+
+ self._obj = CookieCrumbler('foo_cookiecrumbler')
+ self._BODY = _COOKIECRUMBLER_BODY
+
+
+class _CookieCrumblerSetup(PlacelessSetup, BaseRegistryTests):
+
+ def _initSite(self, use_changed=False):
+ self.root.site = Folder(id='site')
+ site = self.root.site
+ cc = site.cookie_authentication = CookieCrumbler('foo_cookiecrumbler')
+
+ if use_changed:
+ cc.auth_cookie = 'value1'
+ cc.cache_header_value = 'value2'
+ cc.name_cookie = 'value3'
+ cc.log_username = 0
+ cc.persist_cookie = 'value4'
+ cc.pw_cookie = 'value5'
+ cc.local_cookie_path = 1
+ cc.auto_login_page = 'value6'
+ cc.unauth_page = 'value7'
+ cc.logout_page = 'value8'
+
+ return site
+
+ def setUp(self):
PlacelessSetup.setUp(self)
+ BaseRegistryTests.setUp(self)
zcml.load_config('meta.zcml', Products.Five)
zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
- self._obj = CookieCrumbler('foo_cookiecrumbler')
- self._XML = _COOKIECRUMBLER_XML
+ def tearDown(self):
+ BaseRegistryTests.tearDown(self)
+ PlacelessSetup.tearDown(self)
+class exportCookieCrumblerTests(_CookieCrumblerSetup):
+
+ def test_unchanged(self):
+ from Products.CMFCore.exportimport.cookieauth \
+ import exportCookieCrumbler
+
+ site = self._initSite(use_changed=False)
+ context = DummyExportContext(site)
+ exportCookieCrumbler(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'cookieauth.xml')
+ self._compareDOM(text, _DEFAULT_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_changed(self):
+ from Products.CMFCore.exportimport.cookieauth \
+ import exportCookieCrumbler
+
+ site = self._initSite(use_changed=True)
+ context = DummyExportContext(site)
+ exportCookieCrumbler(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'cookieauth.xml')
+ self._compareDOM(text, _CHANGED_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+
+class importCookieCrumblerTests(_CookieCrumblerSetup):
+
+ def test_normal(self):
+ from Products.CMFCore.exportimport.cookieauth \
+ import importCookieCrumbler
+
+ site = self._initSite()
+ cc = site.cookie_authentication
+
+ context = DummyImportContext(site)
+ context._files['cookieauth.xml'] = _CHANGED_EXPORT
+ importCookieCrumbler(context)
+
+ self.assertEqual( cc.auth_cookie, 'value1' )
+ self.assertEqual( cc.cache_header_value, 'value2' )
+ self.assertEqual( cc.name_cookie, 'value3' )
+ self.assertEqual( cc.log_username, 0 )
+ self.assertEqual( cc.persist_cookie, 'value4' )
+ self.assertEqual( cc.pw_cookie, 'value5' )
+ self.assertEqual( cc.local_cookie_path, 1 )
+ self.assertEqual( cc.auto_login_page, 'value6' )
+ self.assertEqual( cc.unauth_page, 'value7' )
+ self.assertEqual( cc.logout_page, 'value8' )
+
+
def test_suite():
return unittest.TestSuite((
- unittest.makeSuite(CookieCrumblerNodeAdapterTests),
+ unittest.makeSuite(CookieCrumblerXMLAdapterTests),
+ unittest.makeSuite(exportCookieCrumblerTests),
+ unittest.makeSuite(importCookieCrumblerTests),
))
if __name__ == '__main__':
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_mailhost.py (from rev 40492, CMF/trunk/CMFCore/exportimport/tests/test_mailhost.py)
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_properties.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_properties.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_properties.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,7 +10,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Site properties node adapter unit tests.
+"""Site properties xml adapter and setup handler unit tests.
$Id$
"""
@@ -18,11 +18,17 @@
import unittest
import Testing
+from Products.Five import zcml
+
+from Products.GenericSetup.testing import BodyAdapterTestCase
+from Products.GenericSetup.tests.common import BaseRegistryTests
+from Products.GenericSetup.tests.common import DummyExportContext
+from Products.GenericSetup.tests.common import DummyImportContext
+
from Products.CMFCore.tests.base.testcase import PlacelessSetup
-from Products.GenericSetup.testing import NodeAdapterTestCase
-
-_PROPERTIES_XML = """\
+_PROPERTIES_BODY = """\
+<?xml version="1.0"?>
<site>
<property name="title">Foo</property>
<property name="foo_string" type="string">foo</property>
@@ -30,14 +36,35 @@
</site>
"""
+_EMPTY_EXPORT = """\
+<?xml version="1.0" ?>
+<site>
+ <property name="title"/>
+</site>
+"""
-class PropertiesNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+_NORMAL_EXPORT = """\
+<?xml version="1.0" ?>
+<site>
+ <property name="title"/>
+ <property name="foo" type="string">Foo</property>
+ <property name="bar" type="tokens">
+ <element value="Bar"/>
+ </property>
+ <property name="moo" type="tokens">
+ <element value="Moo"/>
+ </property>
+</site>
+"""
+
+class PropertiesXMLAdapterTests(BodyAdapterTestCase):
+
def _getTargetClass(self):
from Products.CMFCore.exportimport.properties \
- import PropertiesNodeAdapter
+ import PropertiesXMLAdapter
- return PropertiesNodeAdapter
+ return PropertiesXMLAdapter
def _populate(self, obj):
obj._setPropValue('title', 'Foo')
@@ -45,22 +72,166 @@
obj._setProperty('foo_boolean', False, 'boolean')
def setUp(self):
+ import Products.CMFCore.exportimport
from Products.CMFCore.PortalObject import PortalObjectBase
+
+ BodyAdapterTestCase.setUp(self)
+ zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
+
+ self._obj = PortalObjectBase('foo_site')
+ self._BODY = _PROPERTIES_BODY
+
+
+class _SitePropertiesSetup(PlacelessSetup, BaseRegistryTests):
+
+ def _initSite(self, foo=2, bar=2):
+ from Products.CMFCore.PortalObject import PortalObjectBase
+
+ self.root.site = PortalObjectBase('foo_site')
+ site = self.root.site
+
+ if foo > 0:
+ site._setProperty('foo', '', 'string')
+ if foo > 1:
+ site._updateProperty('foo', 'Foo')
+
+ if bar > 0:
+ site._setProperty( 'bar', (), 'tokens' )
+ site._setProperty( 'moo', (), 'tokens' )
+ if bar > 1:
+ site._updateProperty( 'bar', ('Bar',) )
+ site.moo = ['Moo']
+
+ return site
+
+ def setUp(self):
import Products.CMFCore.exportimport
- import Products.Five
- from Products.Five import zcml
PlacelessSetup.setUp(self)
+ BaseRegistryTests.setUp(self)
zcml.load_config('meta.zcml', Products.Five)
zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
- self._obj = PortalObjectBase('foo_site')
- self._XML = _PROPERTIES_XML
+ def tearDown(self):
+ BaseRegistryTests.tearDown(self)
+ PlacelessSetup.tearDown(self)
+class exportSitePropertiesTests(_SitePropertiesSetup):
+
+ def test_empty(self):
+ from Products.CMFCore.exportimport.properties \
+ import exportSiteProperties
+
+ site = self._initSite(0, 0)
+ context = DummyExportContext(site)
+ exportSiteProperties(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'properties.xml')
+ self._compareDOM(text, _EMPTY_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_normal(self):
+ from Products.CMFCore.exportimport.properties \
+ import exportSiteProperties
+
+ site = self._initSite()
+ context = DummyExportContext( site )
+ exportSiteProperties(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'properties.xml')
+ self._compareDOM(text, _NORMAL_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+
+class importSitePropertiesTests(_SitePropertiesSetup):
+
+ def test_empty_default_purge(self):
+ from Products.CMFCore.exportimport.properties \
+ import importSiteProperties
+
+ site = self._initSite()
+
+ self.assertEqual( len( site.propertyIds() ), 4 )
+ self.failUnless( 'foo' in site.propertyIds() )
+ self.assertEqual( site.getProperty('foo'), 'Foo' )
+ self.failUnless( 'bar' in site.propertyIds() )
+ self.assertEqual( site.getProperty('bar'), ('Bar',) )
+
+ context = DummyImportContext(site)
+ context._files['properties.xml'] = _EMPTY_EXPORT
+ importSiteProperties(context)
+
+ self.assertEqual( len( site.propertyIds() ), 1 )
+
+ def test_empty_explicit_purge(self):
+ from Products.CMFCore.exportimport.properties \
+ import importSiteProperties
+
+ site = self._initSite()
+
+ self.assertEqual( len( site.propertyIds() ), 4 )
+ self.failUnless( 'foo' in site.propertyIds() )
+ self.assertEqual( site.getProperty('foo'), 'Foo' )
+ self.failUnless( 'bar' in site.propertyIds() )
+ self.assertEqual( site.getProperty('bar'), ('Bar',) )
+
+ context = DummyImportContext(site, True)
+ context._files['properties.xml'] = _EMPTY_EXPORT
+ importSiteProperties(context)
+
+ self.assertEqual( len( site.propertyIds() ), 1 )
+
+ def test_empty_skip_purge(self):
+ from Products.CMFCore.exportimport.properties \
+ import importSiteProperties
+
+ site = self._initSite()
+
+ self.assertEqual( len( site.propertyIds() ), 4 )
+ self.failUnless( 'foo' in site.propertyIds() )
+ self.assertEqual( site.getProperty('foo'), 'Foo' )
+ self.failUnless( 'bar' in site.propertyIds() )
+ self.assertEqual( site.getProperty('bar'), ('Bar',) )
+
+ context = DummyImportContext(site, False)
+ context._files['properties.xml'] = _EMPTY_EXPORT
+ importSiteProperties(context)
+
+ self.assertEqual( len( site.propertyIds() ), 4 )
+ self.failUnless( 'foo' in site.propertyIds() )
+ self.assertEqual( site.getProperty('foo'), 'Foo' )
+ self.failUnless( 'bar' in site.propertyIds() )
+ self.assertEqual( site.getProperty('bar'), ('Bar',) )
+
+ def test_normal(self):
+ from Products.CMFCore.exportimport.properties \
+ import importSiteProperties
+
+ site = self._initSite(0,0)
+
+ self.assertEqual( len( site.propertyIds() ), 1 )
+
+ context = DummyImportContext(site)
+ context._files['properties.xml'] = _NORMAL_EXPORT
+ importSiteProperties(context)
+
+ self.assertEqual( len( site.propertyIds() ), 4 )
+ self.failUnless( 'foo' in site.propertyIds() )
+ self.assertEqual( site.getProperty('foo'), 'Foo' )
+ self.failUnless( 'bar' in site.propertyIds() )
+ self.assertEqual( site.getProperty('bar'), ('Bar',) )
+
+
def test_suite():
return unittest.TestSuite((
- unittest.makeSuite(PropertiesNodeAdapterTests),
+ unittest.makeSuite(PropertiesXMLAdapterTests),
+ unittest.makeSuite(exportSitePropertiesTests),
+ unittest.makeSuite(importSitePropertiesTests),
))
if __name__ == '__main__':
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_skins.py (from rev 40492, CMF/trunk/CMFCore/exportimport/tests/test_skins.py)
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_typeinfo.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_typeinfo.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_typeinfo.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,21 +10,33 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Types tool node adapter unit tests.
+"""Types tool xml adapter and setup handler unit tests.
$Id$
"""
import unittest
import Testing
-import Zope2
-Zope2.startup()
+import Products
+from OFS.Folder import Folder
+from Products.Five import zcml
+
+from Products.GenericSetup.testing import BodyAdapterTestCase
+from Products.GenericSetup.tests.common import BaseRegistryTests
+from Products.GenericSetup.tests.common import DummyExportContext
+from Products.GenericSetup.tests.common import DummyImportContext
+
+from Products.CMFCore.permissions import View
+from Products.CMFCore.permissions import AccessContentsInformation
+from Products.CMFCore.permissions import ModifyPortalContent
from Products.CMFCore.tests.base.testcase import PlacelessSetup
-from Products.GenericSetup.testing import NodeAdapterTestCase
+from Products.CMFCore.TypesTool import FactoryTypeInformation
+from Products.CMFCore.TypesTool import ScriptableTypeInformation
+from Products.CMFCore.TypesTool import TypesTool
-
-_FTI_XML = """\
+_FTI_BODY = """\
+<?xml version="1.0"?>
<object name="foo_fti" meta_type="Factory-based Type Information"
xmlns:i18n="http://xml.zope.org/namespaces/i18n">
<property name="title"></property>
@@ -46,14 +58,342 @@
</object>
"""
+_TYPESTOOL_BODY = """\
+<?xml version="1.0"?>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <property name="title"></property>
+ <object name="foo_type" meta_type="Factory-based Type Information"/>
+</object>
+"""
-class TypeInformationNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+_TI_LIST = ({
+ 'id': 'foo',
+ 'title': 'Foo',
+ 'description': 'Foo things',
+ 'i18n_domain': 'foo_domain',
+ 'content_meta_type': 'Foo Thing',
+ 'content_icon': 'foo.png',
+ 'product': 'CMFSetup',
+ 'factory': 'addFoo',
+ 'immediate_view': 'foo_view',
+ 'filter_content_types': False,
+ 'allowed_content_types': (),
+ 'allow_discussion': False,
+ 'global_allow': False,
+ 'aliases': {'(Default)': 'foo_view',
+ 'view': 'foo_view',
+ },
+ 'actions': ({'id': 'view',
+ 'name': 'View',
+ 'action': 'string:${object_url}/foo_view',
+ 'permissions': (View,),
+ },
+ {'id': 'edit',
+ 'name': 'Edit',
+ 'action': 'string:${object_url}/foo_edit_form',
+ 'permissions': (ModifyPortalContent,),
+ },
+ {'id': 'metadata',
+ 'name': 'Metadata',
+ 'action': 'string:${object_url}/metadata_edit_form',
+ 'permissions': (ModifyPortalContent,),
+ },
+ ),
+ }, {
+ 'id': 'bar',
+ 'title': 'Bar',
+ 'description': 'Bar things',
+ 'content_meta_type': 'Bar Thing',
+ 'content_icon': 'bar.png',
+ 'constructor_path': 'make_bar',
+ 'permission': 'Add portal content',
+ 'immediate_view': 'bar_view',
+ 'filter_content_types': True,
+ 'allowed_content_types': ('foo',),
+ 'allow_discussion': True,
+ 'global_allow': True,
+ 'aliases': {'(Default)': 'bar_view',
+ 'view': 'bar_view',
+ },
+ 'actions': ({'id': 'view',
+ 'name': 'View',
+ 'action': 'string:${object_url}/bar_view',
+ 'permissions': (View,),
+ },
+ {'id': 'edit',
+ 'name': 'Edit',
+ 'action': 'string:${object_url}/bar_edit_form',
+ 'permissions': (ModifyPortalContent,),
+ },
+ {'id': 'contents',
+ 'name': 'Contents',
+ 'action': 'string:${object_url}/folder_contents',
+ 'permissions': (AccessContentsInformation,),
+ },
+ {'id': 'metadata',
+ 'name': 'Metadata',
+ 'action': 'string:${object_url}/metadata_edit_form',
+ 'permissions': (ModifyPortalContent,),
+ },
+ ),
+ })
+_TI_LIST_WITH_FILENAME = []
+
+for original in _TI_LIST:
+ duplicate = original.copy()
+ duplicate['id'] = '%s object' % original['id']
+ _TI_LIST_WITH_FILENAME.append(duplicate)
+
+_EMPTY_TOOL_EXPORT = """\
+<?xml version="1.0"?>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <property name="title"/>
+</object>
+"""
+
+_EMPTY_TOOL_EXPORT_V1 = """\
+<?xml version="1.0"?>
+<types-tool>
+</types-tool>
+"""
+
+_NORMAL_TOOL_EXPORT = """\
+<?xml version="1.0"?>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <property name="title"/>
+ <object name="bar" meta_type="Scriptable Type Information"/>
+ <object name="foo" meta_type="Factory-based Type Information"/>
+</object>
+"""
+
+_NORMAL_TOOL_EXPORT_V1 = """\
+<?xml version="1.0"?>
+<types-tool>
+ <type id="bar" />
+ <type id="foo" />
+</types-tool>
+"""
+
+_FILENAME_EXPORT = """\
+<?xml version="1.0"?>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <property name="title"/>
+ <object name="bar object" meta_type="Scriptable Type Information"/>
+ <object name="foo object" meta_type="Factory-based Type Information"/>
+</object>
+"""
+
+_FILENAME_EXPORT_V1 = """\
+<?xml version="1.0"?>
+<types-tool>
+ <type id="bar object" filename="types/bar_object.xml" />
+ <type id="foo object" filename="types/foo_object.xml" />
+</types-tool>
+"""
+
+_UPDATE_TOOL_IMPORT = """\
+<?xml version="1.0"?>
+<types-tool>
+ <type id="foo"/>
+</types-tool>
+"""
+
+_FOO_OLD_EXPORT = """\
+<?xml version="1.0"?>
+<type-info
+ id="%s"
+ kind="Factory-based Type Information"
+ title="Foo"
+ meta_type="Foo Thing"
+ icon="foo.png"
+ product="CMFSetup"
+ factory="addFoo"
+ immediate_view="foo_view"
+ filter_content_types="False"
+ allow_discussion="False"
+ global_allow="False" >
+ <description>Foo things</description>
+ <aliases>
+ <alias from="(Default)" to="foo_view" />
+ <alias from="view" to="foo_view" />
+ </aliases>
+ <action
+ action_id="view"
+ title="View"
+ url_expr="string:${object_url}/foo_view"
+ condition_expr=""
+ category="object"
+ visible="True">
+ <permission>View</permission>
+ </action>
+ <action
+ action_id="edit"
+ title="Edit"
+ url_expr="string:${object_url}/foo_edit_form"
+ condition_expr=""
+ category="object"
+ visible="True">
+ <permission>Modify portal content</permission>
+ </action>
+ <action
+ action_id="metadata"
+ title="Metadata"
+ url_expr="string:${object_url}/metadata_edit_form"
+ condition_expr=""
+ category="object"
+ visible="True">
+ <permission>Modify portal content</permission>
+ </action>
+</type-info>
+"""
+
+_FOO_EXPORT = """\
+<?xml version="1.0"?>
+<object name="%s" meta_type="Factory-based Type Information"
+ i18n:domain="foo_domain" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="title" i18n:translate="">Foo</property>
+ <property name="description" i18n:translate="">Foo things</property>
+ <property name="content_icon">foo.png</property>
+ <property name="content_meta_type">Foo Thing</property>
+ <property name="product">CMFSetup</property>
+ <property name="factory">addFoo</property>
+ <property name="immediate_view">foo_view</property>
+ <property name="global_allow">False</property>
+ <property name="filter_content_types">False</property>
+ <property name="allowed_content_types"/>
+ <property name="allow_discussion">False</property>
+ <alias from="(Default)" to="foo_view"/>
+ <alias from="view" to="foo_view"/>
+ <action title="View" action_id="view" category="object" condition_expr=""
+ url_expr="string:${object_url}/foo_view" visible="True">
+ <permission value="View"/>
+ </action>
+ <action title="Edit" action_id="edit" category="object" condition_expr=""
+ url_expr="string:${object_url}/foo_edit_form" visible="True">
+ <permission value="Modify portal content"/>
+ </action>
+ <action title="Metadata" action_id="metadata" category="object"
+ condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
+ visible="True">
+ <permission value="Modify portal content"/>
+ </action>
+</object>
+"""
+
+_BAR_OLD_EXPORT = """\
+<?xml version="1.0"?>
+<type-info
+ id="%s"
+ kind="Scriptable Type Information"
+ title="Bar"
+ meta_type="Bar Thing"
+ icon="bar.png"
+ constructor_path="make_bar"
+ permission="Add portal content"
+ immediate_view="bar_view"
+ filter_content_types="True"
+ allow_discussion="True"
+ global_allow="True" >
+ <description>Bar things</description>
+ <allowed_content_type>foo</allowed_content_type>
+ <aliases>
+ <alias from="(Default)" to="bar_view" />
+ <alias from="view" to="bar_view" />
+ </aliases>
+ <action
+ action_id="view"
+ title="View"
+ url_expr="string:${object_url}/bar_view"
+ condition_expr=""
+ category="object"
+ visible="True">
+ <permission>View</permission>
+ </action>
+ <action
+ action_id="edit"
+ title="Edit"
+ url_expr="string:${object_url}/bar_edit_form"
+ condition_expr=""
+ category="object"
+ visible="True">
+ <permission>Modify portal content</permission>
+ </action>
+ <action
+ action_id="contents"
+ title="Contents"
+ url_expr="string:${object_url}/folder_contents"
+ condition_expr=""
+ category="object"
+ visible="True">
+ <permission>Access contents information</permission>
+ </action>
+ <action
+ action_id="metadata"
+ title="Metadata"
+ url_expr="string:${object_url}/metadata_edit_form"
+ condition_expr=""
+ category="object"
+ visible="True">
+ <permission>Modify portal content</permission>
+ </action>
+</type-info>
+"""
+
+_BAR_EXPORT = """\
+<?xml version="1.0"?>
+<object name="%s" meta_type="Scriptable Type Information"
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="title">Bar</property>
+ <property name="description">Bar things</property>
+ <property name="content_icon">bar.png</property>
+ <property name="content_meta_type">Bar Thing</property>
+ <property name="permission">Add portal content</property>
+ <property name="constructor_path">make_bar</property>
+ <property name="immediate_view">bar_view</property>
+ <property name="global_allow">True</property>
+ <property name="filter_content_types">True</property>
+ <property name="allowed_content_types">
+ <element value="foo"/>
+ </property>
+ <property name="allow_discussion">True</property>
+ <alias from="(Default)" to="bar_view"/>
+ <alias from="view" to="bar_view"/>
+ <action title="View" action_id="view" category="object" condition_expr=""
+ url_expr="string:${object_url}/bar_view" visible="True">
+ <permission value="View"/>
+ </action>
+ <action title="Edit" action_id="edit" category="object" condition_expr=""
+ url_expr="string:${object_url}/bar_edit_form" visible="True">
+ <permission value="Modify portal content"/>
+ </action>
+ <action title="Contents" action_id="contents" category="object"
+ condition_expr="" url_expr="string:${object_url}/folder_contents"
+ visible="True">
+ <permission value="Access contents information"/>
+ </action>
+ <action title="Metadata" action_id="metadata" category="object"
+ condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
+ visible="True">
+ <permission value="Modify portal content"/>
+ </action>
+</object>
+"""
+
+_UPDATE_FOO_IMPORT = """\
+<object name="foo">
+ <alias from="spam" to="eggs"/>
+</object>
+"""
+
+
+class TypeInformationXMLAdapterTests(BodyAdapterTestCase):
+
def _getTargetClass(self):
from Products.CMFCore.exportimport.typeinfo \
- import TypeInformationNodeAdapter
+ import TypeInformationXMLAdapter
- return TypeInformationNodeAdapter
+ return TypeInformationXMLAdapter
def _populate(self, obj):
obj.addAction('foo_action', 'Foo', 'string:${object_url}/foo',
@@ -77,22 +417,288 @@
self.assertEqual(obj._actions[0].condition.text, 'python:1')
def setUp(self):
+ import Products.CMFCore
from Products.CMFCore.TypesTool import FactoryTypeInformation
- import Products.CMFCore.exportimport
- import Products.Five
- from Products.Five import zcml
+ BodyAdapterTestCase.setUp(self)
+ zcml.load_config('configure.zcml', Products.CMFCore)
+
+ self._obj = FactoryTypeInformation('foo_fti')
+ self._BODY = _FTI_BODY
+
+
+class TypesToolXMLAdapterTests(BodyAdapterTestCase):
+
+ def _getTargetClass(self):
+ from Products.CMFCore.exportimport.typeinfo \
+ import TypesToolXMLAdapter
+
+ return TypesToolXMLAdapter
+
+ def _populate(self, obj):
+ from Products.CMFCore.TypesTool import FactoryTypeInformation
+
+ obj._setObject('foo_type', FactoryTypeInformation('foo_type'))
+
+ def setUp(self):
+ import Products.CMFCore
+ from Products.CMFCore.TypesTool import TypesTool
+
+ BodyAdapterTestCase.setUp(self)
+ zcml.load_config('configure.zcml', Products.CMFCore)
+
+ self._obj = TypesTool()
+ self._BODY = _TYPESTOOL_BODY
+
+
+class _TypeInfoSetup(PlacelessSetup, BaseRegistryTests):
+
+ def _initSite(self, foo=0):
+ self.root.site = Folder(id='site')
+ site = self.root.site
+ ttool = site.portal_types = TypesTool()
+
+ if foo == 1:
+ fti = _TI_LIST[0].copy()
+ ttool._setObject(fti['id'], FactoryTypeInformation(**fti))
+ sti = _TI_LIST[1].copy()
+ ttool._setObject(sti['id'], ScriptableTypeInformation(**sti))
+ elif foo == 2:
+ fti = _TI_LIST_WITH_FILENAME[0].copy()
+ ttool._setObject(fti['id'], FactoryTypeInformation(**fti))
+ sti = _TI_LIST_WITH_FILENAME[1].copy()
+ ttool._setObject(sti['id'], ScriptableTypeInformation(**sti))
+
+ return site
+
+ def setUp(self):
PlacelessSetup.setUp(self)
+ BaseRegistryTests.setUp(self)
zcml.load_config('meta.zcml', Products.Five)
- zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
+ zcml.load_config('permissions.zcml', Products.Five)
+ zcml.load_config('configure.zcml', Products.CMFCore)
- self._obj = FactoryTypeInformation('foo_fti')
- self._XML = _FTI_XML
+ def tearDown(self):
+ BaseRegistryTests.tearDown(self)
+ PlacelessSetup.tearDown(self)
+class exportTypesToolTests(_TypeInfoSetup):
+
+ def test_empty(self):
+ from Products.CMFCore.exportimport.typeinfo import exportTypesTool
+
+ site = self._initSite()
+ context = DummyExportContext(site)
+ exportTypesTool(context)
+
+ self.assertEqual(len(context._wrote), 1)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'typestool.xml')
+ self._compareDOM(text, _EMPTY_TOOL_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_normal(self):
+ from Products.CMFCore.exportimport.typeinfo import exportTypesTool
+
+ site = self._initSite(1)
+ context = DummyExportContext(site)
+ exportTypesTool(context)
+
+ self.assertEqual(len(context._wrote), 3)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'typestool.xml')
+ self._compareDOM(text, _NORMAL_TOOL_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+
+ filename, text, content_type = context._wrote[2]
+ self.assertEqual(filename, 'types/bar.xml')
+ self._compareDOM(text, _BAR_EXPORT % 'bar')
+ self.assertEqual(content_type, 'text/xml')
+
+ filename, text, content_type = context._wrote[1]
+ self.assertEqual(filename, 'types/foo.xml')
+ self._compareDOM(text, _FOO_EXPORT % 'foo')
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_with_filenames(self):
+ from Products.CMFCore.exportimport.typeinfo import exportTypesTool
+
+ site = self._initSite(2)
+ context = DummyExportContext(site)
+ exportTypesTool(context)
+
+ self.assertEqual(len(context._wrote), 3)
+ filename, text, content_type = context._wrote[0]
+ self.assertEqual(filename, 'typestool.xml')
+ self._compareDOM(text, _FILENAME_EXPORT)
+ self.assertEqual(content_type, 'text/xml')
+ filename, text, content_type = context._wrote[2]
+ self.assertEqual(filename, 'types/bar_object.xml')
+ self._compareDOM(text, _BAR_EXPORT % 'bar object')
+ self.assertEqual(content_type, 'text/xml')
+ filename, text, content_type = context._wrote[1]
+ self.assertEqual(filename, 'types/foo_object.xml')
+ self._compareDOM(text, _FOO_EXPORT % 'foo object')
+ self.assertEqual(content_type, 'text/xml')
+
+
+class importTypesToolTests(_TypeInfoSetup):
+
+ _EMPTY_TOOL_EXPORT = _EMPTY_TOOL_EXPORT
+ _FILENAME_EXPORT = _FILENAME_EXPORT
+ _NORMAL_TOOL_EXPORT = _NORMAL_TOOL_EXPORT
+
+ def test_empty_default_purge(self):
+ from Products.CMFCore.exportimport.typeinfo import importTypesTool
+
+ site = self._initSite(1)
+ tool = site.portal_types
+
+ self.assertEqual(len(tool.objectIds()), 2)
+
+ context = DummyImportContext(site)
+ context._files['typestool.xml'] = self._EMPTY_TOOL_EXPORT
+ importTypesTool(context)
+
+ self.assertEqual(len(tool.objectIds()), 0)
+
+ def test_empty_explicit_purge(self):
+ from Products.CMFCore.exportimport.typeinfo import importTypesTool
+
+ site = self._initSite(1)
+ tool = site.portal_types
+
+ self.assertEqual(len(tool.objectIds()), 2)
+
+ context = DummyImportContext(site, True)
+ context._files['typestool.xml'] = self._EMPTY_TOOL_EXPORT
+ importTypesTool(context)
+
+ self.assertEqual(len(tool.objectIds()), 0)
+
+ def test_empty_skip_purge(self):
+ from Products.CMFCore.exportimport.typeinfo import importTypesTool
+
+ site = self._initSite(1)
+ tool = site.portal_types
+
+ self.assertEqual(len(tool.objectIds()), 2)
+
+ context = DummyImportContext(site, False)
+ context._files['typestool.xml'] = self._EMPTY_TOOL_EXPORT
+ importTypesTool(context)
+
+ self.assertEqual(len(tool.objectIds()), 2)
+
+ def test_normal(self):
+ from Products.CMFCore.exportimport.typeinfo import importTypesTool
+
+ site = self._initSite()
+ tool = site.portal_types
+
+ self.assertEqual(len(tool.objectIds()), 0)
+
+ context = DummyImportContext(site)
+ context._files['typestool.xml'] = self._NORMAL_TOOL_EXPORT
+ context._files['types/foo.xml'] = _FOO_EXPORT % 'foo'
+ context._files['types/bar.xml'] = _BAR_EXPORT % 'bar'
+ importTypesTool(context)
+
+ self.assertEqual(len(tool.objectIds()), 2)
+ self.failUnless('foo' in tool.objectIds())
+ self.failUnless('bar' in tool.objectIds())
+
+ def test_old_xml(self):
+ from Products.CMFCore.exportimport.typeinfo import exportTypesTool
+ from Products.CMFCore.exportimport.typeinfo import importTypesTool
+
+ site = self._initSite()
+ tool = site.portal_types
+
+ self.assertEqual(len(tool.objectIds()), 0)
+
+ context = DummyImportContext(site)
+ context._files['typestool.xml'] = self._NORMAL_TOOL_EXPORT
+ context._files['types/foo.xml'] = _FOO_OLD_EXPORT % 'foo'
+ context._files['types/bar.xml'] = _BAR_OLD_EXPORT % 'bar'
+ importTypesTool(context)
+
+ self.assertEqual(len(tool.objectIds()), 2)
+ self.failUnless('foo' in tool.objectIds())
+ self.failUnless('bar' in tool.objectIds())
+
+ context = DummyExportContext(site)
+ exportTypesTool(context)
+
+ filename, text, content_type = context._wrote[1]
+ self.assertEqual(filename, 'types/bar.xml')
+ self._compareDOM(text, _BAR_EXPORT % 'bar')
+ self.assertEqual(content_type, 'text/xml')
+
+ def test_with_filenames(self):
+ from Products.CMFCore.exportimport.typeinfo import importTypesTool
+
+ site = self._initSite()
+ tool = site.portal_types
+
+ self.assertEqual(len(tool.objectIds()), 0)
+
+ context = DummyImportContext(site)
+ context._files['typestool.xml'] = self._FILENAME_EXPORT
+ context._files['types/foo_object.xml'] = _FOO_EXPORT % 'foo object'
+ context._files['types/bar_object.xml'] = _BAR_EXPORT % 'bar object'
+ importTypesTool(context)
+
+ self.assertEqual(len(tool.objectIds()), 2)
+ self.failUnless('foo object' in tool.objectIds())
+ self.failUnless('bar object' in tool.objectIds())
+
+ def test_normal_update(self):
+ from Products.CMFCore.exportimport.typeinfo import importTypesTool
+
+ site = self._initSite()
+ tool = site.portal_types
+
+ context = DummyImportContext(site)
+ context._files['typestool.xml'] = self._NORMAL_TOOL_EXPORT
+ context._files['types/foo.xml'] = _FOO_EXPORT % 'foo'
+ context._files['types/bar.xml'] = _BAR_EXPORT % 'bar'
+ importTypesTool(context)
+
+ self.assertEqual(tool.foo.title, 'Foo')
+ self.assertEqual(tool.foo.content_meta_type, 'Foo Thing')
+ self.assertEqual(tool.foo.content_icon, 'foo.png')
+ self.assertEqual(tool.foo.immediate_view, 'foo_view')
+ self.assertEqual(tool.foo._aliases,
+ {'(Default)': 'foo_view', 'view': 'foo_view'})
+
+ context = DummyImportContext(site, False)
+ context._files['typestool.xml'] = _UPDATE_TOOL_IMPORT
+ context._files['types/foo.xml'] = _UPDATE_FOO_IMPORT
+ importTypesTool(context)
+
+ self.assertEqual(tool.foo.title, 'Foo')
+ self.assertEqual(tool.foo.content_meta_type, 'Foo Thing')
+ self.assertEqual(tool.foo.content_icon, 'foo.png')
+ self.assertEqual(tool.foo.immediate_view, 'foo_view')
+ self.assertEqual(tool.foo._aliases,
+ {'(Default)': 'foo_view', 'view': 'foo_view', 'spam': 'eggs'})
+
+class importTypesToolV1Tests(importTypesToolTests):
+
+ _EMPTY_TOOL_EXPORT = _EMPTY_TOOL_EXPORT_V1
+ _FILENAME_EXPORT = _FILENAME_EXPORT_V1
+ _NORMAL_TOOL_EXPORT = _NORMAL_TOOL_EXPORT_V1
+
+
def test_suite():
return unittest.TestSuite((
- unittest.makeSuite(TypeInformationNodeAdapterTests),
+ unittest.makeSuite(TypeInformationXMLAdapterTests),
+ unittest.makeSuite(TypesToolXMLAdapterTests),
+ unittest.makeSuite(exportTypesToolTests),
+ unittest.makeSuite(importTypesToolTests),
+ unittest.makeSuite(importTypesToolV1Tests),
))
if __name__ == '__main__':
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/test_workflow.py (from rev 40492, CMF/trunk/CMFCore/exportimport/tests/test_workflow.py)
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/three (from rev 40492, CMF/trunk/CMFCore/exportimport/tests/three)
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/tests/two (from rev 40492, CMF/trunk/CMFCore/exportimport/tests/two)
Modified: CMF/branches/tseaver-viewification/CMFCore/exportimport/typeinfo.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/exportimport/typeinfo.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/exportimport/typeinfo.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -10,26 +10,41 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Types tool node adapters.
+"""Types tool xml adapters and setup handlers.
$Id$
"""
+from xml.dom.minidom import parseString
+
+import Products
+from zope.app import zapi
+
+from Products.GenericSetup.interfaces import IBody
from Products.GenericSetup.interfaces import PURGE
+from Products.GenericSetup.utils import exportObjects
from Products.GenericSetup.utils import I18NURI
-from Products.GenericSetup.utils import NodeAdapterBase
+from Products.GenericSetup.utils import importObjects
+from Products.GenericSetup.utils import ObjectManagerHelpers
from Products.GenericSetup.utils import PropertyManagerHelpers
+from Products.GenericSetup.utils import XMLAdapterBase
from Products.CMFCore.interfaces import ITypeInformation
+from Products.CMFCore.interfaces import ITypesTool
+from Products.CMFCore.utils import getToolByName
+_FILENAME = 'typestool.xml'
-class TypeInformationNodeAdapter(NodeAdapterBase, PropertyManagerHelpers):
- """Node im- and exporter for TypeInformation.
+class TypeInformationXMLAdapter(XMLAdapterBase, PropertyManagerHelpers):
+
+ """XML im- and exporter for TypeInformation.
"""
__used_for__ = ITypeInformation
+ _LOGGER_ID = 'types'
+
def exportNode(self, doc):
"""Export the object as a DOM node.
"""
@@ -39,6 +54,8 @@
node.appendChild(self._extractProperties())
node.appendChild(self._extractAliases())
node.appendChild(self._extractActions())
+
+ self._logger.info('%r type info exported.' % self.context.getId())
return node
def importNode(self, node, mode=PURGE):
@@ -54,6 +71,8 @@
self._initAliases(node, mode)
self._initActions(node, mode)
+ self._logger.info('%r type info imported.' % self.context.getId())
+
def _extractAliases(self):
fragment = self._doc.createDocumentFragment()
aliases = self.context.getMethodAliases().items()
@@ -176,3 +195,103 @@
permission = node.getAttribute('permission')
obj._updateProperty('constructor_path', constructor_path)
obj._updateProperty('permission', permission)
+
+
+class TypesToolXMLAdapter(XMLAdapterBase, ObjectManagerHelpers,
+ PropertyManagerHelpers):
+
+ """XML im- and exporter for TypesTool.
+ """
+
+ __used_for__ = ITypesTool
+
+ _LOGGER_ID = 'types'
+
+ def exportNode(self, doc):
+ """Export the object as a DOM node.
+ """
+ self._doc = doc
+ node = self._getObjectNode('object')
+ node.appendChild(self._extractProperties())
+ node.appendChild(self._extractObjects())
+
+ self._logger.info('Types tool exported.')
+ return node
+
+ def importNode(self, node, mode=PURGE):
+ """Import the object from the DOM node.
+ """
+ if mode == PURGE:
+ self._purgeProperties()
+ self._purgeObjects()
+
+ self._initProperties(node, mode)
+ self._initObjects(node, mode)
+ self._initBBBObjects(node, mode)
+
+ self._logger.info('Types tool imported.')
+
+ def _initBBBObjects(self, node, mode):
+ for child in node.childNodes:
+ if child.nodeName != 'type':
+ continue
+ parent = self.context
+
+ obj_id = str(child.getAttribute('id'))
+ if obj_id not in parent.objectIds():
+ filename = str(child.getAttribute('filename'))
+ if not filename:
+ filename = 'types/%s.xml' % obj_id.replace(' ', '_')
+ body = self.environ.readDataFile(filename)
+ if body is None:
+ break
+ root = parseString(body).documentElement
+ if root.getAttribute('name') != obj_id:
+ if root.getAttribute('id') != obj_id:
+ break
+ meta_type = str(root.getAttribute('kind'))
+ if not meta_type:
+ meta_type = str(root.getAttribute('meta_type'))
+ for mt_info in Products.meta_types:
+ if mt_info['name'] == meta_type:
+ parent._setObject(obj_id, mt_info['instance'](obj_id))
+ break
+
+
+def importTypesTool(context):
+ """Import types tool and content types from XML files.
+ """
+ site = context.getSite()
+ logger = context.getLogger('types')
+ tool = getToolByName(site, 'portal_types')
+
+ body = context.readDataFile(_FILENAME)
+ if body is None:
+ logger.info('Nothing to import.')
+ return
+
+ importer = zapi.queryMultiAdapter((tool, context), IBody)
+ if importer is None:
+ logger.warning('Import adapter misssing.')
+ return
+
+ importer.body = body
+ importObjects(tool, 'types', context)
+
+def exportTypesTool(context):
+ """Export types tool content types as a set of XML files.
+ """
+ site = context.getSite()
+ logger = context.getLogger('types')
+ tool = getToolByName(site, 'portal_types', None)
+ if tool is None:
+ logger.info('Nothing to export.')
+ return
+
+ exporter = zapi.queryMultiAdapter((tool, context), IBody)
+ if exporter is None:
+ logger.warning('Export adapter misssing.')
+ return
+
+ context.writeDataFile(_FILENAME, exporter.body, exporter.mime_type)
+ exportObjects(tool, 'types', context)
Copied: CMF/branches/tseaver-viewification/CMFCore/exportimport/workflow.py (from rev 40492, CMF/trunk/CMFCore/exportimport/workflow.py)
Modified: CMF/branches/tseaver-viewification/CMFCore/interfaces/_tools.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/interfaces/_tools.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/interfaces/_tools.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -911,14 +911,17 @@
o Must be set to 'portal_metadata'.
""")
+ id = Attribute('id', 'Must be set to "portal_metadata"')
+
#
- # Site-wide queries.
+ # Site-wide queries, specific to Dublin Core metadata.
#
def getFullName(userid):
- """ Convert an internal userid to a "formal" name, if possible
+ """ Convert an internal userid to a "formal" name.
+
+ o Convert only if possible, perhaps using the 'portal_membership'
+ tool; otherwise, return 'userid'.
- o 'userid' is the ID of the user within the user folder.
-
o Used to map userid's for Creator, Contributor DCMI queries.
"""
@@ -927,67 +930,100 @@
"""
#
- # Content-specific queries.
+ # Content-specific queries, for Dublin Core metadata.
#
- def listAllowedSubjects(content=None):
+ def listAllowedSubjects(content=None, content_type=None):
""" List the allowed values of the 'Subject' DCMI element.
- o If 'content' is not None, return only values appropriate for
- content's type; otherwise, return "default" values.
+ o 'Subject' elements should be keywords categorizing their resource.
- o 'Subject' elements should be keywords categorizing their resource.
+ o Return only values appropriate for content's type, or all values if
+ both 'content' and 'content_type' are None.
"""
- def listAllowedFormats(content=None):
+ def listAllowedFormats(content=None, content_type=None):
""" List the allowed values of the 'Format' DCMI element.
- o If 'content' is not None, return only values appropriate for
- content's type; otherwise, return "default" values.
+ o These items should be usable as HTTP 'Content-type' values.
- o 'Format' elements should be usable as HTTP 'Content-type' values.
+ o Return only values appropriate for content's type, or all values if
+ both 'content' and 'content_type' are None.
"""
- def listAllowedLanguages(content=None):
+ def listAllowedLanguages(content=None, content_type=None):
""" List the allowed values of the 'Language' DCMI element.
- o If 'content' is not None, return only values appropriate for
- content's type; otherwise, return "default" values.
-
o 'Language' element values should be suitable for generating
HTTP headers.
+
+ o Return only values appropriate for content's type, or all values if
+ both 'content' and 'content_type' are None.
"""
- def listAllowedRights(content=None):
+ def listAllowedRights(content=None, content_type=None):
""" List the allowed values of the 'Rights' DCMI element.
- o If 'content' is not None, return only values appropriate for
- content's type; otherwise, return "default" values.
+ o The 'Rights' element describes copyright or other IP declarations
+ pertaining to a resource.
- o The 'Rights' element describes copyright or other IP
- declarations pertaining to a resource.
+ o Return only values appropriate for content's type, or all values if
+ both 'content' and 'content_type' are None.
"""
#
- # Validation policy hooks.
+ # Content-specific queries, for generic metadata.
#
- def setInitialMetadata(content):
- """ Set default initial values for content metatdata.
+ def listAllowedVocabulary( schema
+ , element
+ , content=None
+ , content_type=None
+ ):
+ """ List allowed values for a given schema element and content object.
+
+ o List possible keywords if both 'content' and 'content_type' are None.
"""
- def validateMetadata(content):
- """ Enforce portal-wide policies about DCMI elements.
+ #
+ # Schema manipulation
+ #
+ def listSchemas():
+ """ Return a list of (id, schema) tuples enumerating our schema.
+ """
- o Such policy may, e.g., require non-empty title/description, etc.
+ def addSchema( schema_id ):
+ """ Create a new schema with the given ID.
- o Called by the CMF immediately before saving changes to the
- metadata of an object.
+ o Return the newly-created schema object.
- o XXX: Note that the default skins / edit methods do *not*
- call this method; the choice of when to apply the validation
- is policy.
+ o Raise KeyError if such a schema already exists.
"""
+ def removeSchema( schema_id ):
+ """ Remove an existing schema with the given ID.
+ o Raise KeyError if no such schema exists.
+ """
+
+ #
+ # Validation policy hooks.
+ #
+ def setInitialMetadata(content):
+ """ Set initial values for content metatdata.
+
+ o Supply any site-specific defaults.
+ """
+
+ def validateMetadata(content):
+ """ Enforce portal-wide policies about metadata.
+
+ o E.g., policies may require non-empty title/description, etc.
+
+ o This method may be called by view / workflow code at "appropriate"
+ times, such as immediately before saving changes to the metadata of
+ an object.
+ """
+
+
#
# Site Properties tool interface
#
@@ -1133,6 +1169,12 @@
#
# Skins tool interfaces
#
+class IDirectoryView(Interface):
+
+ """ Directory views mount filesystem directories.
+ """
+
+
class ISkinsContainer(Interface):
""" An object that provides skins.
Modified: CMF/branches/tseaver-viewification/CMFCore/tests/base/testcase.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/tests/base/testcase.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/tests/base/testcase.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -30,6 +30,28 @@
from zope.app.tests.placelesssetup import setUp as placelessSetUp
from zope.app.tests.placelesssetup import tearDown as placelessTearDown
+_TRAVERSE_ZCML = """
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:five="http://namespaces.zope.org/five"
+ >
+
+ <adapter
+ for="*"
+ factory=".traversable.FiveTraversable"
+ provides="zope.app.traversing.interfaces.ITraversable"
+ />
+
+ <adapter
+ for="*"
+ factory="zope.app.traversing.adapters.Traverser"
+ provides="zope.app.traversing.interfaces.ITraverser"
+ />
+
+</configure>
+"""
+
+
class LogInterceptor:
_old_log_write = None
Modified: CMF/branches/tseaver-viewification/CMFCore/tests/test_ActionInformation.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/tests/test_ActionInformation.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/tests/test_ActionInformation.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,12 +15,12 @@
$Id$
"""
-from unittest import TestCase, TestSuite, makeSuite, main
+import unittest
import Testing
-import Zope2
-Zope2.startup()
+import Products.Five
from OFS.Folder import manage_addFolder
+from Products.Five import zcml
from Products.PythonScripts.PythonScript import manage_addPythonScript
from Products.CMFCore.Expression import createExprContext
@@ -28,11 +28,13 @@
from Products.CMFCore.tests.base.dummy import DummyContent
from Products.CMFCore.tests.base.dummy import DummySite
from Products.CMFCore.tests.base.dummy import DummyTool as DummyMembershipTool
+from Products.CMFCore.tests.base.testcase import _TRAVERSE_ZCML
+from Products.CMFCore.tests.base.testcase import PlacelessSetup
from Products.CMFCore.tests.base.testcase import SecurityTest
from Products.CMFCore.tests.base.testcase import TransactionalTest
-class ActionCategoryTests(TestCase):
+class ActionCategoryTests(unittest.TestCase):
def _makeOne(self, *args, **kw):
from Products.CMFCore.ActionInformation import ActionCategory
@@ -57,7 +59,7 @@
self.assertEqual( ac.listActions(), (baz,) )
-class ActionTests(TestCase):
+class ActionTests(unittest.TestCase):
def _makeOne(self, *args, **kw):
from Products.CMFCore.ActionInformation import Action
@@ -96,7 +98,7 @@
self.assertEqual( a.getInfoData(), WANTED )
-class ActionInfoTests(TestCase):
+class ActionInfoTests(unittest.TestCase):
def _makeOne(self, *args, **kw):
from Products.CMFCore.ActionInformation import ActionInfo
@@ -287,12 +289,17 @@
self.assertEqual( ai2['allowed'], True )
-class ActionInformationTests(TransactionalTest):
+class ActionInformationTests(PlacelessSetup, TransactionalTest):
- def setUp( self ):
+ def setUp(self):
+ import Products.CMFCore
+ PlacelessSetup.setUp(self)
+ TransactionalTest.setUp(self)
+ zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
+ zcml.load_config('configure.zcml', Products.CMFCore)
+ zcml.load_string(_TRAVERSE_ZCML)
- TransactionalTest.setUp( self )
-
root = self.root
root._setObject('portal', DummyContent('portal', 'url_portal'))
portal = self.portal = root.portal
@@ -300,6 +307,10 @@
self.folder = DummyContent('foo', 'url_foo')
self.object = DummyContent('bar', 'url_bar')
+ def tearDown(self):
+ TransactionalTest.tearDown(self)
+ PlacelessSetup.tearDown(self)
+
def _makeOne(self, *args, **kw):
from Products.CMFCore.ActionInformation import ActionInformation
@@ -416,13 +427,13 @@
def test_suite():
- return TestSuite((
- makeSuite(ActionCategoryTests),
- makeSuite(ActionTests),
- makeSuite(ActionInfoTests),
- makeSuite(ActionInfoSecurityTests),
- makeSuite(ActionInformationTests),
+ return unittest.TestSuite((
+ unittest.makeSuite(ActionCategoryTests),
+ unittest.makeSuite(ActionTests),
+ unittest.makeSuite(ActionInfoTests),
+ unittest.makeSuite(ActionInfoSecurityTests),
+ unittest.makeSuite(ActionInformationTests),
))
if __name__ == '__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Modified: CMF/branches/tseaver-viewification/CMFCore/tests/test_CachingPolicyManager.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/tests/test_CachingPolicyManager.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/tests/test_CachingPolicyManager.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -21,20 +21,22 @@
import base64
import os
+import Products.Five
from AccessControl.SecurityManagement import newSecurityManager
from App.Common import rfc1123_date
from DateTime.DateTime import DateTime
+from Products.Five import zcml
from Products.CMFCore.FSPageTemplate import FSPageTemplate
from Products.CMFCore.tests.base.dummy import DummyContent
from Products.CMFCore.tests.base.dummy import DummySite
from Products.CMFCore.tests.base.dummy import DummyTool
from Products.CMFCore.tests.base.dummy import DummyUserFolder
+from Products.CMFCore.tests.base.testcase import _TRAVERSE_ZCML
from Products.CMFCore.tests.base.testcase import FSDVTest
+from Products.CMFCore.tests.base.testcase import PlacelessSetup
from Products.CMFCore.tests.base.testcase import RequestTest
-from Products.CMFCore.tests.test_FSPageTemplate import FSPTMaker
-
ACCLARK = DateTime( '2001/01/01' )
portal_owner = 'portal_owner'
@@ -600,13 +602,18 @@
self.assertEqual( headers[2][1] , 'max-age=86400' )
-class CachingPolicyManager304Tests(RequestTest, FSDVTest):
+class CachingPolicyManager304Tests(PlacelessSetup, RequestTest, FSDVTest):
def setUp(self):
from Products.CMFCore import CachingPolicyManager
+ PlacelessSetup.setUp(self)
RequestTest.setUp(self)
FSDVTest.setUp(self)
+ zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
+ zcml.load_config('configure.zcml', Products.CMFCore)
+ zcml.load_string(_TRAVERSE_ZCML)
now = DateTime()
@@ -681,6 +688,7 @@
def tearDown(self):
RequestTest.tearDown(self)
FSDVTest.tearDown(self)
+ PlacelessSetup.tearDown(self)
def _cleanup(self):
# Clean up request and response
Modified: CMF/branches/tseaver-viewification/CMFCore/tests/test_TypesTool.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/tests/test_TypesTool.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/tests/test_TypesTool.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,18 +15,18 @@
$Id$
"""
-from unittest import TestCase, TestSuite, makeSuite, main
+import unittest
import Testing
-import Zope2
-Zope2.startup()
+import Products
from AccessControl import Unauthorized
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.SecurityManager import setSecurityPolicy
from Acquisition import aq_base
+from Products.Five import zcml
from Products.PythonScripts.PythonScript import PythonScript
-from Products.PythonScripts.standard import url_quote
+from Products.PythonScripts.standard import html_quote
from webdav.NullResource import NullResource
from Products.CMFCore.ActionInformation import ActionInformation
@@ -38,6 +38,8 @@
from Products.CMFCore.tests.base.dummy import DummyUserFolder
from Products.CMFCore.tests.base.security import OmnipotentUser
from Products.CMFCore.tests.base.security import UserWithRoles
+from Products.CMFCore.tests.base.testcase import _TRAVERSE_ZCML
+from Products.CMFCore.tests.base.testcase import PlacelessSetup
from Products.CMFCore.tests.base.testcase import SecurityTest
from Products.CMFCore.tests.base.testcase import WarningInterceptor
from Products.CMFCore.tests.base.tidata import FTIDATA_ACTIONS
@@ -52,7 +54,7 @@
from Products.CMFCore.tests.base.tidata import STI_SCRIPT
-class TypesToolTests(SecurityTest, WarningInterceptor):
+class TypesToolTests(PlacelessSetup, SecurityTest, WarningInterceptor):
def _makeOne(self):
from Products.CMFCore.TypesTool import TypesTool
@@ -62,7 +64,13 @@
def setUp( self ):
from Products.CMFCore.TypesTool import FactoryTypeInformation as FTI
+ PlacelessSetup.setUp(self)
SecurityTest.setUp(self)
+ zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
+ zcml.load_config('configure.zcml', Products.Five.browser)
+ zcml.load_config('configure.zcml', Products.CMFCore)
+ zcml.load_string(_TRAVERSE_ZCML)
self.site = DummySite('site').__of__(self.root)
self.acl_users = self.site._setObject( 'acl_users', DummyUserFolder() )
@@ -72,6 +80,7 @@
def tearDown(self):
SecurityTest.tearDown(self)
+ PlacelessSetup.tearDown(self)
self._free_warning_output()
def test_z2interfaces(self):
@@ -105,9 +114,9 @@
# so we check for that. If we've got it, something is b0rked.
for factype in tool.all_meta_types():
meta_types[factype['name']]=1
- # The url_quote below is necessary 'cos of the one in
+ # The html_quote below is necessary 'cos of the one in
# main.dtml. Could be removed once that is gone.
- act = tool.unrestrictedTraverse(url_quote(factype['action']))
+ act = tool.unrestrictedTraverse(html_quote(factype['action']))
self.failIf(type(aq_base(act)) is NullResource)
# Check the ones we're expecting are there
@@ -145,7 +154,7 @@
'Unauthorized raised' )
-class TypeInfoTests(TestCase):
+class TypeInfoTests(unittest.TestCase):
def _makeTypesTool(self):
from Products.CMFCore.TypesTool import TypesTool
@@ -466,7 +475,7 @@
self.assertEqual( ti.constructor_path, 'foo_add' )
-class FTIConstructionTests(TestCase):
+class FTIConstructionTests(unittest.TestCase):
def setUp( self ):
noSecurityManager()
@@ -513,7 +522,7 @@
self.failIf( ti.isConstructionAllowed( folder ) )
-class FTIConstructionTests_w_Roles(TestCase):
+class FTIConstructionTests_w_Roles(unittest.TestCase):
def tearDown( self ):
noSecurityManager()
@@ -616,13 +625,13 @@
def test_suite():
- return TestSuite((
- makeSuite(TypesToolTests),
- makeSuite(FTIDataTests),
- makeSuite(STIDataTests),
- makeSuite(FTIConstructionTests),
- makeSuite(FTIConstructionTests_w_Roles),
+ return unittest.TestSuite((
+ unittest.makeSuite(TypesToolTests),
+ unittest.makeSuite(FTIDataTests),
+ unittest.makeSuite(STIDataTests),
+ unittest.makeSuite(FTIConstructionTests),
+ unittest.makeSuite(FTIConstructionTests_w_Roles),
))
if __name__ == '__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Modified: CMF/branches/tseaver-viewification/CMFCore/tests/test_WorkflowTool.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/tests/test_WorkflowTool.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/tests/test_WorkflowTool.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -20,9 +20,7 @@
from OFS.SimpleItem import SimpleItem
-from Products.CMFCore.tests.base.testcase import WarningInterceptor
-
class Dummy( SimpleItem ):
def __init__( self, id ):
@@ -131,24 +129,15 @@
return None
-class WorkflowToolTests(unittest.TestCase, WarningInterceptor):
+class WorkflowToolTests(unittest.TestCase):
- def setUp( self ):
- from Products.CMFCore.WorkflowTool import addWorkflowFactory
- addWorkflowFactory( DummyWorkflow )
-
- def tearDown( self ):
- from Products.CMFCore.WorkflowTool import _removeWorkflowFactory
- _removeWorkflowFactory( DummyWorkflow )
- self._free_warning_output()
-
def _makeOne( self, workflow_ids=() ):
from Products.CMFCore.WorkflowTool import WorkflowTool
tool = WorkflowTool()
for workflow_id in workflow_ids:
- tool.manage_addWorkflow( DummyWorkflow.meta_type, workflow_id )
+ tool._setObject(workflow_id, DummyWorkflow(workflow_id))
return tool
Deleted: CMF/branches/tseaver-viewification/CMFCore/www/addTypeInfo.zpt
===================================================================
--- CMF/branches/tseaver-viewification/CMFCore/www/addTypeInfo.zpt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFCore/www/addTypeInfo.zpt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,47 +0,0 @@
-<h1 tal:replace="structure context/manage_page_header">PAGE HEADER</h1>
-<h2 tal:define="form_title string:Add ${options/add_meta_type}"
- tal:replace="structure context/manage_form_title">FORM TITLE</h2>
-
-<p class="form-help">A type information object defines a portal type.</p>
-
-<form action="manage_addTypeInfo" method="post">
-<input type="hidden" name="add_meta_type" value=""
- tal:attributes="value options/add_meta_type" />
-<table cellspacing="0" cellpadding="2" border="0">
- <tr>
- <td>
- <div class="form-label">ID</div>
- </td>
- <td>
- <input type="text" name="id" size="40" />
- </td>
- </tr>
- <tr tal:condition="options/profiles">
- <td>
- <div class="form-label">Presettings</div>
- </td>
- <td>
- <select name="settings_id">
- <option value="" selected="selected">(None)</option>
- <optgroup label="PROFILE_TITLE"
- tal:repeat="profile options/profiles"
- tal:attributes="label profile/title">
- <option value="SETTINGS_ID"
- tal:repeat="type_id profile/type_ids"
- tal:attributes="value string:${profile/id}/${type_id}"
- tal:content="type_id">TYPE ID</option></optgroup>
- </select>
- </td>
- </tr>
- <tr>
- <td>
-
- </td>
- <td>
- <input class="form-element" type="submit" name="submit" value="Add" />
- </td>
- </tr>
-</table>
-</form>
-
-<h1 tal:replace="structure context/manage_page_footer">PAGE FOOTER</h1>
Modified: CMF/branches/tseaver-viewification/CMFDefault/DEPENDENCIES.txt
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/DEPENDENCIES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/DEPENDENCIES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,4 +1,4 @@
-Zope >= 2.8.2
+Zope >= 2.8.5
Five >= 1.2
CMFCore
GenericSetup
Modified: CMF/branches/tseaver-viewification/CMFDefault/MetadataTool.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/MetadataTool.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/MetadataTool.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -20,6 +20,7 @@
from Globals import DTMLFile
from Globals import InitializeClass
from Globals import PersistentMapping
+from OFS.Folder import Folder
from OFS.SimpleItem import SimpleItem
from zope.interface import implements
@@ -37,10 +38,8 @@
class MetadataElementPolicy( SimpleItem ):
-
+ """ Represent a type-specific policy about a particular metadata element.
"""
- Represent a type-specific policy about a particular DCMI element.
- """
security = ClassSecurityInfo()
#
@@ -77,62 +76,47 @@
#
security.declareProtected(View , 'isMultiValued')
def isMultiValued( self ):
+ """ Can this element hold multiple values?
"""
- Can this element hold multiple values?
- """
return self.is_multi_valued
security.declareProtected(View , 'isRequired')
def isRequired( self ):
+ """ Must this element be supplied?
"""
- Must this element be supplied?
- """
return self.is_required
security.declareProtected(View , 'supplyDefault')
def supplyDefault( self ):
+ """ Should the tool supply a default?
"""
- Should the tool supply a default?
- """
return self.supply_default
security.declareProtected(View , 'defaultValue')
def defaultValue( self ):
+ """ If so, what is the default?
"""
- If so, what is the default?
- """
return self.default_value
security.declareProtected(View , 'enforceVocabulary')
def enforceVocabulary( self ):
+ """ Should the tool enforce the policy's vocabulary?
"""
- """
return self.enforce_vocabulary
security.declareProtected(View , 'allowedVocabulary')
def allowedVocabulary( self ):
+ """ What are the allowed values?
"""
- """
return self.allowed_vocabulary
InitializeClass( MetadataElementPolicy )
-DEFAULT_ELEMENT_SPECS = ( ( 'Title', 0 )
- , ( 'Description', 0 )
- , ( 'Subject', 1 )
- , ( 'Format', 0 )
- , ( 'Language', 0 )
- , ( 'Rights', 0 )
- )
-
class ElementSpec( SimpleItem ):
-
+ """ Represent all the tool knows about a single metadata element.
"""
- Represent all the tool knows about a single metadata element.
- """
-
security = ClassSecurityInfo()
#
@@ -158,10 +142,10 @@
security.declareProtected(View , 'getPolicy')
def getPolicy( self, typ=None ):
+ """ Find the policy for this element for objects of the given type.
+
+ o Return a default, if none found.
"""
- Find the policy this element for objects whose type
- object name is 'typ'; return a default, if none found.
- """
try:
return self.policies[ typ ].__of__(self)
except KeyError:
@@ -169,9 +153,8 @@
security.declareProtected(View , 'listPolicies')
def listPolicies( self ):
+ """ Return a list of all policies for this element.
"""
- Return a list of all policies for this element.
- """
res = []
for k, v in self.policies.items():
res.append((k, v.__of__(self)))
@@ -179,10 +162,8 @@
security.declareProtected(ManagePortal , 'addPolicy')
def addPolicy( self, typ ):
+ """ Add a policy to this element for objects of the given type.
"""
- Add a policy to this element for objects whose type
- object name is 'typ'.
- """
if typ is None:
raise MetadataError, "Can't replace default policy."
@@ -193,10 +174,10 @@
security.declareProtected(ManagePortal, 'removePolicy')
def removePolicy( self, typ ):
+ """ Remove the policy from this element for objects of the given type.
+
+ o Do *not* remvoe the default, however.
"""
- Remove the policy from this element for objects whose type
- object name is 'typ' (*not* the default, however).
- """
if typ is None:
raise MetadataError, "Can't remove default policy."
del self.policies[ typ ]
@@ -204,90 +185,32 @@
InitializeClass( ElementSpec )
-class MetadataTool( UniqueObject, SimpleItem, ActionProviderBase ):
-
- implements(IMetadataTool)
- __implements__ = (z2IMetadataTool, ActionProviderBase.__implements__)
-
- id = 'portal_metadata'
- meta_type = 'Default Metadata Tool'
-
- #
- # Default values.
- #
- publisher = ''
- element_specs = None
- #initial_values_hook = None
- #validation_hook = None
-
+class MetadataSchema( SimpleItem ):
+ """ Describe a metadata schema.
+ """
security = ClassSecurityInfo()
- def __init__( self
- , publisher=None
- #, initial_values_hook=None
- #, validation_hook=None
- , element_specs=DEFAULT_ELEMENT_SPECS
- ):
+ meta_type = 'Metadata Schema'
+ publisher = ''
- self.editProperties( publisher
- #, initial_values_hook
- #, validation_hook
- )
-
+ def __init__( self, id, element_specs=() ):
+ self._setId( id )
self.element_specs = PersistentMapping()
-
for name, is_multi_valued in element_specs:
self.element_specs[ name ] = ElementSpec( is_multi_valued )
+
#
# ZMI methods
#
- manage_options = ( ActionProviderBase.manage_options +
- ( { 'label' : 'Overview'
- , 'action' : 'manage_overview'
- }
- , { 'label' : 'Properties'
- , 'action' : 'propertiesForm'
- }
- , { 'label' : 'Elements'
+ manage_options = ( ( { 'label' : 'Elements'
, 'action' : 'elementPoliciesForm'
}
- # TODO , { 'label' : 'Types'
- # , 'action' : 'typesForm'
- # }
+ ,
)
+ SimpleItem.manage_options
)
- security.declareProtected(ManagePortal, 'manage_overview')
- manage_overview = DTMLFile( 'explainMetadataTool', _dtmldir )
-
- security.declareProtected(ManagePortal, 'propertiesForm')
- propertiesForm = DTMLFile( 'metadataProperties', _dtmldir )
-
- security.declareProtected(ManagePortal, 'editProperties')
- def editProperties( self
- , publisher=None
- # TODO , initial_values_hook=None
- # TODO , validation_hook=None
- , REQUEST=None
- ):
- """
- Form handler for "tool-wide" properties (including list of
- metadata elements).
- """
- if publisher is not None:
- self.publisher = publisher
-
- # TODO self.initial_values_hook = initial_values_hook
- # TODO self.validation_hook = validation_hook
-
- if REQUEST is not None:
- REQUEST[ 'RESPONSE' ].redirect( self.absolute_url()
- + '/propertiesForm'
- + '?manage_tabs_message=Tool+updated.'
- )
-
security.declareProtected(ManagePortal, 'elementPoliciesForm')
elementPoliciesForm = DTMLFile( 'metadataElementPolicies', _dtmldir )
@@ -302,9 +225,8 @@
, allowed_vocabulary
, REQUEST=None
):
+ """ Add a type-specific policy for one of our elements.
"""
- Add a type-specific policy for one of our elements.
- """
if content_type == '<default>':
content_type = None
@@ -330,9 +252,8 @@
, content_type
, REQUEST=None
):
+ """ Remvoe a type-specific policy for one of our elements.
"""
- Remvoe a type-specific policy for one of our elements.
- """
if content_type == '<default>':
content_type = None
@@ -356,10 +277,10 @@
, allowed_vocabulary
, REQUEST=None
):
+ """ Update a policy for one of our elements
+
+ o 'content_type' will be '<default>' when we edit the default.
"""
- Update a policy for one of our elements ('content_type'
- will be '<default>' when we edit the default).
- """
if content_type == '<default>':
content_type = None
spec = self.getElementSpec( element )
@@ -383,10 +304,8 @@
#
security.declareProtected(ManagePortal, 'listElementSpecs')
def listElementSpecs( self ):
+ """ Return a list of ElementSpecs representing the elements we manage.
"""
- Return a list of ElementSpecs representing
- the elements managed by the tool.
- """
res = []
for k, v in self.element_specs.items():
res.append((k, v.__of__(self)))
@@ -394,17 +313,14 @@
security.declareProtected(ManagePortal, 'getElementSpec')
def getElementSpec( self, element ):
+ """ Return an ElementSpec for the given 'element'.
"""
- Return an ElementSpec representing the tool's knowledge
- of 'element'.
- """
return self.element_specs[ element ].__of__( self )
security.declareProtected(ManagePortal, 'addElementSpec')
def addElementSpec( self, element, is_multi_valued, REQUEST=None ):
+ """ Add 'element' to our list of managed elements.
"""
- Add 'element' to our list of managed elements.
- """
# Don't replace.
if self.element_specs.has_key( element ):
return
@@ -419,9 +335,8 @@
security.declareProtected(ManagePortal, 'removeElementSpec')
def removeElementSpec( self, element, REQUEST=None ):
+ """ Remove 'element' from our list of managed elements.
"""
- Remove 'element' from our list of managed elements.
- """
del self.element_specs[ element ]
if REQUEST is not None:
@@ -432,122 +347,276 @@
security.declareProtected(ManagePortal, 'listPolicies')
def listPolicies( self, typ=None ):
+ """ Show all policies for a given content type
+
+ o If 'typ' is none, return the list of default policies.
"""
- Show all policies for a given content type, or the default
- if None.
- """
result = []
for element, spec in self.listElementSpecs():
result.append( ( element, spec.getPolicy( typ ) ) )
return result
+InitializeClass(MetadataSchema)
+
+
+_DCMI_ELEMENT_SPECS = ( ( 'Title', 0 )
+ , ( 'Description', 0 )
+ , ( 'Subject', 1 )
+ , ( 'Format', 0 )
+ , ( 'Language', 0 )
+ , ( 'Rights', 0 )
+ )
+
+class MetadataTool( UniqueObject, Folder, ActionProviderBase ):
+
+ implements(IMetadataTool)
+ __implements__ = (z2IMetadataTool, ActionProviderBase.__implements__)
+
+ id = 'portal_metadata'
+ meta_type = 'Default Metadata Tool'
+ _actions = ()
+
+ _DCMI = None
+ def _get_DCMI( self ):
+
+ if self._DCMI is None:
+ dcmi = self._DCMI = MetadataSchema( 'DCMI', _DCMI_ELEMENT_SPECS )
+
+ old_specs = getattr( self, 'element_specs', None )
+ if old_specs is not None:
+ del self.element_specs
+ for element_id, old_spec in old_specs.items():
+ new_spec = dcmi.getElementSpec( element_id )
+ for typ, policy in old_spec.listPolicies():
+ if typ is not None:
+ new_spec.addPolicy( typ )
+ tp = new_spec.getPolicy( typ )
+ tp.edit( is_required=policy.isRequired()
+ , supply_default=policy.supplyDefault()
+ , default_value=policy.defaultValue()
+ , enforce_vocabulary=policy.enforceVocabulary()
+ , allowed_vocabulary=policy.allowedVocabulary()
+ )
+
+ return self._DCMI
+
+ DCMI = property(_get_DCMI, None)
+
#
- # 'portal_metadata' interface
+ # Default values.
#
+ publisher = ''
+
+ security = ClassSecurityInfo()
+
+ def __init__( self, publisher=None ):
+
+ self.editProperties( publisher )
+
+ #
+ # ZMI methods
+ #
+ manage_options = ( ( { 'label' : 'Schema'
+ , 'action' : 'propertiesForm'
+ }
+ , { 'label' : 'Overview'
+ , 'action' : 'manage_overview'
+ }
+ )
+ + Folder.manage_options[:1]
+ + ActionProviderBase.manage_options +
+ Folder.manage_options[1:]
+ )
+
+ security.declareProtected(ManagePortal, 'manage_overview')
+ manage_overview = DTMLFile( 'explainMetadataTool', _dtmldir )
+
+ security.declareProtected(ManagePortal, 'propertiesForm')
+ propertiesForm = DTMLFile( 'metadataProperties', _dtmldir )
+
+ security.declareProtected(ManagePortal, 'editProperties')
+ def editProperties( self
+ , publisher=None
+ , REQUEST=None
+ ):
+ """ Form handler for "tool-wide" properties
+ """
+ if publisher is not None:
+ self.publisher = publisher
+
+ if REQUEST is not None:
+ REQUEST[ 'RESPONSE' ].redirect( self.absolute_url()
+ + '/propertiesForm'
+ + '?manage_tabs_message=Tool+updated.'
+ )
+
+ security.declareProtected(ManagePortal, 'manage_addSchema')
+ def manage_addSchema( self, schema_id, elements, REQUEST ):
+ """ ZMI wrapper around addSchema
+ """
+ massaged = []
+ for element in elements:
+ if isinstance(element, basestring):
+ element = element.split(',')
+ if len( element ) < 2:
+ element.append(0)
+ massaged.append( element )
+ self.addSchema( schema_id, massaged )
+
+ REQUEST['RESPONSE'].redirect( self.absolute_url()
+ + '/propertiesForm'
+ + '?manage_tabs_message=Schema+added.'
+ )
+
+ security.declareProtected(ManagePortal, 'manage_removeSchemas')
+ def manage_removeSchemas( self, schema_ids, REQUEST ):
+ """ ZMI wrapper around removeSchema
+ """
+ if not schema_ids:
+ raise ValueError, 'No schemas selected!'
+
+ for schema_id in schema_ids:
+ self.removeSchema( schema_id )
+
+ REQUEST['RESPONSE'].redirect( self.absolute_url()
+ + '/propertiesForm'
+ + '?manage_tabs_message=Schemas+removed.'
+ )
+
security.declarePrivate( 'getFullName' )
def getFullName( self, userid ):
+ """ See IMetadataTool.
"""
- Convert an internal userid to a "formal" name, if
- possible, perhaps using the 'portal_membership' tool.
-
- Used to map userid's for Creator, Contributor DCMI
- queries.
- """
return userid # TODO: do lookup here
security.declarePublic( 'getPublisher' )
def getPublisher( self ):
+ """ See IMetadataTool.
"""
- Return the "formal" name of the publisher of the
- portal.
- """
return self.publisher
- security.declarePublic( 'listAllowedVocabulary' )
- def listAllowedVocabulary( self, element, content=None, content_type=None ):
- """
- List allowed keywords for a given portal_type, or all
- possible keywords if none supplied.
- """
- spec = self.getElementSpec( element )
- if content_type is None and content:
- content_type = content.getPortalTypeName()
- return spec.getPolicy( content_type ).allowedVocabulary()
-
security.declarePublic( 'listAllowedSubjects' )
def listAllowedSubjects( self, content=None, content_type=None ):
+ """ See IMetadataTool.
"""
- List allowed keywords for a given portal_type, or all
- possible keywords if none supplied.
- """
- return self.listAllowedVocabulary( 'Subject', content, content_type )
+ return self.listAllowedVocabulary( 'DCMI'
+ , 'Subject'
+ , content
+ , content_type
+ )
security.declarePublic( 'listAllowedFormats' )
def listAllowedFormats( self, content=None, content_type=None ):
+ """ See IMetadataTool.
"""
- List the allowed 'Content-type' values for a particular
- portal_type, or all possible formats if none supplied.
- """
- return self.listAllowedVocabulary( 'Format', content, content_type )
+ return self.listAllowedVocabulary( 'DCMI'
+ , 'Format'
+ , content
+ , content_type
+ )
security.declarePublic( 'listAllowedLanguages' )
def listAllowedLanguages( self, content=None, content_type=None ):
+ """ See IMetadataTool.
"""
- List the allowed language values.
- """
- return self.listAllowedVocabulary( 'Language', content, content_type )
+ return self.listAllowedVocabulary( 'DCMI'
+ , 'Language'
+ , content
+ , content_type
+ )
security.declarePublic( 'listAllowedRights' )
def listAllowedRights( self, content=None, content_type=None ):
+ """ See IMetadata Tool.
"""
- List the allowed values for a "Rights"
- selection list; this gets especially important where
- syndication is involved.
+ return self.listAllowedVocabulary( 'DCMI'
+ , 'Rights'
+ , content
+ , content_type
+ )
+
+ security.declarePublic( 'listAllowedVocabulary' )
+ def listAllowedVocabulary( self
+ , schema
+ , element
+ , content=None
+ , content_type=None
+ ):
+ """ See IMetadataTool.
"""
- return self.listAllowedVocabulary( 'Rights', content, content_type )
+ schema_def = getattr( self, schema )
+ spec = schema_def.getElementSpec( element )
+ if content_type is None and content:
+ content_type = content.getPortalTypeName()
+ return spec.getPolicy( content_type ).allowedVocabulary()
+ security.declarePublic( 'listSchemas' )
+ def listSchemas( self ):
+ """ See IMetadataTool.
+ """
+ result = [ ( 'DCMI', self.DCMI ) ]
+ result.extend( self.objectItems( [ MetadataSchema.meta_type ] ) )
+ return result
+
+ security.declareProtected(ModifyPortalContent, 'addSchema')
+ def addSchema( self, schema_id, elements=() ):
+ """ See IMetadataTool.
+ """
+ if schema_id == 'DCMI' or schema_id in self.objectIds():
+ raise KeyError, 'Duplicate schema ID: %s' % schema_id
+
+ schema = MetadataSchema( schema_id, elements )
+ self._setObject( schema_id, schema )
+
+ return self._getOb( schema_id )
+
+ security.declareProtected(ModifyPortalContent, 'removeSchema')
+ def removeSchema( self, schema_id ):
+ """ See IMetadataTool.
+ """
+ if schema_id == 'DCMI' or schema_id not in self.objectIds():
+ raise KeyError, 'Invalid schema ID: %s' % schema_id
+
+ self._delObject( schema_id )
+
security.declareProtected(ModifyPortalContent, 'setInitialMetadata')
def setInitialMetadata( self, content ):
+ """ See IMetadataTool.
"""
- Set initial values for content metatdata, supplying
- any site-specific defaults.
- """
- for element, policy in self.listPolicies(content.getPortalTypeName()):
+ for schema_id, schema in self.listSchemas():
+ for element, policy in schema.listPolicies(
+ content.getPortalTypeName()):
- if not getattr( content, element )():
+ if not getattr( content, element )():
- if policy.supplyDefault():
- setter = getattr( content, 'set%s' % element )
- setter( policy.defaultValue() )
- elif policy.isRequired():
- raise MetadataError, \
- 'Metadata element %s is required.' % element
+ if policy.supplyDefault():
+ setter = getattr( content, 'set%s' % element )
+ setter( policy.defaultValue() )
+ elif policy.isRequired():
+ raise MetadataError, \
+ 'Metadata element %s is required.' % element
# TODO: Call initial_values_hook, if present
security.declareProtected(View, 'validateMetadata')
def validateMetadata( self, content ):
+ """ See IMetadataTool.
"""
- Enforce portal-wide policies about DCI, e.g.,
- requiring non-empty title/description, etc. Called
- by the CMF immediately before saving changes to the
- metadata of an object.
- """
- for element, policy in self.listPolicies(content.getPortalTypeName()):
+ for schema_id, schema in self.listSchemas():
+ for element, policy in schema.listPolicies(
+ content.getPortalTypeName()):
- value = getattr( content, element )()
- if not value and policy.isRequired():
- raise MetadataError, \
- 'Metadata element %s is required.' % element
+ value = getattr( content, element )()
+ if not value and policy.isRequired():
+ raise MetadataError, \
+ 'Metadata element %s is required.' % element
- if value and policy.enforceVocabulary():
- values = policy.isMultiValued() and value or [ value ]
- for value in values:
- if not value in policy.allowedVocabulary():
- raise MetadataError, \
- 'Value %s is not in allowed vocabulary for ' \
- 'metadata element %s.' % ( value, element )
+ if value and policy.enforceVocabulary():
+ values = policy.isMultiValued() and value or [ value ]
+ for value in values:
+ if not value in policy.allowedVocabulary():
+ raise MetadataError, \
+ 'Value %s is not in allowed vocabulary for ' \
+ 'metadata element %s.' % ( value, element )
- # TODO: Call validation_hook, if present
-
InitializeClass( MetadataTool )
Modified: CMF/branches/tseaver-viewification/CMFDefault/__init__.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/__init__.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/__init__.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -16,6 +16,7 @@
"""
from Products.CMFCore.DirectoryView import registerDirectory
+from Products.CMFCore.interfaces import ISiteRoot
from Products.CMFCore.utils import initializeBasesPhase1
from Products.CMFCore.utils import initializeBasesPhase2
from Products.CMFCore.utils import ToolInit
@@ -114,14 +115,18 @@
'Profile for a default CMFSite.',
'profiles/default',
'CMFDefault',
- BASE)
+ BASE,
+ for_=ISiteRoot,
+ )
profile_registry.registerProfile('sample_content',
'Sample CMFDefault Content',
'Content for a sample CMFSite.',
'profiles/sample_content',
'CMFDefault',
- EXTENSION)
+ EXTENSION,
+ for_=ISiteRoot,
+ )
context.registerClass( Portal.CMFSite
, constructors=(factory.addConfiguredSiteForm,
Modified: CMF/branches/tseaver-viewification/CMFDefault/browser/tests/linkviews.txt
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/browser/tests/linkviews.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/browser/tests/linkviews.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -7,6 +7,8 @@
First, let's create a "dummy" link class, to avoid dependencies on the
actual content object.
+ >>> from zope.app.tests.placelesssetup import setUp, tearDown
+ >>> setUp()
>>> from Products.CMFDefault.interfaces import ILink
>>> class FauxLink:
... def __init__(self, remote_url, title):
@@ -83,3 +85,6 @@
>>> print response._redirected
http://example.com/path/to/link/edit.html?portal_status_message=Link%20updated.
+And clean up at the end:
+
+ >>> tearDown()
Modified: CMF/branches/tseaver-viewification/CMFDefault/dtml/metadataElementPolicies.dtml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/dtml/metadataElementPolicies.dtml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/dtml/metadataElementPolicies.dtml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,9 +1,9 @@
<dtml-var manage_page_header>
<dtml-var manage_tabs>
-<dtml-unless expr="REQUEST.has_key( 'element' )">
-<dtml-call expr="REQUEST.set( 'element', listElementSpecs()[0][0] )">
-</dtml-unless>
+<dtml-let specs=listElementSpecs
+ def_spec="specs and specs[0][0] or None"
+ current="REQUEST.get( 'element', def_spec )">
<h3> Update Element Metadata Policies </h3>
@@ -14,7 +14,7 @@
<td colspan="3">
<dtml-in listElementSpecs>
<dtml-let key=sequence-key>
- <dtml-if expr="key == REQUEST[ 'element' ]">
+ <dtml-if expr="key == current">
&dtml-key;
<dtml-else>
<a href="&dtml-URL;?element=&dtml-key;"> &dtml-key; </a>
@@ -24,14 +24,14 @@
</td>
</tr>
- <dtml-let spec="getElementSpec( element=REQUEST[ 'element' ] )"
+ <dtml-if def_spec>
+ <dtml-let spec="getElementSpec( element=current )"
multi="spec.isMultiValued()"
tokenz="multi and ':tokens' or ''"
>
<dtml-in expr="spec.listPolicies()" sort>
- <dtml-let element="REQUEST[ 'element']"
- key=sequence-key
+ <dtml-let key=sequence-key
typ="key or '<default>'"
policy=sequence-item
rqd="policy.isRequired() and 'checked' or ''"
@@ -44,7 +44,7 @@
>
<form action="&dtml-absolute_url;" method="POST">
- <input type="hidden" name="element" value="&dtml-element;">
+ <input type="hidden" name="element" value="&dtml-current;">
<input type="hidden" name="content_type" value="&dtml-typ;">
<tr style="background-color: DarkGray; color: DarkBlue">
@@ -110,7 +110,7 @@
</dtml-in>
<form action="&dtml-absolute_url;" method="POST">
- <input type="hidden" name="element" value="&dtml-element;">
+ <input type="hidden" name="element" value="&dtml-current;">
<tr style="background-color: DarkGray; color: DarkBlue">
<th colspan="4"> <new type> </th>
@@ -171,6 +171,9 @@
</tr>
</dtml-let>
+ </dtml-if>
</table>
+</dtml-let>
+
<dtml-var manage_page_footer>
Modified: CMF/branches/tseaver-viewification/CMFDefault/dtml/metadataProperties.dtml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/dtml/metadataProperties.dtml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/dtml/metadataProperties.dtml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -20,54 +20,76 @@
</table>
</form>
-<h3> Add Metadata Element </h3>
+<h3> Metadata Schemas </h3>
-<form action="&dtml-absolute_url;/addElementSpec" method="POST">
-<input type="hidden" name="is_multi_valued:int:default" value="0">
+<form action="&dtml-absolute_url;" method="POST">
<table>
+ <dtml-in listSchemas>
+ <dtml-if sequence-start>
+
<tr valign="middle">
- <th width="100" align="right"> Element: </th>
- <td> <input type="text" name="element" size="20"> </td>
+ <td width="16">
+ <br /> <!-- can't remove DCMI schema! -->
+ </td>
+ <td>
+ <a href="&dtml-absolute_url;/manage_workspace">DCMI</a>
+ </td>
</tr>
+ <dtml-else>
+
<tr valign="middle">
- <th width="100" align="right"> Multi-valued? </th>
- <td> <input type="checkbox" name="is_multi_valued:boolean"> </td>
+ <td>
+ <input type="checkbox" name="schema_ids:list" value="&dtml-sequence-key;" />
+ </td>
+ <td>
+ <a href="&dtml-absolute_url;/manage_workspace"
+ > &dtml-sequence-key; </a>
+ </td>
</tr>
+ </dtml-if>
+ </dtml-in>
+
<tr valign="middle">
- <td> <br> </td>
- <td> <input type="submit" value=" Add "> </td>
+ <td colspan="2">
+ <input type="submit" name="manage_removeSchemas:method"
+ value=" Remove Schemas ">
+ </td>
</tr>
-
</table>
-</form>
-<h3> Remove Metadata Element </h3>
+<br />
-<form action="&dtml-absolute_url;/removeElementSpec" method="POST">
<table>
- <tr valign="middle">
- <th width="100" align="right"> Element: </th>
- <td> <dtml-in listElementSpecs>
- <dtml-if sequence-start>
- <select name="element">
- </dtml-if>
- <option value="&dtml-sequence-key;"> &dtml-sequence-key; </option>
- <dtml-if sequence-end>
- </select>
- </dtml-if>
- </dtml-in>
+ <tr>
+ <th colspan="2"
+ style="background-color:#CCCCCC; color:#000088">
+ Add a Schema
+ </th>
+ <tr>
+ <th> Schema ID </th>
+ <td>
+ <input type="text" name="schema_id" size="20"><br />
</td>
</tr>
- <tr valign="middle">
- <td> <br> </td>
- <td> <input type="submit" value=" Remove "> </td>
+ <tr>
+ <th> Elements </th>
+ <td>
+ <textarea name="elements:lines" cols="30" rows="10"></textarea>
+ </td>
</tr>
+ <tr>
+ <td> <br /> </td>
+ <td>
+ <input type="submit" name="manage_addSchema:method" value=" Add Schema ">
+ </td>
+ </tr>
+
</table>
</form>
Modified: CMF/branches/tseaver-viewification/CMFDefault/factory.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/factory.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/factory.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -17,6 +17,7 @@
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from Products.CMFCore.interfaces import ISiteRoot
from Products.CMFCore.utils import getToolByName
from Products.GenericSetup import EXTENSION
from Products.GenericSetup import profile_registry
@@ -36,7 +37,7 @@
base_profiles = []
extension_profiles = []
- for info in profile_registry.listProfileInfo():
+ for info in profile_registry.listProfileInfo(for_=ISiteRoot):
if info.get('type') == EXTENSION:
extension_profiles.append(info)
else:
Modified: CMF/branches/tseaver-viewification/CMFDefault/profiles/default/catalog.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/profiles/default/catalog.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/profiles/default/catalog.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,13 +1,13 @@
<?xml version="1.0"?>
<object name="portal_catalog" meta_type="CMF Catalog">
<property name="title"></property>
- <object name="plaintext_lexicon" meta_type="ZCTextIndex Lexicon">
- <element name="Whitespace splitter" group="Word Splitter"/>
+ <object name="htmltext_lexicon" meta_type="ZCTextIndex Lexicon">
+ <element name="HTML aware splitter" group="Word Splitter"/>
<element name="Case Normalizer" group="Case Normalizer"/>
<element name="Remove listed stop words only" group="Stop Words"/>
</object>
- <object name="htmltext_lexicon" meta_type="ZCTextIndex Lexicon">
- <element name="HTML aware splitter" group="Word Splitter"/>
+ <object name="plaintext_lexicon" meta_type="ZCTextIndex Lexicon">
+ <element name="Whitespace splitter" group="Word Splitter"/>
<element name="Case Normalizer" group="Case Normalizer"/>
<element name="Remove listed stop words only" group="Stop Words"/>
</object>
Modified: CMF/branches/tseaver-viewification/CMFDefault/profiles/default/export_steps.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/profiles/default/export_steps.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/profiles/default/export_steps.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,37 +1,37 @@
<?xml version="1.0"?>
<export-steps>
<export-step id="actions"
- handler="Products.CMFSetup.actions.exportActionProviders"
+ handler="Products.CMFCore.exportimport.actions.exportActionProviders"
title="Action Providers">
Export actions tool's action providers and their actions.
</export-step>
<export-step id="caching_policy_mgr"
- handler="Products.CMFSetup.cachingpolicymgr.exportCachingPolicyManager"
+ handler="Products.CMFCore.exportimport.cachingpolicymgr.exportCachingPolicyManager"
title="Caching Policies">
Export caching policy manager's policies.
</export-step>
<export-step id="catalog"
- handler="Products.CMFSetup.catalog.exportCatalogTool"
+ handler="Products.CMFCore.exportimport.catalog.exportCatalogTool"
title="Catalog Tool">
Export catalog tool's sub-objects, indexes and columns.
</export-step>
<export-step id="content_type_registry"
- handler="Products.CMFSetup.contenttyperegistry.exportContentTypeRegistry"
+ handler="Products.CMFCore.exportimport.contenttyperegistry.exportContentTypeRegistry"
title="Content Type Registry">
Export content type registry's predicates / bindings.
</export-step>
<export-step id="cookieauth"
- handler="Products.CMFSetup.cookieauth.exportCookieCrumbler"
+ handler="Products.CMFCore.exportimport.cookieauth.exportCookieCrumbler"
title="Cookie Authentication">
Export cookie crumbler settings
</export-step>
<export-step id="mailhost"
- handler="Products.CMFSetup.mailhost.exportMailHost"
+ handler="Products.CMFCore.exportimport.mailhost.exportMailHost"
title="MailHost">
Export the mailhost's settings and properties
</export-step>
<export-step id="properties"
- handler="Products.CMFSetup.properties.exportSiteProperties"
+ handler="Products.CMFCore.exportimport.properties.exportSiteProperties"
title="Site Properties">
Export site properties.
</export-step>
@@ -41,7 +41,7 @@
Export custom roles and non-default role-permission mappings.
</export-step>
<export-step id="skins"
- handler="Products.CMFSetup.skins.exportSkinsTool"
+ handler="Products.CMFCore.exportimport.skins.exportSkinsTool"
title="Skins Tool">
Export skins tool's filesystem directory views and skin path definitions.
</export-step>
@@ -56,12 +56,12 @@
Export required / forbidden tools.
</export-step>
<export-step id="typeinfo"
- handler="Products.CMFSetup.typeinfo.exportTypesTool"
+ handler="Products.CMFCore.exportimport.typeinfo.exportTypesTool"
title="Types Tool">
Export types tool's type information objects.
</export-step>
<export-step id="workflows"
- handler="Products.CMFSetup.workflow.exportWorkflowTool"
+ handler="Products.CMFCore.exportimport.workflow.exportWorkflowTool"
title="Workflow Tool">
Export workflow tool's workflow definitions and supporting scripts.
</export-step>
Modified: CMF/branches/tseaver-viewification/CMFDefault/profiles/default/import_steps.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/profiles/default/import_steps.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/profiles/default/import_steps.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,45 +1,45 @@
<?xml version="1.0"?>
<import-steps>
<import-step id="actions" version="20040630-01"
- handler="Products.CMFSetup.actions.importActionProviders"
+ handler="Products.CMFCore.exportimport.actions.importActionProviders"
title="Action Providers">
<dependency step="toolset"/>
Import actions tool's action providers and their actions.
</import-step>
<import-step id="caching_policy_mgr" version="20051011-01"
- handler="Products.CMFSetup.cachingpolicymgr.importCachingPolicyManager"
+ handler="Products.CMFCore.exportimport.cachingpolicymgr.importCachingPolicyManager"
title="Caching Policies">
<dependency step="toolset"/>
Import caching policy manager's policies.
</import-step>
<import-step id="catalog" version="20050929-01"
- handler="Products.CMFSetup.catalog.importCatalogTool"
+ handler="Products.CMFCore.exportimport.catalog.importCatalogTool"
title="Catalog Tool">
<dependency step="toolset"/>
Import catalog tool's sub-objects, indexes and columns.
</import-step>
<import-step id="content_type_registry"
version="20051013-01"
- handler="Products.CMFSetup.contenttyperegistry.importContentTypeRegistry"
+ handler="Products.CMFCore.exportimport.contenttyperegistry.importContentTypeRegistry"
title="Content Type Registry">
<dependency step="toolset"/>
Import content type registry's predicates and bindings.
</import-step>
<import-step id="cookie_authentication"
version="20050903-01"
- handler="Products.CMFSetup.cookieauth.importCookieCrumbler"
+ handler="Products.CMFCore.exportimport.cookieauth.importCookieCrumbler"
title="Cookie Authentication">
<dependency step="toolset"/>
Import cookie crumbler settings
</import-step>
<import-step id="mailhost" version="20050803-01"
- handler="Products.CMFSetup.mailhost.importMailHost"
+ handler="Products.CMFCore.exportimport.mailhost.importMailHost"
title="MailHost">
<dependency step="toolset"/>
Import mailhost settings
</import-step>
<import-step id="properties" version="20041215-01"
- handler="Products.CMFSetup.properties.importSiteProperties"
+ handler="Products.CMFCore.exportimport.properties.importSiteProperties"
title="Site Properties">
Import site properties.
</import-step>
@@ -49,7 +49,7 @@
Import custom roles and non-default role-permission mappings.
</import-step>
<import-step id="skins" version="20040630-01"
- handler="Products.CMFSetup.skins.importSkinsTool"
+ handler="Products.CMFCore.exportimport.skins.importSkinsTool"
title="Skins Tool">
<dependency step="toolset"/>
Import skins tool's filesystem directory views and skin path definitions.
@@ -61,7 +61,7 @@
forbidden ones.
</import-step>
<import-step id="typeinfo" version="20040630-01"
- handler="Products.CMFSetup.typeinfo.importTypesTool"
+ handler="Products.CMFCore.exportimport.typeinfo.importTypesTool"
title="Types Tool">
<dependency step="toolset"/>
Import types tool's type information objects.
@@ -73,10 +73,9 @@
Import various settings from PortalGenerator.
</import-step>
<import-step id="workflow" version="20040630-01"
- handler="Products.CMFSetup.workflow.importWorkflowTool"
+ handler="Products.CMFCore.exportimport.workflow.importWorkflowTool"
title="Workflow Tool">
<dependency step="toolset"/>
- <dependency step="typeinfo"/>
Import workflow tool's workflow definitions and supporting scripts.
</import-step>
</import-steps>
Copied: CMF/branches/tseaver-viewification/CMFDefault/profiles/default/skins (from rev 40492, CMF/trunk/CMFDefault/profiles/default/skins)
Modified: CMF/branches/tseaver-viewification/CMFDefault/profiles/default/skins.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/profiles/default/skins.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/profiles/default/skins.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,20 +1,21 @@
<?xml version="1.0"?>
-<skins-tool default_skin="Basic"
- request_varname="portal_skin" allow_any="0"
- cookie_persistence="0">
- <skin-directory id="Images"
- directory="CMFDefault/skins/Images"/>
- <skin-directory id="zpt_content"
- directory="CMFDefault/skins/zpt_content"/>
- <skin-directory id="zpt_control"
- directory="CMFDefault/skins/zpt_control"/>
- <skin-directory id="zpt_generic"
- directory="CMFDefault/skins/zpt_generic"/>
- <skin-path id="Basic">
+<object name="portal_skins" meta_type="CMF Skins Tool" allow_any="False"
+ cookie_persistence="False" default_skin="Basic"
+ request_varname="portal_skin">
+ <object name="Images" meta_type="Filesystem Directory View"
+ directory="CMFDefault/skins/Images"/>
+ <object name="custom" meta_type="Folder"/>
+ <object name="zpt_content" meta_type="Filesystem Directory View"
+ directory="CMFDefault/skins/zpt_content"/>
+ <object name="zpt_control" meta_type="Filesystem Directory View"
+ directory="CMFDefault/skins/zpt_control"/>
+ <object name="zpt_generic" meta_type="Filesystem Directory View"
+ directory="CMFDefault/skins/zpt_generic"/>
+ <skin-path name="Basic">
<layer name="custom"/>
<layer name="zpt_content"/>
<layer name="zpt_generic"/>
<layer name="zpt_control"/>
<layer name="Images"/>
</skin-path>
-</skins-tool>
+</object>
Modified: CMF/branches/tseaver-viewification/CMFDefault/profiles/default/toolset.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/profiles/default/toolset.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/profiles/default/toolset.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -3,6 +3,8 @@
<required tool_id="MailHost"
class="Products.MailHost.MailHost.MailHost"/>
+ <required tool_id="acl_users"
+ class="AccessControl.User.UserFolder"/>
<required tool_id="caching_policy_manager"
class="Products.CMFCore.CachingPolicyManager.CachingPolicyManager"/>
<required tool_id="content_type_registry"
Modified: CMF/branches/tseaver-viewification/CMFDefault/profiles/default/typestool.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/profiles/default/typestool.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/profiles/default/typestool.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,14 +1,13 @@
<?xml version="1.0"?>
-<types-tool>
- <type id="CMF BTree Folder"
- filename="types/CMF_BTree_Folder.xml"/>
- <type id="Discussion Item"
- filename="types/Discussion_Item.xml"/>
- <type id="Document"/>
- <type id="Favorite"/>
- <type id="File"/>
- <type id="Folder"/>
- <type id="Image"/>
- <type id="Link"/>
- <type id="News Item" filename="types/News_Item.xml"/>
-</types-tool>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <property name="title"></property>
+ <object name="CMF BTree Folder" meta_type="Factory-based Type Information"/>
+ <object name="Discussion Item" meta_type="Factory-based Type Information"/>
+ <object name="Document" meta_type="Factory-based Type Information"/>
+ <object name="Favorite" meta_type="Factory-based Type Information"/>
+ <object name="File" meta_type="Factory-based Type Information"/>
+ <object name="Folder" meta_type="Factory-based Type Information"/>
+ <object name="Image" meta_type="Factory-based Type Information"/>
+ <object name="Link" meta_type="Factory-based Type Information"/>
+ <object name="News Item" meta_type="Factory-based Type Information"/>
+</object>
Modified: CMF/branches/tseaver-viewification/CMFDefault/profiles/default/workflows.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/profiles/default/workflows.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/profiles/default/workflows.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,17 +1,12 @@
<?xml version="1.0"?>
-<workflow-tool>
- <workflow workflow_id="default_workflow"
- meta_type="Workflow"
- filename="workflows/default_workflow/definition.xml"/>
+<object name="portal_workflow" meta_type="CMF Workflow Tool">
+ <property name="title"></property>
+ <object name="default_workflow" meta_type="Workflow"/>
<bindings>
<default>
<bound-workflow workflow_id="default_workflow"/>
</default>
- <type type_id="CMF BTree Folder">
-
- </type>
- <type type_id="Folder">
-
- </type>
+ <type type_id="CMF BTree Folder"/>
+ <type type_id="Folder"/>
</bindings>
-</workflow-tool>
+</object>
Modified: CMF/branches/tseaver-viewification/CMFDefault/setuphandlers.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/setuphandlers.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/setuphandlers.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,8 +15,6 @@
$Id$
"""
-from Products.CMFCore.utils import getToolByName
-
from exceptions import BadRequest
@@ -28,15 +26,10 @@
"""
site = context.getSite()
- # add custom skin folder
- stool = getToolByName(site, 'portal_skins')
try:
- stool.manage_addProduct['OFSP'].manage_addFolder(id='custom')
+ site.manage_addPortalFolder('Members')
except BadRequest:
return 'Various settings: Nothing to import.'
-
- site.manage_addProduct['OFSP'].manage_addUserFolder()
- site.manage_addPortalFolder('Members')
site.Members.manage_addProduct['OFSP'].manage_addDTMLMethod('index_html',
'Member list', '<dtml-return roster>')
Modified: CMF/branches/tseaver-viewification/CMFDefault/tests/test_DefaultWorkflow.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/tests/test_DefaultWorkflow.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/tests/test_DefaultWorkflow.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,37 +15,32 @@
$Id$
"""
-from unittest import TestCase, TestSuite, makeSuite, main
+import unittest
import Testing
-import Zope2
-Zope2.startup()
from Products.CMFCore.tests.base.dummy import DummyContent
from Products.CMFCore.tests.base.dummy import DummySite
from Products.CMFCore.tests.base.dummy import DummyTool
from Products.CMFCore.tests.base.dummy import DummyUserFolder
-from Products.CMFCore.WorkflowTool import addWorkflowFactory
from Products.CMFCore.WorkflowTool import WorkflowTool
-from Products.CMFDefault.MembershipTool import MembershipTool
-from Products.CMFDefault.DefaultWorkflow import DefaultWorkflowDefinition
-class DefaultWorkflowDefinitionTests(TestCase):
+class DefaultWorkflowDefinitionTests(unittest.TestCase):
def setUp(self):
-
+ from Products.CMFDefault.DefaultWorkflow \
+ import DefaultWorkflowDefinition
self.site = DummySite('site')
self.site._setObject('portal_types', DummyTool())
self.site._setObject('portal_workflow', WorkflowTool())
- self.site._setObject('portal_membership', MembershipTool())
+ self.site._setObject('portal_membership', DummyTool())
self.site._setObject('acl_users', DummyUserFolder())
- addWorkflowFactory(DefaultWorkflowDefinition,
- id='default_workflow', title='default_workflow')
+ wftool = self.site.portal_workflow
+ wftool._setObject('wf', DefaultWorkflowDefinition('wf'))
+ wftool.setDefaultChain('wf')
- self._constructDummyWorkflow()
-
def test_z2interfaces(self):
from Interface.Verify import verifyClass
from Products.CMFCore.interfaces.portal_workflow \
@@ -63,12 +58,6 @@
verifyClass(IWorkflowDefinition, DefaultWorkflowDefinition)
- def _constructDummyWorkflow(self):
-
- wftool = self.site.portal_workflow
- wftool.manage_addWorkflow('default_workflow (default_workflow)', 'wf')
- wftool.setDefaultChain('wf')
-
def _getDummyWorkflow(self):
wftool = self.site.portal_workflow
return wftool.wf
@@ -92,10 +81,11 @@
# XXX more tests...
+
def test_suite():
- return TestSuite((
- makeSuite( DefaultWorkflowDefinitionTests ),
+ return unittest.TestSuite((
+ unittest.makeSuite(DefaultWorkflowDefinitionTests),
))
if __name__ == '__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Modified: CMF/branches/tseaver-viewification/CMFDefault/tests/test_DiscussionReply.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/tests/test_DiscussionReply.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/tests/test_DiscussionReply.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,16 +15,15 @@
$Id$
"""
-from unittest import TestSuite, makeSuite, main
+import unittest
import Testing
-import Zope2
-Zope2.startup()
import Products
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from Products.Five import zcml
+from Products.CMFCore.tests.base.testcase import _TRAVERSE_ZCML
from Products.CMFCore.tests.base.testcase import PlacelessSetup
from Products.CMFCore.tests.base.testcase import RequestTest
@@ -35,8 +34,11 @@
PlacelessSetup.setUp(self)
RequestTest.setUp(self)
zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
zcml.load_config('configure.zcml', Products.GenericSetup)
zcml.load_config('configure.zcml', Products.CMFCore)
+ zcml.load_config('configure.zcml', Products.DCWorkflow)
+ zcml.load_string(_TRAVERSE_ZCML)
try:
factory = self.root.manage_addProduct['CMFDefault'].addConfiguredSite
factory('cmf', 'CMFDefault:default', snapshot=False)
@@ -90,10 +92,10 @@
def test_suite():
- suite = TestSuite()
- suite.addTest(makeSuite(DiscussionReplyTest))
- suite.addTest(makeSuite(DiscussionReplyTestMember))
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(DiscussionReplyTest))
+ suite.addTest(unittest.makeSuite(DiscussionReplyTestMember))
return suite
if __name__ == '__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Modified: CMF/branches/tseaver-viewification/CMFDefault/tests/test_Image.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/tests/test_Image.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/tests/test_Image.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -100,8 +100,10 @@
PlacelessSetup.setUp(self)
RequestTest.setUp(self)
zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
zcml.load_config('configure.zcml', Products.GenericSetup)
zcml.load_config('configure.zcml', Products.CMFCore)
+ zcml.load_config('configure.zcml', Products.DCWorkflow)
try:
newSecurityManager(None, UnrestrictedUser('manager', '', ['Manager'], []))
factory = self.root.manage_addProduct['CMFDefault'].addConfiguredSite
Modified: CMF/branches/tseaver-viewification/CMFDefault/tests/test_MetadataTool.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/tests/test_MetadataTool.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/tests/test_MetadataTool.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -14,118 +14,132 @@
$Id$
"""
-
-from unittest import TestCase, TestSuite, makeSuite, main
+import unittest
import Testing
import Zope2
Zope2.startup()
from Acquisition import aq_base
-from Products.CMFDefault.DublinCore import DefaultDublinCoreImpl
-from Products.CMFDefault.exceptions import MetadataError
-from Products.CMFDefault.MetadataTool import DEFAULT_ELEMENT_SPECS
-from Products.CMFDefault.MetadataTool import ElementSpec
-from Products.CMFDefault.MetadataTool import MetadataElementPolicy
-from Products.CMFDefault.MetadataTool import MetadataTool
+class TestMetadataElementPolicy( unittest.TestCase ):
-class TestMetadataElementPolicy( TestCase ):
+ def _getTargetClass( self ):
+ from Products.CMFDefault.MetadataTool import MetadataElementPolicy
+ return MetadataElementPolicy
- def setUp( self ):
- self.sv_policy = MetadataElementPolicy( 0 )
- self.mv_policy = MetadataElementPolicy( 1 )
+ def _makeOne( self, *args, **kw ):
+ return self._getTargetClass()( *args, **kw )
- def tearDown( self ):
- del self.sv_policy
- del self.mv_policy
+ def test_empty_single_valued( self ):
+ sv_policy = self._makeOne( 0 )
+ self.failIf( sv_policy.isMultiValued() )
+ self.failIf( sv_policy.isRequired() )
+ self.failIf( sv_policy.supplyDefault() )
+ self.failIf( sv_policy.defaultValue() )
+ self.failIf( sv_policy.enforceVocabulary() )
+ self.failIf( sv_policy.allowedVocabulary() )
- def test_emptySV( self ):
- assert not self.sv_policy.isMultiValued()
- assert not self.sv_policy.isRequired()
- assert not self.sv_policy.supplyDefault()
- assert not self.sv_policy.defaultValue()
- assert not self.sv_policy.enforceVocabulary()
- assert not self.sv_policy.allowedVocabulary()
+ def test_edit_single_valued( self ):
+ sv_policy = self._makeOne( 0 )
+ sv_policy.edit( 1, 1, 'xxx', 0, '' )
+ self.failIf( sv_policy.isMultiValued() )
+ self.failUnless( sv_policy.isRequired() )
+ self.failUnless( sv_policy.supplyDefault() )
+ self.assertEquals( sv_policy.defaultValue(), 'xxx' )
+ self.failIf( sv_policy.enforceVocabulary() )
+ self.failIf( sv_policy.allowedVocabulary() )
- def test_editSV( self ):
- self.sv_policy.edit( 1, 1, 'xxx', 0, '' )
- assert not self.sv_policy.isMultiValued()
- assert self.sv_policy.isRequired()
- assert self.sv_policy.supplyDefault()
- assert self.sv_policy.defaultValue() == 'xxx'
- assert not self.sv_policy.enforceVocabulary()
- assert not self.sv_policy.allowedVocabulary()
+ def test_empty_multi_valued( self ):
+ mv_policy = self._makeOne( 1 )
+ self.failUnless( mv_policy.isMultiValued() )
+ self.failIf( mv_policy.isRequired() )
+ self.failIf( mv_policy.supplyDefault() )
+ self.failIf( mv_policy.defaultValue() )
+ self.failIf( mv_policy.enforceVocabulary() )
+ self.failIf( mv_policy.allowedVocabulary() )
- def test_emptyMV( self ):
- assert self.mv_policy.isMultiValued()
- assert not self.mv_policy.isRequired()
- assert not self.mv_policy.supplyDefault()
- assert not self.mv_policy.defaultValue()
- assert not self.mv_policy.enforceVocabulary()
- assert not self.mv_policy.allowedVocabulary()
+ def test_edit_multi_valued( self ):
+ mv_policy = self._makeOne( 1 )
+ mv_policy.edit( 1, 1, 'xxx', 1, ( 'xxx', 'yyy' ) )
+ self.failUnless( mv_policy.isMultiValued() )
+ self.failUnless( mv_policy.isRequired() )
+ self.failUnless( mv_policy.supplyDefault() )
+ self.assertEqual( mv_policy.defaultValue(), 'xxx' )
+ self.failUnless( mv_policy.enforceVocabulary() )
+ self.assertEqual( len( mv_policy.allowedVocabulary() ), 2 )
+ self.failUnless( 'xxx' in mv_policy.allowedVocabulary() )
+ self.failUnless( 'yyy' in mv_policy.allowedVocabulary() )
- def test_editMV( self ):
- self.mv_policy.edit( 1, 1, 'xxx', 1, ( 'xxx', 'yyy' ) )
- assert self.mv_policy.isMultiValued()
- assert self.mv_policy.isRequired()
- assert self.mv_policy.supplyDefault()
- assert self.mv_policy.defaultValue() == 'xxx'
- assert self.mv_policy.enforceVocabulary()
- assert len( self.mv_policy.allowedVocabulary() ) == 2
- assert 'xxx' in self.mv_policy.allowedVocabulary()
- assert 'yyy' in self.mv_policy.allowedVocabulary()
-class TestElementSpec( TestCase ):
+class TestElementSpec( unittest.TestCase ):
- def setUp( self ):
- self.sv_spec = ElementSpec( 0 )
- self.mv_spec = ElementSpec( 1 )
+ def _getTargetClass( self ):
+ from Products.CMFDefault.MetadataTool import ElementSpec
+ return ElementSpec
- def tearDown( self ):
- del self.sv_spec
- del self.mv_spec
+ def _makeOne( self, *args, **kw ):
+ return self._getTargetClass()( *args, **kw )
- def test_empty( self ):
- assert not self.sv_spec.isMultiValued()
- assert self.sv_spec.getPolicy() == self.sv_spec.getPolicy( 'XYZ' )
- policies = self.sv_spec.listPolicies()
- assert len( policies ) == 1
- assert policies[0][0] is None
+ def test_empty_single_valued( self ):
+ sv_spec = self._makeOne( 0 )
+ self.failIf( sv_spec.isMultiValued() )
+ self.assertEqual( sv_spec.getPolicy(), sv_spec.getPolicy( 'XYZ' ) )
+ policies = sv_spec.listPolicies()
+ self.assertEqual( len( policies ), 1 )
+ self.assertEqual( policies[0][0], None )
- assert self.mv_spec.isMultiValued()
- assert self.mv_spec.getPolicy() == self.mv_spec.getPolicy( 'XYZ' )
- policies = self.mv_spec.listPolicies()
- assert len( policies ) == 1
- assert policies[0][0] is None
+ def test_empty_multi_valued( self ):
+ mv_spec = self._makeOne( 1 )
+ self.failUnless( mv_spec.isMultiValued() )
+ self.assertEqual( mv_spec.getPolicy(), mv_spec.getPolicy( 'XYZ' ) )
+ policies = mv_spec.listPolicies()
+ self.assertEqual( len( policies ), 1 )
+ self.assertEqual( policies[0][0], None )
-class Foo( DefaultDublinCoreImpl ):
- description = title = language = format = rights = ''
- subject = ()
+class TestMetadataSchema( unittest.TestCase ):
- def __init__( self ):
- pass # skip DDCI's default values
+ def _getTargetClass( self ):
+ from Products.CMFDefault.MetadataTool import MetadataSchema
+ return MetadataSchema
- def getPortalTypeName( self ):
- return 'Foo'
+ def _makeOne( self, *args, **kw ):
+ return self._getTargetClass()( *args, **kw )
-class Bar( Foo ):
+class TestMetadataTool( unittest.TestCase ):
- def getPortalTypeName( self ):
- return 'Bar'
+ def _getTargetClass( self ):
+ from Products.CMFDefault.MetadataTool import MetadataTool
+ return MetadataTool
+ def _makeOne( self, *args, **kw ):
+ return self._getTargetClass()( *args, **kw )
-class TestMetadataTool( TestCase ):
+ def _makeTestObjects( self ):
- def setUp( self ):
- self.tool = MetadataTool()
+ from Products.CMFDefault.DublinCore import DefaultDublinCoreImpl
+ class Foo( DefaultDublinCoreImpl ):
- def tearDown( self ):
- del self.tool
+ description = title = language = format = rights = ''
+ subject = ()
+ def __init__( self ):
+ pass # skip DDCI's default values
+
+ def getPortalTypeName( self ):
+ return 'Foo'
+
+
+ class Bar( Foo ):
+
+ def getPortalTypeName( self ):
+ return 'Bar'
+
+ return Foo(), Bar()
+
def test_z2interfaces(self):
from Interface.Verify import verifyClass
from Products.CMFCore.interfaces.portal_actions \
@@ -133,89 +147,92 @@
from Products.CMFCore.interfaces.portal_metadata \
import portal_metadata as IMetadataTool
- verifyClass(IActionProvider, MetadataTool)
- verifyClass(IMetadataTool, MetadataTool)
+ verifyClass(IActionProvider, self._getTargetClass())
+ verifyClass(IMetadataTool, self._getTargetClass())
def test_z3interfaces(self):
from zope.interface.verify import verifyClass
from Products.CMFCore.interfaces import IActionProvider
from Products.CMFCore.interfaces import IMetadataTool
- verifyClass(IActionProvider, MetadataTool)
- verifyClass(IMetadataTool, MetadataTool)
+ verifyClass(IActionProvider, self._getTargetClass())
+ verifyClass(IMetadataTool, self._getTargetClass())
def test_empty( self ):
+ from Products.CMFDefault.MetadataTool import _DCMI_ELEMENT_SPECS
- assert not self.tool.getPublisher()
- assert self.tool.getFullName( 'foo' ) == 'foo'
+ tool = self._makeOne()
+ self.failIf( tool.getPublisher() )
+ self.assertEqual( tool.getFullName( 'foo' ), 'foo' )
- specs = list( self.tool.listElementSpecs() )
- defaults = list( DEFAULT_ELEMENT_SPECS )
+ dcmi = tool.DCMI
+ specs = list( dcmi.DCMI.listElementSpecs() )
+ defaults = list( _DCMI_ELEMENT_SPECS )
specs.sort(); defaults.sort()
- assert len( specs ) == len( defaults )
+ self.assertEqual( len( specs ), len( defaults ) )
for i in range( len( specs ) ):
- assert specs[i][0] == defaults[i][0]
- assert specs[i][1].isMultiValued() == defaults[i][1]
+ self.assertEqual( specs[i][0], defaults[i][0] )
+ self.assertEqual( specs[i][1].isMultiValued(), defaults[i][1] )
policies = specs[i][1].listPolicies()
- assert len( policies ) == 1
- assert policies[0][0] is None
+ self.assertEqual( len( policies ), 1 )
+ self.failUnless( policies[0][0] is None )
- assert not self.tool.getElementSpec( 'Title' ).isMultiValued()
- assert not self.tool.getElementSpec( 'Description' ).isMultiValued()
- assert self.tool.getElementSpec( 'Subject' ).isMultiValued()
- assert not self.tool.getElementSpec( 'Format' ).isMultiValued()
- assert not self.tool.getElementSpec( 'Language' ).isMultiValued()
- assert not self.tool.getElementSpec( 'Rights' ).isMultiValued()
+ self.failIf( dcmi.getElementSpec( 'Title' ).isMultiValued() )
+ self.failIf( dcmi.getElementSpec( 'Description' ).isMultiValued() )
+ self.failUnless( dcmi.getElementSpec( 'Subject' ).isMultiValued() )
+ self.failIf( dcmi.getElementSpec( 'Format' ).isMultiValued() )
+ self.failIf( dcmi.getElementSpec( 'Language' ).isMultiValued() )
+ self.failIf( dcmi.getElementSpec( 'Rights' ).isMultiValued() )
try:
- dummy = self.tool.getElementSpec( 'Foo' )
+ dummy = dcmi.getElementSpec( 'Foo' )
except KeyError:
pass
else:
- assert 0, "Expected KeyError"
+ self.failUnless( 0, "Expected KeyError" )
- assert not self.tool.listAllowedSubjects()
- assert not self.tool.listAllowedFormats()
- assert not self.tool.listAllowedLanguages()
- assert not self.tool.listAllowedRights()
+ self.failIf( dcmi.listAllowedSubjects() )
+ self.failIf( dcmi.listAllowedFormats() )
+ self.failIf( dcmi.listAllowedLanguages() )
+ self.failIf( dcmi.listAllowedRights() )
- def test_add( self ):
- self.tool.addElementSpec( 'Rating', 1 )
- assert len( self.tool.listElementSpecs() ) \
- == len( DEFAULT_ELEMENT_SPECS ) + 1
- rating = self.tool.getElementSpec( 'Rating' )
- assert rating.isMultiValued()
+ def test_DCMI_addElementSpec( self ):
+ from Products.CMFDefault.MetadataTool import _DCMI_ELEMENT_SPECS
- def test_remove( self ):
- self.tool.removeElementSpec( 'Rights' )
+ tool = self._makeOne()
+ dcmi = tool.DCMI
+ dcmi.addElementSpec( 'Rating', 1 )
+ self.assertEqual( len( dcmi.listElementSpecs() )
+ , len( _DCMI_ELEMENT_SPECS ) + 1 )
+ rating = dcmi.getElementSpec( 'Rating' )
+ self.failUnless( rating.isMultiValued() )
- assert len( self.tool.listElementSpecs() ) \
- == len( DEFAULT_ELEMENT_SPECS ) - 1
+ def test_DCMI_removeElementSpec( self ):
+ from Products.CMFDefault.MetadataTool import _DCMI_ELEMENT_SPECS
- try:
- dummy = self.tool.getElementSpec( 'Rights' )
- except KeyError:
- pass
- else:
- assert 0, "Expected KeyError"
+ tool = self._makeOne()
+ dcmi = tool.DCMI
+ dcmi.removeElementSpec( 'Rights' )
- try:
- self.tool.removeElementSpec( 'Foo' )
- except KeyError:
- pass
- else:
- assert 0, "Expected KeyError"
+ self.assertEqual( len( dcmi.listElementSpecs() )
+ , len( _DCMI_ELEMENT_SPECS ) - 1
+ )
+ self.assertRaises( KeyError, dcmi.getElementSpec, 'Rights' )
+ self.assertRaises( KeyError, dcmi.removeElementSpec, 'Foo' )
+
def test_simplePolicies( self ):
- tSpec = self.tool.getElementSpec( 'Title' )
+ tool = self._makeOne()
+ dcmi = tool.DCMI
+ tSpec = dcmi.getElementSpec( 'Title' )
# Fetch default policy.
tDef = tSpec.getPolicy()
- assert not tDef.isRequired()
- assert not tDef.supplyDefault()
- assert not tDef.defaultValue()
+ self.failIf( tDef.isRequired() )
+ self.failIf( tDef.supplyDefault() )
+ self.failIf( tDef.defaultValue() )
# Fetch (default) policy for a type.
tDoc = tSpec.getPolicy( 'Document' )
@@ -223,40 +240,42 @@
# Changing default changes policies found from there.
tDef.edit( 1, 1, 'xyz', 0, () )
- assert tDef.isRequired()
- assert tDef.supplyDefault()
- assert tDef.defaultValue() == 'xyz'
- assert tDoc.isRequired()
- assert tDoc.supplyDefault()
- assert tDoc.defaultValue() == 'xyz'
+ self.failUnless( tDef.isRequired() )
+ self.failUnless( tDef.supplyDefault() )
+ self.assertEqual( tDef.defaultValue(), 'xyz' )
+ self.failUnless( tDoc.isRequired() )
+ self.failUnless( tDoc.supplyDefault() )
+ self.assertEqual( tDoc.defaultValue(), 'xyz' )
tSpec.addPolicy( 'Document' )
- assert len( tSpec.listPolicies() ) == 2
+ self.assertEqual( len( tSpec.listPolicies() ), 2 )
tDoc = tSpec.getPolicy( 'Document' )
self.assertNotEqual(aq_base(tDoc), aq_base(tDef))
- assert not tDoc.isRequired()
- assert not tDoc.supplyDefault()
- assert not tDoc.defaultValue()
+ self.failIf( tDoc.isRequired() )
+ self.failIf( tDoc.supplyDefault() )
+ self.failIf( tDoc.defaultValue() )
tSpec.removePolicy( 'Document' )
tDoc = tSpec.getPolicy( 'Document' )
self.assertEqual(aq_base(tDoc), aq_base(tDef))
- assert tDoc.isRequired()
- assert tDoc.supplyDefault()
- assert tDoc.defaultValue() == 'xyz'
+ self.failUnless( tDoc.isRequired() )
+ self.failUnless( tDoc.supplyDefault() )
+ self.assertEqual( tDoc.defaultValue(), 'xyz' )
def test_multiValuedPolicies( self ):
- sSpec = self.tool.getElementSpec( 'Subject' )
+ tool = self._makeOne()
+ dcmi = tool.DCMI
+ sSpec = dcmi.getElementSpec( 'Subject' )
# Fetch default policy.
sDef = sSpec.getPolicy()
- assert not sDef.isRequired()
- assert not sDef.supplyDefault()
- assert not sDef.defaultValue()
- assert not sDef.enforceVocabulary()
- assert not sDef.allowedVocabulary()
+ self.failIf( sDef.isRequired() )
+ self.failIf( sDef.supplyDefault() )
+ self.failIf( sDef.defaultValue() )
+ self.failIf( sDef.enforceVocabulary() )
+ self.failIf( sDef.allowedVocabulary() )
# Fetch (default) policy for a type.
sDoc = sSpec.getPolicy( 'Document' )
@@ -264,150 +283,266 @@
# Changing default changes policies found from there.
sDef.edit( 1, 1, 'xyz', 1, ( 'foo', 'bar' ) )
- assert sDef.isRequired()
- assert sDef.supplyDefault()
- assert sDef.defaultValue() == 'xyz'
- assert sDoc.isRequired()
- assert sDoc.supplyDefault()
- assert sDoc.defaultValue() == 'xyz'
- assert sDef.enforceVocabulary()
- assert len( sDef.allowedVocabulary() ) == 2
- assert 'foo' in sDef.allowedVocabulary()
- assert 'bar' in sDef.allowedVocabulary()
- assert sDoc.enforceVocabulary()
- assert len( sDoc.allowedVocabulary() ) == 2
- assert 'foo' in sDoc.allowedVocabulary()
- assert 'bar' in sDoc.allowedVocabulary()
+ self.failUnless( sDef.isRequired() )
+ self.failUnless( sDef.supplyDefault() )
+ self.assertEqual( sDef.defaultValue(), 'xyz' )
+ self.failUnless( sDoc.isRequired() )
+ self.failUnless( sDoc.supplyDefault() )
+ self.assertEqual( sDoc.defaultValue(), 'xyz' )
+ self.failUnless( sDef.enforceVocabulary() )
+ self.assertEqual( len( sDef.allowedVocabulary() ), 2 )
+ self.failUnless( 'foo' in sDef.allowedVocabulary() )
+ self.failUnless( 'bar' in sDef.allowedVocabulary() )
+ self.failUnless( sDoc.enforceVocabulary() )
+ self.assertEqual( len( sDoc.allowedVocabulary() ), 2 )
+ self.failUnless( 'foo' in sDoc.allowedVocabulary() )
+ self.failUnless( 'bar' in sDoc.allowedVocabulary() )
sSpec.addPolicy( 'Document' )
- assert len( sSpec.listPolicies() ) == 2
+ self.assertEqual( len( sSpec.listPolicies() ), 2 )
sDoc = sSpec.getPolicy( 'Document' )
self.assertNotEqual(aq_base(sDoc), aq_base(sDef))
- assert not sDoc.isRequired()
- assert not sDoc.supplyDefault()
- assert not sDoc.defaultValue()
- assert not sDoc.enforceVocabulary()
- assert not sDoc.allowedVocabulary()
+ self.failIf( sDoc.isRequired() )
+ self.failIf( sDoc.supplyDefault() )
+ self.failIf( sDoc.defaultValue() )
+ self.failIf( sDoc.enforceVocabulary() )
+ self.failIf( sDoc.allowedVocabulary() )
sSpec.removePolicy( 'Document' )
sDoc = sSpec.getPolicy( 'Document' )
self.assertEqual(aq_base(sDoc), aq_base(sDef))
- assert sDoc.isRequired()
- assert sDoc.supplyDefault()
- assert sDoc.defaultValue() == 'xyz'
- assert sDoc.enforceVocabulary()
- assert len( sDoc.allowedVocabulary() ) == 2
- assert 'foo' in sDoc.allowedVocabulary()
- assert 'bar' in sDoc.allowedVocabulary()
+ self.failUnless( sDoc.isRequired() )
+ self.failUnless( sDoc.supplyDefault() )
+ self.assertEqual( sDoc.defaultValue(), 'xyz' )
+ self.failUnless( sDoc.enforceVocabulary() )
+ self.assertEqual( len( sDoc.allowedVocabulary() ), 2 )
+ self.failUnless( 'foo' in sDoc.allowedVocabulary() )
+ self.failUnless( 'bar' in sDoc.allowedVocabulary() )
def test_vocabularies( self ):
- fSpec = self.tool.getElementSpec( 'Format' )
+ tool = self._makeOne()
+ dcmi = tool.DCMI
+ fSpec = dcmi.getElementSpec( 'Format' )
fDef = fSpec.getPolicy()
formats = ( 'text/plain', 'text/html' )
fDef.edit( 0, 0, '', 0, ( 'text/plain', 'text/html' ) )
- assert self.tool.listAllowedFormats() == formats
+ self.assertEqual( tool.listAllowedFormats(), formats )
- foo = Foo()
- assert self.tool.listAllowedFormats( foo ) == formats
+ foo, bar = self._makeTestObjects()
+
+ self.assertEqual( tool.listAllowedFormats( foo ), formats )
+
fSpec.addPolicy( 'Foo' )
- assert not self.tool.listAllowedFormats( foo )
+ self.failIf( tool.listAllowedFormats( foo ) )
+
foo_formats = ( 'image/jpeg', 'image/gif', 'image/png' )
fFoo = fSpec.getPolicy( 'Foo' )
fFoo.edit( 0, 0, '', 0, foo_formats )
- assert self.tool.listAllowedFormats( foo ) == foo_formats
+ self.assertEqual( tool.listAllowedFormats( foo ), foo_formats )
- def test_initialValues( self ):
- foo = Foo()
- assert not foo.Title()
- assert not foo.Description()
- assert not foo.Subject()
- assert not foo.Format(), foo.Format()
- assert not foo.Language()
- assert not foo.Rights()
+ def test_initialValues_defaults( self ):
+ tool = self._makeOne()
+ foo, bar = self._makeTestObjects()
+ self.failIf( foo.Title() )
+ self.failIf( foo.Description() )
+ self.failIf( foo.Subject() )
+ self.failIf( foo.Format(), foo.Format() )
+ self.failIf( foo.Language() )
+ self.failIf( foo.Rights() )
- self.tool.setInitialMetadata( foo )
- assert not foo.Title()
- assert not foo.Description()
- assert not foo.Subject()
- assert not foo.Format()
- assert not foo.Language()
- assert not foo.Rights()
+ tool.setInitialMetadata( foo )
+ self.failIf( foo.Title() )
+ self.failIf( foo.Description() )
+ self.failIf( foo.Subject() )
+ self.failIf( foo.Format() )
+ self.failIf( foo.Language() )
+ self.failIf( foo.Rights() )
+ def test_initialValues_implicit( self ):
# Test default policy.
- foo = Foo()
- fSpec = self.tool.getElementSpec( 'Format' )
+ tool = self._makeOne()
+ dcmi = tool.DCMI
+ foo, bar = self._makeTestObjects()
+ fSpec = dcmi.getElementSpec( 'Format' )
fPolicy = fSpec.getPolicy()
fPolicy.edit( 0, 1, 'text/plain', 0, () )
- self.tool.setInitialMetadata( foo )
- assert not foo.Title()
- assert not foo.Description()
- assert not foo.Subject()
- assert foo.Format() == 'text/plain'
- assert not foo.Language()
- assert not foo.Rights()
+ tool.setInitialMetadata( foo )
+ self.failIf( foo.Title() )
+ self.failIf( foo.Description() )
+ self.failIf( foo.Subject() )
+ self.assertEqual( foo.Format(), 'text/plain' )
+ self.failIf( foo.Language() )
+ self.failIf( foo.Rights() )
+ def test_initialValues_explicit_raises_if_constraint_fails( self ):
+ from Products.CMFDefault.exceptions import MetadataError
+
# Test type-specific policy.
- foo = Foo()
- tSpec = self.tool.getElementSpec( 'Title' )
+ tool = self._makeOne()
+ dcmi = tool.DCMI
+ foo, bar = self._makeTestObjects()
+ tSpec = dcmi.getElementSpec( 'Title' )
tSpec.addPolicy( 'Foo' )
tPolicy = tSpec.getPolicy( foo.getPortalTypeName() )
tPolicy.edit( 1, 0, '', 0, () )
- try:
- self.tool.setInitialMetadata( foo )
- except MetadataError:
- pass
- else:
- assert 0, "Expected MetadataError"
+ self.assertRaises( MetadataError, tool.setInitialMetadata, foo )
+ def test_initialValues_explicit_mutliple_types( self ):
+ from Products.CMFDefault.exceptions import MetadataError
+
+ tool = self._makeOne()
+ dcmi = tool.DCMI
+ foo, bar = self._makeTestObjects()
foo.setTitle( 'Foo title' )
- self.tool.setInitialMetadata( foo )
- assert foo.Title() == 'Foo title'
- assert not foo.Description()
- assert not foo.Subject()
- assert foo.Format() == 'text/plain'
- assert not foo.Language()
- assert not foo.Rights()
+ fSpec = dcmi.getElementSpec( 'Format' )
+ fSpec.addPolicy( foo.getPortalTypeName() )
+ fPolicy = fSpec.getPolicy( foo.getPortalTypeName() )
+ fPolicy.edit( 0, 1, 'text/plain', 0, () )
+
+ tool.setInitialMetadata( foo )
+ self.assertEqual( foo.Title(), 'Foo title' )
+ self.failIf( foo.Description() )
+ self.failIf( foo.Subject() )
+ self.assertEqual( foo.Format(), 'text/plain' )
+ self.failIf( foo.Language() )
+ self.failIf( foo.Rights() )
+
# Ensure Foo's policy doesn't interfere with other types.
- bar = Bar()
- self.tool.setInitialMetadata( bar )
- assert not bar.Title()
- assert not bar.Description()
- assert not bar.Subject()
- assert bar.Format() == 'text/plain'
- assert not bar.Language()
- assert not bar.Rights()
+ tool.setInitialMetadata( bar )
+ self.failIf( bar.Title() )
+ self.failIf( bar.Description() )
+ self.failIf( bar.Subject() )
+ self.assertEqual( bar.Format(), '' )
+ self.failIf( bar.Language() )
+ self.failIf( bar.Rights() )
def test_validation( self ):
+ from Products.CMFDefault.exceptions import MetadataError
- foo = Foo()
- self.tool.setInitialMetadata( foo )
- self.tool.validateMetadata( foo )
+ tool = self._makeOne()
+ foo, bar = self._makeTestObjects()
+ tool.setInitialMetadata( foo )
+ tool.validateMetadata( foo )
- tSpec = self.tool.getElementSpec( 'Title' )
+ dcmi = tool.DCMI
+ tSpec = dcmi.getElementSpec( 'Title' )
tSpec.addPolicy( 'Foo' )
tPolicy = tSpec.getPolicy( foo.getPortalTypeName() )
tPolicy.edit( 1, 0, '', 0, () )
- try:
- self.tool.validateMetadata( foo )
- except MetadataError:
- pass
- else:
- assert 0, "Expected MetadataError"
+ self.assertRaises( MetadataError, tool.validateMetadata, foo )
foo.setTitle( 'Foo title' )
- self.tool.validateMetadata( foo )
+ tool.validateMetadata( foo )
+ def test_addSchema_normal( self ):
+ from Products.CMFDefault.MetadataTool import MetadataSchema
+ tool = self._makeOne()
+ before = tool.listSchemas()
+ self.assertEqual( len( before ), 1 )
+ self.assertEqual( before[0][0], 'DCMI' )
+ self.failUnless( isinstance( before[0][1], MetadataSchema ) )
+
+ tool.addSchema( 'Arbitrary' )
+
+ after = tool.listSchemas()
+ self.assertEqual( len( after ), 2 )
+ self.assertEqual( after[0][0], 'DCMI' )
+ self.failUnless( isinstance( after[0][1], MetadataSchema ) )
+ self.assertEqual( after[1][0], 'Arbitrary' )
+ self.failUnless( isinstance( after[1][1], MetadataSchema ) )
+
+ def test_addSchema_duplicate( self ):
+ tool = self._makeOne()
+ before = tool.listSchemas()
+ tool.addSchema( 'Arbitrary' )
+ self.assertRaises( KeyError, tool.addSchema, 'Arbitrary' )
+ self.assertRaises( KeyError, tool.addSchema, 'DCMI' )
+
+ def test_removeSchema_normal( self ):
+ tool = self._makeOne()
+ before = tool.listSchemas()
+ self.assertEqual( len( before ), 1 )
+ self.assertEqual( before[0][0], 'DCMI' )
+
+ tool.addSchema( 'Arbitrary' )
+ tool.addSchema( 'Beneficent' )
+ tool.addSchema( 'Grouchy' )
+
+ middle = tool.listSchemas()
+ self.assertEqual( len( middle ), 4 )
+ self.assertEqual( middle[0][0], 'DCMI' )
+ self.assertEqual( middle[1][0], 'Arbitrary' )
+ self.assertEqual( middle[2][0], 'Beneficent' )
+ self.assertEqual( middle[3][0], 'Grouchy' )
+
+ tool.removeSchema( 'Beneficent' )
+
+ after = tool.listSchemas()
+ self.assertEqual( len( after ), 3 )
+ self.assertEqual( after[0][0], 'DCMI' )
+ self.assertEqual( after[1][0], 'Arbitrary' )
+ self.assertEqual( after[2][0], 'Grouchy' )
+
+ def test_removeSchema_invalid( self ):
+ tool = self._makeOne()
+ self.assertRaises( KeyError, tool.removeSchema, 'DCMI' )
+ tool.addSchema( 'Arbitrary' )
+ tool.removeSchema( 'Arbitrary' )
+ self.assertRaises( KeyError, tool.removeSchema, 'Arbitrary' )
+
+ def test_migration( self ):
+ # Test that we forward-migrate old-style DCMI policies.
+ from Products.CMFDefault.MetadataTool import ElementSpec
+ from Products.CMFDefault.MetadataTool import _DCMI_ELEMENT_SPECS
+
+ tool = self._makeOne()
+ tool.element_specs = { 'Title' : ElementSpec( 0 )
+ , 'Description' : ElementSpec( 0 )
+ , 'Subject' : ElementSpec( 1 )
+ , 'Format' : ElementSpec( 0 )
+ , 'Language' : ElementSpec( 0 )
+ , 'Rights' : ElementSpec( 0 )
+ }
+ subj = tool.element_specs[ 'Subject' ]
+ subj.addPolicy( 'Foo' )
+ subj.getPolicy( 'Foo' ).edit( False
+ , False
+ , None
+ , True
+ , ( 'bar', 'baz' )
+ )
+
+ dcmi = tool.DCMI
+
+ self.assertEqual( dcmi.getId(), 'DCMI' )
+
+ # Accessing the DCMI property converts and clears 'element_specs'
+ self.assertRaises(AttributeError, lambda: tool.element_specs )
+
+ subj2 = dcmi.getElementSpec( 'Subject' )
+ subj_default = subj2.getPolicy( None )
+ subj_foo = subj2.getPolicy( 'Foo' )
+
+ self.assertEqual( subj_foo.isRequired(), False )
+ self.assertEqual( subj_foo.supplyDefault(), False )
+ self.assertEqual( subj_foo.defaultValue(), None )
+ self.assertEqual( subj_foo.enforceVocabulary(), True )
+ self.assertEqual( len( subj_foo.allowedVocabulary() ), 2 )
+ self.failUnless( 'bar' in subj_foo.allowedVocabulary() )
+ self.failUnless( 'baz' in subj_foo.allowedVocabulary() )
+
+
def test_suite():
- return TestSuite((
- makeSuite(TestMetadataElementPolicy),
- makeSuite(TestElementSpec),
- makeSuite(TestMetadataTool),
+ return unittest.TestSuite((
+ unittest.makeSuite(TestMetadataElementPolicy),
+ unittest.makeSuite(TestElementSpec),
+ unittest.makeSuite(TestMetadataTool),
))
if __name__ == '__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Modified: CMF/branches/tseaver-viewification/CMFDefault/tests/test_Portal.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/tests/test_Portal.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/tests/test_Portal.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,10 +15,8 @@
$Id$
"""
-from unittest import TestSuite, makeSuite, main
+import unittest
import Testing
-import Zope2
-Zope2.startup()
import Products
from Acquisition import aq_base
@@ -51,8 +49,10 @@
PlacelessSetup.setUp(self)
SecurityRequestTest.setUp(self)
zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
zcml.load_config('configure.zcml', Products.GenericSetup)
zcml.load_config('configure.zcml', Products.CMFCore)
+ zcml.load_config('configure.zcml', Products.DCWorkflow)
def tearDown(self):
SecurityRequestTest.tearDown(self)
@@ -207,9 +207,9 @@
def test_suite():
- return TestSuite((
- makeSuite(CMFSiteTests),
+ return unittest.TestSuite((
+ unittest.makeSuite(CMFSiteTests),
))
if __name__ == '__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Modified: CMF/branches/tseaver-viewification/CMFDefault/tests/test_join.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFDefault/tests/test_join.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFDefault/tests/test_join.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,16 +15,31 @@
$Id$
"""
-from unittest import TestSuite, makeSuite, main
+import unittest
import Testing
-import Zope2
-Zope2.startup()
+import Products
+from Products.Five import zcml
+
+from Products.CMFCore.tests.base.testcase import PlacelessSetup
from Products.CMFCore.tests.base.testcase import TransactionalTest
-class MembershipTests( TransactionalTest ):
+class MembershipTests(PlacelessSetup, TransactionalTest):
+ def setUp(self):
+ PlacelessSetup.setUp(self)
+ TransactionalTest.setUp(self)
+ zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
+ zcml.load_config('configure.zcml', Products.GenericSetup)
+ zcml.load_config('configure.zcml', Products.CMFCore)
+ zcml.load_config('configure.zcml', Products.DCWorkflow)
+
+ def tearDown(self):
+ TransactionalTest.tearDown(self)
+ PlacelessSetup.tearDown(self)
+
def _makePortal(self):
# Create a portal instance suitable for testing
factory = self.root.manage_addProduct['CMFDefault'].addConfiguredSite
@@ -101,9 +116,9 @@
def test_suite():
- return TestSuite((
- makeSuite(MembershipTests),
+ return unittest.TestSuite((
+ unittest.makeSuite(MembershipTests),
))
if __name__ == '__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Modified: CMF/branches/tseaver-viewification/CMFTopic/DEPENDENCIES.txt
===================================================================
--- CMF/branches/tseaver-viewification/CMFTopic/DEPENDENCIES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFTopic/DEPENDENCIES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,4 +1,4 @@
-Zope >= 2.8.2
+Zope >= 2.8.5
Five >= 1.2
CMFCore
CMFDefault
Modified: CMF/branches/tseaver-viewification/CMFTopic/Topic.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFTopic/Topic.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFTopic/Topic.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -21,12 +21,19 @@
from Products.CMFDefault.SkinnedFolder import SkinnedFolder
from Products.CMFCore.utils import getToolByName
+from zope.interface import Interface
+from zope.interface import implements
+from zope.interface import implementedBy
from permissions import View
from permissions import AddTopics
from permissions import ChangeTopics
+class ITopic(Interface):
+ """ Marker interface.
+ """
+
def addTopic( self, id, title='', REQUEST=None ):
""" Create an empty topic.
"""
@@ -46,7 +53,7 @@
o Each topic holds a set of zero or more Criteria objects specifying
the query.
"""
-
+ implements(ITopic, implementedBy(SkinnedFolder))
meta_type='Portal Topic'
security = ClassSecurityInfo()
Modified: CMF/branches/tseaver-viewification/CMFTopic/__init__.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFTopic/__init__.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFTopic/__init__.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -19,6 +19,7 @@
from ZClasses import createZClassForBase
+from Products.CMFCore.interfaces import ISiteRoot
from Products.CMFCore.utils import ContentInit
from Products.CMFCore.DirectoryView import registerDirectory
from Products.GenericSetup import EXTENSION
@@ -64,4 +65,6 @@
'Adds topic portal type.',
'profiles/default',
'CMFTopic',
- EXTENSION)
+ EXTENSION,
+ for_=ISiteRoot,
+ )
Copied: CMF/branches/tseaver-viewification/CMFTopic/configure.zcml (from rev 40492, CMF/trunk/CMFTopic/configure.zcml)
Copied: CMF/branches/tseaver-viewification/CMFTopic/exportimport.py (from rev 40492, CMF/trunk/CMFTopic/exportimport.py)
Modified: CMF/branches/tseaver-viewification/CMFTopic/profiles/default/skins.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFTopic/profiles/default/skins.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFTopic/profiles/default/skins.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,8 +1,8 @@
<?xml version="1.0"?>
-<skins-tool>
- <skin-directory id="zpt_topic"
- directory="CMFTopic/skins/zpt_topic"/>
- <skin-path id="*">
+<object name="portal_skins" meta_type="CMF Skins Tool">
+ <object name="zpt_topic" meta_type="Filesystem Directory View"
+ directory="CMFTopic/skins/zpt_topic"/>
+ <skin-path name="*">
<layer name="zpt_topic" insert-before="zpt_content"/>
</skin-path>
-</skins-tool>
+</object>
Modified: CMF/branches/tseaver-viewification/CMFTopic/profiles/default/typestool.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFTopic/profiles/default/typestool.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFTopic/profiles/default/typestool.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,4 +1,4 @@
<?xml version="1.0"?>
-<types-tool>
- <type id="Topic"/>
-</types-tool>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <object name="Topic" meta_type="Factory-based Type Information"/>
+</object>
Modified: CMF/branches/tseaver-viewification/CMFTopic/profiles/default/workflows.xml
===================================================================
--- CMF/branches/tseaver-viewification/CMFTopic/profiles/default/workflows.xml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFTopic/profiles/default/workflows.xml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,8 +1,6 @@
<?xml version="1.0"?>
-<workflow-tool>
+<object name="portal_workflow" meta_type="CMF Workflow Tool">
<bindings>
- <type type_id="Topic">
-
- </type>
+ <type type_id="Topic"/>
</bindings>
-</workflow-tool>
+</object>
Modified: CMF/branches/tseaver-viewification/CMFTopic/tests/test_DateC.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFTopic/tests/test_DateC.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFTopic/tests/test_DateC.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,17 +15,17 @@
$Id$
"""
-from unittest import TestSuite, makeSuite, main
+import unittest
import Testing
-import Zope2
-Zope2.startup()
import Products
from DateTime.DateTime import DateTime
+
from Products.CMFCore.tests.base.testcase import PlacelessSetup
from Products.CMFCore.tests.base.testcase import RequestTest
from Products.CMFCore.tests.base.dummy import DummyContent
from Products.CMFTopic.Topic import Topic
+
from common import CriterionTestCase
@@ -165,8 +165,10 @@
PlacelessSetup.setUp(self)
RequestTest.setUp(self)
zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
zcml.load_config('configure.zcml', Products.GenericSetup)
zcml.load_config('configure.zcml', Products.CMFCore)
+ zcml.load_config('configure.zcml', Products.DCWorkflow)
factory = self.root.manage_addProduct['CMFDefault'].addConfiguredSite
factory('site', 'CMFDefault:default', snapshot=False)
@@ -384,10 +386,10 @@
def test_suite():
- return TestSuite((
- makeSuite(FriendlyDateCriterionTests),
- makeSuite(FriendlyDateCriterionFunctionalTests),
+ return unittest.TestSuite((
+ unittest.makeSuite(FriendlyDateCriterionTests),
+ unittest.makeSuite(FriendlyDateCriterionFunctionalTests),
))
if __name__ == '__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Copied: CMF/branches/tseaver-viewification/CMFTopic/tests/test_exportimport.py (from rev 40492, CMF/trunk/CMFTopic/tests/test_exportimport.py)
Copied: CMF/branches/tseaver-viewification/CMFTopic/xml (from rev 40492, CMF/trunk/CMFTopic/xml)
Modified: CMF/branches/tseaver-viewification/CMFUid/DEPENDENCIES.txt
===================================================================
--- CMF/branches/tseaver-viewification/CMFUid/DEPENDENCIES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFUid/DEPENDENCIES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,4 +1,4 @@
-Zope >= 2.8.2
+Zope >= 2.8.5
Five >= 1.2
CMFCore
GenericSetup
Modified: CMF/branches/tseaver-viewification/CMFUid/__init__.py
===================================================================
--- CMF/branches/tseaver-viewification/CMFUid/__init__.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/CMFUid/__init__.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -18,6 +18,7 @@
from sys import modules
from Products.CMFCore import utils
+from Products.CMFCore.interfaces import ISiteRoot
from Products.GenericSetup import EXTENSION
from Products.GenericSetup import profile_registry
@@ -51,4 +52,6 @@
'Adds UID support.',
'profiles/default',
'CMFUid',
- EXTENSION)
+ EXTENSION,
+ for_=ISiteRoot,
+ )
Modified: CMF/branches/tseaver-viewification/DCWorkflow/DCWorkflow.py
===================================================================
--- CMF/branches/tseaver-viewification/DCWorkflow/DCWorkflow.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/DCWorkflow/DCWorkflow.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -35,9 +35,9 @@
from Products.CMFCore.WorkflowCore import ObjectDeleted
from Products.CMFCore.WorkflowCore import ObjectMoved
from Products.CMFCore.WorkflowCore import WorkflowException
-from Products.CMFCore.WorkflowTool import addWorkflowFactory
# DCWorkflow
+from interfaces import IDCWorkflowDefinition
from permissions import ManagePortal
from utils import modifyRolesForPermission
from utils import modifyRolesForGroup
@@ -63,10 +63,9 @@
UI methods are in WorkflowUIMixin.
'''
- implements(IWorkflowDefinition)
+ implements(IDCWorkflowDefinition, IWorkflowDefinition)
__implements__ = z2IWorkflowDefinition
- meta_type = 'Workflow'
title = 'DC Workflow Definition'
_isAWorkflow = 1
@@ -414,7 +413,7 @@
tdef = t
break
return tdef
-
+
def _changeStateOf(self, ob, tdef=None, kwargs=None):
'''
Changes state. Can execute multiple transitions if there are
@@ -537,7 +536,3 @@
return new_sdef
InitializeClass(DCWorkflowDefinition)
-
-
-addWorkflowFactory(DCWorkflowDefinition, id='dc_workflow',
- title='Web-configurable workflow')
Modified: CMF/branches/tseaver-viewification/DCWorkflow/DEPENDENCIES.txt
===================================================================
--- CMF/branches/tseaver-viewification/DCWorkflow/DEPENDENCIES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/DCWorkflow/DEPENDENCIES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,3 +1,4 @@
-Zope >= 2.8.2
+Zope >= 2.8.5
Five >= 1.2
CMFCore
+GenericSetup
Deleted: CMF/branches/tseaver-viewification/DCWorkflow/Default.py
===================================================================
--- CMF/branches/tseaver-viewification/DCWorkflow/Default.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/DCWorkflow/Default.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,321 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-""" Programmatically creates a workflow.
-
-$Id$
-"""
-
-from Products.CMFCore.WorkflowTool import addWorkflowFactory
-
-from DCWorkflow import DCWorkflowDefinition
-from permissions import AccessContentsInformation
-from permissions import ModifyPortalContent
-from permissions import RequestReview
-from permissions import ReviewPortalContent
-from permissions import View
-
-p_access = AccessContentsInformation
-p_modify = ModifyPortalContent
-p_request = RequestReview
-p_review = ReviewPortalContent
-p_view = View
-
-r_anon = 'Anonymous'
-r_manager = 'Manager'
-r_reviewer = 'Reviewer'
-r_owner = 'Owner'
-r_member = 'Member'
-
-
-
-def setupDefaultWorkflowRev2(wf):
- '''
- Sets up a DCWorkflow with the addition of a visible state,
- the show and hide transitions, and corresponding changes.
- wf is a DCWorkflow instance.
- '''
- wf.setProperties(title='CMF default workflow [Revision 2]')
-
- for s in ('private', 'visible', 'pending', 'published'):
- wf.states.addState(s)
- for t in ('publish', 'reject', 'retract', 'submit', 'hide', 'show'):
- wf.transitions.addTransition(t)
- for v in ('action', 'actor', 'comments', 'review_history', 'time'):
- wf.variables.addVariable(v)
- for l in ('reviewer_queue',):
- wf.worklists.addWorklist(l)
- for p in (p_access, p_modify, p_view):
- wf.addManagedPermission(p)
-
- wf.states.setInitialState('visible')
-
- sdef = wf.states['private']
- sdef.setProperties(
- title='Visible and editable only by owner',
- transitions=('show',))
- sdef.setPermission(p_access, 0, (r_manager, r_owner))
- sdef.setPermission(p_view, 0, (r_manager, r_owner))
- sdef.setPermission(p_modify, 0, (r_manager, r_owner))
-
- sdef = wf.states['pending']
- sdef.setProperties(
- title='Waiting for reviewer',
- transitions=('hide', 'publish', 'reject', 'retract',))
- sdef.setPermission(p_access, 1, (r_manager, r_owner, r_reviewer))
- sdef.setPermission(p_view, 1, (r_manager, r_owner, r_reviewer))
- sdef.setPermission(p_modify, 0, (r_manager, r_reviewer))
-
- sdef = wf.states['published']
- sdef.setProperties(
- title='Public',
- transitions=('reject', 'retract',))
- sdef.setPermission(p_access, 1, (r_anon, r_manager))
- sdef.setPermission(p_view, 1, (r_anon, r_manager))
- sdef.setPermission(p_modify, 0, (r_manager,))
-
- sdef = wf.states['visible']
- sdef.setProperties(
- title='Visible but not published',
- transitions=('hide', 'publish', 'submit',))
- sdef.setPermission(p_access, 1, (r_anon, r_manager, r_reviewer))
- sdef.setPermission(p_view, 1, (r_anon, r_manager, r_reviewer))
- sdef.setPermission(p_modify, 0, (r_manager, r_owner))
-
- tdef = wf.transitions['hide']
- tdef.setProperties(
- title='Member makes content private',
- new_state_id='private',
- actbox_name='Make private',
- actbox_url='%(content_url)s/content_hide_form',
- props={'guard_roles':r_owner})
-
- tdef = wf.transitions['publish']
- tdef.setProperties(
- title='Reviewer publishes content',
- new_state_id='published',
- actbox_name='Publish',
- actbox_url='%(content_url)s/content_publish_form',
- props={'guard_permissions':p_review})
-
- tdef = wf.transitions['reject']
- tdef.setProperties(
- title='Reviewer rejects submission',
- new_state_id='visible',
- actbox_name='Reject',
- actbox_url='%(content_url)s/content_reject_form',
- props={'guard_permissions':p_review})
-
- tdef = wf.transitions['retract']
- tdef.setProperties(
- title='Member retracts submission',
- new_state_id='visible',
- actbox_name='Retract',
- actbox_url='%(content_url)s/content_retract_form',
- props={'guard_permissions':p_request})
-
- tdef = wf.transitions['show']
- tdef.setProperties(
- title='Member makes content visible',
- new_state_id='visible',
- actbox_name='Make visible',
- actbox_url='%(content_url)s/content_show_form',
- props={'guard_roles':r_owner})
-
- tdef = wf.transitions['submit']
- tdef.setProperties(
- title='Member requests publishing',
- new_state_id='pending',
- actbox_name='Submit',
- actbox_url='%(content_url)s/content_submit_form',
- props={'guard_permissions':p_request})
-
- wf.variables.setStateVar('review_state')
-
- vdef = wf.variables['action']
- vdef.setProperties(description='The last transition',
- default_expr='transition/getId|nothing',
- for_status=1, update_always=1)
-
- vdef = wf.variables['actor']
- vdef.setProperties(description='The ID of the user who performed '
- 'the last transition',
- default_expr='user/getId',
- for_status=1, update_always=1)
-
- vdef = wf.variables['comments']
- vdef.setProperties(description='Comments about the last transition',
- default_expr="python:state_change.kwargs.get('comment', '')",
- for_status=1, update_always=1)
-
- vdef = wf.variables['review_history']
- vdef.setProperties(description='Provides access to workflow history',
- default_expr="state_change/getHistory",
- props={'guard_permissions':
- p_request + ';' + p_review})
-
- vdef = wf.variables['time']
- vdef.setProperties(description='Time of the last transition',
- default_expr="state_change/getDateTime",
- for_status=1, update_always=1)
-
- ldef = wf.worklists['reviewer_queue']
- ldef.setProperties(description='Reviewer tasks',
- actbox_name='Pending (%(count)d)',
- actbox_url='%(portal_url)s/search?review_state=pending',
- props={'var_match_review_state':'pending',
- 'guard_permissions':p_review})
-
-
-def createDefaultWorkflowRev2(id):
- '''
- '''
- ob = DCWorkflowDefinition(id)
- setupDefaultWorkflowRev2(ob)
- return ob
-
-addWorkflowFactory(createDefaultWorkflowRev2, id='default_workflow',
- title='Web-configurable workflow [Revision 2]')
-
-
-
-
-
-
-
-
-
-def setupDefaultWorkflowClassic(wf):
- '''
- Sets up a DCWorkflow as close as possible to the old DefaultWorkflow,
- with only the private, pending, and published states.
- wf is a DCWorkflow instance.
- '''
- wf.setProperties(title='CMF default workflow [Classic]')
-
- for s in ('private', 'pending', 'published'):
- wf.states.addState(s)
- for t in ('publish', 'reject', 'retract', 'submit'):
- wf.transitions.addTransition(t)
- for v in ('action', 'actor', 'comments', 'review_history', 'time'):
- wf.variables.addVariable(v)
- for l in ('reviewer_queue',):
- wf.worklists.addWorklist(l)
- for p in (p_access, p_modify, p_view):
- wf.addManagedPermission(p)
-
- wf.states.setInitialState('private')
-
- sdef = wf.states['private']
- sdef.setProperties(
- title='Non-visible and editable only by owner',
- transitions=('submit', 'publish',))
- sdef.setPermission(p_access, 0, (r_manager, r_owner))
- sdef.setPermission(p_view, 0, (r_manager, r_owner))
- sdef.setPermission(p_modify, 0, (r_manager, r_owner))
-
- sdef = wf.states['pending']
- sdef.setProperties(
- title='Waiting for reviewer',
- transitions=('publish', 'reject', 'retract',))
- sdef.setPermission(p_access, 0, (r_manager, r_owner, r_reviewer))
- sdef.setPermission(p_view, 0, (r_manager, r_owner, r_reviewer))
- sdef.setPermission(p_modify, 0, (r_manager, r_reviewer))
-
- sdef = wf.states['published']
- sdef.setProperties(
- title='Public',
- transitions=('reject', 'retract',))
- sdef.setPermission(p_access, 1, (r_anon, r_manager))
- sdef.setPermission(p_view, 1, (r_anon, r_manager))
- sdef.setPermission(p_modify, 0, (r_manager,))
-
- tdef = wf.transitions['publish']
- tdef.setProperties(
- title='Reviewer publishes content',
- new_state_id='published',
- actbox_name='Publish',
- actbox_url='%(content_url)s/content_publish_form',
- props={'guard_permissions':p_review})
-
- tdef = wf.transitions['reject']
- tdef.setProperties(
- title='Reviewer rejects submission',
- new_state_id='private',
- actbox_name='Reject',
- actbox_url='%(content_url)s/content_reject_form',
- props={'guard_permissions':p_review})
-
- tdef = wf.transitions['retract']
- tdef.setProperties(
- title='Member retracts submission',
- new_state_id='private',
- actbox_name='Retract',
- actbox_url='%(content_url)s/content_retract_form',
- props={'guard_permissions':p_request})
-
- tdef = wf.transitions['submit']
- tdef.setProperties(
- title='Member requests publishing',
- new_state_id='pending',
- actbox_name='Submit',
- actbox_url='%(content_url)s/content_submit_form',
- props={'guard_permissions':p_request})
-
- wf.variables.setStateVar('review_state')
-
- vdef = wf.variables['action']
- vdef.setProperties(description='The last transition',
- default_expr='transition/getId|nothing',
- for_status=1, update_always=1)
-
- vdef = wf.variables['actor']
- vdef.setProperties(description='The ID of the user who performed '
- 'the last transition',
- default_expr='user/getId',
- for_status=1, update_always=1)
-
- vdef = wf.variables['comments']
- vdef.setProperties(description='Comments about the last transition',
- default_expr="python:state_change.kwargs.get('comment', '')",
- for_status=1, update_always=1)
-
- vdef = wf.variables['review_history']
- vdef.setProperties(description='Provides access to workflow history',
- default_expr="state_change/getHistory",
- props={'guard_permissions':
- p_request + ';' + p_review})
-
- vdef = wf.variables['time']
- vdef.setProperties(description='Time of the last transition',
- default_expr="state_change/getDateTime",
- for_status=1, update_always=1)
-
- ldef = wf.worklists['reviewer_queue']
- ldef.setProperties(description='Reviewer tasks',
- actbox_name='Pending (%(count)d)',
- actbox_url='%(portal_url)s/search?review_state=pending',
- props={'var_match_review_state':'pending',
- 'guard_permissions':p_review})
-
-
-
-def createDefaultWorkflowClassic(id):
- '''
- '''
- ob = DCWorkflowDefinition(id)
- setupDefaultWorkflowClassic(ob)
- return ob
-
-addWorkflowFactory(createDefaultWorkflowClassic, id='default_workflow',
- title='Web-configurable workflow [Classic]')
-
Copied: CMF/branches/tseaver-viewification/DCWorkflow/Extensions (from rev 40492, CMF/trunk/DCWorkflow/Extensions)
Modified: CMF/branches/tseaver-viewification/DCWorkflow/__init__.py
===================================================================
--- CMF/branches/tseaver-viewification/DCWorkflow/__init__.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/DCWorkflow/__init__.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,30 +1,33 @@
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
-#
+#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
-#
+#
##############################################################################
""" Web-configurable workflow.
$Id$
"""
+from Products.CMFCore.interfaces import ISiteRoot
from Products.CMFCore.utils import registerIcon
+from Products.GenericSetup import EXTENSION
+from Products.GenericSetup import profile_registry
+
import DCWorkflow, States, Transitions, Variables, Worklists, Scripts
-import Default
def initialize(context):
-
+
context.registerHelp(directory='help')
context.registerHelpTitle('DCWorkflow')
-
+
registerIcon(DCWorkflow.DCWorkflowDefinition,
'images/workflow.gif', globals())
registerIcon(States.States,
@@ -41,3 +44,11 @@
Worklists.WorklistDefinition.icon = Worklists.Worklists.icon
registerIcon(Scripts.Scripts,
'images/script.gif', globals())
+
+ profile_registry.registerProfile('revision2',
+ 'CMF Default Workflow [Revision 2]',
+ 'Adds revision 2 of default workflow.',
+ 'profiles/revision2',
+ 'DCWorkflow',
+ EXTENSION,
+ for_=ISiteRoot)
Copied: CMF/branches/tseaver-viewification/DCWorkflow/browser (from rev 40492, CMF/trunk/DCWorkflow/browser)
Copied: CMF/branches/tseaver-viewification/DCWorkflow/configure.zcml (from rev 40492, CMF/trunk/DCWorkflow/configure.zcml)
Copied: CMF/branches/tseaver-viewification/DCWorkflow/exportimport.py (from rev 40492, CMF/trunk/DCWorkflow/exportimport.py)
Copied: CMF/branches/tseaver-viewification/DCWorkflow/interfaces.py (from rev 40492, CMF/trunk/DCWorkflow/interfaces.py)
Copied: CMF/branches/tseaver-viewification/DCWorkflow/profiles (from rev 40492, CMF/trunk/DCWorkflow/profiles)
Modified: CMF/branches/tseaver-viewification/DCWorkflow/tests/test_DCWorkflow.py
===================================================================
--- CMF/branches/tseaver-viewification/DCWorkflow/tests/test_DCWorkflow.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/DCWorkflow/tests/test_DCWorkflow.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,27 +15,21 @@
$Id$
"""
-from unittest import TestCase, TestSuite, makeSuite, main
+import unittest
import Testing
-import Zope2
-Zope2.startup()
from Products.CMFCore.tests.base.dummy import DummyContent
from Products.CMFCore.tests.base.dummy import DummySite
from Products.CMFCore.tests.base.dummy import DummyTool
-from Products.CMFCore.WorkflowTool import addWorkflowFactory
from Products.CMFCore.WorkflowTool import WorkflowTool
-class DCWorkflowDefinitionTests(TestCase):
+class DCWorkflowDefinitionTests(unittest.TestCase):
def setUp(self):
- from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
-
self.site = DummySite('site')
self.site._setObject( 'portal_types', DummyTool() )
self.site._setObject( 'portal_workflow', WorkflowTool() )
- addWorkflowFactory(DCWorkflowDefinition)
self._constructDummyWorkflow()
def test_z2interfaces(self):
@@ -54,9 +48,10 @@
verifyClass(IWorkflowDefinition, DCWorkflowDefinition)
def _constructDummyWorkflow(self):
+ from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
wftool = self.site.portal_workflow
- wftool.manage_addWorkflow('Workflow (DC Workflow Definition)', 'wf')
+ wftool._setObject('wf', DCWorkflowDefinition('wf'))
wftool.setDefaultChain('wf')
wf = wftool.wf
@@ -128,9 +123,9 @@
def test_suite():
- return TestSuite((
- makeSuite(DCWorkflowDefinitionTests),
+ return unittest.TestSuite((
+ unittest.makeSuite(DCWorkflowDefinitionTests),
))
if __name__ == '__main__':
- main(defaultTest='test_suite')
+ unittest.main(defaultTest='test_suite')
Copied: CMF/branches/tseaver-viewification/DCWorkflow/tests/test_exportimport.py (from rev 40492, CMF/trunk/DCWorkflow/tests/test_exportimport.py)
Modified: CMF/branches/tseaver-viewification/DCWorkflow/tests/test_guard.py
===================================================================
--- CMF/branches/tseaver-viewification/DCWorkflow/tests/test_guard.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/DCWorkflow/tests/test_guard.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -15,32 +15,31 @@
$Id$
"""
-from unittest import TestCase, TestSuite, makeSuite, main
+import unittest
+import Testing
from AccessControl import getSecurityManager
from Products.PageTemplates.TALES import CompilerError
+from Products.CMFCore.tests.base.dummy import DummyContent
+from Products.CMFCore.tests.base.dummy import DummySite
+from Products.CMFCore.tests.base.dummy import DummyTool
from Products.CMFCore.WorkflowTool import WorkflowTool
-from Products.CMFCore.WorkflowTool import addWorkflowFactory
from Products.DCWorkflow.Guard import Guard
from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
-from Products.CMFCore.tests.base.dummy import DummyContent
-from Products.CMFCore.tests.base.dummy import DummySite
-from Products.CMFCore.tests.base.dummy import DummyTool
-class TestGuard(TestCase):
+class TestGuard(unittest.TestCase):
def setUp(self):
self.site = DummySite('site')
self.site._setObject( 'portal_types', DummyTool() )
self.site._setObject( 'portal_workflow', WorkflowTool() )
- addWorkflowFactory(DCWorkflowDefinition)
# Construct a workflow
wftool = self.site.portal_workflow
- wftool.manage_addWorkflow('Workflow (DC Workflow Definition)', 'wf')
+ wftool._setObject('wf', DCWorkflowDefinition('wf'))
wftool.setDefaultChain('wf')
def _getDummyWorkflow(self):
@@ -260,11 +259,11 @@
# XXX more tests with permissions and roles
+
def test_suite():
- return TestSuite((
- makeSuite(TestGuard),
+ return unittest.TestSuite((
+ unittest.makeSuite(TestGuard),
))
if __name__ == '__main__':
- main(defaultTest='test_suite')
-
+ unittest.main(defaultTest='test_suite')
Modified: CMF/branches/tseaver-viewification/DCWorkflow/utils.py
===================================================================
--- CMF/branches/tseaver-viewification/DCWorkflow/utils.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/DCWorkflow/utils.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,14 +1,14 @@
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
-#
+#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
-#
+#
##############################################################################
""" Some common utilities.
@@ -16,15 +16,15 @@
"""
import os
+
+from AccessControl.Permission import Permission
+from AccessControl.Role import gather_permissions
from App.Common import package_home
_dtmldir = os.path.join( package_home( globals() ), 'dtml' )
+_xmldir = os.path.join( package_home( globals() ), 'xml' )
-from AccessControl.Role import gather_permissions
-from AccessControl.Permission import Permission
-from Acquisition import aq_base
-
def ac_inherited_permissions(ob, all=0):
# Get all permissions not defined in ourself that are inherited
# This will be a sequence of tuples with a name as the first item and
Copied: CMF/branches/tseaver-viewification/DCWorkflow/xml (from rev 40492, CMF/trunk/DCWorkflow/xml)
Modified: CMF/branches/tseaver-viewification/GenericSetup/CHANGES.txt
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/CHANGES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/CHANGES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -2,6 +2,12 @@
After GenericSetup 1.0
+ - Added 'for_' argument to profile registry operations.
+ A profile may be registered and queried as appropriate to a specific
+ site interface; the default value, 'None', indicates that the profile
+ is relevant to any site. Note that this is essentially an adapter
+ lookup; perhaps we should reimplement it so.
+
- Forward ported changes from GenericSetup 0.11 and 0.12 (which were
created in a separate repository).
Modified: CMF/branches/tseaver-viewification/GenericSetup/DEPENDENCIES.txt
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/DEPENDENCIES.txt 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/DEPENDENCIES.txt 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1,2 +1,2 @@
-Zope >= 2.8.2
+Zope >= 2.8.5
Five >= 1.2
Modified: CMF/branches/tseaver-viewification/GenericSetup/MailHost/configure.zcml
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/MailHost/configure.zcml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/MailHost/configure.zcml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -3,15 +3,10 @@
>
<adapter
- factory=".exportimport.MailHostNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeExporter"
- for="Products.MailHost.interfaces.IMailHost"
+ factory=".exportimport.MailHostXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.MailHost.interfaces.IMailHost
+ Products.GenericSetup.interfaces.ISetupContext"
/>
- <adapter
- factory=".exportimport.MailHostNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeImporter"
- for="Products.MailHost.interfaces.IMailHost"
- />
-
</configure>
Modified: CMF/branches/tseaver-viewification/GenericSetup/MailHost/exportimport.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/MailHost/exportimport.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/MailHost/exportimport.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -16,18 +16,20 @@
"""
from Products.GenericSetup.interfaces import PURGE
-from Products.GenericSetup.utils import NodeAdapterBase
+from Products.GenericSetup.utils import XMLAdapterBase
from Products.MailHost.interfaces import IMailHost
-class MailHostNodeAdapter(NodeAdapterBase):
+class MailHostXMLAdapter(XMLAdapterBase):
- """Node im- and exporter for MailHost.
+ """XML im- and exporter for MailHost.
"""
__used_for__ = IMailHost
+ _LOGGER_ID = 'mailhost'
+
def exportNode(self, doc):
"""Export the object as a DOM node.
"""
@@ -37,6 +39,8 @@
node.setAttribute('smtp_port', str(self.context.smtp_port))
node.setAttribute('smtp_uid', self.context.smtp_uid)
node.setAttribute('smtp_pwd', self.context.smtp_pwd)
+
+ self._logger.info('Mailhost exported.')
return node
def importNode(self, node, mode=PURGE):
@@ -46,3 +50,5 @@
self.context.smtp_port = int(node.getAttribute('smtp_port'))
self.context.smtp_uid = node.getAttribute('smtp_uid').encode('utf-8')
self.context.smtp_pwd = node.getAttribute('smtp_pwd').encode('utf-8')
+
+ self._logger.info('Mailhost imported.')
Modified: CMF/branches/tseaver-viewification/GenericSetup/MailHost/tests/test_exportimport.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/MailHost/tests/test_exportimport.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/MailHost/tests/test_exportimport.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -18,22 +18,24 @@
import unittest
import Testing
-from Products.GenericSetup.testing import NodeAdapterTestCase
-from Products.GenericSetup.testing import PlacelessSetup
+from Products.Five import zcml
-_MAILHOST_XML = """\
+from Products.GenericSetup.testing import BodyAdapterTestCase
+
+_MAILHOST_BODY = """\
+<?xml version="1.0"?>
<object name="foo_mailhost" meta_type="Mail Host" smtp_host="localhost"
smtp_port="25" smtp_pwd="" smtp_uid=""/>
"""
-class MailHostNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class MailHostXMLAdapterTests(BodyAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.MailHost.exportimport \
- import MailHostNodeAdapter
+ import MailHostXMLAdapter
- return MailHostNodeAdapter
+ return MailHostXMLAdapter
def _verifyImport(self, obj):
self.assertEqual(type(obj.smtp_host), str)
@@ -46,22 +48,19 @@
self.assertEqual(obj.smtp_uid, '')
def setUp(self):
- import Products.Five
- from Products.Five import zcml
import Products.GenericSetup.MailHost
from Products.MailHost.MailHost import MailHost
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ BodyAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml', Products.GenericSetup.MailHost)
self._obj = MailHost('foo_mailhost')
- self._XML = _MAILHOST_XML
+ self._BODY = _MAILHOST_BODY
def test_suite():
return unittest.TestSuite((
- unittest.makeSuite(MailHostNodeAdapterTests),
+ unittest.makeSuite(MailHostXMLAdapterTests),
))
if __name__ == '__main__':
Copied: CMF/branches/tseaver-viewification/GenericSetup/OFSP (from rev 40492, CMF/trunk/GenericSetup/OFSP)
Modified: CMF/branches/tseaver-viewification/GenericSetup/PluginIndexes/tests/test_exportimport.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/PluginIndexes/tests/test_exportimport.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/PluginIndexes/tests/test_exportimport.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -18,13 +18,9 @@
import unittest
import Testing
-import Products.Five
-import Products.GenericSetup.PluginIndexes
from Products.Five import zcml
from Products.GenericSetup.testing import NodeAdapterTestCase
-from Products.GenericSetup.testing import PlacelessSetup
-
_DATE_XML = """\
<index name="foo_date" meta_type="DateIndex">
<property name="index_naive_time_as_local">True</property>
@@ -72,7 +68,7 @@
"""
-class DateIndexNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class DateIndexNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.PluginIndexes.exportimport \
@@ -81,10 +77,10 @@
return DateIndexNodeAdapter
def setUp(self):
+ import Products.GenericSetup.PluginIndexes
from Products.PluginIndexes.DateIndex.DateIndex import DateIndex
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
@@ -92,7 +88,7 @@
self._XML = _DATE_XML
-class DateRangeIndexNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class DateRangeIndexNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.PluginIndexes.exportimport \
@@ -104,11 +100,11 @@
obj._edit('bar', 'baz')
def setUp(self):
+ import Products.GenericSetup.PluginIndexes
from Products.PluginIndexes.DateRangeIndex.DateRangeIndex \
import DateRangeIndex
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
@@ -116,7 +112,7 @@
self._XML = _DATERANGE_XML
-class FieldIndexNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class FieldIndexNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.PluginIndexes.exportimport \
@@ -128,10 +124,10 @@
obj.indexed_attrs = ('bar',)
def setUp(self):
+ import Products.GenericSetup.PluginIndexes
from Products.PluginIndexes.FieldIndex.FieldIndex import FieldIndex
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
@@ -139,7 +135,7 @@
self._XML = _FIELD_XML
-class KeywordIndexNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class KeywordIndexNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.PluginIndexes.exportimport \
@@ -151,12 +147,11 @@
obj.indexed_attrs = ('bar',)
def setUp(self):
+ import Products.GenericSetup.PluginIndexes
from Products.PluginIndexes.KeywordIndex.KeywordIndex \
import KeywordIndex
-
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
@@ -164,7 +159,7 @@
self._XML = _KEYWORD_XML
-class PathIndexNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class PathIndexNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.PluginIndexes.exportimport \
@@ -173,11 +168,10 @@
return PathIndexNodeAdapter
def setUp(self):
+ import Products.GenericSetup.PluginIndexes
from Products.PluginIndexes.PathIndex.PathIndex import PathIndex
-
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
@@ -185,7 +179,7 @@
self._XML = _PATH_XML
-class VocabularyNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class VocabularyNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.PluginIndexes.exportimport \
@@ -194,10 +188,10 @@
return VocabularyNodeAdapter
def setUp(self):
+ import Products.GenericSetup.PluginIndexes
from Products.PluginIndexes.TextIndex.Vocabulary import Vocabulary
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
@@ -208,7 +202,7 @@
pass
-class TextIndexNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class TextIndexNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.PluginIndexes.exportimport \
@@ -217,10 +211,10 @@
return TextIndexNodeAdapter
def setUp(self):
+ import Products.GenericSetup.PluginIndexes
from Products.PluginIndexes.TextIndex.TextIndex import TextIndex
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
@@ -231,7 +225,7 @@
pass
-class FilteredSetNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class FilteredSetNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.PluginIndexes.exportimport \
@@ -243,11 +237,11 @@
obj.setExpression('True')
def setUp(self):
+ import Products.GenericSetup.PluginIndexes
from Products.PluginIndexes.TopicIndex.FilteredSet \
import PythonFilteredSet
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
@@ -255,7 +249,7 @@
self._XML = _SET_XML
-class TopicIndexNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class TopicIndexNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.PluginIndexes.exportimport \
@@ -268,10 +262,10 @@
obj.addFilteredSet('baz', 'PythonFilteredSet', 'False')
def setUp(self):
+ import Products.GenericSetup.PluginIndexes
from Products.PluginIndexes.TopicIndex.TopicIndex import TopicIndex
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
Copied: CMF/branches/tseaver-viewification/GenericSetup/PythonScripts (from rev 40492, CMF/trunk/GenericSetup/PythonScripts)
Modified: CMF/branches/tseaver-viewification/GenericSetup/ZCTextIndex/tests/test_exportimport.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/ZCTextIndex/tests/test_exportimport.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/ZCTextIndex/tests/test_exportimport.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -20,23 +20,9 @@
from Acquisition import Implicit
-import Products.Five
-import Products.GenericSetup.ZCTextIndex
from Products.Five import zcml
from Products.GenericSetup.testing import NodeAdapterTestCase
-from Products.GenericSetup.testing import PlacelessSetup
-
-class _extra:
-
- pass
-
-
-class DummyCatalog(Implicit):
-
- pass
-
-
_PLEXICON_XML = """\
<object name="foo_plexicon" meta_type="ZCTextIndex Lexicon">
<element name="Whitespace splitter" group="Word Splitter"/>
@@ -54,8 +40,18 @@
"""
-class ZCLexiconNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class _extra:
+ pass
+
+
+class DummyCatalog(Implicit):
+
+ pass
+
+
+class ZCLexiconNodeAdapterTests(NodeAdapterTestCase):
+
def _getTargetClass(self):
from Products.GenericSetup.ZCTextIndex.exportimport \
import ZCLexiconNodeAdapter
@@ -69,17 +65,17 @@
obj._pipeline = (Splitter(), CaseNormalizer(), StopWordRemover())
def setUp(self):
+ import Products.GenericSetup.ZCTextIndex
from Products.ZCTextIndex.ZCTextIndex import PLexicon
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml', Products.GenericSetup.ZCTextIndex)
self._obj = PLexicon('foo_plexicon')
self._XML = _PLEXICON_XML
-class ZCTextIndexNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class ZCTextIndexNodeAdapterTests(NodeAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.ZCTextIndex.exportimport \
@@ -88,11 +84,11 @@
return ZCTextIndexNodeAdapter
def setUp(self):
+ import Products.GenericSetup.ZCTextIndex
from Products.ZCTextIndex.ZCTextIndex import PLexicon
from Products.ZCTextIndex.ZCTextIndex import ZCTextIndex
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ NodeAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml', Products.GenericSetup.ZCTextIndex)
catalog = DummyCatalog()
Modified: CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/configure.zcml
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/configure.zcml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/configure.zcml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -3,15 +3,10 @@
>
<adapter
- factory=".exportimport.ZCatalogNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeExporter"
- for="Products.ZCatalog.interfaces.IZCatalog"
+ factory=".exportimport.ZCatalogXMLAdapter"
+ provides="Products.GenericSetup.interfaces.IBody"
+ for="Products.ZCatalog.interfaces.IZCatalog
+ Products.GenericSetup.interfaces.ISetupContext"
/>
- <adapter
- factory=".exportimport.ZCatalogNodeAdapter"
- provides="Products.GenericSetup.interfaces.INodeImporter"
- for="Products.ZCatalog.interfaces.IZCatalog"
- />
-
</configure>
Modified: CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/exportimport.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/exportimport.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/exportimport.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -18,9 +18,9 @@
from Products.GenericSetup.interfaces import INodeExporter
from Products.GenericSetup.interfaces import INodeImporter
from Products.GenericSetup.interfaces import PURGE
-from Products.GenericSetup.utils import NodeAdapterBase
from Products.GenericSetup.utils import ObjectManagerHelpers
from Products.GenericSetup.utils import PropertyManagerHelpers
+from Products.GenericSetup.utils import XMLAdapterBase
from Products.ZCatalog.interfaces import IZCatalog
@@ -30,14 +30,16 @@
pass
-class ZCatalogNodeAdapter(NodeAdapterBase, ObjectManagerHelpers,
- PropertyManagerHelpers):
+class ZCatalogXMLAdapter(XMLAdapterBase, ObjectManagerHelpers,
+ PropertyManagerHelpers):
- """Node im- and exporter for ZCatalog.
+ """XML im- and exporter for ZCatalog.
"""
__used_for__ = IZCatalog
+ _LOGGER_ID = 'catalog'
+
def exportNode(self, doc):
"""Export the object as a DOM node.
"""
@@ -47,6 +49,8 @@
node.appendChild(self._extractObjects())
node.appendChild(self._extractIndexes())
node.appendChild(self._extractColumns())
+
+ self._logger.info('Catalog exported.')
return node
def importNode(self, node, mode=PURGE):
@@ -63,6 +67,8 @@
self._initIndexes(node, mode)
self._initColumns(node, mode)
+ self._logger.info('Catalog imported.')
+
def _extractIndexes(self):
fragment = self._doc.createDocumentFragment()
indexes = self.context.getIndexObjects()[:]
Modified: CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/tests/test_exportimport.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/tests/test_exportimport.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/ZCatalog/tests/test_exportimport.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -20,20 +20,21 @@
import Zope2
Zope2.startup()
-import Products
from Products.Five import zcml
-from Products.GenericSetup.interfaces import INodeExporter
-from Products.GenericSetup.testing import NodeAdapterTestCase
-from Products.GenericSetup.testing import PlacelessSetup
-from Products.GenericSetup.utils import PrettyDocument
+from zope.app import zapi
+from Products.GenericSetup.interfaces import IBody
+from Products.GenericSetup.testing import BodyAdapterTestCase
+from Products.GenericSetup.tests.common import DummyExportContext
+
class _extra:
pass
-_CATALOG_XML = """\
+_CATALOG_BODY = """\
+<?xml version="1.0"?>
<object name="foo_catalog" meta_type="ZCatalog">
<property name="title"></property>
<object name="foo_plexicon" meta_type="ZCTextIndex Lexicon">
@@ -76,13 +77,13 @@
"""
-class ZCatalogNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+class ZCatalogXMLAdapterTests(BodyAdapterTestCase):
def _getTargetClass(self):
from Products.GenericSetup.ZCatalog.exportimport \
- import ZCatalogNodeAdapter
+ import ZCatalogXMLAdapter
- return ZCatalogNodeAdapter
+ return ZCatalogXMLAdapter
def _populate(self, obj):
from Products.ZCTextIndex.Lexicon import CaseNormalizer
@@ -131,28 +132,29 @@
obj.addIndex('foo_text', 'TextIndex')
def setUp(self):
+ import Products.GenericSetup
from Products.ZCatalog.ZCatalog import ZCatalog
- PlacelessSetup.setUp(self)
- zcml.load_config('meta.zcml', Products.Five)
+ BodyAdapterTestCase.setUp(self)
zcml.load_config('configure.zcml',
Products.GenericSetup.PluginIndexes)
zcml.load_config('configure.zcml', Products.GenericSetup.ZCatalog)
zcml.load_config('configure.zcml', Products.GenericSetup.ZCTextIndex)
self._obj = ZCatalog('foo_catalog')
- self._XML = _CATALOG_XML % ('', '')
+ self._BODY = _CATALOG_BODY % ('', '')
- def test_exportNode_special(self):
+ def test_body_get_special(self):
self._populate_special(self._obj)
- node = INodeExporter(self._obj).exportNode(PrettyDocument())
- self.assertEqual(node.toprettyxml(' '),
- _CATALOG_XML % (_VOCABULARY_XML, _TEXT_XML))
+ context = DummyExportContext(None)
+ exporter = zapi.getMultiAdapter((self._obj, context), IBody)
+ self.assertEqual(exporter.body,
+ _CATALOG_BODY % (_VOCABULARY_XML, _TEXT_XML))
def test_suite():
return unittest.TestSuite((
- unittest.makeSuite(ZCatalogNodeAdapterTests),
+ unittest.makeSuite(ZCatalogXMLAdapterTests),
))
if __name__ == '__main__':
Modified: CMF/branches/tseaver-viewification/GenericSetup/__init__.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/__init__.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/__init__.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -24,3 +24,15 @@
interfaces=None,
icon='www/tool.png',
)
+
+# BBB: for setup tools created with CMF 1.5 if CMFSetup isn't installed
+try:
+ import Products.CMFSetup
+except ImportError:
+ import bbb
+ import bbb.registry
+ import bbb.tool
+
+ __module_aliases__ = (('Products.CMFSetup', bbb),
+ ('Products.CMFSetup.registry', bbb.registry),
+ ('Products.CMFSetup.tool', bbb.tool))
Copied: CMF/branches/tseaver-viewification/GenericSetup/bbb (from rev 40492, CMF/trunk/GenericSetup/bbb)
Copied: CMF/branches/tseaver-viewification/GenericSetup/browser (from rev 40492, CMF/trunk/GenericSetup/browser)
Modified: CMF/branches/tseaver-viewification/GenericSetup/configure.zcml
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/configure.zcml 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/configure.zcml 2005-12-02 18:15:45 UTC (rev 40498)
@@ -4,8 +4,12 @@
<include package=".MailHost"/>
+ <include package=".OFSP"/>
+
<include package=".PluginIndexes"/>
+ <include package=".PythonScripts"/>
+
<include package=".ZCatalog"/>
<include package=".ZCTextIndex"/>
Modified: CMF/branches/tseaver-viewification/GenericSetup/content.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/content.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/content.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -139,8 +139,7 @@
prop_adapter.put_ini(prop_text)
preserve = import_context.readDataFile('.preserve', subdir)
- tool_items = [x for x in context.objectItems()
- if ISetupTool.providedBy(x[1])]
+ must_preserve = self._mustPreserve()
prior = context.objectIds()
@@ -149,7 +148,7 @@
else:
preserve = _globtest(preserve, prior)
- preserve.extend([x[0] for x in tool_items])
+ preserve.extend([x[0] for x in must_preserve])
for id in prior:
if id not in preserve:
@@ -224,6 +223,10 @@
context._setObject(instance_id, instance)
return context._getOb(instance_id)
+
+ def _mustPreserve(self):
+ return [x for x in self.context.objectItems()
+ if ISetupTool.providedBy(x[1])]
def _globtest(globpattern, namelist):
Modified: CMF/branches/tseaver-viewification/GenericSetup/context.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/context.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/context.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -420,6 +420,13 @@
""" See IExportContext.
"""
+ if subdir is not None:
+ filename = '/'.join( ( subdir, filename ) )
+
+ sep = filename.rfind('/')
+ if sep != -1:
+ subdir = filename[:sep]
+ filename = filename[sep+1:]
folder = self._ensureSnapshotsFolder( subdir )
# TODO: switch on content_type
@@ -525,6 +532,13 @@
""" See IImportContext.
"""
+ if subdir is not None:
+ filename = '/'.join( ( subdir, filename ) )
+
+ sep = filename.rfind('/')
+ if sep != -1:
+ subdir = filename[:sep]
+ filename = filename[sep+1:]
try:
snapshot = self._getSnapshotFolder( subdir )
object = snapshot._getOb( filename )
Modified: CMF/branches/tseaver-viewification/GenericSetup/interfaces.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/interfaces.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/interfaces.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -16,8 +16,9 @@
"""
from zope.interface import Interface
+from zope.schema import Text
+from zope.schema import TextLine
-
BASE, EXTENSION = range(1, 3)
PURGE, UPDATE = range(1, 3)
@@ -352,7 +353,7 @@
""" API for profile registry.
"""
- def getProfileInfo( profile_id ):
+ def getProfileInfo( profile_id, for_=None ):
""" Return a mapping describing a registered filesystem profile.
@@ -370,18 +371,36 @@
relative (None for absolute paths).
'type' -- either BASE or EXTENSION
+
+ o 'for_', if passed, should be the interface specifying the "site
+ type" for which the profile is relevant, e.g.
+ Products.CMFCore.interfaces.ISiteRoot or
+ Products.PluggableAuthService.interfaces.IPluggableAuthService.
+ If 'None', list all profiles.
"""
- def listProfiles():
+ def listProfiles( for_=None ):
""" Return a list of IDs for registered profiles.
+
+ o 'for_', if passed, should be the interface specifying the "site
+ type" for which the profile is relevant, e.g.
+ Products.CMFCore.interfaces.ISiteRoot or
+ Products.PluggableAuthService.interfaces.IPluggableAuthService.
+ If 'None', list all profiles.
"""
- def listProfileInfo():
+ def listProfileInfo( for_=None ):
""" Return a list of mappings describing registered profiles.
o See 'getProfileInfo' for a description of the mappings' keys.
+
+ o 'for_', if passed, should be the interface specifying the "site
+ type" for which the profile is relevant, e.g.
+ Products.CMFCore.interfaces.ISiteRoot or
+ Products.PluggableAuthService.interfaces.IPluggableAuthService.
+ If 'None', list all profiles.
"""
def registerProfile( name
@@ -390,6 +409,7 @@
, path
, product=None
, profile_type=BASE
+ , for_=None
):
""" Add a new profile to the registry.
@@ -398,6 +418,12 @@
o If 'product' is passed, then 'path' should be interpreted as
relative to the corresponding product directory.
+
+ o 'for_', if passed, should be the interface specifying the "site
+ type" for which the profile is relevant, e.g.
+ Products.CMFCore.interfaces.ISiteRoot or
+ Products.PluggableAuthService.interfaces.IPluggableAuthService.
+ If 'None', the profile might be used in any site.
"""
class ISetupTool( Interface ):
@@ -562,6 +588,18 @@
"""
+class IBody(Interface):
+
+ """Body im- and exporter.
+ """
+
+ body = Text(description=u'Im- and export the object as a file body.')
+
+ mime_type = TextLine(description=u'MIME type of the file body.')
+
+ suffix = TextLine(description=u'Suffix for the file.')
+
+
class INodeExporter(Interface):
"""Node exporter.
@@ -581,6 +619,7 @@
"""Import the object from the DOM node.
"""
+
class IFilesystemExporter(Interface):
""" Plugin interface for site structure export.
"""
Modified: CMF/branches/tseaver-viewification/GenericSetup/registry.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/registry.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/registry.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -531,26 +531,37 @@
self.clear()
security.declareProtected( ManagePortal, '' )
- def getProfileInfo( self, profile_id ):
+ def getProfileInfo( self, profile_id, for_=None ):
""" See IProfileRegistry.
"""
result = self._profile_info[ profile_id ]
+ if for_ is not None:
+ if not issubclass( for_, result['for'] ):
+ raise KeyError, profile_id
return result.copy()
security.declareProtected( ManagePortal, 'listProfiles' )
- def listProfiles( self ):
+ def listProfiles( self, for_=None ):
""" See IProfileRegistry.
"""
- return tuple( self._profile_ids )
+ result = []
+ for profile_id in self._profile_ids:
+ info = self.getProfileInfo( profile_id )
+ if for_ is None or issubclass( for_, info['for'] ):
+ result.append( profile_id )
+ return tuple( result )
security.declareProtected( ManagePortal, 'listProfileInfo' )
- def listProfileInfo( self ):
+ def listProfileInfo( self, for_=None ):
""" See IProfileRegistry.
"""
- return [ self.getProfileInfo( id ) for id in self.listProfiles() ]
+ candidates = [ self.getProfileInfo( id )
+ for id in self.listProfiles() ]
+ return [ x for x in candidates if for_ is None or x['for'] is None or
+ issubclass( for_, x['for'] ) ]
security.declareProtected( ManagePortal, 'registerProfile' )
def registerProfile( self
@@ -560,6 +571,7 @@
, path
, product=None
, profile_type=BASE
+ , for_=None
):
""" See IProfileRegistry.
"""
@@ -575,6 +587,7 @@
, 'path' : path
, 'product' : product
, 'type': profile_type
+ , 'for': for_
}
self._profile_info[ profile_id ] = info
Modified: CMF/branches/tseaver-viewification/GenericSetup/testing.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/testing.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/testing.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -16,12 +16,20 @@
"""
import unittest
+import Testing
+
from xml.dom.minidom import parseString
+import Products.Five
+from Products.Five import zcml
+from zope.app import zapi
from zope.interface.verify import verifyClass
+from interfaces import IBody
from interfaces import INodeExporter
from interfaces import INodeImporter
+from tests.common import DummyExportContext
+from tests.common import DummyImportContext
from utils import PrettyDocument
try:
@@ -30,7 +38,7 @@
from zope.app.tests.placelesssetup import PlacelessSetup
-class NodeAdapterTestCase(unittest.TestCase):
+class BodyAdapterTestCase(PlacelessSetup, unittest.TestCase):
def _populate(self, obj):
pass
@@ -38,7 +46,50 @@
def _verifyImport(self, obj):
pass
+ def setUp(self):
+ PlacelessSetup.setUp(self)
+ zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
+
+ def tearDown(self):
+ PlacelessSetup.tearDown(self)
+
def test_z3interfaces(self):
+ verifyClass(IBody, self._getTargetClass())
+
+ def test_body_get(self):
+ self._populate(self._obj)
+ context = DummyExportContext(None)
+ exporter = zapi.getMultiAdapter((self._obj, context), IBody)
+ self.assertEqual(exporter.body, self._BODY)
+
+ def test_body_set(self):
+ context = DummyImportContext(None)
+ importer = zapi.getMultiAdapter((self._obj, context), IBody)
+ importer.body = self._BODY
+ self._verifyImport(self._obj)
+ context = DummyExportContext(None)
+ exporter = zapi.getMultiAdapter((self._obj, context), IBody)
+ self.assertEqual(exporter.body, self._BODY)
+
+
+class NodeAdapterTestCase(PlacelessSetup, unittest.TestCase):
+
+ def _populate(self, obj):
+ pass
+
+ def _verifyImport(self, obj):
+ pass
+
+ def setUp(self):
+ PlacelessSetup.setUp(self)
+ zcml.load_config('meta.zcml', Products.Five)
+ zcml.load_config('permissions.zcml', Products.Five)
+
+ def tearDown(self):
+ PlacelessSetup.tearDown(self)
+
+ def test_z3interfaces(self):
verifyClass(INodeExporter, self._getTargetClass())
verifyClass(INodeImporter, self._getTargetClass())
Modified: CMF/branches/tseaver-viewification/GenericSetup/tests/common.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/tests/common.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/tests/common.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -21,7 +21,12 @@
from Acquisition import Implicit
from Testing.ZopeTestCase import ZopeTestCase
+from zope.interface import implements
+from Products.GenericSetup.interfaces import IExportContext
+from Products.GenericSetup.interfaces import IImportContext
+
+
class OmnipotentUser(Implicit):
""" Omnipotent User for unit testing purposes.
"""
@@ -189,6 +194,8 @@
class DummyExportContext:
+ implements(IExportContext)
+
def __init__( self, site, tool=None ):
self._site = site
self._tool = tool
@@ -212,6 +219,8 @@
class DummyImportContext:
+ implements(IImportContext)
+
def __init__( self, site, purge=True, encoding=None, tool=None ):
self._site = site
self._tool = tool
Modified: CMF/branches/tseaver-viewification/GenericSetup/tests/test_context.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/tests/test_context.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/tests/test_context.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -1010,6 +1010,9 @@
self.assertEqual( template.meta_type, DTMLDocument.meta_type )
self.assertEqual( template.read(), _HTML )
+ ctx.writeDataFile( 'sub1/%s2' % FILENAME, _HTML, CONTENT_TYPE)
+ self.assertEqual( len( sub1.objectIds() ), 2 )
+
def test_writeDataFile_nested_subdirs_html( self ):
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
@@ -1198,6 +1201,8 @@
, subdir=SUBDIR )
self.assertEqual( ctx.readDataFile( FILENAME, SUBDIR ), printable )
+ self.assertEqual( ctx.readDataFile( '%s/%s' % (SUBDIR, FILENAME) ),
+ printable )
def test_getLastModified_nonesuch( self ):
Modified: CMF/branches/tseaver-viewification/GenericSetup/tests/test_registry.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/tests/test_registry.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/tests/test_registry.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -23,6 +23,7 @@
from OFS.Folder import Folder
from Products.GenericSetup.tests.common import BaseRegistryTests
from Products.GenericSetup import EXTENSION
+from zope.interface import Interface
from conformance import ConformsToIStepRegistry
from conformance import ConformsToIImportStepRegistry
@@ -1024,6 +1025,16 @@
</tool-setup>
"""
+class ISite(Interface):
+ pass
+
+class IDerivedSite(ISite):
+ pass
+
+class IAnotherSite(Interface):
+ pass
+
+
class ProfileRegistryTests( BaseRegistryTests
, ConformsToIProfileRegistry
):
@@ -1071,21 +1082,86 @@
self.assertEqual( info[ 'path' ], PATH )
self.assertEqual( info[ 'product' ], PRODUCT )
self.assertEqual( info[ 'type' ], PROFILE_TYPE )
+ self.assertEqual( info[ 'for' ], None )
def test_registerProfile_duplicate( self ):
- PROFILE_ID = 'one'
+ NAME = 'one'
TITLE = 'One'
DESCRIPTION = 'One profile'
PATH = '/path/to/one'
registry = self._makeOne()
- registry.registerProfile( PROFILE_ID, TITLE, DESCRIPTION, PATH )
+ registry.registerProfile( NAME, TITLE, DESCRIPTION, PATH )
self.assertRaises( KeyError
, registry.registerProfile
- , PROFILE_ID, TITLE, DESCRIPTION, PATH )
+ , NAME, TITLE, DESCRIPTION, PATH )
+ def test_registerProfile_site_type( self ):
+
+ NAME = 'one'
+ TITLE = 'One'
+ DESCRIPTION = 'One profile'
+ PATH = '/path/to/one'
+ PRODUCT = 'TestProduct'
+ PROFILE_ID = 'TestProduct:one'
+ PROFILE_TYPE = EXTENSION
+ FOR = ISite
+ NOT_FOR = IAnotherSite
+ DERIVED_FOR = IDerivedSite
+
+ registry = self._makeOne()
+ registry.registerProfile( NAME
+ , TITLE
+ , DESCRIPTION
+ , PATH
+ , PRODUCT
+ , PROFILE_TYPE
+ , for_=FOR
+ )
+
+
+ self.assertEqual( len( registry.listProfiles() ), 1 )
+ self.assertEqual( len( registry.listProfiles( for_=FOR ) ), 1 )
+ self.assertEqual( len( registry.listProfiles( for_=DERIVED_FOR ) )
+ , 1 )
+ self.assertEqual( len( registry.listProfiles( for_=NOT_FOR ) )
+ , 0 )
+
+ self.assertEqual( len( registry.listProfileInfo() ), 1 )
+ self.assertEqual( len( registry.listProfileInfo( for_=FOR ) ), 1 )
+ self.assertEqual( len( registry.listProfileInfo( for_=DERIVED_FOR ) )
+ , 1 )
+ self.assertEqual( len( registry.listProfileInfo( for_=NOT_FOR ) )
+ , 0 )
+
+ # Verify that these lookups succeed...
+ info1 = registry.getProfileInfo( PROFILE_ID )
+ info2 = registry.getProfileInfo( PROFILE_ID, for_=FOR )
+ info3 = registry.getProfileInfo( PROFILE_ID, for_=DERIVED_FOR )
+
+ self.assertEqual(info1, info2)
+ self.assertEqual(info1, info3)
+
+ # ...and that this one fails.
+ self.assertRaises( KeyError
+ , registry.getProfileInfo
+ , PROFILE_ID
+ , for_=NOT_FOR
+ )
+
+ info = registry.getProfileInfo( PROFILE_ID , for_=FOR )
+
+ self.assertEqual( info[ 'id' ], PROFILE_ID )
+ self.assertEqual( info[ 'title' ], TITLE )
+ self.assertEqual( info[ 'description' ], DESCRIPTION )
+ self.assertEqual( info[ 'path' ], PATH )
+ self.assertEqual( info[ 'product' ], PRODUCT )
+ self.assertEqual( info[ 'type' ], PROFILE_TYPE )
+ self.assertEqual( info[ 'for' ], FOR )
+
+
def test_suite():
return unittest.TestSuite((
unittest.makeSuite( ImportStepRegistryTests ),
Modified: CMF/branches/tseaver-viewification/GenericSetup/tool.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/tool.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/tool.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -160,7 +160,7 @@
"""
return 'ascii'
- security.declareProtected(ManagePortal, 'getImportContextId')
+ security.declareProtected(ManagePortal, 'getImportContextID')
def getImportContextID(self):
""" See ISetupTool.
@@ -199,7 +199,7 @@
"""
return self._toolset_registry
- security.declareProtected(ManagePortal, 'executeStep')
+ security.declareProtected(ManagePortal, 'runImportStep')
def runImportStep(self, step_id, run_dependencies=True, purge_old=None):
""" See ISetupTool.
@@ -231,7 +231,7 @@
return { 'steps' : steps, 'messages' : messages }
- security.declareProtected(ManagePortal, 'runAllSetupSteps')
+ security.declareProtected(ManagePortal, 'runAllImportSteps')
def runAllImportSteps(self, purge_old=None):
""" See ISetupTool.
Modified: CMF/branches/tseaver-viewification/GenericSetup/utils.py
===================================================================
--- CMF/branches/tseaver-viewification/GenericSetup/utils.py 2005-12-02 18:03:52 UTC (rev 40497)
+++ CMF/branches/tseaver-viewification/GenericSetup/utils.py 2005-12-02 18:15:45 UTC (rev 40498)
@@ -21,7 +21,7 @@
from xml.dom.minidom import Document
from xml.dom.minidom import Element
from xml.dom.minidom import Node
-from xml.dom.minidom import parseString as domParseString
+from xml.dom.minidom import parseString
from xml.sax.handler import ContentHandler
import Products
@@ -29,13 +29,22 @@
from Acquisition import Implicit
from Globals import InitializeClass
from Globals import package_home
+try:
+ from OFS.interfaces import IOrderedContainer
+except:
+ #BBB: for Zope 2.8
+ from Products.Five.bbb.OFS_interfaces import IOrderedContainer
from TAL.TALDefs import attrEscape
+from zope.app import zapi
from zope.interface import implements
+from zope.interface import providedBy
from exceptions import BadRequest
+from interfaces import IBody
from interfaces import INodeExporter
from interfaces import INodeImporter
-from interfaces import PURGE
+from interfaces import ISetupContext
+from interfaces import PURGE, UPDATE
from permissions import ManagePortal
@@ -161,7 +170,7 @@
if reader is not None:
xml = reader()
- dom = domParseString(xml)
+ dom = parseString(xml)
root = dom.documentElement
return self._extractNode(root)
@@ -394,6 +403,36 @@
node.writexml(writer, indent, addindent, newl)
+class BodyAdapterBase(object):
+
+ """Body im- and exporter base.
+ """
+
+ implements(IBody)
+
+ _LOGGER_ID = ''
+
+ def __init__(self, context, environ):
+ self.context = context
+ self.environ = environ
+ self._logger = environ.getLogger(self._LOGGER_ID)
+
+ def _exportBody(self):
+ """Export the object as a file body.
+ """
+ return ''
+
+ def _importBody(self, body):
+ """Import the object from the file body.
+ """
+
+ body = property(_exportBody, _importBody)
+
+ mime_type = 'text/plain'
+
+ suffix = ''
+
+
class NodeAdapterBase(object):
"""Node im- and exporter base.
@@ -436,6 +475,32 @@
def _convertToBoolean(self, val):
return val.lower() in ('true', 'yes', '1')
+
+class XMLAdapterBase(BodyAdapterBase, NodeAdapterBase):
+
+ """XML im- and exporter base.
+ """
+
+ def _exportBody(self):
+ """Export the object as a file body.
+ """
+ doc = PrettyDocument()
+ doc.appendChild(self.exportNode(doc))
+ return doc.toprettyxml(' ')
+
+ def _importBody(self, body):
+ """Import the object from the file body.
+ """
+ mode = self.environ.shouldPurge() and PURGE or UPDATE
+ self.importNode(parseString(body).documentElement, mode=mode)
+
+ body = property(_exportBody, _importBody)
+
+ mime_type = 'text/xml'
+
+ suffix = '.xml'
+
+
class ObjectManagerHelpers(object):
"""ObjectManager im- and export helpers.
@@ -443,11 +508,21 @@
def _extractObjects(self):
fragment = self._doc.createDocumentFragment()
- for obj in self.context.objectValues():
+ objects = self.context.objectValues()
+ if not IOrderedContainer.providedBy(self.context):
+ objects.sort(lambda x,y: cmp(x.getId(), y.getId()))
+ for obj in objects:
exporter = INodeExporter(obj, None)
- if exporter is None:
- continue
- fragment.appendChild(exporter.exportNode(self._doc))
+ if exporter:
+ node = exporter.exportNode(self._doc)
+ fragment.appendChild(node)
+ else:
+ adapters = zapi.getService(zapi.servicenames.Adapters)
+ if adapters.lookup((providedBy(obj), ISetupContext), IBody):
+ node = self._doc.createElement('object')
+ node.setAttribute('name', obj.getId())
+ node.setAttribute('meta_type', obj.meta_type)
+ fragment.appendChild(node)
return fragment
def _purgeObjects(self):
@@ -470,7 +545,7 @@
parent._setObject(obj_id, mt_info['instance'](obj_id))
break
else:
- raise ValueError('unknown meta_type \'%s\'' % obj_id)
+ raise ValueError('unknown meta_type \'%s\'' % meta_type)
if child.hasAttribute('insert-before'):
insert_before = child.getAttribute('insert-before')
@@ -494,7 +569,9 @@
pass
obj = getattr(self.context, obj_id)
- INodeImporter(obj).importNode(child, mode)
+ importer = INodeImporter(obj, None)
+ if importer:
+ importer.importNode(child, mode)
class PropertyManagerHelpers(object):
@@ -588,3 +665,36 @@
prop_value = self._getNodeText(child).encode('utf-8')
obj._updateProperty(prop_id, prop_value)
+
+
+def exportObjects(parent, parent_path, context):
+ """ Export subobjects recursively.
+ """
+ for obj in parent.objectValues():
+ path = '%s/%s' % (parent_path, obj.getId().replace(' ', '_'))
+
+ exporter = zapi.queryMultiAdapter((obj, context), IBody)
+ if exporter:
+ filename = '%s%s' % (path, exporter.suffix)
+ body = exporter.body
+ if body is not None:
+ context.writeDataFile(filename, body, exporter.mime_type)
+
+ if getattr(obj, 'objectValues', False):
+ exportObjects(obj, path, context)
+
+def importObjects(parent, parent_path, context):
+ """ Import subobjects recursively.
+ """
+ for obj in parent.objectValues():
+ path = '%s/%s' % (parent_path, obj.getId().replace(' ', '_'))
+
+ importer = zapi.queryMultiAdapter((obj, context), IBody)
+ if importer:
+ filename = '%s%s' % (path, importer.suffix)
+ body = context.readDataFile(filename)
+ if body is not None:
+ importer.body = body
+
+ if getattr(obj, 'objectValues', False):
+ importObjects(obj, path, context)
More information about the CMF-checkins
mailing list