source: products/quintagroup.analytics/trunk/quintagroup/analytics/tests.py @ 3603

Last change on this file since 3603 was 3603, checked in by ktarasz, 10 years ago

fixed pep8 for tests.py

File size: 20.8 KB
Line 
1import unittest
2import transaction
3
4from AccessControl.SecurityManagement import newSecurityManager
5from Testing import ZopeTestCase as ztc
6from Products.Five import zcml
7from Products.Five import fiveconfigure
8from zope.component import queryMultiAdapter, getUtility
9
10from Products.PloneTestCase import PloneTestCase as ptc
11from Products.PloneTestCase import setup as ptc_setup
12from Products.PloneTestCase.layer import PloneSite
13from plone.portlets.interfaces import IPortletType
14try:
15    from Products.PloneTestCase.version import PLONE40
16    PLONE40 = PLONE40
17except ImportError:
18    PLONE40 = False
19
20import quintagroup.analytics
21
22ptc.setupPloneSite()
23
24
25class Installed(PloneSite):
26
27    @classmethod
28    def setUp(cls):
29        fiveconfigure.debug_mode = True
30        zcml.load_config('configure.zcml',
31                         quintagroup.analytics)
32        fiveconfigure.debug_mode = False
33        ztc.installPackage('quintagroup.analytics')
34        app = ztc.app()
35        portal = app[ptc_setup.portal_name]
36
37        # Sets the local site/manager
38        ptc_setup._placefulSetUp(portal)
39
40        qi = getattr(portal, 'portal_quickinstaller', None)
41        qi.installProduct('quintagroup.analytics')
42        transaction.commit()
43
44    @classmethod
45    def tearDown(cls):
46        pass
47
48
49class SetUpContent(Installed):
50
51    max = 10
52    types_ = ['Document', 'Event', 'Folder']
53    users = [('user%s' % i, 'user%s' % i, 'Member', None)
54             for i in xrange(max)]
55
56    @classmethod
57    def setupUsers(cls, portal):
58        """ Creates users."""
59        acl_users = portal.acl_users
60        mp = portal.portal_membership
61        map(acl_users._doAddUser, *zip(*cls.users))
62        if not mp.memberareaCreationFlag:
63            mp.setMemberareaCreationFlag()
64        map(mp.createMemberArea, [u[0] for u in cls.users])
65
66    @classmethod
67    def setupContent(cls, portal):
68        """ Creates test content."""
69        uf = portal.acl_users
70        pm = portal.portal_membership
71        #portal.portal_catalog
72        users = [u[0] for u in cls.users]
73        for u in users:
74            folder = pm.getHomeFolder(u)
75            user = uf.getUserById(u)
76            if not hasattr(user, 'aq_base'):
77                user = user.__of__(uf)
78            newSecurityManager(None, user)
79            for i in xrange(users.index(u) + cls.max):
80                map(folder.invokeFactory, cls.types_,
81                    [t + str(i) for t in cls.types_])
82        transaction.commit()
83
84    @classmethod
85    def setUp(cls):
86        app = ztc.app()
87        portal = app[ptc_setup.portal_name]
88        cls.setupUsers(portal)
89        cls.setupContent(portal)
90
91    @classmethod
92    def tearDown(cls):
93        pass
94
95
96class TestCase(ptc.PloneTestCase):
97    layer = Installed
98
99
100class TestQAInstallation(TestCase):
101    """ This class veryfies registrations of all needed views and
102        actions.
103    """
104
105    def test_cp_action_installation(self):
106        """This test validates control panel action. """
107        control_panel = self.portal.portal_controlpanel
108        self.assert_(
109            'QAnalytics' in [a.id for a in control_panel.listActions()],
110            "Configlet for quintagroup.analitycs isn't registered.")
111
112    def test_OwnershipByType(self):
113        """ This test validates registration of
114            ownership_by_type view.
115        """
116        view = queryMultiAdapter((self.portal, self.portal.REQUEST),
117                                 name="ownership_by_type")
118
119        self.assert_(view, "Ownership by type view isn't registered")
120
121    def test_OwnershipByState(self):
122        """ This test validates registration of
123            ownership_by_state view.
124        """
125        view = queryMultiAdapter((self.portal, self.portal.REQUEST),
126                                 name="ownership_by_state")
127
128        self.assert_(view, "Ownership by state view isn't registered")
129
130    def test_TypeByState(self):
131        """ This test validates registration of
132            type_by_state view.
133        """
134        view = queryMultiAdapter((self.portal, self.portal.REQUEST),
135                                 name="type_by_state")
136
137        self.assert_(view, "Type by state view isn't registered")
138
139    def test_LegacyPortlets(self):
140        """ This test validates registration of
141            legacy_portlets view.
142        """
143        view = queryMultiAdapter((self.portal, self.portal.REQUEST),
144                                 name="legacy_portlets")
145
146        self.assert_(view, "Legacy Portlets view isn't registered")
147
148    def test_PropertiesStats(self):
149        """ This test validates registration of
150            properties_stats view.
151        """
152        view = queryMultiAdapter((self.portal, self.portal.REQUEST),
153                                 name="properties_stats")
154
155        self.assert_(view, "Properties Stats view isn't registered")
156
157    def test_PortletsStats(self):
158        """ This test validates registration of
159            portlets_stats view.
160        """
161        view = queryMultiAdapter((self.portal, self.portal.REQUEST),
162                                 name="portlets_stats")
163
164        self.assert_(view, "Portlets Stats view isn't registered")
165
166
167class TestOwnershipByType(TestCase):
168    """Tests all ownership by type view methods."""
169
170    layer = SetUpContent
171
172    def afterSetUp(self):
173        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
174                                      name="ownership_by_type")
175        self.pc = self.portal.portal_catalog
176        portal_migration = self.portal.portal_migration
177        version = portal_migration.getFileSystemVersion()
178        self.plone_version = version.replace(".", "")
179
180    def test_getUsers(self):
181        """ Tests method that returns ordered list of users."""
182        users = [u[0] for u in self.layer.users]
183        users.reverse()
184        self.assert_(False not in map(lambda u1, u2: u1 == u2,
185                     users, self.view.getUsers()))
186
187    def test_getTypes(self):
188        """ Tests method that returns ordered list of types."""
189        data = {}
190        index = self.pc._catalog.getIndex('portal_type')
191        for k in index._index.keys():
192            if not k:
193                continue
194            haslen = hasattr(index._index[k], '__len__')
195
196            if haslen:
197                data[k] = len(index._index[k])
198            else:
199                data[k] = 1
200
201        data = data.items()
202        data.sort(lambda a, b: a[1] - b[1])
203        data.reverse()
204        types = [i[0] for i in data]
205        self.assert_(False not in map(lambda t1, t2: t1 == t2,
206                     self.view.getTypes(), types))
207
208    def test_getContent(self):
209        """ This test verifies method that returns list of numbers.
210            Each number is amount of specified content type objects
211            that owned  by particular user.
212        """
213        # we need to login in to the site as Manager to be able to
214        # see catalog results
215        self.loginAsPortalOwner()
216
217        for type_ in self.layer.types_:
218            self.assert_(False not in
219                         map(
220                             lambda i, j: i == j, [len(
221                                 self.pc(portal_type=type_,
222                                         Creator=user))
223                                 for user in self.view.getUsers()],
224                             self.view.getContent(type_)))
225
226    def test_getChart(self):
227        """ This test verifies creation of chart image tag."""
228        plone33chart_tag = \
229            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
230            '57&amp;chd=t:19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,11.0,'\
231            '10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,11.0,10.0|'\
232            '19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,11.0,10.0|0.0,'\
233            '0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0|0.0,0.0,0.0,0.0,'\
234            '0.0,0.0,0.0,0.0,0.0,0.0&amp;chxr=0,0,57&amp;'\
235            'chco=669933,cc9966,993300,ff6633,e8e4e3,a9a486,'\
236            'dcb57e,ffcc99,996633,333300,00ff00&amp;'\
237            'chl=user9|user8|user7|user6|user5|user4|user3|user2|user1|'\
238            'user0&amp;chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;'\
239            'chtt=Content+ownership+by+type&amp;chdl=Folder|Document|Event'\
240            '|Large+Plone+Folder|Topic&amp;chdlp=b"/>'
241        plone4chart_tag = \
242            '<img src="http://chart.apis.google.com/chart?chxt=y&amp;'\
243            'chds=0,57&amp;chd=t:19.0,18.0,17.0,16.0,15.0,14.0,'\
244            '13.0,12.0,11.0,10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,'\
245            '12.0,11.0,10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,'\
246            '11.0,10.0|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0&amp;'\
247            'chxr=0,0,57&amp;chco=669933,cc9966,993300,ff6633,e8e4e3,'\
248            'a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=user9|'\
249            'user8|user7|user6|user5|user4|user3|user2|user1|user0&amp;'\
250            'chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;'\
251            'chtt=Content+ownership+by+type&amp;chdl=Folder|Document|'\
252            'Event|Topic&amp;chdlp=b" />'
253        plone42chart_tag = \
254            '<img src="http://chart.apis.google.com/chart?chxt=y&amp;'\
255            'chds=0,57&amp;chd=t:19.0,18.0,17.0,16.0,15.0,14.0,'\
256            '13.0,12.0,11.0,10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,'\
257            '12.0,11.0,10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,'\
258            '11.0,10.0|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0&amp;'\
259            'chxr=0,0,57&amp;chco=669933,cc9966,993300,ff6633,e8e4e3,'\
260            'a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=user9|'\
261            'user8|user7|user6|user5|user4|user3|user2|user1|user0&amp;'\
262            'chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;'\
263            'chtt=Content+ownership+by+type&amp;chdl=Folder|Document|'\
264            'Event|Collection&amp;chdlp=b"/>'
265
266        if self.plone_version < "40":
267            chart_tag = plone33chart_tag
268        elif self.plone_version > "42":
269            chart_tag = plone42chart_tag
270        else:
271            chart_tag = plone4chart_tag
272
273        self.loginAsPortalOwner()
274        self.assertEqual(*map(lambda s: ''.join(s.split()),
275                              [chart_tag, self.view.getChart()]))
276
277
278class TestOwnershipByState(TestCase):
279    """Tests all ownership by state view methods."""
280
281    layer = SetUpContent
282
283    states = ['private', 'published', 'pending']
284
285    def afterSetUp(self):
286        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
287                                      name="ownership_by_state")
288        self.pc = self.portal.portal_catalog
289
290    def test_getUsers(self):
291        """ Tests method that returns ordered list of users."""
292        users = [u[0] for u in self.layer.users]
293        users.reverse()
294        self.assert_(False not in map(lambda u1, u2: u1 == u2,
295                     users, self.view.getUsers()))
296
297    def test_getStates(self):
298        """ Tests method that returns ordered list of states."""
299        self.assert_(False not in map(lambda s1, s2: s1 == s2,
300                     ['private', 'published'], self.view.getStates()))
301
302    def test_getContent(self):
303        """ This test verifies method that returns list of numbers.
304            Each number is amount of specified content type objects
305            that are in particular workflow state.
306        """
307        # we need to login in to the site as Manager to be able to
308        # see catalog results
309        self.loginAsPortalOwner()
310
311        for state in self.states:
312            self.assert_(False not in
313                         map(
314                             lambda i, j: i == j, [len(
315                                 self.pc(review_state=state,
316                                         Creator=user))
317                                 for user in self.view.getUsers()],
318                             self.view.getContent(state)))
319
320    def test_getChart(self):
321        """ This test verifies creation of chart image tag."""
322        chart_tag = """<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;
323                       chds=0,57&amp;chd=t:57.0,54.0,51.0,48.0,45.0,42.0,39.0,
324                       36.0,33.0,30.0|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
325                       0.0|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0&amp;chxr=0,
326                       0,57&amp;chco=669933,cc9966,993300,ff6633,e8e4e3,a9a486,
327                       dcb57e,ffcc99,996633,333300,00ff00&amp;chl=user9|user8|
328                       user7|user6|user5|user4|user3|user2|user1|user0&amp;
329                       chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;
330                       chtt=Content+ownership+by+state&amp;chdl=private|
331                       published|No+workflow&amp;chdlp=b"/>"""
332        self.loginAsPortalOwner()
333        self.assertEqual(*map(lambda s: ''.join(s.split()),
334                              [chart_tag, self.view.getChart()]))
335
336
337class TestTypeByState(TestCase):
338    """Tests all type_by_state view methods."""
339    layer = SetUpContent
340    states = ['private', 'published', 'pending']
341
342    def afterSetUp(self):
343        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
344                                      name="type_by_state")
345        self.pc = self.portal.portal_catalog
346        portal_migration = self.portal.portal_migration
347        version = portal_migration.getFileSystemVersion()
348        self.plone_version = version.replace(".", "")
349
350    def test_getTypes(self):
351        """ Tests method that returns ordered list of types."""
352        index = self.pc._catalog.getIndex('portal_type')
353        data = {}
354
355        for k in index._index.keys():
356            if not k:
357                continue
358            haslen = hasattr(index._index[k], '__len__')
359
360            if haslen:
361                data[k] = len(index._index[k])
362
363            else:
364                data[k] = 1
365        data = data.items()
366        data.sort(lambda a, b: a[1] - b[1])
367        data.reverse()
368
369        types = [i[0] for i in data]
370        self.assert_(False not in map(lambda t1, t2: t1 == t2, types,
371                                      self.view.getTypes()))
372
373    def test_getStates(self):
374        """ Tests method that returns ordered list of states."""
375        self.assert_(False not in map(lambda s1, s2: s1 == s2,
376                     ['private', 'published'], self.view.getStates()))
377
378    def test_getContent(self):
379        """ This test verifies method that returns list of numbers.
380            Each number is amount of specified content type objects
381            that owned  by particular user.
382        """
383        # we need to login in to the site as Manager to be able to
384        # see catalog results
385        self.loginAsPortalOwner()
386
387        for state in self.states:
388            self.assert_(False not in
389                         map(
390                             lambda i, j: i == j, [len(
391                                 self.pc(portal_type=type_,
392                                         review_state=state))
393                                 for type_ in self.view.getTypes()],
394                             self.view.getContent(state)))
395
396    def test_getChart(self):
397        """ This test verifies creation of chart image tag."""
398        plone33chart_tag = \
399            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
400            '156&amp;chd=t:156.0,145.0,145.0,0.0,0.0|0.0,1.0,0.0,3.0,3.0|'\
401            '0.0,0.0,0.0,0.0,0.0&amp;chxr=0,0,156&amp;chco=669933,cc9966,'\
402            '993300,ff6633,e8e4e3,a9a486,dcb57e,ffcc99,996633,333300,'\
403            '00ff00&amp;chl=Folder|Document|Event|Large+Plone+Folder|'\
404            'Topic&amp;chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;'\
405            'chtt=Content+type+by+state&amp;chdl=private|published|'\
406            'No+workflow&amp;chdlp=b"/>'
407        plone4chart_tag = \
408            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
409            '159&amp;chd=t:156.0,145.0,145.0,0.0|3.0,1.0,0.0,3.0|0.0,0.0,0.'\
410            '0,0.0&amp;chxr=0,0,159&amp;chco=669933,cc9966,993300,ff6633,e8'\
411            'e4e3,a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=Folder|'\
412            'Document|Event|Topic&amp;chbh=a,10,0&amp;chs=800x375&amp;cht=b'\
413            'vs&amp;chtt=Content+type+by+state&amp;chdl=private|published|N'\
414            'o+workflow&amp;chdlp=b"/>'
415        plone41chart_tag = \
416            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
417            '159&amp;chd=t:156.0,145.0,145.0,0.0|3.0,1.0,0.0,2.0|0.0,0.0,0.'\
418            '0,0.0&amp;chxr=0,0,159&amp;chco=669933,cc9966,993300,ff6633,e8'\
419            'e4e3,a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=Folder|'\
420            'Document|Event|Topic&amp;chbh=a,10,0&amp;chs=800x375&amp;cht=b'\
421            'vs&amp;chtt=Content+type+by+state&amp;chdl=private|published|N'\
422            'o+workflow&amp;chdlp=b"/>'
423        plone42chart_tag = \
424            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
425            '159&amp;chd=t:156.0,145.0,145.0,0.0|3.0,1.0,0.0,2.0|0.0,0.0,0.'\
426            '0,0.0&amp;chxr=0,0,159&amp;chco=669933,cc9966,993300,ff6633,e8'\
427            'e4e3,a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=Folder|'\
428            'Document|Event|Collection&amp;chbh=a,10,0&amp;chs=800x375&amp;'\
429            'cht=bvs&amp;chtt=Content+type+by+state&amp;chdl=private|publis'\
430            'hed|No+workflow&amp;chdlp=b"/>'
431
432        if self.plone_version < "40":
433            chart_tag = plone33chart_tag
434        elif self.plone_version > "40" and self.plone_version < "41":
435            chart_tag = plone4chart_tag
436        elif self.plone_version > "41" and self.plone_version < "42":
437            chart_tag = plone41chart_tag
438        elif self.plone_version > "42":
439            chart_tag = plone42chart_tag
440
441        self.loginAsPortalOwner()
442        self.assertEqual(*map(lambda s: ''.join(s.split()),
443                              [chart_tag, self.view.getChart()]))
444
445
446class LegacyPortlets(TestCase):
447    """Test all legasy_portlets view methods."""
448
449    def afterSetUp(self):
450        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
451                                      name='legacy_portlets')
452
453    def test_getPortlets(self):
454        """Tests method that returns portlets info."""
455
456        # this is true for Plone 4
457        self.assert_(self.view.getPortlets() == [])
458
459    def test_getAllPortletExpressions(self):
460        """Tests method that returns portlets expressions."""
461
462        # this is true for Plone 4
463        self.assert_(self.view.getAllPortletExpressions() == [])
464
465
466class TestPropertiesStats(TestCase):
467    """Tests all properties_stats view methods."""
468
469    def afterSetUp(self):
470        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
471                                      name='properties_stats')
472
473    def test_getPropsList(self):
474        self.view.propname = 'title'
475        result = [u'Plone site', u'Welcome to Plone',
476                  u'News', u'Events', u'Users']
477
478        for title in result:
479            self.assert_(title in [prop_info['slots']
480                                   for prop_info in self.view.getPropsList()])
481
482
483class TestPortletsStats(TestCase):
484    """Tests all properties_stats view methods."""
485
486    def afterSetUp(self):
487        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
488                                      name='portlets_stats')
489
490    def test_getPropsList(self):
491        """Tests method that collects portlet information from site."""
492
493        self.loginAsPortalOwner()
494        portlet = getUtility(IPortletType, name='portlets.Calendar')
495        mapping = \
496            self.portal.restrictedTraverse(
497                '++contextportlets++plone.leftcolumn')
498        mapping.restrictedTraverse('+/' + portlet.addview)()
499
500        plone_portlets_info = filter(lambda info: info['path'] == '/plone',
501                                     self.view.getPropsList())
502        lslots = plone_portlets_info[0]['left_slots']
503        self.assert_(info for info in lslots if info['title'] == 'Calendar')
504
505
506def test_suite():
507    test_suite = unittest.TestSuite([
508
509        # Unit tests
510        #doctestunit.DocFileSuite(
511        #    'README.txt', package='quintagroup.contentstats',
512        #    setUp=testing.setUp, tearDown=testing.tearDown),
513
514        #doctestunit.DocTestSuite(
515        #    module='quintagroup.contentstats.mymodule',
516        #    setUp=testing.setUp, tearDown=testing.tearDown),
517
518
519        # Integration tests that use PloneTestCase
520        #ztc.ZopeDocFileSuite(
521        #    'README.txt', package='quintagroup.contentstats',
522        #    test_class=TestCase),
523
524        #ztc.FunctionalDocFileSuite(
525        #    'browser.txt', package='quintagroup.contentstats',
526        #    test_class=TestCase),
527
528    ])
529
530    test_suite.addTest(unittest.makeSuite(TestQAInstallation))
531    test_suite.addTest(unittest.makeSuite(TestOwnershipByType))
532    test_suite.addTest(unittest.makeSuite(TestOwnershipByState))
533    test_suite.addTest(unittest.makeSuite(TestTypeByState))
534    test_suite.addTest(unittest.makeSuite(LegacyPortlets))
535    test_suite.addTest(unittest.makeSuite(TestPropertiesStats))
536    test_suite.addTest(unittest.makeSuite(TestPortletsStats))
537    return test_suite
538
539if __name__ == '__main__':
540    unittest.main(defaultTest='test_suite')
Note: See TracBrowser for help on using the repository browser.