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

Last change on this file since 3437 was 3437, checked in by potar, 12 years ago

Merged tests branch

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