Tests for QuickInstaller installation ===================================== First we set three convenience variables for later use: >>> from zope.component import getSiteManager >>> from Products.CMFQuickInstallerTool.interfaces import IQuickInstallerTool >>> from Products.CMFCore.utils import getToolByName >>> portal = layer['portal'] >>> portal <PloneSite at /plone> >>> qi = getattr(portal, 'portal_quickinstaller', None) >>> qi <QuickInstallerTool at /plone/portal_quickinstaller> And register the QI tool as a utility: >>> sm = getSiteManager() >>> sm.registerUtility(qi, IQuickInstallerTool) And create a fake add-on for us to install: >>> import sys >>> from Products.CMFQuickInstallerTool import interfaces >>> sys.modules['Products.QITest'] = interfaces >>> from Products.GenericSetup.registry import _profile_registry >>> _profile_registry.registerProfile('default', 'Test', ... '', interfaces.__path__[0], 'QITest', 2) Install a product ----------------- Before installing QITest as an example, let's make sure we have no InstalledProduct instance in the QI tool: >>> 'QITest' in qi.objectIds() False After checking that the product is not installed yet, we do install it: >>> qi.installProducts(products=['QITest']) '...Installed Products...QITest:ok:...' Now we have an InstalledProduct instance in the QI tool: >>> 'QITest' in qi.objectIds() True >>> product = qi['QITest'] >>> product.isInstalled() True Uninstall the product again --------------------------- >>> qi.uninstallProducts(products=['QITest']) And we no longer have an InstalledProduct instance in the QI tool: >>> 'QITest' in qi.objectIds() False >>> qi.isProductInstalled('QITest') False >>> setup = getToolByName(portal, 'portal_setup') >>> logs = [i for i in setup.objectIds() if 'QITest' in i] >>> for i in logs: ... setup._delObject(i) Install a product which has a GenericSetup dependency ----------------------------------------------------- There was a bug where if you installed a product which depends on another product, and then uninstalled it, the dependency's entries would be removed. Let's make sure that doesn't happen! First we need to fake a product that depends on QITest: >>> import sys >>> from Products.CMFQuickInstallerTool import tests >>> sys.modules['Products.QITest2'] = tests >>> from Products.GenericSetup.registry import _profile_registry >>> _profile_registry.registerProfile('default', 'Test', ... '', tests.__path__[0], 'QITest2', 2) Now we install our fake product: >>> qi.installProducts(products=['QITest2'], omitSnapshots=True) '...Installed Products...QITest2:ok:...' And confirm that QITest stuff was installed: >>> qi['QITest'].isInstalled() True And remove it: >>> qi.uninstallProducts(products=['QITest2']) The QITest stuff should still be present: >>> qi['QITest'].isInstalled() True Install and Reinstall without deleting custom content ----------------------------------------------------- Custom products can add content items (especially folders) to the root of a plone site. We want to be sure NOT to delete these "non-tool" items. To emulate this we can install any product, add some content, and then fudge the snapshot to make it seem like it was added by the install of the product. >>> before = qi.snapshotPortal(portal) Generic Setup does not like so many installs and needs to fix its timestamp for logging. For now lets artificially time it >>> import time;time.sleep(1) >>> qi.installProducts(products=['QITest']) '...Installed Products...QITest:ok:...' First make sure we can actually create content. >>> from plone.app.testing import setRoles >>> setRoles(portal, 'test_user_1_', ['Contributor']) Add a document to the root - this should remain after uninstall. >>> portal.manage_addFolder("test", title="Test") >>> 'test' in portal.objectIds() True Fudge the snapshot >>> after = qi.snapshotPortal(portal) >>> settings = qi.deriveSettingsFromSnapshots(before, after) >>> p = qi['QITest'] >>> p.update(settings=settings) Uninstall the product and confirm the content is still there >>> qi.uninstallProducts(products=['QITest']) >>> 'test' in portal.objectIds() True Test getUninstallProfile method ------------------------------- >>> sys.modules['Products.QITest3'] = tests >>> qi.installProducts(products=['QITest3']) '...Installed Products...QITest3:ok:...' >>> qi.getUninstallProfile('QITest3') >>> _profile_registry.registerProfile('uninstall', 'Test', ... '', interfaces.__path__[0], 'QITest3', 2) >>> uninstall = qi.getUninstallProfile('QITest3') >>> uninstall['id'] 'QITest3:uninstall' Cleanup >>> qi.uninstallProducts(products=['QITest3']) Uninstalling should run the uninstall-profile --------------------------------------------- We need to test against a step that is not auto-removed by _cascadeRemove, so we add "UninstallTest" to default_page_types in site_properties via a propertiestool.xml. Create a dummy product >>> sys.modules['Products.QITest4'] = tests Make sure there is no dummy in site_properties >>> portal_properties = portal.portal_properties >>> portal_properties <PropertiesTool at /plone/portal_properties> >>> sp = portal_properties.site_properties >>> 'UninstallTest' in sp.getProperty('default_page_types', []) False Installing the product should not run any profile and thus set no properties. >>> qi.installProducts(products=['QITest4']) '...Installed Products...QITest4:ok:...' >>> 'UninstallTest' in sp.getProperty('default_page_types', []) False Register a 'default'-profile that points to profiles/test >>> interfaces_path = interfaces.__path__[0] >>> default_path = interfaces_path[:-11] + '/profiles/test' >>> _profile_registry.registerProfile('default', 'UninstallTest', '', default_path, 'QITest4', 2) Installing the product now runs the default-profile. >>> qi.installProducts(products=['QITest4']) '...Installed Products...QITest4:ok:...' Make sure the property was set by the default-profile. >>> 'UninstallTest' in sp.getProperty('default_page_types', []) True There is no uninstall-profile yet, so the property is kept on uninstalling. >>> qi.getUninstallProfile('QITest4') >>> 'UninstallTest' in sp.getProperty('default_page_types', []) True Install again. >>> qi.installProducts(products=['QITest4']) '...Installed Products...QITest4:ok:...' Register a uninstall profile that points to the profiles/test_uninstall >>> uninstall_path = interfaces_path[:-11] + '/profiles/test_uninstall' >>> _profile_registry.registerProfile('uninstall', 'UninstallTest', '', uninstall_path, 'QITest4', 2) >>> uninstall = qi.getUninstallProfile('QITest4') >>> uninstall['id'] 'QITest4:uninstall' Uninstalling now runs the uninstall-profile, thus removing the property. >>> qi.uninstallProducts(products=['QITest4']) >>> 'UninstallTest' in sp.getProperty('default_page_types', []) False