2010-09-24 15:33:21 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
2010-12-10 09:57:35 +01:00
|
|
|
"""Test plone.app.discussion workflow and permissions.
|
|
|
|
"""
|
2009-10-17 15:50:55 +02:00
|
|
|
from AccessControl import Unauthorized
|
2015-05-03 08:16:39 +02:00
|
|
|
from plone.app.discussion.interfaces import IConversation
|
|
|
|
from plone.app.discussion.interfaces import IDiscussionLayer
|
2015-05-03 08:41:56 +02:00
|
|
|
from plone.app.discussion.testing import PLONE_APP_DISCUSSION_INTEGRATION_TESTING # noqa
|
2015-05-03 08:16:39 +02:00
|
|
|
from plone.app.testing import login
|
|
|
|
from plone.app.testing import logout
|
|
|
|
from plone.app.testing import setRoles
|
|
|
|
from plone.app.testing import TEST_USER_ID
|
2016-02-05 01:39:53 +01:00
|
|
|
from Products.CMFCore.permissions import View
|
|
|
|
from Products.CMFCore.utils import _checkPermission as checkPerm
|
2015-05-03 08:16:39 +02:00
|
|
|
from zope.component import createObject
|
|
|
|
from zope.interface import alsoProvides
|
2010-09-24 15:33:21 +02:00
|
|
|
|
2015-05-03 08:16:39 +02:00
|
|
|
import unittest2 as unittest
|
2009-06-08 23:16:51 +02:00
|
|
|
|
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
class WorkflowSetupTest(unittest.TestCase):
|
2010-12-10 09:57:35 +01:00
|
|
|
"""Make sure the workflows are set up properly.
|
2010-09-24 15:33:21 +02:00
|
|
|
"""
|
2009-06-08 23:16:51 +02:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
def setUp(self):
|
|
|
|
self.portal = self.layer['portal']
|
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
|
|
|
self.portal.invokeFactory('Folder', 'test-folder')
|
|
|
|
self.folder = self.portal['test-folder']
|
2009-06-10 22:17:36 +02:00
|
|
|
self.portal.portal_types['Document'].allow_discussion = True
|
|
|
|
self.folder.invokeFactory('Document', 'doc1')
|
2010-09-24 15:33:21 +02:00
|
|
|
self.doc = self.folder.doc1
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
def test_workflows_installed(self):
|
|
|
|
"""Make sure both comment workflows have been installed properly.
|
|
|
|
"""
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue('one_state_workflow' in
|
2010-09-24 15:33:21 +02:00
|
|
|
self.portal.portal_workflow.objectIds())
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue('comment_review_workflow' in
|
2010-09-24 15:33:21 +02:00
|
|
|
self.portal.portal_workflow.objectIds())
|
2009-06-10 22:17:36 +02:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
def test_default_workflow(self):
|
|
|
|
"""Make sure one_state_workflow is the default workflow.
|
|
|
|
"""
|
2013-04-17 14:24:39 +02:00
|
|
|
self.assertEqual(
|
|
|
|
('one_state_workflow',),
|
|
|
|
self.portal.portal_workflow.getChainForPortalType(
|
|
|
|
'Discussion Item'
|
|
|
|
)
|
|
|
|
)
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
def test_review_comments_permission(self):
|
2015-05-13 14:03:11 +02:00
|
|
|
# 'Review comments' in self.portal.permissionsOfRole('Admin')
|
2009-06-10 22:17:36 +02:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Reviewer'])
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(self.portal.portal_membership.checkPermission(
|
2010-08-28 19:06:53 +02:00
|
|
|
'Review comments', self.folder), self.folder)
|
2011-04-16 11:29:15 +02:00
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Member'])
|
2013-04-17 14:24:39 +02:00
|
|
|
self.assertFalse(
|
|
|
|
self.portal.portal_membership.checkPermission(
|
|
|
|
'Review comments',
|
|
|
|
self.folder
|
|
|
|
),
|
|
|
|
self.folder
|
|
|
|
)
|
2009-06-08 23:16:51 +02:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
def test_reply_to_item_permission(self):
|
|
|
|
pass
|
2009-06-08 23:16:51 +02:00
|
|
|
|
2012-01-14 07:35:59 +01:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
class PermissionsSetupTest(unittest.TestCase):
|
2010-12-10 09:57:35 +01:00
|
|
|
"""Make sure the permissions are set up properly.
|
|
|
|
"""
|
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
def setUp(self):
|
|
|
|
self.portal = self.layer['portal']
|
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
2010-12-10 09:57:35 +01:00
|
|
|
mtool = self.portal.portal_membership
|
|
|
|
self.checkPermission = mtool.checkPermission
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-12-10 09:57:35 +01:00
|
|
|
def test_reply_to_item_permission_assigned(self):
|
|
|
|
"""Make sure the 'Reply to item' permission is properly assigned.
|
|
|
|
By default this permission is assigned to 'Member' and 'Manager'.
|
|
|
|
plone.app.discussion assigns this permission to 'Authenticated' as
|
|
|
|
well to emulate the behavior of the old commenting system.
|
|
|
|
"""
|
2016-02-05 01:39:53 +01:00
|
|
|
ReplyToItemPerm = 'Reply to item'
|
2010-12-10 09:57:35 +01:00
|
|
|
# should be allowed as Member
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(self.checkPermission(ReplyToItemPerm, self.portal))
|
2010-12-10 09:57:35 +01:00
|
|
|
# should be allowed as Authenticated
|
2011-04-16 11:29:15 +02:00
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Authenticated'])
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(self.checkPermission(ReplyToItemPerm, self.portal))
|
2010-12-10 09:57:35 +01:00
|
|
|
# should be allowed as Manager
|
2011-04-16 11:29:15 +02:00
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(self.checkPermission(ReplyToItemPerm, self.portal))
|
2010-12-10 09:57:35 +01:00
|
|
|
# should not be allowed as anonymous
|
2011-04-16 11:29:15 +02:00
|
|
|
logout()
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertFalse(self.checkPermission(ReplyToItemPerm, self.portal))
|
2010-12-10 09:57:35 +01:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
class CommentOneStateWorkflowTest(unittest.TestCase):
|
2010-09-24 15:33:21 +02:00
|
|
|
"""Test the one_state_workflow that ships with plone.app.discussion.
|
|
|
|
"""
|
2009-06-18 22:57:47 +02:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
def setUp(self):
|
|
|
|
self.portal = self.layer['portal']
|
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
|
|
|
self.portal.invokeFactory('Folder', 'test-folder')
|
2012-01-09 16:43:54 +01:00
|
|
|
self.folder = self.portal['test-folder']
|
2010-09-24 15:33:21 +02:00
|
|
|
self.catalog = self.portal.portal_catalog
|
|
|
|
self.workflow = self.portal.portal_workflow
|
|
|
|
self.workflow.setChainForPortalTypes(['Document'],
|
|
|
|
'one_state_workflow')
|
|
|
|
self.folder.invokeFactory('Document', 'doc1')
|
|
|
|
self.doc = self.folder.doc1
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
# Add a comment
|
|
|
|
conversation = IConversation(self.folder.doc1)
|
|
|
|
comment = createObject('plone.Comment')
|
|
|
|
comment.text = 'Comment text'
|
|
|
|
cid = conversation.addComment(comment)
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2013-04-17 14:24:39 +02:00
|
|
|
self.comment = self.folder.doc1.restrictedTraverse(
|
2016-02-05 01:39:53 +01:00
|
|
|
'++conversation++default/{0}'.format(cid)
|
2013-04-17 14:24:39 +02:00
|
|
|
)
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
self.portal.acl_users._doAddUser('member', 'secret', ['Member'], [])
|
2012-01-14 07:35:59 +01:00
|
|
|
self.portal.acl_users._doAddUser(
|
|
|
|
'reviewer', 'secret', ['Reviewer'], [])
|
2010-09-24 15:33:21 +02:00
|
|
|
self.portal.acl_users._doAddUser('manager', 'secret', ['Manager'], [])
|
2012-01-09 16:43:54 +01:00
|
|
|
self.portal.acl_users._doAddUser('editor', ' secret', ['Editor'], [])
|
2010-09-24 15:33:21 +02:00
|
|
|
self.portal.acl_users._doAddUser('reader', 'secret', ['Reader'], [])
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
def test_initial_workflow_state(self):
|
|
|
|
"""Make sure the initial workflow state of a comment is 'published'.
|
|
|
|
"""
|
2010-12-16 00:52:56 +01:00
|
|
|
self.assertEqual(self.workflow.getInfoFor(self.doc, 'review_state'),
|
2010-09-24 15:33:21 +02:00
|
|
|
'published')
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
def test_view_comments(self):
|
|
|
|
"""Make sure published comments can be viewed by everyone.
|
2010-12-16 00:52:56 +01:00
|
|
|
"""
|
2010-09-24 15:33:21 +02:00
|
|
|
# Owner is allowed
|
2015-05-13 14:03:11 +02:00
|
|
|
# self.login(default_user)
|
|
|
|
# self.assertTrue(checkPerm(View, self.doc))
|
2010-09-24 15:33:21 +02:00
|
|
|
# Member is allowed
|
2011-04-16 11:29:15 +02:00
|
|
|
login(self.portal, 'member')
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(checkPerm(View, self.comment))
|
2010-09-24 15:33:21 +02:00
|
|
|
# Reviewer is allowed
|
2011-04-16 11:29:15 +02:00
|
|
|
login(self.portal, 'reviewer')
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(checkPerm(View, self.comment))
|
2010-09-24 15:33:21 +02:00
|
|
|
# Anonymous is allowed
|
2011-04-16 11:29:15 +02:00
|
|
|
logout()
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(checkPerm(View, self.comment))
|
2010-09-24 15:33:21 +02:00
|
|
|
# Editor is allowed
|
2011-04-16 11:29:15 +02:00
|
|
|
login(self.portal, 'editor')
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(checkPerm(View, self.comment))
|
2010-09-24 15:33:21 +02:00
|
|
|
# Reader is allowed
|
2011-04-16 11:29:15 +02:00
|
|
|
login(self.portal, 'reader')
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(checkPerm(View, self.comment))
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-24 15:33:21 +02:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
class CommentReviewWorkflowTest(unittest.TestCase):
|
2010-09-24 15:33:21 +02:00
|
|
|
"""Test the comment_review_workflow that ships with plone.app.discussion.
|
|
|
|
"""
|
2009-06-18 22:57:47 +02:00
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
self.portal = self.layer['portal']
|
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Manager'])
|
|
|
|
self.portal.invokeFactory('Folder', 'test-folder')
|
2012-01-09 16:43:54 +01:00
|
|
|
self.folder = self.portal['test-folder']
|
2009-06-18 22:57:47 +02:00
|
|
|
|
|
|
|
# Allow discussion on the Document content type
|
|
|
|
self.portal.portal_types['Document'].allow_discussion = True
|
|
|
|
# Set workflow for Discussion item to review workflow
|
2010-08-28 19:06:53 +02:00
|
|
|
self.portal.portal_workflow.setChainForPortalTypes(
|
|
|
|
('Discussion Item',),
|
|
|
|
('comment_review_workflow',))
|
2009-06-18 22:57:47 +02:00
|
|
|
|
|
|
|
# Create a conversation for this Document
|
|
|
|
conversation = IConversation(self.portal.doc1)
|
|
|
|
|
|
|
|
# Add a comment.
|
|
|
|
comment = createObject('plone.Comment')
|
|
|
|
comment.text = 'Comment text'
|
|
|
|
comment_id = conversation.addComment(comment)
|
2010-08-28 19:06:53 +02:00
|
|
|
comment = self.portal.doc1.restrictedTraverse(
|
2016-02-05 01:39:53 +01:00
|
|
|
'++conversation++default/{0}'.format(comment_id)
|
|
|
|
)
|
2009-06-18 22:57:47 +02:00
|
|
|
|
|
|
|
self.conversation = conversation
|
|
|
|
self.comment_id = comment_id
|
|
|
|
self.comment = comment
|
|
|
|
|
2011-04-16 11:29:15 +02:00
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Reviewer'])
|
2009-06-18 22:57:47 +02:00
|
|
|
alsoProvides(self.portal.REQUEST, IDiscussionLayer)
|
|
|
|
|
|
|
|
def test_delete(self):
|
2009-10-17 15:50:55 +02:00
|
|
|
self.portal.REQUEST.form['comment_id'] = self.comment_id
|
|
|
|
view = self.comment.restrictedTraverse('@@moderate-delete-comment')
|
|
|
|
view()
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertFalse(self.comment_id in self.conversation.objectIds())
|
2009-10-17 15:50:55 +02:00
|
|
|
|
|
|
|
def test_delete_as_anonymous(self):
|
|
|
|
# Make sure that anonymous users can not delete comments
|
2011-04-16 11:29:15 +02:00
|
|
|
logout()
|
2009-10-17 15:50:55 +02:00
|
|
|
self.portal.REQUEST.form['comment_id'] = self.comment_id
|
|
|
|
self.assertRaises(Unauthorized,
|
|
|
|
self.comment.restrictedTraverse,
|
|
|
|
'@@moderate-delete-comment')
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(self.comment_id in self.conversation.objectIds())
|
2009-10-17 15:50:55 +02:00
|
|
|
|
|
|
|
def test_delete_as_user(self):
|
|
|
|
# Make sure that members can not delete comments
|
2011-04-16 11:29:15 +02:00
|
|
|
logout()
|
|
|
|
setRoles(self.portal, TEST_USER_ID, ['Member'])
|
2009-10-17 15:50:55 +02:00
|
|
|
self.portal.REQUEST.form['comment_id'] = self.comment_id
|
|
|
|
self.assertRaises(Unauthorized,
|
|
|
|
self.comment.restrictedTraverse,
|
|
|
|
'@@moderate-delete-comment')
|
2011-04-15 18:23:38 +02:00
|
|
|
self.assertTrue(self.comment_id in self.conversation.objectIds())
|
2009-06-18 22:57:47 +02:00
|
|
|
|
|
|
|
def test_publish(self):
|
2009-10-17 15:50:55 +02:00
|
|
|
self.portal.REQUEST.form['comment_id'] = self.comment_id
|
2009-10-17 18:14:44 +02:00
|
|
|
self.portal.REQUEST.form['workflow_action'] = 'publish'
|
2013-04-17 14:24:39 +02:00
|
|
|
self.assertEqual(
|
|
|
|
'pending',
|
|
|
|
self.portal.portal_workflow.getInfoFor(
|
|
|
|
self.comment,
|
|
|
|
'review_state'
|
|
|
|
)
|
|
|
|
)
|
2009-10-17 15:50:55 +02:00
|
|
|
view = self.comment.restrictedTraverse('@@moderate-publish-comment')
|
|
|
|
view()
|
2013-04-17 14:24:39 +02:00
|
|
|
self.assertEqual(
|
|
|
|
'published',
|
|
|
|
self.portal.portal_workflow.getInfoFor(
|
|
|
|
self.comment,
|
|
|
|
'review_state'
|
|
|
|
)
|
|
|
|
)
|
2009-10-17 15:50:55 +02:00
|
|
|
|
|
|
|
def test_publish_as_anonymous(self):
|
2011-04-16 11:29:15 +02:00
|
|
|
logout()
|
2009-10-17 15:50:55 +02:00
|
|
|
self.portal.REQUEST.form['comment_id'] = self.comment_id
|
2009-10-17 18:14:44 +02:00
|
|
|
self.portal.REQUEST.form['workflow_action'] = 'publish'
|
2013-04-17 14:24:39 +02:00
|
|
|
self.assertEqual(
|
|
|
|
'pending', self.portal.portal_workflow.getInfoFor(
|
|
|
|
self.comment,
|
|
|
|
'review_state'
|
|
|
|
)
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
Unauthorized,
|
|
|
|
self.comment.restrictedTraverse,
|
|
|
|
'@@moderate-publish-comment'
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
'pending',
|
|
|
|
self.portal.portal_workflow.getInfoFor(
|
|
|
|
self.comment,
|
|
|
|
'review_state'
|
|
|
|
)
|
|
|
|
)
|