def __iter__(self):
        for item in self.previous:
            keys = item.keys()
            typekey = self.typekey(*keys)[0]
            if item[typekey] != 'plone.Comment': # not a comment
                yield item; continue

            pathkey = self.pathkey(*item.keys())[0]
            if not pathkey: # not enough info
                yield item; continue
            path = item[pathkey]

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

            # XXX make sure comment doesn't exist already?

            conversation = IConversation(ob)
            comment = createObject('plone.Comment')
            comment.text              = item['text']
            comment.author_name       = item['author_name']
            comment.author_email      = item['author_email']
            comment.creation_date     = DateTime(item['created']).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['_comment_id']] = id

            yield item
Exemple #2
0
    def setUp(self):
        self.portal = self.layer['portal']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])

        # Create a conversation.
        conversation = IConversation(self.portal.doc1)

        comment1 = createObject('plone.Comment')
        comment1.text = 'Comment Text'
        comment1.creator = "jim"
        comment1.author_username = "******"
        comment1.creation_date = datetime(2006, 9, 17, 14, 18, 12)
        comment1.modification_date = datetime(2006, 9, 17, 14, 18, 12)
        self.new_id1 = conversation.addComment(comment1)

        comment2 = createObject('plone.Comment')
        comment2.text = 'Comment Text'
        comment2.creator = "emma"
        comment2.author_username = "******"
        comment2.creation_date = datetime(2007, 12, 13, 4, 18, 12)
        comment2.modification_date = datetime(2007, 12, 13, 4, 18, 12)
        self.new_id2 = conversation.addComment(comment2)

        comment3 = createObject('plone.Comment')
        comment3.text = 'Comment Text'
        comment3.creator = "lukas"
        comment3.author_username = "******"
        comment3.creation_date = datetime(2009, 4, 12, 11, 12, 12)
        comment3.modification_date = datetime(2009, 4, 12, 11, 12, 12)
        self.new_id3 = conversation.addComment(comment3)

        self.conversation = conversation
    def test_add_and_remove_interface_on_catalog(self):
        self._add_comment('one alert')
        # acquisition wrapped version of the comment
        comment = IConversation(self.document).values()[0]
        condition = TextAlertCondition()
        condition.stop_words = u'one alert\nanother alert'

        # adds the marker interface
        executable = getMultiAdapter(
            (self.portal, condition, CommentDummyEvent(comment)),
            IExecutable
        )
        executable()
        brains = api.content.find(
            self.portal,
            object_provides=IHasStopWords.__identifier__
        )
        self.assertEqual(len(brains), 1)

        comment.text = 'no longer creating an alert'
        executable()
        brains = api.content.find(
            self.portal,
            object_provides=IHasStopWords.__identifier__
        )
        self.assertEqual(len(brains), 0)
    def setUp(self):
        self.portal = self.layer["portal"]
        setRoles(self.portal, TEST_USER_ID, ["Manager"])
        self.portal.invokeFactory(id="doc1", Title="Document 1", type_name="Document")

        self.catalog = getToolByName(self.portal, "portal_catalog")
        conversation = IConversation(self.portal.doc1)
        comment1 = createObject("plone.Comment")
        comment1.title = "Comment 1"
        comment1.text = "Comment text"
        comment1.creator = "Jim"
        comment1.author_username = "******"
        comment1.creation_date = datetime(2006, 9, 17, 14, 18, 12)
        comment1.modification_date = datetime(2006, 9, 17, 14, 18, 12)

        new_comment1_id = conversation.addComment(comment1)
        self.comment_id = new_comment1_id

        brains = self.catalog.searchResults(
            dict(path={"query": "/".join(self.portal.doc1.getPhysicalPath())}, portal_type="Document")
        )
        self.conversation = conversation
        self.brains = brains
        self.doc1_brain = brains[0]
        self.comment1 = comment1
        self.new_comment1_id = new_comment1_id
Exemple #5
0
    def test_delete_comment(self):
        # Add and remove a comment to a CommentReplies adapter

        # 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 to the conversation
        replies = IReplies(conversation)

        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        new_id = replies.addComment(comment)
        comment = self.portal.doc1.restrictedTraverse(
            '++conversation++default/{0}'.format(new_id)
        )

        # Add a reply to the CommentReplies adapter of the first comment
        re_comment = createObject('plone.Comment')
        re_comment.text = 'Comment text'

        replies = IReplies(comment)

        new_re_id = replies.addComment(re_comment)

        # Remove the reply to the CommentReplies adapter
        del replies[new_re_id]

        # Make sure there is no comment left in CommentReplies
        self.assertEqual(len(replies), 0)

        # Make sure the first comment is still in the conversation
        self.assertEqual(conversation.total_comments(), 1)
    def test_get_commenter_portrait(self):

        # Add a user with a member image
        self.membershipTool.addMember('jim', 'Jim', ['Member'], [])
        self.memberdata._setPortrait(Image(
            id='jim',
            file=dummy.File(),
            title=''
        ), 'jim')
        self.assertEqual(
            self.memberdata._getPortrait('jim').getId(),
            'jim'
        )
        self.assertEqual(
            self.memberdata._getPortrait('jim').meta_type,
            'Image'
        )

        # Add a conversation with a comment
        conversation = IConversation(self.portal.doc1)
        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        comment.Creator = 'Jim'
        comment.author_username = '******'
        conversation.addComment(comment)

        # Call get_commenter_portrait method of the viewlet
        self.viewlet.update()
        portrait_url = self.viewlet.get_commenter_portrait('jim')

        # Check if the correct member image URL is returned
        self.assertEqual(
            portrait_url,
            'http://nohost/plone/portal_memberdata/portraits/jim'
        )
 def comments_count(self):
     context = self.content_context
     try:
         conversation = IConversation(context)
     except Exception:
         return 0
     return conversation.total_comments()
    def test_get_commenter_portrait_without_userimage(self):

        # Create a user without a user image
        self.membershipTool.addMember('jim', 'Jim', ['Member'], [])

        # Add a conversation with a comment
        conversation = IConversation(self.portal.doc1)
        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        comment.Creator = 'Jim'
        comment.author_username = '******'
        conversation.addComment(comment)

        # Call get_commenter_portrait method of the viewlet
        self.viewlet.update()
        portrait_url = self.viewlet.get_commenter_portrait('jim')

        # Check if the correct default member image URL is returned.
        # Note that Products.PlonePAS 4.0.5 and later have .png and
        # earlier versions have .gif.
        self.assertTrue(
            portrait_url in (
                'http://nohost/plone/defaultUser.png',
                'http://nohost/plone/defaultUser.gif'
            )
        )
    def setUp(self):
        self.portal = self.layer['portal']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
        self.portal.invokeFactory(id='doc1',
                                  title='Document 1',
                                  type_name='Document')
        self.catalog = getToolByName(self.portal, 'portal_catalog')

        conversation = IConversation(self.portal.doc1)
        self.conversation = conversation

        comment1 = createObject('plone.Comment')
        comment1.text = 'Comment text'
        comment1.creator = 'jim'
        comment1.author_name = 'Jim'
        new_comment1_id = conversation.addComment(comment1)
        self.comment_id = new_comment1_id

        # Comment brain
        self.comment = self.portal.doc1.restrictedTraverse(
            '++conversation++default/%s' % new_comment1_id)
        brains = self.catalog.searchResults(dict(
            path={
                'query':
                '/'.join(self.comment.getPhysicalPath())
            }
        ))
        self.comment_brain = brains[0]
    def setUp(self):
        self.portal = self.layer['portal']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])

        self.portal.invokeFactory(id='doc1',
                          title='Document 1',
                          type_name='Document')

        # 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 = 'Lorem ipsum dolor sit amet.'
        comment.creator = "jim"
        comment.author_name = "Jim"
        comment.creation_date = datetime(2006, 9, 17, 14, 18, 12)
        comment.modification_date = datetime(2008, 3, 12, 7, 32, 52)

        self.comment_id = conversation.addComment(comment)
        self.comment = comment.__of__(conversation)
        self.conversation = conversation
 def test_comment_uid_differs_from_content_uid(self):
     conversation = IConversation(self.portal.doc1)
     comment1 = createObject('plone.Comment')
     conversation.addComment(comment1)
     comment_brain = self.catalog.searchResults(
                         portal_type = 'Discussion Item')[0]
     self.assertNotEqual(self.document_brain.UID, comment_brain.UID)
 def test_get_replies_with_workflow_actions(self):
     self.assertFalse(self.viewlet.get_replies(workflow_actions=True))
     comment = createObject('plone.Comment')
     comment.text = 'Comment text'
     conversation = IConversation(self.portal.doc1)
     c1 = conversation.addComment(comment)
     self.assertEqual(
         len(tuple(self.viewlet.get_replies(workflow_actions=True))),
         1
     )
     # Enable moderation workflow
     self.workflowTool.setChainForPortalTypes(
         ('Discussion Item',),
         ('comment_review_workflow,')
     )
     # Check if workflow actions are available
     reply = self.viewlet.get_replies(workflow_actions=True).next()
     self.assertTrue('actions' in reply)
     self.assertEqual(
         reply['actions'][0]['id'],
         'publish'
     )
     self.assertEqual(
         reply['actions'][0]['url'],
         'http://nohost/plone/doc1/++conversation++default/%s' % int(c1) +
         '/content_status_modify?workflow_action=publish'
     )
 def test_uid(self):
     conversation = IConversation(self.portal.doc1)
     comment1 = createObject('plone.Comment')
     conversation.addComment(comment1)
     comment_brain = self.catalog.searchResults(
                         portal_type = 'Discussion Item')[0]
     self.assertTrue(comment_brain.UID)
Exemple #14
0
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)
Exemple #15
0
    def test_workflow(self):
        """Basic test for the 'comment_review_workflow'
        """
        self.portal.portal_workflow.setChainForPortalTypes(
            ('Discussion Item',),
            ('comment_review_workflow,'))

        conversation = IConversation(self.portal.doc1)
        comment1 = createObject('plone.Comment')
        new_comment1_id = conversation.addComment(comment1)

        comment = conversation[new_comment1_id]

        # Make sure comments use the 'comment_review_workflow'
        chain = self.portal.portal_workflow.getChainFor(comment)
        self.assertEqual(('comment_review_workflow',), chain)

        # Ensure the initial state was entered and recorded
        self.assertEqual(
            1,
            len(comment.workflow_history['comment_review_workflow'])
        )
        self.assertEqual(
            None,
            comment.workflow_history['comment_review_workflow'][0]['action']
        )
        self.assertEqual(
            'pending',
            self.portal.portal_workflow.getInfoFor(comment, 'review_state')
        )
    def setUp(self):
        self.portal = self.layer['portal']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])

        workflow = self.portal.portal_workflow
        workflow.doActionFor(self.portal.doc1, 'publish')

        # Create a conversation.
        conversation = IConversation(self.portal.doc1)

        comment1 = createObject('plone.Comment')
        comment1.text = 'Comment Text'
        comment1.creator = 'jim'
        comment1.author_username = '******'
        comment1.creation_date = datetime(2006, 9, 17, 14, 18, 12)
        comment1.modification_date = datetime(2006, 9, 17, 14, 18, 12)
        self.new_id1 = conversation.addComment(comment1)

        comment2 = createObject('plone.Comment')
        comment2.text = 'Comment Text'
        comment2.creator = 'emma'
        comment2.author_username = '******'
        comment2.creation_date = datetime(2007, 12, 13, 4, 18, 12)
        comment2.modification_date = datetime(2007, 12, 13, 4, 18, 12)
        self.new_id2 = conversation.addComment(comment2)

        comment3 = createObject('plone.Comment')
        comment3.text = 'Comment Text'
        comment3.creator = 'lukas'
        comment3.author_username = '******'
        comment3.creation_date = datetime(2009, 4, 12, 11, 12, 12)
        comment3.modification_date = datetime(2009, 4, 12, 11, 12, 12)
        self.new_id3 = conversation.addComment(comment3)

        self.conversation = conversation
Exemple #17
0
    def setUp(self):
        # Setup session manager
        ztc.utils.setupCoreSessions(self.layer['app'])

        # Setup sandbox
        self.portal = self.layer['portal']
        self.request = self.layer['request']

        # Setup current user properties
        member = self.portal.portal_membership.getMemberById(TEST_USER_ID)
        member.setMemberProperties({
            'fullname': 'X Manager',
            'email': '*****@*****.**'
        })

        setRoles(self.portal, TEST_USER_ID, ['Manager'])
        name = self.portal.invokeFactory(
            id='doc1',
            title='Document 1',
            type_name='Document')

        self.document = self.portal[name]

        comment = createObject('plone.Comment')
        comment.text = "This is a comment"
        comment.author_username = "******"
        comment.author_name = "Jim"
        comment.author_email = "*****@*****.**"
        conversation = IConversation(self.document)
        conversation.addComment(comment)
    def test_traversal(self):
        # Create a nested structure of comment replies and check the traversal

        # make sure comments are traversable, have an id, absolute_url and
        # physical path
        conversation = IConversation(self.portal.doc1)

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

        conversation.addComment(comment1)

        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        new_id = conversation.addComment(comment)
        comment = self.portal.doc1.restrictedTraverse(
            '++conversation++default/%s' % new_id)

        # Add a reply to the CommentReplies adapter of the first comment
        re_comment = createObject('plone.Comment')
        re_comment.text = 'Comment text'
        replies = IReplies(comment)
        new_re_id = replies.addComment(re_comment)
        re_comment = self.portal.doc1.restrictedTraverse(
                '++conversation++default/%s' % new_re_id)

        # Add a reply to the reply
        re_re_comment = createObject('plone.Comment')
        re_re_comment.text = 'Comment text'
        replies = IReplies(re_comment)
        new_re_re_id = replies.addComment(re_re_comment)
        re_re_comment = self.portal.doc1.restrictedTraverse(
                '++conversation++default/%s' % new_re_re_id)

        # Add a reply to the replies reply
        re_re_re_comment = createObject('plone.Comment')
        re_re_re_comment.text = 'Comment text'
        replies = IReplies(re_re_comment)
        new_re_re_re_id = replies.addComment(re_re_re_comment)
        re_re_re_comment = self.portal.doc1.restrictedTraverse(
            '++conversation++default/%s' % new_re_re_re_id)

        self.assertEqual(('', 'plone', 'doc1', '++conversation++default',
                           str(new_id)), comment.getPhysicalPath())
        self.assertEqual('http://nohost/plone/doc1/++conversation++default/' +
                          str(new_id), comment.absolute_url())
        self.assertEqual(('', 'plone', 'doc1', '++conversation++default',
                           str(new_re_id)), re_comment.getPhysicalPath())
        self.assertEqual('http://nohost/plone/doc1/++conversation++default/' +
                          str(new_re_id), re_comment.absolute_url())
        self.assertEqual(('', 'plone', 'doc1', '++conversation++default',
                           str(new_re_re_id)), re_re_comment.getPhysicalPath())
        self.assertEqual('http://nohost/plone/doc1/++conversation++default/' +
                          str(new_re_re_id), re_re_comment.absolute_url())
        self.assertEqual(('', 'plone', 'doc1', '++conversation++default',
                           str(new_re_re_re_id)),
                           re_re_re_comment.getPhysicalPath())
        self.assertEqual('http://nohost/plone/doc1/++conversation++default/' +
                          str(new_re_re_re_id),
                          re_re_re_comment.absolute_url())
 def test_has_replies(self):
     self.assertEqual(self.viewlet.has_replies(), False)
     comment = createObject('plone.Comment')
     comment.text = 'Comment text'
     conversation = IConversation(self.portal.doc1)
     conversation.addComment(comment)
     self.assertEqual(self.viewlet.has_replies(), True)
    def setUp(self):
        self.portal = self.layer['portal']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
        self.portal.invokeFactory(
            id='doc1',
            Title='Document 1',
            type_name='Document'
        )
        self.catalog = getToolByName(self.portal, 'portal_catalog')
        conversation = IConversation(self.portal.doc1)
        comment1 = createObject('plone.Comment')
        comment1.title = 'Comment 1'
        comment1.text = 'Comment text'
        comment1.creator = 'jim'
        comment1.author_username = '******'
        comment1.creation_date = datetime(2006, 9, 17, 14, 18, 12)
        comment1.modification_date = datetime(2006, 9, 17, 14, 18, 12)

        new_comment1_id = conversation.addComment(comment1)
        self.comment_id = new_comment1_id

        brains = self.catalog.searchResults(dict(
            path={
                'query':
                '/'.join(self.portal.doc1.getPhysicalPath())
            },
            portal_type="Document"
        ))
        self.conversation = conversation
        self.brains = brains
        self.doc1_brain = brains[0]
        self.comment1 = comment1
        self.new_comment1_id = new_comment1_id
Exemple #21
0
    def test_view(self):
        # make sure that the comment view is there and redirects to the right
        # URL

        # 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)

        # Create a comment
        comment1 = createObject('plone.Comment')
        comment1.text = 'Comment text'

        # Add comment to the conversation
        new_comment1_id = conversation.addComment(comment1)

        comment = self.portal.doc1.restrictedTraverse(
            '++conversation++default/{0}'.format(new_comment1_id)
        )

        # make sure the view is there
        self.assertTrue(getMultiAdapter((comment, self.request),
                                        name='view'))

        # make sure the HTTP redirect (status code 302) works when a comment
        # is called directly
        view = View(comment, self.request)
        View.__call__(view)
        self.assertEqual(self.request.response.status, 302)
    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']        

        # Allow discussion on the Document content type
        self.portal.portal_types['Document'].allow_discussion = True
        # Set workflow for Discussion item to review workflow
        self.portal.portal_workflow.setChainForPortalTypes(
            ('Discussion Item',),
            ('comment_review_workflow',))

        # Create a Document
        self.portal.invokeFactory('Document', 'doc1')
        self.portal_discussion = self.portal.portal_discussion

        # 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)
        comment = self.portal.doc1.restrictedTraverse(
            '++conversation++default/%s' % comment_id)

        self.conversation = conversation
        self.comment_id = comment_id
        self.comment = comment

        setRoles(self.portal, TEST_USER_ID, ['Reviewer'])
        alsoProvides(self.portal.REQUEST, IDiscussionLayer)
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()
    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)
        )
    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']        
        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

        # Add a comment
        conversation = IConversation(self.folder.doc1)
        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        cid = conversation.addComment(comment)

        self.comment = self.folder.doc1.restrictedTraverse(\
                            '++conversation++default/%s' % cid)

        self.portal.acl_users._doAddUser('member', 'secret', ['Member'], [])
        self.portal.acl_users._doAddUser('reviewer', 'secret', ['Reviewer'], [])
        self.portal.acl_users._doAddUser('manager', 'secret', ['Manager'], [])
        self.portal.acl_users._doAddUser('editor' , ' secret', ['Editor'],[])
        self.portal.acl_users._doAddUser('reader', 'secret', ['Reader'], [])
Exemple #26
0
    def test_traversal(self):
        # make sure comments are traversable, have an id, absolute_url and
        # physical path

        conversation = IConversation(self.portal.doc1)

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

        new_comment1_id = conversation.addComment(comment1)

        comment = self.portal.doc1.restrictedTraverse(
            '++conversation++default/{0}'.format(new_comment1_id)
        )
        self.assertTrue(IComment.providedBy(comment))

        self.assertEqual(
            (
                '', 'plone', 'doc1', '++conversation++default',
                str(new_comment1_id)
            ),
            comment.getPhysicalPath()
        )
        self.assertEqual(
            'http://nohost/plone/doc1/++conversation++default/' +
            str(new_comment1_id), comment.absolute_url()
        )
Exemple #27
0
    def write_comments(self):
        comments = self._data['comments']

        for com in comments:
            cid = com['cid']
            posts = self._posts
            try:
                post = posts[cid]
            except KeyError:
                continue

            conversation = IConversation(post)

            date = DateTime(com['date']).asdatetime()

            comment = createObject('plone.Comment')
            comment.text = fix_text(com['text'])
            comment.author_name = comment.creator = com['name']
            comment.author_email = com['email']
            comment.creation_date = comment.modification_date = date

            conversation.addComment(comment)

            transaction.commit()

            print("Wrote comment by %s" % comment.creator)
Exemple #28
0
 def test_removedEvent(self):
     self.assertFalse(self.registry.commentRemoved)
     comment = createObject('plone.Comment')
     conversation = IConversation(self.document)
     cid = conversation.addComment(comment)
     del conversation[cid]
     self.assertTrue(self.registry.commentRemoved)
 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"])
     typetool = self.portal.portal_types
     typetool.constructContent("Document", self.portal, "doc1")
     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("++conversation++default/%s" % 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("++conversation++default/%s" % 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("++conversation++default/%s" % new_id_3)
     self.conversation = conversation
    def test_move_comments_when_content_object_is_moved(self):
        # Create two folders and a content object with a comment
        self.portal.invokeFactory(id="folder1", title="Folder 1", type_name="Folder")
        self.portal.invokeFactory(id="folder2", title="Folder 2", type_name="Folder")
        self.portal.folder1.invokeFactory(id="moveme", title="Move Me", type_name="Document")
        conversation = IConversation(self.portal.folder1.moveme)
        comment = createObject("plone.Comment")
        comment_id = conversation.addComment(comment)
        # We need to commit here so that _p_jar isn't None and move will work
        transaction.savepoint(optimistic=True)

        # Move moveme from folder1 to folder2
        cp = self.portal.folder1.manage_cutObjects(ids=("moveme",))
        self.portal.folder2.manage_pasteObjects(cp)

        # Make sure no old comment brains are
        brains = self.catalog.searchResults(
            dict(portal_type="Discussion Item", path={"query": "/".join(self.portal.folder1.getPhysicalPath())})
        )
        self.assertEquals(len(brains), 0)

        brains = self.catalog.searchResults(
            dict(portal_type="Discussion Item", path={"query": "/".join(self.portal.folder2.getPhysicalPath())})
        )
        self.assertEquals(len(brains), 1)
        self.assertEquals(brains[0].getPath(), "/plone/folder2/moveme/++conversation++default/" + str(comment_id))
Exemple #31
0
    def test_move_comments_when_content_object_is_moved(self):
        # Create two folders and a content object with a comment
        self.portal.invokeFactory(
            id='folder1',
            title='Folder 1',
            type_name='Folder',
        )
        self.portal.invokeFactory(
            id='folder2',
            title='Folder 2',
            type_name='Folder',
        )
        self.portal.folder1.invokeFactory(
            id='moveme',
            title='Move Me',
            type_name='Document',
        )
        conversation = IConversation(self.portal.folder1.moveme)
        comment = createObject('plone.Comment')
        comment_id = conversation.addComment(comment)
        # We need to commit here so that _p_jar isn't None and move will work
        transaction.savepoint(optimistic=True)

        # Move moveme from folder1 to folder2
        cp = self.portal.folder1.manage_cutObjects(ids=('moveme', ))
        self.portal.folder2.manage_pasteObjects(cp)

        # Make sure no old comment brains are
        brains = self.catalog.searchResults(
            dict(
                portal_type='Discussion Item',
                path={
                    'query': '/'.join(self.portal.folder1.getPhysicalPath()),
                },
            ), )
        self.assertEqual(len(brains), 0)

        brains = self.catalog.searchResults(
            dict(
                portal_type='Discussion Item',
                path={
                    'query': '/'.join(self.portal.folder2.getPhysicalPath()),
                },
            ), )
        self.assertEqual(len(brains), 1)
        self.assertEqual(
            brains[0].getPath(),
            '/plone/folder2/moveme/++conversation++default/' + str(comment_id),
        )
Exemple #32
0
    def get_replies(self, workflow_actions=False):
        """Returns all replies to a content object.

        If workflow_actions is false, only published
        comments are returned.

        If workflow actions is true, comments are
        returned with workflow actions.
        """
        context = aq_inner(self.context)
        conversation = IConversation(context, None)

        if conversation is None:
            return iter([])

        wf = getToolByName(context, 'portal_workflow')

        # workflow_actions is only true when user
        # has 'Manage portal' permission

        def replies_with_workflow_actions():
            # Generator that returns replies dict with workflow actions
            for r in conversation.getThreads():
                comment_obj = r['comment']
                # list all possible workflow actions
                actions = [
                    a for a in wf.listActionInfos(object=comment_obj)
                    if a['category'] == 'workflow' and a['allowed']
                ]
                r = r.copy()
                r['actions'] = actions
                yield r

        def published_replies():
            # Generator that returns replies dict with workflow status.
            for r in conversation.getThreads():
                comment_obj = r['comment']
                workflow_status = wf.getInfoFor(comment_obj, 'review_state')
                if workflow_status == 'published':
                    r = r.copy()
                    r['workflow_status'] = workflow_status
                    yield r

        # Return all direct replies
        if len(conversation.objectIds()):
            if workflow_actions:
                return replies_with_workflow_actions()
            else:
                return published_replies()
    def test_add_anonymous_comment(self):
        self.portal.doc1.allow_discussion = True

        self.viewlet = CommentsViewlet(self.context, self.request, None, None)

        registry = queryUtility(IRegistry)
        settings = registry.forInterface(IDiscussionSettings, check=False)
        settings.anonymous_comments = True

        # Logout
        logout()

        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')

        # Post an anonymous comment and provide a name
        request = make_request(form={
            'form.widgets.name': u'john doe',
            '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, 'action'))

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

        for comment in IConversation(commentForm.context).getComments():
            self.assertEqual(comment.text, u'bar')
            self.assertIsNone(comment.creator)
            roles = comment.get_local_roles()
            self.assertEqual(len(roles), 0)
Exemple #34
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()]))
Exemple #35
0
    def test_commentators(self):
        # add and remove a few comments to make sure the commentators
        # property returns a true set

        # 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)

        self.assertEqual(conversation.total_comments, 0)

        # Add a four comments from three different users
        # Note: in real life, we always create
        # comments via the factory to allow different factories to be
        # swapped in
        comment1 = createObject('plone.Comment')
        comment1.text = 'Comment text'
        comment1.author_username = "******"
        conversation.addComment(comment1)

        comment2 = createObject('plone.Comment')
        comment2.text = 'Comment text'
        comment2.author_username = "******"
        conversation.addComment(comment2)

        comment3 = createObject('plone.Comment')
        comment3.text = 'Comment text'
        comment3.author_username = "******"
        new_comment3_id = conversation.addComment(comment3)

        comment4 = createObject('plone.Comment')
        comment4.text = 'Comment text'
        comment4.author_username = "******"
        new_comment4_id = conversation.addComment(comment4)

        # check if all commentators are in the commentators list
        self.assertEqual(conversation.total_comments, 4)
        self.assertTrue('Jim' in conversation.commentators)
        self.assertTrue('Joe' in conversation.commentators)
        self.assertTrue('Jack' in conversation.commentators)

        # remove the comment from Jack
        del conversation[new_comment3_id]

        # check if Jack is still in the commentators list (since
        # he had added two comments)
        self.assertTrue('Jim' in conversation.commentators)
        self.assertTrue('Joe' in conversation.commentators)
        self.assertTrue('Jack' in conversation.commentators)
        self.assertEqual(conversation.total_comments, 3)

        # remove the second comment from Jack
        del conversation[new_comment4_id]

        # check if Jack has been removed from the commentators list
        self.assertTrue('Jim' in conversation.commentators)
        self.assertTrue('Joe' in conversation.commentators)
        self.assertFalse('Jack' in conversation.commentators)
        self.assertEqual(conversation.total_comments, 2)
    def setUp(self):
        # Setup sandbox
        self.portal = self.layer['portal']
        self.request = self.layer['request']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
        name = self.portal.invokeFactory(id='doc1',
                                         title='Document 1',
                                         type_name='Document')

        self.document = self.portal[name]
        conversation = IConversation(self.document)
        replies = IReplies(conversation)

        comment = createObject('plone.Comment')
        comment.text = 'This is a comment'
        new_id = replies.addComment(comment)
        comment = self.document.restrictedTraverse(
            '++conversation++default/%s' % new_id)

        re_comment = createObject('plone.Comment')
        re_comment.text = 'This is a reply'
        re_comment.author_username = "******"
        re_comment.author_name = "Juliana"
        re_comment.author_email = "*****@*****.**"

        replies = IReplies(comment)
        new_re_id = replies.addComment(re_comment)
 def test_no_comment(self):
     IConversation(self.portal.doc1)
     # Make sure no conversation has been created
     self.assertTrue(
         'plone.app.discussion:conversation' not in
         IAnnotations(self.portal.doc1),
     )
Exemple #38
0
    def setUp(self):
        self.app = self.layer["app"]
        self.portal = self.layer["portal"]
        self.request = self.layer["request"]
        self.portal_url = self.portal.absolute_url()

        # Allow discussion
        registry = getUtility(IRegistry)
        settings = registry.forInterface(IDiscussionSettings, check=False)
        settings.globally_enabled = True
        settings.edit_comment_enabled = True
        settings.delete_own_comment_enabled = True

        # doc with comments
        self.doc = api.content.create(
            container=self.portal,
            type="Document",
            id="doc_with_comments",
            title="Document with comments",
            allow_discussion=True,
        )
        self.conversation = IConversation(self.doc)
        self.replies = IReplies(self.conversation)
        comment = createObject("plone.Comment")
        comment.text = "Comment"
        self.comment = self.replies[self.replies.addComment(comment)]

        comment = createObject("plone.Comment")
        comment.text = "Comment 2"
        self.replies.addComment(comment)
Exemple #39
0
 def commentCount(self, ob):
     if USE_PAD:
         conversation = IConversation(ob)
         return len(conversation)
     else:
         discussion = self.portal_discussion.getDiscussionFor(ob)
         return discussion.replyCount(ob)
Exemple #40
0
    def reply(self):
        # Disable CSRF protection
        if "IDisableCSRFProtection" in dir(plone.protect.interfaces):
            alsoProvides(self.request,
                         plone.protect.interfaces.IDisableCSRFProtection)

        conversation = IConversation(self.context)
        if self.comment_id and self.comment_id not in list(conversation):
            self.request.response.setStatus(404)
            return

        # Fake request data
        body = json_body(self.request)
        for key, value in body.items():
            self.request.form["form.widgets." + key] = value

        form = CommentForm(self.context, self.request)
        form.update()

        action = form.actions["comment"]
        data, errors = form.extractData()
        if errors:
            raise BadRequest({"errors": [err.error for err in errors]})

        form.handleComment(form=form, action=action)

        fix_location_header(self.context, self.request)
        return self.reply_no_content()
Exemple #41
0
    def reply(self):
        if not self.comment_id:
            raise BadRequest("Comment id is a required part of the url")

        conversation = IConversation(self.context)
        if self.comment_id not in list(conversation):
            self.request.response.setStatus(404)
            return
        comment = conversation[self.comment_id]

        # Permission checks
        if not (edit_comment_allowed() and can_edit(comment)):
            raise Unauthorized()

        # Fake request data
        body = json_body(self.request)
        for key, value in body.items():
            self.request.form["form.widgets." + key] = value

        form = EditCommentForm(comment, self.request)
        form.__parent__ = form.context.__parent__.__parent__
        form.update()

        action = form.actions["comment"]
        data, errors = form.extractData()
        if errors:
            raise BadRequest({"errors": [err.error for err in errors]})

        comment.modification_date = datetime.utcnow()
        form.handleComment(form=form, action=action)

        fix_location_header(self.context, self.request)
        return self.reply_no_content()
    def test_delete_comment(self):
        # Add and remove a comment to a CommentReplies adapter

        # 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 to the conversation
        replies = IReplies(conversation)

        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        new_id = replies.addComment(comment)
        comment = self.portal.doc1.restrictedTraverse(
            '++conversation++default/%s' % new_id)

        # Add a reply to the CommentReplies adapter of the first comment
        re_comment = createObject('plone.Comment')
        re_comment.text = 'Comment text'

        replies = IReplies(comment)

        new_re_id = replies.addComment(re_comment)

        # Remove the reply to the CommentReplies adapter
        del replies[new_re_id]

        # Make sure there is no comment left in CommentReplies
        self.assertEqual(len(replies), 0)

        # Make sure the first comment is still in the conversation
        self.assertEqual(conversation.total_comments, 1)
    def test_add_comment(self):
        # Add comments to a CommentReplies adapter

        # 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 to the conversation
        replies = IReplies(conversation)

        comment = createObject('plone.Comment')
        comment.text = 'Comment text'
        new_id = replies.addComment(comment)
        comment = self.portal.doc1.restrictedTraverse(
            '++conversation++default/{0}'.format(new_id), )

        # Add a reply to the CommentReplies adapter of the first comment
        re_comment = createObject('plone.Comment')
        re_comment.text = 'Comment text'

        replies = IReplies(comment)

        new_re_id = replies.addComment(re_comment)

        # check that replies provides the IReplies interface
        self.assertTrue(IReplies.providedBy(replies))

        # Make sure our comment was added
        self.assertTrue(new_re_id in replies)

        # Make sure it is also reflected in the conversation
        self.assertTrue(new_re_id in conversation)

        # Make sure the conversation has the correct comment id
        self.assertEqual(conversation[new_re_id].comment_id, new_re_id)
Exemple #44
0
    def setUp(self):
        # Setup sandbox
        self.portal = self.layer['portal']
        self.request = self.layer['request']
        setRoles(self.portal, TEST_USER_ID, ['Manager'])

        self.document = self.portal['doc1']
        conversation = IConversation(self.document)
        replies = IReplies(conversation)

        comment = createObject('plone.Comment')
        comment.text = 'This is a comment'
        new_id = replies.addComment(comment)
        comment = self.document.restrictedTraverse(
            '++conversation++default/{0}'.format(new_id)
        )

        re_comment = createObject('plone.Comment')
        re_comment.text = 'This is a reply'
        re_comment.author_username = '******'
        re_comment.author_name = 'Juliana'
        re_comment.author_email = '*****@*****.**'

        replies = IReplies(comment)
        replies.addComment(re_comment)
Exemple #45
0
    def test_move_upper_level_folder(self):
        # create a folder with a nested structure
        self.portal.invokeFactory(id='sourcefolder',
                                  title='Source Folder',
                                  type_name='Folder')
        self.portal.sourcefolder.invokeFactory(id='moveme',
                                               title='Move Me',
                                               type_name='Folder')
        self.portal.sourcefolder.moveme.invokeFactory(id='mydocument',
                                                      title='My Document',
                                                      type_name='Folder')
        self.portal.invokeFactory(id='targetfolder',
                                  title='Target Folder',
                                  type_name='Folder')

        # create comment on my-document
        conversation = IConversation(
            self.portal.sourcefolder.moveme.mydocument
        )
        comment = createObject('plone.Comment')
        comment_id = conversation.addComment(comment)

        # We need to commit here so that _p_jar isn't None and move will work
        transaction.savepoint(optimistic=True)

        # Move moveme from folder1 to folder2
        cp = self.portal.sourcefolder.manage_cutObjects(ids=('moveme',))
        self.portal.targetfolder.manage_pasteObjects(cp)

        # Make sure no old comment brains are left
        brains = self.catalog.searchResults(dict(
            portal_type="Discussion Item",
            path={'query': '/plone/sourcefolder/moveme'}
        ))
        self.assertEqual(len(brains), 0)

        # make sure comments are correctly index on the target
        brains = self.catalog.searchResults(dict(
            portal_type="Discussion Item",
            path={'query': '/plone/targetfolder/moveme'}
        ))
        self.assertEqual(len(brains), 1)
        self.assertEqual(
            brains[0].getPath(),
            '/plone/targetfolder/moveme/mydocument/++conversation++default/' +
            str(comment_id)
        )
Exemple #46
0
    def test_add_comment(self):
        """Post 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"
        )

        # The form should return an error if the comment text field is empty
        request = make_request(form={})

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

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

        # 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"))

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

        comment = comments[0]
        self.assertEqual(comment.text, u"bar")
        self.assertEqual(comment.creator, "test-user")
        self.assertEqual(comment.getOwner().getUserName(), "test-user")
        local_roles = comment.get_local_roles()
        self.assertTrue(('test-user', ('Owner',)) in local_roles) 
Exemple #47
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
Exemple #48
0
 def test_get_commenter_home_url(self):
     comment = createObject('plone.Comment')
     comment.text = 'Comment text'
     IConversation(self.portal.doc1)
     portal_membership = getToolByName(self.portal, 'portal_membership')
     m = portal_membership.getAuthenticatedMember()
     self.assertEqual(self.viewlet.get_commenter_home_url(m.getUserName()),
                      'http://nohost/plone/author/test-user')
Exemple #49
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)
Exemple #50
0
 def get_discussion_count(self):
     try:
         # plone.app.discussion.conversation object
         # fetched via IConversation adapter
         conversation = IConversation(self)
     except Exception:
         return 0
     else:
         return conversation.total_comments
Exemple #51
0
def conclusion_reply_number(context):
    replynum = 0
    conclusions = context.values(['Conclusions'])
    if conclusions:
        conclusion = conclusions[0]
        disc = IConversation(conclusion)
        return disc.total_comments

    return replynum
Exemple #52
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)
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())
    def get_replies(self, workflow_actions=False):
        context = aq_inner(self.context)
        conversation = IConversation(context)
        wf = getToolByName(context, 'portal_workflow')

        def replies_with_workflow_actions():
            # Generator that returns replies dict with workflow actions
            for comment_obj in conversation.getComments():

                # list all possible workflow actions
                actions = [
                    a for a in wf.listActionInfos(object=comment_obj)
                    if a['category'] == 'workflow' and a['allowed']
                ]

                yield {'comment': comment_obj, 'actions': actions}

        if len(conversation.objectIds()) > 0:
            return replies_with_workflow_actions()
Exemple #55
0
    def test_tool_indexing(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.
        comment = createObject('plone.Comment')
        comment.creator = 'Jim'
        comment.text = 'Comment text'

        conversation.addComment(comment)

        # Check that the comment got indexed in the tool:
        tool = queryUtility(ICommentingTool)
        comment = list(tool.searchResults())
        self.assertTrue(
            len(comment) == 1, "There is only one comment, but we got"
            " %s results in the search" % len(comment))
        self.assertEqual(comment[0].Title, 'Jim on Document 1')
 def get_discussion(obj, path):
     conversation = IConversation(obj, None)
     if not conversation:
         return
     serializer = getMultiAdapter((conversation, self.request),
                                  ISerializeToJson)
     output = serializer()
     if output:
         results.append({"uuid": IUUID(obj), "conversation": output})
     return
Exemple #57
0
 def test_get_replies_with_workflow_actions(self):
     self.assertFalse(self.viewlet.get_replies(workflow_actions=True))
     comment = createObject('plone.Comment')
     comment.text = 'Comment text'
     conversation = IConversation(self.portal.doc1)
     c1 = conversation.addComment(comment)
     self.assertEqual(
         len(tuple(self.viewlet.get_replies(workflow_actions=True))), 1)
     # Enable moderation workflow
     self.workflowTool.setChainForPortalTypes(('Discussion Item', ),
                                              ('comment_review_workflow,'))
     # Check if workflow actions are available
     reply = self.viewlet.get_replies(workflow_actions=True).next()
     self.assertTrue('actions' in reply)
     self.assertEqual(reply['actions'][0]['id'], 'publish')
     self.assertEqual(
         reply['actions'][0]['url'],
         'http://nohost/plone/doc1/++conversation++default/%s' % int(c1) +
         '/content_status_modify?workflow_action=publish')
Exemple #58
0
 def reply(self):
     conversation = IConversation(self.context)
     if not self.comment_id:
         serializer = getMultiAdapter((conversation, self.request),
                                      ISerializeToJson)
     else:
         comment = conversation[self.comment_id]
         serializer = getMultiAdapter((comment, self.request),
                                      ISerializeToJson)
     return serializer()
Exemple #59
0
    def test_traversal(self):
        # make sure we can traverse to conversations and get a URL and path

        conversation = self.portal.doc1.restrictedTraverse(
            '++conversation++default')
        self.assertTrue(IConversation.providedBy(conversation))

        self.assertEqual(('', 'plone', 'doc1', '++conversation++default'),
                         conversation.getPhysicalPath())
        self.assertEqual('http://nohost/plone/doc1/++conversation++default',
                         conversation.absolute_url())
Exemple #60
0
    def test_parent(self):
        # Check that conversation has a content object as parent

        # Create a conversation.
        conversation = IConversation(self.portal.doc1)

        # Check the parent
        self.assertTrue(conversation.__parent__)
        self.assertTrue(aq_parent(conversation))

        self.assertEqual(conversation.__parent__.getId(), 'doc1')