Back to index

plone3  3.1.7
testMigrations.py
Go to the documentation of this file.
00001 #
00002 # Tests for migration components
00003 #
00004 
00005 import os
00006 from Products.CMFPlone.tests import PloneTestCase
00007 
00008 from Acquisition import aq_base
00009 from OFS.SimpleItem import SimpleItem
00010 from Products.Archetypes.interfaces import IArchetypeTool
00011 from Products.Archetypes.interfaces import IReferenceCatalog
00012 from Products.Archetypes.interfaces import IUIDCatalog
00013 from Products.ATContentTypes.interface import IATCTTool
00014 from Products.CMFActionIcons.interfaces import IActionIconsTool
00015 from Products.CMFCalendar.interfaces import ICalendarTool
00016 from Products.CMFCore.ActionInformation import Action
00017 from Products.CMFCore.ActionInformation import ActionCategory
00018 from Products.CMFCore.utils import getToolByName
00019 from Products.CMFCore.Expression import Expression
00020 from Products.CMFCore.permissions import AccessInactivePortalContent
00021 from Products.CMFCore.interfaces import IActionCategory
00022 from Products.CMFCore.interfaces import IActionInfo
00023 from Products.CMFCore.interfaces import IActionsTool
00024 from Products.CMFCore.interfaces import ICachingPolicyManager
00025 from Products.CMFCore.interfaces import ICatalogTool
00026 from Products.CMFCore.interfaces import IContentTypeRegistry
00027 from Products.CMFCore.interfaces import IDiscussionTool
00028 from Products.CMFCore.interfaces import IMemberDataTool
00029 from Products.CMFCore.interfaces import IMembershipTool
00030 from Products.CMFCore.interfaces import IMetadataTool
00031 from Products.CMFCore.interfaces import IPropertiesTool
00032 from Products.CMFCore.interfaces import IRegistrationTool
00033 from Products.CMFCore.interfaces import ISiteRoot
00034 from Products.CMFCore.interfaces import ISkinsTool
00035 from Products.CMFCore.interfaces import ISyndicationTool
00036 from Products.CMFCore.interfaces import ITypesTool
00037 from Products.CMFCore.interfaces import IUndoTool
00038 from Products.CMFCore.interfaces import IURLTool
00039 from Products.CMFCore.interfaces import IConfigurableWorkflowTool
00040 from Products.CMFCore.ActionInformation import ActionInformation
00041 from Products.CMFDefault.Portal import CMFSite
00042 from Products.CMFDiffTool.interfaces import IDiffTool
00043 from Products.CMFEditions.interfaces import IArchivistTool
00044 from Products.CMFEditions.interfaces import IPortalModifierTool
00045 from Products.CMFEditions.interfaces import IPurgePolicyTool
00046 from Products.CMFEditions.interfaces.IRepository import IRepositoryTool
00047 from Products.CMFEditions.interfaces import IStorageTool
00048 from Products.CMFFormController.interfaces import IFormControllerTool
00049 from Products.CMFQuickInstallerTool.interfaces import IQuickInstallerTool
00050 from Products.CMFPlacefulWorkflow.global_symbols import placeful_prefs_configlet
00051 from Products.CMFPlacefulWorkflow.interfaces import IPlacefulMarker
00052 from Products.CMFPlone.interfaces import IControlPanel
00053 from Products.CMFPlone.interfaces import IFactoryTool
00054 from Products.CMFPlone.interfaces import IInterfaceTool
00055 from Products.CMFPlone.interfaces import IMigrationTool
00056 from Products.CMFPlone.interfaces import IPloneSiteRoot
00057 from Products.CMFPlone.interfaces import IPloneTool
00058 from Products.CMFPlone.interfaces import ITranslationServiceTool
00059 from Products.CMFPlone.UnicodeSplitter import Splitter, CaseNormalizer
00060 from Products.CMFUid.interfaces import IUniqueIdAnnotationManagement
00061 from Products.CMFUid.interfaces import IUniqueIdGenerator
00062 from Products.CMFUid.interfaces import IUniqueIdHandler
00063 from Products.GenericSetup.interfaces import ISetupTool
00064 from Products.MailHost.interfaces import IMailHost
00065 from Products.MimetypesRegistry.interfaces import IMimetypesRegistryTool
00066 from Products.PortalTransforms.interfaces import IPortalTransformsTool
00067 from Products.PloneLanguageTool.interfaces import ILanguageTool
00068 from Products.PlonePAS.interfaces.group import IGroupTool
00069 from Products.PlonePAS.interfaces.group import IGroupDataTool
00070 from Products.ResourceRegistries.interfaces import ICSSRegistry
00071 from Products.ResourceRegistries.interfaces import IJSRegistry
00072 from Products.CMFPlone.migrations.migration_util import loadMigrationProfile
00073 
00074 from Products.CMFPlone.migrations.v2_1.final_two11 import reindexPathIndex
00075 from Products.CMFPlone.migrations.v2_1.two11_two12 import removeCMFTopicSkinLayer
00076 from Products.CMFPlone.migrations.v2_1.two11_two12 import addRenameObjectButton
00077 from Products.CMFPlone.migrations.v2_1.two11_two12 import removeDiscussionItemWorkflow
00078 from Products.CMFPlone.migrations.v2_1.two11_two12 import addMemberData
00079 from Products.CMFPlone.migrations.v2_1.two11_two12 import reinstallPortalTransforms
00080 
00081 from Products.CMFPlone.migrations.v2_1.two12_two13 import normalizeNavtreeProperties
00082 from Products.CMFPlone.migrations.v2_1.two12_two13 import removeVcXMLRPC
00083 from Products.CMFPlone.migrations.v2_1.two12_two13 import addActionDropDownMenuIcons
00084 
00085 from Products.CMFPlone.migrations.v2_5.alphas import installPlacefulWorkflow
00086 from Products.CMFPlone.migrations.v2_5.alphas import installDeprecated
00087 from Products.CMFPlone.migrations.v2_5.alphas import installPlonePAS
00088 
00089 from Products.CMFPlone.migrations.v2_5.betas import addGetEventTypeIndex
00090 from Products.CMFPlone.migrations.v2_5.betas import fixHomeAction
00091 from Products.CMFPlone.migrations.v2_5.betas import removeBogusSkin
00092 from Products.CMFPlone.migrations.v2_5.betas import addPloneSkinLayers
00093 from Products.CMFPlone.migrations.v2_5.betas import installPortalSetup
00094 from Products.CMFPlone.migrations.v2_5.betas import simplifyActions
00095 from Products.CMFPlone.migrations.v2_5.betas import migrateCSSRegExpression
00096 
00097 from Products.CMFPlone.migrations.v2_5.final_two51 import removePloneCssFromRR
00098 from Products.CMFPlone.migrations.v2_5.final_two51 import addEventRegistrationJS
00099 from Products.CMFPlone.migrations.v2_5.final_two51 import fixupPloneLexicon
00100 from Products.CMFPlone.migrations.v2_5.final_two51 import fixObjDeleteAction
00101 
00102 from Products.CMFPlone.migrations.v2_5.two51_two52 import setLoginFormInCookieAuth
00103 from Products.CMFPlone.migrations.v2_5.two52_two53 import addMissingMimeTypes
00104 from Products.CMFPlone.migrations.v2_5.two53_two54 import addGSSteps
00105 from Products.CMFPlone.migrations.v2_5.two53_two54 import PROF_ID
00106 
00107 from Products.CMFPlone.migrations.v3_0.alphas import enableZope3Site
00108 from Products.CMFPlone.migrations.v3_0.alphas import migrateOldActions
00109 from Products.CMFPlone.migrations.v3_0.alphas import addNewCSSFiles
00110 from Products.CMFPlone.migrations.v3_0.alphas import addDefaultAndForbiddenContentTypesProperties
00111 from Products.CMFPlone.migrations.v3_0.alphas import addMarkupConfiglet
00112 from Products.CMFPlone.migrations.v3_0.alphas import addIconForMarkupConfiglet
00113 from Products.CMFPlone.migrations.v3_0.alphas import updateActionsI18NDomain
00114 from Products.CMFPlone.migrations.v3_0.alphas import updateFTII18NDomain
00115 from Products.CMFPlone.migrations.v3_0.alphas import convertLegacyPortlets
00116 from Products.CMFPlone.migrations.v3_0.alphas import addIconForCalendarSettingsConfiglet
00117 from Products.CMFPlone.migrations.v3_0.alphas import addCalendarConfiglet
00118 from Products.CMFPlone.migrations.v3_0.alphas import addMaintenanceConfiglet
00119 from Products.CMFPlone.migrations.v3_0.alphas import updateSearchAndMailHostConfiglet
00120 from Products.CMFPlone.migrations.v3_0.alphas import addFormTabbingJS
00121 from Products.CMFPlone.migrations.v3_0.alphas import addFormInputLabelJS
00122 from Products.CMFPlone.migrations.v3_0.alphas import registerToolsAsUtilities
00123 from Products.CMFPlone.migrations.v3_0.alphas import installKss
00124 from Products.CMFPlone.migrations.v3_0.alphas import installRedirectorUtility
00125 from Products.CMFPlone.migrations.v3_0.alphas import addContentRulesAction
00126 from Products.CMFPlone.migrations.v3_0.alphas import addReaderAndEditorRoles
00127 from Products.CMFPlone.migrations.v3_0.alphas import migrateLocalroleForm
00128 from Products.CMFPlone.migrations.v3_0.alphas import reorderUserActions
00129 from Products.CMFPlone.migrations.v3_0.alphas import updateRtlCSSexpression
00130 from Products.CMFPlone.migrations.v3_0.alphas import addMaintenanceProperty
00131 from Products.CMFPlone.migrations.v3_0.alphas import addLinkIntegritySwitch
00132 from Products.CMFPlone.migrations.v3_0.alphas import installS5
00133 from Products.CMFPlone.migrations.v3_0.alphas import addTableContents
00134 from Products.CMFPlone.migrations.v3_0.alphas import updatePASPlugins
00135 from Products.CMFPlone.migrations.v3_0.alphas import updateSkinsAndSiteConfiglet
00136 from Products.CMFPlone.migrations.v3_0.alphas import updateConfigletTitles
00137 from Products.CMFPlone.migrations.v3_0.alphas import addIconsForFilterAndSecurityConfiglets
00138 from Products.CMFPlone.migrations.v3_0.alphas import addFilterAndSecurityConfiglets
00139 from Products.CMFPlone.migrations.v3_0.alphas import addSitemapProperty
00140 from Products.CMFPlone.migrations.v3_0.alphas import updateKukitJS
00141 from Products.CMFPlone.migrations.v3_0.alphas import addCacheForResourceRegistry
00142 from Products.CMFPlone.migrations.v3_0.alphas import removeHideAddItemsJS
00143 from Products.CMFPlone.migrations.v3_0.alphas import addWebstatsJSProperty
00144 from Products.CMFPlone.migrations.v3_0.alphas import addWebstatsJSFile
00145 from Products.CMFPlone.migrations.v3_0.alphas import removeTablelessSkin
00146 from Products.CMFPlone.migrations.v3_0.alphas import installContentRulesUtility
00147 from Products.CMFPlone.migrations.v3_0.alphas import addIconForContentRulesConfiglet
00148 from Products.CMFPlone.migrations.v3_0.alphas import addContentRulesConfiglet
00149 from Products.CMFPlone.migrations.v3_0.alphas import addObjectProvidesIndex
00150 from Products.CMFPlone.migrations.v3_0.alphas import addExternalLinksOpenNewWindowProperty
00151 from Products.CMFPlone.migrations.v3_0.alphas import addTypesConfiglet
00152 from Products.CMFPlone.migrations.v3_0.alphas import addIconForTypesConfiglet
00153 from Products.CMFPlone.migrations.v3_0.alphas import addMissingWorkflows
00154 from Products.CMFPlone.migrations.v3_0.alphas import addManyGroupsProperty
00155 from Products.CMFPlone.migrations.v3_0.alphas import restorePloneTool
00156 from Products.CMFPlone.migrations.v3_0.alphas import installI18NUtilities
00157 from Products.CMFPlone.migrations.v3_0.alphas import installProduct
00158 from Products.CMFPlone.migrations.v3_0.alphas import addEmailCharsetProperty
00159 
00160 from Products.CMFPlone.migrations.v3_0.betas import migrateHistoryTab
00161 from Products.CMFPlone.migrations.v3_0.betas import changeOrderOfActionProviders
00162 from Products.CMFPlone.migrations.v3_0.betas import cleanupOldActions
00163 from Products.CMFPlone.migrations.v3_0.betas import cleanDefaultCharset
00164 from Products.CMFPlone.migrations.v3_0.betas import addAutoGroupToPAS
00165 from Products.CMFPlone.migrations.v3_0.betas import removeS5Actions
00166 from Products.CMFPlone.migrations.v3_0.betas import addCacheForKSSRegistry
00167 from Products.CMFPlone.migrations.v3_0.betas import addContributorToCreationPermissions
00168 from Products.CMFPlone.migrations.v3_0.betas import removeSharingAction
00169 from Products.CMFPlone.migrations.v3_0.betas import addEditorToSecondaryEditorPermissions
00170 from Products.CMFPlone.migrations.v3_0.betas import updateEditActionConditionForLocking
00171 from Products.CMFPlone.migrations.v3_0.betas import addOnFormUnloadJS
00172 
00173 from Products.CMFPlone.migrations.v3_0.betas import beta3_rc1
00174 from Products.CMFPlone.migrations.v3_0.betas import moveKupuAndCMFPWControlPanel
00175 from Products.CMFPlone.migrations.v3_0.betas import updateLanguageControlPanel
00176 from Products.CMFPlone.migrations.v3_0.betas import updateTopicTitle
00177 from Products.CMFPlone.migrations.v3_0.betas import cleanupActionProviders
00178 from Products.CMFPlone.migrations.v3_0.betas import hidePropertiesAction
00179 
00180 from Products.CMFPlone.migrations.v3_0.rcs import addIntelligentText
00181 
00182 from Products.CMFPlone.migrations.v3_0.final_three0x import installNewModifiers
00183 
00184 from Products.CMFPlone.migrations.v3_1.betas import reinstallCMFPlacefulWorkflow
00185 from Products.CMFPlone.setuphandlers import replace_local_role_manager
00186 
00187 from five.localsitemanager.registry import FiveVerifyingAdapterLookup
00188 
00189 from zope.app.cache.interfaces.ram import IRAMCache
00190 from zope.app.component.hooks import clearSite
00191 from zope.app.component.interfaces import ISite
00192 from zope.component import getGlobalSiteManager
00193 from zope.component import getSiteManager
00194 from zope.component import getUtility, getMultiAdapter, queryUtility
00195 from zope.interface import noLongerProvides
00196 
00197 from plone.app.i18n.locales.interfaces import IContentLanguages
00198 from plone.app.i18n.locales.interfaces import ICountries
00199 from plone.app.i18n.locales.interfaces import IMetadataLanguages
00200 
00201 from plone.app.redirector.interfaces import IRedirectionStorage
00202 from plone.contentrules.engine.interfaces import IRuleStorage
00203 
00204 from plone.app.portlets import portlets
00205 from plone.portlets.interfaces import IPortletManager
00206 from plone.portlets.interfaces import IPortletAssignmentMapping
00207 from plone.portlets.interfaces import ILocalPortletAssignmentManager
00208 from plone.portlets.constants import CONTEXT_CATEGORY as CONTEXT_PORTLETS
00209 
00210 from Products.PluggableAuthService.interfaces.plugins import IRolesPlugin
00211 from Products.PlonePAS.interfaces.plugins import ILocalRolesPlugin
00212 
00213 class BogusMailHost(SimpleItem):
00214     meta_type = 'Bad Mailer'
00215     title = 'Mailer'
00216     smtp_port = 37
00217     smtp_host = 'my.badhost.com'
00218 
00219 
00220 class MigrationTest(PloneTestCase.PloneTestCase):
00221 
00222     def removeActionFromTool(self, action_id, category=None, action_provider='portal_actions'):
00223         # Removes an action from portal_actions
00224         tool = getattr(self.portal, action_provider)
00225         if category is None:
00226             if action_id in tool.objectIds() and IActionInfo.providedBy(tool._getOb(action_id)):
00227                 tool._delOb(action_id)
00228         else:
00229             if category in tool.objectIds() and IActionCategory.providedBy(tool._getOb(category)):
00230                 if action_id in tool.objectIds() and IActionInfo.providedBy(tool._getOb(action_id)):
00231                     tool._delOb(action_id)
00232 
00233     def removeActionIconFromTool(self, action_id, category='plone'):
00234         # Removes an action icon from portal_actionicons
00235         tool = getattr(self.portal, 'portal_actionicons')
00236         try:
00237             tool.removeActionIcon(category, action_id)
00238         except KeyError:
00239             pass # No icon associated
00240 
00241     def addResourceToJSTool(self, resource_name):
00242         # Registers a resource with the javascripts tool
00243         tool = getattr(self.portal, 'portal_javascripts')
00244         if not resource_name in tool.getResourceIds():
00245             tool.registerScript(resource_name)
00246 
00247     def addResourceToCSSTool(self, resource_name):
00248         # Registers a resource with the css tool
00249         tool = getattr(self.portal, 'portal_css')
00250         if not resource_name in tool.getResourceIds():
00251             tool.registerStylesheet(resource_name)
00252 
00253     def removeSiteProperty(self, property_id):
00254         # Removes a site property from portal_properties
00255         tool = getattr(self.portal, 'portal_properties')
00256         sheet = getattr(tool, 'site_properties')
00257         if sheet.hasProperty(property_id):
00258             sheet.manage_delProperties([property_id])
00259 
00260     def addSiteProperty(self, property_id):
00261         # adds a site property to portal_properties
00262         tool = getattr(self.portal, 'portal_properties')
00263         sheet = getattr(tool, 'site_properties')
00264         if not sheet.hasProperty(property_id):
00265             sheet.manage_addProperty(property_id,[],'lines')
00266 
00267     def removeNavTreeProperty(self, property_id):
00268         # Removes a navtree property from portal_properties
00269         tool = getattr(self.portal, 'portal_properties')
00270         sheet = getattr(tool, 'navtree_properties')
00271         if sheet.hasProperty(property_id):
00272             sheet.manage_delProperties([property_id])
00273 
00274     def addNavTreeProperty(self, property_id):
00275         # adds a navtree property to portal_properties
00276         tool = getattr(self.portal, 'portal_properties')
00277         sheet = getattr(tool, 'navtree_properties')
00278         if not sheet.hasProperty(property_id):
00279             sheet.manage_addProperty(property_id,[],'lines')
00280 
00281     def removeMemberdataProperty(self, property_id):
00282         # Removes a memberdata property from portal_memberdata
00283         tool = getattr(self.portal, 'portal_memberdata')
00284         if tool.hasProperty(property_id):
00285             tool.manage_delProperties([property_id])
00286 
00287     def uninstallProduct(self, product_name):
00288         # Removes a product
00289         tool = getattr(self.portal, 'portal_quickinstaller')
00290         if tool.isProductInstalled(product_name):
00291             tool.uninstallProducts([product_name])
00292 
00293     def addSkinLayer(self, layer, skin='Plone Default', pos=None):
00294         # Adds a skin layer at pos. If pos is None, the layer is appended
00295         path = self.skins.getSkinPath(skin)
00296         path = [x.strip() for x in path.split(',')]
00297         if layer in path:
00298             path.remove(layer)
00299         if pos is None:
00300             path.append(layer)
00301         else:
00302             path.insert(pos, layer)
00303         self.skins.addSkinSelection(skin, ','.join(path))
00304 
00305     def removeSkinLayer(self, layer, skin='Plone Default'):
00306         # Removes a skin layer from skin
00307         path = self.skins.getSkinPath(skin)
00308         path = [x.strip() for x in path.split(',')]
00309         if layer in path:
00310             path.remove(layer)
00311             self.skins.addSkinSelection(skin, ','.join(path))
00312 
00313 
00314 class TestMigrations_v2_1_1(MigrationTest):
00315 
00316     def afterSetUp(self):
00317         self.actions = self.portal.portal_actions
00318         self.icons = self.portal.portal_actionicons
00319         self.properties = self.portal.portal_properties
00320         self.memberdata = self.portal.portal_memberdata
00321         self.membership = self.portal.portal_membership
00322         self.catalog = self.portal.portal_catalog
00323         self.groups = self.portal.portal_groups
00324         self.factory = self.portal.portal_factory
00325         self.portal_memberdata = self.portal.portal_memberdata
00326         self.cp = self.portal.portal_controlpanel
00327         self.skins = self.portal.portal_skins
00328 
00329     def testReindexPathIndex(self):
00330         # Should reindex the path index to create new index structures
00331         orig_results = self.catalog(path={'query':'news', 'level':1})
00332         orig_len = len(orig_results)
00333         self.failUnless(orig_len)
00334         # Simulate the old EPI
00335         delattr(self.catalog.Indexes['path'], '_index_parents')
00336         self.assertRaises(AttributeError, self.catalog,
00337                                         {'path':{'query':'/','navtree':1}})
00338         reindexPathIndex(self.portal, [])
00339         results = self.catalog(path={'query':'news', 'level':1})
00340         self.assertEqual(len(results), orig_len)
00341 
00342     def testReindexPathIndexTwice(self):
00343         # Should not fail when migrated twice, should do nothing if already
00344         # migrated
00345         orig_results = self.catalog(path={'query':'news', 'level':1})
00346         orig_len = len(orig_results)
00347         self.failUnless(orig_len)
00348         # Simulate the old EPI
00349         delattr(self.catalog.Indexes['path'], '_index_parents')
00350         self.assertRaises(AttributeError, self.catalog,
00351                                         {'path':{'query':'/','navtree':1}})
00352         out = []
00353         reindexPathIndex(self.portal, out)
00354         # Should return a message on the first iteration
00355         self.failUnless(out)
00356         out = []
00357         reindexPathIndex(self.portal, out)
00358         results = self.catalog(path={'query':'news', 'level':1})
00359         self.assertEqual(len(results), orig_len)
00360         # should return an empty list on the second iteration because nothing
00361         # was done
00362         self.failIf(out)
00363 
00364     def testReindexPathIndexNoIndex(self):
00365         # Should not fail when index is missing
00366         self.catalog.delIndex('path')
00367         reindexPathIndex(self.portal, [])
00368 
00369     def testReindexPathIndexNoCatalog(self):
00370         # Should not fail when index is missing
00371         self.portal._delObject('portal_catalog')
00372         reindexPathIndex(self.portal, [])
00373 
00374 
00375 class TestMigrations_v2_1_2(MigrationTest):
00376 
00377     def afterSetUp(self):
00378         self.actions = self.portal.portal_actions
00379         self.memberdata = self.portal.portal_memberdata
00380         self.skins = self.portal.portal_skins
00381         self.types = self.portal.portal_types
00382         self.workflow = self.portal.portal_workflow
00383 
00384     def testRemoveCMFTopicSkinPathFromDefault(self):
00385         # Should remove plone_3rdParty/CMFTopic from skin paths
00386         self.addSkinLayer('plone_3rdParty/CMFTopic')
00387         removeCMFTopicSkinLayer(self.portal, [])
00388         path = self.skins.getSkinPath('Plone Default')
00389         self.failIf('plone_3rdParty/CMFTopic' in path)
00390 
00391     def testRemoveCMFTopicSkinTwice(self):
00392         # Should not fail if migrated again
00393         self.addSkinLayer('plone_3rdParty/CMFTopic')
00394         removeCMFTopicSkinLayer(self.portal, [])
00395         removeCMFTopicSkinLayer(self.portal, [])
00396         path = self.skins.getSkinPath('Plone Default')
00397         self.failIf('plone_3rdParty/CMFTopic' in path)
00398 
00399     def testRemoveCMFTopicSkinNoTool(self):
00400         # Should not fail if tool is missing
00401         self.portal._delObject('portal_skins')
00402         removeCMFTopicSkinLayer(self.portal, [])
00403 
00404     def testRemoveCMFTopicSkinPathNoLayer(self):
00405         # Should not fail if plone_3rdParty layer is missing
00406         self.removeSkinLayer('plone_3rdParty')
00407         removeCMFTopicSkinLayer(self.portal, [])
00408         path = self.skins.getSkinPath('Plone Default')
00409         self.failIf('plone_3rdParty/CMFTopic' in path)
00410 
00411     def testAddRenameObjectButton(self):
00412         # Should add 'rename' object_button action
00413         editActions = self.actions.object_buttons.objectIds()
00414         assert 'rename' in editActions
00415         self.removeActionFromTool('rename', 'object_buttons')
00416         addRenameObjectButton(self.portal, [])
00417         actions = self.actions.object_buttons.objectIds()
00418         self.assertEqual(sorted(actions), sorted(editActions))
00419 
00420     def testAddRenameObjectButtonTwice(self):
00421         # Should not fail if migrated again
00422         editActions = self.actions.object_buttons.objectIds()
00423         assert 'rename' in editActions
00424         self.removeActionFromTool('rename', 'object_buttons')
00425         addRenameObjectButton(self.portal, [])
00426         addRenameObjectButton(self.portal, [])
00427         actions = self.actions.object_buttons.objectIds()
00428         self.assertEqual(sorted(actions), sorted(editActions))
00429 
00430     def testAddRenameObjectButtonActionExists(self):
00431         # Should add 'rename' object_button action
00432         editActions = self.actions.object_buttons.objectIds()
00433         assert 'rename' in editActions
00434         addRenameObjectButton(self.portal, [])
00435         actions = self.actions.object_buttons.objectIds()
00436         self.assertEqual(sorted(actions), sorted(editActions))
00437 
00438     def testAddRenameObjectButtonNoTool(self):
00439         # Should not fail if tool is missing
00440         self.portal._delObject('portal_actions')
00441         addRenameObjectButton(self.portal, [])
00442 
00443     def testAddSEHighLightJS(self):
00444         jsreg = self.portal.portal_javascripts
00445         script_ids = jsreg.getResourceIds()
00446         self.failUnless('se-highlight.js' in script_ids)
00447         # if highlightsearchterms.js is available se-highlight.js
00448         # should be positioned right underneath it
00449         if 'highlightsearchterms.js' in script_ids:
00450             posSE = jsreg.getResourcePosition('se-highlight.js')
00451             posHST = jsreg.getResourcePosition('highlightsearchterms.js')
00452             self.failUnless((posSE - 1) == posHST)
00453 
00454     def testRemoveDiscussionItemWorkflow(self):
00455         self.workflow.setChainForPortalTypes(('Discussion Item',), ('(Default)',))
00456         removeDiscussionItemWorkflow(self.portal, [])
00457         self.assertEqual(self.workflow.getChainForPortalType('Discussion Item'), ())
00458 
00459     def testRemoveDiscussionItemWorkflowNoTool(self):
00460         self.portal._delObject('portal_workflow')
00461         removeDiscussionItemWorkflow(self.portal, [])
00462 
00463     def testRemoveDiscussionItemWorkflowNoType(self):
00464         self.types._delObject('Discussion Item')
00465         removeDiscussionItemWorkflow(self.portal, [])
00466 
00467     def testRemoveDiscussionItemWorkflowTwice(self):
00468         self.workflow.setChainForPortalTypes(('Discussion Item',), ('(Default)',))
00469         removeDiscussionItemWorkflow(self.portal, [])
00470         self.assertEqual(self.workflow.getChainForPortalType('Discussion Item'), ())
00471         removeDiscussionItemWorkflow(self.portal, [])
00472         self.assertEqual(self.workflow.getChainForPortalType('Discussion Item'), ())
00473 
00474     def testAddMustChangePassword(self):
00475         # Should add the 'must change password' property
00476         self.removeMemberdataProperty('must_change_password')
00477         self.failIf(self.memberdata.hasProperty('must_change_password'))
00478         addMemberData(self.portal, [])
00479         self.failUnless(self.memberdata.hasProperty('must_change_password'))
00480 
00481     def testAddMustChangePasswordTwice(self):
00482         # Should not fail if migrated again
00483         self.removeMemberdataProperty('must_change_password')
00484         self.failIf(self.memberdata.hasProperty('must_change_password'))
00485         addMemberData(self.portal, [])
00486         addMemberData(self.portal, [])
00487         self.failUnless(self.memberdata.hasProperty('must_change_password'))
00488 
00489     def testAddMustChangePasswordNoTool(self):
00490         # Should not fail if portal_memberdata is missing
00491         self.portal._delObject('portal_memberdata')
00492         addMemberData(self.portal, [])
00493 
00494     def testReinstallPortalTransforms(self):
00495         self.portal._delObject('portal_transforms')
00496         reinstallPortalTransforms(self.portal, [])
00497         self.failUnless(hasattr(self.portal.aq_base, 'portal_transforms'))
00498 
00499     def testReinstallPortalTransformsTwice(self):
00500         self.portal._delObject('portal_transforms')
00501         reinstallPortalTransforms(self.portal, [])
00502         reinstallPortalTransforms(self.portal, [])
00503         self.failUnless(hasattr(self.portal.aq_base, 'portal_transforms'))
00504 
00505     def testReinstallPortalTransformsNoTool(self):
00506         self.portal._delObject('portal_quickinstaller')
00507         reinstallPortalTransforms(self.portal, [])
00508 
00509 
00510 class TestMigrations_v2_1_3(MigrationTest):
00511 
00512     def testNormalizeNavtreeProperties(self):
00513         ntp = self.portal.portal_properties.navtree_properties
00514         toRemove = ['skipIndex_html', 'showMyUserFolderOnly', 'showFolderishSiblingsOnly',
00515                     'showFolderishChildrenOnly', 'showNonFolderishObject', 'showTopicResults',
00516                     'rolesSeeContentView', 'rolesSeeUnpublishedContent', 'batchSize',
00517                     'croppingLength', 'forceParentsInBatch', 'rolesSeeHiddenContent', 'typesLinkToFolderContents']
00518         toAdd = {'name' : '', 'root' : '/', 'currentFolderOnlyInNavtree' : False}
00519         for property in toRemove:
00520             ntp._setProperty(property, 'X', 'string')
00521         for property, value in toAdd.items():
00522             ntp._delProperty(property)
00523         ntp.manage_changeProperties(bottomLevel = 65535)
00524         normalizeNavtreeProperties(self.portal, [])
00525         for property in toRemove:
00526             self.assertEqual(ntp.getProperty(property, None), None)
00527         for property, value in toAdd.items():
00528             self.assertEqual(ntp.getProperty(property), value)
00529         self.assertEqual(ntp.getProperty('bottomLevel'), 0)
00530 
00531     def testNormalizeNavtreePropertiesTwice(self):
00532         ntp = self.portal.portal_properties.navtree_properties
00533         toRemove = ['skipIndex_html', 'showMyUserFolderOnly', 'showFolderishSiblingsOnly',
00534                     'showFolderishChildrenOnly', 'showNonFolderishObject', 'showTopicResults',
00535                     'rolesSeeContentView', 'rolesSeeUnpublishedContent', 'rolesSeeContentsView',
00536                     'batchSize', 'sortCriteria', 'croppingLength', 'forceParentsInBatch',
00537                     'rolesSeeHiddenContent', 'typesLinkToFolderContents']
00538         toAdd = {'name' : '', 'root' : '/', 'currentFolderOnlyInNavtree' : False}
00539         for property in toRemove:
00540             ntp._setProperty(property, 'X', 'string')
00541         for property, value in toAdd.items():
00542             ntp._delProperty(property)
00543         ntp.manage_changeProperties(bottomLevel = 65535)
00544         normalizeNavtreeProperties(self.portal, [])
00545         normalizeNavtreeProperties(self.portal, [])
00546         for property in toRemove:
00547             self.assertEqual(ntp.getProperty(property, None), None)
00548         for property, value in toAdd.items():
00549             self.assertEqual(ntp.getProperty(property), value)
00550         self.assertEqual(ntp.getProperty('bottomLevel'), 0)
00551 
00552     def testNormalizeNavtreePropertiesNoTool(self):
00553         self.portal._delObject('portal_properties')
00554         normalizeNavtreeProperties(self.portal, [])
00555 
00556     def testNormalizeNavtreePropertiesNoSheet(self):
00557         self.portal.portal_properties._delObject('navtree_properties')
00558         normalizeNavtreeProperties(self.portal, [])
00559 
00560     def testNormalizeNavtreePropertiesNoPropertyToRemove(self):
00561         ntp = self.portal.portal_properties.navtree_properties
00562         if ntp.getProperty('skipIndex_html', None) is not None:
00563             ntp._delProperty('skipIndex_html')
00564         normalizeNavtreeProperties(self.portal, [])
00565 
00566     def testNormalizeNavtreePropertiesNewPropertyExists(self):
00567         ntp = self.portal.portal_properties.navtree_properties
00568         ntp.manage_changeProperties(root = '/foo', bottomLevel = 10)
00569         normalizeNavtreeProperties(self.portal, [])
00570         self.assertEqual(ntp.getProperty('root'), '/foo')
00571         self.assertEqual(ntp.getProperty('bottomLevel'), 10)
00572 
00573     def testRemoveVcXMLRPC(self):
00574         # Should unregister vcXMLRPC.js
00575         self.addResourceToJSTool('vcXMLRPC.js')
00576         removeVcXMLRPC(self.portal, [])
00577         jsreg = self.portal.portal_javascripts
00578         script_ids = jsreg.getResourceIds()
00579         self.failIf('vcXMLRPC.js' in script_ids)
00580 
00581     def testRemoveVcXMLRPCTwice(self):
00582         # Should not fail if migrated again
00583         self.addResourceToJSTool('vcXMLRPC.js')
00584         removeVcXMLRPC(self.portal, [])
00585         removeVcXMLRPC(self.portal, [])
00586         jsreg = self.portal.portal_javascripts
00587         script_ids = jsreg.getResourceIds()
00588         self.failIf('vcXMLRPC.js' in script_ids)
00589 
00590     def testRemoveVcXMLRPCNoTool(self):
00591         # Should not break if javascripts tool is missing
00592         self.portal._delObject('portal_javascripts')
00593         removeVcXMLRPC(self.portal, [])
00594 
00595     def testAddActionDropDownMenuIcons(self):
00596         # Should add icons to object buttons
00597         self.removeActionIconFromTool('cut', 'object_buttons')
00598         self.removeActionIconFromTool('copy', 'object_buttons')
00599         self.removeActionIconFromTool('paste', 'object_buttons')
00600         self.removeActionIconFromTool('delete', 'object_buttons')
00601         addActionDropDownMenuIcons(self.portal, [])
00602         ai=self.portal.portal_actionicons
00603         icons = dict([
00604             ((x.getCategory(), x.getActionId()), x)
00605             for x in ai.listActionIcons()
00606         ])
00607         self.failIf(('object_buttons', 'cut') not in icons)
00608         self.failIf(('object_buttons', 'copy') not in icons)
00609         self.failIf(('object_buttons', 'paste') not in icons)
00610         self.failIf(('object_buttons', 'delete') not in icons)
00611         self.assertEqual(icons[('object_buttons', 'cut')].getExpression(), 'cut_icon.gif')
00612         self.assertEqual(icons[('object_buttons', 'copy')].getExpression(), 'copy_icon.gif')
00613         self.assertEqual(icons[('object_buttons', 'paste')].getExpression(), 'paste_icon.gif')
00614         self.assertEqual(icons[('object_buttons', 'delete')].getExpression(), 'delete_icon.gif')
00615         self.assertEqual(icons[('object_buttons', 'cut')].getTitle(), 'Cut')
00616         self.assertEqual(icons[('object_buttons', 'copy')].getTitle(), 'Copy')
00617         self.assertEqual(icons[('object_buttons', 'paste')].getTitle(), 'Paste')
00618         self.assertEqual(icons[('object_buttons', 'delete')].getTitle(), 'Delete')
00619 
00620     def testAddActionDropDownMenuIconsTwice(self):
00621         # Should not fail if migrated again
00622         self.removeActionIconFromTool('cut', 'object_buttons')
00623         self.removeActionIconFromTool('copy', 'object_buttons')
00624         self.removeActionIconFromTool('paste', 'object_buttons')
00625         self.removeActionIconFromTool('delete', 'object_buttons')
00626         addActionDropDownMenuIcons(self.portal, [])
00627         addActionDropDownMenuIcons(self.portal, [])
00628         ai=self.portal.portal_actionicons
00629         icons = dict([
00630             ((x.getCategory(), x.getActionId()), x)
00631             for x in ai.listActionIcons()
00632         ])
00633         self.failIf(('object_buttons', 'cut') not in icons)
00634         self.failIf(('object_buttons', 'copy') not in icons)
00635         self.failIf(('object_buttons', 'paste') not in icons)
00636         self.failIf(('object_buttons', 'delete') not in icons)
00637         self.assertEqual(icons[('object_buttons', 'cut')].getExpression(), 'cut_icon.gif')
00638         self.assertEqual(icons[('object_buttons', 'copy')].getExpression(), 'copy_icon.gif')
00639         self.assertEqual(icons[('object_buttons', 'paste')].getExpression(), 'paste_icon.gif')
00640         self.assertEqual(icons[('object_buttons', 'delete')].getExpression(), 'delete_icon.gif')
00641         self.assertEqual(icons[('object_buttons', 'cut')].getTitle(), 'Cut')
00642         self.assertEqual(icons[('object_buttons', 'copy')].getTitle(), 'Copy')
00643         self.assertEqual(icons[('object_buttons', 'paste')].getTitle(), 'Paste')
00644         self.assertEqual(icons[('object_buttons', 'delete')].getTitle(), 'Delete')
00645 
00646     def testAddActionDropDownMenuIconsNoTool(self):
00647         # Should not break if actionicons tool is missing
00648         self.portal._delObject('portal_actionicons')
00649         addActionDropDownMenuIcons(self.portal, [])
00650 
00651 
00652 class TestMigrations_v2_5(MigrationTest):
00653 
00654     def afterSetUp(self):
00655         self.actions = self.portal.portal_actions
00656         self.memberdata = self.portal.portal_memberdata
00657         self.catalog = self.portal.portal_catalog
00658         self.skins = self.portal.portal_skins
00659         self.types = self.portal.portal_types
00660         self.workflow = self.portal.portal_workflow
00661 
00662     def testInstallPlacefulWorkflow(self):
00663         if 'portal_placefulworkflow' in self.portal.objectIds():
00664             self.portal._delObject('portal_placeful_workflow')
00665         installPlacefulWorkflow(self.portal, [])
00666         self.failUnless('portal_placeful_workflow' in self.portal.objectIds())
00667 
00668     def testInstallPlacefulWorkflowTwice(self):
00669         if 'portal_placefulworkflow' in self.portal.objectIds():
00670             self.portal._delObject('portal_placeful_workflow')
00671         installPlacefulWorkflow(self.portal, [])
00672         installPlacefulWorkflow(self.portal, [])
00673         self.failUnless('portal_placeful_workflow' in self.portal.objectIds())
00674 
00675     def testInstallPortalSetup(self):
00676         if 'portal_setup' in self.portal.objectIds():
00677             self.portal._delObject('portal_setup')
00678         installPortalSetup(self.portal, [])
00679         self.failUnless('portal_setup' in self.portal.objectIds())
00680 
00681     def testInstallPortalSetupTwice(self):
00682         if 'portal_setup' in self.portal.objectIds():
00683             self.portal._delObject('portal_setup')
00684         installPortalSetup(self.portal, [])
00685         installPortalSetup(self.portal, [])
00686         self.failUnless('portal_setup' in self.portal.objectIds())
00687 
00688     def testInstallPlonePAS(self):
00689         qi = self.portal.portal_quickinstaller
00690         if qi.isProductInstalled('PlonePAS'):
00691             self.setRoles(('Manager',))
00692             qi.uninstallProducts(['PlonePAS'])
00693         self.failIf(qi.isProductInstalled('PlonePAS'))
00694         installPlonePAS(self.portal, [])
00695         self.failUnless(qi.isProductInstalled('PlonePAS'))
00696 
00697     def testInstallPlonePASTwice(self):
00698         qi = self.portal.portal_quickinstaller
00699         if qi.isProductInstalled('PlonePAS'):
00700             self.setRoles(('Manager',))
00701             qi.uninstallProducts(['PlonePAS'])
00702         installPlonePAS(self.portal, [])
00703         installPlonePAS(self.portal, [])
00704         self.failUnless(qi.isProductInstalled('PlonePAS'))
00705 
00706     def testInstallPlonePASWithEnvironmentVariableSet(self):
00707         qi = self.portal.portal_quickinstaller
00708         if qi.isProductInstalled('PlonePAS'):
00709             self.setRoles(('Manager',))
00710             qi.uninstallProducts(['PlonePAS'])
00711         self.failIf(qi.isProductInstalled('PlonePAS'))
00712         os.environ['SUPPRESS_PLONEPAS_INSTALLATION'] = 'YES'
00713         installPlonePAS(self.portal, [])
00714         self.failIf(qi.isProductInstalled('PlonePAS'))
00715         del os.environ['SUPPRESS_PLONEPAS_INSTALLATION']
00716         installPlonePAS(self.portal, [])
00717         self.failUnless(qi.isProductInstalled('PlonePAS'))
00718 
00719     def testInstallDeprecated(self):
00720         # Remove skin
00721         self.skins._delObject('plone_deprecated')
00722         skins = ['Plone Default']
00723         for s in skins:
00724             path = self.skins.getSkinPath(s)
00725             path = [p.strip() for p in  path.split(',')]
00726             path.remove('plone_deprecated')
00727             self.skins.addSkinSelection(s, ','.join(path))
00728         self.failIf('plone_deprecated' in
00729                            self.skins.getSkinPath('Plone Default').split(','))
00730         installDeprecated(self.portal, [])
00731         self.failUnless('plone_deprecated' in self.skins.objectIds())
00732         # it should be in the skin now
00733         self.assertEqual(self.skins.getSkinPath('Plone Default').split(',')[-3],
00734                          'plone_deprecated')
00735 
00736     def testInstallDeprecatedTwice(self):
00737         # Remove skin
00738         self.skins._delObject('plone_deprecated')
00739         skins = ['Plone Default']
00740         for s in skins:
00741             path = self.skins.getSkinPath(s)
00742             path = [p.strip() for p in  path.split(',')]
00743             path.remove('plone_deprecated')
00744             self.skins.addSkinSelection(s, ','.join(path))
00745         self.failIf('plone_deprecated' in
00746                            self.skins.getSkinPath('Plone Default').split(','))
00747         skin_len = len(self.skins.getSkinPath('Plone Default').split(','))
00748         installDeprecated(self.portal, [])
00749         installDeprecated(self.portal, [])
00750         self.failUnless('plone_deprecated' in self.skins.objectIds())
00751         # it should be in the skin now
00752         self.assertEqual(self.skins.getSkinPath('Plone Default').split(',')[-3],
00753                          'plone_deprecated')
00754         self.assertEqual(len(self.skins.getSkinPath('Plone Default').split(',')),
00755                          skin_len+1)
00756 
00757     def testInstallDeprecatedNoTool(self):
00758         # Remove skin
00759         self.portal._delObject('portal_skins')
00760         installDeprecated(self.portal, [])
00761 
00762     def testAddDragDropReorderJS(self):
00763         jsreg = self.portal.portal_javascripts
00764         script_ids = jsreg.getResourceIds()
00765         self.failUnless('dragdropreorder.js' in script_ids)
00766         # if dropdown.js is available dragdropreorder.js
00767         # should be positioned right underneath it
00768         if 'dropdown.js' in script_ids:
00769             posSE = jsreg.getResourcePosition('dragdropreorder.js')
00770             posHST = jsreg.getResourcePosition('select_all.js')
00771             self.failUnless((posSE - 1) == posHST)
00772 
00773     def testAddGetEventTypeIndex(self):
00774         # Should add getEventType index
00775         self.catalog.delIndex('getEventType')
00776         addGetEventTypeIndex(self.portal, [])
00777         index = self.catalog._catalog.getIndex('getEventType')
00778         self.assertEqual(index.__class__.__name__, 'KeywordIndex')
00779 
00780     def testAddGetEventTypeIndexTwice(self):
00781         # Should not fail if migrated again
00782         self.catalog.delIndex('getEventType')
00783         addGetEventTypeIndex(self.portal, [])
00784         addGetEventTypeIndex(self.portal, [])
00785         index = self.catalog._catalog.getIndex('getEventType')
00786         self.assertEqual(index.__class__.__name__, 'KeywordIndex')
00787 
00788     def testAddGetEventTypeIndexNoCatalog(self):
00789         # Should not fail if portal_catalog is missing
00790         self.portal._delObject('portal_catalog')
00791         addGetEventTypeIndex(self.portal, [])
00792 
00793     def testFixHomeAction(self):
00794         editActions = ('index_html',)
00795         for a in editActions:
00796             self.removeActionFromTool(a)
00797         fixHomeAction(self.portal, [])
00798         actions = [x.id for x in self.actions.listActions()]
00799         for a in editActions:
00800             self.failUnless(a in actions)
00801 
00802     def testFixHomeActionTwice(self):
00803         editActions = ('index_html',)
00804         for a in editActions:
00805             self.removeActionFromTool(a)
00806         fixHomeAction(self.portal, [])
00807         fixHomeAction(self.portal, [])
00808         actions = [x.id for x in self.actions.listActions()]
00809         for a in editActions:
00810             self.failUnless(a in actions)
00811 
00812     def testFixHomeActionNoTool(self):
00813         self.portal._delObject('portal_actions')
00814         fixHomeAction(self.portal, [])
00815 
00816     def testRemoveBogusSkin(self):
00817         # Add bogus skin
00818         self.skins.manage_skinLayers(add_skin=1, skinname='cmf_legacy',
00819                                   skinpath=['plone_forms','plone_templates'])
00820         self.failUnless(self.skins._getSelections().has_key('cmf_legacy'))
00821         removeBogusSkin(self.portal, [])
00822         # It should be gone
00823         self.failIf(self.skins._getSelections().has_key('cmf_legacy'))
00824 
00825     def testAddPloneSkinLayers(self):
00826         # Add bogus skin
00827         self.skins.manage_skinLayers(add_skin=1, skinname='foo_bar',
00828                                   skinpath=['plone_forms','plone_templates'])
00829         self.failUnless(self.skins._getSelections().has_key('foo_bar'))
00830 
00831         path = [p.strip() for p in self.skins.getSkinPath('foo_bar').split(',')]
00832         self.assertEqual(['plone_forms', 'plone_templates'], path)
00833 
00834         addPloneSkinLayers(self.portal, [])
00835 
00836         path = [p.strip() for p in self.skins.getSkinPath('foo_bar').split(',')]
00837         self.assertEqual(['plone_forms', 'plone_templates', 'plone_deprecated'], path)
00838 
00839     def testRemoveBogusSkinTwice(self):
00840         self.skins.manage_skinLayers(add_skin=1, skinname='cmf_legacy',
00841                                   skinpath=['plone_forms','plone_templates'])
00842         self.failUnless(self.skins._getSelections().has_key('cmf_legacy'))
00843         removeBogusSkin(self.portal, [])
00844         removeBogusSkin(self.portal, [])
00845         self.failIf(self.skins._getSelections().has_key('cmf_legacy'))
00846 
00847     def testRemoveBogusSkinNoSkin(self):
00848         self.failIf(self.skins._getSelections().has_key('cmf_legacy'))
00849         removeBogusSkin(self.portal, [])
00850         self.failIf(self.skins._getSelections().has_key('cmf_legacy'))
00851 
00852     def testRemoveBogusSkinNoTool(self):
00853         self.portal._delObject('portal_skins')
00854         removeBogusSkin(self.portal, [])
00855 
00856     def testSimplifyActions(self):
00857         # Should simplify a number of actions across multiple tools using the
00858         # view methods
00859         tool = self.portal.portal_actions
00860         paste = tool.object_buttons.paste
00861         rename = tool.object_buttons.rename
00862         contents = tool.object.folderContents
00863         index = tool.portal_tabs.index_html
00864         # Set the expressions and conditions to their 2.5 analogues to test
00865         # every substitution
00866         paste._updateProperty('url_expr',
00867                 'python:"%s/object_paste"%((object.isDefaultPageInFolder() or not object.is_folderish()) and object.getParentNode().absolute_url() or object_url)')
00868         rename._updateProperty('url_expr',
00869                 'python:"%s/object_rename"%(object.isDefaultPageInFolder() and object.getParentNode().absolute_url() or object_url)')
00870         rename.edit('available_expr',
00871                 'python:portal.portal_membership.checkPermission("Delete objects", object.aq_inner.getParentNode()) and portal.portal_membership.checkPermission("Copy or Move", object) and portal.portal_membership.checkPermission("Add portal content", object) and object is not portal and not (object.isDefaultPageInFolder() and object.getParentNode() is portal)')
00872         contents._updateProperty('url_expr',
00873                 "python:((object.isDefaultPageInFolder() and object.getParentNode().absolute_url()) or folder_url)+'/folder_contents'")
00874         index._updateProperty('url_expr',
00875                 'string: ${here/@@plone/navigationRootUrl}')
00876 
00877         # Verify that the changes have been made
00878         paste = tool.object_buttons.paste
00879         self.failUnless("object.isDefaultPageInFolder()" in
00880                                                   paste.getProperty('url_expr'))
00881         # Run the action simplifications
00882         simplifyActions(self.portal, [])
00883         self.assertEqual(paste.getProperty('url_expr'),
00884                 "string:${globals_view/getCurrentFolderUrl}/object_paste")
00885         self.assertEqual(rename.getProperty('url_expr'),
00886                 "string:${globals_view/getCurrentObjectUrl}/object_rename")
00887         self.assertEqual(rename.getProperty('available_expr'),
00888                 'python:checkPermission("Delete objects", globals_view.getParentObject()) and checkPermission("Copy or Move", object) and checkPermission("Add portal content", object) and not globals_view.isPortalOrPortalDefaultPage()')
00889         self.assertEqual(contents.getProperty('url_expr'),
00890                 "string:${globals_view/getCurrentFolderUrl}/folder_contents")
00891         self.assertEqual(index.getProperty('url_expr'),
00892                 "string:${globals_view/navigationRootUrl}")
00893 
00894     def testSimplifyActionsTwice(self):
00895         # Should result in the same string when applied twice
00896         tool = self.portal.portal_actions
00897         paste = tool.object_buttons.paste
00898         paste._updateProperty('url_expr',
00899                               'python:"%s/object_paste"%((object.isDefaultPageInFolder() or not object.is_folderish()) and object.getParentNode().absolute_url() or object_url)')
00900 
00901         # Verify that the changes have been made
00902         paste = tool.object_buttons.paste
00903         self.failUnless("object.isDefaultPageInFolder()" in
00904                                 paste.getProperty('url_expr'))
00905 
00906         # Run the action simplifications twice
00907         simplifyActions(self.portal, [])
00908         simplifyActions(self.portal, [])
00909 
00910         # We should have the same result
00911         self.assertEqual(paste.getProperty('url_expr'),
00912                 "string:${globals_view/getCurrentFolderUrl}/object_paste")
00913 
00914     def testSimplifyActionsNoTool(self):
00915         # Sholud not fail if the tool is missing
00916         self.portal._delObject('portal_actions')
00917         simplifyActions(self.portal, [])
00918 
00919     def testMigrateCSSRegExpression(self):
00920         # Should convert the expression using a deprecated script to use the
00921         # view
00922         css_reg = self.portal.portal_css
00923         resource = css_reg.getResource('RTL.css')
00924         resource.setExpression("python:object.isRightToLeft(domain='plone')")
00925         css_reg.cookResources()
00926 
00927         # Ensure the change worked
00928         resource = css_reg.getResource('RTL.css')
00929         self.failUnless('object.isRightToLeft' in resource.getExpression())
00930 
00931         # perform the migration
00932         migrateCSSRegExpression(self.portal, [])
00933         self.assertEqual(resource.getExpression(),
00934                 "object/@@plone/isRightToLeft")
00935 
00936     def testMigrateCSSRegExpressionWith25Expression(self):
00937         # Should replace the restrictedTraverse call with the more compact
00938         # path expression
00939         css_reg = self.portal.portal_css
00940         resource = css_reg.getResource('RTL.css')
00941         resource.setExpression(
00942 "python:object.restrictedTraverse('@@plone').isRightToLeft(domain='plone')")
00943         css_reg.cookResources()
00944 
00945         # perform the migration
00946         migrateCSSRegExpression(self.portal, [])
00947         self.assertEqual(resource.getExpression(),
00948                 "object/@@plone/isRightToLeft")
00949 
00950     def testMigrateCSSRegExpressionTwice(self):
00951         # Should result in the same string when applied twice
00952         css_reg = self.portal.portal_css
00953         resource = css_reg.getResource('RTL.css')
00954         resource.setExpression("python:object.isRightToLeft(domain='plone')")
00955         css_reg.cookResources()
00956 
00957         # perform the migration twice
00958         migrateCSSRegExpression(self.portal, [])
00959         migrateCSSRegExpression(self.portal, [])
00960         self.assertEqual(resource.getExpression(),
00961                 "object/@@plone/isRightToLeft")
00962 
00963     def testMigrateCSSRegExpressionNoTool(self):
00964         # Should not fail if the tool is missing
00965         self.portal._delObject('portal_css')
00966         migrateCSSRegExpression(self.portal, [])
00967 
00968     def testMigrateCSSRegExpressionNoResource(self):
00969         # Should not fail if the resource is missing
00970         css_reg = self.portal.portal_css
00971         css_reg.unregisterResource('RTL.css')
00972         migrateCSSRegExpression(self.portal, [])
00973 
00974 class TestMigrations_v2_5_1(MigrationTest):
00975 
00976     def afterSetUp(self):
00977         self.actions = self.portal.portal_actions
00978         self.memberdata = self.portal.portal_memberdata
00979         self.catalog = self.portal.portal_catalog
00980         self.skins = self.portal.portal_skins
00981         self.types = self.portal.portal_types
00982         self.workflow = self.portal.portal_workflow
00983         self.css = self.portal.portal_css
00984 
00985     def testRemovePloneCssFromRR(self):
00986         # Check to ensure that plone.css gets removed from portal_css
00987         self.css.registerStylesheet('plone.css', media='all')
00988         self.failUnless('plone.css' in self.css.getResourceIds())
00989         removePloneCssFromRR(self.portal, [])
00990         self.failIf('plone.css' in self.css.getResourceIds())
00991 
00992     def testRemovePloneCssFromRRTwice(self):
00993         # Should not fail if performed twice
00994         self.css.registerStylesheet('plone.css', media='all')
00995         self.failUnless('plone.css' in self.css.getResourceIds())
00996         removePloneCssFromRR(self.portal, [])
00997         removePloneCssFromRR(self.portal, [])
00998         self.failIf('plone.css' in self.css.getResourceIds())
00999 
01000     def testRemovePloneCssFromRRNoCSS(self):
01001         # Should not fail if the stylesheet is missing
01002         self.failIf('plone.css' in self.css.getResourceIds())
01003         removePloneCssFromRR(self.portal, [])
01004 
01005     def testRemovePloneCssFromRRNoTool(self):
01006         # Should not fail if the tool is missing
01007         self.portal._delObject('portal_css')
01008         removePloneCssFromRR(self.portal, [])
01009 
01010     def testAddEventRegistrationJS(self):
01011         jsreg = self.portal.portal_javascripts
01012         # unregister first
01013         jsreg.unregisterResource('event-registration.js')
01014         script_ids = jsreg.getResourceIds()
01015         self.failIf('event-registration.js' in script_ids)
01016         # migrate and test again
01017         addEventRegistrationJS(self.portal, [])
01018         script_ids = jsreg.getResourceIds()
01019         self.failUnless('event-registration.js' in script_ids)
01020         self.assertEqual(jsreg.getResourcePosition('event-registration.js'), 0)
01021 
01022     def testAddEventRegistrationJSTwice(self):
01023         # Should not break if migrated again
01024         jsreg = self.portal.portal_javascripts
01025         # unregister first
01026         jsreg.unregisterResource('event-registration.js')
01027         script_ids = jsreg.getResourceIds()
01028         self.failIf('event-registration.js' in script_ids)
01029         # migrate and test again
01030         addEventRegistrationJS(self.portal, [])
01031         addEventRegistrationJS(self.portal, [])
01032         script_ids = jsreg.getResourceIds()
01033         self.failUnless('event-registration.js' in script_ids)
01034         self.assertEqual(jsreg.getResourcePosition('event-registration.js'), 0)
01035 
01036     def testAddEventRegistrationJSNoTool(self):
01037         # Should not break if the tool is missing
01038         self.portal._delObject('portal_javascripts')
01039         addEventRegistrationJS(self.portal, [])
01040 
01041     def testFixupPloneLexicon(self):
01042         # Should update the plone_lexicon pipeline
01043         lexicon = self.portal.portal_catalog.plone_lexicon
01044         lexicon._pipeline = (object(), object())
01045         fixupPloneLexicon(self.portal, [])
01046         self.failUnless(isinstance(lexicon._pipeline[0], Splitter))
01047         self.failUnless(isinstance(lexicon._pipeline[1], CaseNormalizer))
01048 
01049     def testFixupPloneLexiconTwice(self):
01050         # Should not break if migrated again
01051         lexicon = self.portal.portal_catalog.plone_lexicon
01052         lexicon._pipeline = (object(), object())
01053         fixupPloneLexicon(self.portal, [])
01054         fixupPloneLexicon(self.portal, [])
01055         self.failUnless(isinstance(lexicon._pipeline[0], Splitter))
01056         self.failUnless(isinstance(lexicon._pipeline[1], CaseNormalizer))
01057 
01058     def testFixupPloneLexiconNoLexicon(self):
01059         # Should not break if plone_lexicon is missing
01060         self.portal.portal_catalog._delObject('plone_lexicon')
01061         fixupPloneLexicon(self.portal, [])
01062 
01063     def testFixupPloneLexiconNoTool(self):
01064         # Should not break if portal_catalog is missing
01065         self.portal._delObject('portal_catalog')
01066         fixupPloneLexicon(self.portal, [])
01067 
01068     def tesFixObjDeleteActionTwice(self):
01069         # Should not error if performed twice
01070         editActions = ('delete',)
01071         for a in editActions:
01072             self.removeActionFromTool(a)
01073         fixObjDeleteAction(self.portal, [])
01074         fixObjDeleteAction(self.portal, [])
01075         actions = [x.id for x in self.actions.listActions()
01076                    if x.id in editActions]
01077         # check that all of our deleted actions are now present
01078         for a in editActions:
01079             self.failUnless(a in actions)
01080         # ensure that they are present only once
01081         self.failUnlessEqual(len(editActions), len(actions))
01082 
01083     def testFixObjDeleteActionNoAction(self):
01084         # Should add the action
01085         editActions = ('delete',)
01086         for a in editActions:
01087             self.removeActionFromTool(a)
01088         fixObjDeleteAction(self.portal, [])
01089         actions = [x for x in self.actions.object_buttons.objectIds()
01090                    if x in editActions]
01091         for a in editActions:
01092             self.failUnless(a in actions)
01093         self.failUnlessEqual(len(editActions), len(actions))
01094 
01095     def testFixObjDeleteActionNoTool(self):
01096         self.portal._delObject('portal_actions')
01097         fixObjDeleteAction(self.portal, [])
01098 
01099     def testSetLoginFormInCookieAuth(self):
01100         setLoginFormInCookieAuth(self.portal, [])
01101         cookie_auth = self.portal.acl_users.credentials_cookie_auth
01102         self.failUnlessEqual(cookie_auth.getProperty('login_path'),
01103                              'require_login')
01104 
01105     def testSetLoginFormNoCookieAuth(self):
01106         # Shouldn't error
01107         uf = self.portal.acl_users
01108         uf._delOb('credentials_cookie_auth')
01109         setLoginFormInCookieAuth(self.portal, [])
01110 
01111     def testSetLoginFormAlreadyChanged(self):
01112         # Shouldn't change the value if it's not the default
01113         cookie_auth = self.portal.acl_users.credentials_cookie_auth
01114         cookie_auth.manage_changeProperties(login_path='foo')
01115         out = []
01116         setLoginFormInCookieAuth(self.portal, out)
01117         self.failIf(len(out) > 0)
01118         self.failIfEqual(cookie_auth.getProperty('login_path'),
01119                          'require_login')
01120 
01121 class TestMigrations_v2_5_2(MigrationTest):
01122 
01123     def afterSetUp(self):
01124         self.mimetypes = self.portal.mimetypes_registry
01125         
01126     def testMissingMimeTypes(self):
01127         # we're testing for 'text/x-web-markdown' and 'text/x-web-textile'
01128         missing_types = ['text/x-web-markdown', 'text/x-web-textile']
01129         # since we're running a full 2.5.4 instance in this test, the missing
01130         # types might in fact already be there:
01131         current_types = self.mimetypes.list_mimetypes()
01132         types_to_delete = []
01133         for mtype in missing_types:
01134             if mtype in current_types:
01135                 types_to_delete.append(mtype)
01136         if types_to_delete:
01137             self.mimetypes.manage_delObjects(types_to_delete)
01138         # now they're gone:
01139         self.failIf(set(self.mimetypes.list_mimetypes()).issuperset(set(missing_types)))
01140         out = []
01141         addMissingMimeTypes(self.portal, out)
01142         # now they're back:
01143         self.failUnless(set(self.mimetypes.list_mimetypes()).issuperset(set(missing_types)))
01144 
01145 
01146 class TestMigrations_v2_5_4(MigrationTest):
01147 
01148     def afterSetUp(self):
01149         self.setup = self.portal.portal_setup
01150 
01151     def testAddGSSteps(self):
01152         # unset the gs profile
01153         self.setup._baseline_context_id = ''
01154         self.assertEqual(self.setup.getBaselineContextID(), '')
01155         addGSSteps(self.portal, [])
01156         self.assertEqual(self.setup.getBaselineContextID(),
01157                          'profile-' + PROF_ID)
01158 
01159     def testAddGSStepsAlreadyThere(self):
01160         # set a bogus existing profile, ensure we don't change it
01161         self.setup._baseline_context_id = 'profile-Bogus:bogus'
01162         self.assertEqual(self.setup.getBaselineContextID(),
01163                          'profile-Bogus:bogus')
01164         addGSSteps(self.portal, [])
01165         self.assertEqual(self.setup.getBaselineContextID(),
01166                          'profile-Bogus:bogus')
01167 
01168     def testAddGSStepsNoPloneStep(self):
01169         # if the plone step is not there, don't set it
01170         # first remove it from the registry
01171         self.setup._baseline_context_id = ''
01172         from Products.GenericSetup.registry import _profile_registry
01173         _profile_registry._profile_ids.remove(PROF_ID)
01174         prof_info = _profile_registry._profile_info[PROF_ID]
01175         del _profile_registry._profile_info[PROF_ID]
01176 
01177         # Then go through the normal migration process
01178         self.assertEqual(self.setup.getBaselineContextID(),
01179                          '')
01180         addGSSteps(self.portal, [])
01181         self.assertEqual(self.setup.getBaselineContextID(),
01182                          '')
01183         # restore registry, because this is not undone by the transaction
01184         _profile_registry._profile_ids.append(PROF_ID)
01185         _profile_registry._profile_info[PROF_ID] = prof_info
01186 
01187     def testAddGSStepsNoTool(self):
01188         # do nothing if there's no tool
01189         self.portal._delObject('portal_setup')
01190         addGSSteps(self.portal, [])
01191 
01192 
01193 class TestMigrations_v3_0_Actions(MigrationTest):
01194 
01195     def afterSetUp(self):
01196         self.actions = self.portal.portal_actions
01197         self.types = self.portal.portal_types
01198         self.workflow = self.portal.portal_workflow
01199         
01200         # Create dummy old ActionInformation
01201         self.reply = ActionInformation('reply',
01202             title='Reply',
01203             category='reply_actions',
01204             condition='context/replyAllowed',
01205             permissions=(AccessInactivePortalContent, ),
01206             priority=10,
01207             visible=True,
01208             action='context/reply'
01209         )
01210         self.discussion = self.portal.portal_discussion
01211         self.discussion._actions = (self.reply, )
01212 
01213     def testMigrateActions(self):
01214         self.failUnless(self.discussion._actions == (self.reply, ))
01215         
01216         migrateOldActions(self.portal, [])
01217 
01218         reply_actions = getattr(self.actions, 'reply_actions', None)
01219         self.failIf(reply_actions is None)
01220         reply = getattr(reply_actions, 'reply', None)
01221         self.failIf(reply is None)
01222         self.failUnless(isinstance(reply, Action))
01223 
01224         # Verify all data has been migrated correctly to the new Action
01225         data = reply.getInfoData()[0]
01226         self.assertEquals(data['category'], 'reply_actions')
01227         self.assertEquals(data['title'], 'Reply')
01228         self.assertEquals(data['visible'], True)
01229         self.assertEquals(data['permissions'], (AccessInactivePortalContent, ))
01230         self.assertEquals(data['available'].text, 'context/replyAllowed')
01231         self.assertEquals(data['url'].text, 'context/reply')
01232 
01233         # Make sure the original action has been removed
01234         self.failUnless(len(self.discussion._actions) == 0)
01235 
01236     def testMigrateActionsTwice(self):
01237         self.failUnless(self.discussion._actions == (self.reply, ))
01238 
01239         migrateOldActions(self.portal, [])
01240         migrateOldActions(self.portal, [])
01241 
01242         reply_actions = getattr(self.actions, 'reply_actions', None)
01243         self.failIf(reply_actions is None)
01244         reply = getattr(reply_actions, 'reply', None)
01245         self.failIf(reply is None)
01246         self.failUnless(isinstance(reply, Action))
01247 
01248         # Verify all data has been migrated correctly to the new Action
01249         data = reply.getInfoData()[0]
01250         self.assertEquals(data['category'], 'reply_actions')
01251         self.assertEquals(data['title'], 'Reply')
01252         self.assertEquals(data['visible'], True)
01253         self.assertEquals(data['permissions'], (AccessInactivePortalContent, ))
01254         self.assertEquals(data['available'].text, 'context/replyAllowed')
01255         self.assertEquals(data['url'].text, 'context/reply')
01256 
01257         # Make sure the original action has been removed
01258         self.failUnless(len(self.discussion._actions) == 0)
01259 
01260     def testUpdateActionsI18NDomain(self):
01261         migrateOldActions(self.portal, [])
01262         reply = self.actions.reply_actions.reply
01263         self.assertEquals(reply.i18n_domain, '')
01264 
01265         updateActionsI18NDomain(self.portal, [])
01266         
01267         self.assertEquals(reply.i18n_domain, 'plone')
01268 
01269     def testUpdateActionsI18NDomainTwice(self):
01270         migrateOldActions(self.portal, [])
01271         reply = self.actions.reply_actions.reply
01272         self.assertEquals(reply.i18n_domain, '')
01273 
01274         updateActionsI18NDomain(self.portal, [])
01275         updateActionsI18NDomain(self.portal, [])
01276 
01277         self.assertEquals(reply.i18n_domain, 'plone')
01278 
01279     def testUpdateActionsI18NDomainNonAscii(self):
01280         migrateOldActions(self.portal, [])
01281         reply = self.actions.reply_actions.reply
01282         reply.title = 'Foo\xc3'
01283         self.assertEquals(reply.i18n_domain, '')
01284         self.assertEquals(reply.title, 'Foo\xc3')
01285 
01286         updateActionsI18NDomain(self.portal, [])
01287         
01288         self.assertEquals(reply.i18n_domain, '')
01289 
01290     def testHistoryActionID(self):
01291         migrateHistoryTab(self.portal, [])
01292         objects = getattr(self.actions, 'object', None)
01293         self.failIf('rss' in objects.objectIds())
01294 
01295     def testHistoryActionIDTwice(self):
01296         migrateHistoryTab(self.portal, [])
01297         migrateHistoryTab(self.portal, [])
01298         objects = getattr(self.actions, 'object', None)
01299         self.failIf('rss' in objects.objectIds())
01300 
01301 
01302     def testProviderCleanup(self):
01303         self.actions.addActionProvider("portal_membership")
01304         self.failUnless("portal_membership" in self.actions.listActionProviders())
01305         cleanupActionProviders(self.portal, [])
01306         self.failIf("portal_membership" in self.actions.listActionProviders())
01307 
01308 
01309     def testRemovePropertiesActions(self):
01310         ti=self.types.getTypeInfo("Document")
01311         if ti.getActionObject("object/properties") is None:
01312             ti.addAction("metadata", "name", "action", "condition",
01313                     "permission", "object",)
01314         hidePropertiesAction(self.portal, [])
01315         self.failUnless(ti.getActionObject("object/metadata") is None)
01316 
01317 
01318     def beforeTearDown(self):
01319         if len(self.discussion._actions) > 0:
01320             self.discussion._actions = ()
01321 
01322 
01323 class TestMigrations_v3_0(MigrationTest):
01324 
01325     def afterSetUp(self):
01326         self.actions = self.portal.portal_actions
01327         self.cp = self.portal.portal_controlpanel
01328         self.icons = self.portal.portal_actionicons
01329         self.skins = self.portal.portal_skins
01330         self.types = self.portal.portal_types
01331         self.workflow = self.portal.portal_workflow
01332         self.properties = self.portal.portal_properties
01333         self.cp = self.portal.portal_controlpanel
01334 
01335     def disableSite(self, obj, iface=ISite):
01336         # We need our own disableSite method as the CMF portal implements
01337         # ISite directly, so we cannot remove it, like the disableSite method
01338         # in Five.component would have done
01339         from ZPublisher.BeforeTraverse import unregisterBeforeTraverse
01340         from Products.Five.component import HOOK_NAME
01341 
01342         obj = aq_base(obj)
01343         if not iface.providedBy(obj):
01344             raise TypeError('Object must be a site.')
01345 
01346         unregisterBeforeTraverse(obj, HOOK_NAME)
01347         if hasattr(obj, HOOK_NAME):
01348             delattr(obj, HOOK_NAME)
01349 
01350     def testEnableZope3Site(self):
01351         # First we remove the site and site manager
01352         self.disableSite(self.portal)
01353         clearSite(self.portal)
01354         self.portal.setSiteManager(None)
01355 
01356         # Then run the migration step
01357         enableZope3Site(self.portal, [])
01358 
01359         # And see if we have an ISite with a local site manager
01360         self.failUnless(ISite.providedBy(self.portal))
01361         gsm = getGlobalSiteManager()
01362         sm = getSiteManager(self.portal)
01363         self.failIf(gsm is sm)
01364         lc = sm.utilities.LookupClass
01365         self.failUnless(lc == FiveVerifyingAdapterLookup)
01366 
01367         # Test the lookupclass migration
01368         sm.utilities.LookupClass = None
01369 
01370         enableZope3Site(self.portal, [])
01371 
01372         self.failUnless(sm.utilities.LookupClass == FiveVerifyingAdapterLookup)
01373         self.failUnless(sm.utilities.__parent__ == sm)
01374         self.failUnless(sm.__parent__ == self.portal)
01375 
01376     def testEnableZope3SiteTwice(self):
01377         # First we remove the site and site manager
01378         self.disableSite(self.portal)
01379         clearSite(self.portal)
01380         self.portal.setSiteManager(None)
01381 
01382         # Then run the migration step
01383         enableZope3Site(self.portal, [])
01384         enableZope3Site(self.portal, [])
01385 
01386         # And see if we have an ISite with a local site manager
01387         self.failUnless(ISite.providedBy(self.portal))
01388         gsm = getGlobalSiteManager()
01389         sm = getSiteManager(self.portal)
01390         self.failIf(gsm is sm)
01391 
01392         # Test the lookupclass migration
01393         sm.utilities.LookupClass = None
01394 
01395         enableZope3Site(self.portal, [])
01396         enableZope3Site(self.portal, [])
01397 
01398         self.failUnless(sm.utilities.LookupClass == FiveVerifyingAdapterLookup)
01399         self.failUnless(sm.utilities.__parent__ == sm)
01400         self.failUnless(sm.__parent__ == self.portal)
01401 
01402     def testAddNewCSSFiles(self):
01403         cssreg = self.portal.portal_css
01404         added_ids = ['navtree.css', 'invisibles.css', 'forms.css']
01405         for id in added_ids:
01406             cssreg.unregisterResource(id)
01407         stylesheet_ids = cssreg.getResourceIds()
01408         for id in added_ids:
01409             self.failIf('navtree.css' in stylesheet_ids)
01410         addNewCSSFiles(self.portal, [])
01411         stylesheet_ids = cssreg.getResourceIds()
01412         for id in added_ids:
01413             self.failUnless(id in stylesheet_ids)
01414         # perform migration twice
01415         addNewCSSFiles(self.portal, [])
01416         for id in added_ids:
01417             self.failUnless(id in stylesheet_ids)
01418 
01419     def testAddNewBeta2CSSFiles(self):
01420         cssreg = self.portal.portal_css
01421         added_ids = ['controlpanel.css']
01422         for id in added_ids:
01423             cssreg.unregisterResource(id)
01424         stylesheet_ids = cssreg.getResourceIds()
01425         for id in added_ids:
01426             self.failIf('controlpanel.css' in stylesheet_ids)
01427         loadMigrationProfile(self.portal,
01428                 'profile-Products.CMFPlone.migrations:3.0b1-3.0b2',
01429                 steps=["cssregistry"])
01430         stylesheet_ids = cssreg.getResourceIds()
01431         for id in added_ids:
01432             self.failUnless(id in stylesheet_ids)
01433         # perform migration twice
01434         loadMigrationProfile(self.portal,
01435                 'profile-Products.CMFPlone.migrations:3.0b1-3.0b2',
01436                 steps=["cssregistry"])
01437         for id in added_ids:
01438             self.failUnless(id in stylesheet_ids)
01439 
01440     def testAddDefaultAndForbiddenContentTypesProperties(self):
01441         # Should add the forbidden_contenttypes and default_contenttype property
01442         self.removeSiteProperty('forbidden_contenttypes')
01443         self.removeSiteProperty('default_contenttype')
01444         self.failIf(self.properties.site_properties.hasProperty('forbidden_contenttypes'))
01445         self.failIf(self.properties.site_properties.hasProperty('default_contenttype'))
01446         addDefaultAndForbiddenContentTypesProperties(self.portal, [])
01447         self.failUnless(self.properties.site_properties.hasProperty('forbidden_contenttypes'))
01448         self.failUnless(self.properties.site_properties.hasProperty('default_contenttype'))
01449         self.failUnless(self.properties.site_properties.forbidden_contenttypes == ( 
01450             'text/structured',
01451             'text/x-rst',
01452             'text/plain-pre',
01453             'text/x-python',
01454             'text/x-web-markdown',
01455             'text/x-web-textile',
01456             'text/x-web-intelligent')
01457         )
01458 
01459     def testAddDefaultAndForbiddenContentTypesPropertiesTwice(self):
01460         # Should not fail if migrated again
01461         self.removeSiteProperty('forbidden_contenttypes')
01462         self.removeSiteProperty('default_contenttype')
01463         self.failIf(self.properties.site_properties.hasProperty('forbidden_contenttypes'))
01464         self.failIf(self.properties.site_properties.hasProperty('default_contenttype'))
01465         addDefaultAndForbiddenContentTypesProperties(self.portal, [])
01466         self.failUnless(self.properties.site_properties.forbidden_contenttypes == ( 
01467             'text/structured',
01468             'text/x-rst',
01469             'text/plain-pre',
01470             'text/x-python',
01471             'text/x-web-markdown',
01472             'text/x-web-textile',
01473             'text/x-web-intelligent')
01474         )
01475         self.properties.site_properties.forbidden_contenttypes = ('text/x-rst',)
01476         addDefaultAndForbiddenContentTypesProperties(self.portal, [])
01477         self.failUnless(self.properties.site_properties.hasProperty('forbidden_contenttypes'))
01478         self.failUnless(self.properties.site_properties.hasProperty('default_contenttype'))
01479         # adding a second time should leave existing `forbidden_contenttypes` settings alone:
01480         self.failUnless(self.properties.site_properties.forbidden_contenttypes == ( 
01481             'text/x-rst', 
01482             )
01483         )
01484         
01485     def testAddIconForMarkupConfiglet(self):
01486         self.removeActionIconFromTool('MarkupSettings')
01487         addIconForMarkupConfiglet(self.portal, [])
01488         self.failUnless('MarkupSettings' in [x.getActionId() for x in self.icons.listActionIcons()])
01489 
01490     def testAddIconForMarkupConfigletTwice(self):
01491         self.removeActionIconFromTool('MarkupSettings')
01492         addIconForMarkupConfiglet(self.portal, [])
01493         addIconForMarkupConfiglet(self.portal, [])
01494         self.failUnless('MarkupSettings' in [x.getActionId() for x in self.icons.listActionIcons()])
01495 
01496     def testAddIconForMarkupConfigletNoTool(self):
01497         self.portal._delObject('portal_actionicons')
01498         addIconForMarkupConfiglet(self.portal, [])
01499     
01500     def testAddMarkupConfiglet(self):
01501         self.removeActionFromTool('MarkupSettings', action_provider='portal_controlpanel')
01502         addMarkupConfiglet(self.portal, [])
01503         self.failUnless('MarkupSettings' in [action.getId() for action in self.cp.listActions()])
01504         types = self.cp.getActionObject('Plone/MarkupSettings')
01505         self.assertEquals(types.action.text,
01506                           'string:${portal_url}/@@markup-controlpanel')
01507 
01508     def testAddMarkupConfigletTwice(self):
01509         self.removeActionFromTool('MarkupSettings', action_provider='portal_controlpanel')
01510         addMarkupConfiglet(self.portal, [])
01511         addMarkupConfiglet(self.portal, [])
01512         self.failUnless('MarkupSettings' in [action.getId() for action in self.cp.listActions()])
01513         types = self.cp.getActionObject('Plone/MarkupSettings')
01514         self.assertEquals(types.action.text,
01515                           'string:${portal_url}/@@markup-controlpanel')
01516                           
01517     def testAddMarkupConfigletNoTool(self):
01518         self.portal._delObject('portal_controlpanel')
01519         addMarkupConfiglet(self.portal, [])
01520                               
01521     def testAddIconForTypesConfiglet(self):
01522         self.removeActionIconFromTool('TypesSettings')
01523         addIconForTypesConfiglet(self.portal, [])
01524         self.failUnless('TypesSettings' in [x.getActionId() for x in self.icons.listActionIcons()])
01525 
01526     def testAddIconForTypesConfigletTwice(self):
01527         self.removeActionIconFromTool('TypesSettings')
01528         addIconForTypesConfiglet(self.portal, [])
01529         addIconForTypesConfiglet(self.portal, [])
01530         self.failUnless('TypesSettings' in [x.getActionId() for x in self.icons.listActionIcons()])
01531 
01532     def testAddIconForTypesConfigletNoTool(self):
01533         self.portal._delObject('portal_actionicons')
01534         addIconForTypesConfiglet(self.portal, [])      
01535                           
01536     def testAddTypesConfiglet(self):
01537         self.removeActionFromTool('TypesSettings', action_provider='portal_controlpanel')
01538         addTypesConfiglet(self.portal, [])
01539         self.failUnless('TypesSettings' in [action.getId() for action in self.cp.listActions()])
01540         types = self.cp.getActionObject('Plone/TypesSettings')
01541         self.assertEquals(types.action.text,
01542                           'string:${portal_url}/@@types-controlpanel')
01543 
01544     def testAddTypesConfigletTwice(self):
01545         self.removeActionFromTool('TypesSettings', action_provider='portal_controlpanel')
01546         addTypesConfiglet(self.portal, [])
01547         addTypesConfiglet(self.portal, [])
01548         self.failUnless('TypesSettings' in [action.getId() for action in self.cp.listActions()])
01549         types = self.cp.getActionObject('Plone/TypesSettings')
01550         self.assertEquals(types.action.text,
01551                           'string:${portal_url}/@@types-controlpanel')
01552 
01553     def testAddTypesConfigletNoTool(self):
01554         self.portal._delObject('portal_controlpanel')
01555         addTypesConfiglet(self.portal, [])
01556 
01557     def testAddFormTabbingJS(self):
01558         jsreg = self.portal.portal_javascripts
01559         # unregister first
01560         jsreg.unregisterResource('form_tabbing.js')
01561         script_ids = jsreg.getResourceIds()
01562         self.failIf('form_tabbing.js' in script_ids)
01563         # migrate and test again
01564         addFormTabbingJS(self.portal, [])
01565         script_ids = jsreg.getResourceIds()
01566         self.failUnless('form_tabbing.js' in script_ids)
01567         # if collapsiblesections.js is available form_tabbing.js
01568         # should be positioned right underneath it
01569         if 'collapsiblesections.js' in script_ids:
01570             posSE = jsreg.getResourcePosition('form_tabbing.js')
01571             posHST = jsreg.getResourcePosition('collapsiblesections.js')
01572             self.failUnless((posSE - 1) == posHST)
01573 
01574     def testAddFormInputLabelJS(self):
01575         jsreg = self.portal.portal_javascripts
01576         # unregister first
01577         jsreg.unregisterResource('input-label.js')
01578         script_ids = jsreg.getResourceIds()
01579         self.failIf('input-label.js' in script_ids)
01580         # migrate and test again
01581         addFormInputLabelJS(self.portal, [])
01582         script_ids = jsreg.getResourceIds()
01583         self.failUnless('input-label.js' in script_ids)
01584 
01585     def testUpdateFTII18NDomain(self):
01586         doc = self.types.Document
01587         doc.i18n_domain = ''
01588         # Update FTI's
01589         updateFTII18NDomain(self.portal, [])
01590         # domain should have been updated
01591         self.assertEquals(doc.i18n_domain, 'plone')
01592 
01593     def testUpdateFTII18NDomainTwice(self):
01594         doc = self.types.Document
01595         doc.i18n_domain = ''
01596         # Update FTI's twice
01597         updateFTII18NDomain(self.portal, [])
01598         updateFTII18NDomain(self.portal, [])
01599         # domain should have been updated
01600         self.assertEquals(doc.i18n_domain, 'plone')
01601 
01602     def testUpdateFTII18NDomainNonAscii(self):
01603         doc = self.types.Document
01604         doc.i18n_domain = ''
01605         doc.title = 'Foo\xc3'
01606         # Update FTI's
01607         updateFTII18NDomain(self.portal, [])
01608         # domain should have been updated
01609         self.assertEquals(doc.i18n_domain, '')
01610 
01611     def testLegacyPortletsConverted(self):
01612         self.setRoles(('Manager',))
01613         leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
01614         rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
01615         
01616         left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
01617         right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
01618         
01619         for k in left:
01620             del left[k]
01621         for k in right:
01622             del right[k]
01623                 
01624         self.portal.left_slots = ['here/portlet_recent/macros/portlet',
01625                                   'here/portlet_news/macros/portlet',
01626                                   'here/portlet_related/macros/portlet']
01627         self.portal.right_slots = ['here/portlet_login/macros/portlet',
01628                                    'here/portlet_languages/macros/portlet']
01629         
01630         convertLegacyPortlets(self.portal, [])
01631         
01632         self.assertEquals(self.portal.left_slots, [])
01633         self.assertEquals(self.portal.right_slots, [])
01634         
01635         lp = left.values()
01636         self.assertEquals(2, len(lp))
01637 
01638         self.failUnless(isinstance(lp[0], portlets.recent.Assignment))
01639         self.failUnless(isinstance(lp[1], portlets.news.Assignment))
01640         
01641         rp = right.values()
01642         self.assertEquals(1, len(rp))
01643         self.failUnless(isinstance(rp[0], portlets.login.Assignment))
01644         
01645         members = self.portal.Members
01646         portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
01647         self.assertEquals(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
01648         
01649     def testLegacyPortletsConvertedTwice(self):
01650         self.setRoles(('Manager',))
01651         leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
01652         rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
01653         
01654         left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
01655         right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
01656         
01657         for k in left:
01658             del left[k]
01659         for k in right:
01660             del right[k]
01661             
01662         self.portal.left_slots = ['here/portlet_recent/macros/portlet',
01663                                   'here/portlet_news/macros/portlet',
01664                                   'here/portlet_related/macros/portlet']
01665         self.portal.right_slots = ['here/portlet_login/macros/portlet',
01666                                    'here/portlet_languages/macros/portlet']
01667         
01668         convertLegacyPortlets(self.portal, [])
01669         convertLegacyPortlets(self.portal, [])
01670         
01671         self.assertEquals(self.portal.left_slots, [])
01672         self.assertEquals(self.portal.right_slots, [])
01673         
01674         lp = left.values()
01675         self.assertEquals(2, len(lp))
01676         
01677         self.failUnless(isinstance(lp[0], portlets.recent.Assignment))
01678         self.failUnless(isinstance(lp[1], portlets.news.Assignment))
01679         
01680         rp = right.values()
01681         self.assertEquals(1, len(rp))
01682         self.failUnless(isinstance(rp[0], portlets.login.Assignment))
01683         
01684         members = self.portal.Members
01685         portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
01686         self.assertEquals(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
01687         
01688     def testLegacyPortletsConvertedNoSlots(self):
01689         self.setRoles(('Manager',))
01690         leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
01691         rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
01692         
01693         left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
01694         right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
01695         
01696         for k in left:
01697             del left[k]
01698         for k in right:
01699             del right[k]
01700             
01701         self.portal.left_slots = ['here/portlet_recent/macros/portlet',
01702                                   'here/portlet_news/macros/portlet']
01703         if hasattr(self.portal.aq_base, 'right_slots'):
01704             delattr(self.portal, 'right_slots')
01705         
01706         convertLegacyPortlets(self.portal, [])
01707         
01708         self.assertEquals(self.portal.left_slots, [])
01709         
01710         lp = left.values()
01711         self.assertEquals(2, len(lp))
01712         
01713         self.failUnless(isinstance(lp[0], portlets.recent.Assignment))
01714         self.failUnless(isinstance(lp[1], portlets.news.Assignment))
01715         
01716         rp = right.values()
01717         self.assertEquals(0, len(rp))
01718         
01719         members = self.portal.Members
01720         portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
01721         self.assertEquals(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
01722         
01723     def testLegacyPortletsConvertedBadSlots(self):
01724         self.setRoles(('Manager',))
01725         leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
01726         rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
01727         
01728         left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
01729         right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
01730         
01731         for k in left:
01732             del left[k]
01733         for k in right:
01734             del right[k]
01735         
01736         self.portal.left_slots = ['here/portlet_recent/macros/portlet',
01737                                   'here/portlet_news/macros/portlet',
01738                                   'foobar',]
01739         self.portal.right_slots = ['here/portlet_login/macros/portlet']
01740         
01741         convertLegacyPortlets(self.portal, [])
01742         
01743         self.assertEquals(self.portal.left_slots, [])
01744         self.assertEquals(self.portal.right_slots, [])
01745         
01746         lp = left.values()
01747         self.assertEquals(2, len(lp))
01748 
01749         self.failUnless(isinstance(lp[0], portlets.recent.Assignment))
01750         self.failUnless(isinstance(lp[1], portlets.news.Assignment))
01751         
01752         rp = right.values()
01753         self.assertEquals(1, len(rp))
01754         self.failUnless(isinstance(rp[0], portlets.login.Assignment))
01755         
01756         members = self.portal.Members
01757         portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
01758         self.assertEquals(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
01759         
01760     def testLegacyPortletsConvertedNoMembersFolder(self):
01761         self.setRoles(('Manager',))
01762         leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
01763         rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
01764         
01765         left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
01766         right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
01767         
01768         for k in left:
01769             del left[k]
01770         for k in right:
01771             del right[k]
01772         
01773         self.portal.left_slots = ['here/portlet_recent/macros/portlet',
01774                                   'here/portlet_news/macros/portlet',
01775                                   'foobar',]
01776         self.portal.right_slots = ['here/portlet_login/macros/portlet']
01777         
01778         
01779         self.portal._delObject('Members')
01780         
01781         convertLegacyPortlets(self.portal, [])
01782         
01783         self.assertEquals(self.portal.left_slots, [])
01784         self.assertEquals(self.portal.right_slots, [])
01785         
01786         lp = left.values()
01787         self.assertEquals(2, len(lp))
01788         
01789         self.failUnless(isinstance(lp[0], portlets.recent.Assignment))
01790         self.failUnless(isinstance(lp[1], portlets.news.Assignment))
01791         
01792         rp = right.values()
01793         self.assertEquals(1, len(rp))
01794         self.failUnless(isinstance(rp[0], portlets.login.Assignment))
01795 
01796     def testAddIconForCalendarSettingsConfiglet(self):
01797         # Should add the calendar action icon
01798         self.removeActionIconFromTool('CalendarSettings')
01799         addIconForCalendarSettingsConfiglet(self.portal, [])
01800         self.failUnless('CalendarSettings' in [x.getActionId() for x in self.icons.listActionIcons()])
01801 
01802     def testAddIconForCalendarSettingsConfigletTwice(self):
01803         # Should not fail if migrated again
01804         self.removeActionIconFromTool('CalendarSettings')
01805         addIconForCalendarSettingsConfiglet(self.portal, [])
01806         addIconForCalendarSettingsConfiglet(self.portal, [])
01807         self.failUnless('CalendarSettings' in [x.getActionId() for x in self.icons.listActionIcons()])
01808 
01809     def testAddIconForCalendarSettingsConfigletNoTool(self):
01810         # Should not fail if portal_actionicons is missing
01811         self.portal._delObject('portal_actionicons')
01812         addIconForCalendarSettingsConfiglet(self.portal, [])
01813 
01814     def testAddCalendarConfiglet(self):
01815         self.removeActionFromTool('CalendarSettings', action_provider='portal_controlpanel')
01816         addCalendarConfiglet(self.portal, [])
01817         self.failUnless('CalendarSettings' in [x.getId() for x in self.cp.listActions()])
01818         cal = self.cp.getActionObject('Plone/CalendarSettings')
01819         self.assertEquals(cal.title, 'Calendar')
01820         self.assertEquals(cal.action.text,
01821                           'string:${portal_url}/@@calendar-controlpanel')
01822     
01823     def testAddCalendarConfigletTwice(self):
01824         # Should not fail if done twice
01825         self.removeActionFromTool('CalendarSettings', action_provider='portal_controlpanel')
01826         addCalendarConfiglet(self.portal, [])
01827         addCalendarConfiglet(self.portal, [])
01828         self.failUnless('CalendarSettings' in [x.getId() for x in self.cp.listActions()])
01829         cal = self.cp.getActionObject('Plone/CalendarSettings')
01830         self.assertEquals(cal.title, 'Calendar')
01831         self.assertEquals(cal.action.text,
01832                           'string:${portal_url}/@@calendar-controlpanel')
01833     
01834     def testAddCalendarConfigletNoTool(self):
01835         # Should not fail if tool is missing
01836         self.portal._delObject('portal_controlpanel')
01837         addCalendarConfiglet(self.portal, [])
01838 
01839     def testUpdateSearchAndMailHostConfiglet(self):
01840         search = self.cp.getActionObject('Plone/SearchSettings')
01841         mail = self.cp.getActionObject('Plone/MailHost')
01842         search.action = Expression('string:search')
01843         mail.action = Expression('string:mail')
01844         updateSearchAndMailHostConfiglet(self.portal, [])
01845         self.assertEquals(search.title, 'Search')
01846         self.assertEquals(search.action.text,
01847                           'string:${portal_url}/@@search-controlpanel')
01848         self.assertEquals(mail.title, 'Mail')
01849         self.assertEquals(mail.action.text,
01850                           'string:${portal_url}/@@mail-controlpanel')
01851     
01852     def testUpdateSearchAndMailHostConfigletTwice(self):
01853         # Should not fail if done twice
01854         search = self.cp.getActionObject('Plone/SearchSettings')
01855         mail = self.cp.getActionObject('Plone/MailHost')
01856         search.action = Expression('string:search')
01857         mail.action = Expression('string:mail')
01858         updateSearchAndMailHostConfiglet(self.portal, [])
01859         updateSearchAndMailHostConfiglet(self.portal, [])
01860         self.assertEquals(search.title, 'Search')
01861         self.assertEquals(search.action.text,
01862                           'string:${portal_url}/@@search-controlpanel')
01863         self.assertEquals(mail.title, 'Mail')
01864         self.assertEquals(mail.action.text,
01865                           'string:${portal_url}/@@mail-controlpanel')
01866     
01867     def testUpdateSearchAndMailHostConfigletNoTool(self):
01868         # Should not fail if tool is missing
01869         self.portal._delObject('portal_controlpanel')
01870         updateSearchAndMailHostConfiglet(self.portal, [])
01871 
01872     def testRegisterToolsAsUtilities(self):
01873         sm = getSiteManager(self.portal)
01874         interfaces = (ISiteRoot, IPloneSiteRoot, IInterfaceTool,
01875                       IMigrationTool, IActionIconsTool, ISyndicationTool,
01876                       IMetadataTool, IPropertiesTool, IUndoTool, IMailHost,
01877                       IUniqueIdAnnotationManagement, IUniqueIdGenerator,
01878                       IDiffTool, IATCTTool, IMimetypesRegistryTool,
01879                       IPortalTransformsTool, IDiscussionTool, )
01880         for i in interfaces:
01881             sm.unregisterUtility(provided=i)
01882         registerToolsAsUtilities(self.portal, [])
01883         for i in interfaces:
01884             self.failIf(sm.queryUtility(i) is None)
01885 
01886         for i in interfaces:
01887             sm.unregisterUtility(provided=i)
01888         registerToolsAsUtilities(self.portal, [])
01889         registerToolsAsUtilities(self.portal, [])
01890         for i in interfaces:
01891             self.failIf(sm.queryUtility(i) is None)
01892 
01893     def testDontRegisterToolsAsUtilities(self):
01894         sm = getSiteManager(self.portal)
01895         interfaces = (ILanguageTool, IArchivistTool, IPortalModifierTool,
01896                       IPurgePolicyTool, IRepositoryTool, IStorageTool,
01897                       IFormControllerTool, IReferenceCatalog, IUIDCatalog,
01898                       ICalendarTool, IActionsTool, ICatalogTool,
01899                       IContentTypeRegistry, ISkinsTool, ITypesTool, IURLTool,
01900                       IConfigurableWorkflowTool, IPloneTool, ICSSRegistry,
01901                       IJSRegistry, IUniqueIdHandler, IFactoryTool,
01902                       IMembershipTool, IGroupTool, IGroupDataTool,
01903                       IMemberDataTool, IArchetypeTool, ICachingPolicyManager,
01904                       IRegistrationTool, ITranslationServiceTool,
01905                       IControlPanel, ISetupTool, IQuickInstallerTool,
01906                      )
01907         for i in interfaces:
01908             sm.unregisterUtility(provided=i)
01909         registerToolsAsUtilities(self.portal, [])
01910         for i in interfaces:
01911             self.failUnless(sm.queryUtility(i) is None)
01912 
01913         for i in interfaces:
01914             sm.unregisterUtility(provided=i)
01915         registerToolsAsUtilities(self.portal, [])
01916         registerToolsAsUtilities(self.portal, [])
01917         for i in interfaces:
01918             self.failUnless(sm.queryUtility(i) is None)
01919     
01920     def testInstallKss(self, unregister=True):
01921         'Test kss migration'
01922         jstool = self.portal.portal_javascripts
01923         csstool = self.portal.portal_css
01924         mt = self.portal.mimetypes_registry
01925         mtid = 'text/kss'
01926         st = self.portal.portal_skins
01927         skins = ['Plone Default']
01928         if unregister:
01929             # unregister first
01930             for id, _compression, _enabled in installKss.js_all:
01931                 jstool.unregisterResource(id)
01932             for id in installKss.css_all + installKss.kss_all:
01933                 csstool.unregisterResource(id)
01934             mt.manage_delObjects((mtid, ))
01935             js_ids = jstool.getResourceIds()
01936             for id, _compression, _enabled in installKss.js_all:
01937                 self.failIf(id in js_ids)
01938             css_ids = csstool.getResourceIds()
01939             for id in installKss.css_all + installKss.kss_all:
01940                 self.failIf(id in css_ids)
01941             self.failIf(mtid in mt.list_mimetypes())
01942             selections = st._getSelections()
01943             for s in skins:
01944                 if not selections.has_key(s):
01945                     continue
01946                 path = st.getSkinPath(s)
01947                 path = [p.strip() for p in  path.split(',')]
01948                 path_changed = False
01949                 if 'plone.kss' in path:
01950                     path.remove('plone.kss')
01951                     path_changed = True
01952                 if 'at.kss' in path:
01953                     path.remove('at.kss')
01954                     path_changed = True
01955                 if path_changed:
01956                     st.addSkinSelection(s, ','.join(path))
01957             # XXX we cannot remove the directory views, so...
01958         # migrate and test again
01959         installKss(self.portal, [])
01960         js_ids = jstool.getResourceIds()
01961         css_dict = csstool.getResourcesDict()
01962         for id in installKss.js_unregister:
01963             self.failIf(id in js_ids)
01964         for id, _compression, _enabled in installKss.js_all:
01965             self.assert_(id in js_ids, '%r is not registered' % id)
01966         for id in installKss.css_all:
01967             self.assert_(id in css_dict)
01968         for id in installKss.kss_all:
01969             self.assert_(id in css_dict)
01970             value = css_dict[id]
01971             self.assertEqual(value.getEnabled(), True)
01972             self.assertEqual(value.getRel(), 'k-stylesheet')
01973             self.assertEqual(value.getRendering(), 'link')
01974         self.assert_(mtid in mt.list_mimetypes())
01975         # check the skins
01976         selections = st._getSelections()
01977         for s in skins:
01978             if not selections.has_key(s):
01979                continue
01980             path = st.getSkinPath(s)
01981             path = [p.strip() for p in  path.split(',')]
01982             self.assert_('plone_kss' in path)
01983             self.assert_('archetypes_kss' in path)
01984         self.assert_(hasattr(aq_base(st), 'plone_kss'))
01985         self.assert_(hasattr(aq_base(st), 'archetypes_kss'))
01986 
01987     def testInstallKssTwice(self):
01988         'Test kss migration, twice'
01989         self.testInstallKss()
01990         self.testInstallKss(unregister=False)
01991         
01992     def testInstallRedirectorUtility(self):
01993         sm = getSiteManager(self.portal)
01994         sm.unregisterUtility(provided=IRedirectionStorage)
01995         installRedirectorUtility(self.portal, [])
01996         self.failIf(sm.queryUtility(IRedirectionStorage) is None)
01997 
01998     def testInstallRedirectorUtilityTwice(self):
01999         sm = getSiteManager(self.portal)
02000         sm.unregisterUtility(provided=IRedirectionStorage)
02001         installRedirectorUtility(self.portal, [])
02002         installRedirectorUtility(self.portal, [])
02003         self.failIf(sm.queryUtility(IRedirectionStorage) is None)
02004         
02005     def testAddContentRulesAction(self):
02006         self.portal.portal_actions.object._delObject('contentrules')
02007         addContentRulesAction(self.portal, [])
02008         self.failUnless('contentrules' in self.portal.portal_actions.object.objectIds())
02009         
02010     def testAddContentRulesActionTwice(self):
02011         self.portal.portal_actions.object._delOb('contentrules')
02012         addContentRulesAction(self.portal, [])
02013         addContentRulesAction(self.portal, [])
02014         self.failUnless('contentrules' in self.portal.portal_actions.object.objectIds())
02015         
02016     def testAddContentRulesActionNoTool(self):
02017         self.portal._delOb('portal_actions')
02018         addContentRulesAction(self.portal, [])
02019         
02020     def testAddContentRulesActionNoCategory(self):
02021         self.portal.portal_actions._delOb('object')
02022         addContentRulesAction(self.portal, [])
02023         
02024     def testAddReaderEditorRoles(self):
02025         self.portal._delRoles(['Reader', 'Editor'])
02026         addReaderAndEditorRoles(self.portal, [])
02027         self.failUnless('Reader' in self.portal.valid_roles())
02028         self.failUnless('Editor' in self.portal.valid_roles())
02029         self.failUnless('Reader' in self.portal.acl_users.portal_role_manager.listRoleIds())
02030         self.failUnless('Editor' in self.portal.acl_users.portal_role_manager.listRoleIds())
02031         self.failUnless('View' in [r['name'] for r in self.portal.permissionsOfRole('Reader') if r['selected']])
02032         self.failUnless('Modify portal content' in [r['name'] for r in self.portal.permissionsOfRole('Editor') if r['selected']])
02033         
02034     def testAddReaderEditorRolesPermissionOnly(self):
02035         self.portal.manage_permission('View', [], True)
02036         self.portal.manage_permission('Modify portal content', [], True)
02037         addReaderAndEditorRoles(self.portal, [])
02038         self.failUnless('Reader' in self.portal.valid_roles())
02039         self.failUnless('Editor' in self.portal.valid_roles())
02040         self.failUnless('Reader' in self.portal.acl_users.portal_role_manager.listRoleIds())
02041         self.failUnless('Editor' in self.portal.acl_users.portal_role_manager.listRoleIds())
02042         self.failUnless('View' in [r['name'] for r in self.portal.permissionsOfRole('Reader') if r['selected']])
02043         self.failUnless('Modify portal content' in [r['name'] for r in self.portal.permissionsOfRole('Editor') if r['selected']])
02044         
02045     def testAddReaderEditorRolesTwice(self):
02046         self.portal._delRoles(['Reader', 'Editor'])
02047         addReaderAndEditorRoles(self.portal, [])
02048         addReaderAndEditorRoles(self.portal, [])
02049         self.failUnless('Reader' in self.portal.valid_roles())
02050         self.failUnless('Editor' in self.portal.valid_roles())
02051         self.failUnless('Reader' in self.portal.acl_users.portal_role_manager.listRoleIds())
02052         self.failUnless('Editor' in self.portal.acl_users.portal_role_manager.listRoleIds())
02053         self.failUnless('View' in [r['name'] for r in self.portal.permissionsOfRole('Reader') if r['selected']])
02054         self.failUnless('Modify portal content' in [r['name'] for r in self.portal.permissionsOfRole('Editor') if r['selected']])
02055 
02056     def testMigrateLocalroleForm(self):
02057         fti = self.portal.portal_types['Document']
02058         aliases = fti.getMethodAliases()
02059         aliases['sharing'] = 'folder_localrole_form'
02060         fti.setMethodAliases(aliases)
02061         fti.addAction('test', 'Test', 'string:${object_url}/folder_localrole_form', None, 'View', 'object')
02062         migrateLocalroleForm(self.portal, [])
02063         self.assertEquals('@@sharing', fti.getMethodAliases()['sharing'])
02064         test_action = fti.listActions()[-1]
02065         self.assertEquals('string:${object_url}/@@sharing', test_action.getActionExpression())
02066 
02067     def testMigrateLocalroleFormTwice(self):
02068         fti = self.portal.portal_types['Document']
02069         aliases = fti.getMethodAliases()
02070         aliases['sharing'] = 'folder_localrole_form'
02071         fti.setMethodAliases(aliases)
02072         fti.addAction('test', 'Test', 'string:${object_url}/folder_localrole_form', None, 'View', 'object')
02073         migrateLocalroleForm(self.portal, [])
02074         migrateLocalroleForm(self.portal, [])
02075         self.assertEquals('@@sharing', fti.getMethodAliases()['sharing'])
02076         test_action = fti.listActions()[-1]
02077         self.assertEquals('string:${object_url}/@@sharing', test_action.getActionExpression())
02078         
02079     def testMigrateLocalroleFormNoTool(self):
02080         self.portal._delObject('portal_types')
02081         migrateLocalroleForm(self.portal, [])
02082 
02083     def testReorderUserActions(self):
02084         self.actions.user.moveObjectsToTop(['logout', 'undo', 'join'])
02085         reorderUserActions(self.portal, [])
02086         # build a dict that has the position as the value to make it easier to
02087         # compare postions in the ordered list of actions
02088         n = 0
02089         sort = {}
02090         for action in self.actions.user.objectIds():
02091             sort[action] = n
02092             n += 1
02093         self.failUnless(sort['preferences'] < sort['undo'])
02094         self.failUnless(sort['undo'] < sort['logout'])
02095         self.failUnless(sort['login'] < sort['join'])
02096 
02097     def testReorderUserActionsTwice(self):
02098         self.actions.user.moveObjectsToTop(['logout', 'undo', 'join'])
02099         reorderUserActions(self.portal, [])
02100         reorderUserActions(self.portal, [])
02101         # build a dict that has the position as the value to make it easier to
02102         # compare postions in the ordered list of actions
02103         n = 0
02104         sort = {}
02105         for action in self.actions.user.objectIds():
02106             sort[action] = n
02107             n += 1
02108         self.failUnless(sort['preferences'] < sort['undo'])
02109         self.failUnless(sort['undo'] < sort['logout'])
02110         self.failUnless(sort['login'] < sort['join'])
02111 
02112     def testReorderUserActionsNoTool(self):
02113         self.portal._delObject('portal_actions')
02114         reorderUserActions(self.portal, [])
02115 
02116     def testReorderUserActionsIncompleteActions(self):
02117         self.actions.user.moveObjectsToTop(['logout', 'undo', 'join'])
02118         self.actions.user._delObject('preferences')
02119         reorderUserActions(self.portal, [])
02120         # build a dict that has the position as the value to make it easier to
02121         # compare postions in the ordered list of actions
02122         n = 0
02123         sort = {}
02124         for action in self.actions.user.objectIds():
02125             sort[action] = n
02126             n += 1
02127         self.failUnless(sort['undo'] < sort['logout'])
02128         self.failUnless(sort['login'] < sort['join'])
02129 
02130     def testUpdateRtlCSSexpression(self):
02131         cssreg = self.portal.portal_css
02132         rtl = cssreg.getResource('RTL.css')
02133         rtl.setExpression('string:foo')
02134         updateRtlCSSexpression(self.portal, [])
02135         expr = rtl.getExpression()
02136         self.failUnless(expr == "python:portal.restrictedTraverse('@@plone_portal_state').is_rtl()")
02137 
02138     def testUpdateRtlCSSexpressionTwice(self):
02139         # perform migration twice
02140         cssreg = self.portal.portal_css
02141         rtl = cssreg.getResource('RTL.css')
02142         rtl.setExpression('string:foo')
02143         updateRtlCSSexpression(self.portal, [])
02144         updateRtlCSSexpression(self.portal, [])
02145         expr = rtl.getExpression()
02146         self.failUnless(expr == "python:portal.restrictedTraverse('@@plone_portal_state').is_rtl()")
02147 
02148     def testAddMaintenanceConfiglet(self):
02149         self.removeActionFromTool('Maintenance', action_provider='portal_controlpanel')
02150         addMaintenanceConfiglet(self.portal, [])
02151         self.failUnless('Maintenance' in [x.getId() for x in self.cp.listActions()])
02152         main = self.cp.getActionObject('Plone/Maintenance')
02153         self.assertEquals(main.title, 'Maintenance')
02154         self.assertEquals(main.action.text,
02155                           'string:${portal_url}/@@maintenance-controlpanel')
02156 
02157     def testAddMaintenanceConfigletTwice(self):
02158         self.removeActionFromTool('Maintenance', action_provider='portal_controlpanel')
02159         addMaintenanceConfiglet(self.portal, [])
02160         addMaintenanceConfiglet(self.portal, [])
02161         self.failUnless('Maintenance' in [x.getId() for x in self.cp.listActions()])
02162         main = self.cp.getActionObject('Plone/Maintenance')
02163         self.assertEquals(main.title, 'Maintenance')
02164         self.assertEquals(main.action.text,
02165                           'string:${portal_url}/@@maintenance-controlpanel')
02166 
02167     def testAddIconForMaintenanceConfiglet(self):
02168         # Should add the maintenance action icon
02169         self.removeActionIconFromTool('Maintenance')
02170         addIconForCalendarSettingsConfiglet(self.portal, [])
02171         self.failUnless('Maintenance' in [x.getActionId() for x in self.icons.listActionIcons()])
02172 
02173     def testAddIconForMaintenanceConfigletTwice(self):
02174         # Should add the maintenance action icon
02175         self.removeActionIconFromTool('Maintenance')
02176         addIconForCalendarSettingsConfiglet(self.portal, [])
02177         addIconForCalendarSettingsConfiglet(self.portal, [])
02178         self.failUnless('Maintenance' in [x.getActionId() for x in self.icons.listActionIcons()])
02179 
02180     def testAddMaintenanceProperty(self):
02181         # adds a site property to portal_properties
02182         self.removeSiteProperty('number_of_days_to_keep')
02183         addMaintenanceProperty(self.portal, [])
02184         tool = self.portal.portal_properties
02185         sheet = tool.site_properties
02186         self.failUnless(sheet.hasProperty('number_of_days_to_keep'))
02187     
02188     def testAddLinkIntegritySwitch(self):
02189         # adds a site property to portal_properties
02190         self.removeSiteProperty('enable_link_integrity_checks')
02191         addLinkIntegritySwitch(self.portal, [])
02192         tool = self.portal.portal_properties
02193         sheet = tool.site_properties
02194         self.failUnless(sheet.hasProperty('enable_link_integrity_checks'))
02195     
02196     def testAddInlineEditingSwitch(self):
02197         # adds a site property to portal_properties
02198         self.removeSiteProperty('enable_inline_editing')
02199         loadMigrationProfile(self.portal,
02200                 'profile-Products.CMFPlone.migrations:3.1.3-3.1.4',
02201                 steps=["propertiestool"])
02202         tool = self.portal.portal_properties
02203         sheet = tool.site_properties
02204         self.failUnless(sheet.hasProperty('enable_inline_editing'))
02205     
02206     def testAddTableContents(self):
02207         css = self.portal.portal_css
02208         js = self.portal.portal_javascripts
02209         css.manage_removeStylesheet("toc.css")
02210         js.manage_removeScript("toc.js")
02211         addTableContents(self.portal, [])
02212         self.failUnless("toc.js" in js.getResourceIds())
02213         self.failUnless("toc.css" in css.getResourceIds())
02214         addTableContents(self.portal, [])
02215         self.failUnless("toc.js" in js.getResourceIds())
02216         self.failUnless("toc.css" in css.getResourceIds())
02217         
02218     def testUpdateMemberSecurity(self):
02219         pprop = getToolByName(self.portal, 'portal_properties')
02220         self.assertEquals(
02221                 pprop.site_properties.getProperty('allowAnonymousViewAbout'),
02222                 False)
02223 
02224         pmembership = getToolByName(self.portal, 'portal_membership')
02225         self.assertEquals(pmembership.memberareaCreationFlag, False)
02226 
02227         self.assertEquals(self.portal.getProperty('validate_email'), True)
02228 
02229         app_roles = self.portal.rolesOfPermission(permission='Add portal member')
02230         app_perms = self.portal.permission_settings(permission='Add portal member')
02231         acquire_check = app_perms[0]['acquire']
02232         reg_roles = []
02233         for appperm in app_roles:
02234             if appperm['selected'] == 'SELECTED':
02235                 reg_roles.append(appperm['name'])
02236         self.failUnless('Manager' in reg_roles)
02237         self.failUnless('Owner' in reg_roles)
02238         self.failUnless(acquire_check == '')
02239 
02240 
02241     def testPloneS5(self):
02242         pa = self.portal.portal_actions
02243         self.removeActionIconFromTool('s5_presentation')
02244         self.removeActionFromTool('s5_presentation', action_provider='portal_actions')
02245         installS5(self.portal, [])
02246         
02247         self.folder.invokeFactory('Document', id="test_document")
02248         doc_ids = self.portal.portal_actions.listFilteredActionsFor(self.folder.test_document)["document_actions"]
02249         assert "s5_presentation" not in [ i["id"] for i in doc_ids ]
02250         
02251         self.folder.invokeFactory('News Item', id="test_news_item")
02252         ni_ids = self.portal.portal_actions.listFilteredActionsFor(self.folder.test_news_item)["document_actions"]
02253         assert "s5_presentation" not in [ i["id"] for i in ni_ids ]
02254         
02255         # add in something to the document
02256         self.folder.test_document.setPresentation(True)
02257         self.folder.test_document.setText("<h1>Test</h1><p>foo</p>")
02258         
02259         # now it should appear
02260         doc_ids = self.portal.portal_actions.listFilteredActionsFor(self.folder.test_document)["document_actions"]
02261         assert "s5_presentation" in [ i["id"] for i in doc_ids ]
02262         
02263         # and install again
02264         self.failUnless('s5_presentation' in [x.getActionId() for x in self.icons.listActionIcons()])
02265         installS5(self.portal, [])
02266         self.failUnless('s5_presentation' in [x.getActionId() for x in self.icons.listActionIcons()])
02267 
02268 
02269     def testPASPluginInterfaces(self):
02270         pas = self.portal.acl_users
02271         from Products.PluggableAuthService.interfaces.plugins import IUserEnumerationPlugin
02272         pas.plugins.deactivatePlugin(IUserEnumerationPlugin, 'mutable_properties')
02273         updatePASPlugins(self.portal, [])
02274 
02275         plugin = pas.mutable_properties
02276         for intf_id in plugin.listInterfaces():
02277             try:
02278                 intf = pas.plugins._getInterfaceFromName(intf_id)
02279                 self.failUnless('mutable_properties' in pas.plugins.listPluginIds(intf))
02280             except KeyError:
02281                 # Ignore unregistered interface types 
02282                 pass
02283 
02284     def testInstallContentrulesUtility(self):
02285         sm = getSiteManager(self.portal)
02286         sm.unregisterUtility(provided=IRuleStorage)
02287         installContentRulesUtility(self.portal, [])
02288         installContentRulesUtility(self.portal, [])
02289         self.failIf(sm.queryUtility(IRuleStorage) is None)
02290 
02291     def testContentRulesConfiglet(self):
02292         pc = self.portal.portal_controlpanel
02293         self.removeActionIconFromTool('ContentRules')
02294         self.removeActionFromTool('ContentRules', action_provider='portal_controlpanel')
02295         addIconForContentRulesConfiglet(self.portal, [])
02296         addContentRulesConfiglet(self.portal, [])
02297         self.failUnless('ContentRules' in [x.getActionId() for x in self.icons.listActionIcons()])
02298         self.failUnless('ContentRules' in [x.getId() for x in pc.listActions()])
02299 
02300 
02301     def testUpdateSkinsAndSiteConfiglet(self):
02302         skins = self.cp.getActionObject('Plone/PortalSkin')
02303         site = self.cp.getActionObject('Plone/PloneReconfig')
02304         skins.action = Expression('string:skins')
02305         site.action = Expression('string:site')
02306         updateSkinsAndSiteConfiglet(self.portal, [])
02307         self.assertEquals(skins.title, 'Themes')
02308         self.assertEquals(skins.action.text,
02309                           'string:${portal_url}/@@skins-controlpanel')
02310         self.assertEquals(site.title, 'Site settings')
02311         self.assertEquals(site.action.text,
02312                           'string:${portal_url}/@@site-controlpanel')
02313     
02314     def testUpdateSkinsAndSiteConfigletTwice(self):
02315         # Should not fail if done twice
02316         skins = self.cp.getActionObject('Plone/PortalSkin')
02317         site = self.cp.getActionObject('Plone/PloneReconfig')
02318         skins.action = Expression('string:skins')
02319         site.action = Expression('string:site')
02320         updateSkinsAndSiteConfiglet(self.portal, [])
02321         updateSkinsAndSiteConfiglet(self.portal, [])
02322         self.assertEquals(skins.title, 'Themes')
02323         self.assertEquals(skins.action.text,
02324                           'string:${portal_url}/@@skins-controlpanel')
02325         self.assertEquals(site.title, 'Site settings')
02326         self.assertEquals(site.action.text,
02327                           'string:${portal_url}/@@site-controlpanel')
02328 
02329     def testUpdateSkinsAndSiteConfigletNoTool(self):
02330         # Should not fail if tool is missing
02331         self.portal._delObject('portal_controlpanel')
02332         updateSkinsAndSiteConfiglet(self.portal, [])
02333 
02334     def testUpdateConfigletTitles(self):
02335         collection = self.cp.getActionObject('Plone/portal_atct')
02336         language = self.cp.getActionObject('Plone/PloneLanguageTool')
02337         navigation = self.cp.getActionObject('Plone/NavigationSettings')
02338         types = self.cp.getActionObject('Plone/TypesSettings')
02339         users = self.cp.getActionObject('Plone/UsersGroups')
02340         users2 = self.cp.getActionObject('Plone/UsersGroups2')
02341         updateConfigletTitles(self.portal, [])
02342         self.assertEquals(collection.title, 'Collection')
02343         self.assertEquals(language.title, 'Language')
02344         self.assertEquals(navigation.title, 'Navigation')
02345         self.assertEquals(types.title, 'Types')
02346         self.assertEquals(users.title, 'Users and Groups')
02347         self.assertEquals(users2.title, 'Users and Groups')
02348 
02349     def testUpdateConfigletTitlesTwice(self):
02350         collection = self.cp.getActionObject('Plone/portal_atct')
02351         language = self.cp.getActionObject('Plone/PloneLanguageTool')
02352         navigation = self.cp.getActionObject('Plone/NavigationSettings')
02353         types = self.cp.getActionObject('Plone/TypesSettings')
02354         users = self.cp.getActionObject('Plone/UsersGroups')
02355         users2 = self.cp.getActionObject('Plone/UsersGroups2')
02356         updateConfigletTitles(self.portal, [])
02357         updateConfigletTitles(self.portal, [])
02358         self.assertEquals(collection.title, 'Collection')
02359         self.assertEquals(language.title, 'Language')
02360         self.assertEquals(navigation.title, 'Navigation')
02361         self.assertEquals(types.title, 'Types')
02362         self.assertEquals(users.title, 'Users and Groups')
02363         self.assertEquals(users2.title, 'Users and Groups')
02364 
02365     def testUpdateConfigletTitlesNoTool(self):
02366         # Should not fail if tool is missing
02367         self.portal._delObject('portal_controlpanel')
02368         updateConfigletTitles(self.portal, [])
02369 
02370     def testaddIconsForFilterAndSecurityConfigletsNoTool(self):
02371         # Should not fail if portal_actionicons is missing
02372         self.portal._delObject('portal_actionicons')
02373         addIconsForFilterAndSecurityConfiglets(self.portal, [])
02374 
02375     def testAddFilterAndSecurityConfiglets(self):
02376         self.removeActionFromTool('HtmlFilter', action_provider='portal_controlpanel')
02377         self.removeActionFromTool('SecuritySettings', action_provider='portal_controlpanel')
02378         addFilterAndSecurityConfiglets(self.portal, [])
02379         self.failUnless('HtmlFilter' in [x.getId() for x in self.cp.listActions()])
02380         self.failUnless('SecuritySettings' in [x.getId() for x in self.cp.listActions()])
02381         htmlfilter = self.cp.getActionObject('Plone/HtmlFilter')
02382         self.assertEquals(htmlfilter.title, 'HTML Filtering')
02383         self.assertEquals(htmlfilter.action.text,
02384                           'string:${portal_url}/@@filter-controlpanel')
02385         security = self.cp.getActionObject('Plone/SecuritySettings')
02386         self.assertEquals(security.title, 'Security')
02387         self.assertEquals(security.action.text,
02388                           'string:${portal_url}/@@security-controlpanel')
02389 
02390     def testAddFilterAndSecurityConfigletsTwice(self):
02391         # Should not fail if done twice
02392         self.removeActionFromTool('HtmlFilter', action_provider='portal_controlpanel')
02393         self.removeActionFromTool('SecuritySettings', action_provider='portal_controlpanel')
02394         addFilterAndSecurityConfiglets(self.portal, [])
02395         addFilterAndSecurityConfiglets(self.portal, [])
02396         self.failUnless('HtmlFilter' in [x.getId() for x in self.cp.listActions()])
02397         self.failUnless('SecuritySettings' in [x.getId() for x in self.cp.listActions()])
02398         htmlfilter = self.cp.getActionObject('Plone/HtmlFilter')
02399         self.assertEquals(htmlfilter.title, 'HTML Filtering')
02400         self.assertEquals(htmlfilter.action.text,
02401                           'string:${portal_url}/@@filter-controlpanel')
02402         security = self.cp.getActionObject('Plone/SecuritySettings')
02403         self.assertEquals(security.title, 'Security')
02404         self.assertEquals(security.action.text,
02405                           'string:${portal_url}/@@security-controlpanel')
02406 
02407     def testAddFilterAndSecurityConfigletsNoTool(self):
02408         # Should not fail if tool is missing
02409         self.portal._delObject('portal_controlpanel')
02410         addFilterAndSecurityConfiglets(self.portal, [])
02411 
02412     def testAddSitemapProperty(self):
02413         self.removeSiteProperty('enable_sitemap')
02414         addSitemapProperty(self.portal, [])
02415         tool = self.portal.portal_properties
02416         sheet = tool.site_properties
02417         self.failUnless(sheet.hasProperty('enable_sitemap'))
02418 
02419     def testUpdateKukitJS(self):
02420         jsreg = self.portal.portal_javascripts
02421         # put into old state first
02422         jsreg.unregisterResource('++resource++kukit.js')
02423         jsreg.unregisterResource('++resource++kukit-devel.js')
02424         script_ids = jsreg.getResourceIds()
02425         self.failIf('++resource++kukit.js' in script_ids)
02426         self.failIf('++resource++kukit-devel.js' in script_ids)
02427         self.failIf('++resource++kukit-src.js' in script_ids)
02428         jsreg.registerScript('++resource++kukit.js', compression="none")
02429         script_ids = jsreg.getResourceIds()
02430         self.failUnless('++resource++kukit.js' in script_ids)
02431         # migrate and test again
02432         updateKukitJS(self.portal, [])
02433         script_ids = jsreg.getResourceIds()
02434         self.failUnless('++resource++kukit-src.js' in script_ids)
02435         resource = jsreg.getResource('++resource++kukit-src.js')
02436         self.failUnless(resource.getCompression() == 'full')
02437         # Run the last migration and check that everything is in its
02438         # place. We must have both the devel and production resources.
02439         # They both should be uncompressed since kss compresses them
02440         # directly. Also they should have conditions that switches them.
02441         beta3_rc1(self.portal)
02442         script_ids = jsreg.getResourceIds()
02443         self.failIf('++resource++kukit-src.js' in script_ids)
02444         resource1 = jsreg.getResource('++resource++kukit.js')
02445         resource2 = jsreg.getResource('++resource++kukit-devel.js')
02446         self.failUnless(resource1.getCompression() == 'none')
02447         self.failUnless(resource2.getCompression() == 'none')
02448         self.failUnless('@@kss_devel_mode' in resource1.getExpression())
02449         self.failUnless('@@kss_devel_mode' in resource2.getExpression())
02450         self.failUnless('isoff' in resource1.getExpression())
02451         self.failUnless('ison' in resource2.getExpression())
02452         
02453     def testAddCacheForResourceRegistry(self):
02454         ram_cache_id = 'ResourceRegistryCache'
02455         # first remove the cache manager and make sure it's removed
02456         self.portal._delObject(ram_cache_id)
02457         self.failIf(ram_cache_id in self.portal.objectIds())
02458         cssreg = self.portal.portal_css
02459         cssreg.ZCacheable_setEnabled(0)
02460         cssreg.ZCacheable_setManagerId(None)
02461         self.failIf(cssreg.ZCacheable_enabled())
02462         self.failUnless(cssreg.ZCacheable_getManagerId() is None)
02463         jsreg = self.portal.portal_javascripts
02464         jsreg.ZCacheable_setEnabled(0)
02465         jsreg.ZCacheable_setManagerId(None)
02466         self.failIf(jsreg.ZCacheable_enabled())
02467         self.failUnless(jsreg.ZCacheable_getManagerId() is None)
02468         # then migrate
02469         addCacheForResourceRegistry(self.portal, [])
02470         # and test
02471         self.failUnless(ram_cache_id in self.portal.objectIds())
02472         self.failUnless(cssreg.ZCacheable_enabled())
02473         self.failIf(cssreg.ZCacheable_getManagerId() is None)
02474         self.failUnless(jsreg.ZCacheable_enabled())
02475         self.failIf(jsreg.ZCacheable_getManagerId() is None)
02476 
02477     def testTablelessRemoval(self):
02478         st = getToolByName(self.portal, "portal_skins")
02479         if "Plone Tableless" not in st.getSkinSelections():
02480             st.addSkinSelection('Plone Tableless', 'one,two', make_default=True)
02481         removeTablelessSkin(self.portal, [])
02482         self.failIf('Plone Tableless' in st.getSkinSelections())
02483         self.failIf(st.default_skin == 'Plone Tableless')
02484 
02485     def testUpdateCssQueryJS(self):
02486         jsreg = self.portal.portal_javascripts
02487         jsreg.registerScript("folder_contents_hideAddItems.js")
02488         self.failUnless('folder_contents_hideAddItems.js' in jsreg.getResourceIds())
02489         # migrate and test again
02490         removeHideAddItemsJS(self.portal, [])
02491         self.failIf('folder_contents_hideAddItems.js' in jsreg.getResourceIds())
02492         # try double migration
02493         removeHideAddItemsJS(self.portal, [])
02494 
02495     def testAddWebstatsJSProperty(self):
02496         # adds a site property to portal_properties
02497         self.removeSiteProperty('webstats_js')
02498         addWebstatsJSProperty(self.portal, [])
02499         tool = self.portal.portal_properties
02500         sheet = tool.site_properties
02501         self.failUnless(sheet.hasProperty('webstats_js'))
02502 
02503     def testAddWebstatsJS(self):
02504         jsreg = self.portal.portal_javascripts
02505         # unregister first
02506         jsreg.unregisterResource('webstats.js')
02507         script_ids = jsreg.getResourceIds()
02508         self.failIf('webstats.js' in script_ids)
02509         # migrate and test again
02510         addWebstatsJSFile(self.portal, [])
02511         script_ids = jsreg.getResourceIds()
02512         self.failUnless('webstats.js' in script_ids)
02513         if 'webstats.js' in script_ids:
02514             pos1 = jsreg.getResourcePosition('toc.js')
02515             pos2 = jsreg.getResourcePosition('webstats.js')
02516             self.failUnless((pos2 - 1) == pos1)
02517         # check if enabled
02518         res = jsreg.getResource('webstats.js')
02519         self.assertEqual(res.getEnabled(),True)
02520 
02521     def testWebstatsJSTwice(self):
02522         # Should not break if migrated again
02523         jsreg = self.portal.portal_javascripts
02524         # unregister first
02525         jsreg.unregisterResource('webstats.js')
02526         script_ids = jsreg.getResourceIds()
02527         self.failIf('webstats.js' in script_ids)
02528         # migrate and test again
02529         addWebstatsJSFile(self.portal, [])
02530         addWebstatsJSFile(self.portal, [])
02531         script_ids = jsreg.getResourceIds()
02532         self.failUnless('webstats.js' in script_ids)
02533         if 'webstats.js' in script_ids:
02534             pos1 = jsreg.getResourcePosition('toc.js')
02535             pos2 = jsreg.getResourcePosition('webstats.js')
02536             self.failUnless((pos2 - 1) == pos1)
02537         # check if enabled 
02538         res = jsreg.getResource('webstats.js') 
02539         self.assertEqual(res.getEnabled(),True)
02540 
02541     def testaddIconsForFilterAndSecurityConfiglets(self):
02542         # Should add the filter and security action icons
02543         self.removeActionIconFromTool('HtmlFilter')
02544         self.removeActionIconFromTool('SecuritySettings')
02545         addIconsForFilterAndSecurityConfiglets(self.portal, [])
02546         self.failUnless('HtmlFilter' in [x.getActionId() for x in self.icons.listActionIcons()])
02547         self.failUnless('SecuritySettings' in [x.getActionId() for x in self.icons.listActionIcons()])
02548 
02549     def testaddIconsForFilterAndSecurityConfigletsTwice(self):
02550         # Should not fail if migrated again
02551         self.removeActionIconFromTool('HtmlFilter')
02552         self.removeActionIconFromTool('SecuritySettings')
02553         addIconsForFilterAndSecurityConfiglets(self.portal, [])
02554         addIconsForFilterAndSecurityConfiglets(self.portal, [])
02555         self.failUnless('HtmlFilter' in [x.getActionId() for x in self.icons.listActionIcons()])
02556         self.failUnless('SecuritySettings' in [x.getActionId() for x in self.icons.listActionIcons()])
02557 
02558     def testObjectProvidesIndex(self):
02559         catalog = getToolByName(self.portal, 'portal_catalog')
02560         if 'object_provides' in catalog.indexes():
02561             catalog.delIndex('object_provides')
02562         self.failIf('object_provides' in catalog.indexes())
02563         addObjectProvidesIndex(self.portal, [])
02564         self.failUnless('object_provides' in catalog.indexes())
02565 
02566     def testAddExternalLinksOpenNewWindowProperty(self):
02567         # adds a site property to portal_properties
02568         tool = self.portal.portal_properties
02569         sheet = tool.site_properties
02570         self.removeSiteProperty('external_links_open_new_window')
02571         addExternalLinksOpenNewWindowProperty(self.portal, [])
02572         self.failUnless(sheet.hasProperty('external_links_open_new_window'))
02573         self.failUnless(sheet.external_links_open_new_window == 'false')
02574         # Test migrations succeeds if run multiple times
02575         self.removeSiteProperty('external_links_open_new_window')
02576         addExternalLinksOpenNewWindowProperty(self.portal, [])
02577         addExternalLinksOpenNewWindowProperty(self.portal, [])
02578         self.failUnless(sheet.hasProperty('external_links_open_new_window'))
02579         self.failUnless(sheet.external_links_open_new_window == 'false')
02580 
02581     def testAddMissingWorkflowsNoTool(self):
02582         self.portal._delObject('portal_workflow')
02583         addMissingWorkflows(self.portal, [])
02584 
02585     def testAddManyGroupsProperty(self):
02586         # adds a site property to portal_properties
02587         tool = self.portal.portal_properties
02588         sheet = tool.site_properties
02589         self.removeSiteProperty('many_groups')
02590         addManyGroupsProperty(self.portal, [])
02591         self.failUnless(sheet.hasProperty('many_groups'))
02592         self.failUnless(sheet.many_groups == False)
02593         # Test migrations succeeds if run multiple times
02594         self.removeSiteProperty('many_groups')
02595         addManyGroupsProperty(self.portal, [])
02596         addManyGroupsProperty(self.portal, [])
02597         self.failUnless(sheet.hasProperty('many_groups'))
02598         self.failUnless(sheet.many_groups == False)
02599 
02600     def testMigratePloneTool(self):
02601         from Products.CMFPlone import ToolNames
02602         tool = self.portal.plone_utils
02603         tool.meta_type = 'PlonePAS Utilities Tool'
02604         restorePloneTool(self.portal, [])
02605         tool = self.portal.plone_utils
02606         self.assertEquals(ToolNames.UtilsTool, tool.meta_type)
02607 
02608     def testInstallI18NUtilities(self):
02609         sm = getSiteManager()
02610         sm.unregisterUtility(provided=ICountries)
02611         sm.unregisterUtility(provided=IContentLanguages)
02612         sm.unregisterUtility(provided=IMetadataLanguages)
02613         installI18NUtilities(self.portal, [])
02614         self.failIf(sm.queryUtility(ICountries) is None)
02615         self.failIf(sm.queryUtility(IContentLanguages) is None)
02616         self.failIf(sm.queryUtility(IMetadataLanguages) is None)
02617 
02618     def testInstallI18NUtilitiesTwice(self):
02619         sm = getSiteManager()
02620         sm.unregisterUtility(provided=ICountries)
02621         sm.unregisterUtility(provided=IContentLanguages)
02622         sm.unregisterUtility(provided=IMetadataLanguages)
02623         installI18NUtilities(self.portal, [])
02624         installI18NUtilities(self.portal, [])
02625         self.failIf(sm.queryUtility(ICountries) is None)
02626         self.failIf(sm.queryUtility(IContentLanguages) is None)
02627         self.failIf(sm.queryUtility(IMetadataLanguages) is None)
02628 
02629     def testInstallPloneLanguageTool(self):
02630         CMFSite.manage_delObjects(self.portal, ['portal_languages'])
02631         self.uninstallProduct('PloneLanguageTool')
02632         qi = getToolByName(self.portal, "portal_quickinstaller")
02633         installProduct('PloneLanguageTool', self.portal, [])
02634         self.failUnless(qi.isProductInstalled('PloneLanguageTool'))
02635         self.failUnless('portal_languages' in self.portal.keys())
02636 
02637     def testAddEmailCharsetProperty(self):
02638         if self.portal.hasProperty('email_charset'):
02639             self.portal.manage_delProperties(['email_charset'])
02640         addEmailCharsetProperty(self.portal, [])
02641         self.failUnless(self.portal.hasProperty('email_charset'))
02642         self.assertEquals(self.portal.getProperty('email_charset'), 'utf-8')
02643 
02644     def testAddEmailCharsetPropertyTwice(self):
02645         out = []
02646         if self.portal.hasProperty('email_charset'):
02647             self.portal.manage_delProperties(['email_charset'])
02648         addEmailCharsetProperty(self.portal, out)
02649         addEmailCharsetProperty(self.portal, out)
02650         self.failUnless(self.portal.hasProperty('email_charset'))
02651         self.assertEquals(self.portal.getProperty('email_charset'), 'utf-8')
02652 
02653     def testChangeOrderOfActionProviders(self):
02654         out = []
02655         self.actions.deleteActionProvider('portal_types')
02656         self.actions.addActionProvider('portal_types')
02657         self.assertEquals(
02658             self.actions.listActionProviders(),
02659             ('portal_workflow', 'portal_actions', 'portal_types'))
02660         changeOrderOfActionProviders(self.portal, out)
02661         self.assertEquals(
02662             self.actions.listActionProviders(),
02663             ('portal_workflow', 'portal_types', 'portal_actions'))
02664 
02665     def testChangeOrderOfActionProvidersTwice(self):
02666         out = []
02667         self.actions.deleteActionProvider('portal_types')
02668         self.actions.addActionProvider('portal_types')
02669         self.assertEquals(
02670             self.actions.listActionProviders(),
02671             ('portal_workflow', 'portal_actions', 'portal_types'))
02672         changeOrderOfActionProviders(self.portal, out)
02673         changeOrderOfActionProviders(self.portal, out)
02674         self.assertEquals(
02675             self.actions.listActionProviders(),
02676             ('portal_workflow', 'portal_types', 'portal_actions'))
02677 
02678     def testCleanupOldActions(self):
02679         out = []
02680         reply = Action('reply', title='Reply')
02681         logged_in = Action('logged_in', title='Logged in')
02682         change_ownership = Action('change_ownership', title='Change ownership')
02683 
02684         object_ = self.actions.object
02685         object_tabs = getattr(self.actions, 'object_tabs', None)
02686         if object_tabs is None:
02687             category = 'object_tabs'
02688             self.actions._setObject(category, ActionCategory(id=category))
02689             object_tabs = self.actions.object_tabs
02690         if getattr(self.actions, 'global', None) is None:
02691             category = 'global'
02692             self.actions._setObject(category, ActionCategory(id=category))
02693 
02694         if not 'reply' in object_.keys():
02695             object_._setObject('reply', reply)
02696         user = self.actions.user
02697         if not 'logged_in' in user.keys():
02698             user._setObject('logged_in', logged_in)
02699         if not 'change_ownership' in object_tabs.keys():
02700             object_tabs._setObject('change_ownership', change_ownership)
02701         del object_tabs
02702 
02703         cleanupOldActions(self.portal, out)
02704 
02705         self.failIf('reply' in object_.keys())
02706         self.failIf('logged_in' in user.keys())
02707         self.failIf('object_tabs' in self.actions.keys())
02708         self.failIf('global' in self.actions.keys())
02709 
02710     def testCleanupOldActionsTwice(self):
02711         out = []
02712         reply = Action('reply', title='Reply')
02713         logged_in = Action('logged_in', title='Logged in')
02714         change_ownership = Action('change_ownership', title='Change ownership')
02715 
02716         object_ = self.actions.object
02717         object_tabs = getattr(self.actions, 'object_tabs', None)
02718         if object_tabs is None:
02719             category = 'object_tabs'
02720             self.actions._setObject(category, ActionCategory(id=category))
02721             object_tabs = self.actions.object_tabs
02722         if getattr(self.actions, 'global', None) is None:
02723             category = 'global'
02724             self.actions._setObject(category, ActionCategory(id=category))
02725 
02726         if not 'reply' in object_.keys():
02727             object_._setObject('reply', reply)
02728         user = self.actions.user
02729         if not 'logged_in' in user.keys():
02730             user._setObject('logged_in', logged_in)
02731         if not 'change_ownership' in object_tabs.keys():
02732             object_tabs._setObject('change_ownership', change_ownership)
02733         del object_tabs
02734 
02735         cleanupOldActions(self.portal, out)
02736         cleanupOldActions(self.portal, out)
02737 
02738         self.failIf('reply' in object_.keys())
02739         self.failIf('logged_in' in user.keys())
02740         self.failIf('object_tabs' in self.actions.keys())
02741         self.failIf('global' in self.actions.keys())
02742 
02743     def testCharsetCleanup(self):
02744         if not self.portal.hasProperty('default_charset'):
02745             self.portal.manage_addProperty('default_charset', '', 'string')
02746 
02747         self.portal.manage_changeProperties(default_charset = 'latin1')
02748         cleanDefaultCharset(self.portal, [])
02749         self.assertEqual(self.portal.getProperty('default_charset', 'nothere'),
02750                 'latin1')
02751 
02752         self.portal.manage_changeProperties(default_charset = '')
02753         cleanDefaultCharset(self.portal, [])
02754         self.assertEqual(self.portal.getProperty('default_charset', 'nothere'),
02755                 'nothere')
02756 
02757     def testAutoGroupCreated(self):
02758         pas = self.portal.acl_users
02759         ids = pas.objectIds(['Automatic Group Plugin'])
02760         if ids:
02761             pas.manage_delObjects(ids)
02762         addAutoGroupToPAS(self.portal, [])
02763         self.assertEqual(pas.objectIds(['Automatic Group Plugin']),
02764                 ['auto_group'])
02765         plugin = pas.auto_group
02766         interfaces = [info['interface'] for info in pas.plugins.listPluginTypeInfo()]
02767         for iface in interfaces:
02768             if plugin.testImplements(iface):
02769                 self.failIf('auto_group' not in pas.plugins.listPluginIds(iface))
02770         self.assertEqual(len(pas.searchGroups(id='AuthenticatedUsers',
02771                                               exact_match=True)), 1)
02772 
02773     def testPloneS5(self):
02774         pt = getToolByName(self.portal, "portal_types")
02775         ait = getToolByName(self.portal, "portal_actionicons")
02776         document = pt.restrictedTraverse('Document')
02777 
02778         action_ids = [x.getId() for x in document.listActions()]
02779         assert "s5_presentation" not in action_ids
02780 
02781         icon_ids = [x.getActionId() for x in ait.listActionIcons()]
02782         assert "s5_presentation" not in icon_ids
02783 
02784         installS5(self.portal, [])
02785 
02786         action_ids = [x.getId() for x in document.listActions()]
02787         assert "s5_presentation" in action_ids
02788 
02789         icon_ids = [x.getActionId() for x in ait.listActionIcons()]
02790         assert "s5_presentation" in icon_ids
02791 
02792         removeS5Actions(self.portal, [])
02793 
02794         action_ids = [x.getId() for x in document.listActions()]
02795         assert "s5_presentation" not in action_ids
02796 
02797         icon_ids = [x.getActionId() for x in ait.listActionIcons()]
02798         assert "s5_presentation" not in icon_ids
02799 
02800     def testAddCacheForKSSRegistry(self):
02801         ram_cache_id = 'ResourceRegistryCache'
02802         kssreg = self.portal.portal_kss
02803         kssreg.ZCacheable_setEnabled(0)
02804         kssreg.ZCacheable_setManagerId(None)
02805         self.failIf(kssreg.ZCacheable_enabled())
02806         self.failUnless(kssreg.ZCacheable_getManagerId() is None)
02807         # migrate
02808         addCacheForKSSRegistry(self.portal, [])
02809         # and test
02810         self.failUnless(kssreg.ZCacheable_enabled())
02811         self.failIf(kssreg.ZCacheable_getManagerId() is None)
02812 
02813     def testAddContributorToCreationPermissions(self):
02814         self.portal._delRoles(['Contributor',])
02815         for p in ['Add portal content', 'Add portal folders', 'ATContentTypes: Add Document',
02816                     'ATContentTypes: Add Event', 'ATContentTypes: Add Favorite',
02817                     'ATContentTypes: Add File', 'ATContentTypes: Add Folder', 
02818                     'ATContentTypes: Add Image', 'ATContentTypes: Add Large Plone Folder',
02819                     'ATContentTypes: Add Link', 'ATContentTypes: Add News Item', ]:
02820             self.portal.manage_permission(p, ['Manager', 'Owner'], True)
02821         addContributorToCreationPermissions(self.portal, [])
02822         self.failUnless('Contributor' in self.portal.valid_roles())
02823         self.failUnless('Contributor' in self.portal.acl_users.portal_role_manager.listRoleIds())
02824         for p in ['Add portal content', 'Add portal folders', 'ATContentTypes: Add Document',
02825                     'ATContentTypes: Add Event', 'ATContentTypes: Add Favorite',
02826                     'ATContentTypes: Add File', 'ATContentTypes: Add Folder', 
02827                     'ATContentTypes: Add Image', 'ATContentTypes: Add Large Plone Folder',
02828                     'ATContentTypes: Add Link', 'ATContentTypes: Add News Item', ]:
02829             self.failUnless(p in [r['name'] for r in 
02830                                 self.portal.permissionsOfRole('Contributor') if r['selected']])
02831 
02832     def testAddEditorToCreationPermissionsNoStomp(self):
02833         self.portal.manage_permission('Add portal content', ['Manager'], False)
02834         addContributorToCreationPermissions(self.portal, [])
02835         roles = sorted([r['name'] for r in self.portal.rolesOfPermission('Add portal content') if r['selected']])
02836         self.assertEquals(['Contributor', 'Manager'], roles)
02837         self.assertEquals(False, bool(self.portal.acquiredRolesAreUsedBy('Add portal content')))
02838                                 
02839     def testAddEditorToCreationPermissionsTwice(self):
02840         self.portal._delRoles(['Contributor',])
02841         for p in ['Add portal content', 'Add portal folders', 'ATContentTypes: Add Document',
02842                     'ATContentTypes: Add Event', 'ATContentTypes: Add Favorite',
02843                     'ATContentTypes: Add File', 'ATContentTypes: Add Folder', 
02844                     'ATContentTypes: Add Image', 'ATContentTypes: Add Large Plone Folder',
02845                     'ATContentTypes: Add Link', 'ATContentTypes: Add News Item', ]:
02846             self.portal.manage_permission(p, ['Manager', 'Owner'], True)
02847         addContributorToCreationPermissions(self.portal, [])
02848         addContributorToCreationPermissions(self.portal, [])
02849         self.failUnless('Contributor' in self.portal.valid_roles())
02850         self.failUnless('Contributor' in self.portal.acl_users.portal_role_manager.listRoleIds())
02851         for p in ['Add portal content', 'Add portal folders', 'ATContentTypes: Add Document',
02852                     'ATContentTypes: Add Event', 'ATContentTypes: Add Favorite',
02853                     'ATContentTypes: Add File', 'ATContentTypes: Add Folder', 
02854                     'ATContentTypes: Add Image', 'ATContentTypes: Add Large Plone Folder',
02855                     'ATContentTypes: Add Link', 'ATContentTypes: Add News Item', ]:
02856             self.failUnless(p in [r['name'] for r in 
02857                                 self.portal.permissionsOfRole('Contributor') if r['selected']])
02858 
02859     def testAddBeta2VersioningPermissionsToNewRoles(self):
02860         # This migration just uses GS to apply the role changes,
02861         # these permissions will not have been installed previously,
02862         # so this should be safe
02863         for p in ['CMFEditions: Apply version control',
02864                   'CMFEditions: Save new version',
02865                   'CMFEditions: Access previous versions',
02866                   'CMFEditions: Revert to previous versions',
02867                   'CMFEditions: Checkout to location']:
02868             self.portal.manage_permission(p, ['Manager', 'Owner'], True)
02869         loadMigrationProfile(self.portal,
02870                 'profile-Products.CMFPlone.migrations:3.0b1-3.0b2',
02871                 steps=["rolemap"])
02872         for p in ['CMFEditions: Apply version control',
02873                   'CMFEditions: Save new version',
02874                   'CMFEditions: Access previous versions']:
02875             self.failUnless(p in [r['name'] for r in 
02876                                 self.portal.permissionsOfRole('Contributor') if r['selected']])
02877             self.failUnless(p in [r['name'] for r in 
02878                                 self.portal.permissionsOfRole('Editor') if r['selected']])
02879         for p in ['CMFEditions: Revert to previous versions',
02880                   'CMFEditions: Checkout to location']:
02881             self.failUnless(p in [r['name'] for r in 
02882                                 self.portal.permissionsOfRole('Editor') if r['selected']])
02883         # perform migration twice
02884         loadMigrationProfile(self.portal,
02885                 'profile-Products.CMFPlone.migrations:3.0b1-3.0b2',
02886                 steps=["rolemap"])
02887         for p in ['CMFEditions: Apply version control',
02888                   'CMFEditions: Save new version',
02889                   'CMFEditions: Access previous versions']:
02890             self.failUnless(p in [r['name'] for r in 
02891                                 self.portal.permissionsOfRole('Contributor') if r['selected']])
02892             self.failUnless(p in [r['name'] for r in 
02893                                 self.portal.permissionsOfRole('Editor') if r['selected']])
02894         for p in ['CMFEditions: Revert to previous versions',
02895                   'CMFEditions: Checkout to location']:
02896             self.failUnless(p in [r['name'] for r in 
02897                                 self.portal.permissionsOfRole('Editor') if r['selected']])
02898 
02899     def testRemoveSharingAction(self):
02900         fti = self.types['Document']
02901         fti.addAction(id='local_roles', name='Sharing', 
02902                       action='string:${object_url}/sharing',
02903                       condition=None, permission='Manage properties',
02904                       category='object')
02905         removeSharingAction(self.portal, [])
02906         self.failIf('local_roles' in [a.id for a in fti.listActions()])
02907         
02908     def testRemoveSharingActionNoTool(self):
02909         self.portal._delOb('portal_types')
02910         removeSharingAction(self.portal, [])
02911         
02912     def testRemoveSharingActionTwice(self):
02913         fti = self.types['Document']
02914         fti.addAction(id='local_roles', name='Sharing', 
02915                       action='string:${object_url}/sharing',
02916                       condition=None, permission='Manage properties',
02917                       category='object')
02918         removeSharingAction(self.portal, [])
02919         removeSharingAction(self.portal, [])
02920         self.failIf('local_roles' in [a.id for a in fti.listActions()])
02921         
02922     def testAddContributorToCreationPermissions(self):
02923         for p in ['Manage properties', 'Modify view template', 'Request review']:
02924             self.portal.manage_permission(p, ['Manager', 'Owner'], True)
02925         addEditorToSecondaryEditorPermissions(self.portal, [])
02926         for p in ['Manage properties', 'Modify view template', 'Request review']:
02927             self.failUnless(p in [r['name'] for r in 
02928                 self.portal.permissionsOfRole('Editor') if r['selected']])
02929 
02930     def testAddEditorToCreationPermissionsNoStomp(self):
02931         self.portal.manage_permission('Manage properties', ['Manager'], False)
02932         addEditorToSecondaryEditorPermissions(self.portal, [])
02933         roles = sorted([r['name'] for r in self.portal.rolesOfPermission('Manage properties') if r['selected']])
02934         self.assertEquals(['Editor', 'Manager'], roles)
02935         self.assertEquals(False, bool(self.portal.acquiredRolesAreUsedBy('Manage properties')))
02936                                 
02937     def testAddEditorToSecondaryEditPermissionsTwice(self):
02938         for p in ['Manage properties', 'Modify view template', 'Request review']:
02939             self.portal.manage_permission(p, ['Manager', 'Owner'], True)
02940         addEditorToSecondaryEditorPermissions(self.portal, [])
02941         addEditorToSecondaryEditorPermissions(self.portal, [])
02942         for p in ['Manage properties', 'Modify view template', 'Request review']:
02943             self.failUnless(p in [r['name'] for r in 
02944                 self.portal.permissionsOfRole('Editor') if r['selected']])
02945 
02946     def testUpdateEditActionConditionForLocking(self):
02947         out = []
02948         lockable_types = ['Document', 'Event', 'Favorite', 'File', 'Folder',
02949                           'Image', 'Large Plone Folder', 'Link',
02950                           'News Item', 'Topic']
02951         for contentType in lockable_types:
02952             fti = self.types.getTypeInfo(contentType)
02953             for action in fti.listActions():
02954                 if action.getId() == 'edit':
02955                     action.condition = ''
02956         updateEditActionConditionForLocking(self.portal, out)
02957         for contentType in lockable_types:
02958             fti = self.types.getTypeInfo(contentType)
02959             for action in fti.listActions():
02960                 if action.getId() == 'edit':
02961                     expressionCondition = action.condition
02962                     self.assertEquals(action.condition.text, "not:object/@@plone_lock_info/is_locked_for_current_user|python:True")
02963 
02964     def testUpdateEditActionConditionForLockingTwice(self):
02965         out = []
02966         lockable_types = ['Document', 'Event', 'Favorite', 'File', 'Folder',
02967                           'Image', 'Large Plone Folder', 'Link',
02968                           'News Item', 'Topic']
02969         for contentType in lockable_types:
02970             fti = self.types.getTypeInfo(contentType)
02971             for action in fti.listActions():
02972                 if action.getId() == 'edit':
02973                     action.condition = ''
02974         updateEditActionConditionForLocking(self.portal, out)
02975         updateEditActionConditionForLocking(self.portal, out)
02976         for contentType in lockable_types:
02977             fti = self.types.getTypeInfo(contentType)
02978             for action in fti.listActions():
02979                 if action.getId() == 'edit':
02980                     expressionCondition = action.condition
02981                     self.assertEquals(action.condition.text, "not:object/@@plone_lock_info/is_locked_for_current_user|python:True")
02982 
02983     def testUpdateEditExistingActionConditionForLocking(self):
02984         out = []
02985         fti = self.types.getTypeInfo('Document')
02986         for action in fti.listActions():
02987             if action.getId() == 'edit':
02988                 action.condition = Expression("foo")
02989         updateEditActionConditionForLocking(self.portal, out)
02990         fti = self.types.getTypeInfo('Document')
02991         for action in fti.listActions():
02992             if action.getId() == 'edit':
02993                 self.assertEquals(action.condition.text, 'foo')
02994 
02995     def testAddOnFormUnloadRegistrationJS(self):
02996         jsreg = self.portal.portal_javascripts
02997         # unregister first
02998         jsreg.unregisterResource('unlockOnFormUnload.js')
02999         script_ids = jsreg.getResourceIds()
03000         self.failIf('unlockOnFormUnload.js' in script_ids)
03001         # migrate and test again
03002         addOnFormUnloadJS(self.portal, [])
03003         script_ids = jsreg.getResourceIds()
03004         self.failUnless('unlockOnFormUnload.js' in script_ids)
03005 
03006     def testAddOnFormUnloadRegistrationJSTwice(self):
03007         jsreg = self.portal.portal_javascripts
03008         # unregister first
03009         jsreg.unregisterResource('unlockOnFormUnload.js')
03010         script_ids = jsreg.getResourceIds()
03011         self.failIf('unlockOnFormUnload.js' in script_ids)
03012         # migrate and test again
03013         addOnFormUnloadJS(self.portal, [])
03014         addOnFormUnloadJS(self.portal, [])
03015         script_ids = jsreg.getResourceIds()
03016         self.failUnless('unlockOnFormUnload.js' in script_ids)
03017 
03018     def testAddRAMCache(self):
03019         sm = getSiteManager()
03020         sm.unregisterUtility(provided=IRAMCache)
03021         util = queryUtility(IRAMCache)
03022         self.failUnless(util.maxAge == 86400)
03023         beta3_rc1(self.portal)
03024         util = queryUtility(IRAMCache)
03025         self.failUnless(util.maxAge == 3600)
03026 
03027     def testMoveKupuAndCMFPWControlPanel(self):
03028         kupu = self.cp.getActionObject('Plone/kupu')
03029         kupu.category = 'Products'
03030         cmfpw = self.cp.getActionObject('Products/placefulworkflow')
03031         if cmfpw is None:
03032             self.cp.registerConfiglet(**placeful_prefs_configlet)
03033         cmfpw = self.cp.getActionObject('Products/placefulworkflow')
03034         cmfpw.category = 'Plone'
03035         # migrate
03036         moveKupuAndCMFPWControlPanel(self.portal, [])
03037         kupu = self.cp.getActionObject('Plone/kupu')
03038         self.assertEquals(kupu.getCategory(), 'Plone')
03039         cmfpw = self.cp.getActionObject('Products/placefulworkflow')
03040         self.assertEquals(cmfpw.getCategory(), 'Products')
03041 
03042     def testMoveKupuAndCMFPWControlPanelTwice(self):
03043         # Should not fail if done twice
03044         kupu = self.cp.getActionObject('Plone/kupu')
03045         kupu.category = 'Products'
03046         cmfpw = self.cp.getActionObject('Products/placefulworkflow')
03047         if cmfpw is None:
03048             self.cp.registerConfiglet(**placeful_prefs_configlet)
03049         cmfpw = self.cp.getActionObject('Products/placefulworkflow')
03050         cmfpw.category = 'Plone'
03051         # migrate
03052         moveKupuAndCMFPWControlPanel(self.portal, [])
03053         moveKupuAndCMFPWControlPanel(self.portal, [])
03054         kupu = self.cp.getActionObject('Plone/kupu')
03055         self.assertEquals(kupu.getCategory(), 'Plone')
03056         cmfpw = self.cp.getActionObject('Products/placefulworkflow')
03057         self.assertEquals(cmfpw.getCategory(), 'Products')
03058 
03059     def testMoveKupuAndCMFPWControlPanelNoTool(self):
03060         # Should not fail if tool is missing
03061         self.portal._delObject('portal_controlpanel')
03062         moveKupuAndCMFPWControlPanel(self.portal, [])
03063 
03064     def testUpdateLanguageControlPanel(self):
03065         lang = self.cp.getActionObject('Plone/PloneLanguageTool')
03066         lang.action = Expression('string:lang')
03067         updateLanguageControlPanel(self.portal, [])
03068         self.assertEquals(lang.action.text,
03069                           'string:${portal_url}/@@language-controlpanel')
03070 
03071     def testUpdateLanguageControlPanelTwice(self):
03072         # Should not fail if done twice
03073         lang = self.cp.getActionObject('Plone/PloneLanguageTool')
03074         lang.action = Expression('string:lang')
03075         updateLanguageControlPanel(self.portal, [])
03076         updateLanguageControlPanel(self.portal, [])
03077         self.assertEquals(lang.action.text,
03078                           'string:${portal_url}/@@language-controlpanel')
03079 
03080     def testUpdateLanguageControlPanelNoTool(self):
03081         # Should not fail if tool is missing
03082         self.portal._delObject('portal_controlpanel')
03083         updateLanguageControlPanel(self.portal, [])
03084 
03085     def testUpdateTopicTitle(self):
03086         topic = self.types.get('Topic')
03087         topic.title = 'Unmigrated'
03088         updateTopicTitle(self.portal, [])
03089         self.failUnless(topic.title == 'Collection')
03090 
03091     def testUpdateTopicTitleTwice(self):
03092         topic = self.types.get('Topic')
03093         topic.title = 'Unmigrated'
03094         updateTopicTitle(self.portal, [])
03095         updateTopicTitle(self.portal, [])
03096         self.failUnless(topic.title == 'Collection')
03097 
03098     def testUpdateTopicTitleNoTool(self):
03099         self.portal._delObject('portal_types')
03100         updateTopicTitle(self.portal, [])
03101 
03102     def testAddIntelligentText(self):
03103         # Before migration, the mime type and transforms of
03104         # intelligent text are not available.  They *are* here in a
03105         # fresh site, so we may need to remove them first for testing.
03106 
03107         # First we remove the transforms, as they depend on the
03108         # mimetype being there.
03109         missing_transforms = ["web_intelligent_plain_text_to_html",
03110                               "html_to_web_intelligent_plain_text"]
03111         ptr = self.portal.portal_transforms
03112         current_transforms = ptr.objectIds()
03113         for trans in missing_transforms:
03114             if trans in current_transforms:
03115                 ptr.unregisterTransform(trans)
03116 
03117         # Then we remove the mime type
03118         mime_type = 'text/x-web-intelligent'
03119         mtr = self.portal.mimetypes_registry
03120         current_types = mtr.list_mimetypes()
03121         if mime_type in current_types:
03122             mtr.manage_delObjects((mime_type,))
03123 
03124         # now all are gone:
03125         self.failIf(mime_type in mtr.list_mimetypes())
03126         self.failIf(set(ptr.objectIds()).issuperset(set(missing_transforms)))
03127 
03128         out = []
03129         addIntelligentText(self.portal, out)
03130         # now all are back:
03131         self.failUnless(mime_type in mtr.list_mimetypes())
03132         self.failUnless(set(ptr.objectIds()).issuperset(set(missing_transforms)))
03133 
03134     def testInstallNewModifiers(self):
03135         # ensure the new modifiers are installed
03136         modifiers = self.portal.portal_modifier
03137         self.failUnless('AbortVersioningOfLargeFilesAndImages' in
03138                                                           modifiers.objectIds())
03139         modifiers.manage_delObjects(['AbortVersioningOfLargeFilesAndImages',
03140                                      'SkipVersioningOfLargeFilesAndImages'])
03141         self.failIf('AbortVersioningOfLargeFilesAndImages' in
03142                                                           modifiers.objectIds())
03143         installNewModifiers(self.portal, [])
03144         self.failUnless('AbortVersioningOfLargeFilesAndImages' in
03145                                                           modifiers.objectIds())
03146         self.failUnless('SkipVersioningOfLargeFilesAndImages' in
03147                                                           modifiers.objectIds())
03148 
03149     def testInstallNewModifiersTwice(self):
03150         # ensure that we get no errors when run twice
03151         modifiers = self.portal.portal_modifier
03152         installNewModifiers(self.portal, [])
03153         installNewModifiers(self.portal, [])
03154 
03155     def testInstallNewModifiersDoesNotStompChanges(self):
03156         # ensure that reinstalling doesn't kill customizations
03157         modifiers = self.portal.portal_modifier
03158         modifiers.AbortVersioningOfLargeFilesAndImages.max_size = 1000
03159         installNewModifiers(self.portal, [])
03160         self.assertEqual(modifiers.AbortVersioningOfLargeFilesAndImages.max_size,
03161                          1000)
03162 
03163     def testInstallNewModifiersNoTool(self):
03164         # make sure there are no errors if the tool is missing
03165         self.portal._delObject('portal_modifier')
03166         installNewModifiers(self.portal, [])
03167 
03168 class TestMigrations_v3_1(MigrationTest):
03169 
03170     def afterSetUp(self):
03171         self.qi = self.portal.portal_quickinstaller
03172         self.wf = self.portal.portal_workflow
03173         self.ps = self.portal.portal_setup
03174 
03175     def testReinstallCMFPlacefulWorkflow(self):
03176         # first the product needs to be installed
03177         self.qi.installProduct('CMFPlacefulWorkflow')
03178         # Delete existing logs to prevent race condition
03179         self.ps.manage_delObjects(self.ps.objectIds())
03180         # We remove the new marker, to ensure it's added on reinstall
03181         if IPlacefulMarker.providedBy(self.wf):
03182             noLongerProvides(self.wf, IPlacefulMarker)
03183         reinstallCMFPlacefulWorkflow(self.portal, [])
03184         self.failUnless(IPlacefulMarker.providedBy(self.wf))
03185 
03186     def testReinstallCMFPlacefulWorkflowDoesNotInstall(self):
03187         reinstallCMFPlacefulWorkflow(self.portal, [])
03188         self.failIf(self.qi.isProductInstalled('CMFPlacefulWorkflow'))
03189 
03190     def testReinstallCMFPlacefulWorkflowNoTool(self):
03191         self.portal._delObject('portal_quickinstaller')
03192         reinstallCMFPlacefulWorkflow(self.portal, [])
03193 
03194     def testReplaceLocalRoleManager(self):
03195         # first we replace the local role manager with the one from PlonePAS
03196         uf = self.portal.acl_users
03197         # deactivate and remove the borg plugin
03198         uf.plugins.removePluginById('borg_localroles')
03199         uf.manage_delObjects(['borg_localroles'])
03200         # activate the standard plugin
03201         uf.plugins.activatePlugin(ILocalRolesPlugin, 'local_roles')
03202         # Bring things back to normal
03203         replace_local_role_manager(self.portal, [])
03204         plugins = uf.plugins.listPlugins(ILocalRolesPlugin)
03205         self.failUnlessEqual(len(plugins), 1)
03206         self.failUnlessEqual(plugins[0][0], 'borg_localroles')
03207 
03208     def testReplaceLocalRoleManagerTwice(self):
03209         # first we replace the local role manager with the one from PlonePAS
03210         uf = self.portal.acl_users
03211         # deactivate and remove the borg plugin
03212         uf.plugins.removePluginById('borg_localroles')
03213         uf.manage_delObjects(['borg_localroles'])
03214         # activate the standard plugin
03215         uf.plugins.activatePlugin(ILocalRolesPlugin, 'local_roles')
03216         # run the migration twice
03217         replace_local_role_manager(self.portal, [])
03218         replace_local_role_manager(self.portal, [])
03219         plugins = uf.plugins.listPlugins(ILocalRolesPlugin)
03220         self.failUnlessEqual(len(plugins), 1)
03221         self.failUnlessEqual(plugins[0][0], 'borg_localroles')
03222 
03223     def testReplaceLocalRoleManagerNoPlugin(self):
03224         # first we replace the local role manager with the one from PlonePAS
03225         uf = self.portal.acl_users
03226         # deactivate and remove the borg plugin
03227         uf.plugins.removePluginById('borg_localroles')
03228         uf.manage_delObjects(['borg_localroles'])
03229         # delete the standard plugin
03230         uf.manage_delObjects(['local_roles'])
03231         # Run the migration, which shouldn't fail even if the expected
03232         # plugin is missing
03233         replace_local_role_manager(self.portal, [])
03234         plugins = uf.plugins.listPlugins(ILocalRolesPlugin)
03235         self.failUnlessEqual(len(plugins), 1)
03236         self.failUnlessEqual(plugins[0][0], 'borg_localroles')
03237 
03238     def testReplaceLocalRoleManagerNoPAS(self):
03239         uf = self.portal.acl_users
03240         # delete the plugin registry
03241         uf._delObject('plugins')
03242         replace_local_role_manager(self.portal, [])
03243 
03244     def testReplaceLocalRoleManagerNoUF(self):
03245         # Delete the user folder
03246         uf = self.portal._delObject('acl_users')
03247         replace_local_role_manager(self.portal, [])
03248 
03249 
03250 def test_suite():
03251     from unittest import TestSuite, makeSuite
03252     suite = TestSuite()
03253     suite.addTest(makeSuite(TestMigrations_v2_1_1))
03254     suite.addTest(makeSuite(TestMigrations_v2_1_2))
03255     suite.addTest(makeSuite(TestMigrations_v2_1_3))
03256     suite.addTest(makeSuite(TestMigrations_v2_5))
03257     suite.addTest(makeSuite(TestMigrations_v2_5_1))
03258     suite.addTest(makeSuite(TestMigrations_v2_5_2))
03259     suite.addTest(makeSuite(TestMigrations_v2_5_4))
03260     suite.addTest(makeSuite(TestMigrations_v3_0))
03261     suite.addTest(makeSuite(TestMigrations_v3_0_Actions))
03262     suite.addTest(makeSuite(TestMigrations_v3_1))
03263     return suite