plone.app.discussion/plone/app/discussion/tests/test_workflow.py

340 lines
12 KiB
Python
Raw Normal View History

"""Test plone.app.discussion workflow and permissions.
"""
from ..interfaces import IConversation
from ..interfaces import IDiscussionLayer
from ..testing import PLONE_APP_DISCUSSION_INTEGRATION_TESTING
from AccessControl import Unauthorized
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
from plone.app.testing import TEST_USER_NAME
2022-09-19 04:30:04 +02:00
from plone.app.testing import TEST_USER_PASSWORD
from Products.CMFCore.permissions import View
from Products.CMFCore.utils import _checkPermission as checkPerm
from zope.component import createObject
from zope.interface import alsoProvides
import unittest
class WorkflowSetupTest(unittest.TestCase):
2022-05-01 23:14:09 +02:00
"""Make sure the workflows are set up properly."""
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
def setUp(self):
2022-05-01 23:14:09 +02:00
self.portal = self.layer["portal"]
setRoles(self.portal, TEST_USER_ID, ["Manager"])
self.portal.invokeFactory("Folder", "test-folder")
self.folder = self.portal["test-folder"]
self.portal.portal_types["Document"].allow_discussion = True
self.folder.invokeFactory("Document", "doc1")
self.doc = self.folder.doc1
def test_workflows_installed(self):
2022-05-01 23:14:09 +02:00
"""Make sure both comment workflows have been installed properly."""
self.assertTrue(
"comment_one_state_workflow" in self.portal.portal_workflow.objectIds()
)
self.assertTrue(
"comment_review_workflow" in self.portal.portal_workflow.objectIds()
)
def test_default_workflow(self):
2022-05-01 23:14:09 +02:00
"""Make sure one_state_workflow is the default workflow."""
2013-04-17 14:24:39 +02:00
self.assertEqual(
2022-05-01 23:14:09 +02:00
("comment_one_state_workflow",),
2013-04-17 14:24:39 +02:00
self.portal.portal_workflow.getChainForPortalType(
2022-05-01 23:14:09 +02:00
"Discussion Item",
),
2013-04-17 14:24:39 +02:00
)
def test_review_comments_permission(self):
2015-05-13 14:03:11 +02:00
# 'Review comments' in self.portal.permissionsOfRole('Admin')
2022-05-01 23:14:09 +02:00
setRoles(self.portal, TEST_USER_ID, ["Reviewer"])
self.assertTrue(
self.portal.portal_membership.checkPermission(
"Review comments", self.folder
),
self.folder,
)
setRoles(self.portal, TEST_USER_ID, ["Member"])
2013-04-17 14:24:39 +02:00
self.assertFalse(
self.portal.portal_membership.checkPermission(
2022-05-01 23:14:09 +02:00
"Review comments",
self.folder,
2013-04-17 14:24:39 +02:00
),
self.folder,
2013-04-17 14:24:39 +02:00
)
def test_reply_to_item_permission(self):
pass
2012-01-14 07:35:59 +01:00
class PermissionsSetupTest(unittest.TestCase):
2022-05-01 23:14:09 +02:00
"""Make sure the permissions are set up properly."""
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
def setUp(self):
2022-05-01 23:14:09 +02:00
self.portal = self.layer["portal"]
setRoles(self.portal, TEST_USER_ID, ["Manager"])
mtool = self.portal.portal_membership
self.checkPermission = mtool.checkPermission
def test_reply_to_item_permission_assigned(self):
"""Make sure the 'Reply to item' permission is properly assigned.
2022-05-01 23:14:09 +02:00
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.
"""
2022-05-01 23:14:09 +02:00
ReplyToItemPerm = "Reply to item"
# should be allowed as Member
self.assertTrue(self.checkPermission(ReplyToItemPerm, self.portal))
# should be allowed as Authenticated
2022-05-01 23:14:09 +02:00
setRoles(self.portal, TEST_USER_ID, ["Authenticated"])
self.assertTrue(self.checkPermission(ReplyToItemPerm, self.portal))
# should be allowed as Manager
2022-05-01 23:14:09 +02:00
setRoles(self.portal, TEST_USER_ID, ["Manager"])
self.assertTrue(self.checkPermission(ReplyToItemPerm, self.portal))
# should not be allowed as anonymous
logout()
self.assertFalse(self.checkPermission(ReplyToItemPerm, self.portal))
class CommentOneStateWorkflowTest(unittest.TestCase):
2022-05-01 23:14:09 +02:00
"""Test the comment_one_state_workflow that ships with plone.app.discussion."""
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
def setUp(self):
2022-05-01 23:14:09 +02:00
self.portal = self.layer["portal"]
setRoles(self.portal, TEST_USER_ID, ["Manager"])
self.portal.invokeFactory("Folder", "test-folder")
self.folder = self.portal["test-folder"]
self.catalog = self.portal.portal_catalog
self.workflow = self.portal.portal_workflow
2022-05-01 23:14:09 +02:00
self.folder.invokeFactory("Document", "doc1")
self.doc = self.folder.doc1
# Add a comment
conversation = IConversation(self.folder.doc1)
2022-05-01 23:14:09 +02:00
comment = createObject("plone.Comment")
comment.text = "Comment text"
cid = conversation.addComment(comment)
2013-04-17 14:24:39 +02:00
self.comment = self.folder.doc1.restrictedTraverse(
f"++conversation++default/{cid}",
2013-04-17 14:24:39 +02:00
)
2022-09-19 04:30:04 +02:00
self.portal.acl_users._doAddUser("member", TEST_USER_PASSWORD, ["Member"], [])
self.portal.acl_users._doAddUser("reviewer", TEST_USER_PASSWORD, ["Reviewer"], [])
self.portal.acl_users._doAddUser("manager", TEST_USER_PASSWORD, ["Manager"], [])
self.portal.acl_users._doAddUser("editor", TEST_USER_PASSWORD, ["Editor"], [])
self.portal.acl_users._doAddUser("reader", TEST_USER_PASSWORD, ["Reader"], [])
def test_initial_workflow_state(self):
2022-05-01 23:14:09 +02:00
"""Make sure the initial workflow state of a comment is 'private'."""
self.assertEqual(
2022-05-01 23:14:09 +02:00
self.workflow.getInfoFor(self.doc, "review_state"),
"private",
)
def test_view_comments(self):
2022-05-01 23:14:09 +02:00
"""Make sure published comments can be viewed by everyone."""
# Owner is allowed
2015-05-13 14:03:11 +02:00
# self.login(default_user)
# self.assertTrue(checkPerm(View, self.doc))
# Member is allowed
login(self.portal, TEST_USER_NAME)
workflow = self.portal.portal_workflow
2022-05-01 23:14:09 +02:00
workflow.doActionFor(self.doc, "publish")
2022-05-01 23:14:09 +02:00
login(self.portal, "member")
self.assertTrue(checkPerm(View, self.comment))
# Reviewer is allowed
2022-05-01 23:14:09 +02:00
login(self.portal, "reviewer")
self.assertTrue(checkPerm(View, self.comment))
# Anonymous is allowed
logout()
self.assertTrue(checkPerm(View, self.comment))
# Editor is allowed
2022-05-01 23:14:09 +02:00
login(self.portal, "editor")
self.assertTrue(checkPerm(View, self.comment))
# Reader is allowed
2022-05-01 23:14:09 +02:00
login(self.portal, "reader")
self.assertTrue(checkPerm(View, self.comment))
def test_comment_on_private_content_not_visible_to_world(self):
logout()
self.assertFalse(checkPerm(View, self.comment))
def test_migration(self):
from plone.app.discussion.upgrades import upgrade_comment_workflows
2022-05-01 23:14:00 +02:00
# Fake permission according to earlier one_comment_workflow.
2022-05-01 23:14:09 +02:00
self.comment._View_Permission = ("Anonymous",)
# Anonymous can see the comment.
logout()
self.assertTrue(checkPerm(View, self.comment))
# Run the upgrade.
login(self.portal, TEST_USER_NAME)
upgrade_comment_workflows(self.portal.portal_setup)
# The workflow chain is still what we want.
self.assertEqual(
2022-05-01 23:14:09 +02:00
self.portal.portal_workflow.getChainFor("Discussion Item"),
("comment_one_state_workflow",),
)
# A Manager can still see the comment.
self.assertTrue(checkPerm(View, self.comment))
# Anonymous cannot see the comment.
logout()
self.assertFalse(checkPerm(View, self.comment))
class CommentReviewWorkflowTest(unittest.TestCase):
2022-05-01 23:14:09 +02:00
"""Test the comment_review_workflow that ships with plone.app.discussion."""
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
def setUp(self):
2022-05-01 23:14:09 +02:00
self.portal = self.layer["portal"]
setRoles(self.portal, TEST_USER_ID, ["Manager"])
self.portal.invokeFactory("Folder", "test-folder")
self.folder = self.portal["test-folder"]
# Allow discussion on the Document content type
2022-05-01 23:14:09 +02:00
self.portal.portal_types["Document"].allow_discussion = True
# Set workflow for Discussion item to review workflow
self.portal.portal_workflow.setChainForPortalTypes(
2022-05-01 23:14:09 +02:00
("Discussion Item",),
("comment_review_workflow",),
)
# Create a conversation for this Document
conversation = IConversation(self.portal.doc1)
# Add a comment.
2022-05-01 23:14:09 +02:00
comment = createObject("plone.Comment")
comment.text = "Comment text"
comment_id = conversation.addComment(comment)
comment = self.portal.doc1.restrictedTraverse(
f"++conversation++default/{comment_id}",
)
self.conversation = conversation
self.comment_id = comment_id
self.comment = comment
2022-05-01 23:14:09 +02:00
setRoles(self.portal, TEST_USER_ID, ["Reviewer"])
alsoProvides(self.portal.REQUEST, IDiscussionLayer)
def test_delete(self):
2022-05-01 23:14:09 +02:00
self.portal.REQUEST.form["comment_id"] = self.comment_id
view = self.comment.restrictedTraverse("@@moderate-delete-comment")
view()
self.assertFalse(self.comment_id in self.conversation.objectIds())
def test_delete_as_anonymous(self):
# Make sure that anonymous users can not delete comments
logout()
2022-05-01 23:14:09 +02:00
self.portal.REQUEST.form["comment_id"] = self.comment_id
self.assertRaises(
Unauthorized,
self.comment.restrictedTraverse,
2022-05-01 23:14:09 +02:00
"@@moderate-delete-comment",
)
self.assertTrue(self.comment_id in self.conversation.objectIds())
def test_delete_as_user(self):
# Make sure that members can not delete comments
logout()
2022-05-01 23:14:09 +02:00
setRoles(self.portal, TEST_USER_ID, ["Member"])
self.portal.REQUEST.form["comment_id"] = self.comment_id
self.assertRaises(
Unauthorized,
self.comment.restrictedTraverse,
2022-05-01 23:14:09 +02:00
"@@moderate-delete-comment",
)
self.assertTrue(self.comment_id in self.conversation.objectIds())
def test_publish(self):
2022-05-01 23:14:09 +02:00
self.portal.REQUEST.form["comment_id"] = self.comment_id
self.portal.REQUEST.form["workflow_action"] = "publish"
2013-04-17 14:24:39 +02:00
self.assertEqual(
2022-05-01 23:14:09 +02:00
"pending",
2013-04-17 14:24:39 +02:00
self.portal.portal_workflow.getInfoFor(
self.comment,
2022-05-01 23:14:09 +02:00
"review_state",
),
2013-04-17 14:24:39 +02:00
)
2022-05-01 23:14:09 +02:00
view = self.comment.restrictedTraverse("@@transmit-comment")
view()
2013-04-17 14:24:39 +02:00
self.assertEqual(
2022-05-01 23:14:09 +02:00
"published",
2013-04-17 14:24:39 +02:00
self.portal.portal_workflow.getInfoFor(
self.comment,
2022-05-01 23:14:09 +02:00
"review_state",
),
2013-04-17 14:24:39 +02:00
)
def test_publish_as_anonymous(self):
logout()
2022-05-01 23:14:09 +02:00
self.portal.REQUEST.form["comment_id"] = self.comment_id
self.portal.REQUEST.form["workflow_action"] = "publish"
2013-04-17 14:24:39 +02:00
self.assertEqual(
2022-05-01 23:14:09 +02:00
"pending",
self.portal.portal_workflow.getInfoFor(
2013-04-17 14:24:39 +02:00
self.comment,
2022-05-01 23:14:09 +02:00
"review_state",
),
2013-04-17 14:24:39 +02:00
)
self.assertRaises(
Unauthorized,
self.comment.restrictedTraverse,
2022-05-01 23:14:09 +02:00
"@@transmit-comment",
2013-04-17 14:24:39 +02:00
)
self.assertEqual(
2022-05-01 23:14:09 +02:00
"pending",
2013-04-17 14:24:39 +02:00
self.portal.portal_workflow.getInfoFor(
self.comment,
2022-05-01 23:14:09 +02:00
"review_state",
),
2013-04-17 14:24:39 +02:00
)
def test_publish_comment_on_private_content_not_visible_to_world(self):
logout()
self.assertFalse(checkPerm(View, self.comment))
# publish comment and check again
login(self.portal, TEST_USER_NAME)
workflow = self.portal.portal_workflow
2022-05-01 23:14:09 +02:00
workflow.doActionFor(self.comment, "publish")
logout()
self.assertFalse(checkPerm(View, self.comment))
def test_migration(self):
from plone.app.discussion.upgrades import upgrade_comment_workflows
2022-05-01 23:14:00 +02:00
# Fake permission according to earlier comment_review_workflow.
2022-05-01 23:14:09 +02:00
self.comment._View_Permission = ("Anonymous",)
# Anonymous can see the comment.
logout()
self.assertTrue(checkPerm(View, self.comment))
# Run the upgrade.
login(self.portal, TEST_USER_NAME)
upgrade_comment_workflows(self.portal.portal_setup)
# The workflow chain is still what we want.
self.assertEqual(
2022-05-01 23:14:09 +02:00
self.portal.portal_workflow.getChainFor("Discussion Item"),
("comment_review_workflow",),
)
# A Manager can still see the comment.
self.assertTrue(checkPerm(View, self.comment))
# Anonymous cannot see the comment.
logout()
self.assertFalse(checkPerm(View, self.comment))