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

Last change on this file since 3465 was 3465, checked in by kroman0, 12 years ago

Fixed tests for plone 42 and pyflakes

File size: 20.6 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(lambda i, j: i == j, [len(self.pc(portal_type=type_,
220                                               Creator=user))
221                                   for user in self.view.getUsers()],
222                                  self.view.getContent(type_)))
223
224    def test_getChart(self):
225        """ This test verifies creation of chart image tag."""
226        plone33chart_tag = \
227            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
228            '57&amp;chd=t:19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,11.0,'\
229            '10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,11.0,10.0|'\
230            '19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,11.0,10.0|0.0,'\
231            '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,'\
232            '0.0,0.0,0.0,0.0,0.0,0.0&amp;chxr=0,0,57&amp;'\
233            'chco=669933,cc9966,993300,ff6633,e8e4e3,a9a486,'\
234            'dcb57e,ffcc99,996633,333300,00ff00&amp;'\
235            'chl=user9|user8|user7|user6|user5|user4|user3|user2|user1|'\
236            'user0&amp;chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;'\
237            'chtt=Content+ownership+by+type&amp;chdl=Folder|Document|Event'\
238            '|Large+Plone+Folder|Topic&amp;chdlp=b"/>'
239        plone4chart_tag = \
240            '<img src="http://chart.apis.google.com/chart?chxt=y&amp;'\
241            'chds=0,57&amp;chd=t:19.0,18.0,17.0,16.0,15.0,14.0,'\
242            '13.0,12.0,11.0,10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,'\
243            '12.0,11.0,10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,'\
244            '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;'\
245            'chxr=0,0,57&amp;chco=669933,cc9966,993300,ff6633,e8e4e3,'\
246            'a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=user9|'\
247            'user8|user7|user6|user5|user4|user3|user2|user1|user0&amp;'\
248            'chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;'\
249            'chtt=Content+ownership+by+type&amp;chdl=Folder|Document|'\
250            'Event|Topic&amp;chdlp=b" />'
251        plone42chart_tag = \
252            '<img src="http://chart.apis.google.com/chart?chxt=y&amp;'\
253            'chds=0,57&amp;chd=t:19.0,18.0,17.0,16.0,15.0,14.0,'\
254            '13.0,12.0,11.0,10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,'\
255            '12.0,11.0,10.0|19.0,18.0,17.0,16.0,15.0,14.0,13.0,12.0,'\
256            '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;'\
257            'chxr=0,0,57&amp;chco=669933,cc9966,993300,ff6633,e8e4e3,'\
258            'a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=user9|'\
259            'user8|user7|user6|user5|user4|user3|user2|user1|user0&amp;'\
260            'chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;'\
261            'chtt=Content+ownership+by+type&amp;chdl=Folder|Document|'\
262            'Event|Collection&amp;chdlp=b"/>'           
263
264        if self.plone_version < "40":
265            chart_tag = plone33chart_tag
266        elif self.plone_version > "42":
267            chart_tag = plone42chart_tag
268        else:
269            chart_tag = plone4chart_tag
270
271        self.loginAsPortalOwner()
272        self.assertEqual(*map(lambda s: ''.join(s.split()),
273                              [chart_tag, self.view.getChart()]))
274
275
276class TestOwnershipByState(TestCase):
277    """Tests all ownership by state view methods."""
278
279    layer = SetUpContent
280
281    states = ['private', 'published', 'pending']
282
283    def afterSetUp(self):
284        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
285                                 name="ownership_by_state")
286        self.pc = self.portal.portal_catalog
287
288    def test_getUsers(self):
289        """ Tests method that returns ordered list of users."""
290        users = [u[0] for u in self.layer.users]
291        users.reverse()
292        self.assert_(False not in map(lambda u1, u2: u1 == u2,
293                     users, self.view.getUsers()))
294
295    def test_getStates(self):
296        """ Tests method that returns ordered list of states."""
297        self.assert_(False not in map(lambda s1, s2: s1 == s2,
298                     ['private', 'published'], self.view.getStates()))
299
300    def test_getContent(self):
301        """ This test verifies method that returns list of numbers.
302            Each number is amount of specified content type objects
303            that are in particular workflow state.
304        """
305        # we need to login in to the site as Manager to be able to
306        # see catalog results
307        self.loginAsPortalOwner()
308
309        for state in self.states:
310            self.assert_(False not in \
311            map(lambda i, j: i == j, [len(self.pc(review_state=state,
312                                              Creator=user))
313                                  for user in self.view.getUsers()],
314                                 self.view.getContent(state)))
315
316    def test_getChart(self):
317        """ This test verifies creation of chart image tag."""
318        chart_tag = """<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;
319                       chds=0,57&amp;chd=t:57.0,54.0,51.0,48.0,45.0,42.0,39.0,
320                       36.0,33.0,30.0|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
321                       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,
322                       0,57&amp;chco=669933,cc9966,993300,ff6633,e8e4e3,a9a486,
323                       dcb57e,ffcc99,996633,333300,00ff00&amp;chl=user9|user8|
324                       user7|user6|user5|user4|user3|user2|user1|user0&amp;
325                       chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;
326                       chtt=Content+ownership+by+state&amp;chdl=private|
327                       published|No+workflow&amp;chdlp=b"/>"""
328        self.loginAsPortalOwner()
329        self.assertEqual(*map(lambda s: ''.join(s.split()),
330                              [chart_tag, self.view.getChart()]))
331
332
333class TestTypeByState(TestCase):
334    """Tests all type_by_state view methods."""
335    layer = SetUpContent
336    states = ['private', 'published', 'pending']
337
338    def afterSetUp(self):
339        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
340                                 name="type_by_state")
341        self.pc = self.portal.portal_catalog
342        portal_migration = self.portal.portal_migration
343        version = portal_migration.getFileSystemVersion()
344        self.plone_version = version.replace(".", "")
345
346    def test_getTypes(self):
347        """ Tests method that returns ordered list of types."""
348        index = self.pc._catalog.getIndex('portal_type')
349        data = {}
350
351        for k in index._index.keys():
352            if not k:
353                continue
354            haslen = hasattr(index._index[k], '__len__')
355
356            if haslen:
357                data[k] = len(index._index[k])
358
359            else:
360                data[k] = 1
361        data = data.items()
362        data.sort(lambda a, b: a[1] - b[1])
363        data.reverse()
364
365        types = [i[0] for i in data]
366        self.assert_(False not in map(lambda t1, t2: t1 == t2, types,
367                                      self.view.getTypes()))
368
369    def test_getStates(self):
370        """ Tests method that returns ordered list of states."""
371        self.assert_(False not in map(lambda s1, s2: s1 == s2,
372                     ['private', 'published'], self.view.getStates()))
373
374    def test_getContent(self):
375        """ This test verifies method that returns list of numbers.
376            Each number is amount of specified content type objects
377            that owned  by particular user.
378        """
379        # we need to login in to the site as Manager to be able to
380        # see catalog results
381        self.loginAsPortalOwner()
382
383        for state in self.states:
384            self.assert_(False not in \
385            map(lambda i, j: i == j, [len(self.pc(portal_type=type_,
386                                               review_state=state))
387                                   for type_ in self.view.getTypes()],
388                                  self.view.getContent(state)))
389
390    def test_getChart(self):
391        """ This test verifies creation of chart image tag."""
392        plone33chart_tag = \
393            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
394            '156&amp;chd=t:156.0,145.0,145.0,0.0,0.0|0.0,1.0,0.0,3.0,3.0|'\
395            '0.0,0.0,0.0,0.0,0.0&amp;chxr=0,0,156&amp;chco=669933,cc9966,'\
396            '993300,ff6633,e8e4e3,a9a486,dcb57e,ffcc99,996633,333300,'\
397            '00ff00&amp;chl=Folder|Document|Event|Large+Plone+Folder|'\
398            'Topic&amp;chbh=a,10,0&amp;chs=800x375&amp;cht=bvs&amp;'\
399            'chtt=Content+type+by+state&amp;chdl=private|published|'\
400            'No+workflow&amp;chdlp=b"/>'
401        plone4chart_tag = \
402            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
403            '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.'\
404            '0,0.0&amp;chxr=0,0,159&amp;chco=669933,cc9966,993300,ff6633,e8'\
405            'e4e3,a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=Folder|'\
406            'Document|Event|Topic&amp;chbh=a,10,0&amp;chs=800x375&amp;cht=b'\
407            'vs&amp;chtt=Content+type+by+state&amp;chdl=private|published|N'\
408            'o+workflow&amp;chdlp=b"/>'
409        plone41chart_tag = \
410            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
411            '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.'\
412            '0,0.0&amp;chxr=0,0,159&amp;chco=669933,cc9966,993300,ff6633,e8'\
413            'e4e3,a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=Folder|'\
414            'Document|Event|Topic&amp;chbh=a,10,0&amp;chs=800x375&amp;cht=b'\
415            'vs&amp;chtt=Content+type+by+state&amp;chdl=private|published|N'\
416            'o+workflow&amp;chdlp=b"/>'
417        plone42chart_tag = \
418            '<imgsrc="http://chart.apis.google.com/chart?chxt=y&amp;chds=0,'\
419            '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.'\
420            '0,0.0&amp;chxr=0,0,159&amp;chco=669933,cc9966,993300,ff6633,e8'\
421            'e4e3,a9a486,dcb57e,ffcc99,996633,333300,00ff00&amp;chl=Folder|'\
422            'Document|Event|Collection&amp;chbh=a,10,0&amp;chs=800x375&amp;'\
423            'cht=bvs&amp;chtt=Content+type+by+state&amp;chdl=private|publis'\
424            'hed|No+workflow&amp;chdlp=b"/>'
425
426        if self.plone_version < "40":
427            chart_tag = plone33chart_tag
428        elif self.plone_version > "40" and self.plone_version < "41":
429            chart_tag = plone4chart_tag
430        elif self.plone_version > "41" and self.plone_version < "42":
431            chart_tag = plone41chart_tag
432        elif self.plone_version > "42":
433            chart_tag = plone42chart_tag
434
435        self.loginAsPortalOwner()
436        self.assertEqual(*map(lambda s: ''.join(s.split()),
437                              [chart_tag, self.view.getChart()]))
438
439
440class LegacyPortlets(TestCase):
441    """Test all legasy_portlets view methods."""
442
443    def afterSetUp(self):
444        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
445                                       name='legacy_portlets')
446
447    def test_getPortlets(self):
448        """Tests method that returns portlets info."""
449
450        # this is true for Plone 4
451        self.assert_(self.view.getPortlets() == [])
452
453    def test_getAllPortletExpressions(self):
454        """Tests method that returns portlets expressions."""
455
456        # this is true for Plone 4
457        self.assert_(self.view.getAllPortletExpressions() == [])
458
459
460class TestPropertiesStats(TestCase):
461    """Tests all properties_stats view methods."""
462
463    def afterSetUp(self):
464        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
465                                       name='properties_stats')
466
467    def test_getPropsList(self):
468        self.view.propname = 'title'
469        result = [u'Plone site', u'Welcome to Plone',
470                  u'News', u'Events', u'Users']
471
472        for title in result:
473            self.assert_(title in [prop_info['slots']
474                     for prop_info in self.view.getPropsList()])
475
476
477class TestPortletsStats(TestCase):
478    """Tests all properties_stats view methods."""
479
480    def afterSetUp(self):
481        self.view = queryMultiAdapter((self.portal, self.portal.REQUEST),
482                                       name='portlets_stats')
483
484    def test_getPropsList(self):
485        """Tests method that collects portlet information from site."""
486
487        self.loginAsPortalOwner()
488        portlet = getUtility(IPortletType, name='portlets.Calendar')
489        mapping = \
490          self.portal.restrictedTraverse('++contextportlets++plone.leftcolumn')
491        mapping.restrictedTraverse('+/' + portlet.addview)()
492
493        plone_portlets_info = filter(lambda info: info['path'] == '/plone',
494                                     self.view.getPropsList())
495        lslots = plone_portlets_info[0]['left_slots']
496        self.assert_(info for info in lslots if info['title'] == 'Calendar')
497
498
499def test_suite():
500    test_suite = unittest.TestSuite([
501
502        # Unit tests
503        #doctestunit.DocFileSuite(
504        #    'README.txt', package='quintagroup.contentstats',
505        #    setUp=testing.setUp, tearDown=testing.tearDown),
506
507        #doctestunit.DocTestSuite(
508        #    module='quintagroup.contentstats.mymodule',
509        #    setUp=testing.setUp, tearDown=testing.tearDown),
510
511
512        # Integration tests that use PloneTestCase
513        #ztc.ZopeDocFileSuite(
514        #    'README.txt', package='quintagroup.contentstats',
515        #    test_class=TestCase),
516
517        #ztc.FunctionalDocFileSuite(
518        #    'browser.txt', package='quintagroup.contentstats',
519        #    test_class=TestCase),
520
521        ])
522
523    test_suite.addTest(unittest.makeSuite(TestQAInstallation))
524    test_suite.addTest(unittest.makeSuite(TestOwnershipByType))
525    test_suite.addTest(unittest.makeSuite(TestOwnershipByState))
526    test_suite.addTest(unittest.makeSuite(TestTypeByState))
527    test_suite.addTest(unittest.makeSuite(LegacyPortlets))
528    test_suite.addTest(unittest.makeSuite(TestPropertiesStats))
529    test_suite.addTest(unittest.makeSuite(TestPortletsStats))
530    return test_suite
531
532if __name__ == '__main__':
533    unittest.main(defaultTest='test_suite')
Note: See TracBrowser for help on using the repository browser.