Back to index

plone3  3.1.7
test_typeinfo.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """Types tool xml adapter and setup handler unit tests.
00014 
00015 $Id: test_typeinfo.py 77004 2007-06-24 08:57:54Z yuppie $
00016 """
00017 
00018 import unittest
00019 import Testing
00020 
00021 from OFS.Folder import Folder
00022 
00023 from Products.GenericSetup.testing import BodyAdapterTestCase
00024 from Products.GenericSetup.tests.common import BaseRegistryTests
00025 from Products.GenericSetup.tests.common import DummyExportContext
00026 from Products.GenericSetup.tests.common import DummyImportContext
00027 
00028 from Products.CMFCore.permissions import View
00029 from Products.CMFCore.permissions import AccessContentsInformation
00030 from Products.CMFCore.permissions import ModifyPortalContent
00031 from Products.CMFCore.testing import ExportImportZCMLLayer
00032 from Products.CMFCore.TypesTool import FactoryTypeInformation
00033 from Products.CMFCore.TypesTool import ScriptableTypeInformation
00034 from Products.CMFCore.TypesTool import TypesTool
00035 
00036 _FTI_BODY = """\
00037 <?xml version="1.0"?>
00038 <object name="foo_fti" meta_type="Factory-based Type Information"
00039    xmlns:i18n="http://xml.zope.org/namespaces/i18n">
00040  <property name="title"></property>
00041  <property name="description"></property>
00042  <property name="content_icon"></property>
00043  <property name="content_meta_type"></property>
00044  <property name="product"></property>
00045  <property name="factory"></property>
00046  <property name="immediate_view"></property>
00047  <property name="global_allow">True</property>
00048  <property name="filter_content_types">True</property>
00049  <property name="allowed_content_types"/>
00050  <property name="allow_discussion">False</property>
00051  <alias from="(Default)" to="foo"/>
00052  <alias from="view" to="foo"/>
00053  <action title="Foo" action_id="foo_action" category="Bar"
00054     condition_expr="python:1" url_expr="string:${object_url}/foo"
00055     visible="True"/>
00056 </object>
00057 """
00058 
00059 _TYPESTOOL_BODY = """\
00060 <?xml version="1.0"?>
00061 <object name="portal_types" meta_type="CMF Types Tool">
00062  <property name="title"></property>
00063  <object name="foo_type" meta_type="Factory-based Type Information"/>
00064 </object>
00065 """
00066 
00067 _TI_LIST = ({
00068     'id':                    'foo',
00069     'title':                 'Foo',
00070     'description':           'Foo things',
00071     'i18n_domain':           'foo_domain',
00072     'content_meta_type':     'Foo Thing',
00073     'content_icon':          'foo.png',
00074     'product':               'CMFSetup',
00075     'factory':               'addFoo',
00076     'immediate_view':        'foo_view',
00077     'filter_content_types':  False,
00078     'allowed_content_types': (),
00079     'allow_discussion':      False,
00080     'global_allow':          False,
00081     'aliases': {'(Default)': 'foo_view',
00082                 'view':      'foo_view',
00083                 },
00084     'actions': ({'id':     'view',
00085                  'title':  'View',
00086                  'action': 'string:${object_url}/foo_view',
00087                  'permissions': (View,),
00088                  },
00089                 {'id':     'edit',
00090                  'title':  'Edit',
00091                  'action': 'string:${object_url}/foo_edit_form',
00092                  'permissions': (ModifyPortalContent,),
00093                  },
00094                 {'id':     'metadata',
00095                  'title':  'Metadata',
00096                  'action': 'string:${object_url}/metadata_edit_form',
00097                  'permissions': (ModifyPortalContent,),
00098                  },
00099                 ),
00100     }, {
00101     'id':                    'bar',
00102     'title':                 'Bar',
00103     'description':           'Bar things',
00104     'content_meta_type':     'Bar Thing',
00105     'content_icon':          'bar.png',
00106     'constructor_path':      'make_bar',
00107     'permission':            'Add portal content',
00108     'immediate_view':        'bar_view',
00109     'filter_content_types':  True,
00110     'allowed_content_types': ('foo',),
00111     'allow_discussion':      True,
00112     'global_allow':          True,
00113     'aliases': {'(Default)': 'bar_view',
00114                 'view':      'bar_view',
00115                 },
00116     'actions': ({'id':     'view',
00117                  'title':  'View',
00118                  'action': 'string:${object_url}/bar_view',
00119                  'permissions': (View,),
00120                  },
00121                 {'id':     'edit',
00122                  'title':  'Edit',
00123                  'action': 'string:${object_url}/bar_edit_form',
00124                  'permissions': (ModifyPortalContent,),
00125                  },
00126                 {'id':     'contents',
00127                  'title':  'Contents',
00128                  'action': 'string:${object_url}/folder_contents',
00129                  'permissions': (AccessContentsInformation,),
00130                  },
00131                 {'id':     'metadata',
00132                  'title':  'Metadata',
00133                  'action': 'string:${object_url}/metadata_edit_form',
00134                  'permissions': (ModifyPortalContent,),
00135                  },
00136                ),
00137     })
00138 
00139 _TI_LIST_WITH_FILENAME = []
00140 
00141 for original in _TI_LIST:
00142     duplicate = original.copy()
00143     duplicate['id'] = '%s object' % original['id']
00144     _TI_LIST_WITH_FILENAME.append(duplicate)
00145 
00146 _EMPTY_TOOL_EXPORT = """\
00147 <?xml version="1.0"?>
00148 <object name="portal_types" meta_type="CMF Types Tool">
00149  <property name="title"/>
00150 </object>
00151 """
00152 
00153 _NORMAL_TOOL_EXPORT = """\
00154 <?xml version="1.0"?>
00155 <object name="portal_types" meta_type="CMF Types Tool">
00156  <property name="title"/>
00157  <object name="bar" meta_type="Scriptable Type Information"/>
00158  <object name="foo" meta_type="Factory-based Type Information"/>
00159 </object>
00160 """
00161 
00162 _FILENAME_EXPORT = """\
00163 <?xml version="1.0"?>
00164 <object name="portal_types" meta_type="CMF Types Tool">
00165  <property name="title"/>
00166  <object name="bar object" meta_type="Scriptable Type Information"/>
00167  <object name="foo object" meta_type="Factory-based Type Information"/>
00168 </object>
00169 """
00170 
00171 _UPDATE_TOOL_IMPORT = """\
00172 <?xml version="1.0"?>
00173 <types-tool>
00174  <type id="foo"/>
00175 </types-tool>
00176 """
00177 
00178 _FOO_EXPORT = """\
00179 <?xml version="1.0"?>
00180 <object name="%s" meta_type="Factory-based Type Information"
00181    i18n:domain="foo_domain" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
00182  <property name="title" i18n:translate="">Foo</property>
00183  <property name="description" i18n:translate="">Foo things</property>
00184  <property name="content_icon">foo.png</property>
00185  <property name="content_meta_type">Foo Thing</property>
00186  <property name="product">CMFSetup</property>
00187  <property name="factory">addFoo</property>
00188  <property name="immediate_view">foo_view</property>
00189  <property name="global_allow">False</property>
00190  <property name="filter_content_types">False</property>
00191  <property name="allowed_content_types"/>
00192  <property name="allow_discussion">False</property>
00193  <alias from="(Default)" to="foo_view"/>
00194  <alias from="view" to="foo_view"/>
00195  <action title="View" action_id="view" category="object" condition_expr=""
00196     url_expr="string:${object_url}/foo_view" visible="True">
00197   <permission value="View"/>
00198  </action>
00199  <action title="Edit" action_id="edit" category="object" condition_expr=""
00200     url_expr="string:${object_url}/foo_edit_form" visible="True">
00201   <permission value="Modify portal content"/>
00202  </action>
00203  <action title="Metadata" action_id="metadata" category="object"
00204     condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
00205     visible="True">
00206   <permission value="Modify portal content"/>
00207  </action>
00208 </object>
00209 """
00210 
00211 _BAR_EXPORT = """\
00212 <?xml version="1.0"?>
00213 <object name="%s" meta_type="Scriptable Type Information"
00214    xmlns:i18n="http://xml.zope.org/namespaces/i18n">
00215  <property name="title">Bar</property>
00216  <property name="description">Bar things</property>
00217  <property name="content_icon">bar.png</property>
00218  <property name="content_meta_type">Bar Thing</property>
00219  <property name="permission">Add portal content</property>
00220  <property name="constructor_path">make_bar</property>
00221  <property name="immediate_view">bar_view</property>
00222  <property name="global_allow">True</property>
00223  <property name="filter_content_types">True</property>
00224  <property name="allowed_content_types">
00225   <element value="foo"/>
00226  </property>
00227  <property name="allow_discussion">True</property>
00228  <alias from="(Default)" to="bar_view"/>
00229  <alias from="view" to="bar_view"/>
00230  <action title="View" action_id="view" category="object" condition_expr=""
00231     url_expr="string:${object_url}/bar_view" visible="True">
00232   <permission value="View"/>
00233  </action>
00234  <action title="Edit" action_id="edit" category="object" condition_expr=""
00235     url_expr="string:${object_url}/bar_edit_form" visible="True">
00236   <permission value="Modify portal content"/>
00237  </action>
00238  <action title="Contents" action_id="contents" category="object"
00239     condition_expr="" url_expr="string:${object_url}/folder_contents"
00240     visible="True">
00241   <permission value="Access contents information"/>
00242  </action>
00243  <action title="Metadata" action_id="metadata" category="object"
00244     condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
00245     visible="True">
00246   <permission value="Modify portal content"/>
00247  </action>
00248 </object>
00249 """
00250 
00251 _UPDATE_FOO_IMPORT = """\
00252 <object name="foo">
00253  <alias from="spam" to="eggs"/>
00254 </object>
00255 """
00256 
00257 
00258 class TypeInformationXMLAdapterTests(BodyAdapterTestCase):
00259 
00260     layer = ExportImportZCMLLayer
00261 
00262     def _getTargetClass(self):
00263         from Products.CMFCore.exportimport.typeinfo \
00264                 import TypeInformationXMLAdapter
00265 
00266         return TypeInformationXMLAdapter
00267 
00268     def _populate(self, obj):
00269         obj.setMethodAliases({'(Default)': 'foo', 'view': 'foo'})
00270         obj.addAction('foo_action', 'Foo', 'string:${object_url}/foo',
00271                       'python:1', (), 'Bar')
00272 
00273     def _verifyImport(self, obj):
00274         self.assertEqual(type(obj._aliases), dict)
00275         self.assertEqual(obj._aliases, {'(Default)': 'foo', 'view': 'foo'})
00276         self.assertEqual(type(obj._aliases['view']), str)
00277         self.assertEqual(obj._aliases['view'], 'foo')
00278         self.assertEqual(type(obj._actions), tuple)
00279         self.assertEqual(type(obj._actions[0].id), str)
00280         self.assertEqual(obj._actions[0].id, 'foo_action')
00281         self.assertEqual(type(obj._actions[0].title), str)
00282         self.assertEqual(obj._actions[0].title, 'Foo')
00283         self.assertEqual(type(obj._actions[0].description), str)
00284         self.assertEqual(obj._actions[0].description, '')
00285         self.assertEqual(type(obj._actions[0].category), str)
00286         self.assertEqual(obj._actions[0].category, 'Bar')
00287         self.assertEqual(type(obj._actions[0].condition.text), str)
00288         self.assertEqual(obj._actions[0].condition.text, 'python:1')
00289 
00290     def setUp(self):
00291         BodyAdapterTestCase.setUp(self)
00292         self._obj = FactoryTypeInformation('foo_fti')
00293         self._BODY = _FTI_BODY
00294 
00295 
00296 class TypesToolXMLAdapterTests(BodyAdapterTestCase):
00297 
00298     layer = ExportImportZCMLLayer
00299 
00300     def _getTargetClass(self):
00301         from Products.CMFCore.exportimport.typeinfo \
00302                 import TypesToolXMLAdapter
00303 
00304         return TypesToolXMLAdapter
00305 
00306     def _populate(self, obj):
00307         obj._setObject('foo_type', FactoryTypeInformation('foo_type'))
00308 
00309     def setUp(self):
00310         BodyAdapterTestCase.setUp(self)
00311         self._obj = TypesTool()
00312         self._BODY = _TYPESTOOL_BODY
00313 
00314 
00315 class _TypeInfoSetup(BaseRegistryTests):
00316 
00317     def _initSite(self, foo=0):
00318         self.root.site = Folder(id='site')
00319         site = self.root.site
00320         ttool = site.portal_types = TypesTool()
00321 
00322         if foo == 1:
00323             fti = _TI_LIST[0].copy()
00324             ttool._setObject(fti['id'], FactoryTypeInformation(**fti))
00325             sti = _TI_LIST[1].copy()
00326             ttool._setObject(sti['id'], ScriptableTypeInformation(**sti))
00327         elif foo == 2:
00328             fti = _TI_LIST_WITH_FILENAME[0].copy()
00329             ttool._setObject(fti['id'], FactoryTypeInformation(**fti))
00330             sti = _TI_LIST_WITH_FILENAME[1].copy()
00331             ttool._setObject(sti['id'], ScriptableTypeInformation(**sti))
00332 
00333         return site
00334 
00335 
00336 class exportTypesToolTests(_TypeInfoSetup):
00337 
00338     layer = ExportImportZCMLLayer
00339 
00340     def test_empty(self):
00341         from Products.CMFCore.exportimport.typeinfo import exportTypesTool
00342 
00343         site = self._initSite()
00344         context = DummyExportContext(site)
00345         exportTypesTool(context)
00346 
00347         self.assertEqual(len(context._wrote), 1)
00348         filename, text, content_type = context._wrote[0]
00349         self.assertEqual(filename, 'types.xml')
00350         self._compareDOM(text, _EMPTY_TOOL_EXPORT)
00351         self.assertEqual(content_type, 'text/xml')
00352 
00353     def test_normal(self):
00354         from Products.CMFCore.exportimport.typeinfo import exportTypesTool
00355 
00356         site = self._initSite(1)
00357         context = DummyExportContext(site)
00358         exportTypesTool(context)
00359 
00360         self.assertEqual(len(context._wrote), 3)
00361         filename, text, content_type = context._wrote[0]
00362         self.assertEqual(filename, 'types.xml')
00363         self._compareDOM(text, _NORMAL_TOOL_EXPORT)
00364         self.assertEqual(content_type, 'text/xml')
00365 
00366         filename, text, content_type = context._wrote[2]
00367         self.assertEqual(filename, 'types/bar.xml')
00368         self._compareDOM(text, _BAR_EXPORT % 'bar')
00369         self.assertEqual(content_type, 'text/xml')
00370 
00371         filename, text, content_type = context._wrote[1]
00372         self.assertEqual(filename, 'types/foo.xml')
00373         self._compareDOM(text, _FOO_EXPORT % 'foo')
00374         self.assertEqual(content_type, 'text/xml')
00375 
00376     def test_with_filenames(self):
00377         from Products.CMFCore.exportimport.typeinfo import exportTypesTool
00378 
00379         site = self._initSite(2)
00380         context = DummyExportContext(site)
00381         exportTypesTool(context)
00382 
00383         self.assertEqual(len(context._wrote), 3)
00384         filename, text, content_type = context._wrote[0]
00385         self.assertEqual(filename, 'types.xml')
00386         self._compareDOM(text, _FILENAME_EXPORT)
00387         self.assertEqual(content_type, 'text/xml')
00388         filename, text, content_type = context._wrote[2]
00389         self.assertEqual(filename, 'types/bar_object.xml')
00390         self._compareDOM(text, _BAR_EXPORT % 'bar object')
00391         self.assertEqual(content_type, 'text/xml')
00392         filename, text, content_type = context._wrote[1]
00393         self.assertEqual(filename, 'types/foo_object.xml')
00394         self._compareDOM(text, _FOO_EXPORT % 'foo object')
00395         self.assertEqual(content_type, 'text/xml')
00396 
00397 
00398 class importTypesToolTests(_TypeInfoSetup):
00399 
00400     layer = ExportImportZCMLLayer
00401 
00402     _EMPTY_TOOL_EXPORT = _EMPTY_TOOL_EXPORT
00403     _FILENAME_EXPORT = _FILENAME_EXPORT
00404     _NORMAL_TOOL_EXPORT = _NORMAL_TOOL_EXPORT
00405 
00406     def test_empty_default_purge(self):
00407         from Products.CMFCore.exportimport.typeinfo import importTypesTool
00408 
00409         site = self._initSite(1)
00410         tool = site.portal_types
00411 
00412         self.assertEqual(len(tool.objectIds()), 2)
00413 
00414         context = DummyImportContext(site)
00415         context._files['types.xml'] = self._EMPTY_TOOL_EXPORT
00416         importTypesTool(context)
00417 
00418         self.assertEqual(len(tool.objectIds()), 0)
00419 
00420     def test_empty_explicit_purge(self):
00421         from Products.CMFCore.exportimport.typeinfo import importTypesTool
00422 
00423         site = self._initSite(1)
00424         tool = site.portal_types
00425 
00426         self.assertEqual(len(tool.objectIds()), 2)
00427 
00428         context = DummyImportContext(site, True)
00429         context._files['types.xml'] = self._EMPTY_TOOL_EXPORT
00430         importTypesTool(context)
00431 
00432         self.assertEqual(len(tool.objectIds()), 0)
00433 
00434     def test_empty_skip_purge(self):
00435         from Products.CMFCore.exportimport.typeinfo import importTypesTool
00436 
00437         site = self._initSite(1)
00438         tool = site.portal_types
00439 
00440         self.assertEqual(len(tool.objectIds()), 2)
00441 
00442         context = DummyImportContext(site, False)
00443         context._files['types.xml'] = self._EMPTY_TOOL_EXPORT
00444         importTypesTool(context)
00445 
00446         self.assertEqual(len(tool.objectIds()), 2)
00447 
00448     def test_normal(self):
00449         from Products.CMFCore.exportimport.typeinfo import importTypesTool
00450 
00451         site = self._initSite()
00452         tool = site.portal_types
00453 
00454         self.assertEqual(len(tool.objectIds()), 0)
00455 
00456         context = DummyImportContext(site)
00457         context._files['types.xml'] = self._NORMAL_TOOL_EXPORT
00458         context._files['types/foo.xml'] = _FOO_EXPORT % 'foo'
00459         context._files['types/bar.xml'] = _BAR_EXPORT % 'bar'
00460         importTypesTool(context)
00461 
00462         self.assertEqual(len(tool.objectIds()), 2)
00463         self.failUnless('foo' in tool.objectIds())
00464         self.failUnless('bar' in tool.objectIds())
00465 
00466     def test_with_filenames(self):
00467         from Products.CMFCore.exportimport.typeinfo import importTypesTool
00468 
00469         site = self._initSite()
00470         tool = site.portal_types
00471 
00472         self.assertEqual(len(tool.objectIds()), 0)
00473 
00474         context = DummyImportContext(site)
00475         context._files['types.xml'] = self._FILENAME_EXPORT
00476         context._files['types/foo_object.xml'] = _FOO_EXPORT % 'foo object'
00477         context._files['types/bar_object.xml'] = _BAR_EXPORT % 'bar object'
00478         importTypesTool(context)
00479 
00480         self.assertEqual(len(tool.objectIds()), 2)
00481         self.failUnless('foo object' in tool.objectIds())
00482         self.failUnless('bar object' in tool.objectIds())
00483 
00484     def test_normal_update(self):
00485         from Products.CMFCore.exportimport.typeinfo import importTypesTool
00486 
00487         site = self._initSite()
00488         tool = site.portal_types
00489 
00490         context = DummyImportContext(site)
00491         context._files['types.xml'] = self._NORMAL_TOOL_EXPORT
00492         context._files['types/foo.xml'] = _FOO_EXPORT % 'foo'
00493         context._files['types/bar.xml'] = _BAR_EXPORT % 'bar'
00494         importTypesTool(context)
00495 
00496         self.assertEqual(tool.foo.title, 'Foo')
00497         self.assertEqual(tool.foo.content_meta_type, 'Foo Thing')
00498         self.assertEqual(tool.foo.content_icon, 'foo.png')
00499         self.assertEqual(tool.foo.immediate_view, 'foo_view')
00500         self.assertEqual(tool.foo._aliases,
00501                          {'(Default)': 'foo_view', 'view': 'foo_view'})
00502 
00503         context = DummyImportContext(site, False)
00504         context._files['types.xml'] = _UPDATE_TOOL_IMPORT
00505         context._files['types/foo.xml'] = _UPDATE_FOO_IMPORT
00506         importTypesTool(context)
00507 
00508         self.assertEqual(tool.foo.title, 'Foo')
00509         self.assertEqual(tool.foo.content_meta_type, 'Foo Thing')
00510         self.assertEqual(tool.foo.content_icon, 'foo.png')
00511         self.assertEqual(tool.foo.immediate_view, 'foo_view')
00512         self.assertEqual(tool.foo._aliases,
00513                {'(Default)': 'foo_view', 'view': 'foo_view', 'spam': 'eggs'})
00514 
00515 
00516 def test_suite():
00517     return unittest.TestSuite((
00518         unittest.makeSuite(TypeInformationXMLAdapterTests),
00519         unittest.makeSuite(TypesToolXMLAdapterTests),
00520         unittest.makeSuite(exportTypesToolTests),
00521         unittest.makeSuite(importTypesToolTests),
00522         ))
00523 
00524 if __name__ == '__main__':
00525     from Products.CMFCore.testing import run
00526     run(test_suite())