コード例 #1
0
    def test_delete_comment(self):
        # Create a conversation. In this case we doesn't assign it to an
        # object, as we just want to check the Conversation object API.
        conversation = IConversation(self.portal.doc1)

        # Add a comment. Note: in real life, we always create comments via the
        # factory to allow different factories to be swapped in

        comment = createObject('plone.Comment')
        comment.text = 'Comment text'

        new_id = conversation.addComment(comment)

        # make sure the comment has been added
        self.assertEqual(len(list(conversation.getComments())), 1)
        self.assertEqual(len(tuple(conversation.getThreads())), 1)
        self.assertEqual(conversation.total_comments, 1)

        # delete the comment we just created
        del conversation[new_id]

        # make sure there is no comment left in the conversation
        self.assertEqual(len(list(conversation.getComments())), 0)
        self.assertEqual(len(tuple(conversation.getThreads())), 0)
        self.assertEqual(conversation.total_comments, 0)
コード例 #2
0
    def test_delete_comment(self):
        # Create a conversation. In this case we doesn't assign it to an
        # object, as we just want to check the Conversation object API.
        conversation = IConversation(self.portal.doc1)

        # Add a comment. Note: in real life, we always create comments via the
        # factory to allow different factories to be swapped in

        comment = createObject('plone.Comment')
        comment.text = 'Comment text'

        new_id = conversation.addComment(comment)

        # make sure the comment has been added
        self.assertEqual(len(list(conversation.getComments())), 1)
        self.assertEqual(len(tuple(conversation.getThreads())), 1)
        self.assertEqual(conversation.total_comments, 1)

        # delete the comment we just created
        del conversation[new_id]

        # make sure there is no comment left in the conversation
        self.assertEqual(len(list(conversation.getComments())), 0)
        self.assertEqual(len(tuple(conversation.getThreads())), 0)
        self.assertEqual(conversation.total_comments, 0)
コード例 #3
0
    def test_edit_comment(self):
        """Edit a comment as logged-in user.
        """

        # Allow discussion
        self.discussionTool.overrideDiscussionFor(self.portal.doc1, True)
        self.viewlet = CommentsViewlet(self.context, self.request, None, None)

        def make_request(form={}):
            request = TestRequest()
            request.form.update(form)
            alsoProvides(request, IFormLayer)
            alsoProvides(request, IAttributeAnnotatable)
            return request

        provideAdapter(
            adapts=(Interface, IBrowserRequest),
            provides=Interface,
            factory=CommentForm,
            name=u"comment-form"
        )

        provideAdapter(
            adapts=(Interface, IBrowserRequest),
            provides=Interface,
            factory=EditCommentForm,
            name=u"edit-comment-form"
        )

        # The form is submitted successfully, if the required text field is
        # filled out
        request = make_request(form={'form.widgets.text': u'bar'})

        commentForm = getMultiAdapter(
            (self.context, request),
            name=u"comment-form"
        )
        commentForm.update()
        data, errors = commentForm.extractData()  # pylint: disable-msg=W0612

        self.assertEqual(len(errors), 0)
        self.assertFalse(commentForm.handleComment(commentForm, "foo"))

        # Edit the last comment
        conversation = IConversation(self.context)
        comment = [x for x in conversation.getComments()][-1]
        request = make_request(form={'form.widgets.text': u'foobar'})
        editForm = getMultiAdapter(
            (comment, request),
            name=u"edit-comment-form"
        )
        editForm.update()
        data, errors = editForm.extractData()  # pylint: disable-msg=W0612

        self.assertEqual(len(errors), 0)
        self.assertFalse(editForm.handleComment(editForm, "foo"))
        comment = [x for x in conversation.getComments()][-1]
        self.assertEquals(comment.text, u"foobar")
コード例 #4
0
    def test_delete_own_comment(self):
        """Delete own comment as logged-in user.
        """

        # Allow discussion
        self.portal.doc1.allow_discussion = True
        self.viewlet = CommentsViewlet(self.context, self.request, None, None)

        def make_request(form={}):
            request = TestRequest()
            request.form.update(form)
            alsoProvides(request, IFormLayer)
            alsoProvides(request, IAttributeAnnotatable)
            return request

        provideAdapter(
            adapts=(Interface, IBrowserRequest),
            provides=Interface,
            factory=CommentForm,
            name=u"comment-form"
        )

        # The form is submitted successfully, if the required text field is
        # filled out
        form_request = make_request(form={'form.widgets.text': u'bar'})

        commentForm = getMultiAdapter(
            (self.context, form_request),
            name=u"comment-form"
        )

        commentForm.update()
        data, errors = commentForm.extractData()  # pylint: disable-msg=W0612
        self.assertEqual(len(errors), 0)
        self.assertFalse(commentForm.handleComment(commentForm, "foo"))

        # Delete the last comment
        conversation = IConversation(self.context)
        comment = [x for x in conversation.getComments()][-1]
        deleteView = getMultiAdapter(
            (comment, self.request),
            name=u"delete-own-comment"
        )
        # try to delete last comment with johndoe
        setRoles(self.portal, 'johndoe', ['Member'])
        login(self.portal, 'johndoe')
        self.assertRaises(
            Unauthorized,
            comment.restrictedTraverse,
            "@@delete-own-comment"
        )
        self.assertEqual(1, len([x for x in conversation.getComments()]))
        # try to delete last comment with the same user that created it
        login(self.portal, TEST_USER_NAME)
        setRoles(self.portal, TEST_USER_ID, ['Member'])
        deleteView()
        self.assertEqual(0, len([x for x in conversation.getComments()]))
コード例 #5
0
    def test_delete_own_comment(self):
        """Delete own comment as logged-in user.
        """

        # Allow discussion
        self.portal.doc1.allow_discussion = True
        self.viewlet = CommentsViewlet(self.context, self.request, None, None)

        def make_request(form={}):
            request = TestRequest()
            request.form.update(form)
            alsoProvides(request, IFormLayer)
            alsoProvides(request, IAttributeAnnotatable)
            return request

        provideAdapter(
            adapts=(Interface, IBrowserRequest),
            provides=Interface,
            factory=CommentForm,
            name=u'comment-form'
        )

        # The form is submitted successfully, if the required text field is
        # filled out
        form_request = make_request(form={'form.widgets.text': u'bar'})

        commentForm = getMultiAdapter(
            (self.context, form_request),
            name=u'comment-form'
        )

        commentForm.update()
        data, errors = commentForm.extractData()  # pylint: disable-msg=W0612
        self.assertEqual(len(errors), 0)
        self.assertFalse(commentForm.handleComment(commentForm, 'foo'))

        # Delete the last comment
        conversation = IConversation(self.context)
        comment = [x for x in conversation.getComments()][-1]
        deleteView = getMultiAdapter(
            (comment, self.request),
            name=u'delete-own-comment'
        )
        # try to delete last comment with johndoe
        setRoles(self.portal, 'johndoe', ['Member'])
        login(self.portal, 'johndoe')
        self.assertRaises(
            Unauthorized,
            comment.restrictedTraverse,
            '@@delete-own-comment'
        )
        self.assertEqual(1, len([x for x in conversation.getComments()]))
        # try to delete last comment with the same user that created it
        login(self.portal, TEST_USER_NAME)
        setRoles(self.portal, TEST_USER_ID, ['Member'])
        deleteView()
        self.assertEqual(0, len([x for x in conversation.getComments()]))
コード例 #6
0
    def catalog_comments(self, force=False):
        """Catalog the comments of this object.

        When force=True, we force this, otherwise we check if the
        number of items currently in the catalog under this context is
        the same as the number of actual comments on the context.

        This check does not work well for folderish items, so they
        probably always get recataloged, but that is of small concern.
        """
        context = aq_inner(self.context)
        actual= self.actual_comment_count()
        if not actual:
            return
        in_catalog = self.num_total_comments()
        if not force and actual == in_catalog:
            return
        logger.info("Cataloging %s replies for obj at %s", actual,
                    context.absolute_url())

        conversation = None
        if IConversation is not None:
            conversation = IConversation(context, None)
            if conversation is not None:
                for comment in conversation.getComments():
                    comment.reindexObject()
                return

        portal_discussion = getToolByName(context, 'portal_discussion')
        talkback = portal_discussion.getDiscussionFor(context)
        ids = talkback.objectIds()
        for reply_id in ids:
            reply = talkback.getReply(reply_id)
            reply.reindexObject()
コード例 #7
0
    def test_like_discussion_item(self):
        # test discussion-item
        conversation = IConversation(self.doc1)
        comment1 = createObject("plone.Comment")
        conversation.addComment(comment1)
        comment = [i for i in conversation.getComments()][0]
        comment_id = IUUID(comment)

        self.request.form["like_button"] = "like"
        view = api.content.get_view("toggle_like", self.portal, self.request)
        view = view.publishTraverse(self.request, comment_id)

        # Toggle like for comment
        output = view()
        self.assertIn("(1)", output)
        self.assertIn("Unlike", output)
        user_likes = self.util.get_items_for_user(self.user_id)

        self.assertTrue(self.util.is_item_liked_by_user(self.user_id, comment_id))
        self.assertEqual(len(user_likes), 1)

        # Toggle like for comment
        output = view()
        user_likes = self.util.get_items_for_user(self.user_id)
        self.assertEqual(len(user_likes), 0)
        self.assertIn("(0)", output)
        self.assertIn("Like", output)
コード例 #8
0
 def __call__(self):
     """
     """
     conversation = IConversation(self.context)
     comments = conversation.getComments()
     comments = [comment for comment in comments]
     tmp_lst = []
     for item in comments:
         tmp_dict = item.__dict__
         if not tmp_dict.get("status"):
             states = list(tmp_dict["workflow_history"].values())
             comment_status = states[0][-1]["review_state"]
         try:
             del tmp_dict["__parent__"]
             del tmp_dict["workflow_history"]
         except Exception:
             pass
         tmp_dict["modification_date"] = (DateTime(
             tmp_dict["modification_date"]).asdatetime().isoformat())
         tmp_dict["creation_date"] = (DateTime(
             tmp_dict["creation_date"]).asdatetime().isoformat())
         if not tmp_dict.get("status"):
             tmp_dict.update({"status": comment_status})
         tmp_lst.append(tmp_dict)
     return {"discussions": tmp_lst}
コード例 #9
0
def notify_content_object_moved(obj, event):
    """Update all comments of a content object that has been moved.
    """
    if event.oldParent is None or event.newParent is None \
            or event.oldName is None or event.newName is None:
        return

    # This method is also called for sublocations of moved objects. We
    # therefore can't assume that event.object == obj and event.
    # {old,new}{Parent,Name} may refer to the actually moved object further up
    # in the object hierarchy. The object is already moved at this point. so
    # obj.getPhysicalPath retruns the new path get the part of the path that
    # was moved.
    moved_path = obj.getPhysicalPath()[
        len(event.newParent.getPhysicalPath()) + 1:
    ]

    # Remove comments at the old location from catalog
    catalog = getToolByName(obj, 'portal_catalog')
    old_path = '/'.join(
        event.oldParent.getPhysicalPath() +
        (event.oldName,) +
        moved_path
    )
    brains = catalog.searchResults(dict(
        path={'query': old_path},
        portal_type="Discussion Item"
    ))
    for brain in brains:
        catalog.uncatalog_object(brain.getPath())
    # Reindex comment at the new location
    conversation = IConversation(obj, None)
    if conversation is not None:
        for comment in conversation.getComments():
            comment.reindexObject()
コード例 #10
0
    def test_like_discussion_item(self):
        # test discussion-item
        conversation = IConversation(self.doc1)
        comment1 = createObject('plone.Comment')
        conversation.addComment(comment1)
        comment = [i for i in conversation.getComments()][0]
        comment_id = IUUID(comment)

        self.request.form['like_button'] = 'like'
        view = api.content.get_view('toggle_like', self.portal, self.request)
        view = view.publishTraverse(self.request, comment_id)

        # Toggle like for comment
        output = view()
        self.assertIn('(1)', output)
        self.assertIn('Unlike', output)
        user_likes = self.util.get_items_for_user(self.user_id)

        self.assertTrue(
            self.util.is_item_liked_by_user(self.user_id, comment_id))
        self.assertEqual(len(user_likes), 1)

        # Toggle like for comment
        output = view()
        user_likes = self.util.get_items_for_user(self.user_id)
        self.assertEqual(len(user_likes), 0)
        self.assertIn('(0)', output)
        self.assertIn('Like', output)
コード例 #11
0
 def update_comments(obj, path):
     """Update the comments of this object
     """
     if IConversation is not None:
         conversation = IConversation(obj, None)
         if conversation is not None:
             for comment in conversation.getComments():
                 comment.reindexObject()
             return
     try:
         talkback = self.portal_discussion.getDiscussionFor(obj)
     except (TypeError, AttributeError):
         # Happens for the 'portal_types' object and for
         # objects in portal_skins/custom.
         logger.debug("Error getting discussion for obj at %s", path)
         return
     except DiscussionNotAllowed:
         logger.debug("Discussion not allowed for obj at %s", path)
         if not self.force:
             return
         # Try anyway:
         if not hasattr(aq_base(obj), 'talkback'):
             return
         talkback = getattr(obj, 'talkback')
         logger.info("Discussion not allowed for obj, but forcing "
                     "recatalog anyway at %s", path)
     ids = talkback.objectIds()
     if ids:
         logger.info("%s replies found for obj at %s", len(ids), path)
         for reply_id in ids:
             reply = talkback.getReply(reply_id)
             reply.reindexObject()
コード例 #12
0
ファイル: utils.py プロジェクト: derFreitag/collective.solr
def findObjects(origin):
    """ generator to recursively find and yield all zope objects below
        the given start point """
    traverse = origin.unrestrictedTraverse
    base = '/'.join(origin.getPhysicalPath())
    cut = len(base) + 1
    paths = [base]
    for idx, path in enumerate(paths):
        obj = traverse(path)
        yield path[cut:], obj
        if hasattr(aq_base(obj), 'objectIds'):
            from zope.component.interfaces import ComponentLookupError
            try:
                for id in obj.objectIds():
                    paths.insert(idx + 1, path + '/' + id)
            except ComponentLookupError:
                logger.error(
                    'Can not list sub-objects of object {0}'.format(path)
                )

        try:
            conversation = IConversation(obj)
        except TypeError:
            continue

        for comment in conversation.getComments():
            comment_path = '/'.join(comment.getPhysicalPath()[-2:])
            paths.insert(idx + 1, path + '/' + comment_path)
コード例 #13
0
def notify_content_object_moved(obj, event):
    """Update all comments of a content object that has been moved.
    """
    if event.oldParent is None or event.newParent is None \
            or event.oldName is None or event.newName is None:
        return

    # This method is also called for sublocations of moved objects. We
    # therefore can't assume that event.object == obj and event.
    # {old,new}{Parent,Name} may refer to the actually moved object further up
    # in the object hierarchy. The object is already moved at this point. so
    # obj.getPhysicalPath retruns the new path get the part of the path that
    # was moved.
    moved_path = obj.getPhysicalPath()[len(event.newParent.getPhysicalPath()) +
                                       1:]

    # Remove comments at the old location from catalog
    catalog = getToolByName(obj, 'portal_catalog')
    old_path = '/'.join(event.oldParent.getPhysicalPath() + (event.oldName, ) +
                        moved_path)
    brains = catalog.searchResults(
        dict(path={'query': old_path}, portal_type="Discussion Item"))
    for brain in brains:
        catalog.uncatalog_object(brain.getPath())
    # Reindex comment at the new location
    conversation = IConversation(obj, None)
    if conversation is not None:
        for comment in conversation.getComments():
            comment.reindexObject()
コード例 #14
0
    def test_add_comment(self):
        # Create a conversation. In this case we doesn't assign it to an
        # object, as we just want to check the Conversation object API.
        conversation = IConversation(self.portal.doc1)

        # Add a comment. Note: in real life, we always create comments via the
        # factory to allow different factories to be swapped in

        comment = createObject('plone.Comment')
        comment.text = 'Comment text'

        new_id = conversation.addComment(comment)

        # Check that the conversation methods return the correct data
        self.assertTrue(isinstance(comment.comment_id, int))
        self.assertTrue(IComment.providedBy(conversation[new_id]))
        self.assertEqual(
            aq_base(conversation[new_id].__parent__),
            aq_base(conversation),
        )
        self.assertEqual(new_id, comment.comment_id)
        self.assertEqual(len(list(conversation.getComments())), 1)
        self.assertEqual(len(tuple(conversation.getThreads())), 1)
        self.assertEqual(conversation.total_comments(), 1)
        self.assertTrue(
            conversation.last_comment_date - datetime.utcnow() <
            timedelta(seconds=1),
        )
コード例 #15
0
    def test_add_comment(self):
        # Create a conversation. In this case we doesn't assign it to an
        # object, as we just want to check the Conversation object API.
        conversation = IConversation(self.portal.doc1)

        # Add a comment. Note: in real life, we always create comments via the
        # factory to allow different factories to be swapped in

        comment = createObject('plone.Comment')
        comment.text = 'Comment text'

        new_id = conversation.addComment(comment)

        # Check that the conversation methods return the correct data
        self.assertTrue(isinstance(comment.comment_id, long))
        self.assertTrue(IComment.providedBy(conversation[new_id]))
        self.assertEqual(
            aq_base(conversation[new_id].__parent__),
            aq_base(conversation)
        )
        self.assertEqual(new_id, comment.comment_id)
        self.assertEqual(len(list(conversation.getComments())), 1)
        self.assertEqual(len(tuple(conversation.getThreads())), 1)
        self.assertEqual(conversation.total_comments(), 1)
        self.assertTrue(
            conversation.last_comment_date - datetime.utcnow() <
            timedelta(seconds=1)
        )
コード例 #16
0
ファイル: test_migration.py プロジェクト: CGTIC/Plone_SP
    def test_migrate_comment_with_creator(self):
        # Create a comment
        talkback = self.discussion.getDiscussionFor(self.doc)
        self.doc.talkback.createReply('My Title', 'My Text', Creator='Jim')
        reply = talkback.getReplies()[0]
        reply.setReplyTo(self.doc)
        reply.creation_date = DateTime(2003, 3, 11, 9, 28, 6, 'GMT')
        reply.modification_date = DateTime(2009, 7, 12, 19, 38, 7, 'GMT')
        reply.author_username = '******'
        reply.email = '*****@*****.**'

        self._publish(reply)
        self.assertEqual(reply.Title(), 'My Title')
        self.assertEqual(reply.EditableBody(), 'My Text')
        self.assertTrue('Jim' in reply.listCreators())
        self.assertEqual(talkback.replyCount(self.doc), 1)
        self.assertEqual(reply.inReplyTo(), self.doc)
        self.assertEqual(reply.author_username, 'Jim')
        self.assertEqual(reply.email, '*****@*****.**')

        # Call migration script
        self.view()

        # Make sure a conversation has been created
        self.assertTrue(
            'plone.app.discussion:conversation' in IAnnotations(self.doc)
        )
        conversation = IConversation(self.doc)

        # Check migration
        self.assertEqual(conversation.total_comments, 1)
        self.assertTrue(conversation.getComments().next())
        comment1 = conversation.values()[0]
        self.assertTrue(IComment.providedBy(comment1))
        self.assertEqual(comment1.Title(), 'My Title')
        self.assertEqual(comment1.text, '<p>My Text</p>\n')
        self.assertEqual(comment1.mime_type, 'text/html')
        self.assertEqual(comment1.Creator(), 'Jim')
        self.assertEqual(
            comment1.creation_date,
            datetime(2003, 3, 11, 9, 28, 6)
        )
        self.assertEqual(
            comment1.modification_date,
            datetime(2009, 7, 12, 19, 38, 7)
        )
        self.assertEqual([
            {'comment': comment1, 'depth': 0, 'id': long(comment1.id)}
        ], list(conversation.getThreads()))
        self.assertFalse(self.doc.talkback)

        # Though this should be Jimmy, but looks like getProperty won't pick
        # up 'author_username' (reply.author_username is not None), so it's
        # propagating Creator()..?
        self.assertEqual(comment1.author_username, 'Jim')

        self.assertEqual(comment1.author_name, 'Jimmy Jones')
        self.assertEqual(comment1.author_email, '*****@*****.**')
コード例 #17
0
    def test_push_to_tmpstorage(self):
        push_to_tmpstorage(self.portal.doc1)

        conversation = IConversation(self.portal)
        self.assertEqual(len(conversation), 1)

        self.assertEqual(
            conversation.getComments().next().text,
            'Comment text'
        )
コード例 #18
0
    def test_migrate_comment_with_creator(self):
        # Create a comment
        talkback = self.discussion.getDiscussionFor(self.doc)
        self.doc.talkback.createReply('My Title', 'My Text', Creator='Jim')
        reply = talkback.getReplies()[0]
        reply.setReplyTo(self.doc)
        reply.creation_date = DateTime(2003, 3, 11, 9, 28, 6, 'GMT')
        reply.modification_date = DateTime(2009, 7, 12, 19, 38, 7, 'GMT')
        reply.author_username = '******'
        reply.email = '*****@*****.**'

        self._publish(reply)
        self.assertEqual(reply.Title(), 'My Title')
        self.assertEqual(reply.EditableBody(), 'My Text')
        self.assertTrue('Jim' in reply.listCreators())
        self.assertEqual(talkback.replyCount(self.doc), 1)
        self.assertEqual(reply.inReplyTo(), self.doc)
        self.assertEqual(reply.author_username, 'Jim')
        self.assertEqual(reply.email, '*****@*****.**')

        # Call migration script
        self.view()

        # Make sure a conversation has been created
        self.assertTrue(
            'plone.app.discussion:conversation' in IAnnotations(self.doc))
        conversation = IConversation(self.doc)

        # Check migration
        self.assertEqual(conversation.total_comments, 1)
        self.assertTrue(conversation.getComments().next())
        comment1 = conversation.values()[0]
        self.assertTrue(IComment.providedBy(comment1))
        self.assertEqual(comment1.Title(), 'My Title')
        self.assertEqual(comment1.text, '<p>My Text</p>\n')
        self.assertEqual(comment1.mime_type, 'text/html')
        self.assertEqual(comment1.Creator(), 'Jim')
        self.assertEqual(comment1.creation_date,
                         datetime(2003, 3, 11, 9, 28, 6))
        self.assertEqual(comment1.modification_date,
                         datetime(2009, 7, 12, 19, 38, 7))
        self.assertEqual([{
            'comment': comment1,
            'depth': 0,
            'id': long(comment1.id)
        }], list(conversation.getThreads()))
        self.assertFalse(self.doc.talkback)

        # Though this should be Jimmy, but looks like getProperty won't pick
        # up 'author_username' (reply.author_username is not None), so it's
        # propagating Creator()..?
        self.assertEqual(comment1.author_username, 'Jim')

        self.assertEqual(comment1.author_name, 'Jimmy Jones')
        self.assertEqual(comment1.author_email, '*****@*****.**')
コード例 #19
0
 def testDiscussionReply(self):
     from zope.component import createObject, queryUtility
     from plone.registry.interfaces import IRegistry
     from plone.app.discussion.interfaces import IDiscussionSettings
     from plone.app.discussion.interfaces import IConversation
     self.folder.invokeFactory('Document', id='doc', title="Document")
     # Enable discussion
     registry = queryUtility(IRegistry)
     settings = registry.forInterface(IDiscussionSettings)
     settings.globally_enabled = True
     # Create the conversation object
     conversation = IConversation(self.folder.doc)
     # Add a comment
     comment = createObject('plone.Comment')
     comment.text = 'Comment text'
     conversation.addComment(comment)
     # Test the comment
     self.assertEqual(len(list(conversation.getComments())), 1)
     reply = conversation.getComments().next()
     self.assertEqual(reply.Title(), u'Anonymous on Document')
     self.assertEqual(reply.text, 'Comment text')
コード例 #20
0
 def testDiscussionReply(self):
     from zope.component import createObject, queryUtility
     from plone.registry.interfaces import IRegistry
     from plone.app.discussion.interfaces import IDiscussionSettings
     from plone.app.discussion.interfaces import IConversation
     self.folder.invokeFactory('Document', id='doc', title="Document")
     # Enable discussion
     registry = queryUtility(IRegistry)
     settings = registry.forInterface(IDiscussionSettings)
     settings.globally_enabled = True
     # Create the conversation object
     conversation = IConversation(self.folder.doc)
     # Add a comment
     comment = createObject('plone.Comment')
     comment.text = 'Comment text'
     conversation.addComment(comment)
     # Test the comment
     self.assertEquals(len(list(conversation.getComments())), 1)
     reply = conversation.getComments().next()
     self.assertEqual(reply.Title(), u'Anonymous on Document')
     self.assertEquals(reply.text, 'Comment text')
コード例 #21
0
    def test_delete_comment_when_content_object_is_deleted(self):
        # Make sure all comments of a content object are deleted when the
        # object itself is deleted.
        conversation = IConversation(self.portal.doc1)
        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        conversation.addComment(comment)

        # Delete the content object
        self.portal.manage_delObjects(['doc1'])

        # Make sure the comment has been deleted as well
        self.assertEqual(len(list(conversation.getComments())), 0)
        self.assertEqual(len(tuple(conversation.getThreads())), 0)
        self.assertEqual(conversation.total_comments, 0)
コード例 #22
0
    def test_delete_comment_when_content_object_is_deleted(self):
        # Make sure all comments of a content object are deleted when the
        # object itself is deleted.
        conversation = IConversation(self.portal.doc1)
        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        conversation.addComment(comment)

        # Delete the content object
        self.portal.manage_delObjects(['doc1'])

        # Make sure the comment has been deleted as well
        self.assertEqual(len(list(conversation.getComments())), 0)
        self.assertEqual(len(tuple(conversation.getThreads())), 0)
        self.assertEqual(conversation.total_comments, 0)
コード例 #23
0
 def test_discussion_normal(self):
     self._create_commentable_doc()
     self.browser.open(self.portal_url + '/doc')
     self.browser.getControl(
         name='form.widgets.author_name').value = 'Mr. Spammer'
     self.browser.getControl(
         name='form.widgets.text').value = 'Spam spam.'
     self.browser.getControl(name='form.buttons.comment').click()
     self.assertTrue(
         'Required input is missing.' not in self.browser.contents)
     # The comment is added.
     conversation = IConversation(self.portal.doc)
     self.assertEqual(len(list(conversation.getComments())), 1)
     # No mails are sent.
     self.assertEqual(len(self.mailhost.messages), 0)
コード例 #24
0
ファイル: test_migration.py プロジェクト: CGTIC/Plone_SP
    def test_migrate_comment(self):

        # Create a comment
        talkback = self.discussion.getDiscussionFor(self.doc)
        self.doc.talkback.createReply('My Title', 'My Text', Creator='Jim')
        reply = talkback.getReplies()[0]
        reply.setReplyTo(self.doc)
        reply.creation_date = DateTime(2003, 3, 11, 9, 28, 6, 'GMT')
        reply.modification_date = DateTime(2009, 7, 12, 19, 38, 7, 'GMT')

        self._publish(reply)
        self.assertEqual(reply.Title(), 'My Title')
        self.assertEqual(reply.EditableBody(), 'My Text')
        self.assertTrue('Jim' in reply.listCreators())
        self.assertEqual(talkback.replyCount(self.doc), 1)
        self.assertEqual(reply.inReplyTo(), self.doc)

        # Call migration script
        self.view()

        # Make sure a conversation has been created
        self.assertTrue(
            'plone.app.discussion:conversation' in IAnnotations(self.doc)
        )
        conversation = IConversation(self.doc)

        # Check migration
        self.assertEqual(conversation.total_comments, 1)
        self.assertTrue(conversation.getComments().next())
        comment1 = conversation.values()[0]
        self.assertTrue(IComment.providedBy(comment1))
        self.assertEqual(comment1.Title(), 'My Title')
        self.assertEqual(comment1.text, '<p>My Text</p>\n')
        self.assertEqual(comment1.mime_type, 'text/html')
        self.assertEqual(comment1.Creator(), 'Jim')
        self.assertEqual(
            comment1.creation_date,
            datetime(2003, 3, 11, 9, 28, 6)
        )
        self.assertEqual(
            comment1.modification_date,
            datetime(2009, 7, 12, 19, 38, 7)
        )
        self.assertEqual([
            {'comment': comment1, 'depth': 0, 'id': long(comment1.id)}
        ], list(conversation.getThreads()))
        self.assertFalse(self.doc.talkback)
コード例 #25
0
def _comments(obj):
    from plone.app.discussion.interfaces import IConversation
    conversation = IConversation(obj)
    comments = []

    for c in conversation.getComments():
        comments.append({
            'author_username':
            c.author_username,
            'text':
            c.text,
            'comment_id':
            c.comment_id,
            'creation_date':
            api.portal.get_localized_time(c.creation_date, long_format=True)
        })
    return comments
コード例 #26
0
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, PublishComment):
            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, PublishComment):
            view = Klass(self.comment, self.request)
            view.__parent__ = self.comment
            self.assertNotEqual('http://attacker.com', view())
コード例 #27
0
    def test_migrate_comment(self):

        # Create a comment
        talkback = self.discussion.getDiscussionFor(self.doc)
        self.doc.talkback.createReply('My Title', 'My Text', Creator='Jim')
        reply = talkback.getReplies()[0]
        reply.setReplyTo(self.doc)
        reply.creation_date = DateTime(2003, 3, 11, 9, 28, 6, 'GMT')
        reply.modification_date = DateTime(2009, 7, 12, 19, 38, 7, 'GMT')

        self._publish(reply)
        self.assertEqual(reply.Title(), 'My Title')
        self.assertEqual(reply.EditableBody(), 'My Text')
        self.assertTrue('Jim' in reply.listCreators())
        self.assertEqual(talkback.replyCount(self.doc), 1)
        self.assertEqual(reply.inReplyTo(), self.doc)

        # Call migration script
        self.view()

        # Make sure a conversation has been created
        self.assertTrue(
            'plone.app.discussion:conversation' in IAnnotations(self.doc))
        conversation = IConversation(self.doc)

        # Check migration
        self.assertEqual(conversation.total_comments, 1)
        self.assertTrue(conversation.getComments().next())
        comment1 = conversation.values()[0]
        self.assertTrue(IComment.providedBy(comment1))
        self.assertEqual(comment1.Title(), 'My Title')
        self.assertEqual(comment1.text, '<p>My Text</p>\n')
        self.assertEqual(comment1.mime_type, 'text/html')
        self.assertEqual(comment1.Creator(), 'Jim')
        self.assertEqual(comment1.creation_date,
                         datetime(2003, 3, 11, 9, 28, 6))
        self.assertEqual(comment1.modification_date,
                         datetime(2009, 7, 12, 19, 38, 7))
        self.assertEqual([{
            'comment': comment1,
            'depth': 0,
            'id': long(comment1.id)
        }], list(conversation.getThreads()))
        self.assertFalse(self.doc.talkback)
コード例 #28
0
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, PublishComment):
            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, PublishComment):
            view = Klass(self.comment, self.request)
            view.__parent__ = self.comment
            self.assertNotEqual('http://attacker.com', view())
コード例 #29
0
def notify_content_object_moved(obj, event):
    """Update all comments of a content object that has been moved.
    """
    if (
        event.oldParent is None
        or event.newParent is None
        or event.oldName is None
        or event.newName is None
        or event.oldParent == event.newParent
    ):
        return
    # Remove comments at the old location from catalog
    catalog = getToolByName(obj, "portal_catalog")
    for brain in catalog.searchResults(portal_type="Discussion Item"):
        catalog.uncatalog_object(brain.getPath())
    # Reindex comment at the new location
    conversation = IConversation(obj)
    for comment in conversation.getComments():
        comment.__parent__.__parent__.__parent__ = event.newParent
        catalog.reindexObject(aq_base(comment))
コード例 #30
0
ファイル: utils.py プロジェクト: kkdhanesh/NBADEMO
def move_comments(source_object, target_object):
    """Move comments by copying the annotation to the target
    and then removing the comments from the source (not the annotation).
    """
    source_annotations = IAnnotations(source_object)
    comments = source_annotations.get(DISCUSSION_KEY, None)
    if comments is not None:
        target_annotations = IAnnotations(target_object)
        if target_annotations.get(DISCUSSION_KEY, None) is not None:
            logger.error('Comments exist on {0}').format(
                target_object.absolute_url())
        target_annotations[DISCUSSION_KEY] = deepcopy(comments)

        # Delete comments from the portal where wthey were stored temporarily.
        # Comments on the old objects will be removed with the objects.
        if IPloneSiteRoot.providedBy(source_object):
            source_conversation = IConversation(source_object)
            for comment in source_conversation.getComments():
                del source_conversation[comment.comment_id]
            del source_annotations[DISCUSSION_KEY]
コード例 #31
0
def move_comments(source_object, target_object):
    """Move comments by copying the annotation to the target
    and then removing the comments from the source (not the annotation).
    """
    source_annotations = IAnnotations(source_object)
    comments = source_annotations.get(DISCUSSION_KEY, None)
    if comments is not None:
        target_annotations = IAnnotations(target_object)
        if target_annotations.get(DISCUSSION_KEY, None) is not None:
            logger.error('Comments exist on {0}').format(
                target_object.absolute_url())
        target_annotations[DISCUSSION_KEY] = deepcopy(comments)

        # Delete comments from the portal where wthey were stored temporarily.
        # Comments on the old objects will be removed with the objects.
        if IPloneSiteRoot.providedBy(source_object):
            source_conversation = IConversation(source_object)
            for comment in source_conversation.getComments():
                del source_conversation[comment.comment_id]
            del source_annotations[DISCUSSION_KEY]
コード例 #32
0
ファイル: comment.py プロジェクト: retsu/plone.app.discussion
def notify_content_object_moved(obj, event):
    """Update all comments of a content object that has been moved.
    """
    if event.oldParent is None or event.newParent is None \
       or event.oldName is None or event.newName is None:
        return
    # Remove comments at the old location from catalog
    catalog = getToolByName(obj, 'portal_catalog')
    old_path = '/'.join(event.oldParent.getPhysicalPath() + (event.oldName,))
    brains = catalog.searchResults(dict(
                 path={'query': old_path},
                 portal_type="Discussion Item"
                 ))
    for brain in brains:
        catalog.uncatalog_object(brain.getPath())
    # Reindex comment at the new location
    conversation = IConversation(obj, None)
    if conversation is not None:
        for comment in conversation.getComments():
            aq_base(comment).__parent__.__parent__.__parent__ = event.newParent
            catalog.reindexObject(aq_base(comment))
コード例 #33
0
def notify_content_object_moved(obj, event):
    """Update all comments of a content object that has been moved.
    """
    if event.oldParent is None or event.newParent is None \
       or event.oldName is None or event.newName is None:
        return
    # Remove comments at the old location from catalog
    catalog = getToolByName(obj, 'portal_catalog')
    old_path = '/'.join(event.oldParent.getPhysicalPath() + (event.oldName,))
    brains = catalog.searchResults(dict(
                 path={'query': old_path},
                 portal_type="Discussion Item"
                 ))
    for brain in brains:
        catalog.uncatalog_object(brain.getPath())
    # Reindex comment at the new location
    conversation = IConversation(obj, None)
    if conversation is not None:
        for comment in conversation.getComments():
            aq_base(comment).__parent__.__parent__.__parent__ = event.newParent
            catalog.reindexObject(aq_base(comment))
コード例 #34
0
ファイル: forum.py プロジェクト: UPCnet/genweb.simpleforum
    def posts(self):
        # llista de posts ordenats de més recent a més antic
        results = []
        mtool = api.portal.get_tool(name='portal_membership')
        brains = self.context.getFolderContents(contentFilter={
            'portal_type': 'genweb.simpleforum.post',
            'sort_on': 'modified',
            'sort_order': 'reverse'})

        for brain in brains:
            conversation = IConversation(brain.getObject())
            total_comments = conversation.total_comments
            comments = conversation.getComments()
            last_comment = None
            for last_comment in comments:
                pass
            if last_comment:
                last_author = last_comment.Creator()
            else:
                last_author = brain.Creator

            # si hi ha comentaris mostrem la data del darrer comentari, si no, la data de modificació del post
            if total_comments > 0:
                modification_date = utc_to_local(conversation.last_comment_date)
            else:
                modification_date = brain.ModificationDate
            modification_date = self.context.toLocalizedTime(modification_date, long_format='%B %d, %Y')

            results.append({
                'title': brain.Title,
                'url': brain.getURL(),
                'author': mtool.getMemberInfo(last_author)['fullname'],
                'modificationDate': modification_date,
                'portrait': mtool.getPersonalPortrait(id=brain.listCreators[0]).absolute_url(),
                'comments': total_comments
            })
            # ordenem els resultas inversament data creació o d'últim comentari
            results = sorted(results, key=itemgetter('modificationDate'), reverse=True)
        # import pdb; pdb.set_trace()
        return results
コード例 #35
0
    def __iter__(self):
        for item in self.previous:
            if item['_type'] != 'Discussion Item':  # not a comment
                yield item
                continue
            path = item['_path']

            pathlist = path.split('/')
            pathlist.remove('talkback')
            path = '/'.join(pathlist[:-1])

            ob = self.context.unrestrictedTraverse(path.lstrip('/'), None)
            if ob is None:
                yield item
                continue  # object not found

            logger.info("importing Comment on %s", ob)
            conversation = IConversation(ob)

            #check to see if comment already exists
            already_exists = False
            for comment in conversation.getComments():
                if comment.text == item['text']:
                    already_exists = True
                    continue

            if already_exists:
                logger.info('comment already exists, skipping')
                yield item
                continue

            comment = createObject('plone.Comment')
            comment.text = item['text']
            comment.author_name = item.get('author_name')
            comment.author_email = item.get('author_email')
            comment.creation_date = DateTime(
                item['creation_date']).asdatetime()
            comment.modification_date = comment.creation_date
            in_reply_to = item.get('_in_reply_to', 0)
            if in_reply_to:
                comment.in_reply_to = self.comment_map[in_reply_to]

            id = conversation.addComment(comment)
            self.comment_map[item['_id']] = id

            item_tmp = item
            workflowhistorykey = "_workflow_history"
            # get back datetime stamp and set the workflow history
            for workflow in item_tmp[workflowhistorykey]:
                for k, workflow2 in enumerate(
                        item_tmp[workflowhistorykey][workflow]):  # noqa
                    if 'time' in item_tmp[workflowhistorykey][workflow][k]:
                        item_tmp[workflowhistorykey][workflow][k][
                            'time'] = DateTime(  # noqa
                                item_tmp[workflowhistorykey][workflow][k]
                                ['time'])  # noqa

            #change workflow key/name from 'comment_worklfow' to 'comment_review_workflow'
            item_tmp[workflowhistorykey]['comment_review_workflow'] = \
                item_tmp[workflowhistorykey].pop('comment_workflow')
            comment.workflow_history.data = item_tmp[workflowhistorykey]

            # update security
            workflows = self.wftool.getWorkflowsFor(comment)
            if workflows:
                workflows[0].updateRoleMappingsFor(comment)

            yield item
コード例 #36
0
    def test_edit_comment(self):
        """Edit a comment as logged-in user.
        """

        # Allow discussion
        self.portal.doc1.allow_discussion = True
        self.viewlet = CommentsViewlet(self.context, self.request, None, None)

        def make_request(form={}):
            request = TestRequest()
            request.form.update(form)
            alsoProvides(request, IFormLayer)
            alsoProvides(request, IAttributeAnnotatable)
            return request

        provideAdapter(
            adapts=(Interface, IBrowserRequest),
            provides=Interface,
            factory=CommentForm,
            name=u"comment-form"
        )

        provideAdapter(
            adapts=(Interface, IBrowserRequest),
            provides=Interface,
            factory=EditCommentForm,
            name=u"edit-comment-form"
        )

        # The form is submitted successfully, if the required text field is
        # filled out
        request = make_request(form={'form.widgets.text': u'bar'})

        commentForm = getMultiAdapter(
            (self.context, request),
            name=u"comment-form"
        )
        commentForm.update()
        data, errors = commentForm.extractData()  # pylint: disable-msg=W0612

        self.assertEqual(len(errors), 0)
        self.assertFalse(commentForm.handleComment(commentForm, "foo"))

        # Edit the last comment
        conversation = IConversation(self.context)
        comment = [x for x in conversation.getComments()][-1]
        request = make_request(form={'form.widgets.text': u'foobar'})
        editForm = getMultiAdapter(
            (comment, request),
            name=u"edit-comment-form"
        )
        editForm.update()
        data, errors = editForm.extractData()  # pylint: disable-msg=W0612

        self.assertEqual(len(errors), 0)
        self.assertFalse(editForm.handleComment(editForm, "foo"))
        comment = [x for x in conversation.getComments()][-1]
        self.assertEquals(comment.text, u"foobar")

        comments = IConversation(commentForm.context).getComments()
        comments = [comment for comment in comments]  # consume itertor
        self.assertEqual(len(comments), 1)

        for comment in comments:
            self.assertEqual(comment.text, u"foobar")
            self.assertEqual(comment.creator, "test_user_1_")

            self.assertEqual(comment.getOwner().getUserName(), "test-user")
            local_roles = comment.get_local_roles()
            self.assertEqual(len(local_roles), 1)
            userid, roles = local_roles[0]
            self.assertEqual(userid, 'test_user_1_')
            self.assertEqual(len(roles), 1)
            self.assertEqual(roles[0], 'Owner')