source: products/quintagroup.plonetabs/trunk/quintagroup/plonetabs/tests/test_controlpanel.py @ 3608

Last change on this file since 3608 was 3608, checked in by vmaksymiv, 12 years ago

PPP fixes

File size: 20.8 KB
RevLine 
[775]1import unittest
2
[799]3from zope.interface import Interface
[775]4from zope.interface.verify import verifyClass
[799]5from zope.component import getMultiAdapter, provideAdapter
[775]6
7from Products.CMFCore.utils import getToolByName
[3437]8from Products.CMFCore.ActionInformation import Action
[775]9
[874]10from quintagroup.plonetabs import messageFactory as _
[775]11from quintagroup.plonetabs.browser.interfaces import IPloneTabsControlPanel
[3437]12from quintagroup.plonetabs.browser.plonetabs \
[3608]13    import PloneTabsControlPanel as ptp
[775]14from quintagroup.plonetabs.tests.base import PloneTabsTestCase
[798]15from quintagroup.plonetabs.tests.data import PORTAL_ACTIONS
[775]16
[3437]17
[798]18class TestControlPanelHelperMethods(PloneTabsTestCase):
19    """Test here configlet helper methods"""
[775]20    def afterSetUp(self):
[865]21        super(TestControlPanelHelperMethods, self).afterSetUp()
[775]22        self.loginAsPortalOwner()
[865]23        panel = getMultiAdapter((self.portal, self.portal.REQUEST),
[3608]24                                name='plonetabs-controlpanel')
[865]25        # we need this to apply zope2 security (got from zope2 traverse method)
26        self.panel = panel.__of__(self.portal)
[775]27        self.tool = getToolByName(self.portal, 'portal_actions')
[3437]28
[798]29    def test_redirect(self):
30        response = self.portal.REQUEST.RESPONSE
31        method = self.panel.redirect
[3437]32        portal_url = getMultiAdapter((self.portal, self.portal.REQUEST),
[3608]33                                     name=u"plone_portal_state").portal_url()
[865]34        url = '%s/@@plonetabs-controlpanel' % portal_url
[798]35        method()
36        self.assertEquals(response.headers.get('location', ''), url,
[3608]37                          'Redirect method is not working properly.')
[3437]38
[798]39        # check query string and anchor hash
40        method('http://quintagroup.com', 'q=test', 'hash_code')
41        self.assertEquals(response.headers.get('location', ''),
[3608]42                          'http://quintagroup.com?q=test#hash_code',
43                          'Redirect method is not working properly.')
[3437]44
[798]45    def test_fixExpression(self):
46        method = self.panel.fixExpression
47        self.assertEquals(method('/slash'), 'string:${portal_url}/slash')
[3437]48        self.assertEquals(method('https://test.com'),
[3608]49                          'string:https://test.com')
[798]50        self.assertEquals(method('python:True'), 'python:True')
51        self.assertEquals(method('hello'), 'string:${object_url}/hello')
[3437]52
[798]53    def test_copyAction(self):
54        data = PORTAL_ACTIONS[0][1]['children'][0][1]
55        action = Action('act1', **data)
56        info = self.panel.copyAction(action)
57        self.assertEquals(len(info.keys()), 6)
58        self.assertEquals(info['description'], 'The most important place')
[3437]59
[798]60    def test_validateActionFields(self):
61        method = self.panel.validateActionFields
62        good_data = PORTAL_ACTIONS[0][1]['children'][0][1].copy()
63        good_data['id'] = 'new_one'
64        errors = method('new_category', good_data)
65        self.assertEquals(errors, {},
[3608]66                          'There should be no errors for valid data.')
[3437]67
68        bad_data = {'id': '',
[798]69                    'title': ' ',
70                    'available_expr': 'bad_type:test',
71                    'url_expr': 'bad_type:test'}
[3437]72
[801]73        # Revert PloneTestCase's optimization
74        # because this breaks our test
[3437]75        from Products.CMFCore.Expression import getEngine
76        from Products.CMFCore.Expression import Expression
77
[801]78        def __init__(self, text):
79            self.text = text
80            if text.strip():
81                self._v_compiled = getEngine().compile(text)
[3437]82
[801]83        optimized__init__ = Expression.__init__
84        Expression.__init__ = __init__
[798]85        errors = method('new_category', bad_data)
[801]86        # rollback our patch
87        Expression.__init__ = optimized__init__
[3437]88
[798]89        self.assertEquals(len(errors.keys()), 4,
[3608]90                          'validateActionFields method is not working '
91                          'properly.')
[3437]92        #### pyflakes.scripts.pyflakes ends.
93
[798]94    def test_processErrors(self):
[799]95        method = self.panel.processErrors
[3437]96        errors = {'error': 'error message'}
[799]97        self.assertEquals(method(errors), errors,
[3608]98                          'processErrors method is not working properly.')
[799]99        self.assertEquals(method(errors, 'pre_', '_post'),
[3608]100                          {'pre_error_post': 'error message'},
101                          'processErrors method is not working properly.')
[3437]102
[798]103    def test_parseEditForm(self):
[799]104        method = self.panel.parseEditForm
105        form = {'orig_id': 'id1',
106                'category': 'cat1',
107                'visible_id1': True,
108                'id_id1': 'id_new',
109                'title_id1': 'title1',
110                'url_expr_id1': 'expr1',
111                'available_expr_id1': 'expr2'}
112        self.assertEquals(method(form),
[3608]113                          ('id1', 'cat1', {'id': 'id_new',
114                                           'title': 'title1',
115                                           'url_expr': 'expr1',
116                                           'available_expr': 'expr2',
117                                           'visible': True}),
118                          'parseEditForm method is not working properly.')
[3437]119
[799]120        del form['orig_id']
121        self.failUnlessRaises(KeyError, method, form)
[3437]122
[798]123    def test_parseAddForm(self):
[799]124        method = self.panel.parseAddForm
125        form = {'id': 'id1',
126                'category': 'cat1',
127                'visible': True,
128                'title': 'title1',
129                'url_expr': 'string:expr1',
130                'available_expr': 'expr2'}
131        self.assertEquals(method(form),
[3608]132                          ('id1', 'cat1', {'id': 'id1',
133                                           'visible': True,
134                                           'title': 'title1',
135                                           'url_expr': 'string:expr1',
136                                           'available_expr': 'expr2'}),
137                          'parseAddForm method is not working properly.')
[3437]138
[799]139        del form['id']
140        self.failUnlessRaises(KeyError, method, form)
[3437]141
[798]142    def test_getActionCategory(self):
[799]143        method = self.panel.getActionCategory
144        self.purgeActions()
145        self.failUnlessRaises(KeyError, method, 'portal_tabs')
[3437]146
[799]147        self.setupActions(self.tool)
148        self.assertEquals(method('portal_tabs').id, 'portal_tabs',
[3608]149                          'getActionCategory is not working properly.')
[3437]150
[798]151    def test_getOrCreateCategory(self):
[799]152        method = self.panel.getOrCreateCategory
153        self.purgeActions()
154        self.assertEquals(method('portal_tabs').id, 'portal_tabs',
[3608]155                          'getOrCreateCategory is not working properly.')
[3437]156
[798]157    def test_setSiteProperties(self):
[799]158        self.panel.setSiteProperties(title='Test Title')
159        sp = getToolByName(self.portal, 'portal_properties').site_properties
160        self.assertEquals(sp.getProperty('title'), 'Test Title',
[3608]161                          'setSiteProperties method is not working properly.')
[3437]162
[798]163    def test_renderViewlet(self):
[799]164        # register test viewlet and it's manager
165        from zope.viewlet.interfaces import IViewlet, IViewletManager
166        from zope.viewlet.viewlet import ViewletBase
167        from zope.viewlet.manager import ViewletManagerBase
168        from zope.publisher.interfaces.browser import IDefaultBrowserLayer
169        from zope.publisher.interfaces.browser import IBrowserView
[3437]170
[799]171        class TestViewlet(ViewletBase):
172            def __of__(self, obj):
173                return self
[3437]174
[799]175            def render(self):
176                return 'test viewlet'
[3437]177
[799]178        provideAdapter(
179            TestViewlet,
180            (Interface, IDefaultBrowserLayer, IBrowserView, IViewletManager),
181            IViewlet,
182            name=u'test_viewlet')
183        provideAdapter(
184            ViewletManagerBase,
185            (Interface, IDefaultBrowserLayer, IBrowserView),
186            IViewletManager,
187            name=u'test_manager')
[3437]188
[799]189        self.assertEquals(
190            self.panel.renderViewlet('test_manager', 'test_viewlet'),
191            'test viewlet',
192            'renderViewlet method is not workig properly')
[3437]193
[798]194    def test_addAction(self):
[799]195        self.purgeActions()
[3437]196        self.panel.addAction('new_category', {'id': 'id1', 'title': 'Test'})
[799]197        self.failUnless('id1' in self.tool.new_category.objectIds(),
[3608]198                        'addAction method is not workig properly')
[3437]199
[798]200    def test_updateAction(self):
[799]201        method = self.panel.updateAction
[3437]202
[799]203        self.purgeActions()
[3437]204        self.failUnlessRaises(KeyError, method, 'id1', 'cat1', {'id': 'new'})
205
[799]206        self.setupActions(self.tool)
207        # we need to commit transaction because
208        # we are going to rename just added action now
209        import transaction
210        transaction.savepoint()
[3437]211        method('home', 'portal_tabs', {'id': 'new_home'})
[799]212        self.failUnless('new_home' in self.tool.portal_tabs.objectIds(),
[3608]213                        'updateAction method is not workig properly')
[3437]214
[798]215    def test_deleteAction(self):
[799]216        self.purgeActions()
217        self.setupActions(self.tool)
218        self.panel.deleteAction('home', 'portal_tabs')
219        self.failIf('home' in self.tool.portal_tabs.objectIds(),
[3608]220                    'deleteAction method is not workig properly')
[3437]221
[798]222    def test_moveAction(self):
[799]223        self.purgeActions()
224        self.setupActions(self.tool)
225        pos = self.tool.portal_tabs.getObjectPosition
226        self.assertEquals(pos('home'), 0,
[3608]227                          'moveAction method is not workig properly')
[799]228        self.panel.moveAction('home', 'portal_tabs', -1)
229        self.assertEquals(pos('home'), 1,
[3608]230                          'moveAction method is not workig properly')
[798]231
232
[917]233class TestControlPanelAPIMethods(PloneTabsTestCase):
[798]234    """Test here interface methods of control panel class"""
[3437]235
[798]236    def afterSetUp(self):
[917]237        super(TestControlPanelAPIMethods, self).afterSetUp()
[798]238        self.loginAsPortalOwner()
[865]239        panel = getMultiAdapter((self.portal, self.portal.REQUEST),
[3608]240                                name='plonetabs-controlpanel')
[865]241        # we need this to apply zope2 security (got from zope2 traverse method)
242        self.panel = panel.__of__(self.portal)
[798]243        self.tool = getToolByName(self.portal, 'portal_actions')
[3437]244
[775]245    def test_interface(self):
246        self.failUnless(IPloneTabsControlPanel.implementedBy(ptp),
[3608]247                        'PloneTabs control panel does not implement '
248                        'required interface.')
[775]249        self.failUnless(verifyClass(IPloneTabsControlPanel, ptp),
[3608]250                        'PloneTabs control panel does not implement '
251                        'required interface.')
[3437]252
[775]253    def test_getPageTitle(self):
254        self.assertEquals(self.panel.getPageTitle(),
[3608]255                          _(u"Portal Tabs Configuration"),
256                          'getPageTitle method is broken')
[775]257        self.assertEquals(self.panel.getPageTitle(category='notexists'),
[3608]258                          _(u"Plone '${cat_name}' Configuration",
259                            mapping={'cat_name': 'notexists'}),
260                          'getPageTitle method is broken')
[3437]261
[775]262    def test_hasActions(self):
263        method = self.panel.hasActions
264        # purge any default portal actions
265        self.purgeActions()
266        self.failIf(method(),
[3608]267                    'There should be no portal_tab actions in portal')
[3437]268
[775]269        # setup our own actions
270        self.setupActions(self.tool)
271        self.failUnless(method(),
[3608]272                        'There should be portal_tab actions in portal')
[3437]273
[775]274    def test_getPortalActions(self):
275        method = self.panel.getPortalActions
276        # purge any default portal actions
277        self.purgeActions()
[3608]278        self.assertEquals(len(method()), 0, 'There should be no actions in '
279                          'portal_tabs category.')
[3437]280
[775]281        # setup our own actions
282        self.setupActions(self.tool)
283        self.assertEquals(len(method()), 2,
[3608]284                          'There should be 2 actions in portal_tabs category.')
[3437]285
[775]286        # marginal arguments
287        self.assertEquals(len(method('notexistent_category')), 0,
[3608]288                          'There should be no actions for not existed '
289                          'category.')
[3437]290
[775]291    def test_isGeneratedTabs(self):
292        method = self.panel.isGeneratedTabs
293        # prepare value
294        sp = getToolByName(self.portal, 'portal_properties').site_properties
295        sp.manage_changeProperties(disable_folder_sections=True)
296        self.failIf(method(), 'But folder sections are disabled...')
[3437]297
[775]298    def test_isNotFoldersGenerated(self):
299        method = self.panel.isNotFoldersGenerated
300        # prepare value
301        sp = getToolByName(self.portal, 'portal_properties').site_properties
302        sp.manage_changeProperties(disable_nonfolderish_sections=True)
303        self.failIf(method(), 'But non folderish sections are disabled...')
[3437]304
[775]305    def test_getActionsList(self):
306        method = self.panel.getActionsList
307        # purge any default portal actions
308        self.purgeActions()
309        self.failIf('class="editform"' in method(),
[3608]310                    'There should no be actions in actions list template.')
[775]311        self.setupActions(self.tool)
312        self.failUnless('class="editform"' in method(),
[3608]313                        'There are no actions in actions list template.')
[3437]314
[775]315    def test_getAutoGenereatedSection(self):
316        method = self.panel.getAutoGenereatedSection
317        self.failIf('<form' in method('user'),
[3608]318                    'There should be no form in autogenerated tabs template '
319                    'for category other than portal_tabs.')
[775]320        self.failUnless('<form' in method('portal_tabs'),
[3608]321                        'There should be form in autogenerated tabs template '
322                        'for portal_tabs category.')
[3437]323
[775]324    def test_getGeneratedTabs(self):
325        self.panel.getGeneratedTabs()
326        # check expiration header set by generated tabs template
327        self.assertEquals(
328            self.portal.REQUEST.RESPONSE.headers.get('expires', ''),
329            'Mon, 26 Jul 1996 05:00:00 GMT',
330            'Expiration header is not set properly.')
[3437]331
[775]332    def test_getRootTabs(self):
333        method = self.panel.getRootTabs
334        # make sure we don't depend on external settings
335        self.purgeContent()
336        self.assertEquals(len(method()), 0,
[3608]337                          'There should be no root elements for navigation.')
[3437]338
[775]339        # now add some testing content
340        self.setupContent(self.portal)
[3608]341        self.assertEquals(len(method()), 2, 'There should be 2 elements in '
342                          'portal root for navigation.')
[3437]343
[775]344        # now switch off autogeneration
345        sp = getToolByName(self.portal, 'portal_properties').site_properties
346        sp.manage_changeProperties(disable_folder_sections=True)
347        self.assertEquals(len(method()), 0,
[3608]348                          'There should be no root elements for navigation '
349                          'when tabs autogeneration is switched off.')
[3437]350
[775]351    def test_getCategories(self):
352        method = self.panel.getCategories
353        # purge any default portal actions
354        self.purgeActions()
[3608]355        self.assertEquals(len(method()), 0, 'There should be no categories '
356                          'in portal_actions tool.')
[3437]357
[775]358        # now setup actions
359        self.setupActions(self.tool)
360        self.assertEquals(method(), ['portal_tabs', 'new_category'],
[3608]361                          'There should be exactly 2 categories in '
362                          'portal_actions tool.')
[3437]363
[775]364    def test_portal_tabs(self):
365        method = self.panel.portal_tabs
366        self.purgeContent()
367        self.purgeActions()
368        self.assertEquals(len(method()), 0,
[3608]369                          'There should be no portal tabs.')
[3437]370
[798]371        # cleanup memoize cache
372        # cause actions method of portal context state is caching it's
373        # results in request and we have the same request for every call
374        self.purgeCache(self.portal.REQUEST)
[3437]375
[775]376        # add actions
377        self.setupActions(self.tool)
378        self.assertEquals(len(method()), 2,
[3608]379                          'There should be 2 portal tabs.')
[3437]380
[775]381        # add content
382        self.setupContent(self.portal)
383        self.assertEquals(len(method()), 4,
[3608]384                          'There should be 4 portal tabs.')
[3437]385
[775]386    def test_selected_portal_tab(self):
[798]387        self.assertEquals(self.panel.selected_portal_tab(), 'index_html',
[3608]388                          'index_html is not selected tab while being on '
389                          'configlet.')
[775]390
391    def test_test(self):
[798]392        self.assertEquals(self.panel.test(True, 'true', 'false'), 'true',
[3608]393                          'Test function does not work properly.')
[775]394
395
[801]396class TestControlPanelManageMethods(PloneTabsTestCase):
397    """Test here management methods of control panel class"""
[3437]398
[801]399    def afterSetUp(self):
[865]400        super(TestControlPanelManageMethods, self).afterSetUp()
[801]401        self.loginAsPortalOwner()
[865]402        panel = getMultiAdapter((self.portal, self.portal.REQUEST),
[3608]403                                name='plonetabs-controlpanel')
[865]404        # we need this to apply zope2 security (got from zope2 traverse method)
405        self.panel = panel.__of__(self.portal)
[801]406        self.tool = getToolByName(self.portal, 'portal_actions')
[3437]407
[801]408        # purge standard set of actions and set our own testing ones
409        self.purgeActions()
410        self.setupActions(self.tool)
[3437]411
[801]412    def test_manage_setAutogeneration(self):
413        self.setupContent(self.portal)
414        form = {'generated_tabs': '1',
415                'nonfolderish_tabs': '0',
416                'folder1': '0'}
417        self.panel.manage_setAutogeneration(form, {})
418        self.failUnless(self.portal.folder1.exclude_from_nav())
419        sp = getToolByName(self.portal, 'portal_properties').site_properties
420        self.failIf(sp.disable_folder_sections)
421        self.failUnless(sp.disable_nonfolderish_sections)
[3437]422
[801]423    def test_manage_addAction(self):
424        self.purgeActions()
425        form = {'id': 'id1',
426                'category': 'cat1',
427                'visible': True,
428                'title': 'title1',
429                'url_expr': 'string:expr1',
430                'available_expr': 'expr2'}
431        postback = self.panel.manage_addAction(form, {})
432        self.failUnless('id1' in self.tool.cat1.objectIds())
433        self.failIf(postback,
[3608]434                    'There should be redirect after successfull adding.')
[3437]435
[801]436    def test_manage_editAction(self):
437        method = self.panel.manage_editAction
438        self.purgeActions()
439        self.setupActions(self.tool)
440        form = {'orig_id': 'home',
441                'category': 'portal_tabs',
442                'visible_home': True,
443                'id_home': 'id_new',
444                'title_home': 'title1',
445                'url_expr_home': 'expr1',
446                'available_expr_home': 'expr2'}
447        import transaction
448        transaction.savepoint()
[3437]449
[801]450        postback = method(form, {})
451        self.failUnless('id_new' in self.tool.portal_tabs.objectIds())
452        self.failIf(postback,
[3608]453                    'There should be redirect after successfull edition.')
[3437]454
[801]455        form['category'] = 'non_existent'
456        self.failUnlessRaises(KeyError, method, form, {})
[3437]457
[801]458    def test_manage_deleteAction(self):
459        self.purgeActions()
460        self.setupActions(self.tool)
461        form = {'orig_id': 'home',
462                'category': 'portal_tabs',
463                'visible_home': True,
464                'id_home': 'id_new',
465                'title_home': 'title1',
466                'url_expr_home': 'expr1',
467                'available_expr_home': 'expr2'}
468        self.panel.manage_deleteAction(form, {})
469        self.failIf('home' in self.tool.portal_tabs.objectIds())
[3437]470
[801]471    def test_manage_moveUpAction(self):
472        self.purgeActions()
473        self.setupActions(self.tool)
474        form = {'orig_id': 'quintagroup',
475                'category': 'portal_tabs',
476                'visible_quintagroup': True,
477                'id_quintagroup': 'quintagroup',
478                'title_quintagroup': 'title1',
479                'url_expr_quintagroup': 'expr1',
480                'available_expr_quintagroup': 'expr2'}
481        self.panel.manage_moveUpAction(form, {})
482        self.assertEquals(
483            self.tool.portal_tabs.getObjectPosition('quintagroup'), 0)
[3437]484
[801]485    def test_manage_moveDownAction(self):
486        self.purgeActions()
487        self.setupActions(self.tool)
488        form = {'orig_id': 'home',
489                'category': 'portal_tabs',
490                'visible_home': True,
491                'id_home': 'home',
492                'title_home': 'title1',
493                'url_expr_home': 'expr1',
494                'available_expr_home': 'expr2'}
495        self.panel.manage_moveDownAction(form, {})
496        self.assertEquals(self.tool.portal_tabs.getObjectPosition('home'), 1)
497
498
[775]499def test_suite():
500    suite = unittest.TestSuite()
[798]501    suite.addTest(unittest.makeSuite(TestControlPanelHelperMethods))
[917]502    suite.addTest(unittest.makeSuite(TestControlPanelAPIMethods))
[801]503    suite.addTest(unittest.makeSuite(TestControlPanelManageMethods))
[3437]504
[865]505    # these tests are implemented as Selenium KSS Tests
506    # using kss.demo package, and KSS plugins are tested by means of
507    # ecmaunit.js
[775]508    #suite.addTest(unittest.makeSuite(TestControlPanelKSSMethods))
509    return suite
Note: See TracBrowser for help on using the repository browser.