[Testbot] Plone 4.3 - Python 2.6 - Build # 2612 - Still failing! - 0 failure(s)

jenkins at plone.org jenkins at plone.org
Tue Jan 6 16:46:26 UTC 2015


-------------------------------------------------------------------------------
Plone 4.3 - Python 2.6 - Build # 2612 - Still Failing!
-------------------------------------------------------------------------------

http://jenkins.plone.org/job/plone-4.3-python-2.6/2612/


-------------------------------------------------------------------------------
CHANGES
-------------------------------------------------------------------------------

Repository: plone.app.upgrade
Branch: refs/heads/master
Date: 2014-12-10T10:32:22+01:00
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/plone.app.upgrade/commit/dc181409b1e45cfd6feb3f47ebb1499a0fa72436

updated egg classifiers

Files changed:
M setup.py

diff --git a/setup.py b/setup.py
index 1dd33a5..ab8b563 100644
--- a/setup.py
+++ b/setup.py
@@ -10,10 +10,12 @@
       classifiers=[
           "Environment :: Web Environment",
           "Framework :: Plone",
+          "Framework :: Plone :: 5.0",
           "Framework :: Zope2",
           "License :: OSI Approved :: GNU General Public License (GPL)",
           "Operating System :: OS Independent",
           "Programming Language :: Python",
+          "Programming Language :: Python :: 2.7",
         ],
       keywords='Plone upgrade migration',
       author='Plone Foundation',


Repository: plone.app.upgrade
Branch: refs/heads/master
Date: 2014-12-10T11:08:00+01:00
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/plone.app.upgrade/commit/3419d3f9144c89f3164eb3c80257a2be8a170e88

remove traces of PloneTestCase

Files changed:
M plone/app/upgrade/tests/base.py
M setup.py

diff --git a/plone/app/upgrade/tests/base.py b/plone/app/upgrade/tests/base.py
index 840416c..f25f530 100644
--- a/plone/app/upgrade/tests/base.py
+++ b/plone/app/upgrade/tests/base.py
@@ -9,10 +9,7 @@
 import transaction
 from zope.site.hooks import setSite
 
-from Testing.ZopeTestCase.sandbox import Sandboxed
-from Products.PloneTestCase.layer import PloneSiteLayer
-from Products.PloneTestCase.ptc import PloneTestCase
-from Products.PloneTestCase.ptc import setupPloneSite
+from plone.app.testing.bbb import PloneTestCase
 
 from Products.CMFCore.interfaces import IActionCategory
 from Products.CMFCore.interfaces import IActionInfo
@@ -20,8 +17,6 @@
 from Products.CMFCore.tests.base.testcase import WarningInterceptor
 from Products.GenericSetup.context import TarballImportContext
 
-setupPloneSite()
-
 
 class MigrationTest(PloneTestCase):
 
@@ -111,21 +106,10 @@ def removeSkinLayer(self, layer, skin='Plone Default'):
             skins.addSkinSelection(skin, ','.join(path))
 
 
-class FunctionalUpgradeLayer(PloneSiteLayer):
-
-    @classmethod
-    def setUp(cls):
-        pass
-
-    @classmethod
-    def tearDown(cls):
-        pass
-
 
-class FunctionalUpgradeTestCase(Sandboxed, PloneTestCase, WarningInterceptor):
+class FunctionalUpgradeTestCase(PloneTestCase, WarningInterceptor):
 
     _setup_fixture = 0
-    layer = FunctionalUpgradeLayer
     site_id = 'test'
 
     def afterSetUp(self):
diff --git a/setup.py b/setup.py
index ab8b563..1a44248 100644
--- a/setup.py
+++ b/setup.py
@@ -30,13 +30,13 @@
         test=[
             'Products.CMFPlacefulWorkflow',
             'Products.CMFQuickInstallerTool',
-            'Products.PloneTestCase',
             'plone.contentrules',
             'plone.app.i18n',
             'plone.app.iterate',
             'plone.app.openid',
             'plone.app.redirector',
             'plone.app.viewletmanager',
+            'plone.app.testing',
             'plone.app.theming',
         ]
       ),


Repository: plone.app.upgrade
Branch: refs/heads/master
Date: 2014-12-11T13:26:23+01:00
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/plone.app.upgrade/commit/f89ec3961373c568f79ede8d07b212a8f724e027

removed all tests for migrations older than 4.3 -> 5.0

Files changed:
M CHANGES.rst
M setup.py
D plone/app/upgrade/v25/tests.py
D plone/app/upgrade/v30/tests.py
D plone/app/upgrade/v31/tests.py
D plone/app/upgrade/v32/tests.py
D plone/app/upgrade/v33/tests.py
D plone/app/upgrade/v40/tests.py
D plone/app/upgrade/v41/tests.py
D plone/app/upgrade/v42/tests.py

diff --git a/CHANGES.rst b/CHANGES.rst
index 66d69fd..f6874cf 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,12 +1,17 @@
 Changelog
 =========
 
-1.3.9 (unreleased)
+2.0 (unreleased)
 ------------------
 
 - Add upgrade steps for markup control panel.
   [thet]
 
+- Ported tests to plone.app.testing
+  [tomgross]
+
+- Removed all tests for migrations older than 4.3 -> 5.0
+  [tomgross]
 
 1.3.8 (2014-11-01)
 ------------------
diff --git a/plone/app/upgrade/v25/tests.py b/plone/app/upgrade/v25/tests.py
deleted file mode 100644
index 036e8b5..0000000
--- a/plone/app/upgrade/v25/tests.py
+++ /dev/null
@@ -1,124 +0,0 @@
-from Products.CMFPlone.UnicodeSplitter import Splitter
-from Products.CMFPlone.UnicodeSplitter import CaseNormalizer
-
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.utils import loadMigrationProfile
-
-from plone.app.upgrade.v25 import fixupPloneLexicon
-from plone.app.upgrade.v25 import setLoginFormInCookieAuth
-from plone.app.upgrade.v25 import addMissingMimeTypes
-
-
-class TestMigrations_v2_5_0(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v25:2.5final-2.5.1'
-        self.actions = self.portal.portal_actions
-        self.css = self.portal.portal_css
-
-    def tesFixObjDeleteAction(self):
-        # Prepare delete actions test
-        editActions = ('delete',)
-        for a in editActions:
-            self.removeActionFromTool(a, category='object_buttons')
-        loadMigrationProfile(self.portal, self.profile, ('actions', ))
-        # delete action tests
-        actions = [x.id for x in self.actions.object_buttons.listActions()
-                   if x.id in editActions]
-        # check that all of our deleted actions are now present
-        for a in editActions:
-            self.assertTrue(a in actions)
-        # ensure that they are present only once
-        self.assertEqual(len(editActions), len(actions))
-
-    def testFixupPloneLexicon(self):
-        # Should update the plone_lexicon pipeline
-        lexicon = self.portal.portal_catalog.plone_lexicon
-        lexicon._pipeline = (object(), object())
-        # Test it twice
-        for i in range(2):
-            fixupPloneLexicon(self.portal)
-            self.assertTrue(isinstance(lexicon._pipeline[0], Splitter))
-            self.assertTrue(isinstance(lexicon._pipeline[1], CaseNormalizer))
-
-
-class TestMigrations_v2_5_1(MigrationTest):
-
-    def afterSetUp(self):
-        self.actions = self.portal.portal_actions
-        self.memberdata = self.portal.portal_memberdata
-        self.catalog = self.portal.portal_catalog
-        self.skins = self.portal.portal_skins
-        self.types = self.portal.portal_types
-        self.workflow = self.portal.portal_workflow
-        self.css = self.portal.portal_css
-
-    def testSetLoginFormInCookieAuth(self):
-        setLoginFormInCookieAuth(self.portal)
-        cookie_auth = self.portal.acl_users.credentials_cookie_auth
-        self.assertEqual(cookie_auth.getProperty('login_path'),
-                             'require_login')
-
-    def testSetLoginFormNoCookieAuth(self):
-        # Shouldn't error
-        uf = self.portal.acl_users
-        uf._delOb('credentials_cookie_auth')
-        setLoginFormInCookieAuth(self.portal)
-
-    def testSetLoginFormAlreadyChanged(self):
-        # Shouldn't change the value if it's not the default
-        cookie_auth = self.portal.acl_users.credentials_cookie_auth
-        cookie_auth.manage_changeProperties(login_path='foo')
-        setLoginFormInCookieAuth(self.portal)
-        self.assertTrue(cookie_auth.getProperty('login_path') != 'require_login')
-
-class TestMigrations_v2_5_2(MigrationTest):
-
-    def afterSetUp(self):
-        self.mimetypes = self.portal.mimetypes_registry
-
-    def testMissingMimeTypes(self):
-        # we're testing for 'text/x-web-markdown' and 'text/x-web-textile'
-        missing_types = ['text/x-web-markdown', 'text/x-web-textile']
-        # since we're running a full 2.5.4 instance in this test, the missing
-        # types might in fact already be there:
-        current_types = self.mimetypes.list_mimetypes()
-        types_to_delete = []
-        for mtype in missing_types:
-            if mtype in current_types:
-                types_to_delete.append(mtype)
-        if types_to_delete:
-            self.mimetypes.manage_delObjects(types_to_delete)
-        # now they're gone:
-        self.assertFalse(set(self.mimetypes.list_mimetypes()).issuperset(set(missing_types)))
-        addMissingMimeTypes(self.portal)
-        # now they're back:
-        self.assertTrue(set(self.mimetypes.list_mimetypes()).issuperset(set(missing_types)))
-
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testDCMIStorageUpdated(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        dcmi = getattr(oldsite.portal_metadata, 'DCMI', None)
-        self.assertFalse(dcmi is None)
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v2_5_0))
-    suite.addTest(makeSuite(TestMigrations_v2_5_1))
-    suite.addTest(makeSuite(TestMigrations_v2_5_2))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v30/tests.py b/plone/app/upgrade/v30/tests.py
deleted file mode 100644
index 9325d0d..0000000
--- a/plone/app/upgrade/v30/tests.py
+++ /dev/null
@@ -1,1109 +0,0 @@
-from Acquisition import aq_base
-
-from five.localsitemanager.registry import FiveVerifyingAdapterLookup
-
-from plone.contentrules.engine.interfaces import IRuleStorage
-from plone.app.i18n.locales.interfaces import IContentLanguages
-from plone.app.i18n.locales.interfaces import ICountries
-from plone.app.i18n.locales.interfaces import IMetadataLanguages
-from plone.app.portlets import portlets
-from plone.app.redirector.interfaces import IRedirectionStorage
-from plone.portlets.interfaces import IPortletManager
-from plone.portlets.interfaces import IPortletAssignmentMapping
-from plone.portlets.interfaces import ILocalPortletAssignmentManager
-from plone.portlets.constants import CONTEXT_CATEGORY as CONTEXT_PORTLETS
-
-from zope.location.interfaces import ISite
-from zope.component import getGlobalSiteManager
-from zope.component import getSiteManager
-from zope.component import getUtility, getMultiAdapter
-from zope.component.hooks import clearSite
-
-from Products.Archetypes.interfaces import IArchetypeTool
-from Products.Archetypes.interfaces import IReferenceCatalog
-from Products.Archetypes.interfaces import IUIDCatalog
-from Products.CMFActionIcons.interfaces import IActionIconsTool
-from Products.CMFCalendar.interfaces import ICalendarTool
-from Products.CMFCore.ActionInformation import Action
-from Products.CMFCore.ActionInformation import ActionCategory
-from Products.CMFCore.utils import getToolByName
-from Products.CMFCore.utils import getToolInterface
-from Products.CMFCore.Expression import Expression
-from Products.CMFCore.permissions import AccessInactivePortalContent
-from Products.CMFCore.interfaces import IActionsTool
-from Products.CMFCore.interfaces import ICachingPolicyManager
-from Products.CMFCore.interfaces import ICatalogTool
-from Products.CMFCore.interfaces import IContentTypeRegistry
-from Products.CMFCore.interfaces import IDiscussionTool
-from Products.CMFCore.interfaces import IMemberDataTool
-from Products.CMFCore.interfaces import IMembershipTool
-from Products.CMFCore.interfaces import IMetadataTool
-from Products.CMFCore.interfaces import IPropertiesTool
-from Products.CMFCore.interfaces import IRegistrationTool
-from Products.CMFCore.interfaces import ISiteRoot
-from Products.CMFCore.interfaces import ISkinsTool
-from Products.CMFCore.interfaces import ISyndicationTool
-from Products.CMFCore.interfaces import ITypesTool
-from Products.CMFCore.interfaces import IURLTool
-from Products.CMFCore.interfaces import IConfigurableWorkflowTool
-from Products.CMFCore.ActionInformation import ActionInformation
-from Products.CMFDiffTool.interfaces import IDiffTool
-from Products.CMFEditions.interfaces import IArchivistTool
-from Products.CMFEditions.interfaces import IPortalModifierTool
-from Products.CMFEditions.interfaces import IPurgePolicyTool
-from Products.CMFEditions.interfaces.IRepository import IRepositoryTool
-from Products.CMFEditions.interfaces import IStorageTool
-from Products.CMFFormController.interfaces import IFormControllerTool
-from Products.CMFQuickInstallerTool.interfaces import IQuickInstallerTool
-from Products.CMFPlone.interfaces import IPloneSiteRoot
-from Products.CMFPlone.interfaces import IPloneTool
-from Products.CMFPlone.interfaces import ITranslationServiceTool
-from Products.CMFUid.interfaces import IUniqueIdAnnotationManagement
-from Products.CMFUid.interfaces import IUniqueIdGenerator
-from Products.CMFUid.interfaces import IUniqueIdHandler
-from Products.GenericSetup.interfaces import ISetupTool
-from Products.MailHost.interfaces import IMailHost
-from Products.MimetypesRegistry.interfaces import IMimetypesRegistryTool
-from Products.PortalTransforms.interfaces import IPortalTransformsTool
-from Products.PloneLanguageTool.interfaces import ILanguageTool
-from Products.PlonePAS.interfaces.group import IGroupTool
-from Products.PlonePAS.interfaces.group import IGroupDataTool
-from Products.ResourceRegistries.interfaces import ICSSRegistry
-from Products.ResourceRegistries.interfaces import IJSRegistry
-
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.utils import loadMigrationProfile
-
-from plone.app.upgrade.v30.alphas import enableZope3Site
-from plone.app.upgrade.v30.alphas import migrateOldActions
-from plone.app.upgrade.v30.alphas import updateActionsI18NDomain
-from plone.app.upgrade.v30.alphas import updateFTII18NDomain
-from plone.app.upgrade.v30.alphas import convertLegacyPortlets
-from plone.app.upgrade.v30.alphas import registerToolsAsUtilities
-from plone.app.upgrade.v30.alphas import registration
-from plone.app.upgrade.v30.alphas import addReaderAndEditorRoles
-from plone.app.upgrade.v30.alphas import migrateLocalroleForm
-from plone.app.upgrade.v30.alphas import reorderUserActions
-from plone.app.upgrade.v30.alphas import updatePASPlugins
-from plone.app.upgrade.v30.alphas import updateConfigletTitles
-from plone.app.upgrade.v30.alphas import addCacheForResourceRegistry
-from plone.app.upgrade.v30.alphas import removeTablelessSkin
-from plone.app.upgrade.v30.alphas import addObjectProvidesIndex
-from plone.app.upgrade.v30.alphas import restorePloneTool
-from plone.app.upgrade.v30.alphas import installProduct
-
-from plone.app.upgrade.v30.betas import migrateHistoryTab
-from plone.app.upgrade.v30.betas import changeOrderOfActionProviders
-from plone.app.upgrade.v30.betas import cleanupOldActions
-from plone.app.upgrade.v30.betas import cleanDefaultCharset
-from plone.app.upgrade.v30.betas import addAutoGroupToPAS
-from plone.app.upgrade.v30.betas import removeS5Actions
-from plone.app.upgrade.v30.betas import addContributorToCreationPermissions
-from plone.app.upgrade.v30.betas import removeSharingAction
-from plone.app.upgrade.v30.betas import addEditorToSecondaryEditorPermissions
-from plone.app.upgrade.v30.betas import updateEditActionConditionForLocking
-from plone.app.upgrade.v30.betas import addOnFormUnloadJS
-
-from plone.app.upgrade.v30.betas import updateTopicTitle
-from plone.app.upgrade.v30.betas import cleanupActionProviders
-from plone.app.upgrade.v30.betas import hidePropertiesAction
-
-from plone.app.upgrade.v30.rcs import addIntelligentText
-
-from plone.app.upgrade.v30.final_three0x import installNewModifiers
-
-try:
-    from Products.ATContentTypes.interface import IATCTTool
-    HAS_ATCT = True
-except ImportError:
-    HAS_ATCT = False
-
-try:
-    from Products.CMFPlone.interfaces import IFactoryTool
-except:
-    from Products.ATContentTypes.interfaces import IFactoryTool
-
-
-class TestMigrations_v3_0_Actions(MigrationTest):
-
-    def afterSetUp(self):
-        self.actions = self.portal.portal_actions
-        self.types = self.portal.portal_types
-        self.workflow = self.portal.portal_workflow
-        self._migrate_reply_action()
-
-    def _migrate_reply_action(self):
-        # Create dummy old ActionInformation
-        reply = ActionInformation('reply',
-            title='Reply',
-            category='reply_actions',
-            condition='context/replyAllowed',
-            permissions=(AccessInactivePortalContent, ),
-            priority=10,
-            visible=True,
-            action='context/reply'
-        )
-
-        from OFS.SimpleItem import SimpleItem
-        class DummyTool(SimpleItem):
-            pass
-        dummy = DummyTool()
-        dummy._actions = (reply,)
-        self.portal._setObject('dummy', dummy)
-
-    def testMigrateActions(self):
-        # Test it twice
-        for i in range(2):
-            migrateOldActions(self.portal)
-            reply_actions = getattr(self.actions, 'reply_actions', None)
-            self.assertFalse(reply_actions is None)
-            reply = getattr(reply_actions, 'reply', None)
-            self.assertFalse(reply is None)
-            self.assertTrue(isinstance(reply, Action))
-            # Verify all data has been upgraded correctly to the new Action
-            data = reply.getInfoData()[0]
-            self.assertEqual(data['category'], 'reply_actions')
-            self.assertEqual(data['title'], 'Reply')
-            self.assertEqual(data['visible'], True)
-            self.assertEqual(data['permissions'], (AccessInactivePortalContent, ))
-            self.assertEqual(data['available'].text, 'context/replyAllowed')
-            self.assertEqual(data['url'].text, 'context/reply')
-            # Make sure the original action has been removed
-            self.assertEqual(len(self.portal.dummy._actions), 0)
-
-    def testUpdateActionsI18NDomain(self):
-        migrateOldActions(self.portal)
-        reply = self.actions.reply_actions.reply
-        self.assertEqual(reply.i18n_domain, '')
-        # Test it twice
-        for i in range(2):
-            updateActionsI18NDomain(self.portal)
-            self.assertEqual(reply.i18n_domain, 'plone')
-
-    def testUpdateActionsI18NDomainNonAscii(self):
-        migrateOldActions(self.portal)
-        reply = self.actions.reply_actions.reply
-        reply.title = 'Foo\xc3'
-        self.assertEqual(reply.i18n_domain, '')
-        self.assertEqual(reply.title, 'Foo\xc3')
-
-        updateActionsI18NDomain(self.portal)
-
-        self.assertEqual(reply.i18n_domain, '')
-
-    def testHistoryActionID(self):
-        # Test it twice
-        for i in range(2):
-            migrateHistoryTab(self.portal)
-            objects = getattr(self.actions, 'object', None)
-            self.assertFalse('rss' in objects.objectIds())
-
-    def testProviderCleanup(self):
-        self.actions.addActionProvider("portal_membership")
-        self.assertTrue("portal_membership" in self.actions.listActionProviders())
-        # Test it twice
-        for i in range(2):
-            cleanupActionProviders(self.portal)
-            self.assertFalse("portal_membership" in self.actions.listActionProviders())
-
-    def testRemovePropertiesActions(self):
-        ti = self.types.getTypeInfo("Document")
-        if ti.getActionObject("object/properties") is None:
-            ti.addAction("metadata", "name", "action", "condition",
-                    "permission", "object",)
-        # Test it twice
-        for i in range(2):
-            hidePropertiesAction(self.portal)
-            self.assertTrue(ti.getActionObject("object/metadata") is None)
-
-    def tearDown(self):
-        self.portal._delObject('dummy')
-
-
-class TestMigrations_v2_5_x(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v30:2.5.x-3.0a1'
-        self.types = self.portal.portal_types
-        self.properties = self.portal.portal_properties
-
-        for legacy_tool in ('portal_discussion', 'portal_actionicons'):
-            if legacy_tool not in self.portal:
-                from OFS.SimpleItem import SimpleItem
-                self.portal._setObject(legacy_tool, SimpleItem())
-
-    def disableSite(self, obj, iface=ISite):
-        # We need our own disableSite method as the CMF portal implements
-        # ISite directly, so we cannot remove it, like the disableSite method
-        # in Five.component would have done
-        from ZPublisher.BeforeTraverse import unregisterBeforeTraverse
-        from Products.Five.component import HOOK_NAME
-        obj = aq_base(obj)
-        if not iface.providedBy(obj):
-            raise TypeError('Object must be a site.')
-        unregisterBeforeTraverse(obj, HOOK_NAME)
-        if hasattr(obj, HOOK_NAME):
-            delattr(obj, HOOK_NAME)
-
-    def testEnableZope3Site(self):
-        # First we remove the site and site manager
-        self.disableSite(self.portal)
-        clearSite(self.portal)
-        self.portal.setSiteManager(None)
-        gsm = getGlobalSiteManager()
-        # Test it twice
-        for i in range(2):
-            enableZope3Site(self.portal)
-            # And see if we have an ISite with a local site manager
-            self.assertTrue(ISite.providedBy(self.portal))
-            sm = getSiteManager(self.portal)
-            self.assertFalse(gsm is sm)
-            lc = sm.utilities.LookupClass
-            self.assertEqual(lc, FiveVerifyingAdapterLookup)
-
-        # Test the lookupclass migration
-        sm.utilities.LookupClass = None
-        # Test it twice
-        for i in range(2):
-            enableZope3Site(self.portal)
-            self.assertEqual(sm.utilities.LookupClass, FiveVerifyingAdapterLookup)
-            self.assertEqual(sm.utilities.__parent__, sm)
-            self.assertEqual(sm.__parent__, self.portal)
-
-    def testUpdateFTII18NDomain(self):
-        doc = self.types.Document
-        doc.i18n_domain = ''
-        # Test it twice
-        for i in range(2):
-            updateFTII18NDomain(self.portal)
-            self.assertEqual(doc.i18n_domain, 'plone')
-
-    def testUpdateFTII18NDomainNonAscii(self):
-        doc = self.types.Document
-        doc.i18n_domain = ''
-        doc.title = 'Foo\xc3'
-        # Update FTI's
-        updateFTII18NDomain(self.portal)
-        # domain should have been updated
-        self.assertEqual(doc.i18n_domain, '')
-
-    def testAddDefaultAndForbiddenContentTypesProperties(self):
-        # Should add the forbidden_contenttypes and default_contenttype property
-        self.removeSiteProperty('forbidden_contenttypes')
-        self.removeSiteProperty('default_contenttype')
-        self.assertFalse(self.properties.site_properties.hasProperty('forbidden_contenttypes'))
-        self.assertFalse(self.properties.site_properties.hasProperty('default_contenttype'))
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('propertiestool', ))
-            self.assertTrue(self.properties.site_properties.hasProperty('forbidden_contenttypes'))
-            self.assertTrue(self.properties.site_properties.hasProperty('default_contenttype'))
-            self.assertEqual(self.properties.site_properties.forbidden_contenttypes,
-                ('text/structured', 'text/restructured', 'text/x-rst',
-                'text/plain', 'text/plain-pre', 'text/x-python',
-                'text/x-web-markdown', 'text/x-web-intelligent', 'text/x-web-textile')
-            )
-
-    def testTablelessRemoval(self):
-        st = getToolByName(self.portal, "portal_skins")
-        if "Plone Tableless" not in st.getSkinSelections():
-            st.addSkinSelection('Plone Tableless', 'one,two', make_default=True)
-        # Test it twice
-        for i in range(2):
-            removeTablelessSkin(self.portal)
-            self.assertFalse('Plone Tableless' in st.getSkinSelections())
-            self.assertFalse(st.default_skin == 'Plone Tableless')
-
-    def testLegacyPortletsConverted(self):
-        self.setRoles(('Manager',))
-        leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
-        rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        for k in left:
-            del left[k]
-        for k in right:
-            del right[k]
-
-        self.portal.left_slots = ['here/portlet_recent/macros/portlet',
-                                  'here/portlet_news/macros/portlet',
-                                  'here/portlet_related/macros/portlet']
-        self.portal.right_slots = ['here/portlet_login/macros/portlet',
-                                   'here/portlet_languages/macros/portlet']
-
-        self.portal.Members.right_slots = []
-
-        # Test it twice
-        for i in range(2):
-            convertLegacyPortlets(self.portal)
-
-            self.assertEqual(self.portal.left_slots, [])
-            self.assertEqual(self.portal.right_slots, [])
-
-            left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-            right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-            lp = left.values()
-            self.assertEqual(2, len(lp))
-
-            self.assertTrue(isinstance(lp[0], portlets.recent.Assignment))
-            self.assertTrue(isinstance(lp[1], portlets.news.Assignment))
-
-            rp = right.values()
-            self.assertEqual(1, len(rp))
-            self.assertTrue(isinstance(rp[0], portlets.login.Assignment))
-
-            members = self.portal.Members
-            portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
-            self.assertEqual(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
-
-    def testLegacyPortletsConvertedNoSlots(self):
-        self.setRoles(('Manager',))
-        leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
-        rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        for k in left:
-            del left[k]
-        for k in right:
-            del right[k]
-
-        self.portal.left_slots = ['here/portlet_recent/macros/portlet',
-                                  'here/portlet_news/macros/portlet']
-
-        self.portal.Members.right_slots = []
-
-        if hasattr(self.portal.aq_base, 'right_slots'):
-            delattr(self.portal, 'right_slots')
-
-        convertLegacyPortlets(self.portal)
-
-        self.assertEqual(self.portal.left_slots, [])
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        lp = left.values()
-        self.assertEqual(2, len(lp))
-
-        self.assertTrue(isinstance(lp[0], portlets.recent.Assignment))
-        self.assertTrue(isinstance(lp[1], portlets.news.Assignment))
-
-        rp = right.values()
-        self.assertEqual(0, len(rp))
-
-        members = self.portal.Members
-        portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
-        self.assertEqual(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
-
-    def testLegacyPortletsConvertedBadSlots(self):
-        self.setRoles(('Manager',))
-        leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
-        rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        for k in left:
-            del left[k]
-        for k in right:
-            del right[k]
-
-        self.portal.left_slots = ['here/portlet_recent/macros/portlet',
-                                  'here/portlet_news/macros/portlet',
-                                  'foobar',]
-        self.portal.right_slots = ['here/portlet_login/macros/portlet']
-
-        self.portal.Members.right_slots = []
-
-        convertLegacyPortlets(self.portal)
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        self.assertEqual(self.portal.left_slots, [])
-        self.assertEqual(self.portal.right_slots, [])
-
-        lp = left.values()
-        self.assertEqual(2, len(lp))
-
-        self.assertTrue(isinstance(lp[0], portlets.recent.Assignment))
-        self.assertTrue(isinstance(lp[1], portlets.news.Assignment))
-
-        rp = right.values()
-        self.assertEqual(1, len(rp))
-        self.assertTrue(isinstance(rp[0], portlets.login.Assignment))
-
-        members = self.portal.Members
-        portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
-        self.assertEqual(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
-
-    def testLegacyPortletsConvertedNoMembersFolder(self):
-        self.setRoles(('Manager',))
-        leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
-        rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        for k in left:
-            del left[k]
-        for k in right:
-            del right[k]
-
-        self.portal.left_slots = ['here/portlet_recent/macros/portlet',
-                                  'here/portlet_news/macros/portlet',
-                                  'foobar',]
-        self.portal.right_slots = ['here/portlet_login/macros/portlet']
-
-        self.portal._delObject('Members')
-
-        convertLegacyPortlets(self.portal)
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        self.assertEqual(self.portal.left_slots, [])
-        self.assertEqual(self.portal.right_slots, [])
-
-        lp = left.values()
-        self.assertEqual(2, len(lp))
-
-        self.assertTrue(isinstance(lp[0], portlets.recent.Assignment))
-        self.assertTrue(isinstance(lp[1], portlets.news.Assignment))
-
-        rp = right.values()
-        self.assertEqual(1, len(rp))
-        self.assertTrue(isinstance(rp[0], portlets.login.Assignment))
-
-    def testRegisterToolsAsUtilities(self):
-        sm = getSiteManager(self.portal)
-        interfaces = (ISiteRoot, IPloneSiteRoot,
-                      IActionIconsTool, ISyndicationTool,
-                      IMetadataTool, IPropertiesTool, IMailHost,
-                      IUniqueIdAnnotationManagement, IUniqueIdGenerator,
-                      IDiffTool, IMimetypesRegistryTool,
-                      IPortalTransformsTool, IDiscussionTool, )
-        if HAS_ATCT:
-            interfaces += (IATCTTool,)
-        for i in interfaces:
-            sm.unregisterUtility(provided=i)
-        registerToolsAsUtilities(self.portal)
-        for i in interfaces:
-            self.assertFalse(sm.queryUtility(i) is None)
-
-        for i in interfaces:
-            sm.unregisterUtility(provided=i)
-        registerToolsAsUtilities(self.portal)
-        registerToolsAsUtilities(self.portal)
-        for i in interfaces:
-            self.assertFalse(sm.queryUtility(i) is None)
-
-    def testDontRegisterToolsAsUtilities(self):
-        sm = getSiteManager(self.portal)
-        interfaces = (ILanguageTool, IArchivistTool, IPortalModifierTool,
-                      IPurgePolicyTool, IRepositoryTool, IStorageTool,
-                      IFormControllerTool, IReferenceCatalog, IUIDCatalog,
-                      ICalendarTool, IActionsTool, ICatalogTool,
-                      IContentTypeRegistry, ISkinsTool, ITypesTool, IURLTool,
-                      IConfigurableWorkflowTool, IPloneTool, ICSSRegistry,
-                      IJSRegistry, IUniqueIdHandler, IFactoryTool,
-                      IMembershipTool, IGroupTool, IGroupDataTool,
-                      IMemberDataTool, IArchetypeTool, ICachingPolicyManager,
-                      IRegistrationTool, ITranslationServiceTool,
-                      ISetupTool, IQuickInstallerTool,
-                     )
-        for i in interfaces:
-            sm.unregisterUtility(provided=i)
-        registerToolsAsUtilities(self.portal)
-        for i in interfaces:
-            self.assertTrue(sm.queryUtility(i) is None)
-
-        for i in interfaces:
-            sm.unregisterUtility(provided=i)
-        registerToolsAsUtilities(self.portal)
-        registerToolsAsUtilities(self.portal)
-        for i in interfaces:
-            self.assertTrue(sm.queryUtility(i) is None)
-
-    def testToolRegistration(self):
-        for (tool_id, interface) in registration:
-            self.assertEqual(getToolInterface(tool_id), interface)
-
-
-class TestMigrations_v3_0_alpha1(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v30:3.0a1-3.0a2'
-        self.actions = self.portal.portal_actions
-
-    def testInstallRedirectorUtility(self):
-        sm = getSiteManager(self.portal)
-        sm.unregisterUtility(provided=IRedirectionStorage)
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('componentregistry', ))
-            self.assertFalse(sm.queryUtility(IRedirectionStorage) is None)
-
-    def testAddReaderEditorRoles(self):
-        self.portal._delRoles(['Reader', 'Editor'])
-        # Test it twice
-        for i in range(2):
-            addReaderAndEditorRoles(self.portal)
-            self.assertTrue('Reader' in self.portal.valid_roles())
-            self.assertTrue('Editor' in self.portal.valid_roles())
-            self.assertTrue('Reader' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            self.assertTrue('Editor' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            self.assertTrue('View' in [r['name'] for r in self.portal.permissionsOfRole('Reader') if r['selected']])
-            self.assertTrue('Modify portal content' in [r['name'] for r in self.portal.permissionsOfRole('Editor') if r['selected']])
-
-    def testAddReaderEditorRolesPermissionOnly(self):
-        self.portal.manage_permission('View', [], True)
-        self.portal.manage_permission('Modify portal content', [], True)
-        # Test it twice
-        for i in range(2):
-            addReaderAndEditorRoles(self.portal)
-            self.assertTrue('Reader' in self.portal.valid_roles())
-            self.assertTrue('Editor' in self.portal.valid_roles())
-            self.assertTrue('Reader' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            self.assertTrue('Editor' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            self.assertTrue('View' in [r['name'] for r in self.portal.permissionsOfRole('Reader') if r['selected']])
-            self.assertTrue('Modify portal content' in [r['name'] for r in self.portal.permissionsOfRole('Editor') if r['selected']])
-
-    def testMigrateLocalroleForm(self):
-        fti = self.portal.portal_types['Document']
-        aliases = fti.getMethodAliases()
-        aliases['sharing'] = 'folder_localrole_form'
-        fti.setMethodAliases(aliases)
-        fti.addAction('test', 'Test', 'string:${object_url}/folder_localrole_form', None, 'View', 'object')
-        # Test it twice
-        for i in range(2):
-            migrateLocalroleForm(self.portal)
-            self.assertEqual('@@sharing', fti.getMethodAliases()['sharing'])
-            test_action = fti.listActions()[-1]
-            self.assertEqual('string:${object_url}/@@sharing', test_action.getActionExpression())
-
-    def testReorderUserActions(self):
-        self.actions.user.moveObjectsToTop(['logout', 'undo', 'join'])
-        # Test it twice
-        for i in range(2):
-            reorderUserActions(self.portal)
-            # build a dict that has the position as the value to make it easier
-            # to compare postions in the ordered list of actions
-            n = 0
-            sort = {}
-            for action in self.actions.user.objectIds():
-                sort[action] = n
-                n += 1
-            self.assertTrue(sort['preferences'] < sort['undo'])
-            self.assertTrue(sort['undo'] < sort['logout'])
-            self.assertTrue(sort['login'] < sort['join'])
-
-    def testReorderUserActionsIncompleteActions(self):
-        self.actions.user.moveObjectsToTop(['logout', 'undo', 'join'])
-        self.actions.user._delObject('preferences')
-        # Test it twice
-        for i in range(2):
-            reorderUserActions(self.portal)
-            n = 0
-            sort = {}
-            for action in self.actions.user.objectIds():
-                sort[action] = n
-                n += 1
-            self.assertTrue(sort['undo'] < sort['logout'])
-            self.assertTrue(sort['login'] < sort['join'])
-
-
-class TestMigrations_v3_0_alpha2(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v30:3.0a2-3.0b1'
-        self.actions = self.portal.portal_actions
-        self.properties = self.portal.portal_properties
-        self.cp = self.portal.portal_controlpanel
-
-    def testAddVariousProperties(self):
-        PROPERTIES = ('enable_link_integrity_checks', 'enable_sitemap',
-                      'external_links_open_new_window', 'many_groups',
-                      'number_of_days_to_keep', 'webstats_js')
-        for prop in PROPERTIES:
-            self.removeSiteProperty(prop)
-        sheet = self.properties.site_properties
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('propertiestool', ))
-            for prop in PROPERTIES:
-                self.assertTrue(sheet.hasProperty(prop))
-
-    def testInstallContentrulesAndLanguageUtilities(self):
-        sm = getSiteManager()
-        INTERFACES = (IRuleStorage, ICountries, IContentLanguages,
-                      IMetadataLanguages)
-        for i in INTERFACES:
-            sm.unregisterUtility(provided=i)
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('componentregistry', ))
-            for i in INTERFACES:
-                self.assertFalse(sm.queryUtility(i) is None)
-
-    def testAddEmailCharsetProperty(self):
-        if self.portal.hasProperty('email_charset'):
-            self.portal.manage_delProperties(['email_charset'])
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('properties', ))
-            self.assertTrue(self.portal.hasProperty('email_charset'))
-            self.assertEqual(self.portal.getProperty('email_charset'), 'utf-8')
-
-    def testUpdateMemberSecurity(self):
-        pprop = getToolByName(self.portal, 'portal_properties')
-        self.assertEqual(
-                pprop.site_properties.getProperty('allowAnonymousViewAbout'),
-                False)
-
-        pmembership = getToolByName(self.portal, 'portal_membership')
-        self.assertEqual(pmembership.memberareaCreationFlag, False)
-        self.assertEqual(self.portal.getProperty('validate_email'), True)
-
-        app_roles = self.portal.rolesOfPermission(permission='Add portal member')
-        app_perms = self.portal.permission_settings(permission='Add portal member')
-        acquire_check = app_perms[0]['acquire']
-        reg_roles = []
-        for appperm in app_roles:
-            if appperm['selected'] == 'SELECTED':
-                reg_roles.append(appperm['name'])
-        self.assertTrue('Manager' in reg_roles)
-        self.assertTrue('Owner' in reg_roles)
-        self.assertEqual(acquire_check, '')
-
-    def testPASPluginInterfaces(self):
-        pas = self.portal.acl_users
-        from Products.PluggableAuthService.interfaces.plugins import IUserEnumerationPlugin
-        pas.plugins.deactivatePlugin(IUserEnumerationPlugin, 'mutable_properties')
-        updatePASPlugins(self.portal)
-
-        plugin = pas.mutable_properties
-        for intf_id in plugin.listInterfaces():
-            try:
-                intf = pas.plugins._getInterfaceFromName(intf_id)
-                self.assertTrue('mutable_properties' in pas.plugins.listPluginIds(intf))
-            except KeyError:
-                # Ignore unregistered interface types
-                pass
-
-    def testUpdateConfigletTitles(self):
-        collection = self.cp.getActionObject('Plone/portal_atct')
-        language = self.cp.getActionObject('Plone/PloneLanguageTool')
-        navigation = self.cp.getActionObject('Plone/NavigationSettings')
-        types = self.cp.getActionObject('Plone/TypesSettings')
-        users = self.cp.getActionObject('Plone/UsersGroups')
-        users2 = self.cp.getActionObject('Plone/UsersGroups2')
-        # test it twice
-        for i in range(2):
-            updateConfigletTitles(self.portal)
-            self.assertEqual(collection.title, 'Collection')
-            self.assertEqual(language.title, 'Language')
-            self.assertEqual(navigation.title, 'Navigation')
-            self.assertEqual(types.title, 'Types')
-            self.assertEqual(users.title, 'Users and Groups')
-            self.assertEqual(users2.title, 'Users and Groups')
-
-    def testAddCacheForResourceRegistry(self):
-        ram_cache_id = 'ResourceRegistryCache'
-        # first remove the cache manager and make sure it's removed
-        self.portal._delObject(ram_cache_id)
-        self.assertFalse(ram_cache_id in self.portal.objectIds())
-        cssreg = self.portal.portal_css
-        cssreg.ZCacheable_setEnabled(0)
-        cssreg.ZCacheable_setManagerId(None)
-        self.assertFalse(cssreg.ZCacheable_enabled())
-        self.assertTrue(cssreg.ZCacheable_getManagerId() is None)
-        jsreg = self.portal.portal_javascripts
-        jsreg.ZCacheable_setEnabled(0)
-        jsreg.ZCacheable_setManagerId(None)
-        self.assertFalse(jsreg.ZCacheable_enabled())
-        self.assertTrue(jsreg.ZCacheable_getManagerId() is None)
-        # Test it twice
-        for i in range(2):
-            addCacheForResourceRegistry(self.portal)
-            self.assertTrue(ram_cache_id in self.portal.objectIds())
-            self.assertTrue(cssreg.ZCacheable_enabled())
-            self.assertFalse(cssreg.ZCacheable_getManagerId() is None)
-            self.assertTrue(jsreg.ZCacheable_enabled())
-            self.assertFalse(jsreg.ZCacheable_getManagerId() is None)
-
-    def testObjectProvidesIndex(self):
-        catalog = getToolByName(self.portal, 'portal_catalog')
-        if 'object_provides' in catalog.indexes():
-            catalog.delIndex('object_provides')
-        self.assertFalse('object_provides' in catalog.indexes())
-        # Test it twice
-        for i in range(2):
-            addObjectProvidesIndex(self.portal)
-            self.assertTrue('object_provides' in catalog.indexes())
-
-    def testMigratePloneTool(self):
-        tool = self.portal.plone_utils
-        tool.meta_type = 'PlonePAS Utilities Tool'
-        # Test it twice
-        for i in range(2):
-            restorePloneTool(self.portal)
-            tool = self.portal.plone_utils
-            self.assertEqual('Plone Utility Tool', tool.meta_type)
-
-    def testInstallPloneLanguageTool(self):
-        super(self.portal.__class__, self.portal).manage_delObjects(
-            ['portal_languages'])
-        self.uninstallProduct('PloneLanguageTool')
-        qi = getToolByName(self.portal, "portal_quickinstaller")
-        # Test it twice
-        for i in range(2):
-            installProduct('PloneLanguageTool', self.portal)
-            self.assertTrue(qi.isProductInstalled('PloneLanguageTool'))
-            self.assertTrue('portal_languages' in self.portal.keys())
-
-
-class TestMigrations_v3_0(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v30:3.0b1-3.0b2'
-        self.actions = self.portal.portal_actions
-        self.skins = self.portal.portal_skins
-        self.types = self.portal.portal_types
-        self.workflow = self.portal.portal_workflow
-        self.properties = getToolByName(self.portal, 'portal_properties')
-
-    def testAddContentRulesAction(self):
-        self.portal.portal_actions.object._delObject('contentrules')
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('actions', ))
-            self.assertTrue('contentrules' in self.portal.portal_actions.object.objectIds())
-
-    def testChangeOrderOfActionProviders(self):
-        self.actions.deleteActionProvider('portal_types')
-        self.actions.addActionProvider('portal_types')
-        self.assertEqual(
-            self.actions.listActionProviders(),
-            ('portal_workflow', 'portal_actions', 'portal_types'))
-        # Test it twice
-        for i in range(2):
-            changeOrderOfActionProviders(self.portal)
-            self.assertEqual(
-                self.actions.listActionProviders(),
-                ('portal_workflow', 'portal_types', 'portal_actions'))
-
-    def testCleanupOldActions(self):
-        reply = Action('reply', title='Reply')
-        logged_in = Action('logged_in', title='Logged in')
-        change_ownership = Action('change_ownership', title='Change ownership')
-
-        object_ = self.actions.object
-        object_tabs = getattr(self.actions, 'object_tabs', None)
-        if object_tabs is None:
-            category = 'object_tabs'
-            self.actions._setObject(category, ActionCategory(id=category))
-            object_tabs = self.actions.object_tabs
-        if getattr(self.actions, 'global', None) is None:
-            category = 'global'
-            self.actions._setObject(category, ActionCategory(id=category))
-
-        if not 'reply' in object_.keys():
-            object_._setObject('reply', reply)
-        user = self.actions.user
-        if not 'logged_in' in user.keys():
-            user._setObject('logged_in', logged_in)
-        if not 'change_ownership' in object_tabs.keys():
-            object_tabs._setObject('change_ownership', change_ownership)
-        del object_tabs
-
-        # Test it twice
-        for i in range(2):
-            cleanupOldActions(self.portal)
-            self.assertFalse('reply' in object_.keys())
-            self.assertFalse('logged_in' in user.keys())
-            self.assertFalse('object_tabs' in self.actions.keys())
-            self.assertFalse('global' in self.actions.keys())
-
-    def testCharsetCleanup(self):
-        if not self.portal.hasProperty('default_charset'):
-            self.portal.manage_addProperty('default_charset', '', 'string')
-        # Test it twice
-        for i in range(2):
-            self.portal.manage_changeProperties(default_charset = 'latin1')
-            cleanDefaultCharset(self.portal)
-            self.assertEqual(self.portal.getProperty('default_charset', 'nothere'),
-                    'latin1')
-        # Test it twice
-        for i in range(2):
-            self.portal.manage_changeProperties(default_charset = '')
-            cleanDefaultCharset(self.portal)
-            self.assertEqual(self.portal.getProperty('default_charset', 'nothere'),
-                    'nothere')
-
-    def testAutoGroupCreated(self):
-        pas = self.portal.acl_users
-        ids = pas.objectIds(['Automatic Group Plugin'])
-        if ids:
-            pas.manage_delObjects(ids)
-        addAutoGroupToPAS(self.portal)
-        self.assertEqual(pas.objectIds(['Automatic Group Plugin']),
-                ['auto_group'])
-        plugin = pas.auto_group
-        interfaces = [info['interface'] for info in pas.plugins.listPluginTypeInfo()]
-        for iface in interfaces:
-            if plugin.testImplements(iface):
-                self.assertFalse('auto_group' not in pas.plugins.listPluginIds(iface))
-        self.assertEqual(len(pas.searchGroups(id='AuthenticatedUsers',
-                                              exact_match=True)), 1)
-
-    def testPloneS5(self):
-        pt = getToolByName(self.portal, "portal_types")
-        document = pt.restrictedTraverse('Document')
-        document.addAction('s5_presentation',
-            name='View as presentation',
-            action="string:${object/absolute_url}/document_s5_presentation",
-            condition='python:object.document_s5_alter(test=True)',
-            permission='View',
-            category='document_actions',
-            visible=1,
-            )
-        action_ids = [x.getId() for x in document.listActions()]
-        self.assertTrue("s5_presentation" in action_ids)
-        # Test it twice
-        for i in range(2):
-            removeS5Actions(self.portal)
-            action_ids = [x.getId() for x in document.listActions()]
-            self.assertFalse("s5_presentation" in action_ids)
-
-    def testAddContributorToCreationPermissions(self):
-        self.portal._delRoles(['Contributor',])
-        for p in ['Add portal content', 'Add portal folders', 'ATContentTypes: Add Document',
-                    'ATContentTypes: Add Event',
-                    'ATContentTypes: Add File', 'ATContentTypes: Add Folder',
-                    'ATContentTypes: Add Image', 'ATContentTypes: Add Link',
-                    'ATContentTypes: Add News Item', ]:
-            self.portal.manage_permission(p, ['Manager', 'Owner'], True)
-        # Test it twice
-        for i in range(2):
-            addContributorToCreationPermissions(self.portal)
-            self.assertTrue('Contributor' in self.portal.valid_roles())
-            self.assertTrue('Contributor' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            for p in ['Add portal content', 'Add portal folders', 'ATContentTypes: Add Document',
-                        'ATContentTypes: Add Event',
-                        'ATContentTypes: Add File', 'ATContentTypes: Add Folder',
-                        'ATContentTypes: Add Image', 'ATContentTypes: Add Link',
-                        'ATContentTypes: Add News Item', ]:
-                self.assertTrue(p in [r['name'] for r in
-                                    self.portal.permissionsOfRole('Contributor') if r['selected']])
-
-    def testAddContributerToCreationPermissionsNoStomp(self):
-        self.portal.manage_permission('Add portal content', ['Manager'], False)
-        # Test it twice
-        for i in range(2):
-            addContributorToCreationPermissions(self.portal)
-            roles = sorted([r['name'] for r in self.portal.rolesOfPermission('Add portal content') if r['selected']])
-            self.assertEqual(['Contributor', 'Manager'], roles)
-            self.assertEqual(False, bool(self.portal.acquiredRolesAreUsedBy('Add portal content')))
-
-    def testAddBeta2VersioningPermissionsToNewRoles(self):
-        # This upgrade just uses GS to apply the role changes,
-        # these permissions will not have been installed previously,
-        # so this should be safe
-        for p in ['CMFEditions: Apply version control',
-                  'CMFEditions: Save new version',
-                  'CMFEditions: Access previous versions',
-                  'CMFEditions: Revert to previous versions',
-                  'CMFEditions: Checkout to location']:
-            self.portal.manage_permission(p, ['Manager', 'Owner'], True)
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal,
-                    'profile-plone.app.upgrade.v30:3.0b1-3.0b2',
-                    steps=["rolemap"])
-            for p in ['CMFEditions: Apply version control',
-                      'CMFEditions: Save new version',
-                      'CMFEditions: Access previous versions']:
-                self.assertTrue(p in [r['name'] for r in
-                                    self.portal.permissionsOfRole('Contributor') if r['selected']])
-                self.assertTrue(p in [r['name'] for r in
-                                    self.portal.permissionsOfRole('Editor') if r['selected']])
-            for p in ['CMFEditions: Revert to previous versions',
-                      'CMFEditions: Checkout to location']:
-                self.assertTrue(p in [r['name'] for r in
-                                    self.portal.permissionsOfRole('Editor') if r['selected']])
-
-    def testRemoveSharingAction(self):
-        fti = self.types['Document']
-        fti.addAction(id='local_roles', name='Sharing',
-                      action='string:${object_url}/sharing',
-                      condition=None, permission='Manage properties',
-                      category='object')
-        # Test it twice
-        for i in range(2):
-            removeSharingAction(self.portal)
-            self.assertFalse('local_roles' in [a.id for a in fti.listActions()])
-
-    def testAddEditorToCreationPermissions(self):
-        for p in ['Manage properties', 'Modify view template', 'Request review']:
-            self.portal.manage_permission(p, ['Manager', 'Owner'], True)
-        # Test it twice
-        for i in range(2):
-            addEditorToSecondaryEditorPermissions(self.portal)
-            for p in ['Manage properties', 'Modify view template', 'Request review']:
-                self.assertTrue(p in [r['name'] for r in
-                    self.portal.permissionsOfRole('Editor') if r['selected']])
-
-    def testAddEditorToCreationPermissionsNoStomp(self):
-        self.portal.manage_permission('Manage properties', ['Manager'], False)
-        # Test it twice
-        for i in range(2):
-            addEditorToSecondaryEditorPermissions(self.portal)
-            roles = sorted([r['name'] for r in self.portal.rolesOfPermission('Manage properties') if r['selected']])
-            self.assertEqual(['Editor', 'Manager'], roles)
-            self.assertEqual(False, bool(self.portal.acquiredRolesAreUsedBy('Manage properties')))
-
-    def testUpdateEditActionConditionForLocking(self):
-        lockable_types = ['Document', 'Event', 'File', 'Folder',
-                          'Image', 'Link', 'News Item', 'Topic']
-        for contentType in lockable_types:
-            fti = self.types.getTypeInfo(contentType)
-            for action in fti.listActions():
-                if action.getId() == 'edit':
-                    action.condition = ''
-        # Test it twice
-        for i in range(2):
-            updateEditActionConditionForLocking(self.portal)
-            for contentType in lockable_types:
-                fti = self.types.getTypeInfo(contentType)
-                for action in fti.listActions():
-                    if action.getId() == 'edit':
-                        self.assertEqual(action.condition.text,
-                            "not:object/@@plone_lock_info/is_locked_for_current_user|python:True")
-
-    def testUpdateEditExistingActionConditionForLocking(self):
-        fti = self.types.getTypeInfo('Document')
-        for action in fti.listActions():
-            if action.getId() == 'edit':
-                action.condition = Expression("foo")
-        # Test it twice
-        for i in range(2):
-            updateEditActionConditionForLocking(self.portal)
-            fti = self.types.getTypeInfo('Document')
-            for action in fti.listActions():
-                if action.getId() == 'edit':
-                    self.assertEqual(action.condition.text, 'foo')
-
-    def testAddOnFormUnloadRegistrationJS(self):
-        jsreg = self.portal.portal_javascripts
-        # unregister first
-        jsreg.unregisterResource('unlockOnFormUnload.js')
-        script_ids = jsreg.getResourceIds()
-        self.assertFalse('unlockOnFormUnload.js' in script_ids)
-        # Test it twice
-        for i in range(2):
-            addOnFormUnloadJS(self.portal)
-            script_ids = jsreg.getResourceIds()
-            self.assertTrue('unlockOnFormUnload.js' in script_ids)
-
-    def testUpdateTopicTitle(self):
-        topic = self.types.get('Topic')
-        topic.title = 'Old'
-        # Test it twice
-        for i in range(2):
-            updateTopicTitle(self.portal)
-            self.assertEqual(topic.title, 'Collection')
-
-    def testAddIntelligentText(self):
-        # Before the upgrade, the mime type and transforms of intelligent text
-        # are not available. They *are* here in a fresh site, so we may need
-        # to remove them first for testing. First we remove the transforms,
-        # as they depend on the mimetype being there.
-        missing_transforms = ["web_intelligent_plain_text_to_html",
-                              "html_to_web_intelligent_plain_text"]
-        ptr = self.portal.portal_transforms
-        current_transforms = ptr.objectIds()
-        for trans in missing_transforms:
-            if trans in current_transforms:
-                ptr.unregisterTransform(trans)
-        # Then we remove the mime type
-        mime_type = 'text/x-web-intelligent'
-        mtr = self.portal.mimetypes_registry
-        current_types = mtr.list_mimetypes()
-        if mime_type in current_types:
-            mtr.manage_delObjects((mime_type,))
-        # now all are gone:
-        self.assertFalse(mime_type in mtr.list_mimetypes())
-        self.assertFalse(set(ptr.objectIds()).issuperset(set(missing_transforms)))
-        # Test it twice
-        for i in range(2):
-            addIntelligentText(self.portal)
-            # now all are back:
-            self.assertTrue(mime_type in mtr.list_mimetypes())
-            self.assertTrue(set(ptr.objectIds()).issuperset(set(missing_transforms)))
-
-    def testInstallNewModifiers(self):
-        # ensure the new modifiers are installed
-        modifiers = self.portal.portal_modifier
-        self.assertTrue('AbortVersioningOfLargeFilesAndImages' in
-                                                          modifiers.objectIds())
-        modifiers.manage_delObjects(['AbortVersioningOfLargeFilesAndImages',
-                                     'SkipVersioningOfLargeFilesAndImages'])
-        self.assertFalse('AbortVersioningOfLargeFilesAndImages' in
-                                                          modifiers.objectIds())
-        installNewModifiers(self.portal)
-        self.assertTrue('AbortVersioningOfLargeFilesAndImages' in
-                                                          modifiers.objectIds())
-        self.assertTrue('SkipVersioningOfLargeFilesAndImages' in
-                                                          modifiers.objectIds())
-
-    def testInstallNewModifiersTwice(self):
-        # ensure that we get no errors when run twice
-        installNewModifiers(self.portal)
-        installNewModifiers(self.portal)
-
-    def testInstallNewModifiersDoesNotStompChanges(self):
-        # ensure that reinstalling doesn't kill customizations
-        modifiers = self.portal.portal_modifier
-        modifiers.AbortVersioningOfLargeFilesAndImages.max_size = 1000
-        installNewModifiers(self.portal)
-        self.assertEqual(modifiers.AbortVersioningOfLargeFilesAndImages.max_size,
-                         1000)
-
-    def testInstallNewModifiersNoTool(self):
-        # make sure there are no errors if the tool is missing
-        self.portal._delObject('portal_modifier')
-        installNewModifiers(self.portal)
-
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testBaseUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFullUpgrade(self):
-        self.importFile(__file__, 'test-full.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v2_5_x))
-    suite.addTest(makeSuite(TestMigrations_v3_0_Actions))
-    suite.addTest(makeSuite(TestMigrations_v3_0_alpha1))
-    suite.addTest(makeSuite(TestMigrations_v3_0_alpha2))
-    suite.addTest(makeSuite(TestMigrations_v3_0))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v31/tests.py b/plone/app/upgrade/v31/tests.py
deleted file mode 100644
index 01005b3..0000000
--- a/plone/app/upgrade/v31/tests.py
+++ /dev/null
@@ -1,118 +0,0 @@
-from borg.localrole.utils import replace_local_role_manager
-from zope.interface import noLongerProvides
-
-from Products.PlonePAS.interfaces.plugins import ILocalRolesPlugin
-
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-
-from plone.app.upgrade.v31.betas import reinstallCMFPlacefulWorkflow
-
-
-class TestMigrations_v3_1(MigrationTest):
-
-    def afterSetUp(self):
-        self.qi = self.portal.portal_quickinstaller
-        self.wf = self.portal.portal_workflow
-        self.ps = self.portal.portal_setup
-
-    def testReinstallCMFPlacefulWorkflow(self):
-        try:
-            from Products.CMFPlacefulWorkflow.interfaces import IPlacefulMarker
-        except ImportError:
-            return
-        # first the product needs to be installed
-        self.qi.installProduct('CMFPlacefulWorkflow')
-        # Delete existing logs to prevent race condition
-        self.ps.manage_delObjects(self.ps.objectIds())
-        # We remove the new marker, to ensure it's added on reinstall
-        if IPlacefulMarker.providedBy(self.wf):
-            noLongerProvides(self.wf, IPlacefulMarker)
-        reinstallCMFPlacefulWorkflow(self.portal, [])
-        self.assertTrue(IPlacefulMarker.providedBy(self.wf))
-
-    def testReinstallCMFPlacefulWorkflowDoesNotInstall(self):
-        reinstallCMFPlacefulWorkflow(self.portal, [])
-        self.assertFalse(self.qi.isProductInstalled('CMFPlacefulWorkflow'))
-
-    def testReinstallCMFPlacefulWorkflowNoTool(self):
-        self.portal._delObject('portal_quickinstaller')
-        reinstallCMFPlacefulWorkflow(self.portal, [])
-
-    def testReplaceLocalRoleManager(self):
-        # first we replace the local role manager with the one from PlonePAS
-        uf = self.portal.acl_users
-        # deactivate and remove the borg plugin
-        uf.plugins.removePluginById('borg_localroles')
-        uf.manage_delObjects(['borg_localroles'])
-        # activate the standard plugin
-        uf.plugins.activatePlugin(ILocalRolesPlugin, 'local_roles')
-        # Bring things back to normal
-        replace_local_role_manager(self.portal)
-        plugins = uf.plugins.listPlugins(ILocalRolesPlugin)
-        self.assertEqual(len(plugins), 1)
-        self.assertEqual(plugins[0][0], 'borg_localroles')
-
-    def testReplaceLocalRoleManagerTwice(self):
-        # first we replace the local role manager with the one from PlonePAS
-        uf = self.portal.acl_users
-        # deactivate and remove the borg plugin
-        uf.plugins.removePluginById('borg_localroles')
-        uf.manage_delObjects(['borg_localroles'])
-        # activate the standard plugin
-        uf.plugins.activatePlugin(ILocalRolesPlugin, 'local_roles')
-        # run the upgrade twice
-        replace_local_role_manager(self.portal)
-        replace_local_role_manager(self.portal)
-        plugins = uf.plugins.listPlugins(ILocalRolesPlugin)
-        self.assertEqual(len(plugins), 1)
-        self.assertEqual(plugins[0][0], 'borg_localroles')
-
-    def testReplaceLocalRoleManagerNoPlugin(self):
-        # first we replace the local role manager with the one from PlonePAS
-        uf = self.portal.acl_users
-        # deactivate and remove the borg plugin
-        uf.plugins.removePluginById('borg_localroles')
-        uf.manage_delObjects(['borg_localroles'])
-        # delete the standard plugin
-        uf.manage_delObjects(['local_roles'])
-        # Run the upgrade, which shouldn't fail even if the expected
-        # plugin is missing
-        replace_local_role_manager(self.portal)
-        plugins = uf.plugins.listPlugins(ILocalRolesPlugin)
-        self.assertEqual(len(plugins), 1)
-        self.assertEqual(plugins[0][0], 'borg_localroles')
-
-    def testReplaceLocalRoleManagerNoPAS(self):
-        uf = self.portal.acl_users
-        # delete the plugin registry
-        uf._delObject('plugins')
-        replace_local_role_manager(self.portal)
-
-    def testReplaceLocalRoleManagerNoUF(self):
-        # Delete the user folder
-        replace_local_role_manager(self.portal)
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testBaseUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFullUpgrade(self):
-        self.importFile(__file__, 'test-full.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v3_1))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v32/tests.py b/plone/app/upgrade/v32/tests.py
deleted file mode 100644
index bc0e7a1..0000000
--- a/plone/app/upgrade/v32/tests.py
+++ /dev/null
@@ -1,50 +0,0 @@
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.v32.betas import three1_beta1
-
-class TestMigrations_v3_2(MigrationTest):
-
-    def afterSetUp(self):
-        self.qi = self.portal.portal_quickinstaller
-        self.actions = self.portal.portal_actions
-        self.migration = self.portal.portal_migration
-
-    def testIterateActionsMigratedIfIterateInstalled(self):
-        self.qi.installProduct('plone.app.iterate')
-        self.actions.object_buttons.iterate_checkin.permissions = (
-            'Modify portal content',)
-        three1_beta1(self.portal)
-        self.assertEqual(
-            self.actions.object_buttons.iterate_checkin.permissions,
-            ('iterate : Check in content',))
-
-    def testIterateInstalledButActionMissing(self):
-        self.qi.installProduct('plone.app.iterate')
-        self.actions.object_buttons.manage_delObjects(['iterate_checkin'])
-        three1_beta1(self.portal)
-        self.assertFalse('iterate_checkin' in
-                    self.actions.object_buttons.objectIds())
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testBaseUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFullUpgrade(self):
-        self.importFile(__file__, 'test-full.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v3_2))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v33/tests.py b/plone/app/upgrade/v33/tests.py
deleted file mode 100644
index 01a5de8..0000000
--- a/plone/app/upgrade/v33/tests.py
+++ /dev/null
@@ -1,93 +0,0 @@
-from Products.CMFCore.utils import getToolByName
-
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.v33 import three2_three3
-
-class TestMigrations_v3_3(MigrationTest):
-
-    def afterSetUp(self):
-        self.types = self.portal.portal_types
-        self.properties = getToolByName(self.portal, 'portal_properties')
-
-    def _upgrade(self):
-        three2_three3(self.portal)
-
-    def testRedirectLinksProperty(self):
-        del self.properties.site_properties.redirect_links
-        self._upgrade()
-        self.assertEqual(True,
-            self.properties.site_properties.getProperty('redirect_links'))
-
-    def testLinkDefaultView(self):
-        self.types.Link.default_view = 'link_view'
-        self.types.Link.immediate_view = 'link_view'
-        self.types.Link.view_methods = ('link_view',)
-        self._upgrade()
-        self.assertEqual(self.types.Link.default_view, 'link_redirect_view')
-        self.assertEqual(self.types.Link.immediate_view, 'link_redirect_view')
-        self.assertEqual(self.types.Link.view_methods, ('link_redirect_view',))
-
-    def testCustomizedLinkDefaultView(self):
-        # but only change if old default was 'link_view'
-        self.types.Link.default_view = 'foobar'
-        self.types.Link.immediate_view = 'foobar'
-        self.types.Link.view_methods = ('foobar',)
-        self._upgrade()
-        self.assertEqual(self.types.Link.default_view, 'foobar')
-        self.assertEqual(self.types.Link.immediate_view, 'foobar')
-        self.assertEqual(self.types.Link.view_methods, ('foobar',))
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testBaseUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFullUpgrade(self):
-        self.importFile(__file__, 'test-full.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFolderUpgrade(self):
-        from plone.folder.interfaces import IOrderableFolder
-        self.importFile(__file__, 'test-full.zexp')
-        # `portal_type` and `Type` can be checked before migration...
-        oldsite = getattr(self.app, self.site_id)
-        ids = 'news', 'events', 'Members'
-        for id in ids:
-            obj = oldsite[id]
-            self.assertEqual(obj.portal_type, 'Large Plone Folder')
-            self.assertEqual(obj.Type(), 'Large Folder')
-            brain, = oldsite.portal_catalog(getId=id)   # asserts only one
-            self.assertEqual(brain.portal_type, 'Large Plone Folder')
-            self.assertEqual(brain.Type, 'Large Folder')
-        # now let's migrate...
-        oldsite, result = self.migrate()
-        self.assertFalse(oldsite.portal_migration.needUpgrading())
-        # after migration `/news`, `/events` and `/Members` are based on
-        # `plone.(app.)folder`, but still have no ordering set...
-        for id in ids:
-            obj = oldsite[id]
-            self.assertTrue(IOrderableFolder.providedBy(obj),
-                '%s not orderable?' % id)
-            self.assertEqual(obj._ordering, 'unordered',
-                '%s has no `_ordering`?' % id)
-            self.assertEqual(obj.portal_type, 'Folder')
-            self.assertEqual(obj.Type(), 'Folder')
-            brain, = oldsite.portal_catalog(getId=id)   # asserts only one
-            self.assertEqual(brain.portal_type, 'Folder')
-            self.assertEqual(brain.Type, 'Folder')
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v3_3))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v40/tests.py b/plone/app/upgrade/v40/tests.py
deleted file mode 100644
index c350619..0000000
--- a/plone/app/upgrade/v40/tests.py
+++ /dev/null
@@ -1,666 +0,0 @@
-import time
-
-from zope.component import getMultiAdapter
-from zope.component import getSiteManager
-from zope.component import getUtility
-from zope.component import queryUtility
-from zope.ramcache.interfaces.ram import IRAMCache
-
-from Products.CMFCore.ActionInformation import Action
-from Products.CMFCore.Expression import Expression
-from Products.CMFCore.utils import getToolByName
-from Products.MailHost.interfaces import IMailHost
-
-from plone.app.upgrade.utils import loadMigrationProfile
-from plone.app.upgrade.v40.alphas import _KNOWN_ACTION_ICONS
-from plone.app.upgrade.v40.alphas import migrateActionIcons
-from plone.app.upgrade.v40.alphas import migrateTypeIcons
-from plone.app.upgrade.v40.alphas import addOrReplaceRamCache
-from plone.app.upgrade.v40.alphas import changeWorkflowActorVariableExpression
-from plone.app.upgrade.v40.alphas import changeAuthenticatedResourcesCondition
-from plone.app.upgrade.v40.alphas import setupReferencebrowser
-from plone.app.upgrade.v40.alphas import migrateMailHost
-from plone.app.upgrade.v40.alphas import migrateFolders
-from plone.app.upgrade.v40.alphas import renameJoinFormFields
-from plone.app.upgrade.v40.alphas import updateLargeFolderType
-from plone.app.upgrade.v40.alphas import addRecursiveGroupsPlugin
-from plone.app.upgrade.v40.alphas import cleanUpClassicThemeResources
-from plone.app.upgrade.v40.alphas import migrateStaticTextPortlets
-from plone.app.upgrade.v40.betas import repositionRecursiveGroupsPlugin
-from plone.app.upgrade.v40.betas import updateIconMetadata
-from plone.app.upgrade.v40.betas import removeLargePloneFolder
-from plone.app.upgrade.tests.base import MigrationTest
-
-from plone.portlet.static import static
-from plone.portlets.interfaces import IPortletAssignmentMapping
-from plone.portlets.interfaces import IPortletAssignmentSettings
-from plone.portlets.interfaces import IPortletManager
-
-
-class FakeSecureMailHost(object):
-
-    meta_type = 'Secure Mail Host'
-    id = 'MailHost'
-    title = 'Fake MailHost'
-    smtp_host = 'smtp.example.com'
-    smtp_port = 587
-    smtp_userid='me'
-    smtp_pass='secret'
-    smtp_notls=False
-
-    def manage_fixupOwnershipAfterAdd(self):
-        pass
-
-
-class TestMigrations_v4_0alpha1(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:3-4alpha1"
-
-    def afterSetUp(self):
-        self.atool = getToolByName(self.portal, 'portal_actions')
-        self.cptool = getToolByName(self.portal, 'portal_controlpanel')
-        self.wftool = getToolByName(self.portal, 'portal_workflow')
-        self.csstool = getToolByName(self.portal, 'portal_css')
-        self.jstool = getToolByName(self.portal, 'portal_javascripts')
-
-        if 'portal_actionicons' not in self.portal:
-            from plone.app.upgrade.bbb import ActionIconsTool
-            self.portal._setObject('portal_actionicons', ActionIconsTool())
-        self.aitool = self.portal.portal_actionicons
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        self.setRoles(['Manager'])
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testMigrateActionIcons(self):
-        _KNOWN_ACTION_ICONS['object_buttons'].extend(['test_id', 'test2_id'])
-        self.aitool.addActionIcon(
-            category='object_buttons',
-            action_id='test_id',
-            icon_expr='test.gif',
-            title='Test my icon',
-            )
-        self.aitool.addActionIcon(
-            category='object_buttons',
-            action_id='test2_id',
-            icon_expr='python:context.getIcon()',
-            title='Test my second icon',
-            )
-        test_action = Action('test_id',
-            title='Test me',
-            description='',
-            url_expr='',
-            icon_expr='',
-            available_expr='',
-            permissions=('View', ),
-            visible = True)
-        test2_action = Action('test2_id',
-            title='Test me too',
-            description='',
-            url_expr='',
-            icon_expr='',
-            available_expr='',
-            permissions=('View', ),
-            visible = True)
-
-        object_buttons = self.atool.object_buttons
-        if getattr(object_buttons, 'test_id', None) is None:
-            object_buttons._setObject('test_id', test_action)
-        if getattr(object_buttons, 'test2_id', None) is None:
-            object_buttons._setObject('test2_id', test2_action)
-
-        self.assertEqual(object_buttons.test_id.icon_expr, '')
-        self.assertEqual(object_buttons.test2_id.icon_expr, '')
-        # Test it twice
-        for i in range(2):
-            migrateActionIcons(self.portal)
-            icons = [ic._action_id for ic in self.aitool.listActionIcons()]
-            self.assertFalse('test_id' in icons)
-            self.assertFalse('test2_id' in icons)
-            self.assertEqual(object_buttons.test_id.icon_expr,
-                             'string:$portal_url/test.gif')
-            self.assertEqual(object_buttons.test2_id.icon_expr,
-                             'python:context.getIcon()')
-
-    def testMigrateControlPanelActionIcons(self):
-        _KNOWN_ACTION_ICONS['controlpanel'].extend(['test_id'])
-        self.aitool.addActionIcon(
-            category='controlpanel',
-            action_id='test_id',
-            icon_expr='test.gif',
-            title='Test my icon',
-            )
-
-        self.cptool.registerConfiglet(
-            id='test_id',
-            name='Test Configlet',
-            action='string:${portal_url}/test',
-            permission='Manage portal',
-            category='Plone',
-            visible=True,
-            appId='',
-            icon_expr='',
-            )
-
-        action = self.cptool.getActionObject('Plone/test_id')
-        self.assertEqual(action.getIconExpression(), '')
-        # Test it twice
-        for i in range(2):
-            migrateActionIcons(self.portal)
-            icons = [ic._action_id for ic in self.aitool.listActionIcons()]
-            self.assertFalse('test_id' in icons)
-            self.assertEqual(action.getIconExpression(),
-                             'string:$portal_url/test.gif')
-
-    def testContentTypeIconExpressions(self):
-        """
-        FTIs should now be using icon_expr instead of content_icon.
-        (The former caches the expression object.)
-        """
-        tt = getToolByName(self.portal, "portal_types")
-        tt.Document.icon_expr = None
-        loadMigrationProfile(self.portal, self.profile, ('typeinfo', ))
-        self.assertEqual(tt.Document.icon_expr,
-                         "string:${portal_url}/document_icon.png")
-
-    def testMigrateTypeIcons(self):
-        """
-        FTIs having content_icon should be upgraded to icon_expr.
-        """
-        tt = getToolByName(self.portal, "portal_types")
-        del tt.Document.icon_expr
-        tt.Document.content_icon = 'document_icon.gif'
-        migrateTypeIcons(self.portal)
-        self.assertEqual(tt.Document.icon_expr,
-                         "string:${portal_url}/document_icon.gif")
-        self.assertTrue(hasattr(tt.Document, 'icon_expr_object'))
-
-        #Don't upgrade if there is already an icon_expr.
-        tt.Document.icon_expr = "string:${portal_url}/document_icon.png"
-        tt.Document.content_icon = 'document_icon.gif'
-        migrateTypeIcons(self.portal)
-        self.assertEqual(tt.Document.icon_expr,
-                         "string:${portal_url}/document_icon.png")
-
-    def testPngContentIcons(self):
-        tt = getToolByName(self.portal, "portal_types")
-        tt.Document.icon_expr = "string:${portal_url}/document_icon.gif"
-        loadMigrationProfile(self.portal, self.profile, ('typeinfo', ))
-        self.assertEqual(tt.Document.icon_expr,
-            "string:${portal_url}/document_icon.png")
-
-    def testAddRAMCache(self):
-        # Test it twice
-        for i in range(2):
-            sm = getSiteManager()
-            sm.unregisterUtility(provided=IRAMCache)
-            util = queryUtility(IRAMCache)
-            self.assertEqual(util.maxAge, 86400)
-            addOrReplaceRamCache(self.portal)
-            util = queryUtility(IRAMCache)
-            self.assertEqual(util.maxAge, 3600)
-
-    def testReplaceOldRamCache(self):
-        sm = getSiteManager()
-
-        # Test it twice
-        for i in range(2):
-            sm.unregisterUtility(provided=IRAMCache)
-            from zope.app.cache.interfaces.ram import IRAMCache as OldIRAMCache
-            from zope.app.cache.ram import RAMCache as OldRAMCache
-            sm.registerUtility(factory=OldRAMCache, provided=OldIRAMCache)
-
-            addOrReplaceRamCache(self.portal)
-            util = queryUtility(IRAMCache)
-            self.assertEqual(util.maxAge, 3600)
-
-    def testChangeWorkflowActorVariableExpression(self):
-        self.wftool.intranet_folder_workflow.variables.actor.setProperties('')
-
-        for i in range(2):
-            changeWorkflowActorVariableExpression(self.portal)
-            wf = self.wftool.intranet_folder_workflow
-            self.assertEqual(wf.variables.actor.getDefaultExprText(),
-                             'user/getId')
-            wf = self.wftool.one_state_workflow
-            self.assertEqual(wf.variables.actor.getDefaultExprText(),
-                             'user/getId')
-            wf = self.wftool.simple_publication_workflow
-            self.assertEqual(wf.variables.actor.getDefaultExprText(),
-                             'user/getId')
-
-        # make sure it doesn't break if the workflow is missing
-        wf = self.wftool.intranet_folder_workflow
-        self.wftool._delOb('intranet_folder_workflow')
-        changeWorkflowActorVariableExpression(self.portal)
-        self.wftool._setOb('intranet_folder_workflow', wf)
-
-    def testChangeAuthenticatedResourcesCondition(self):
-        # make sure CSS resource is updated
-        res = self.csstool.getResource('member.css')
-        if res is None:
-            return
-        res.setAuthenticated(False)
-        res.setExpression('not: portal/portal_membership/isAnonymousUser')
-        # test it twice
-        for i in range(2):
-            changeAuthenticatedResourcesCondition(self.portal)
-            self.assertEqual(res.getExpression(), '')
-            self.assertTrue(res.getAuthenticated())
-
-        # make sure it doesn't update it if the expression has been
-        # customized
-        res.setExpression('python:False')
-        changeAuthenticatedResourcesCondition(self.portal)
-        self.assertEqual(res.getExpression(), 'python:False')
-
-    def testAddedUseEmailProperty(self):
-        tool = getToolByName(self.portal, 'portal_properties')
-        sheet = getattr(tool, 'site_properties')
-        #self.assertEqual(sheet.getProperty('use_email_as_login'), False)
-        self.removeSiteProperty('use_email_as_login')
-        loadMigrationProfile(self.portal, self.profile, ('propertiestool', ))
-        self.assertEqual(sheet.getProperty('use_email_as_login'), False)
-
-    def testReplaceReferencebrowser(self):
-        self.setRoles(['Manager'])
-        skins_tool = getToolByName(self.portal, 'portal_skins')
-        if 'referencebrowser' not in skins_tool:
-            return
-        sels = skins_tool._getSelections()
-        for skinname, layer in sels.items():
-            layers = layer.split(',')
-            self.assertFalse('ATReferenceBrowserWidget' in layers)
-            layers.remove('referencebrowser')
-            new_layers = ','.join(layers)
-            sels[skinname] = new_layers
-
-        from .alphas import threeX_alpha1
-        threeX_alpha1(self.portal)
-        setupReferencebrowser(self.portal)
-
-        sels = skins_tool._getSelections()
-        for skinname, layer in sels.items():
-            layers = layer.split(',')
-            self.assertTrue('referencebrowser' in layers)
-
-    def testInstallNewDependencies(self):
-        from plone.app.upgrade.v40.alphas import threeX_alpha1
-        self.setRoles(['Manager'])
-        # test for running the TinyMCE profile by checking for the skin layer
-        # it installs (the profile is marked as noninstallable, so we can't
-        # ask the quick installer)
-        skins_tool = getToolByName(self.portal, 'portal_skins')
-        if 'tinymce' not in skins_tool:
-            # Skip test in new Plones that don't have tinymce to begin with
-            return
-        del skins_tool['tinymce']
-        for i in range(2):
-            threeX_alpha1(self.portal)
-            self.assertTrue('tinymce' in skins_tool)
-            # sleep to avoid a GS log filename collision :-o
-            time.sleep(1)
-
-    def testReplaceSecureMailHost(self):
-        portal = self.portal
-        sm = getSiteManager(context=portal)
-        # try it with an unmodified site to ensure it doesn't give any errors
-        migrateMailHost(portal.portal_setup)
-        portal._delObject('MailHost')
-        # Run it with our MailHost replaced
-        portal._setObject('MailHost', FakeSecureMailHost())
-        self.assertEqual(portal.MailHost.meta_type, 'Secure Mail Host')
-        sm.unregisterUtility(provided=IMailHost)
-        sm.registerUtility(portal.MailHost, provided=IMailHost)
-        migrateMailHost(portal)
-        new_mh = portal.MailHost
-        self.assertEqual(new_mh.meta_type, 'Mail Host')
-        self.assertEqual(new_mh.title, 'Fake MailHost')
-        self.assertEqual(new_mh.smtp_host, 'smtp.example.com')
-        self.assertEqual(new_mh.smtp_port, 587)
-        self.assertEqual(new_mh.smtp_uid, 'me')
-        self.assertEqual(new_mh.smtp_pwd, 'secret')
-        #Force TLS is always false, because SMH has no equivalent option
-        self.assertEqual(new_mh.force_tls, False)
-
-    def testFolderMigration(self):
-        from plone.app.folder.tests.content import create
-        from plone.app.folder.tests.test_migration import reverseMigrate
-        from plone.app.folder.tests.test_migration import isSaneBTreeFolder
-        # create a folder in an unmigrated state & check it's broken...
-        folder = create('Folder', self.portal, 'foo', title='Foo')
-        reverseMigrate(self.portal)
-        self.assertFalse(isSaneBTreeFolder(self.portal.foo))
-        # now run the migration step...
-        migrateFolders(self.portal)
-        folder = self.portal.foo
-        self.assertTrue(isSaneBTreeFolder(folder))
-        self.assertEqual(folder.getId(), 'foo')
-        self.assertEqual(folder.Title(), 'Foo')
-
-    def testMigrateStaticTextPortlets(self):
-        class HiddenAssignment(static.Assignment):
-            hide = True
-
-        self.setRoles(["Manager"])
-        self.portal.invokeFactory('Folder', id="statictest")
-        folder = self.portal['statictest']
-
-        manager = getUtility(
-                IPortletManager, name='plone.rightcolumn',
-                context=folder)
-        assignments = getMultiAdapter(
-                (folder, manager), IPortletAssignmentMapping)
-        hidden_portlet = HiddenAssignment()
-        visible_portlet = static.Assignment()
-        assignments['hidden'] = hidden_portlet
-        assignments['visible'] = visible_portlet
-
-        migrateStaticTextPortlets(self.portal)
-
-        self.assertFalse(
-                IPortletAssignmentSettings(hidden_portlet).get(
-                        'visible', True))
-        self.assertTrue(
-                IPortletAssignmentSettings(visible_portlet).get(
-                        'visible', True))
-
-
-
-class TestMigrations_v4_0alpha2(MigrationTest):
-
-    def testMigrateJoinFormFields(self):
-        ptool = getToolByName(self.portal, 'portal_properties')
-        sheet = getattr(ptool, 'site_properties')
-        self.removeSiteProperty('user_registration_fields')
-        self.addSiteProperty('join_form_fields')
-        sheet.join_form_fields = (
-            'username', 'password', 'email', 'mail_me', 'groups')
-        renameJoinFormFields(self)
-        self.assertEqual(sheet.hasProperty('join_form_fields'), False)
-        self.assertEqual(sheet.hasProperty('user_registration_fields'), True)
-        self.assertEqual(sheet.getProperty('user_registration_fields'),
-                         ('username', 'password', 'email', 'mail_me'))
-
-
-class TestMigrations_v4_0alpha3(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:4alpha2-4alpha3"
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testJoinActionURL(self):
-        self.portal.portal_actions.user.join.url_expr = 'foo'
-        loadMigrationProfile(self.portal, self.profile, ('actions', ))
-        self.assertEqual(self.portal.portal_actions.user.join.url_expr,
-            'string:${globals_view/navigationRootUrl}/@@register')
-
-
-class TestMigrations_v4_0alpha5(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:4alpha4-4alpha5"
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testMigrateLargeFolderType(self):
-        portal = self.portal
-        catalog = getToolByName(portal, 'portal_catalog')
-        # set things up in the old way...
-        ids = 'news', 'events', 'Members'
-        for id in ids:
-            obj = portal[id]
-            obj._setPortalTypeName('Large Plone Folder')
-            obj.reindexObject()
-            self.assertEqual(obj.portal_type, 'Large Plone Folder')
-            # Type falls back to meta_type since there's no
-            # Large Plone Folder FTI
-            self.assertEqual(obj.Type(), 'ATFolder')
-            brain, = catalog(getId=id)
-            self.assertEqual(brain.portal_type, 'Large Plone Folder')
-            self.assertEqual(brain.Type, 'ATFolder')
-        # migrate & check again...
-        updateLargeFolderType(self.portal)
-        for id in ids:
-            obj = portal[id]
-            self.assertEqual(obj.portal_type, 'Folder')
-            self.assertEqual(obj.Type(), 'Folder')
-            brain, = catalog(getId=id)
-            self.assertEqual(brain.portal_type, 'Folder')
-            self.assertEqual(brain.Type, 'Folder')
-
-    def testAddRecursiveGroupsPlugin(self):
-        acl = getToolByName(self.portal, 'acl_users')
-        addRecursiveGroupsPlugin(self.portal)
-        self.assertTrue('recursive_groups' in acl)
-        # Now that we have an existing one, let's make sure it's handled
-        # properly if this migration is run again.
-        addRecursiveGroupsPlugin(self.portal)
-        self.assertTrue('recursive_groups' in acl)
-
-    def testClassicThemeResourcesCleanUp(self):
-        """Test that the plonetheme.classic product doesn't have any
-        registered CSS resource in its metadata after migration.
-        """
-        portal = self.portal
-        qi = getToolByName(portal, 'portal_quickinstaller')
-        qi.installProduct('plonetheme.classic')
-        classictheme = qi['plonetheme.classic']
-        classictheme.resources_css = ['something'] # add a random resource
-        cleanUpClassicThemeResources(portal)
-        self.assertEqual(classictheme.resources_css, [])
-
-    def testGetObjPositionInParentIndex(self):
-        from plone.app.folder.nogopip import GopipIndex
-        catalog = self.portal.portal_catalog
-        catalog.delIndex('getObjPositionInParent')
-        catalog.addIndex('getObjPositionInParent', 'FieldIndex')
-        self.assertFalse(isinstance(catalog.Indexes['getObjPositionInParent'],
-            GopipIndex))
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue('getObjPositionInParent' in catalog.indexes())
-        self.assertTrue(isinstance(catalog.Indexes['getObjPositionInParent'],
-            GopipIndex))
-
-    def testGetEventTypeIndex(self):
-        catalog = self.portal.portal_catalog
-        catalog.addIndex('getEventType', 'KeywordIndex')
-        self.assertTrue('getEventType' in catalog.indexes())
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertFalse('getEventType' in catalog.indexes())
-
-
-class TestMigrations_v4_0beta1(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:4alpha5-4beta1"
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testRepositionRecursiveGroupsPlugin(self):
-        # Ensure that the recursive groups plugin is moved to the bottom
-        # of the IGroups plugins list, if active.
-        addRecursiveGroupsPlugin(self.portal)
-        # Plugin is installed, but not active, run against this state.
-        from Products.PluggableAuthService.interfaces.plugins import \
-            IGroupsPlugin
-        acl = getToolByName(self.portal, 'acl_users')
-        plugins = acl.plugins
-        # The plugin was originally moved to the top of the list of
-        # IGroupsPlugin plugins by p.a.controlpanel. Recreate that state.
-        while (plugins.getAllPlugins('IGroupsPlugin')['active'].index(
-               'recursive_groups') > 0):
-            plugins.movePluginsUp(IGroupsPlugin, ['recursive_groups'])
-
-        active_groups = plugins.getAllPlugins('IGroupsPlugin')['active']
-        self.assertEqual(active_groups[0], 'recursive_groups')
-
-        # Rerun the migration, making sure that it's now the last item in the
-        # list of IGroupsPlugin plugins.
-        repositionRecursiveGroupsPlugin(self.portal)
-        active_groups = plugins.getAllPlugins('IGroupsPlugin')['active']
-        self.assertEqual(active_groups[-1], 'recursive_groups')
-
-
-class TestMigrations_v4_0beta2(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:4beta1-4beta2"
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testCoreContentIconExprCleared(self):
-        types = getToolByName(self.portal, 'portal_types')
-        catalog = getToolByName(self.portal, 'portal_catalog')
-        # Reinstate the now-empty icon expression for the Document type
-        doc_icon_expr = Expression('string:${portal_url}/document_icon.png')
-        types['Document'].icon_expr_object = doc_icon_expr
-        front = self.portal['front-page']
-        catalog.reindexObject(front)
-        old_modified = front.modified()
-        # Make sure the getIcon metadata column shows the "original" value
-        brains = catalog(id='front-page')
-        self.assertEqual(brains[0].getIcon, 'document_icon.png')
-        # Run the migration
-        loadMigrationProfile(self.portal, self.profile)
-        updateIconMetadata(self.portal)
-        # The getIcon column should now be empty
-        self.assertEqual(catalog(id='front-page')[0].getIcon, '')
-        self.assertEqual(front.modified(), old_modified)
-
-
-class TestMigrations_v4_0beta4(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4beta3-4beta4'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testRemoveLargePloneFolder(self):
-        # re-create pre-migration settings
-        ptool = self.portal.portal_properties
-        nav_props = ptool.navtree_properties
-        l = list(nav_props.parentMetaTypesNotToQuery)
-        nav_props.parentMetaTypesNotToQuery = l + ['Large Plone Folder']
-        site_props = ptool.site_properties
-        l = list(site_props.typesLinkToFolderContentsInFC)
-        site_props.typesLinkToFolderContentsInFC = l + ['Large Plone Folder']
-        temp_folder_fti = self.portal.portal_types['TempFolder']
-        l = list(temp_folder_fti.allowed_content_types)
-        temp_folder_fti.allowed_content_types = l + ['Large Plone Folder']
-        l = set(self.portal.portal_factory.getFactoryTypes())
-        l.add('Large Plone Folder')
-        ftool = self.portal.portal_factory
-        ftool.manage_setPortalFactoryTypes(listOfTypeIds=list(l))
-
-        for i in xrange(2):
-            loadMigrationProfile(self.portal, self.profile)
-            removeLargePloneFolder(self.portal)
-            self.assertFalse('Large Plone Folder' in self.portal.portal_types)
-            self.assertFalse('Large Plone Folder' in
-                        temp_folder_fti.allowed_content_types)
-            self.assertTrue('Folder' in temp_folder_fti.allowed_content_types)
-            self.assertFalse('Large Plone Folder' in ftool.getFactoryTypes())
-            self.assertTrue('Folder' in ftool.getFactoryTypes())
-            self.assertFalse('Large Plone Folder' in
-                        nav_props.parentMetaTypesNotToQuery)
-            self.assertTrue('TempFolder' in
-                            nav_props.parentMetaTypesNotToQuery)
-            self.assertFalse('Large Plone Folder' in
-                        site_props.typesLinkToFolderContentsInFC)
-            self.assertTrue('Folder' in
-                            site_props.typesLinkToFolderContentsInFC)
-            # sleep to avoid a GS log filename collision :-o
-            time.sleep(1)
-
-
-class TestMigrations_v4_0beta5(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4beta4-4beta5'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-
-class TestMigrations_v4_0rc1(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4beta5-4rc1'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4rc1-4final'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_1(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0-4.0.1'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_2(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0.1-4.0.2'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_3(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0.2-4.0.3'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_4(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0.3-4.0.4'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_5(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0.4-4.0.5'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-
-def test_suite():
-    from unittest import defaultTestLoader
-    return defaultTestLoader.loadTestsFromName(__name__)
diff --git a/plone/app/upgrade/v41/tests.py b/plone/app/upgrade/v41/tests.py
deleted file mode 100644
index 4570a4c..0000000
--- a/plone/app/upgrade/v41/tests.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import unittest
-from Products.ZCatalog.ZCatalog import ZCatalog
-from Products.ZCTextIndex.ZCTextIndex import ZCTextIndex, PLexicon
-from Products.ZCTextIndex.OkapiIndex import OkapiIndex
-
-
-class MigrationUnitTests(unittest.TestCase):
-
-    def test_fixOkapiIndexes(self):
-        catalog = ZCatalog('catalog')
-        catalog.lexicon = PLexicon('lexicon')
-        catalog.addIndex('test',
-            ZCTextIndex('test', index_factory=OkapiIndex,
-                        caller=catalog, lexicon_id='lexicon'))
-        catalog.Indexes['test'].index._totaldoclen = -1000
-
-        from plone.app.upgrade.v41.final import fixOkapiIndexes
-        fixOkapiIndexes(catalog)
-        self.assertEqual(0L, catalog.Indexes['test'].index._totaldoclen())
diff --git a/plone/app/upgrade/v42/tests.py b/plone/app/upgrade/v42/tests.py
deleted file mode 100644
index 0ff501e..0000000
--- a/plone/app/upgrade/v42/tests.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.utils import loadMigrationProfile
-
-
-class TestMigrations_v4_2beta1(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v42:to42beta1'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testAddSiteAdminToKeywordRoles(self):
-        ptool = self.portal.portal_properties
-        site_props = ptool.site_properties
-        site_props.allowRolesToAddKeywords = ('Manager', 'Reviewer')
-        loadMigrationProfile(self.portal, self.profile)
-        roles = site_props.allowRolesToAddKeywords
-        self.assertEqual(roles, ('Manager', 'Reviewer', 'Site Administrator'))
diff --git a/setup.py b/setup.py
index 1a44248..c500ee7 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
 from setuptools import setup, find_packages
 
-version = '1.3.9.dev0'
+version = '2.0.dev0'
 
 setup(name='plone.app.upgrade',
       version=version,


Repository: plone.app.upgrade
Branch: refs/heads/master
Date: 2015-01-06T14:49:49+01:00
Author: Tom Gross (tomgross) <itconsense at gmail.com>
Commit: https://github.com/plone/plone.app.upgrade/commit/d1ce53e82795e65836b02da38cc85b7c3fd182fe

Merge remote-tracking branch 'origin/master' into tomgross-noptc

Files changed:
A plone/app/upgrade/v50/profiles/to_beta1/registry.xml
M CHANGES.rst
M plone/app/upgrade/v50/betas.py
M plone/app/upgrade/v50/configure.zcml
M plone/app/upgrade/v50/profiles.zcml
M plone/app/upgrade/v50/profiles/to_alpha3/registry.xml

diff --git a/CHANGES.rst b/CHANGES.rst
index f6874cf..6e27679 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,6 +4,12 @@ Changelog
 2.0 (unreleased)
 ------------------
 
+- Add upgrade step for the security control panel.
+  [jcerjak]
+
+- Add upgrade step for mail control panel. Refs PLIP 10359.
+  [jcerjak, khink]
+
 - Add upgrade steps for markup control panel.
   [thet]
 
diff --git a/plone/app/upgrade/v50/betas.py b/plone/app/upgrade/v50/betas.py
index 0b8ae9f..2d44444 100644
--- a/plone/app/upgrade/v50/betas.py
+++ b/plone/app/upgrade/v50/betas.py
@@ -1,8 +1,49 @@
 # -*- coding: utf-8 -*-
 from Products.CMFCore.utils import getToolByName
+from Products.CMFPlone.interfaces import IMailSchema
 from Products.CMFPlone.interfaces import IMarkupSchema
+from Products.CMFPlone.interfaces import ISecuritySchema
+from plone.app.upgrade.utils import loadMigrationProfile
 from plone.registry.interfaces import IRegistry
 from zope.component import getUtility
+from zope.component.hooks import getSite
+
+
+def to50beta1(context):
+    """5.0alpha3 -> 5.0beta1"""
+    loadMigrationProfile(context, 'profile-plone.app.upgrade.v50:to50beta1')
+
+
+def upgrade_mail_controlpanel_settings(context):
+    registry = getUtility(IRegistry)
+    # XXX: Somehow this code is excecuted for old migration steps as well
+    # ( < Plone 4 ) and breaks because there is no registry. Looking up the
+    # registry interfaces with 'check=False' will not work, because it will
+    # return a settings object and then fail when we try to access the
+    # attributes.
+    try:
+        mail_settings = registry.forInterface(IMailSchema, prefix='plone')
+    except KeyError:
+        return
+    portal = getSite()
+
+    smtp_host = getattr(portal.MailHost, 'smtp_host', '')
+    mail_settings.smtp_host = unicode(smtp_host)
+
+    smtp_port = getattr(portal.MailHost, 'smtp_port', 25)
+    mail_settings.smtp_port = smtp_port
+
+    smtp_user_id = portal.MailHost.get('smtp_user_id')
+    mail_settings.smtp_user_id = smtp_user_id
+
+    smtp_pass = portal.MailHost.get('smtp_pass')
+    mail_settings.smtp_pass = smtp_pass
+
+    email_from_address = portal.get('email_from_address')
+    mail_settings.email_from_address = email_from_address
+
+    email_from_name = portal.get('email_from_name')
+    mail_settings.email_from_name = email_from_name
 
 
 def upgrade_markup_controlpanel_settings(context):
@@ -40,3 +81,53 @@ def upgrade_markup_controlpanel_settings(context):
             if _type not in forbidden_types
             and _type not in 'text/x-plone-outputfilters-html'  # removed, as in plone.app.vocabularies.types  # noqa
         ])
+
+
+def upgrade_security_controlpanel_settings(context):
+    """Copy security control panel settings from portal properties and various
+    other locations into the new registry.
+    """
+    def _get_enable_self_reg():
+        app_perms = portal.rolesOfPermission(permission='Add portal member')
+        for appperm in app_perms:
+            if appperm['name'] == 'Anonymous' and \
+               appperm['selected'] == 'SELECTED':
+                return True
+        return False
+
+    # get the old site properties
+    portal_url = getToolByName(context, 'portal_url')
+    portal = portal_url.getPortalObject()
+    portal_properties = getToolByName(portal, "portal_properties")
+    site_properties = portal_properties.site_properties
+
+    # get the new registry
+    registry = getUtility(IRegistry)
+
+    # XXX: Somehow this code is excecuted for old migration steps as well
+    # ( < Plone 4 ) and breaks because there is no registry. Looking up the
+    # registry interfaces with 'check=False' will not work, because it will
+    # return a settings object and then fail when we try to access the
+    # attributes.
+    try:
+        settings = registry.forInterface(
+            ISecuritySchema,
+            prefix='plone',
+        )
+    except KeyError:
+        settings = False
+    if settings:
+        settings.enable_self_reg = _get_enable_self_reg()
+        validate_email = portal.getProperty('validate_email', True)
+        if validate_email:
+            settings.enable_user_pwd_choice = False
+        else:
+            settings.enable_user_pwd_choice = True
+        pmembership = getToolByName(portal, 'portal_membership')
+        settings.enable_user_folders = pmembership.getMemberareaCreationFlag()
+        settings.allow_anon_views_about = site_properties.getProperty(
+            'allowAnonymousViewAbout', False)
+        settings.use_email_as_login = site_properties.getProperty(
+            'use_email_as_login', False)
+        settings.use_uuid_as_userid = site_properties.getProperty(
+            'use_uuid_as_userid', False)
diff --git a/plone/app/upgrade/v50/configure.zcml b/plone/app/upgrade/v50/configure.zcml
index b53fe05..01dd8e9 100644
--- a/plone/app/upgrade/v50/configure.zcml
+++ b/plone/app/upgrade/v50/configure.zcml
@@ -88,11 +88,29 @@
         profile="Products.CMFPlone:plone">
 
        <gs:upgradeStep
+           title="Run to50beta1 upgrade profile"
+           description=""
+           handler=".betas.to50beta1"
+           />
+
+       <gs:upgradeStep
            title="Upgrade markup control panel settings"
            description=""
            handler=".betas.upgrade_markup_controlpanel_settings"
            />
 
+       <gs:upgradeStep
+           title="Upgrade mail control panel settings"
+           description="Take portal properties and put them in IMailSettings registry"
+           handler=".betas.upgrade_mail_controlpanel_settings"
+           />
+
+       <gs:upgradeStep
+           title="Upgrade security control panel settings"
+           description=""
+           handler=".betas.upgrade_security_controlpanel_settings"
+           />
+
     </gs:upgradeSteps>
 
 </configure>
diff --git a/plone/app/upgrade/v50/profiles.zcml b/plone/app/upgrade/v50/profiles.zcml
index 271af6b..7655975 100644
--- a/plone/app/upgrade/v50/profiles.zcml
+++ b/plone/app/upgrade/v50/profiles.zcml
@@ -21,4 +21,13 @@
       provides="Products.GenericSetup.interfaces.EXTENSION"
       />
 
+  <genericsetup:registerProfile
+      name="to50beta1"
+      title="Upgrade profile for Plone 5003 to Plone 5.0beta1"
+      description=""
+      directory="profiles/to_beta1"
+      for="Products.CMFPlone.interfaces.IMigratingPloneSiteRoot"
+      provides="Products.GenericSetup.interfaces.EXTENSION"
+      />
+
 </configure>
diff --git a/plone/app/upgrade/v50/profiles/to_alpha3/registry.xml b/plone/app/upgrade/v50/profiles/to_alpha3/registry.xml
index ae456b6..94c1214 100644
--- a/plone/app/upgrade/v50/profiles/to_alpha3/registry.xml
+++ b/plone/app/upgrade/v50/profiles/to_alpha3/registry.xml
@@ -4,6 +4,8 @@
            prefix="plone" />
   <records interface="Products.CMFPlone.interfaces.IMaintenanceSchema"
            prefix="plone" />
+  <records interface="Products.CMFPlone.interfaces.IMailSchema"
+           prefix="plone" />
   <records interface="Products.CMFPlone.interfaces.INavigationSchema"
            prefix="plone" />
   <records interface="Products.CMFPlone.interfaces.ISearchSchema"
@@ -813,12 +815,12 @@
 
   <records prefix="plone.resources/rjs"
             interface='Products.CMFPlone.interfaces.IResourceRegistry'>
-      <value key="js">++plone++static/components/r.js/dist/r.js</value>           
+      <value key="js">++plone++static/components/r.js/dist/r.js</value>
   </records>
 
   <!-- legacy js -->
 
-  
+
   <records prefix="plone.resources/plone_javascript_variables"
             interface='Products.CMFPlone.interfaces.IResourceRegistry'>
       <value key="js">plone_javascript_variables.js</value>
diff --git a/plone/app/upgrade/v50/profiles/to_beta1/registry.xml b/plone/app/upgrade/v50/profiles/to_beta1/registry.xml
new file mode 100644
index 0000000..fd89c49
--- /dev/null
+++ b/plone/app/upgrade/v50/profiles/to_beta1/registry.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<registry>
+  <records interface="Products.CMFPlone.interfaces.ISecuritySchema"
+           prefix="plone" />
+</registry>


Repository: plone.app.upgrade
Branch: refs/heads/master
Date: 2015-01-06T17:12:44+01:00
Author: Timo Stollenwerk (tisto) <tisto at plone.org>
Commit: https://github.com/plone/plone.app.upgrade/commit/d484e8d35381dfbda5a4179b8e227c8cbb7d2375

Merge pull request #22 from plone/tomgross-noptc

Ported to plone.app.testing

Files changed:
M CHANGES.rst
M plone/app/upgrade/tests/base.py
M setup.py
D plone/app/upgrade/v25/tests.py
D plone/app/upgrade/v30/tests.py
D plone/app/upgrade/v31/tests.py
D plone/app/upgrade/v32/tests.py
D plone/app/upgrade/v33/tests.py
D plone/app/upgrade/v40/tests.py
D plone/app/upgrade/v41/tests.py
D plone/app/upgrade/v42/tests.py

diff --git a/CHANGES.rst b/CHANGES.rst
index 1bf846a..6e27679 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,7 +1,7 @@
 Changelog
 =========
 
-1.3.9 (unreleased)
+2.0 (unreleased)
 ------------------
 
 - Add upgrade step for the security control panel.
@@ -13,6 +13,11 @@ Changelog
 - Add upgrade steps for markup control panel.
   [thet]
 
+- Ported tests to plone.app.testing
+  [tomgross]
+
+- Removed all tests for migrations older than 4.3 -> 5.0
+  [tomgross]
 
 1.3.8 (2014-11-01)
 ------------------
diff --git a/plone/app/upgrade/tests/base.py b/plone/app/upgrade/tests/base.py
index 840416c..f25f530 100644
--- a/plone/app/upgrade/tests/base.py
+++ b/plone/app/upgrade/tests/base.py
@@ -9,10 +9,7 @@
 import transaction
 from zope.site.hooks import setSite
 
-from Testing.ZopeTestCase.sandbox import Sandboxed
-from Products.PloneTestCase.layer import PloneSiteLayer
-from Products.PloneTestCase.ptc import PloneTestCase
-from Products.PloneTestCase.ptc import setupPloneSite
+from plone.app.testing.bbb import PloneTestCase
 
 from Products.CMFCore.interfaces import IActionCategory
 from Products.CMFCore.interfaces import IActionInfo
@@ -20,8 +17,6 @@
 from Products.CMFCore.tests.base.testcase import WarningInterceptor
 from Products.GenericSetup.context import TarballImportContext
 
-setupPloneSite()
-
 
 class MigrationTest(PloneTestCase):
 
@@ -111,21 +106,10 @@ def removeSkinLayer(self, layer, skin='Plone Default'):
             skins.addSkinSelection(skin, ','.join(path))
 
 
-class FunctionalUpgradeLayer(PloneSiteLayer):
-
-    @classmethod
-    def setUp(cls):
-        pass
-
-    @classmethod
-    def tearDown(cls):
-        pass
-
 
-class FunctionalUpgradeTestCase(Sandboxed, PloneTestCase, WarningInterceptor):
+class FunctionalUpgradeTestCase(PloneTestCase, WarningInterceptor):
 
     _setup_fixture = 0
-    layer = FunctionalUpgradeLayer
     site_id = 'test'
 
     def afterSetUp(self):
diff --git a/plone/app/upgrade/v25/tests.py b/plone/app/upgrade/v25/tests.py
deleted file mode 100644
index 036e8b5..0000000
--- a/plone/app/upgrade/v25/tests.py
+++ /dev/null
@@ -1,124 +0,0 @@
-from Products.CMFPlone.UnicodeSplitter import Splitter
-from Products.CMFPlone.UnicodeSplitter import CaseNormalizer
-
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.utils import loadMigrationProfile
-
-from plone.app.upgrade.v25 import fixupPloneLexicon
-from plone.app.upgrade.v25 import setLoginFormInCookieAuth
-from plone.app.upgrade.v25 import addMissingMimeTypes
-
-
-class TestMigrations_v2_5_0(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v25:2.5final-2.5.1'
-        self.actions = self.portal.portal_actions
-        self.css = self.portal.portal_css
-
-    def tesFixObjDeleteAction(self):
-        # Prepare delete actions test
-        editActions = ('delete',)
-        for a in editActions:
-            self.removeActionFromTool(a, category='object_buttons')
-        loadMigrationProfile(self.portal, self.profile, ('actions', ))
-        # delete action tests
-        actions = [x.id for x in self.actions.object_buttons.listActions()
-                   if x.id in editActions]
-        # check that all of our deleted actions are now present
-        for a in editActions:
-            self.assertTrue(a in actions)
-        # ensure that they are present only once
-        self.assertEqual(len(editActions), len(actions))
-
-    def testFixupPloneLexicon(self):
-        # Should update the plone_lexicon pipeline
-        lexicon = self.portal.portal_catalog.plone_lexicon
-        lexicon._pipeline = (object(), object())
-        # Test it twice
-        for i in range(2):
-            fixupPloneLexicon(self.portal)
-            self.assertTrue(isinstance(lexicon._pipeline[0], Splitter))
-            self.assertTrue(isinstance(lexicon._pipeline[1], CaseNormalizer))
-
-
-class TestMigrations_v2_5_1(MigrationTest):
-
-    def afterSetUp(self):
-        self.actions = self.portal.portal_actions
-        self.memberdata = self.portal.portal_memberdata
-        self.catalog = self.portal.portal_catalog
-        self.skins = self.portal.portal_skins
-        self.types = self.portal.portal_types
-        self.workflow = self.portal.portal_workflow
-        self.css = self.portal.portal_css
-
-    def testSetLoginFormInCookieAuth(self):
-        setLoginFormInCookieAuth(self.portal)
-        cookie_auth = self.portal.acl_users.credentials_cookie_auth
-        self.assertEqual(cookie_auth.getProperty('login_path'),
-                             'require_login')
-
-    def testSetLoginFormNoCookieAuth(self):
-        # Shouldn't error
-        uf = self.portal.acl_users
-        uf._delOb('credentials_cookie_auth')
-        setLoginFormInCookieAuth(self.portal)
-
-    def testSetLoginFormAlreadyChanged(self):
-        # Shouldn't change the value if it's not the default
-        cookie_auth = self.portal.acl_users.credentials_cookie_auth
-        cookie_auth.manage_changeProperties(login_path='foo')
-        setLoginFormInCookieAuth(self.portal)
-        self.assertTrue(cookie_auth.getProperty('login_path') != 'require_login')
-
-class TestMigrations_v2_5_2(MigrationTest):
-
-    def afterSetUp(self):
-        self.mimetypes = self.portal.mimetypes_registry
-
-    def testMissingMimeTypes(self):
-        # we're testing for 'text/x-web-markdown' and 'text/x-web-textile'
-        missing_types = ['text/x-web-markdown', 'text/x-web-textile']
-        # since we're running a full 2.5.4 instance in this test, the missing
-        # types might in fact already be there:
-        current_types = self.mimetypes.list_mimetypes()
-        types_to_delete = []
-        for mtype in missing_types:
-            if mtype in current_types:
-                types_to_delete.append(mtype)
-        if types_to_delete:
-            self.mimetypes.manage_delObjects(types_to_delete)
-        # now they're gone:
-        self.assertFalse(set(self.mimetypes.list_mimetypes()).issuperset(set(missing_types)))
-        addMissingMimeTypes(self.portal)
-        # now they're back:
-        self.assertTrue(set(self.mimetypes.list_mimetypes()).issuperset(set(missing_types)))
-
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testDCMIStorageUpdated(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        dcmi = getattr(oldsite.portal_metadata, 'DCMI', None)
-        self.assertFalse(dcmi is None)
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v2_5_0))
-    suite.addTest(makeSuite(TestMigrations_v2_5_1))
-    suite.addTest(makeSuite(TestMigrations_v2_5_2))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v30/tests.py b/plone/app/upgrade/v30/tests.py
deleted file mode 100644
index 9325d0d..0000000
--- a/plone/app/upgrade/v30/tests.py
+++ /dev/null
@@ -1,1109 +0,0 @@
-from Acquisition import aq_base
-
-from five.localsitemanager.registry import FiveVerifyingAdapterLookup
-
-from plone.contentrules.engine.interfaces import IRuleStorage
-from plone.app.i18n.locales.interfaces import IContentLanguages
-from plone.app.i18n.locales.interfaces import ICountries
-from plone.app.i18n.locales.interfaces import IMetadataLanguages
-from plone.app.portlets import portlets
-from plone.app.redirector.interfaces import IRedirectionStorage
-from plone.portlets.interfaces import IPortletManager
-from plone.portlets.interfaces import IPortletAssignmentMapping
-from plone.portlets.interfaces import ILocalPortletAssignmentManager
-from plone.portlets.constants import CONTEXT_CATEGORY as CONTEXT_PORTLETS
-
-from zope.location.interfaces import ISite
-from zope.component import getGlobalSiteManager
-from zope.component import getSiteManager
-from zope.component import getUtility, getMultiAdapter
-from zope.component.hooks import clearSite
-
-from Products.Archetypes.interfaces import IArchetypeTool
-from Products.Archetypes.interfaces import IReferenceCatalog
-from Products.Archetypes.interfaces import IUIDCatalog
-from Products.CMFActionIcons.interfaces import IActionIconsTool
-from Products.CMFCalendar.interfaces import ICalendarTool
-from Products.CMFCore.ActionInformation import Action
-from Products.CMFCore.ActionInformation import ActionCategory
-from Products.CMFCore.utils import getToolByName
-from Products.CMFCore.utils import getToolInterface
-from Products.CMFCore.Expression import Expression
-from Products.CMFCore.permissions import AccessInactivePortalContent
-from Products.CMFCore.interfaces import IActionsTool
-from Products.CMFCore.interfaces import ICachingPolicyManager
-from Products.CMFCore.interfaces import ICatalogTool
-from Products.CMFCore.interfaces import IContentTypeRegistry
-from Products.CMFCore.interfaces import IDiscussionTool
-from Products.CMFCore.interfaces import IMemberDataTool
-from Products.CMFCore.interfaces import IMembershipTool
-from Products.CMFCore.interfaces import IMetadataTool
-from Products.CMFCore.interfaces import IPropertiesTool
-from Products.CMFCore.interfaces import IRegistrationTool
-from Products.CMFCore.interfaces import ISiteRoot
-from Products.CMFCore.interfaces import ISkinsTool
-from Products.CMFCore.interfaces import ISyndicationTool
-from Products.CMFCore.interfaces import ITypesTool
-from Products.CMFCore.interfaces import IURLTool
-from Products.CMFCore.interfaces import IConfigurableWorkflowTool
-from Products.CMFCore.ActionInformation import ActionInformation
-from Products.CMFDiffTool.interfaces import IDiffTool
-from Products.CMFEditions.interfaces import IArchivistTool
-from Products.CMFEditions.interfaces import IPortalModifierTool
-from Products.CMFEditions.interfaces import IPurgePolicyTool
-from Products.CMFEditions.interfaces.IRepository import IRepositoryTool
-from Products.CMFEditions.interfaces import IStorageTool
-from Products.CMFFormController.interfaces import IFormControllerTool
-from Products.CMFQuickInstallerTool.interfaces import IQuickInstallerTool
-from Products.CMFPlone.interfaces import IPloneSiteRoot
-from Products.CMFPlone.interfaces import IPloneTool
-from Products.CMFPlone.interfaces import ITranslationServiceTool
-from Products.CMFUid.interfaces import IUniqueIdAnnotationManagement
-from Products.CMFUid.interfaces import IUniqueIdGenerator
-from Products.CMFUid.interfaces import IUniqueIdHandler
-from Products.GenericSetup.interfaces import ISetupTool
-from Products.MailHost.interfaces import IMailHost
-from Products.MimetypesRegistry.interfaces import IMimetypesRegistryTool
-from Products.PortalTransforms.interfaces import IPortalTransformsTool
-from Products.PloneLanguageTool.interfaces import ILanguageTool
-from Products.PlonePAS.interfaces.group import IGroupTool
-from Products.PlonePAS.interfaces.group import IGroupDataTool
-from Products.ResourceRegistries.interfaces import ICSSRegistry
-from Products.ResourceRegistries.interfaces import IJSRegistry
-
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.utils import loadMigrationProfile
-
-from plone.app.upgrade.v30.alphas import enableZope3Site
-from plone.app.upgrade.v30.alphas import migrateOldActions
-from plone.app.upgrade.v30.alphas import updateActionsI18NDomain
-from plone.app.upgrade.v30.alphas import updateFTII18NDomain
-from plone.app.upgrade.v30.alphas import convertLegacyPortlets
-from plone.app.upgrade.v30.alphas import registerToolsAsUtilities
-from plone.app.upgrade.v30.alphas import registration
-from plone.app.upgrade.v30.alphas import addReaderAndEditorRoles
-from plone.app.upgrade.v30.alphas import migrateLocalroleForm
-from plone.app.upgrade.v30.alphas import reorderUserActions
-from plone.app.upgrade.v30.alphas import updatePASPlugins
-from plone.app.upgrade.v30.alphas import updateConfigletTitles
-from plone.app.upgrade.v30.alphas import addCacheForResourceRegistry
-from plone.app.upgrade.v30.alphas import removeTablelessSkin
-from plone.app.upgrade.v30.alphas import addObjectProvidesIndex
-from plone.app.upgrade.v30.alphas import restorePloneTool
-from plone.app.upgrade.v30.alphas import installProduct
-
-from plone.app.upgrade.v30.betas import migrateHistoryTab
-from plone.app.upgrade.v30.betas import changeOrderOfActionProviders
-from plone.app.upgrade.v30.betas import cleanupOldActions
-from plone.app.upgrade.v30.betas import cleanDefaultCharset
-from plone.app.upgrade.v30.betas import addAutoGroupToPAS
-from plone.app.upgrade.v30.betas import removeS5Actions
-from plone.app.upgrade.v30.betas import addContributorToCreationPermissions
-from plone.app.upgrade.v30.betas import removeSharingAction
-from plone.app.upgrade.v30.betas import addEditorToSecondaryEditorPermissions
-from plone.app.upgrade.v30.betas import updateEditActionConditionForLocking
-from plone.app.upgrade.v30.betas import addOnFormUnloadJS
-
-from plone.app.upgrade.v30.betas import updateTopicTitle
-from plone.app.upgrade.v30.betas import cleanupActionProviders
-from plone.app.upgrade.v30.betas import hidePropertiesAction
-
-from plone.app.upgrade.v30.rcs import addIntelligentText
-
-from plone.app.upgrade.v30.final_three0x import installNewModifiers
-
-try:
-    from Products.ATContentTypes.interface import IATCTTool
-    HAS_ATCT = True
-except ImportError:
-    HAS_ATCT = False
-
-try:
-    from Products.CMFPlone.interfaces import IFactoryTool
-except:
-    from Products.ATContentTypes.interfaces import IFactoryTool
-
-
-class TestMigrations_v3_0_Actions(MigrationTest):
-
-    def afterSetUp(self):
-        self.actions = self.portal.portal_actions
-        self.types = self.portal.portal_types
-        self.workflow = self.portal.portal_workflow
-        self._migrate_reply_action()
-
-    def _migrate_reply_action(self):
-        # Create dummy old ActionInformation
-        reply = ActionInformation('reply',
-            title='Reply',
-            category='reply_actions',
-            condition='context/replyAllowed',
-            permissions=(AccessInactivePortalContent, ),
-            priority=10,
-            visible=True,
-            action='context/reply'
-        )
-
-        from OFS.SimpleItem import SimpleItem
-        class DummyTool(SimpleItem):
-            pass
-        dummy = DummyTool()
-        dummy._actions = (reply,)
-        self.portal._setObject('dummy', dummy)
-
-    def testMigrateActions(self):
-        # Test it twice
-        for i in range(2):
-            migrateOldActions(self.portal)
-            reply_actions = getattr(self.actions, 'reply_actions', None)
-            self.assertFalse(reply_actions is None)
-            reply = getattr(reply_actions, 'reply', None)
-            self.assertFalse(reply is None)
-            self.assertTrue(isinstance(reply, Action))
-            # Verify all data has been upgraded correctly to the new Action
-            data = reply.getInfoData()[0]
-            self.assertEqual(data['category'], 'reply_actions')
-            self.assertEqual(data['title'], 'Reply')
-            self.assertEqual(data['visible'], True)
-            self.assertEqual(data['permissions'], (AccessInactivePortalContent, ))
-            self.assertEqual(data['available'].text, 'context/replyAllowed')
-            self.assertEqual(data['url'].text, 'context/reply')
-            # Make sure the original action has been removed
-            self.assertEqual(len(self.portal.dummy._actions), 0)
-
-    def testUpdateActionsI18NDomain(self):
-        migrateOldActions(self.portal)
-        reply = self.actions.reply_actions.reply
-        self.assertEqual(reply.i18n_domain, '')
-        # Test it twice
-        for i in range(2):
-            updateActionsI18NDomain(self.portal)
-            self.assertEqual(reply.i18n_domain, 'plone')
-
-    def testUpdateActionsI18NDomainNonAscii(self):
-        migrateOldActions(self.portal)
-        reply = self.actions.reply_actions.reply
-        reply.title = 'Foo\xc3'
-        self.assertEqual(reply.i18n_domain, '')
-        self.assertEqual(reply.title, 'Foo\xc3')
-
-        updateActionsI18NDomain(self.portal)
-
-        self.assertEqual(reply.i18n_domain, '')
-
-    def testHistoryActionID(self):
-        # Test it twice
-        for i in range(2):
-            migrateHistoryTab(self.portal)
-            objects = getattr(self.actions, 'object', None)
-            self.assertFalse('rss' in objects.objectIds())
-
-    def testProviderCleanup(self):
-        self.actions.addActionProvider("portal_membership")
-        self.assertTrue("portal_membership" in self.actions.listActionProviders())
-        # Test it twice
-        for i in range(2):
-            cleanupActionProviders(self.portal)
-            self.assertFalse("portal_membership" in self.actions.listActionProviders())
-
-    def testRemovePropertiesActions(self):
-        ti = self.types.getTypeInfo("Document")
-        if ti.getActionObject("object/properties") is None:
-            ti.addAction("metadata", "name", "action", "condition",
-                    "permission", "object",)
-        # Test it twice
-        for i in range(2):
-            hidePropertiesAction(self.portal)
-            self.assertTrue(ti.getActionObject("object/metadata") is None)
-
-    def tearDown(self):
-        self.portal._delObject('dummy')
-
-
-class TestMigrations_v2_5_x(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v30:2.5.x-3.0a1'
-        self.types = self.portal.portal_types
-        self.properties = self.portal.portal_properties
-
-        for legacy_tool in ('portal_discussion', 'portal_actionicons'):
-            if legacy_tool not in self.portal:
-                from OFS.SimpleItem import SimpleItem
-                self.portal._setObject(legacy_tool, SimpleItem())
-
-    def disableSite(self, obj, iface=ISite):
-        # We need our own disableSite method as the CMF portal implements
-        # ISite directly, so we cannot remove it, like the disableSite method
-        # in Five.component would have done
-        from ZPublisher.BeforeTraverse import unregisterBeforeTraverse
-        from Products.Five.component import HOOK_NAME
-        obj = aq_base(obj)
-        if not iface.providedBy(obj):
-            raise TypeError('Object must be a site.')
-        unregisterBeforeTraverse(obj, HOOK_NAME)
-        if hasattr(obj, HOOK_NAME):
-            delattr(obj, HOOK_NAME)
-
-    def testEnableZope3Site(self):
-        # First we remove the site and site manager
-        self.disableSite(self.portal)
-        clearSite(self.portal)
-        self.portal.setSiteManager(None)
-        gsm = getGlobalSiteManager()
-        # Test it twice
-        for i in range(2):
-            enableZope3Site(self.portal)
-            # And see if we have an ISite with a local site manager
-            self.assertTrue(ISite.providedBy(self.portal))
-            sm = getSiteManager(self.portal)
-            self.assertFalse(gsm is sm)
-            lc = sm.utilities.LookupClass
-            self.assertEqual(lc, FiveVerifyingAdapterLookup)
-
-        # Test the lookupclass migration
-        sm.utilities.LookupClass = None
-        # Test it twice
-        for i in range(2):
-            enableZope3Site(self.portal)
-            self.assertEqual(sm.utilities.LookupClass, FiveVerifyingAdapterLookup)
-            self.assertEqual(sm.utilities.__parent__, sm)
-            self.assertEqual(sm.__parent__, self.portal)
-
-    def testUpdateFTII18NDomain(self):
-        doc = self.types.Document
-        doc.i18n_domain = ''
-        # Test it twice
-        for i in range(2):
-            updateFTII18NDomain(self.portal)
-            self.assertEqual(doc.i18n_domain, 'plone')
-
-    def testUpdateFTII18NDomainNonAscii(self):
-        doc = self.types.Document
-        doc.i18n_domain = ''
-        doc.title = 'Foo\xc3'
-        # Update FTI's
-        updateFTII18NDomain(self.portal)
-        # domain should have been updated
-        self.assertEqual(doc.i18n_domain, '')
-
-    def testAddDefaultAndForbiddenContentTypesProperties(self):
-        # Should add the forbidden_contenttypes and default_contenttype property
-        self.removeSiteProperty('forbidden_contenttypes')
-        self.removeSiteProperty('default_contenttype')
-        self.assertFalse(self.properties.site_properties.hasProperty('forbidden_contenttypes'))
-        self.assertFalse(self.properties.site_properties.hasProperty('default_contenttype'))
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('propertiestool', ))
-            self.assertTrue(self.properties.site_properties.hasProperty('forbidden_contenttypes'))
-            self.assertTrue(self.properties.site_properties.hasProperty('default_contenttype'))
-            self.assertEqual(self.properties.site_properties.forbidden_contenttypes,
-                ('text/structured', 'text/restructured', 'text/x-rst',
-                'text/plain', 'text/plain-pre', 'text/x-python',
-                'text/x-web-markdown', 'text/x-web-intelligent', 'text/x-web-textile')
-            )
-
-    def testTablelessRemoval(self):
-        st = getToolByName(self.portal, "portal_skins")
-        if "Plone Tableless" not in st.getSkinSelections():
-            st.addSkinSelection('Plone Tableless', 'one,two', make_default=True)
-        # Test it twice
-        for i in range(2):
-            removeTablelessSkin(self.portal)
-            self.assertFalse('Plone Tableless' in st.getSkinSelections())
-            self.assertFalse(st.default_skin == 'Plone Tableless')
-
-    def testLegacyPortletsConverted(self):
-        self.setRoles(('Manager',))
-        leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
-        rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        for k in left:
-            del left[k]
-        for k in right:
-            del right[k]
-
-        self.portal.left_slots = ['here/portlet_recent/macros/portlet',
-                                  'here/portlet_news/macros/portlet',
-                                  'here/portlet_related/macros/portlet']
-        self.portal.right_slots = ['here/portlet_login/macros/portlet',
-                                   'here/portlet_languages/macros/portlet']
-
-        self.portal.Members.right_slots = []
-
-        # Test it twice
-        for i in range(2):
-            convertLegacyPortlets(self.portal)
-
-            self.assertEqual(self.portal.left_slots, [])
-            self.assertEqual(self.portal.right_slots, [])
-
-            left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-            right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-            lp = left.values()
-            self.assertEqual(2, len(lp))
-
-            self.assertTrue(isinstance(lp[0], portlets.recent.Assignment))
-            self.assertTrue(isinstance(lp[1], portlets.news.Assignment))
-
-            rp = right.values()
-            self.assertEqual(1, len(rp))
-            self.assertTrue(isinstance(rp[0], portlets.login.Assignment))
-
-            members = self.portal.Members
-            portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
-            self.assertEqual(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
-
-    def testLegacyPortletsConvertedNoSlots(self):
-        self.setRoles(('Manager',))
-        leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
-        rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        for k in left:
-            del left[k]
-        for k in right:
-            del right[k]
-
-        self.portal.left_slots = ['here/portlet_recent/macros/portlet',
-                                  'here/portlet_news/macros/portlet']
-
-        self.portal.Members.right_slots = []
-
-        if hasattr(self.portal.aq_base, 'right_slots'):
-            delattr(self.portal, 'right_slots')
-
-        convertLegacyPortlets(self.portal)
-
-        self.assertEqual(self.portal.left_slots, [])
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        lp = left.values()
-        self.assertEqual(2, len(lp))
-
-        self.assertTrue(isinstance(lp[0], portlets.recent.Assignment))
-        self.assertTrue(isinstance(lp[1], portlets.news.Assignment))
-
-        rp = right.values()
-        self.assertEqual(0, len(rp))
-
-        members = self.portal.Members
-        portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
-        self.assertEqual(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
-
-    def testLegacyPortletsConvertedBadSlots(self):
-        self.setRoles(('Manager',))
-        leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
-        rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        for k in left:
-            del left[k]
-        for k in right:
-            del right[k]
-
-        self.portal.left_slots = ['here/portlet_recent/macros/portlet',
-                                  'here/portlet_news/macros/portlet',
-                                  'foobar',]
-        self.portal.right_slots = ['here/portlet_login/macros/portlet']
-
-        self.portal.Members.right_slots = []
-
-        convertLegacyPortlets(self.portal)
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        self.assertEqual(self.portal.left_slots, [])
-        self.assertEqual(self.portal.right_slots, [])
-
-        lp = left.values()
-        self.assertEqual(2, len(lp))
-
-        self.assertTrue(isinstance(lp[0], portlets.recent.Assignment))
-        self.assertTrue(isinstance(lp[1], portlets.news.Assignment))
-
-        rp = right.values()
-        self.assertEqual(1, len(rp))
-        self.assertTrue(isinstance(rp[0], portlets.login.Assignment))
-
-        members = self.portal.Members
-        portletAssignments = getMultiAdapter((members, rightColumn,), ILocalPortletAssignmentManager)
-        self.assertEqual(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))
-
-    def testLegacyPortletsConvertedNoMembersFolder(self):
-        self.setRoles(('Manager',))
-        leftColumn = getUtility(IPortletManager, name=u'plone.leftcolumn', context=self.portal)
-        rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.portal)
-
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        for k in left:
-            del left[k]
-        for k in right:
-            del right[k]
-
-        self.portal.left_slots = ['here/portlet_recent/macros/portlet',
-                                  'here/portlet_news/macros/portlet',
-                                  'foobar',]
-        self.portal.right_slots = ['here/portlet_login/macros/portlet']
-
-        self.portal._delObject('Members')
-
-        convertLegacyPortlets(self.portal)
-        left = getMultiAdapter((self.portal, leftColumn,), IPortletAssignmentMapping, context=self.portal)
-        right = getMultiAdapter((self.portal, rightColumn,), IPortletAssignmentMapping, context=self.portal)
-
-        self.assertEqual(self.portal.left_slots, [])
-        self.assertEqual(self.portal.right_slots, [])
-
-        lp = left.values()
-        self.assertEqual(2, len(lp))
-
-        self.assertTrue(isinstance(lp[0], portlets.recent.Assignment))
-        self.assertTrue(isinstance(lp[1], portlets.news.Assignment))
-
-        rp = right.values()
-        self.assertEqual(1, len(rp))
-        self.assertTrue(isinstance(rp[0], portlets.login.Assignment))
-
-    def testRegisterToolsAsUtilities(self):
-        sm = getSiteManager(self.portal)
-        interfaces = (ISiteRoot, IPloneSiteRoot,
-                      IActionIconsTool, ISyndicationTool,
-                      IMetadataTool, IPropertiesTool, IMailHost,
-                      IUniqueIdAnnotationManagement, IUniqueIdGenerator,
-                      IDiffTool, IMimetypesRegistryTool,
-                      IPortalTransformsTool, IDiscussionTool, )
-        if HAS_ATCT:
-            interfaces += (IATCTTool,)
-        for i in interfaces:
-            sm.unregisterUtility(provided=i)
-        registerToolsAsUtilities(self.portal)
-        for i in interfaces:
-            self.assertFalse(sm.queryUtility(i) is None)
-
-        for i in interfaces:
-            sm.unregisterUtility(provided=i)
-        registerToolsAsUtilities(self.portal)
-        registerToolsAsUtilities(self.portal)
-        for i in interfaces:
-            self.assertFalse(sm.queryUtility(i) is None)
-
-    def testDontRegisterToolsAsUtilities(self):
-        sm = getSiteManager(self.portal)
-        interfaces = (ILanguageTool, IArchivistTool, IPortalModifierTool,
-                      IPurgePolicyTool, IRepositoryTool, IStorageTool,
-                      IFormControllerTool, IReferenceCatalog, IUIDCatalog,
-                      ICalendarTool, IActionsTool, ICatalogTool,
-                      IContentTypeRegistry, ISkinsTool, ITypesTool, IURLTool,
-                      IConfigurableWorkflowTool, IPloneTool, ICSSRegistry,
-                      IJSRegistry, IUniqueIdHandler, IFactoryTool,
-                      IMembershipTool, IGroupTool, IGroupDataTool,
-                      IMemberDataTool, IArchetypeTool, ICachingPolicyManager,
-                      IRegistrationTool, ITranslationServiceTool,
-                      ISetupTool, IQuickInstallerTool,
-                     )
-        for i in interfaces:
-            sm.unregisterUtility(provided=i)
-        registerToolsAsUtilities(self.portal)
-        for i in interfaces:
-            self.assertTrue(sm.queryUtility(i) is None)
-
-        for i in interfaces:
-            sm.unregisterUtility(provided=i)
-        registerToolsAsUtilities(self.portal)
-        registerToolsAsUtilities(self.portal)
-        for i in interfaces:
-            self.assertTrue(sm.queryUtility(i) is None)
-
-    def testToolRegistration(self):
-        for (tool_id, interface) in registration:
-            self.assertEqual(getToolInterface(tool_id), interface)
-
-
-class TestMigrations_v3_0_alpha1(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v30:3.0a1-3.0a2'
-        self.actions = self.portal.portal_actions
-
-    def testInstallRedirectorUtility(self):
-        sm = getSiteManager(self.portal)
-        sm.unregisterUtility(provided=IRedirectionStorage)
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('componentregistry', ))
-            self.assertFalse(sm.queryUtility(IRedirectionStorage) is None)
-
-    def testAddReaderEditorRoles(self):
-        self.portal._delRoles(['Reader', 'Editor'])
-        # Test it twice
-        for i in range(2):
-            addReaderAndEditorRoles(self.portal)
-            self.assertTrue('Reader' in self.portal.valid_roles())
-            self.assertTrue('Editor' in self.portal.valid_roles())
-            self.assertTrue('Reader' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            self.assertTrue('Editor' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            self.assertTrue('View' in [r['name'] for r in self.portal.permissionsOfRole('Reader') if r['selected']])
-            self.assertTrue('Modify portal content' in [r['name'] for r in self.portal.permissionsOfRole('Editor') if r['selected']])
-
-    def testAddReaderEditorRolesPermissionOnly(self):
-        self.portal.manage_permission('View', [], True)
-        self.portal.manage_permission('Modify portal content', [], True)
-        # Test it twice
-        for i in range(2):
-            addReaderAndEditorRoles(self.portal)
-            self.assertTrue('Reader' in self.portal.valid_roles())
-            self.assertTrue('Editor' in self.portal.valid_roles())
-            self.assertTrue('Reader' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            self.assertTrue('Editor' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            self.assertTrue('View' in [r['name'] for r in self.portal.permissionsOfRole('Reader') if r['selected']])
-            self.assertTrue('Modify portal content' in [r['name'] for r in self.portal.permissionsOfRole('Editor') if r['selected']])
-
-    def testMigrateLocalroleForm(self):
-        fti = self.portal.portal_types['Document']
-        aliases = fti.getMethodAliases()
-        aliases['sharing'] = 'folder_localrole_form'
-        fti.setMethodAliases(aliases)
-        fti.addAction('test', 'Test', 'string:${object_url}/folder_localrole_form', None, 'View', 'object')
-        # Test it twice
-        for i in range(2):
-            migrateLocalroleForm(self.portal)
-            self.assertEqual('@@sharing', fti.getMethodAliases()['sharing'])
-            test_action = fti.listActions()[-1]
-            self.assertEqual('string:${object_url}/@@sharing', test_action.getActionExpression())
-
-    def testReorderUserActions(self):
-        self.actions.user.moveObjectsToTop(['logout', 'undo', 'join'])
-        # Test it twice
-        for i in range(2):
-            reorderUserActions(self.portal)
-            # build a dict that has the position as the value to make it easier
-            # to compare postions in the ordered list of actions
-            n = 0
-            sort = {}
-            for action in self.actions.user.objectIds():
-                sort[action] = n
-                n += 1
-            self.assertTrue(sort['preferences'] < sort['undo'])
-            self.assertTrue(sort['undo'] < sort['logout'])
-            self.assertTrue(sort['login'] < sort['join'])
-
-    def testReorderUserActionsIncompleteActions(self):
-        self.actions.user.moveObjectsToTop(['logout', 'undo', 'join'])
-        self.actions.user._delObject('preferences')
-        # Test it twice
-        for i in range(2):
-            reorderUserActions(self.portal)
-            n = 0
-            sort = {}
-            for action in self.actions.user.objectIds():
-                sort[action] = n
-                n += 1
-            self.assertTrue(sort['undo'] < sort['logout'])
-            self.assertTrue(sort['login'] < sort['join'])
-
-
-class TestMigrations_v3_0_alpha2(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v30:3.0a2-3.0b1'
-        self.actions = self.portal.portal_actions
-        self.properties = self.portal.portal_properties
-        self.cp = self.portal.portal_controlpanel
-
-    def testAddVariousProperties(self):
-        PROPERTIES = ('enable_link_integrity_checks', 'enable_sitemap',
-                      'external_links_open_new_window', 'many_groups',
-                      'number_of_days_to_keep', 'webstats_js')
-        for prop in PROPERTIES:
-            self.removeSiteProperty(prop)
-        sheet = self.properties.site_properties
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('propertiestool', ))
-            for prop in PROPERTIES:
-                self.assertTrue(sheet.hasProperty(prop))
-
-    def testInstallContentrulesAndLanguageUtilities(self):
-        sm = getSiteManager()
-        INTERFACES = (IRuleStorage, ICountries, IContentLanguages,
-                      IMetadataLanguages)
-        for i in INTERFACES:
-            sm.unregisterUtility(provided=i)
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('componentregistry', ))
-            for i in INTERFACES:
-                self.assertFalse(sm.queryUtility(i) is None)
-
-    def testAddEmailCharsetProperty(self):
-        if self.portal.hasProperty('email_charset'):
-            self.portal.manage_delProperties(['email_charset'])
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('properties', ))
-            self.assertTrue(self.portal.hasProperty('email_charset'))
-            self.assertEqual(self.portal.getProperty('email_charset'), 'utf-8')
-
-    def testUpdateMemberSecurity(self):
-        pprop = getToolByName(self.portal, 'portal_properties')
-        self.assertEqual(
-                pprop.site_properties.getProperty('allowAnonymousViewAbout'),
-                False)
-
-        pmembership = getToolByName(self.portal, 'portal_membership')
-        self.assertEqual(pmembership.memberareaCreationFlag, False)
-        self.assertEqual(self.portal.getProperty('validate_email'), True)
-
-        app_roles = self.portal.rolesOfPermission(permission='Add portal member')
-        app_perms = self.portal.permission_settings(permission='Add portal member')
-        acquire_check = app_perms[0]['acquire']
-        reg_roles = []
-        for appperm in app_roles:
-            if appperm['selected'] == 'SELECTED':
-                reg_roles.append(appperm['name'])
-        self.assertTrue('Manager' in reg_roles)
-        self.assertTrue('Owner' in reg_roles)
-        self.assertEqual(acquire_check, '')
-
-    def testPASPluginInterfaces(self):
-        pas = self.portal.acl_users
-        from Products.PluggableAuthService.interfaces.plugins import IUserEnumerationPlugin
-        pas.plugins.deactivatePlugin(IUserEnumerationPlugin, 'mutable_properties')
-        updatePASPlugins(self.portal)
-
-        plugin = pas.mutable_properties
-        for intf_id in plugin.listInterfaces():
-            try:
-                intf = pas.plugins._getInterfaceFromName(intf_id)
-                self.assertTrue('mutable_properties' in pas.plugins.listPluginIds(intf))
-            except KeyError:
-                # Ignore unregistered interface types
-                pass
-
-    def testUpdateConfigletTitles(self):
-        collection = self.cp.getActionObject('Plone/portal_atct')
-        language = self.cp.getActionObject('Plone/PloneLanguageTool')
-        navigation = self.cp.getActionObject('Plone/NavigationSettings')
-        types = self.cp.getActionObject('Plone/TypesSettings')
-        users = self.cp.getActionObject('Plone/UsersGroups')
-        users2 = self.cp.getActionObject('Plone/UsersGroups2')
-        # test it twice
-        for i in range(2):
-            updateConfigletTitles(self.portal)
-            self.assertEqual(collection.title, 'Collection')
-            self.assertEqual(language.title, 'Language')
-            self.assertEqual(navigation.title, 'Navigation')
-            self.assertEqual(types.title, 'Types')
-            self.assertEqual(users.title, 'Users and Groups')
-            self.assertEqual(users2.title, 'Users and Groups')
-
-    def testAddCacheForResourceRegistry(self):
-        ram_cache_id = 'ResourceRegistryCache'
-        # first remove the cache manager and make sure it's removed
-        self.portal._delObject(ram_cache_id)
-        self.assertFalse(ram_cache_id in self.portal.objectIds())
-        cssreg = self.portal.portal_css
-        cssreg.ZCacheable_setEnabled(0)
-        cssreg.ZCacheable_setManagerId(None)
-        self.assertFalse(cssreg.ZCacheable_enabled())
-        self.assertTrue(cssreg.ZCacheable_getManagerId() is None)
-        jsreg = self.portal.portal_javascripts
-        jsreg.ZCacheable_setEnabled(0)
-        jsreg.ZCacheable_setManagerId(None)
-        self.assertFalse(jsreg.ZCacheable_enabled())
-        self.assertTrue(jsreg.ZCacheable_getManagerId() is None)
-        # Test it twice
-        for i in range(2):
-            addCacheForResourceRegistry(self.portal)
-            self.assertTrue(ram_cache_id in self.portal.objectIds())
-            self.assertTrue(cssreg.ZCacheable_enabled())
-            self.assertFalse(cssreg.ZCacheable_getManagerId() is None)
-            self.assertTrue(jsreg.ZCacheable_enabled())
-            self.assertFalse(jsreg.ZCacheable_getManagerId() is None)
-
-    def testObjectProvidesIndex(self):
-        catalog = getToolByName(self.portal, 'portal_catalog')
-        if 'object_provides' in catalog.indexes():
-            catalog.delIndex('object_provides')
-        self.assertFalse('object_provides' in catalog.indexes())
-        # Test it twice
-        for i in range(2):
-            addObjectProvidesIndex(self.portal)
-            self.assertTrue('object_provides' in catalog.indexes())
-
-    def testMigratePloneTool(self):
-        tool = self.portal.plone_utils
-        tool.meta_type = 'PlonePAS Utilities Tool'
-        # Test it twice
-        for i in range(2):
-            restorePloneTool(self.portal)
-            tool = self.portal.plone_utils
-            self.assertEqual('Plone Utility Tool', tool.meta_type)
-
-    def testInstallPloneLanguageTool(self):
-        super(self.portal.__class__, self.portal).manage_delObjects(
-            ['portal_languages'])
-        self.uninstallProduct('PloneLanguageTool')
-        qi = getToolByName(self.portal, "portal_quickinstaller")
-        # Test it twice
-        for i in range(2):
-            installProduct('PloneLanguageTool', self.portal)
-            self.assertTrue(qi.isProductInstalled('PloneLanguageTool'))
-            self.assertTrue('portal_languages' in self.portal.keys())
-
-
-class TestMigrations_v3_0(MigrationTest):
-
-    def afterSetUp(self):
-        self.profile = 'profile-plone.app.upgrade.v30:3.0b1-3.0b2'
-        self.actions = self.portal.portal_actions
-        self.skins = self.portal.portal_skins
-        self.types = self.portal.portal_types
-        self.workflow = self.portal.portal_workflow
-        self.properties = getToolByName(self.portal, 'portal_properties')
-
-    def testAddContentRulesAction(self):
-        self.portal.portal_actions.object._delObject('contentrules')
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal, self.profile, ('actions', ))
-            self.assertTrue('contentrules' in self.portal.portal_actions.object.objectIds())
-
-    def testChangeOrderOfActionProviders(self):
-        self.actions.deleteActionProvider('portal_types')
-        self.actions.addActionProvider('portal_types')
-        self.assertEqual(
-            self.actions.listActionProviders(),
-            ('portal_workflow', 'portal_actions', 'portal_types'))
-        # Test it twice
-        for i in range(2):
-            changeOrderOfActionProviders(self.portal)
-            self.assertEqual(
-                self.actions.listActionProviders(),
-                ('portal_workflow', 'portal_types', 'portal_actions'))
-
-    def testCleanupOldActions(self):
-        reply = Action('reply', title='Reply')
-        logged_in = Action('logged_in', title='Logged in')
-        change_ownership = Action('change_ownership', title='Change ownership')
-
-        object_ = self.actions.object
-        object_tabs = getattr(self.actions, 'object_tabs', None)
-        if object_tabs is None:
-            category = 'object_tabs'
-            self.actions._setObject(category, ActionCategory(id=category))
-            object_tabs = self.actions.object_tabs
-        if getattr(self.actions, 'global', None) is None:
-            category = 'global'
-            self.actions._setObject(category, ActionCategory(id=category))
-
-        if not 'reply' in object_.keys():
-            object_._setObject('reply', reply)
-        user = self.actions.user
-        if not 'logged_in' in user.keys():
-            user._setObject('logged_in', logged_in)
-        if not 'change_ownership' in object_tabs.keys():
-            object_tabs._setObject('change_ownership', change_ownership)
-        del object_tabs
-
-        # Test it twice
-        for i in range(2):
-            cleanupOldActions(self.portal)
-            self.assertFalse('reply' in object_.keys())
-            self.assertFalse('logged_in' in user.keys())
-            self.assertFalse('object_tabs' in self.actions.keys())
-            self.assertFalse('global' in self.actions.keys())
-
-    def testCharsetCleanup(self):
-        if not self.portal.hasProperty('default_charset'):
-            self.portal.manage_addProperty('default_charset', '', 'string')
-        # Test it twice
-        for i in range(2):
-            self.portal.manage_changeProperties(default_charset = 'latin1')
-            cleanDefaultCharset(self.portal)
-            self.assertEqual(self.portal.getProperty('default_charset', 'nothere'),
-                    'latin1')
-        # Test it twice
-        for i in range(2):
-            self.portal.manage_changeProperties(default_charset = '')
-            cleanDefaultCharset(self.portal)
-            self.assertEqual(self.portal.getProperty('default_charset', 'nothere'),
-                    'nothere')
-
-    def testAutoGroupCreated(self):
-        pas = self.portal.acl_users
-        ids = pas.objectIds(['Automatic Group Plugin'])
-        if ids:
-            pas.manage_delObjects(ids)
-        addAutoGroupToPAS(self.portal)
-        self.assertEqual(pas.objectIds(['Automatic Group Plugin']),
-                ['auto_group'])
-        plugin = pas.auto_group
-        interfaces = [info['interface'] for info in pas.plugins.listPluginTypeInfo()]
-        for iface in interfaces:
-            if plugin.testImplements(iface):
-                self.assertFalse('auto_group' not in pas.plugins.listPluginIds(iface))
-        self.assertEqual(len(pas.searchGroups(id='AuthenticatedUsers',
-                                              exact_match=True)), 1)
-
-    def testPloneS5(self):
-        pt = getToolByName(self.portal, "portal_types")
-        document = pt.restrictedTraverse('Document')
-        document.addAction('s5_presentation',
-            name='View as presentation',
-            action="string:${object/absolute_url}/document_s5_presentation",
-            condition='python:object.document_s5_alter(test=True)',
-            permission='View',
-            category='document_actions',
-            visible=1,
-            )
-        action_ids = [x.getId() for x in document.listActions()]
-        self.assertTrue("s5_presentation" in action_ids)
-        # Test it twice
-        for i in range(2):
-            removeS5Actions(self.portal)
-            action_ids = [x.getId() for x in document.listActions()]
-            self.assertFalse("s5_presentation" in action_ids)
-
-    def testAddContributorToCreationPermissions(self):
-        self.portal._delRoles(['Contributor',])
-        for p in ['Add portal content', 'Add portal folders', 'ATContentTypes: Add Document',
-                    'ATContentTypes: Add Event',
-                    'ATContentTypes: Add File', 'ATContentTypes: Add Folder',
-                    'ATContentTypes: Add Image', 'ATContentTypes: Add Link',
-                    'ATContentTypes: Add News Item', ]:
-            self.portal.manage_permission(p, ['Manager', 'Owner'], True)
-        # Test it twice
-        for i in range(2):
-            addContributorToCreationPermissions(self.portal)
-            self.assertTrue('Contributor' in self.portal.valid_roles())
-            self.assertTrue('Contributor' in self.portal.acl_users.portal_role_manager.listRoleIds())
-            for p in ['Add portal content', 'Add portal folders', 'ATContentTypes: Add Document',
-                        'ATContentTypes: Add Event',
-                        'ATContentTypes: Add File', 'ATContentTypes: Add Folder',
-                        'ATContentTypes: Add Image', 'ATContentTypes: Add Link',
-                        'ATContentTypes: Add News Item', ]:
-                self.assertTrue(p in [r['name'] for r in
-                                    self.portal.permissionsOfRole('Contributor') if r['selected']])
-
-    def testAddContributerToCreationPermissionsNoStomp(self):
-        self.portal.manage_permission('Add portal content', ['Manager'], False)
-        # Test it twice
-        for i in range(2):
-            addContributorToCreationPermissions(self.portal)
-            roles = sorted([r['name'] for r in self.portal.rolesOfPermission('Add portal content') if r['selected']])
-            self.assertEqual(['Contributor', 'Manager'], roles)
-            self.assertEqual(False, bool(self.portal.acquiredRolesAreUsedBy('Add portal content')))
-
-    def testAddBeta2VersioningPermissionsToNewRoles(self):
-        # This upgrade just uses GS to apply the role changes,
-        # these permissions will not have been installed previously,
-        # so this should be safe
-        for p in ['CMFEditions: Apply version control',
-                  'CMFEditions: Save new version',
-                  'CMFEditions: Access previous versions',
-                  'CMFEditions: Revert to previous versions',
-                  'CMFEditions: Checkout to location']:
-            self.portal.manage_permission(p, ['Manager', 'Owner'], True)
-        # Test it twice
-        for i in range(2):
-            loadMigrationProfile(self.portal,
-                    'profile-plone.app.upgrade.v30:3.0b1-3.0b2',
-                    steps=["rolemap"])
-            for p in ['CMFEditions: Apply version control',
-                      'CMFEditions: Save new version',
-                      'CMFEditions: Access previous versions']:
-                self.assertTrue(p in [r['name'] for r in
-                                    self.portal.permissionsOfRole('Contributor') if r['selected']])
-                self.assertTrue(p in [r['name'] for r in
-                                    self.portal.permissionsOfRole('Editor') if r['selected']])
-            for p in ['CMFEditions: Revert to previous versions',
-                      'CMFEditions: Checkout to location']:
-                self.assertTrue(p in [r['name'] for r in
-                                    self.portal.permissionsOfRole('Editor') if r['selected']])
-
-    def testRemoveSharingAction(self):
-        fti = self.types['Document']
-        fti.addAction(id='local_roles', name='Sharing',
-                      action='string:${object_url}/sharing',
-                      condition=None, permission='Manage properties',
-                      category='object')
-        # Test it twice
-        for i in range(2):
-            removeSharingAction(self.portal)
-            self.assertFalse('local_roles' in [a.id for a in fti.listActions()])
-
-    def testAddEditorToCreationPermissions(self):
-        for p in ['Manage properties', 'Modify view template', 'Request review']:
-            self.portal.manage_permission(p, ['Manager', 'Owner'], True)
-        # Test it twice
-        for i in range(2):
-            addEditorToSecondaryEditorPermissions(self.portal)
-            for p in ['Manage properties', 'Modify view template', 'Request review']:
-                self.assertTrue(p in [r['name'] for r in
-                    self.portal.permissionsOfRole('Editor') if r['selected']])
-
-    def testAddEditorToCreationPermissionsNoStomp(self):
-        self.portal.manage_permission('Manage properties', ['Manager'], False)
-        # Test it twice
-        for i in range(2):
-            addEditorToSecondaryEditorPermissions(self.portal)
-            roles = sorted([r['name'] for r in self.portal.rolesOfPermission('Manage properties') if r['selected']])
-            self.assertEqual(['Editor', 'Manager'], roles)
-            self.assertEqual(False, bool(self.portal.acquiredRolesAreUsedBy('Manage properties')))
-
-    def testUpdateEditActionConditionForLocking(self):
-        lockable_types = ['Document', 'Event', 'File', 'Folder',
-                          'Image', 'Link', 'News Item', 'Topic']
-        for contentType in lockable_types:
-            fti = self.types.getTypeInfo(contentType)
-            for action in fti.listActions():
-                if action.getId() == 'edit':
-                    action.condition = ''
-        # Test it twice
-        for i in range(2):
-            updateEditActionConditionForLocking(self.portal)
-            for contentType in lockable_types:
-                fti = self.types.getTypeInfo(contentType)
-                for action in fti.listActions():
-                    if action.getId() == 'edit':
-                        self.assertEqual(action.condition.text,
-                            "not:object/@@plone_lock_info/is_locked_for_current_user|python:True")
-
-    def testUpdateEditExistingActionConditionForLocking(self):
-        fti = self.types.getTypeInfo('Document')
-        for action in fti.listActions():
-            if action.getId() == 'edit':
-                action.condition = Expression("foo")
-        # Test it twice
-        for i in range(2):
-            updateEditActionConditionForLocking(self.portal)
-            fti = self.types.getTypeInfo('Document')
-            for action in fti.listActions():
-                if action.getId() == 'edit':
-                    self.assertEqual(action.condition.text, 'foo')
-
-    def testAddOnFormUnloadRegistrationJS(self):
-        jsreg = self.portal.portal_javascripts
-        # unregister first
-        jsreg.unregisterResource('unlockOnFormUnload.js')
-        script_ids = jsreg.getResourceIds()
-        self.assertFalse('unlockOnFormUnload.js' in script_ids)
-        # Test it twice
-        for i in range(2):
-            addOnFormUnloadJS(self.portal)
-            script_ids = jsreg.getResourceIds()
-            self.assertTrue('unlockOnFormUnload.js' in script_ids)
-
-    def testUpdateTopicTitle(self):
-        topic = self.types.get('Topic')
-        topic.title = 'Old'
-        # Test it twice
-        for i in range(2):
-            updateTopicTitle(self.portal)
-            self.assertEqual(topic.title, 'Collection')
-
-    def testAddIntelligentText(self):
-        # Before the upgrade, the mime type and transforms of intelligent text
-        # are not available. They *are* here in a fresh site, so we may need
-        # to remove them first for testing. First we remove the transforms,
-        # as they depend on the mimetype being there.
-        missing_transforms = ["web_intelligent_plain_text_to_html",
-                              "html_to_web_intelligent_plain_text"]
-        ptr = self.portal.portal_transforms
-        current_transforms = ptr.objectIds()
-        for trans in missing_transforms:
-            if trans in current_transforms:
-                ptr.unregisterTransform(trans)
-        # Then we remove the mime type
-        mime_type = 'text/x-web-intelligent'
-        mtr = self.portal.mimetypes_registry
-        current_types = mtr.list_mimetypes()
-        if mime_type in current_types:
-            mtr.manage_delObjects((mime_type,))
-        # now all are gone:
-        self.assertFalse(mime_type in mtr.list_mimetypes())
-        self.assertFalse(set(ptr.objectIds()).issuperset(set(missing_transforms)))
-        # Test it twice
-        for i in range(2):
-            addIntelligentText(self.portal)
-            # now all are back:
-            self.assertTrue(mime_type in mtr.list_mimetypes())
-            self.assertTrue(set(ptr.objectIds()).issuperset(set(missing_transforms)))
-
-    def testInstallNewModifiers(self):
-        # ensure the new modifiers are installed
-        modifiers = self.portal.portal_modifier
-        self.assertTrue('AbortVersioningOfLargeFilesAndImages' in
-                                                          modifiers.objectIds())
-        modifiers.manage_delObjects(['AbortVersioningOfLargeFilesAndImages',
-                                     'SkipVersioningOfLargeFilesAndImages'])
-        self.assertFalse('AbortVersioningOfLargeFilesAndImages' in
-                                                          modifiers.objectIds())
-        installNewModifiers(self.portal)
-        self.assertTrue('AbortVersioningOfLargeFilesAndImages' in
-                                                          modifiers.objectIds())
-        self.assertTrue('SkipVersioningOfLargeFilesAndImages' in
-                                                          modifiers.objectIds())
-
-    def testInstallNewModifiersTwice(self):
-        # ensure that we get no errors when run twice
-        installNewModifiers(self.portal)
-        installNewModifiers(self.portal)
-
-    def testInstallNewModifiersDoesNotStompChanges(self):
-        # ensure that reinstalling doesn't kill customizations
-        modifiers = self.portal.portal_modifier
-        modifiers.AbortVersioningOfLargeFilesAndImages.max_size = 1000
-        installNewModifiers(self.portal)
-        self.assertEqual(modifiers.AbortVersioningOfLargeFilesAndImages.max_size,
-                         1000)
-
-    def testInstallNewModifiersNoTool(self):
-        # make sure there are no errors if the tool is missing
-        self.portal._delObject('portal_modifier')
-        installNewModifiers(self.portal)
-
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testBaseUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFullUpgrade(self):
-        self.importFile(__file__, 'test-full.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v2_5_x))
-    suite.addTest(makeSuite(TestMigrations_v3_0_Actions))
-    suite.addTest(makeSuite(TestMigrations_v3_0_alpha1))
-    suite.addTest(makeSuite(TestMigrations_v3_0_alpha2))
-    suite.addTest(makeSuite(TestMigrations_v3_0))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v31/tests.py b/plone/app/upgrade/v31/tests.py
deleted file mode 100644
index 01005b3..0000000
--- a/plone/app/upgrade/v31/tests.py
+++ /dev/null
@@ -1,118 +0,0 @@
-from borg.localrole.utils import replace_local_role_manager
-from zope.interface import noLongerProvides
-
-from Products.PlonePAS.interfaces.plugins import ILocalRolesPlugin
-
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-
-from plone.app.upgrade.v31.betas import reinstallCMFPlacefulWorkflow
-
-
-class TestMigrations_v3_1(MigrationTest):
-
-    def afterSetUp(self):
-        self.qi = self.portal.portal_quickinstaller
-        self.wf = self.portal.portal_workflow
-        self.ps = self.portal.portal_setup
-
-    def testReinstallCMFPlacefulWorkflow(self):
-        try:
-            from Products.CMFPlacefulWorkflow.interfaces import IPlacefulMarker
-        except ImportError:
-            return
-        # first the product needs to be installed
-        self.qi.installProduct('CMFPlacefulWorkflow')
-        # Delete existing logs to prevent race condition
-        self.ps.manage_delObjects(self.ps.objectIds())
-        # We remove the new marker, to ensure it's added on reinstall
-        if IPlacefulMarker.providedBy(self.wf):
-            noLongerProvides(self.wf, IPlacefulMarker)
-        reinstallCMFPlacefulWorkflow(self.portal, [])
-        self.assertTrue(IPlacefulMarker.providedBy(self.wf))
-
-    def testReinstallCMFPlacefulWorkflowDoesNotInstall(self):
-        reinstallCMFPlacefulWorkflow(self.portal, [])
-        self.assertFalse(self.qi.isProductInstalled('CMFPlacefulWorkflow'))
-
-    def testReinstallCMFPlacefulWorkflowNoTool(self):
-        self.portal._delObject('portal_quickinstaller')
-        reinstallCMFPlacefulWorkflow(self.portal, [])
-
-    def testReplaceLocalRoleManager(self):
-        # first we replace the local role manager with the one from PlonePAS
-        uf = self.portal.acl_users
-        # deactivate and remove the borg plugin
-        uf.plugins.removePluginById('borg_localroles')
-        uf.manage_delObjects(['borg_localroles'])
-        # activate the standard plugin
-        uf.plugins.activatePlugin(ILocalRolesPlugin, 'local_roles')
-        # Bring things back to normal
-        replace_local_role_manager(self.portal)
-        plugins = uf.plugins.listPlugins(ILocalRolesPlugin)
-        self.assertEqual(len(plugins), 1)
-        self.assertEqual(plugins[0][0], 'borg_localroles')
-
-    def testReplaceLocalRoleManagerTwice(self):
-        # first we replace the local role manager with the one from PlonePAS
-        uf = self.portal.acl_users
-        # deactivate and remove the borg plugin
-        uf.plugins.removePluginById('borg_localroles')
-        uf.manage_delObjects(['borg_localroles'])
-        # activate the standard plugin
-        uf.plugins.activatePlugin(ILocalRolesPlugin, 'local_roles')
-        # run the upgrade twice
-        replace_local_role_manager(self.portal)
-        replace_local_role_manager(self.portal)
-        plugins = uf.plugins.listPlugins(ILocalRolesPlugin)
-        self.assertEqual(len(plugins), 1)
-        self.assertEqual(plugins[0][0], 'borg_localroles')
-
-    def testReplaceLocalRoleManagerNoPlugin(self):
-        # first we replace the local role manager with the one from PlonePAS
-        uf = self.portal.acl_users
-        # deactivate and remove the borg plugin
-        uf.plugins.removePluginById('borg_localroles')
-        uf.manage_delObjects(['borg_localroles'])
-        # delete the standard plugin
-        uf.manage_delObjects(['local_roles'])
-        # Run the upgrade, which shouldn't fail even if the expected
-        # plugin is missing
-        replace_local_role_manager(self.portal)
-        plugins = uf.plugins.listPlugins(ILocalRolesPlugin)
-        self.assertEqual(len(plugins), 1)
-        self.assertEqual(plugins[0][0], 'borg_localroles')
-
-    def testReplaceLocalRoleManagerNoPAS(self):
-        uf = self.portal.acl_users
-        # delete the plugin registry
-        uf._delObject('plugins')
-        replace_local_role_manager(self.portal)
-
-    def testReplaceLocalRoleManagerNoUF(self):
-        # Delete the user folder
-        replace_local_role_manager(self.portal)
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testBaseUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFullUpgrade(self):
-        self.importFile(__file__, 'test-full.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v3_1))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v32/tests.py b/plone/app/upgrade/v32/tests.py
deleted file mode 100644
index bc0e7a1..0000000
--- a/plone/app/upgrade/v32/tests.py
+++ /dev/null
@@ -1,50 +0,0 @@
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.v32.betas import three1_beta1
-
-class TestMigrations_v3_2(MigrationTest):
-
-    def afterSetUp(self):
-        self.qi = self.portal.portal_quickinstaller
-        self.actions = self.portal.portal_actions
-        self.migration = self.portal.portal_migration
-
-    def testIterateActionsMigratedIfIterateInstalled(self):
-        self.qi.installProduct('plone.app.iterate')
-        self.actions.object_buttons.iterate_checkin.permissions = (
-            'Modify portal content',)
-        three1_beta1(self.portal)
-        self.assertEqual(
-            self.actions.object_buttons.iterate_checkin.permissions,
-            ('iterate : Check in content',))
-
-    def testIterateInstalledButActionMissing(self):
-        self.qi.installProduct('plone.app.iterate')
-        self.actions.object_buttons.manage_delObjects(['iterate_checkin'])
-        three1_beta1(self.portal)
-        self.assertFalse('iterate_checkin' in
-                    self.actions.object_buttons.objectIds())
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testBaseUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFullUpgrade(self):
-        self.importFile(__file__, 'test-full.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v3_2))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v33/tests.py b/plone/app/upgrade/v33/tests.py
deleted file mode 100644
index 01a5de8..0000000
--- a/plone/app/upgrade/v33/tests.py
+++ /dev/null
@@ -1,93 +0,0 @@
-from Products.CMFCore.utils import getToolByName
-
-from plone.app.upgrade.tests.base import FunctionalUpgradeTestCase
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.v33 import three2_three3
-
-class TestMigrations_v3_3(MigrationTest):
-
-    def afterSetUp(self):
-        self.types = self.portal.portal_types
-        self.properties = getToolByName(self.portal, 'portal_properties')
-
-    def _upgrade(self):
-        three2_three3(self.portal)
-
-    def testRedirectLinksProperty(self):
-        del self.properties.site_properties.redirect_links
-        self._upgrade()
-        self.assertEqual(True,
-            self.properties.site_properties.getProperty('redirect_links'))
-
-    def testLinkDefaultView(self):
-        self.types.Link.default_view = 'link_view'
-        self.types.Link.immediate_view = 'link_view'
-        self.types.Link.view_methods = ('link_view',)
-        self._upgrade()
-        self.assertEqual(self.types.Link.default_view, 'link_redirect_view')
-        self.assertEqual(self.types.Link.immediate_view, 'link_redirect_view')
-        self.assertEqual(self.types.Link.view_methods, ('link_redirect_view',))
-
-    def testCustomizedLinkDefaultView(self):
-        # but only change if old default was 'link_view'
-        self.types.Link.default_view = 'foobar'
-        self.types.Link.immediate_view = 'foobar'
-        self.types.Link.view_methods = ('foobar',)
-        self._upgrade()
-        self.assertEqual(self.types.Link.default_view, 'foobar')
-        self.assertEqual(self.types.Link.immediate_view, 'foobar')
-        self.assertEqual(self.types.Link.view_methods, ('foobar',))
-
-class TestFunctionalMigrations(FunctionalUpgradeTestCase):
-
-    def testBaseUpgrade(self):
-        self.importFile(__file__, 'test-base.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFullUpgrade(self):
-        self.importFile(__file__, 'test-full.zexp')
-        oldsite, result = self.migrate()
-
-        mig = oldsite.portal_migration
-        self.assertFalse(mig.needUpgrading())
-
-    def testFolderUpgrade(self):
-        from plone.folder.interfaces import IOrderableFolder
-        self.importFile(__file__, 'test-full.zexp')
-        # `portal_type` and `Type` can be checked before migration...
-        oldsite = getattr(self.app, self.site_id)
-        ids = 'news', 'events', 'Members'
-        for id in ids:
-            obj = oldsite[id]
-            self.assertEqual(obj.portal_type, 'Large Plone Folder')
-            self.assertEqual(obj.Type(), 'Large Folder')
-            brain, = oldsite.portal_catalog(getId=id)   # asserts only one
-            self.assertEqual(brain.portal_type, 'Large Plone Folder')
-            self.assertEqual(brain.Type, 'Large Folder')
-        # now let's migrate...
-        oldsite, result = self.migrate()
-        self.assertFalse(oldsite.portal_migration.needUpgrading())
-        # after migration `/news`, `/events` and `/Members` are based on
-        # `plone.(app.)folder`, but still have no ordering set...
-        for id in ids:
-            obj = oldsite[id]
-            self.assertTrue(IOrderableFolder.providedBy(obj),
-                '%s not orderable?' % id)
-            self.assertEqual(obj._ordering, 'unordered',
-                '%s has no `_ordering`?' % id)
-            self.assertEqual(obj.portal_type, 'Folder')
-            self.assertEqual(obj.Type(), 'Folder')
-            brain, = oldsite.portal_catalog(getId=id)   # asserts only one
-            self.assertEqual(brain.portal_type, 'Folder')
-            self.assertEqual(brain.Type, 'Folder')
-
-
-def test_suite():
-    from unittest import TestSuite, makeSuite
-    suite = TestSuite()
-    suite.addTest(makeSuite(TestMigrations_v3_3))
-    suite.addTest(makeSuite(TestFunctionalMigrations))
-    return suite
diff --git a/plone/app/upgrade/v40/tests.py b/plone/app/upgrade/v40/tests.py
deleted file mode 100644
index c350619..0000000
--- a/plone/app/upgrade/v40/tests.py
+++ /dev/null
@@ -1,666 +0,0 @@
-import time
-
-from zope.component import getMultiAdapter
-from zope.component import getSiteManager
-from zope.component import getUtility
-from zope.component import queryUtility
-from zope.ramcache.interfaces.ram import IRAMCache
-
-from Products.CMFCore.ActionInformation import Action
-from Products.CMFCore.Expression import Expression
-from Products.CMFCore.utils import getToolByName
-from Products.MailHost.interfaces import IMailHost
-
-from plone.app.upgrade.utils import loadMigrationProfile
-from plone.app.upgrade.v40.alphas import _KNOWN_ACTION_ICONS
-from plone.app.upgrade.v40.alphas import migrateActionIcons
-from plone.app.upgrade.v40.alphas import migrateTypeIcons
-from plone.app.upgrade.v40.alphas import addOrReplaceRamCache
-from plone.app.upgrade.v40.alphas import changeWorkflowActorVariableExpression
-from plone.app.upgrade.v40.alphas import changeAuthenticatedResourcesCondition
-from plone.app.upgrade.v40.alphas import setupReferencebrowser
-from plone.app.upgrade.v40.alphas import migrateMailHost
-from plone.app.upgrade.v40.alphas import migrateFolders
-from plone.app.upgrade.v40.alphas import renameJoinFormFields
-from plone.app.upgrade.v40.alphas import updateLargeFolderType
-from plone.app.upgrade.v40.alphas import addRecursiveGroupsPlugin
-from plone.app.upgrade.v40.alphas import cleanUpClassicThemeResources
-from plone.app.upgrade.v40.alphas import migrateStaticTextPortlets
-from plone.app.upgrade.v40.betas import repositionRecursiveGroupsPlugin
-from plone.app.upgrade.v40.betas import updateIconMetadata
-from plone.app.upgrade.v40.betas import removeLargePloneFolder
-from plone.app.upgrade.tests.base import MigrationTest
-
-from plone.portlet.static import static
-from plone.portlets.interfaces import IPortletAssignmentMapping
-from plone.portlets.interfaces import IPortletAssignmentSettings
-from plone.portlets.interfaces import IPortletManager
-
-
-class FakeSecureMailHost(object):
-
-    meta_type = 'Secure Mail Host'
-    id = 'MailHost'
-    title = 'Fake MailHost'
-    smtp_host = 'smtp.example.com'
-    smtp_port = 587
-    smtp_userid='me'
-    smtp_pass='secret'
-    smtp_notls=False
-
-    def manage_fixupOwnershipAfterAdd(self):
-        pass
-
-
-class TestMigrations_v4_0alpha1(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:3-4alpha1"
-
-    def afterSetUp(self):
-        self.atool = getToolByName(self.portal, 'portal_actions')
-        self.cptool = getToolByName(self.portal, 'portal_controlpanel')
-        self.wftool = getToolByName(self.portal, 'portal_workflow')
-        self.csstool = getToolByName(self.portal, 'portal_css')
-        self.jstool = getToolByName(self.portal, 'portal_javascripts')
-
-        if 'portal_actionicons' not in self.portal:
-            from plone.app.upgrade.bbb import ActionIconsTool
-            self.portal._setObject('portal_actionicons', ActionIconsTool())
-        self.aitool = self.portal.portal_actionicons
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        self.setRoles(['Manager'])
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testMigrateActionIcons(self):
-        _KNOWN_ACTION_ICONS['object_buttons'].extend(['test_id', 'test2_id'])
-        self.aitool.addActionIcon(
-            category='object_buttons',
-            action_id='test_id',
-            icon_expr='test.gif',
-            title='Test my icon',
-            )
-        self.aitool.addActionIcon(
-            category='object_buttons',
-            action_id='test2_id',
-            icon_expr='python:context.getIcon()',
-            title='Test my second icon',
-            )
-        test_action = Action('test_id',
-            title='Test me',
-            description='',
-            url_expr='',
-            icon_expr='',
-            available_expr='',
-            permissions=('View', ),
-            visible = True)
-        test2_action = Action('test2_id',
-            title='Test me too',
-            description='',
-            url_expr='',
-            icon_expr='',
-            available_expr='',
-            permissions=('View', ),
-            visible = True)
-
-        object_buttons = self.atool.object_buttons
-        if getattr(object_buttons, 'test_id', None) is None:
-            object_buttons._setObject('test_id', test_action)
-        if getattr(object_buttons, 'test2_id', None) is None:
-            object_buttons._setObject('test2_id', test2_action)
-
-        self.assertEqual(object_buttons.test_id.icon_expr, '')
-        self.assertEqual(object_buttons.test2_id.icon_expr, '')
-        # Test it twice
-        for i in range(2):
-            migrateActionIcons(self.portal)
-            icons = [ic._action_id for ic in self.aitool.listActionIcons()]
-            self.assertFalse('test_id' in icons)
-            self.assertFalse('test2_id' in icons)
-            self.assertEqual(object_buttons.test_id.icon_expr,
-                             'string:$portal_url/test.gif')
-            self.assertEqual(object_buttons.test2_id.icon_expr,
-                             'python:context.getIcon()')
-
-    def testMigrateControlPanelActionIcons(self):
-        _KNOWN_ACTION_ICONS['controlpanel'].extend(['test_id'])
-        self.aitool.addActionIcon(
-            category='controlpanel',
-            action_id='test_id',
-            icon_expr='test.gif',
-            title='Test my icon',
-            )
-
-        self.cptool.registerConfiglet(
-            id='test_id',
-            name='Test Configlet',
-            action='string:${portal_url}/test',
-            permission='Manage portal',
-            category='Plone',
-            visible=True,
-            appId='',
-            icon_expr='',
-            )
-
-        action = self.cptool.getActionObject('Plone/test_id')
-        self.assertEqual(action.getIconExpression(), '')
-        # Test it twice
-        for i in range(2):
-            migrateActionIcons(self.portal)
-            icons = [ic._action_id for ic in self.aitool.listActionIcons()]
-            self.assertFalse('test_id' in icons)
-            self.assertEqual(action.getIconExpression(),
-                             'string:$portal_url/test.gif')
-
-    def testContentTypeIconExpressions(self):
-        """
-        FTIs should now be using icon_expr instead of content_icon.
-        (The former caches the expression object.)
-        """
-        tt = getToolByName(self.portal, "portal_types")
-        tt.Document.icon_expr = None
-        loadMigrationProfile(self.portal, self.profile, ('typeinfo', ))
-        self.assertEqual(tt.Document.icon_expr,
-                         "string:${portal_url}/document_icon.png")
-
-    def testMigrateTypeIcons(self):
-        """
-        FTIs having content_icon should be upgraded to icon_expr.
-        """
-        tt = getToolByName(self.portal, "portal_types")
-        del tt.Document.icon_expr
-        tt.Document.content_icon = 'document_icon.gif'
-        migrateTypeIcons(self.portal)
-        self.assertEqual(tt.Document.icon_expr,
-                         "string:${portal_url}/document_icon.gif")
-        self.assertTrue(hasattr(tt.Document, 'icon_expr_object'))
-
-        #Don't upgrade if there is already an icon_expr.
-        tt.Document.icon_expr = "string:${portal_url}/document_icon.png"
-        tt.Document.content_icon = 'document_icon.gif'
-        migrateTypeIcons(self.portal)
-        self.assertEqual(tt.Document.icon_expr,
-                         "string:${portal_url}/document_icon.png")
-
-    def testPngContentIcons(self):
-        tt = getToolByName(self.portal, "portal_types")
-        tt.Document.icon_expr = "string:${portal_url}/document_icon.gif"
-        loadMigrationProfile(self.portal, self.profile, ('typeinfo', ))
-        self.assertEqual(tt.Document.icon_expr,
-            "string:${portal_url}/document_icon.png")
-
-    def testAddRAMCache(self):
-        # Test it twice
-        for i in range(2):
-            sm = getSiteManager()
-            sm.unregisterUtility(provided=IRAMCache)
-            util = queryUtility(IRAMCache)
-            self.assertEqual(util.maxAge, 86400)
-            addOrReplaceRamCache(self.portal)
-            util = queryUtility(IRAMCache)
-            self.assertEqual(util.maxAge, 3600)
-
-    def testReplaceOldRamCache(self):
-        sm = getSiteManager()
-
-        # Test it twice
-        for i in range(2):
-            sm.unregisterUtility(provided=IRAMCache)
-            from zope.app.cache.interfaces.ram import IRAMCache as OldIRAMCache
-            from zope.app.cache.ram import RAMCache as OldRAMCache
-            sm.registerUtility(factory=OldRAMCache, provided=OldIRAMCache)
-
-            addOrReplaceRamCache(self.portal)
-            util = queryUtility(IRAMCache)
-            self.assertEqual(util.maxAge, 3600)
-
-    def testChangeWorkflowActorVariableExpression(self):
-        self.wftool.intranet_folder_workflow.variables.actor.setProperties('')
-
-        for i in range(2):
-            changeWorkflowActorVariableExpression(self.portal)
-            wf = self.wftool.intranet_folder_workflow
-            self.assertEqual(wf.variables.actor.getDefaultExprText(),
-                             'user/getId')
-            wf = self.wftool.one_state_workflow
-            self.assertEqual(wf.variables.actor.getDefaultExprText(),
-                             'user/getId')
-            wf = self.wftool.simple_publication_workflow
-            self.assertEqual(wf.variables.actor.getDefaultExprText(),
-                             'user/getId')
-
-        # make sure it doesn't break if the workflow is missing
-        wf = self.wftool.intranet_folder_workflow
-        self.wftool._delOb('intranet_folder_workflow')
-        changeWorkflowActorVariableExpression(self.portal)
-        self.wftool._setOb('intranet_folder_workflow', wf)
-
-    def testChangeAuthenticatedResourcesCondition(self):
-        # make sure CSS resource is updated
-        res = self.csstool.getResource('member.css')
-        if res is None:
-            return
-        res.setAuthenticated(False)
-        res.setExpression('not: portal/portal_membership/isAnonymousUser')
-        # test it twice
-        for i in range(2):
-            changeAuthenticatedResourcesCondition(self.portal)
-            self.assertEqual(res.getExpression(), '')
-            self.assertTrue(res.getAuthenticated())
-
-        # make sure it doesn't update it if the expression has been
-        # customized
-        res.setExpression('python:False')
-        changeAuthenticatedResourcesCondition(self.portal)
-        self.assertEqual(res.getExpression(), 'python:False')
-
-    def testAddedUseEmailProperty(self):
-        tool = getToolByName(self.portal, 'portal_properties')
-        sheet = getattr(tool, 'site_properties')
-        #self.assertEqual(sheet.getProperty('use_email_as_login'), False)
-        self.removeSiteProperty('use_email_as_login')
-        loadMigrationProfile(self.portal, self.profile, ('propertiestool', ))
-        self.assertEqual(sheet.getProperty('use_email_as_login'), False)
-
-    def testReplaceReferencebrowser(self):
-        self.setRoles(['Manager'])
-        skins_tool = getToolByName(self.portal, 'portal_skins')
-        if 'referencebrowser' not in skins_tool:
-            return
-        sels = skins_tool._getSelections()
-        for skinname, layer in sels.items():
-            layers = layer.split(',')
-            self.assertFalse('ATReferenceBrowserWidget' in layers)
-            layers.remove('referencebrowser')
-            new_layers = ','.join(layers)
-            sels[skinname] = new_layers
-
-        from .alphas import threeX_alpha1
-        threeX_alpha1(self.portal)
-        setupReferencebrowser(self.portal)
-
-        sels = skins_tool._getSelections()
-        for skinname, layer in sels.items():
-            layers = layer.split(',')
-            self.assertTrue('referencebrowser' in layers)
-
-    def testInstallNewDependencies(self):
-        from plone.app.upgrade.v40.alphas import threeX_alpha1
-        self.setRoles(['Manager'])
-        # test for running the TinyMCE profile by checking for the skin layer
-        # it installs (the profile is marked as noninstallable, so we can't
-        # ask the quick installer)
-        skins_tool = getToolByName(self.portal, 'portal_skins')
-        if 'tinymce' not in skins_tool:
-            # Skip test in new Plones that don't have tinymce to begin with
-            return
-        del skins_tool['tinymce']
-        for i in range(2):
-            threeX_alpha1(self.portal)
-            self.assertTrue('tinymce' in skins_tool)
-            # sleep to avoid a GS log filename collision :-o
-            time.sleep(1)
-
-    def testReplaceSecureMailHost(self):
-        portal = self.portal
-        sm = getSiteManager(context=portal)
-        # try it with an unmodified site to ensure it doesn't give any errors
-        migrateMailHost(portal.portal_setup)
-        portal._delObject('MailHost')
-        # Run it with our MailHost replaced
-        portal._setObject('MailHost', FakeSecureMailHost())
-        self.assertEqual(portal.MailHost.meta_type, 'Secure Mail Host')
-        sm.unregisterUtility(provided=IMailHost)
-        sm.registerUtility(portal.MailHost, provided=IMailHost)
-        migrateMailHost(portal)
-        new_mh = portal.MailHost
-        self.assertEqual(new_mh.meta_type, 'Mail Host')
-        self.assertEqual(new_mh.title, 'Fake MailHost')
-        self.assertEqual(new_mh.smtp_host, 'smtp.example.com')
-        self.assertEqual(new_mh.smtp_port, 587)
-        self.assertEqual(new_mh.smtp_uid, 'me')
-        self.assertEqual(new_mh.smtp_pwd, 'secret')
-        #Force TLS is always false, because SMH has no equivalent option
-        self.assertEqual(new_mh.force_tls, False)
-
-    def testFolderMigration(self):
-        from plone.app.folder.tests.content import create
-        from plone.app.folder.tests.test_migration import reverseMigrate
-        from plone.app.folder.tests.test_migration import isSaneBTreeFolder
-        # create a folder in an unmigrated state & check it's broken...
-        folder = create('Folder', self.portal, 'foo', title='Foo')
-        reverseMigrate(self.portal)
-        self.assertFalse(isSaneBTreeFolder(self.portal.foo))
-        # now run the migration step...
-        migrateFolders(self.portal)
-        folder = self.portal.foo
-        self.assertTrue(isSaneBTreeFolder(folder))
-        self.assertEqual(folder.getId(), 'foo')
-        self.assertEqual(folder.Title(), 'Foo')
-
-    def testMigrateStaticTextPortlets(self):
-        class HiddenAssignment(static.Assignment):
-            hide = True
-
-        self.setRoles(["Manager"])
-        self.portal.invokeFactory('Folder', id="statictest")
-        folder = self.portal['statictest']
-
-        manager = getUtility(
-                IPortletManager, name='plone.rightcolumn',
-                context=folder)
-        assignments = getMultiAdapter(
-                (folder, manager), IPortletAssignmentMapping)
-        hidden_portlet = HiddenAssignment()
-        visible_portlet = static.Assignment()
-        assignments['hidden'] = hidden_portlet
-        assignments['visible'] = visible_portlet
-
-        migrateStaticTextPortlets(self.portal)
-
-        self.assertFalse(
-                IPortletAssignmentSettings(hidden_portlet).get(
-                        'visible', True))
-        self.assertTrue(
-                IPortletAssignmentSettings(visible_portlet).get(
-                        'visible', True))
-
-
-
-class TestMigrations_v4_0alpha2(MigrationTest):
-
-    def testMigrateJoinFormFields(self):
-        ptool = getToolByName(self.portal, 'portal_properties')
-        sheet = getattr(ptool, 'site_properties')
-        self.removeSiteProperty('user_registration_fields')
-        self.addSiteProperty('join_form_fields')
-        sheet.join_form_fields = (
-            'username', 'password', 'email', 'mail_me', 'groups')
-        renameJoinFormFields(self)
-        self.assertEqual(sheet.hasProperty('join_form_fields'), False)
-        self.assertEqual(sheet.hasProperty('user_registration_fields'), True)
-        self.assertEqual(sheet.getProperty('user_registration_fields'),
-                         ('username', 'password', 'email', 'mail_me'))
-
-
-class TestMigrations_v4_0alpha3(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:4alpha2-4alpha3"
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testJoinActionURL(self):
-        self.portal.portal_actions.user.join.url_expr = 'foo'
-        loadMigrationProfile(self.portal, self.profile, ('actions', ))
-        self.assertEqual(self.portal.portal_actions.user.join.url_expr,
-            'string:${globals_view/navigationRootUrl}/@@register')
-
-
-class TestMigrations_v4_0alpha5(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:4alpha4-4alpha5"
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testMigrateLargeFolderType(self):
-        portal = self.portal
-        catalog = getToolByName(portal, 'portal_catalog')
-        # set things up in the old way...
-        ids = 'news', 'events', 'Members'
-        for id in ids:
-            obj = portal[id]
-            obj._setPortalTypeName('Large Plone Folder')
-            obj.reindexObject()
-            self.assertEqual(obj.portal_type, 'Large Plone Folder')
-            # Type falls back to meta_type since there's no
-            # Large Plone Folder FTI
-            self.assertEqual(obj.Type(), 'ATFolder')
-            brain, = catalog(getId=id)
-            self.assertEqual(brain.portal_type, 'Large Plone Folder')
-            self.assertEqual(brain.Type, 'ATFolder')
-        # migrate & check again...
-        updateLargeFolderType(self.portal)
-        for id in ids:
-            obj = portal[id]
-            self.assertEqual(obj.portal_type, 'Folder')
-            self.assertEqual(obj.Type(), 'Folder')
-            brain, = catalog(getId=id)
-            self.assertEqual(brain.portal_type, 'Folder')
-            self.assertEqual(brain.Type, 'Folder')
-
-    def testAddRecursiveGroupsPlugin(self):
-        acl = getToolByName(self.portal, 'acl_users')
-        addRecursiveGroupsPlugin(self.portal)
-        self.assertTrue('recursive_groups' in acl)
-        # Now that we have an existing one, let's make sure it's handled
-        # properly if this migration is run again.
-        addRecursiveGroupsPlugin(self.portal)
-        self.assertTrue('recursive_groups' in acl)
-
-    def testClassicThemeResourcesCleanUp(self):
-        """Test that the plonetheme.classic product doesn't have any
-        registered CSS resource in its metadata after migration.
-        """
-        portal = self.portal
-        qi = getToolByName(portal, 'portal_quickinstaller')
-        qi.installProduct('plonetheme.classic')
-        classictheme = qi['plonetheme.classic']
-        classictheme.resources_css = ['something'] # add a random resource
-        cleanUpClassicThemeResources(portal)
-        self.assertEqual(classictheme.resources_css, [])
-
-    def testGetObjPositionInParentIndex(self):
-        from plone.app.folder.nogopip import GopipIndex
-        catalog = self.portal.portal_catalog
-        catalog.delIndex('getObjPositionInParent')
-        catalog.addIndex('getObjPositionInParent', 'FieldIndex')
-        self.assertFalse(isinstance(catalog.Indexes['getObjPositionInParent'],
-            GopipIndex))
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue('getObjPositionInParent' in catalog.indexes())
-        self.assertTrue(isinstance(catalog.Indexes['getObjPositionInParent'],
-            GopipIndex))
-
-    def testGetEventTypeIndex(self):
-        catalog = self.portal.portal_catalog
-        catalog.addIndex('getEventType', 'KeywordIndex')
-        self.assertTrue('getEventType' in catalog.indexes())
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertFalse('getEventType' in catalog.indexes())
-
-
-class TestMigrations_v4_0beta1(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:4alpha5-4beta1"
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testRepositionRecursiveGroupsPlugin(self):
-        # Ensure that the recursive groups plugin is moved to the bottom
-        # of the IGroups plugins list, if active.
-        addRecursiveGroupsPlugin(self.portal)
-        # Plugin is installed, but not active, run against this state.
-        from Products.PluggableAuthService.interfaces.plugins import \
-            IGroupsPlugin
-        acl = getToolByName(self.portal, 'acl_users')
-        plugins = acl.plugins
-        # The plugin was originally moved to the top of the list of
-        # IGroupsPlugin plugins by p.a.controlpanel. Recreate that state.
-        while (plugins.getAllPlugins('IGroupsPlugin')['active'].index(
-               'recursive_groups') > 0):
-            plugins.movePluginsUp(IGroupsPlugin, ['recursive_groups'])
-
-        active_groups = plugins.getAllPlugins('IGroupsPlugin')['active']
-        self.assertEqual(active_groups[0], 'recursive_groups')
-
-        # Rerun the migration, making sure that it's now the last item in the
-        # list of IGroupsPlugin plugins.
-        repositionRecursiveGroupsPlugin(self.portal)
-        active_groups = plugins.getAllPlugins('IGroupsPlugin')['active']
-        self.assertEqual(active_groups[-1], 'recursive_groups')
-
-
-class TestMigrations_v4_0beta2(MigrationTest):
-
-    profile = "profile-plone.app.upgrade.v40:4beta1-4beta2"
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testCoreContentIconExprCleared(self):
-        types = getToolByName(self.portal, 'portal_types')
-        catalog = getToolByName(self.portal, 'portal_catalog')
-        # Reinstate the now-empty icon expression for the Document type
-        doc_icon_expr = Expression('string:${portal_url}/document_icon.png')
-        types['Document'].icon_expr_object = doc_icon_expr
-        front = self.portal['front-page']
-        catalog.reindexObject(front)
-        old_modified = front.modified()
-        # Make sure the getIcon metadata column shows the "original" value
-        brains = catalog(id='front-page')
-        self.assertEqual(brains[0].getIcon, 'document_icon.png')
-        # Run the migration
-        loadMigrationProfile(self.portal, self.profile)
-        updateIconMetadata(self.portal)
-        # The getIcon column should now be empty
-        self.assertEqual(catalog(id='front-page')[0].getIcon, '')
-        self.assertEqual(front.modified(), old_modified)
-
-
-class TestMigrations_v4_0beta4(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4beta3-4beta4'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testRemoveLargePloneFolder(self):
-        # re-create pre-migration settings
-        ptool = self.portal.portal_properties
-        nav_props = ptool.navtree_properties
-        l = list(nav_props.parentMetaTypesNotToQuery)
-        nav_props.parentMetaTypesNotToQuery = l + ['Large Plone Folder']
-        site_props = ptool.site_properties
-        l = list(site_props.typesLinkToFolderContentsInFC)
-        site_props.typesLinkToFolderContentsInFC = l + ['Large Plone Folder']
-        temp_folder_fti = self.portal.portal_types['TempFolder']
-        l = list(temp_folder_fti.allowed_content_types)
-        temp_folder_fti.allowed_content_types = l + ['Large Plone Folder']
-        l = set(self.portal.portal_factory.getFactoryTypes())
-        l.add('Large Plone Folder')
-        ftool = self.portal.portal_factory
-        ftool.manage_setPortalFactoryTypes(listOfTypeIds=list(l))
-
-        for i in xrange(2):
-            loadMigrationProfile(self.portal, self.profile)
-            removeLargePloneFolder(self.portal)
-            self.assertFalse('Large Plone Folder' in self.portal.portal_types)
-            self.assertFalse('Large Plone Folder' in
-                        temp_folder_fti.allowed_content_types)
-            self.assertTrue('Folder' in temp_folder_fti.allowed_content_types)
-            self.assertFalse('Large Plone Folder' in ftool.getFactoryTypes())
-            self.assertTrue('Folder' in ftool.getFactoryTypes())
-            self.assertFalse('Large Plone Folder' in
-                        nav_props.parentMetaTypesNotToQuery)
-            self.assertTrue('TempFolder' in
-                            nav_props.parentMetaTypesNotToQuery)
-            self.assertFalse('Large Plone Folder' in
-                        site_props.typesLinkToFolderContentsInFC)
-            self.assertTrue('Folder' in
-                            site_props.typesLinkToFolderContentsInFC)
-            # sleep to avoid a GS log filename collision :-o
-            time.sleep(1)
-
-
-class TestMigrations_v4_0beta5(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4beta4-4beta5'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-
-class TestMigrations_v4_0rc1(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4beta5-4rc1'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4rc1-4final'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_1(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0-4.0.1'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_2(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0.1-4.0.2'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_3(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0.2-4.0.3'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_4(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0.3-4.0.4'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-class TestMigrations_v4_0_5(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v40:4.0.4-4.0.5'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-
-def test_suite():
-    from unittest import defaultTestLoader
-    return defaultTestLoader.loadTestsFromName(__name__)
diff --git a/plone/app/upgrade/v41/tests.py b/plone/app/upgrade/v41/tests.py
deleted file mode 100644
index 4570a4c..0000000
--- a/plone/app/upgrade/v41/tests.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import unittest
-from Products.ZCatalog.ZCatalog import ZCatalog
-from Products.ZCTextIndex.ZCTextIndex import ZCTextIndex, PLexicon
-from Products.ZCTextIndex.OkapiIndex import OkapiIndex
-
-
-class MigrationUnitTests(unittest.TestCase):
-
-    def test_fixOkapiIndexes(self):
-        catalog = ZCatalog('catalog')
-        catalog.lexicon = PLexicon('lexicon')
-        catalog.addIndex('test',
-            ZCTextIndex('test', index_factory=OkapiIndex,
-                        caller=catalog, lexicon_id='lexicon'))
-        catalog.Indexes['test'].index._totaldoclen = -1000
-
-        from plone.app.upgrade.v41.final import fixOkapiIndexes
-        fixOkapiIndexes(catalog)
-        self.assertEqual(0L, catalog.Indexes['test'].index._totaldoclen())
diff --git a/plone/app/upgrade/v42/tests.py b/plone/app/upgrade/v42/tests.py
deleted file mode 100644
index 0ff501e..0000000
--- a/plone/app/upgrade/v42/tests.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from plone.app.upgrade.tests.base import MigrationTest
-from plone.app.upgrade.utils import loadMigrationProfile
-
-
-class TestMigrations_v4_2beta1(MigrationTest):
-
-    profile = 'profile-plone.app.upgrade.v42:to42beta1'
-
-    def testProfile(self):
-        # This tests the whole upgrade profile can be loaded
-        loadMigrationProfile(self.portal, self.profile)
-        self.assertTrue(True)
-
-    def testAddSiteAdminToKeywordRoles(self):
-        ptool = self.portal.portal_properties
-        site_props = ptool.site_properties
-        site_props.allowRolesToAddKeywords = ('Manager', 'Reviewer')
-        loadMigrationProfile(self.portal, self.profile)
-        roles = site_props.allowRolesToAddKeywords
-        self.assertEqual(roles, ('Manager', 'Reviewer', 'Site Administrator'))
diff --git a/setup.py b/setup.py
index 1dd33a5..c500ee7 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
 from setuptools import setup, find_packages
 
-version = '1.3.9.dev0'
+version = '2.0.dev0'
 
 setup(name='plone.app.upgrade',
       version=version,
@@ -10,10 +10,12 @@
       classifiers=[
           "Environment :: Web Environment",
           "Framework :: Plone",
+          "Framework :: Plone :: 5.0",
           "Framework :: Zope2",
           "License :: OSI Approved :: GNU General Public License (GPL)",
           "Operating System :: OS Independent",
           "Programming Language :: Python",
+          "Programming Language :: Python :: 2.7",
         ],
       keywords='Plone upgrade migration',
       author='Plone Foundation',
@@ -28,13 +30,13 @@
         test=[
             'Products.CMFPlacefulWorkflow',
             'Products.CMFQuickInstallerTool',
-            'Products.PloneTestCase',
             'plone.contentrules',
             'plone.app.i18n',
             'plone.app.iterate',
             'plone.app.openid',
             'plone.app.redirector',
             'plone.app.viewletmanager',
+            'plone.app.testing',
             'plone.app.theming',
         ]
       ),




-------------------------------------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CHANGES.log
Type: application/octet-stream
Size: 215166 bytes
Desc: not available
URL: <http://lists.plone.org/pipermail/plone-testbot/attachments/20150106/e310ef92/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: build.log
Type: application/octet-stream
Size: 186670 bytes
Desc: not available
URL: <http://lists.plone.org/pipermail/plone-testbot/attachments/20150106/e310ef92/attachment-0003.obj>


More information about the Testbot mailing list