from ..browser.moderation import BulkActionsView from ..browser.moderation import CommentTransition from ..browser.moderation import DeleteComment from ..browser.moderation import View from ..interfaces import IConversation from ..interfaces import IDiscussionSettings from ..testing import PLONE_APP_DISCUSSION_INTEGRATION_TESTING from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from plone.registry.interfaces import IRegistry from Products.CMFCore.utils import getToolByName from zope.component import createObject from zope.component import queryUtility import unittest class ModerationViewTest(unittest.TestCase): layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING def setUp(self): self.app = self.layer["app"] self.portal = self.layer["portal"] self.request = self.layer["request"] setRoles(self.portal, TEST_USER_ID, ["Manager"]) self.portal_discussion = getToolByName(self.portal, "portal_discussion", None) self.membership_tool = getToolByName(self.portal, "portal_membership") self.memberdata = self.portal.portal_memberdata request = self.app.REQUEST context = getattr(self.portal, "doc1") self.view = View(context, request) self.portal.portal_workflow.setChainForPortalTypes( ("Discussion Item",), "comment_review_workflow" ) self.wf_tool = self.portal.portal_workflow def test_moderation_enabled(self): """Make sure that moderation_enabled returns true if the comment workflow implements a 'pending' state. """ # If workflow is not set, enabled must return False self.wf_tool.setChainForPortalTypes(("Discussion Item",), ()) self.assertEqual(self.view.moderation_enabled(), False) # The comment_one_state_workflow does not have a 'pending' state self.wf_tool.setChainForPortalTypes( ("Discussion Item",), ("comment_one_state_workflow,") ) self.assertEqual(self.view.moderation_enabled(), False) # The comment_review_workflow does have a 'pending' state self.wf_tool.setChainForPortalTypes( ("Discussion Item",), ("comment_review_workflow,") ) self.assertEqual(self.view.moderation_enabled(), True) class ModerationBulkActionsViewTest(unittest.TestCase): layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING def setUp(self): self.app = self.layer["app"] self.portal = self.layer["portal"] self.request = self.layer["request"] setRoles(self.portal, TEST_USER_ID, ["Manager"]) self.wf = getToolByName(self.portal, "portal_workflow", None) self.context = self.portal self.portal.portal_workflow.setChainForPortalTypes( ("Discussion Item",), "comment_review_workflow", ) self.wf_tool = self.portal.portal_workflow # Add a conversation with three comments conversation = IConversation(self.portal.doc1) comment1 = createObject("plone.Comment") comment1.title = "Comment 1" comment1.text = "Comment text" comment1.Creator = "Jim" new_id_1 = conversation.addComment(comment1) self.comment1 = self.portal.doc1.restrictedTraverse( f"++conversation++default/{new_id_1}", ) comment2 = createObject("plone.Comment") comment2.title = "Comment 2" comment2.text = "Comment text" comment2.Creator = "Joe" new_id_2 = conversation.addComment(comment2) self.comment2 = self.portal.doc1.restrictedTraverse( f"++conversation++default/{new_id_2}", ) comment3 = createObject("plone.Comment") comment3.title = "Comment 3" comment3.text = "Comment text" comment3.Creator = "Emma" new_id_3 = conversation.addComment(comment3) self.comment3 = self.portal.doc1.restrictedTraverse( f"++conversation++default/{new_id_3}", ) self.conversation = conversation def test_default_bulkaction(self): # Make sure no error is raised when no bulk actions has been supplied self.request.set("form.select.BulkAction", "-1") self.request.set("paths", ["/".join(self.comment1.getPhysicalPath())]) view = BulkActionsView(self.portal, self.request) self.assertFalse(view()) def test_publish(self): self.request.set("form.select.BulkAction", "publish") self.request.set("paths", ["/".join(self.comment1.getPhysicalPath())]) view = BulkActionsView(self.portal, self.request) view() # Count published comments published_comments = 0 for r in self.conversation.getThreads(): comment_obj = r["comment"] workflow_status = self.wf.getInfoFor(comment_obj, "review_state") if workflow_status == "published": published_comments += 1 # Make sure the comment has been published self.assertEqual(published_comments, 1) def test_delete(self): # Initially we have three comments self.assertEqual(len(self.conversation.objectIds()), 3) # Delete two comments with bulk actions self.request.set("form.select.BulkAction", "delete") self.request.set( "paths", [ "/".join(self.comment1.getPhysicalPath()), "/".join(self.comment3.getPhysicalPath()), ], ) view = BulkActionsView(self.app, self.request) view() # Make sure that the two comments have been deleted self.assertEqual(len(self.conversation.objectIds()), 1) comment = next(self.conversation.getComments()) self.assertTrue(comment) self.assertEqual(comment, self.comment2) class RedirectionTest(unittest.TestCase): layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING def setUp(self): # Update settings. self.portal = self.layer["portal"] self.request = self.layer["request"] setRoles(self.portal, TEST_USER_ID, ["Manager"]) # applyProfile(self.portal, 'plone.app.discussion:default') registry = queryUtility(IRegistry) settings = registry.forInterface(IDiscussionSettings) settings.globally_enabled = True self.portal.portal_workflow.setChainForPortalTypes( ("Discussion Item",), ("comment_review_workflow",), ) # Create page plus comment. self.portal.invokeFactory( id="page", title="Page 1", type_name="Document", ) self.page = self.portal.page self.conversation = IConversation(self.page) comment = createObject("plone.Comment") comment.text = "Comment text" self.comment_id = self.conversation.addComment(comment) self.comment = list(self.conversation.getComments())[0] def test_regression(self): page_url = self.page.absolute_url() self.request["HTTP_REFERER"] = page_url for Klass in (DeleteComment, CommentTransition): view = Klass(self.comment, self.request) view.__parent__ = self.comment self.assertEqual(page_url, view()) def test_valid_next_url(self): self.request["HTTP_REFERER"] = "http://attacker.com" for Klass in (DeleteComment, CommentTransition): view = Klass(self.comment, self.request) view.__parent__ = self.comment self.assertNotEqual("http://attacker.com", view())