source: products/qPloneComments/trunk/tests/testQPloneCommentsModeration.py @ 1

Last change on this file since 1 was 1, checked in by myroslav, 18 years ago

Building directory structure

File size: 12.3 KB
Line 
1#
2# Test moderation behavior
3#
4
5import os, sys, string
6if __name__ == '__main__':
7    execfile(os.path.join(sys.path[0], 'framework.py'))
8
9from Products.PloneTestCase import PloneTestCase
10from Products.CMFCore.utils import getToolByName
11import re
12
13from common import *
14
15PloneTestCase.installProduct(PRODUCT)
16PloneTestCase.setupPloneSite()
17
18class TestModeration(PloneTestCase.FunctionalTestCase):
19
20    def afterSetUp(self):
21        self.loginAsPortalOwner()
22
23        self.qi = getToolByName(self.portal, 'portal_quickinstaller', None)
24        self.qi.installProduct(PRODUCT)
25        # VERY IMPORTANT to guarantee product skin's content visibility
26        self._refreshSkinData()
27
28        # Get Plone version
29        self.version = getToolByName(self.portal, 'portal_migration').getFileSystemVersion()
30
31        # Add all users
32        addMembers(self.portal, USERS)
33           
34        # For correct testing notification - add 'portal_owner' with 'email'
35        #self.membership.addMember('portal_owner', 'secret' , ['Manager'], [])
36        #member = self.membership.getMemberById('portal_owner')
37        #member.setMemberProperties({'email':'creator@test.com'})
38        #self.login('portal_owner')
39
40        # Add users to Discussion Manager group
41        add2Group(self.portal, 'DiscussionManager', DM_USERS_IDS)
42       
43        #portal_groups = getToolByName(self.portal, 'portal_groups')
44        ##portal_groups.addGroup('DiscussionManager', roles=['DiscussionManager'])
45        #dm_group = portal_groups.getGroupById('DiscussionManager')
46        #dm_users = [dm_group.addMember(u) for u in DM_USERS_IDS]
47
48        # Allow discussion for Document
49        portal_types = getToolByName(self.portal, 'portal_types', None)
50        doc_fti = portal_types.getTypeInfo('Document')
51        doc_fti._updateProperty('allow_discussion', 1)
52
53        # Add testing documents to portal. Add one document for avery user.
54        # For testing behaviors, where made some changes to document state it's more usefull.
55        self.discussion = getToolByName(self.portal, 'portal_discussion', None)
56        all_users_id = DM_USERS_IDS + COMMON_USERS_IDS
57        for user_id in all_users_id:
58            doc_id = 'doc_%s' % user_id
59            self.portal.invokeFactory('Document', id=doc_id)
60            doc_obj = getattr(self.portal, doc_id)
61            doc_obj.edit(text_format='plain', text='hello world from %s' % doc_id)
62            # Create talkback for document and Add comment to doc_obj
63            self.discussion.getDiscussionFor(doc_obj)
64            doc_obj.discussion_reply('A Reply for %s' % doc_id,'text of reply for %s' % doc_id)
65
66    ## TEST VIEWING
67
68    def testViewRepliesNotPublishedDMUsers(self):
69        # All members of DiscussionManager group MUST VIEW comments
70        doc = getattr(self.portal, 'doc_%s' % DM_USERS_IDS[0])
71        for u in DM_USERS_IDS:
72            self.logout()
73            self.login(u)
74            replies = self.discussion.getDiscussionFor(doc).getReplies()
75            self.assert_(replies, "Viewing discussion item forbiden for %s - member of DiscussionManager group" % u)
76
77
78    def testViewRepliesNotPublishedNotDMUsers(self):
79        # All common users SHOULD NOT VIEW NOT PUBLISHED comments
80        doc = getattr(self.portal, 'doc_%s' % DM_USERS_IDS[0])
81        roles = [r['name'] for r in self.portal.rolesOfPermission('Moderate Discussion') if r['selected'] == 'SELECTED']
82        authorized_users = [user for user in COMMON_USERS_IDS if user !='anonym']
83        users_without_md_perm = [u for u in authorized_users if filter(lambda x: x not in roles, USERS[u]['roles'])]
84        for u in users_without_md_perm:
85            self.logout()
86            if not u=='anonym':
87                self.login(u)
88            replies = self.discussion.getDiscussionFor(doc).getReplies()
89            self.assert_(not replies, "Viewing of NOT published discussion item allow %s - user without 'Moderate Discussion' permission" % u)
90
91    def testViewRepliesPublishedAllUsers(self):
92        # All users MUST VIEW PUBLISHED comments
93        # Get any document and publish it's comment
94        doc = getattr(self.portal, 'doc_%s' % 'dm_admin')
95        self.login('dm_admin')
96        di = self.discussion.getDiscussionFor(doc).getReplies()[0]
97        di.discussion_publish_comment()
98
99        all_users_id = USERS.keys() + ['anonym']
100        for u in all_users_id:
101            self.logout()
102            if not u=='anonym':
103                self.login(u)
104            replies = self.discussion.getDiscussionFor(doc).getReplies()
105            self.assert_(replies, "Viewing PUBLISHED discussion item forbiden for %s user" % u)
106
107    ## TEST PUBLISHING
108
109    def testViewPublishButtonNonDMUsers(self):
110        # Publish button MUST BE ABSENT in document view form
111        # Pattern for publish button presence checking
112        if self.version.startswith("2.1"):
113            pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish"\\s*/>',\
114                                 re.S|re.M)
115        elif self.version.startswith("2.5"):
116            pattern = re.compile('.*<input.+?value="Publish"',\
117                                 re.S|re.M)
118        else:
119            pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish This Discussion"\\s*/>',\
120                                 re.S|re.M)
121
122        roles = [r['name'] for r in self.portal.rolesOfPermission('Moderate Discussion') if r['selected'] == 'SELECTED']
123        authorized_users = [user for user in COMMON_USERS_IDS if user !='anonym']
124        users_without_md_perm = [u for u in authorized_users if filter(lambda x: x not in roles, USERS[u]['roles'])]
125        for u in users_without_md_perm:
126            self.logout()
127            auth = "%s:" % u
128            if not u=='anonym':
129                self.login(u)
130                auth = '%s:%s' % (u,USERS[u]['passw'])
131            doc_id = "doc_%s" % u
132            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
133            m = pattern.match(html)
134            self.assert_(not m, "Publish button present for %s - user without Moderate Discussion permission" % u)
135
136    def testViewPublishButtonDMUsers(self):
137        # Publish button MUST PRESENT in document view form
138        # Pattern for publish button presence checking
139        if self.version.startswith("2.1"):
140            pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish"\\s*/>',\
141                                 re.S|re.M)
142        elif self.version.startswith("2.5"):
143            pattern = re.compile('.*<input.+?value="Publish"',\
144                                 re.S|re.M)
145        else:
146            pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish"\\s*/>',\
147                                 re.S|re.M)
148        for u in DM_USERS_IDS:
149            self.logout()
150            self.login(u)
151            auth = '%s:%s' % (u,USERS[u]['passw'])
152            doc_id = "doc_%s" % u
153            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
154            m = pattern.match(html)
155            self.assert_(m, "Publish button NOT PRESENT for %s - member of DiscussionManager group" % u)
156
157
158    def testPublishing(self):
159        # Check whether perform real publishing
160        # Pattern for publish button presence checking
161        if self.version.startswith("2.1"):
162            pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish"\\s*/>',\
163                                 re.S|re.M)
164        elif self.version.startswith("2.5"):
165            pattern = re.compile('.*<input.+?value="Publish"',\
166                                 re.S|re.M)
167        else:
168            pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish This Discussion"\\s*/>',\
169                                 re.S|re.M)
170        for u in DM_USERS_IDS:
171            doc_id = "doc_%s" % u
172            doc_obj = getattr(self.portal, doc_id)
173            getReplies = self.discussion.getDiscussionFor(doc_obj).getReplies
174            # Check whether anonymous get no reply
175            self.logout()
176            self.assert_(not getReplies(), "View not published reply ALLOW for Anonymous")
177            # Login with actual (tested) user with DiscussionManager role and publish discussion
178            self.login(u)
179            self.assert_(getReplies(), "%s - member of DiscussionManager group NOT VIEW not published reply" % u)
180            getReplies()[0].discussion_publish_comment()
181            # Check if Publish button still present in document view page
182            auth = "%s:" % u
183            if not u=='anonym':
184                auth = '%s:%s' % (u,USERS[u]['passw'])
185            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
186            m = pattern.match(html)
187            self.assert_(not m, "Publish button present for %s - DiscussionManager role user after publishing" % u)
188            # Check whether Anonym view published reply
189            self.logout()
190            self.assert_(getReplies(), "%s - member of DiscussionManager group NOT PUBLISH reply" % u)
191
192
193    ## TEST DELETING
194
195    def testViewDeleteButtonNonDMUsers(self):
196        # Check Delete reply button presense ONLY for PUBLISHED reply.
197        # Because of NOT PUBLUISHED replies is not visible at all for common users.
198        # Delete reply button in document view form MUST BE ABSENT for all EXCEPT manager.
199        # Publish replies
200        self.logout()
201        self.login('dm_admin')
202        for u in COMMON_USERS_IDS:
203            doc_id = "doc_%s" % u
204            doc_obj = getattr(self.portal, doc_id)
205            reply = self.discussion.getDiscussionFor(doc_obj).getReplies()[0]
206            reply.discussion_publish_comment()
207        # Prepare pattern for delete reply button presence checking
208        if self.version.startswith("2.1"):
209            pattern = re.compile('.*<input\\s*class="destructive"\\s*type="submit"\\s*value="Remove"\\s*/>',\
210                                 re.S|re.M)
211        elif self.version.startswith("2.5"):
212            pattern = re.compile('.*<input\\s*class="destructive"\\s*type="submit"\\s*value="Remove"\\s*/>',\
213                                 re.S|re.M)
214        else:
215            pattern = re.compile('.*<input\\s*class="destructive"\\s*type="submit"\\s*value="Remove"\\s*/>',\
216                                 re.S|re.M)
217        for u in COMMON_USERS_IDS:
218            self.logout()
219            auth = "%s:" % u
220            if not u=='anonym':
221                self.login(u)
222                auth = '%s:%s' % (u,USERS[u]['passw'])
223            doc_id = "doc_%s" % u
224            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
225            m = pattern.match(html)
226            if not u=='anonym' and 'Manager' in USERS[u]['roles']:
227                self.assert_(m, "%s - user with Manager role NOT VIEW Delete reply button for published reply on document view form" % u)
228            else:
229                self.assert_(not m, "%s - user without Manager role CAN VIEW Delete reply button for published reply on document view form" % u)
230
231    def testDeleting(self):
232        # Manager with DiscussionManager role CAN delete ANY REPLY.
233        # Manager without DiscussionManager role [common manager] CAN delete ONLY PUBLISHED REPLY.
234        # Get Managers
235        managers = [u for u in USERS.keys() if 'Manager' in USERS[u]['roles']]
236        dm_man = [u for u in managers if u.startswith('dm_')][0]
237        common_man = [u for u in managers if not u.startswith('dm_')][0]
238        # Publish document for common manager
239        self.logout()
240        self.login(dm_man)
241        doc_obj = getattr(self.portal, "doc_%s" % common_man)
242        reply = self.discussion.getDiscussionFor(doc_obj).getReplies()[0]
243        reply.discussion_publish_comment()
244        # Check for really deleting
245        for u in managers:
246            self.logout()
247            self.login(u)
248            auth = '%s:%s' % (u,USERS[u]['passw'])
249            doc_id = "doc_%s" % u
250            doc_obj = getattr(self.portal, doc_id)
251            getReplies = self.discussion.getDiscussionFor(doc_obj).getReplies
252            self.assert_(getReplies(), "%s - user with Manager role not view discussion reply" % u)
253            getReplies()[0].deleteDiscussion()
254            self.assert_(not getReplies(), "%s - user with Manager role not really delete discussion" % u)
255
256
257TESTS = [TestModeration]
258
259def test_suite():
260    from unittest import TestSuite, makeSuite
261    suite = TestSuite()
262    suite.addTest(makeSuite(TestModeration))
263    return suite
264
265if __name__ == '__main__':
266    framework()
267
Note: See TracBrowser for help on using the repository browser.