source: products/qPloneComments/tags/1.7.2/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    ## 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        pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish This Discussion"\\s*/>',\
126                             re.S|re.M)
127        for u in COMMON_USERS_IDS:
128            self.logout()
129            auth = u
130            if not u=='anonym':
131                self.login(u)
132                auth = '%s:%s' % (u,USERS[u]['passw'])
133            doc_id = "doc_%s" % u
134            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
135            m = pattern.match(html)
136            self.assert_(not m, "Publish button present for %s - user without DiscussionManager role" % u)
137   
138
139    def testViewPublishButtonDMUsers(self):
140        # Publish button MUST PRESENT in document view form
141        # Pattern for publish button presence checking
142        pattern = re.compile('.*<input\\s*class="standalone"\\s*type="submit"\\s*value="Publish This Discussion"\\s*/>',\
143                             re.S|re.M)
144        for u in DM_USERS_IDS:
145            self.logout()
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_(m, "Publish button NOT PRESENT for %s - member of DiscussionManager group" % u)
152
153
154    def testPublishing(self):
155        # Check whether perform real publishing
156        for u in DM_USERS_IDS:
157            doc_id = "doc_%s" % u
158            doc_obj = getattr(self.portal, doc_id)
159            getReplies = self.discussion.getDiscussionFor(doc_obj).getReplies
160            # Check whether anonymous get no reply
161            self.logout()
162            self.assert_(not getReplies(), "View not published reply ALLOW for Anonymous")
163            # Login with actual (tested) user with DiscussionManager role and publish discussion
164            self.login(u)
165            self.assert_(getReplies(), "%s - member of DiscussionManager group NOT VIEW not published reply" % u)
166            getReplies()[0].discussion_publish_comment()
167            # Check whether Anonym view published reply
168            self.logout()
169            self.assert_(getReplies(), "%s - member of DiscussionManager group NOT PUBLISH reply" % u)
170
171   
172    ## TEST DELETING
173
174    def testViewDeleteButtonNonDMUsers(self):
175        # Check Delete reply button presense ONLY for PUBLISHED reply.
176        # Because of NOT PUBLUISHED replies is not visible at all for common users.
177        # Delete reply button in document view form MUST BE ABSENT for all EXCEPT manager.
178        # Publish replies
179        self.logout()
180        self.login('dm_admin')
181        for u in COMMON_USERS_IDS:
182            doc_id = "doc_%s" % u
183            doc_obj = getattr(self.portal, doc_id)
184            reply = self.discussion.getDiscussionFor(doc_obj).getReplies()[0]
185            reply.discussion_publish_comment()
186        # Prepare pattern for delete reply button presence checking
187        pattern = re.compile('.*<input\\s*class="destructive"\\s*type="submit"\\s*value="Remove This Discussion"\\s*/>',\
188                             re.S|re.M)
189        for u in COMMON_USERS_IDS:
190            self.logout()
191            auth = u
192            if not u=='anonym':
193                self.login(u)
194                auth = '%s:%s' % (u,USERS[u]['passw'])
195            doc_id = "doc_%s" % u
196            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
197            m = pattern.match(html)
198            if not u=='anonym' and 'Manager' in USERS[u]['roles']:
199                self.assert_(m, "%s - user with Manager role NOT VIEW Delete reply button for published reply on document view form" % u)
200            else:
201                self.assert_(not m, "%s - user without Manager role CAN VIEW Delete reply button for published reply on document view form" % u)
202   
203
204    def testViewDeleteButtonDMUsers(self):
205        # Delete reply button in document view form MUST BE ABSENT for all EXCEPT manager.
206        # Prepare pattern for delete reply button presence checking
207        pattern = re.compile('.*<input\\s*class="destructive"\\s*type="submit"\\s*value="Remove This Discussion"\\s*/>',\
208                             re.S|re.M)
209        for u in DM_USERS_IDS:
210            self.logout()
211            self.login(u)
212            auth = '%s:%s' % (u,USERS[u]['passw'])
213            doc_id = "doc_%s" % u
214            html = str(self.publish(self.portal.id+'/%s' % doc_id, auth))
215            m = pattern.match(html)
216            if 'Manager' in USERS[u]['roles']:
217                self.assert_(m, "%s - user with Manager role NOT VIEW Delete reply button on document view form" % u)
218            else:
219                self.assert_(not m, "%s - user without Manager role CAN VIEW Delete reply button on document view form" % u)
220   
221
222    def testDeleting(self):
223        # Manager with DiscussionManager role CAN delete ANY REPLY.
224        # Manager without DiscussionManager role [common manager] CAN delete ONLY PUBLISHED REPLY.
225        # Get Managers
226        managers = [u for u in USERS.keys() if 'Manager' in USERS[u]['roles']]
227        dm_man = [u for u in managers if u.startswith('dm_')][0]
228        common_man = [u for u in managers if not u.startswith('dm_')][0]
229        # Publish document for common manager
230        self.logout()
231        self.login(dm_man)
232        doc_obj = getattr(self.portal, "doc_%s" % common_man)
233        reply = self.discussion.getDiscussionFor(doc_obj).getReplies()[0]
234        reply.discussion_publish_comment()
235        # Check for really deleting
236        for u in managers:
237            self.logout()
238            self.login(u)
239            auth = '%s:%s' % (u,USERS[u]['passw'])
240            doc_id = "doc_%s" % u
241            doc_obj = getattr(self.portal, doc_id)
242            getReplies = self.discussion.getDiscussionFor(doc_obj).getReplies
243            self.assert_(getReplies(), "%s - user with Manager role not view discussion reply" % u)
244            getReplies()[0].deleteDiscussion()
245            self.assert_(not getReplies(), "%s - user with Manager role not really delete discussion" % u)
246
247
248TESTS = [TestModeration]
249
250def test_suite():
251    from unittest import TestSuite, makeSuite
252    suite = TestSuite()
253    suite.addTest(makeSuite(TestModeration))
254    return suite
255
256if __name__ == '__main__':
257    framework()
258
Note: See TracBrowser for help on using the repository browser.