source: products/qPloneComments/tags/1.6/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: 11.7 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        '''Preparation for functional testing'''
44        # By default on installation terning on moderation and anonymus commenting
45        # But if that changes. Following 4 lines must be uncommenting
46        #self.request = self.app.REQUEST
47        #self.request.form['Enable_Anonymous_Commenting'] = 'True'
48        #self.request.form['Enable_Moderation'] = 'True'
49        #self.portal.prefs_comments_setup()
50
51        # Add all users
52        self.membership = getToolByName(self.portal, 'portal_membership', None)
53        for user_id in USERS.keys():
54            self.membership.addMember(user_id, USERS[user_id]['passw'] , USERS[user_id]['roles'], [])
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
81    ## TEST VIEWING
82
83    def testViewRepliesNotPublishedDMUsers(self):
84        # All members of DiscussionManager group MUST VIEW comments
85        doc = getattr(self.portal, 'doc_%s' % DM_USERS_IDS[0])
86        for u in DM_USERS_IDS:
87            self.logout()
88            self.login(u)
89            replies = self.discussion.getDiscussionFor(doc).getReplies()
90            self.assert_(replies, "Viewing discussion item forbiden for %s - member of DiscussionManager group" % u)
91
92
93    def testViewRepliesNotPublishedNotDMUsers(self):
94        # All common users SHOULD NOT VIEW NOT PUBLISHED comments
95        doc = getattr(self.portal, 'doc_%s' % DM_USERS_IDS[0])
96        for u in COMMON_USERS_IDS:
97            self.logout()
98            if not u=='anonym':
99                self.login(u)
100            replies = self.discussion.getDiscussionFor(doc).getReplies()
101            self.assert_(not replies, "Viewing of NOT published discussion item allow %s - user without DiscussionManager role" % u)
102
103
104    def testViewRepliesPublishedAllUsers(self):
105        # All users MUST VIEW PUBLISHED comments
106        # Get any document and publish it's comment
107        doc = getattr(self.portal, 'doc_%s' % 'dm_admin')
108        self.login('dm_admin')
109        di = self.discussion.getDiscussionFor(doc).getReplies()[0]
110        di.discussion_publish_comment()
111       
112        all_users_id = USERS.keys() + ['anonym']
113        for u in all_users_id:
114            self.logout()
115            if not u=='anonym':
116                self.login(u)
117            replies = self.discussion.getDiscussionFor(doc).getReplies()
118            self.assert_(replies, "Viewing PUBLISHED discussion item forbiden for %s user" % u)
119
120
121    ## TEST PUBLISHING   
122
123    def testViewPublishButtonNonDMUsers(self):
124        # Publish button MUST BE ABSENT in document view form
125        # Pattern for publish button presence checking
126        pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish This Discussion"\\s*/>',\
127                             re.S|re.M)
128        for u in COMMON_USERS_IDS:
129            self.logout()
130            auth = u
131            if not u=='anonym':
132                self.login(u)
133                auth = '%s:%s' % (u,USERS[u]['passw'])
134            doc_id = "doc_%s" % u
135            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
136            m = pattern.match(html)
137            self.assert_(not m, "Publish button present for %s - user without DiscussionManager role" % u)
138   
139
140    def testViewPublishButtonDMUsers(self):
141        # Publish button MUST PRESENT in document view form
142        # Pattern for publish button presence checking
143        pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish This Discussion"\\s*/>',\
144                             re.S|re.M)
145        for u in DM_USERS_IDS:
146            self.logout()
147            self.login(u)
148            auth = '%s:%s' % (u,USERS[u]['passw'])
149            doc_id = "doc_%s" % u
150            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
151            m = pattern.match(html)
152            self.assert_(m, "Publish button NOT PRESENT for %s - member of DiscussionManager group" % u)
153
154
155    def testPublishing(self):
156        # Check whether perform real publishing
157        for u in DM_USERS_IDS:
158            doc_id = "doc_%s" % u
159            doc_obj = getattr(self.portal, doc_id)
160            getReplies = self.discussion.getDiscussionFor(doc_obj).getReplies
161            # Check whether anonymous get no reply
162            self.logout()
163            self.assert_(not getReplies(), "View not published reply ALLOW for Anonymous")
164            # Login with actual (tested) user with DiscussionManager role and publish discussion
165            self.login(u)
166            self.assert_(getReplies(), "%s - member of DiscussionManager group NOT VIEW not published reply" % u)
167            getReplies()[0].discussion_publish_comment()
168            # Check whether Anonym view published reply
169            self.logout()
170            self.assert_(getReplies(), "%s - member of DiscussionManager group NOT PUBLISH reply" % u)
171
172   
173    ## TEST DELETING
174
175    def testViewDeleteButtonNonDMUsers(self):
176        # Check Delete reply button presense ONLY for PUBLISHED reply.
177        # Because of NOT PUBLUISHED replies is not visible at all for common users.
178        # Delete reply button in document view form MUST BE ABSENT for all EXCEPT manager.
179        # Publish replies
180        self.logout()
181        self.login('dm_admin')
182        for u in COMMON_USERS_IDS:
183            doc_id = "doc_%s" % u
184            doc_obj = getattr(self.portal, doc_id)
185            reply = self.discussion.getDiscussionFor(doc_obj).getReplies()[0]
186            reply.discussion_publish_comment()
187        # Prepare pattern for delete reply button presence checking
188        pattern = re.compile('.*<input\\s*class="destructive"\\s*type="submit"\\s*value="Remove This Discussion"\\s*/>',\
189                             re.S|re.M)
190        for u in COMMON_USERS_IDS:
191            self.logout()
192            auth = u
193            if not u=='anonym':
194                self.login(u)
195                auth = '%s:%s' % (u,USERS[u]['passw'])
196            doc_id = "doc_%s" % u
197            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
198            m = pattern.match(html)
199            if not u=='anonym' and 'Manager' in USERS[u]['roles']:
200                self.assert_(m, "%s - user with Manager role NOT VIEW Delete reply button for published reply on document view form" % u)
201            else:
202                self.assert_(not m, "%s - user without Manager role CAN VIEW Delete reply button for published reply on document view form" % u)
203   
204
205    def testViewDeleteButtonDMUsers(self):
206        # Delete reply button in document view form MUST BE ABSENT for all EXCEPT manager.
207        # Prepare pattern for delete reply button presence checking
208        pattern = re.compile('.*<input\\s*class="destructive"\\s*type="submit"\\s*value="Remove This Discussion"\\s*/>',\
209                             re.S|re.M)
210        for u in DM_USERS_IDS:
211            self.logout()
212            self.login(u)
213            auth = '%s:%s' % (u,USERS[u]['passw'])
214            doc_id = "doc_%s" % u
215            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
216            m = pattern.match(html)
217            if 'Manager' in USERS[u]['roles']:
218                self.assert_(m, "%s - user with Manager role NOT VIEW Delete reply button on document view form" % u)
219            else:
220                self.assert_(not m, "%s - user without Manager role CAN VIEW Delete reply button on document view form" % u)
221
222
223    def testDeleting(self):
224        # Manager with DiscussionManager role CAN delete ANY REPLY.
225        # Manager without DiscussionManager role [common manager] CAN delete ONLY PUBLISHED REPLY.
226        # Get Managers
227        managers = [u for u in USERS.keys() if 'Manager' in USERS[u]['roles']]
228        dm_man = [u for u in managers if u.startswith('dm_')][0]
229        common_man = [u for u in managers if not u.startswith('dm_')][0]
230        # Publish document for common manager
231        self.logout()
232        self.login(dm_man)
233        doc_obj = getattr(self.portal, "doc_%s" % common_man)
234        reply = self.discussion.getDiscussionFor(doc_obj).getReplies()[0]
235        reply.discussion_publish_comment()
236        # Check for really deleting
237        for u in managers:
238            self.logout()
239            self.login(u)
240            auth = '%s:%s' % (u,USERS[u]['passw'])
241            doc_id = "doc_%s" % u
242            doc_obj = getattr(self.portal, doc_id)
243            getReplies = self.discussion.getDiscussionFor(doc_obj).getReplies
244            self.assert_(getReplies(), "%s - user with Manager role not view discussion reply" % u)
245            getReplies()[0].deleteDiscussion()
246            self.assert_(not getReplies(), "%s - user with Manager role not really delete discussion" % u)
247
248
249TESTS = [TestModeration]
250
251def test_suite():
252    from unittest import TestSuite, makeSuite
253    suite = TestSuite()
254    suite.addTest(makeSuite(TestModeration))
255    return suite
256
257if __name__ == '__main__':
258    framework()
259
Note: See TracBrowser for help on using the repository browser.