source: products/qPloneComments/branches/plone205-21merge/tests/testQPloneCommentsModeration.py @ 1

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

Building directory structure

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