source: products/qPloneComments/tags/2.3/tests/testQPloneCommentsModeration.py @ 1591

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

Building directory structure

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