source: products/quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/tests/testInstallation.py @ 3223

Last change on this file since 3223 was 3140, checked in by zidane, 13 years ago

fixes pylint

File size: 12.5 KB
RevLine 
[1493]1#
2# Test product's installation
3#
4import string
[1836]5from zope.interface import alsoProvides
6from zope.component import queryMultiAdapter
7from zope.viewlet.interfaces import IViewletManager
[1897]8
[1930]9from quintagroup.canonicalpath.adapters import PROPERTY_LINK
[1836]10from quintagroup.seoptimizer.browser.interfaces import IPloneSEOLayer
[3140]11from quintagroup.seoptimizer.tests.base import TestCase, \
12    FunctionalTestCaseNotInstalled
13from quintagroup.seoptimizer.config import PROJECT_NAME, SUPPORT_BLAYER
[1493]14
[3140]15from Products.CMFCore.utils import getToolByName
16
[1958]17PROPERTY_SHEET = 'seo_properties'
18STOP_WORDS = ['a', 'an', 'amp', 'and', 'are', 'arial', 'as', 'at', 'be', 'but',
19    'by', 'can', 'com', 'do', 'font', 'for', 'from', 'gif', 'had', 'has',
20    'have', 'he', 'helvetica', 'her', 'his', 'how', 'href', 'i', 'if', 'in',
21    'is', 'it', 'javascript', 'jpg', 'made', 'net', 'of', 'on', 'or', 'org',
22    'our', 'sans', 'see', 'serif', 'she', 'that', 'the', 'this', 'to', 'us',
23    'we', 'with', 'you', 'your']
24
[1877]25PROPS = {'stop_words': STOP_WORDS,
26         'fields': ['seo_title', 'seo_description', 'seo_keywords']}
[1493]27
[1877]28DEFAULT_METATAGS_ORDER = [
29    'DC.contributors', 'DC.creator', 'DC.date.created',
[3134]30    'DC.date.modified', 'DC.description', 'DC.distribution',
[1877]31    'DC.format', 'DC.language', 'DC.publisher', 'DC.rights',
32    'DC.subject', 'DC.type', 'description', 'distribution',
33    'keywords', 'robots']
34DEFAULT_METATAGS_ORDER.sort()
35
36SEO_CONTENT = ['File', 'Document', 'News Item']
[3134]37CONTENTTYPES_WITH_SEOACTION = ['File', 'Document', 'News Item', 'Folder',
38                               'Event']
[1877]39CONTENTTYPES_WITH_SEOACTION.sort()
40
41
[1897]42class TestBeforeInstallation(FunctionalTestCaseNotInstalled):
[1493]43
44    def afterSetUp(self):
45        self.basic_auth = 'mgr:mgrpw'
46        self.portal_path = '/%s' % self.portal.absolute_url(1)
47
48    def testAccessPortalRootAnonymous(self):
49        response = self.publish(self.portal_path)
50        self.assertEqual(response.getStatus(), 200)
51
52    def testAccessPortalRootAuthenticated(self):
53        response = self.publish(self.portal_path, self.basic_auth)
54        self.assertEqual(response.getStatus(), 200)
55
56
57class TestInstallation(TestCase):
58
59    def afterSetUp(self):
60        self.properties = getToolByName(self.portal, 'portal_properties')
61
62    def testAddingPropertySheet(self):
63        """ Test adding property sheet to portal_properties tool """
64        self.failUnless(hasattr(self.properties.aq_base, PROPERTY_SHEET))
65
66    def testAddingPropertyFields(self):
[3134]67        """ Test adding property field to portal_properties.maps_properties
68            sheet
69        """
[1493]70        map_sheet = self.properties[PROPERTY_SHEET]
71        for key, value in PROPS.items():
[3134]72            self.failUnless(map_sheet.hasProperty(key) and \
73                            list(map_sheet.getProperty(key)) == value)
[1493]74
75    def test_configlet_install(self):
76        configTool = getToolByName(self.portal, 'portal_controlpanel', None)
[3134]77        self.assert_(PROJECT_NAME in [a.getId() for a in \
78                                      configTool.listActions()], \
79                     'Configlet not found')
[1493]80
[1836]81    def test_viewlets_install(self):
82        VIEWLETS = ['plone.htmlhead.title',
83                    'plone.resourceregistries',
84                    'quintagroup.seoptimizer.seotags',
85                    'quintagroup.seoptimizer.customscript']
86        request = self.app.REQUEST
87        # mark request with our browser layer
88        alsoProvides(request, IPloneSEOLayer)
89        view = queryMultiAdapter((self.portal, request), name="plone")
[3134]90        manager = queryMultiAdapter((self.portal['front-page'], request, view),
[1836]91                                     IViewletManager, name='plone.htmlhead')
92        for p in VIEWLETS:
[3134]93            self.assert_(manager.get(p) is not None, "Not registered '%s' " \
94                         "viewlet" % p)
[1958]95
[1836]96    def test_browser_layer(self):
[2124]97        if not SUPPORT_BLAYER:
98            return
99
[1897]100        from plone.browserlayer import utils
[1836]101        self.assert_(IPloneSEOLayer in utils.registered_layers(),
102                     "Not registered 'IPloneSEOLayer' browser layer")
[1493]103
[1836]104    def test_action_install(self):
[3134]105        atool = getToolByName(self.portal, 'portal_actions')
[1836]106        action_ids = [a.id for a in atool.listActions()]
107        self.assert_("SEOProperties" in action_ids,
108                     "Not added 'SEOProperties' action")
[1835]109
[3134]110
[1835]111class TestUninstallation(TestCase):
112
113    def afterSetUp(self):
114        self.qi = self.portal.portal_quickinstaller
115        self.qi.uninstallProducts([PROJECT_NAME])
116
[1837]117    def test_propertysheet_uninstall(self):
118        properties = getToolByName(self.portal, 'portal_properties')
[2201]119        self.assert_(hasattr(properties.aq_base, PROPERTY_SHEET),
[3134]120                     "'%s' property sheet not uninstalled" % PROPERTY_SHEET)
[1493]121
[1837]122    def test_configlet_uninstall(self):
123        self.assertNotEqual(self.qi.isProductInstalled(PROJECT_NAME), True,
124            'qSEOptimizer is already installed')
[1493]125
[1837]126        configTool = getToolByName(self.portal, 'portal_controlpanel', None)
[3134]127        self.assertEqual(PROJECT_NAME in [a.getId() for a in \
128                                          configTool.listActions()], False,
129                         'Configlet found after uninstallation')
[1837]130
131    def test_viewlets_uninstall(self):
132        VIEWLETS = ['quintagroup.seoptimizer.seotags',
133                    'quintagroup.seoptimizer.customscript']
134        request = self.app.REQUEST
135        view = queryMultiAdapter((self.portal, request), name="plone")
[3134]136        manager = queryMultiAdapter((self.portal['front-page'], request, view),
137                                    IViewletManager, name='plone.htmlhead')
[1837]138        for p in VIEWLETS:
139            self.assertEqual(manager.get(p) is None, True,
140                "'%s' viewlet present after uninstallation" % p)
[1493]141
[1837]142    def test_browserlayer_uninstall(self):
[2124]143        if not SUPPORT_BLAYER:
144            return
145
[1897]146        from plone.browserlayer import utils
[1837]147        self.assertEqual(IPloneSEOLayer in utils.registered_layers(), False,
[1897]148            "Still registered 'IPloneSEOLayer' browser layer")
[1493]149
[1837]150    def test_action_uninstall(self):
[3134]151        atool = getToolByName(self.portal, 'portal_actions')
[1837]152        action_ids = [a.id for a in atool.listActions()]
153        self.assertEqual("SEOProperties" in action_ids, False,
[3134]154                         "'SEOProperties' action not removed from " \
155                         "portal_actions on uninstallation")
[1835]156
[3134]157
[1849]158class TestReinstallation(TestCase):
[1836]159
[1849]160    def afterSetUp(self):
161        self.qi = self.portal.portal_quickinstaller
162        self.types_tool = getToolByName(self.portal, 'portal_types')
163        self.setup_tool = getToolByName(self.portal, 'portal_setup')
164        self.pprops_tool = getToolByName(self.portal, 'portal_properties')
[3134]165        self.seoprops_tool = getToolByName(self.pprops_tool, 'seo_properties',
166                                           None)
167        # Set earlier version profile (2.0.0) for using upgrade steps
168        self.setup_tool.setLastVersionForProfile('%s:default' % PROJECT_NAME,
169                                                 '2.0.0')
[1849]170
171    def testChangeDomain(self):
[3134]172        # Test changed of content type's domain from 'quintagroup.seoptimizer'
173        # to 'plone'
[1849]174        for type in SEO_CONTENT:
[3134]175            i18n_domain = 'quintagroup.seoptimizer'
176            self.types_tool.getTypeInfo(type).i18n_domain = i18n_domain
[1849]177        self.qi.reinstallProducts([PROJECT_NAME])
178        for type in SEO_CONTENT:
[3134]179            self.assertEqual(self.types_tool.getTypeInfo(type).i18n_domain,
180                             'plone', "Not changed of %s content type's " \
181                             "domain to 'plone'" % type)
[1849]182
183    def testCutItemsMetatagsOrderList(self):
[3134]184        # Test changed format metatags order list from "metaname accessor"
185        # to "metaname"
186        value, expect_mto = ['name1 accessor1', 'name2 accessor2'], \
187                            ['name1', 'name2']
[1849]188        self.seoprops_tool.manage_changeProperties(metatags_order=value)
189        self.qi.reinstallProducts([PROJECT_NAME])
190        mto = list(self.seoprops_tool.getProperty('metatags_order'))
191        mto.sort()
192        self.assertEqual(mto, expect_mto,
[3134]193                         "Not changed format metatags order list from \"" \
194                         "metaname accessor\" to \"metaname\". %s != %s" \
195                         % (mto, expect_mto))
[1849]196
197    def testAddMetatagsOrderList(self):
198        # Test added metatags order list if it was not there before
199        self.seoprops_tool.manage_delProperties(['metatags_order'])
200        self.qi.reinstallProducts([PROJECT_NAME])
201        mto = list(self.seoprops_tool.getProperty('metatags_order'))
202        mto.sort()
203        self.assertEqual(mto, DEFAULT_METATAGS_ORDER,
[3134]204                         "Not added metatags order list with default values." \
205                         "%s != %s" % (mto, DEFAULT_METATAGS_ORDER))
[1849]206
207    def testMigrationActions(self):
208        # Test migrated actions from portal_types action to seoproperties tool
209        self.seoprops_tool.content_types_with_seoproperties = ()
210
211        # Add seoaction to content type for testing
[3134]212
[1849]213        for type in CONTENTTYPES_WITH_SEOACTION:
[3134]214            self.types_tool.getTypeInfo(type).addAction(
215                                    id='seo_properties',
216                                    name='SEO Properties',
217                                    action=None,
218                                    condition=None,
219                                    permission=(u'Modify portal content',),
220                                    category='object',
221                                   )
[1849]222            # Check presence seoaction in content type
[3134]223            seoaction = [act.id for act in \
224                         self.types_tool.getTypeInfo(type).listActions() \
225                         if act.id == 'seo_properties']
[1849]226            self.assertEqual(bool(seoaction), True,
[3134]227                             "Not added seoaction to content type %s for " \
228                             "testing" % type)
[1849]229
230        self.qi.reinstallProducts([PROJECT_NAME])
231
232        # Check presence seoaction in content type
233        for type in CONTENTTYPES_WITH_SEOACTION:
[3134]234            seoaction = [act.id for act in \
235                         self.types_tool.getTypeInfo(type).listActions() \
236                         if act.id == 'seo_properties']
[1849]237            self.assertEqual(bool(seoaction), False,
238                "Not removed seoaction in content type %s" % type)
239
[3134]240        # Check added content type names in seo properties tool
241        # if content types have seoaction
[1849]242        ctws = list(self.seoprops_tool.content_types_with_seoproperties)
243        ctws.sort()
244        self.assertEqual(ctws, CONTENTTYPES_WITH_SEOACTION,
[3134]245                         "Not added content type names in seo properties " \
246                         "tool if content types have seoaction. %s != %s" \
247                         % (ctws, CONTENTTYPES_WITH_SEOACTION))
[1849]248
[1926]249    def testRemoveSkin(self):
250        # Test remove layers
251        layer = 'quintagroup.seoptimizer'
252        skinstool = getToolByName(self.portal, 'portal_skins')
253        for skin in skinstool.getSkinSelections():
[3134]254            paths = ','.join((skinstool.getSkinPath(skin), layer))
[1926]255            skinstool.addSkinSelection(skin, paths)
256        self.qi.reinstallProducts([PROJECT_NAME])
257        for skin in skinstool.getSkinSelections():
258            path = skinstool.getSkinPath(skin)
259            path = map(string.strip, string.split(path, ','))
260            self.assertEqual(layer in path, False,
[3134]261                             '%s layer found in %s after uninstallation' \
262                             % (layer, skin))
[1849]263
[1930]264    def testMigrateCanonical(self):
265        """ Test Migrate qSEO_canonical property into PROPERTY_LINK
266            for all portal objects, which use SEO
267        """
268        doc = self.portal.get('front-page')
269        doc.manage_addProperty('qSEO_canonical', 'val', 'string')
270        value = doc.getProperty('qSEO_canonical')
[3134]271        assert doc.getProperty('qSEO_canonical') == 'val'
[1926]272
[1930]273        self.qi.reinstallProducts([PROJECT_NAME])
274        value = doc.getProperty(PROPERTY_LINK)
275        has_prop = bool(doc.hasProperty('qSEO_canonical'))
[3134]276        self.assertEqual(has_prop, False, "Property 'qSEO_canonical' is " \
277                         "not deleted.")
278        self.assertEqual(value == 'val', True, "Property not migrated from " \
279                         "'qSEO_canonical' to '%s'." % PROPERTY_LINK)
[1930]280
[3134]281
[1493]282def test_suite():
283    from unittest import TestSuite, makeSuite
284    suite = TestSuite()
[1835]285    suite.addTest(makeSuite(TestBeforeInstallation))
[1493]286    suite.addTest(makeSuite(TestInstallation))
[1835]287    suite.addTest(makeSuite(TestUninstallation))
[1849]288    suite.addTest(makeSuite(TestReinstallation))
[1493]289    return suite
Note: See TracBrowser for help on using the repository browser.