2010-08-25 11:19:28 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
2009-06-06 10:23:33 +02:00
|
|
|
import unittest
|
2010-09-07 14:03:18 +02:00
|
|
|
import time
|
2010-07-13 12:45:53 +02:00
|
|
|
from datetime import datetime
|
2009-06-06 10:23:33 +02:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
from AccessControl import Unauthorized
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-07-12 15:47:53 +02:00
|
|
|
from zope.component import createObject, queryUtility
|
2009-06-06 10:23:33 +02:00
|
|
|
|
2009-06-07 22:58:41 +02:00
|
|
|
from OFS.Image import Image
|
|
|
|
|
2010-09-02 22:00:43 +02:00
|
|
|
from zope.interface import alsoProvides
|
|
|
|
from zope.publisher.browser import TestRequest
|
|
|
|
from zope.annotation.interfaces import IAttributeAnnotatable
|
|
|
|
from z3c.form.interfaces import IFormLayer
|
|
|
|
|
|
|
|
from zope.component import provideAdapter
|
|
|
|
from zope.publisher.interfaces.browser import IBrowserRequest
|
|
|
|
|
2010-09-03 23:57:36 +02:00
|
|
|
from zope.interface import Interface
|
2010-09-02 22:00:43 +02:00
|
|
|
from zope.component import getMultiAdapter
|
2010-11-08 18:10:19 +01:00
|
|
|
from zope.component import createObject, queryUtility
|
2010-09-02 22:00:43 +02:00
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
from plone.registry.interfaces import IRegistry
|
|
|
|
|
2009-06-06 10:23:33 +02:00
|
|
|
from Products.CMFCore.utils import getToolByName
|
2010-09-03 22:40:27 +02:00
|
|
|
|
2009-06-07 22:58:41 +02:00
|
|
|
from Products.CMFPlone.tests import dummy
|
2010-09-03 22:40:27 +02:00
|
|
|
|
2009-06-06 10:23:33 +02:00
|
|
|
from Products.PloneTestCase.ptc import PloneTestCase
|
2010-09-03 23:57:36 +02:00
|
|
|
|
2010-07-13 12:45:53 +02:00
|
|
|
from plone.app.discussion.browser.comments import CommentsViewlet
|
2010-09-02 22:00:43 +02:00
|
|
|
from plone.app.discussion.browser.comments import CommentForm
|
2010-12-16 00:52:56 +01:00
|
|
|
from plone.app.discussion.interfaces import IConversation
|
2009-06-06 10:23:33 +02:00
|
|
|
from plone.app.discussion.tests.layer import DiscussionLayer
|
2010-11-08 18:10:19 +01:00
|
|
|
from plone.app.discussion.interfaces import IDiscussionSettings
|
2009-06-06 10:23:33 +02:00
|
|
|
|
|
|
|
|
2010-01-22 13:29:26 +01:00
|
|
|
class TestCommentForm(PloneTestCase):
|
|
|
|
|
|
|
|
layer = DiscussionLayer
|
|
|
|
|
|
|
|
def afterSetUp(self):
|
|
|
|
self.loginAsPortalOwner()
|
|
|
|
typetool = self.portal.portal_types
|
|
|
|
typetool.constructContent('Document', self.portal, 'doc1')
|
2010-12-16 00:52:56 +01:00
|
|
|
self.dtool = getToolByName(self.portal,
|
|
|
|
'portal_discussion',
|
2010-09-03 22:40:27 +02:00
|
|
|
None)
|
|
|
|
self.dtool.overrideDiscussionFor(self.portal.doc1, False)
|
|
|
|
self.mtool = getToolByName(self.folder, 'portal_membership', None)
|
2010-01-22 13:29:26 +01:00
|
|
|
self.memberdata = self.portal.portal_memberdata
|
2010-09-02 22:00:43 +02:00
|
|
|
self.request = self.app.REQUEST
|
|
|
|
self.context = getattr(self.portal, 'doc1')
|
2010-12-14 18:58:46 +01:00
|
|
|
|
|
|
|
# Allow discussion
|
|
|
|
registry = queryUtility(IRegistry)
|
|
|
|
settings = registry.forInterface(IDiscussionSettings)
|
|
|
|
settings.globally_enabled = True
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-02-05 23:40:38 +01:00
|
|
|
def test_add_comment(self):
|
2010-11-08 18:10:19 +01:00
|
|
|
"""Post a comment as logged-in user.
|
|
|
|
"""
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
# Allow discussion
|
|
|
|
self.dtool.overrideDiscussionFor(self.portal.doc1, True)
|
|
|
|
self.viewlet = CommentsViewlet(self.context, self.request, None, None)
|
2010-09-02 22:00:43 +02:00
|
|
|
|
|
|
|
def make_request(form={}):
|
|
|
|
request = TestRequest()
|
|
|
|
request.form.update(form)
|
|
|
|
alsoProvides(request, IFormLayer)
|
|
|
|
alsoProvides(request, IAttributeAnnotatable)
|
|
|
|
return request
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-02 22:00:43 +02:00
|
|
|
provideAdapter(adapts=(Interface, IBrowserRequest),
|
|
|
|
provides=Interface,
|
|
|
|
factory=CommentForm,
|
|
|
|
name=u"comment-form")
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
# The form should return an error if the comment text field is empty
|
2010-09-29 09:56:36 +02:00
|
|
|
request = make_request(form={})
|
2010-09-02 22:00:43 +02:00
|
|
|
|
2010-12-16 00:52:56 +01:00
|
|
|
commentForm = getMultiAdapter((self.context, request),
|
2010-09-02 22:52:33 +02:00
|
|
|
name=u"comment-form")
|
2010-09-02 22:00:43 +02:00
|
|
|
commentForm.update()
|
2010-12-16 00:52:56 +01:00
|
|
|
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
|
|
|
|
2010-09-02 22:00:43 +02:00
|
|
|
self.assertEquals(len(errors), 1)
|
2010-09-03 22:40:27 +02:00
|
|
|
self.failIf(commentForm.handleComment(commentForm, "foo"))
|
2010-12-16 00:52:56 +01:00
|
|
|
|
|
|
|
# The form is submitted successfully, if the required text field is
|
2010-09-03 22:40:27 +02:00
|
|
|
# filled out
|
2010-09-29 09:56:36 +02:00
|
|
|
request = make_request(form={'form.widgets.text': u'bar'})
|
2010-09-03 22:40:27 +02:00
|
|
|
|
2010-12-16 00:52:56 +01:00
|
|
|
commentForm = getMultiAdapter((self.context, request),
|
2010-09-03 22:40:27 +02:00
|
|
|
name=u"comment-form")
|
|
|
|
commentForm.update()
|
2010-12-16 00:52:56 +01:00
|
|
|
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
2010-09-06 12:40:06 +02:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
self.assertEquals(len(errors), 0)
|
|
|
|
self.failIf(commentForm.handleComment(commentForm, "foo"))
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-11-08 18:10:19 +01:00
|
|
|
def test_add_anonymous_comment(self):
|
|
|
|
"""Add a comment as anonymous.
|
|
|
|
"""
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-11-08 18:10:19 +01:00
|
|
|
# Allow discussion
|
|
|
|
self.dtool.overrideDiscussionFor(self.portal.doc1, True)
|
|
|
|
self.viewlet = CommentsViewlet(self.context, self.request, None, None)
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-11-08 18:10:19 +01:00
|
|
|
registry = queryUtility(IRegistry)
|
|
|
|
settings = registry.forInterface(IDiscussionSettings, check=False)
|
|
|
|
settings.anonymous_comments = True
|
|
|
|
|
|
|
|
# Logout
|
|
|
|
self.logout()
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-11-08 18:10:19 +01:00
|
|
|
def make_request(form={}):
|
|
|
|
request = TestRequest()
|
|
|
|
request.form.update(form)
|
|
|
|
alsoProvides(request, IFormLayer)
|
|
|
|
alsoProvides(request, IAttributeAnnotatable)
|
|
|
|
return request
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-11-08 18:10:19 +01:00
|
|
|
provideAdapter(adapts=(Interface, IBrowserRequest),
|
|
|
|
provides=Interface,
|
|
|
|
factory=CommentForm,
|
|
|
|
name=u"comment-form")
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-11-08 18:10:19 +01:00
|
|
|
# Post an anonymous comment and provide a name
|
|
|
|
request = make_request(form={'form.widgets.name': u'john doe',
|
|
|
|
'form.widgets.text': u'bar'})
|
|
|
|
|
2010-12-16 00:52:56 +01:00
|
|
|
commentForm = getMultiAdapter((self.context, request),
|
2010-11-08 18:10:19 +01:00
|
|
|
name=u"comment-form")
|
|
|
|
commentForm.update()
|
2010-12-16 00:52:56 +01:00
|
|
|
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
2010-11-08 18:10:19 +01:00
|
|
|
|
|
|
|
self.assertEquals(len(errors), 0)
|
|
|
|
self.failIf(commentForm.handleComment(commentForm, "action"))
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
def test_can_not_add_comments_if_discussion_is_not_allowed(self):
|
|
|
|
"""Make sure that comments can't be posted if discussion is disabled.
|
|
|
|
"""
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
# Discussion is disabled by default
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
def make_request(form={}):
|
|
|
|
request = TestRequest()
|
|
|
|
request.form.update(form)
|
|
|
|
alsoProvides(request, IFormLayer)
|
|
|
|
alsoProvides(request, IAttributeAnnotatable)
|
|
|
|
return request
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
provideAdapter(adapts=(Interface, IBrowserRequest),
|
|
|
|
provides=Interface,
|
|
|
|
factory=CommentForm,
|
|
|
|
name=u"comment-form")
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-10-03 21:41:02 +02:00
|
|
|
request = make_request(form={'form.widgets.text': u'bar'})
|
2010-09-02 22:00:43 +02:00
|
|
|
|
2010-12-16 00:52:56 +01:00
|
|
|
commentForm = getMultiAdapter((self.context, request),
|
2010-09-02 22:52:33 +02:00
|
|
|
name=u"comment-form")
|
2010-09-02 22:00:43 +02:00
|
|
|
commentForm.update()
|
2010-12-16 00:52:56 +01:00
|
|
|
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
# No form errors, but raise unauthorized because discussion is not
|
|
|
|
# allowed
|
2010-09-02 22:00:43 +02:00
|
|
|
self.assertEquals(len(errors), 0)
|
2010-09-03 22:40:27 +02:00
|
|
|
self.assertRaises(Unauthorized,
|
|
|
|
commentForm.handleComment,
|
|
|
|
commentForm,
|
|
|
|
"foo")
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-11-08 18:10:19 +01:00
|
|
|
def test_anonymous_can_not_add_comments_if_discussion_is_not_allowed(self):
|
2010-09-03 22:40:27 +02:00
|
|
|
"""Make sure that anonymous users can't post comments if anonymous
|
|
|
|
comments are disabled.
|
|
|
|
"""
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
# Anonymous comments are disabled by default
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
self.logout()
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
def make_request(form={}):
|
|
|
|
request = TestRequest()
|
|
|
|
request.form.update(form)
|
|
|
|
alsoProvides(request, IFormLayer)
|
|
|
|
alsoProvides(request, IAttributeAnnotatable)
|
|
|
|
return request
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
provideAdapter(adapts=(Interface, IBrowserRequest),
|
|
|
|
provides=Interface,
|
|
|
|
factory=CommentForm,
|
|
|
|
name=u"comment-form")
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-10-03 21:41:02 +02:00
|
|
|
request = make_request(form={'form.widgets.text': u'bar'})
|
2010-09-03 22:40:27 +02:00
|
|
|
|
2010-12-16 00:52:56 +01:00
|
|
|
commentForm = getMultiAdapter((self.context, request),
|
2010-09-03 22:40:27 +02:00
|
|
|
name=u"comment-form")
|
|
|
|
commentForm.update()
|
2010-12-16 00:52:56 +01:00
|
|
|
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
|
|
|
|
2010-09-03 22:40:27 +02:00
|
|
|
self.assertEquals(len(errors), 0)
|
|
|
|
self.assertRaises(Unauthorized,
|
|
|
|
commentForm.handleComment,
|
|
|
|
commentForm,
|
|
|
|
"foo")
|
2010-09-02 22:00:43 +02:00
|
|
|
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
class TestCommentsViewlet(PloneTestCase):
|
2009-06-06 10:23:33 +02:00
|
|
|
|
|
|
|
layer = DiscussionLayer
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2009-06-06 10:23:33 +02:00
|
|
|
def afterSetUp(self):
|
|
|
|
self.loginAsPortalOwner()
|
|
|
|
typetool = self.portal.portal_types
|
|
|
|
typetool.constructContent('Document', self.portal, 'doc1')
|
2010-12-16 00:52:56 +01:00
|
|
|
self.portal_discussion = getToolByName(self.portal,
|
|
|
|
'portal_discussion',
|
2010-08-28 19:06:53 +02:00
|
|
|
None)
|
2010-09-03 22:40:27 +02:00
|
|
|
self.mtool = getToolByName(self.folder, 'portal_membership')
|
2009-06-07 22:58:41 +02:00
|
|
|
self.memberdata = self.portal.portal_memberdata
|
2009-06-06 10:23:33 +02:00
|
|
|
request = self.app.REQUEST
|
|
|
|
context = getattr(self.portal, 'doc1')
|
|
|
|
self.viewlet = CommentsViewlet(context, request, None, None)
|
2010-01-22 13:29:26 +01:00
|
|
|
|
2010-12-14 18:58:46 +01:00
|
|
|
# Allow discussion
|
|
|
|
registry = queryUtility(IRegistry)
|
|
|
|
settings = registry.forInterface(IDiscussionSettings)
|
|
|
|
settings.globally_enabled = True
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-08-25 11:19:28 +02:00
|
|
|
def test_cook(self):
|
|
|
|
text = """First paragraph
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-08-25 11:19:28 +02:00
|
|
|
Second paragraph"""
|
|
|
|
self.assertEquals(self.viewlet.cook(text),
|
2010-12-16 00:52:56 +01:00
|
|
|
"<p>First paragraph<br /><br /> Second paragraph</p>")
|
2010-08-25 11:19:28 +02:00
|
|
|
|
|
|
|
def test_cook_no_html(self):
|
|
|
|
text = """<b>Got HTML?</b>"""
|
|
|
|
self.assertEquals(self.viewlet.cook(text),
|
|
|
|
"<p><b>Got HTML?</b></p>")
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-08-25 11:19:28 +02:00
|
|
|
def test_cook_with_no_ascii_characters(self):
|
|
|
|
text = """Umlaute sind ä, ö und ü."""
|
2010-12-16 00:52:56 +01:00
|
|
|
self.assertEquals(self.viewlet.cook(text),
|
2010-08-28 19:06:53 +02:00
|
|
|
"<p>Umlaute sind \xc3\xa4, \xc3\xb6 und \xc3\xbc.</p>")
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-08-25 11:19:28 +02:00
|
|
|
def test_cook_links(self):
|
|
|
|
text = "Go to http://www.plone.org"
|
2010-12-16 00:52:56 +01:00
|
|
|
self.assertEquals(self.viewlet.cook(text),
|
2010-08-25 11:19:28 +02:00
|
|
|
"<p>Go to http://www.plone.org</p>")
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
def test_can_reply(self):
|
2010-01-18 12:04:08 +01:00
|
|
|
# Portal owner can reply
|
2010-01-18 10:55:44 +01:00
|
|
|
self.failUnless(self.viewlet.can_reply())
|
2010-01-18 12:04:08 +01:00
|
|
|
self.logout()
|
|
|
|
# Anonymous users can not reply
|
|
|
|
self.failIf(self.viewlet.can_reply())
|
2010-01-18 10:55:44 +01:00
|
|
|
|
2010-10-06 15:55:57 +02:00
|
|
|
def test_can_review(self):
|
|
|
|
# Portal owner has 'can review' permission
|
|
|
|
self.failUnless(self.viewlet.can_review())
|
2010-01-18 12:04:08 +01:00
|
|
|
self.logout()
|
2010-10-06 15:55:57 +02:00
|
|
|
# Anonymous has no 'can review' permission
|
|
|
|
self.failIf(self.viewlet.can_review())
|
|
|
|
# The reviewer role has the 'Review comments' permission
|
|
|
|
self.portal.acl_users._doAddUser('reviewer', 'secret', ['Reviewer'], [])
|
|
|
|
self.login('reviewer')
|
2010-12-16 00:52:56 +01:00
|
|
|
self.failUnless(self.viewlet.can_review())
|
2010-11-03 12:26:18 +01:00
|
|
|
|
|
|
|
def test_can_manage(self):
|
|
|
|
"""We keep this method for backward compatibility. This method has been
|
|
|
|
removed in version 1.0b9 and added again in 1.0b11 because we don't
|
|
|
|
do API changes in beta releases.
|
|
|
|
"""
|
|
|
|
# Portal owner has 'can review' permission
|
|
|
|
self.failUnless(self.viewlet.can_manage())
|
|
|
|
self.logout()
|
|
|
|
# Anonymous has no 'can review' permission
|
|
|
|
self.failIf(self.viewlet.can_manage())
|
|
|
|
# The reviewer role has the 'Review comments' permission
|
|
|
|
self.portal.acl_users._doAddUser('reviewer', 'secret', ['Reviewer'], [])
|
|
|
|
self.login('reviewer')
|
2010-12-16 00:52:56 +01:00
|
|
|
self.failUnless(self.viewlet.can_manage())
|
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
def test_is_discussion_allowed(self):
|
2010-01-18 12:04:08 +01:00
|
|
|
# By default, discussion is disabled
|
|
|
|
self.failIf(self.viewlet.is_discussion_allowed())
|
|
|
|
# Enable discussion
|
|
|
|
portal_discussion = getToolByName(self.portal, 'portal_discussion')
|
|
|
|
portal_discussion.overrideDiscussionFor(self.portal.doc1, True)
|
|
|
|
# Test if discussion has been enabled
|
|
|
|
self.failUnless(self.viewlet.is_discussion_allowed())
|
2010-11-29 23:42:20 +01:00
|
|
|
|
|
|
|
def test_comment_transform_message(self):
|
2011-01-07 11:20:24 +01:00
|
|
|
|
|
|
|
# Default transform is plain/text and comment moderation disabled
|
2010-11-29 23:42:20 +01:00
|
|
|
self.failUnless(self.viewlet.comment_transform_message())
|
|
|
|
self.assertEquals(
|
|
|
|
self.viewlet.comment_transform_message(),
|
|
|
|
"You can add a comment by filling out the form below. Plain text " +
|
|
|
|
"formatting.")
|
|
|
|
|
|
|
|
# Set text transform to intelligent text
|
|
|
|
registry = queryUtility(IRegistry)
|
|
|
|
settings = registry.forInterface(IDiscussionSettings, check=False)
|
|
|
|
settings.text_transform = "text/x-web-intelligent"
|
|
|
|
|
2011-01-07 11:20:24 +01:00
|
|
|
# Make sure the comment description changes accordingly
|
2010-11-29 23:42:20 +01:00
|
|
|
self.assertEquals(
|
2010-12-16 00:52:56 +01:00
|
|
|
self.viewlet.comment_transform_message(),
|
2010-11-29 23:42:20 +01:00
|
|
|
"You can add a comment by filling out the form below. " +
|
|
|
|
"Plain text formatting. Web and email addresses are transformed " +
|
|
|
|
"into clickable links.")
|
2011-01-07 11:20:24 +01:00
|
|
|
|
|
|
|
# Enable moderation workflow
|
|
|
|
self.portal.portal_workflow.setChainForPortalTypes(
|
|
|
|
('Discussion Item',),
|
|
|
|
('comment_review_workflow,'))
|
|
|
|
|
|
|
|
# Make sure the comment description shows that comments are moderated
|
|
|
|
self.assertEquals(
|
|
|
|
self.viewlet.comment_transform_message(),
|
|
|
|
"You can add a comment by filling out the form below. " +
|
|
|
|
"Plain text formatting. Web and email addresses are transformed " +
|
|
|
|
"into clickable links. Comments are moderated.")
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-01-18 12:38:57 +01:00
|
|
|
def test_has_replies(self):
|
2010-01-22 20:02:41 +01:00
|
|
|
self.assertEquals(self.viewlet.has_replies(), False)
|
2010-01-18 12:04:08 +01:00
|
|
|
comment = createObject('plone.Comment')
|
|
|
|
comment.text = 'Comment text'
|
|
|
|
conversation = IConversation(self.portal.doc1)
|
|
|
|
conversation.addComment(comment)
|
2010-01-22 20:02:41 +01:00
|
|
|
self.assertEquals(self.viewlet.has_replies(), True)
|
2010-01-22 13:29:26 +01:00
|
|
|
|
2010-01-18 12:38:57 +01:00
|
|
|
def test_get_replies(self):
|
2010-01-18 12:04:08 +01:00
|
|
|
self.failIf(self.viewlet.get_replies())
|
|
|
|
comment = createObject('plone.Comment')
|
|
|
|
comment.text = 'Comment text'
|
|
|
|
conversation = IConversation(self.portal.doc1)
|
|
|
|
conversation.addComment(comment)
|
|
|
|
conversation.addComment(comment)
|
2010-01-18 13:20:45 +01:00
|
|
|
replies = self.viewlet.get_replies()
|
2010-12-16 00:52:56 +01:00
|
|
|
self.assertEquals(len(tuple(replies)), 2)
|
2010-01-18 13:20:45 +01:00
|
|
|
replies = self.viewlet.get_replies()
|
|
|
|
replies.next()
|
|
|
|
replies.next()
|
|
|
|
self.assertRaises(StopIteration, replies.next)
|
2010-01-18 12:04:08 +01:00
|
|
|
|
2010-01-18 12:38:57 +01:00
|
|
|
def test_get_replies_with_workflow_actions(self):
|
|
|
|
self.failIf(self.viewlet.get_replies(workflow_actions=True))
|
|
|
|
comment = createObject('plone.Comment')
|
|
|
|
comment.text = 'Comment text'
|
|
|
|
conversation = IConversation(self.portal.doc1)
|
|
|
|
c1 = conversation.addComment(comment)
|
2010-10-30 20:58:20 +02:00
|
|
|
self.assertEquals(
|
2010-12-16 00:52:56 +01:00
|
|
|
len(tuple(self.viewlet.get_replies(workflow_actions=True))), 1)
|
2010-01-18 12:38:57 +01:00
|
|
|
# Enable moderation workflow
|
2010-08-28 19:06:53 +02:00
|
|
|
self.portal.portal_workflow.setChainForPortalTypes(
|
|
|
|
('Discussion Item',),
|
2010-10-08 13:03:14 +02:00
|
|
|
('comment_review_workflow,'))
|
2010-01-18 12:38:57 +01:00
|
|
|
# Check if workflow actions are available
|
|
|
|
reply = self.viewlet.get_replies(workflow_actions=True).next()
|
|
|
|
self.failUnless(reply.has_key('actions'))
|
|
|
|
self.assertEquals(reply['actions'][0]['id'],
|
|
|
|
'publish')
|
|
|
|
self.assertEquals(reply['actions'][0]['url'],
|
2010-08-28 19:06:53 +02:00
|
|
|
'http://nohost/plone/doc1/++conversation++default/%s' % int(c1) +
|
2010-12-16 00:52:56 +01:00
|
|
|
'/content_status_modify?workflow_action=publish')
|
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
def test_get_commenter_home_url(self):
|
2010-01-18 12:04:08 +01:00
|
|
|
comment = createObject('plone.Comment')
|
|
|
|
comment.text = 'Comment text'
|
2010-07-13 12:45:53 +02:00
|
|
|
IConversation(self.portal.doc1)
|
2010-01-18 12:04:08 +01:00
|
|
|
portal_membership = getToolByName(self.portal, 'portal_membership')
|
|
|
|
m = portal_membership.getAuthenticatedMember()
|
|
|
|
self.assertEquals(self.viewlet.get_commenter_home_url(m.getUserName()),
|
|
|
|
'http://nohost/plone/author/portal_owner')
|
2010-01-18 12:38:57 +01:00
|
|
|
|
|
|
|
def test_get_commenter_home_url_is_none(self):
|
|
|
|
self.failIf(self.viewlet.get_commenter_home_url())
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2009-06-06 10:23:33 +02:00
|
|
|
def test_get_commenter_portrait(self):
|
2009-06-07 22:58:41 +02:00
|
|
|
|
|
|
|
# Add a user with a member image
|
2010-09-03 22:40:27 +02:00
|
|
|
self.mtool.addMember('jim', 'Jim', ['Member'], [])
|
2010-12-16 00:52:56 +01:00
|
|
|
self.memberdata._setPortrait(Image(id='jim',
|
2010-08-28 19:06:53 +02:00
|
|
|
file=dummy.File(),
|
|
|
|
title=''), 'jim')
|
2010-12-16 00:52:56 +01:00
|
|
|
self.assertEqual(self.memberdata._getPortrait('jim').getId(),
|
2010-08-28 19:06:53 +02:00
|
|
|
'jim')
|
2010-12-16 00:52:56 +01:00
|
|
|
self.assertEqual(self.memberdata._getPortrait('jim').meta_type,
|
2010-08-28 19:06:53 +02:00
|
|
|
'Image')
|
2009-06-07 22:58:41 +02:00
|
|
|
|
|
|
|
# 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 = 'jim'
|
2010-07-13 12:45:53 +02:00
|
|
|
conversation.addComment(comment)
|
2009-06-07 22:58:41 +02:00
|
|
|
|
|
|
|
# Call get_commenter_portrait method of the viewlet
|
2009-06-06 10:23:33 +02:00
|
|
|
self.viewlet.update()
|
2009-06-15 10:54:35 +02:00
|
|
|
portrait_url = self.viewlet.get_commenter_portrait('jim')
|
2009-06-07 22:58:41 +02:00
|
|
|
|
2009-06-15 10:54:35 +02:00
|
|
|
# Check if the correct member image URL is returned
|
2010-12-16 00:52:56 +01:00
|
|
|
self.assertEquals(portrait_url,
|
2010-08-28 19:06:53 +02:00
|
|
|
'http://nohost/plone/portal_memberdata/portraits/jim')
|
2009-06-06 10:23:33 +02:00
|
|
|
|
2010-01-18 12:38:57 +01:00
|
|
|
def test_get_commenter_portrait_is_none(self):
|
2010-12-16 00:52:56 +01:00
|
|
|
self.assertEquals(self.viewlet.get_commenter_portrait(),
|
2010-01-18 12:38:57 +01:00
|
|
|
'defaultUser.gif')
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2009-06-06 10:23:33 +02:00
|
|
|
def test_get_commenter_portrait_without_userimage(self):
|
2009-06-07 22:58:41 +02:00
|
|
|
|
2009-06-06 10:23:33 +02:00
|
|
|
# Create a user without a user image
|
2010-09-03 22:40:27 +02:00
|
|
|
self.mtool.addMember('jim', 'Jim', ['Member'], [])
|
2009-06-07 22:58:41 +02:00
|
|
|
|
|
|
|
# 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 = 'jim'
|
2010-07-13 12:45:53 +02:00
|
|
|
conversation.addComment(comment)
|
2009-06-07 22:58:41 +02:00
|
|
|
|
|
|
|
# Call get_commenter_portrait method of the viewlet
|
|
|
|
self.viewlet.update()
|
2009-06-15 10:54:35 +02:00
|
|
|
portrait_url = self.viewlet.get_commenter_portrait('jim')
|
2009-06-07 22:58:41 +02:00
|
|
|
|
2011-03-09 04:03:17 +01:00
|
|
|
# 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.failUnless(portrait_url in
|
|
|
|
('http://nohost/plone/defaultUser.png',
|
|
|
|
'http://nohost/plone/defaultUser.gif'))
|
2009-06-06 10:23:33 +02:00
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
def test_anonymous_discussion_allowed(self):
|
|
|
|
# Anonymous discussion is not allowed by default
|
|
|
|
self.failIf(self.viewlet.anonymous_discussion_allowed())
|
|
|
|
# Allow anonymous discussion
|
2010-07-12 15:47:53 +02:00
|
|
|
registry = queryUtility(IRegistry)
|
2010-08-28 19:06:53 +02:00
|
|
|
registry['plone.app.discussion.interfaces.IDiscussionSettings.' +
|
|
|
|
'anonymous_comments'] = True
|
2010-01-18 10:55:44 +01:00
|
|
|
# Test if anonymous discussion is allowed for the viewlet
|
|
|
|
self.failUnless(self.viewlet.anonymous_discussion_allowed())
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
def test_show_commenter_image(self):
|
|
|
|
self.failUnless(self.viewlet.show_commenter_image())
|
2010-07-12 15:47:53 +02:00
|
|
|
registry = queryUtility(IRegistry)
|
2010-08-28 19:06:53 +02:00
|
|
|
registry['plone.app.discussion.interfaces.IDiscussionSettings.' +
|
2010-12-16 00:52:56 +01:00
|
|
|
'show_commenter_image'] = False
|
2010-01-18 12:04:08 +01:00
|
|
|
self.failIf(self.viewlet.show_commenter_image())
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
def test_is_anonymous(self):
|
2010-01-18 12:04:08 +01:00
|
|
|
self.failIf(self.viewlet.is_anonymous())
|
|
|
|
self.logout()
|
|
|
|
self.failUnless(self.viewlet.is_anonymous())
|
2009-06-06 10:23:33 +02:00
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
def test_login_action(self):
|
2010-01-18 12:04:08 +01:00
|
|
|
self.viewlet.update()
|
|
|
|
self.assertEquals(self.viewlet.login_action(),
|
2010-12-16 00:52:56 +01:00
|
|
|
'http://nohost/plone/login_form?came_from=http%3A//nohost')
|
|
|
|
|
2010-01-18 10:55:44 +01:00
|
|
|
def test_format_time(self):
|
|
|
|
python_time = datetime(2009, 02, 01, 23, 32, 03, 57)
|
2010-09-07 14:03:18 +02:00
|
|
|
# Python Time must be utc time. There seems to be no too simple way
|
|
|
|
# to tell datetime to be of utc time.
|
|
|
|
# therefor, we convert the time to seconds since epoch, which seems
|
|
|
|
# to assume, that the datetime was given in local time, and does the
|
|
|
|
# correction to the seconds since epoch. Then time.gmtime returns
|
|
|
|
# a correct utc time that can be used to make datetime set the utc
|
|
|
|
# time of the local time given above. That way, the time for the
|
|
|
|
# example below is correct within each time zone, independent of DST
|
2010-10-06 10:47:24 +02:00
|
|
|
python_time = datetime(
|
|
|
|
*time.gmtime(time.mktime(python_time.timetuple()))[:7])
|
2010-01-18 10:55:44 +01:00
|
|
|
localized_time = self.viewlet.format_time(python_time)
|
|
|
|
self.assertEquals(localized_time, "Feb 01, 2009 11:32 PM")
|
2009-06-06 10:23:33 +02:00
|
|
|
|
2010-12-16 00:52:56 +01:00
|
|
|
|
2009-06-06 10:23:33 +02:00
|
|
|
def test_suite():
|
2010-08-28 19:06:53 +02:00
|
|
|
return unittest.defaultTestLoader.loadTestsFromName(__name__)
|