This commit is contained in:
Timo Stollenwerk 2013-04-17 19:27:30 +02:00
parent 943065c15f
commit b4c22e90bf
2 changed files with 199 additions and 102 deletions

View File

@ -31,65 +31,100 @@ class RegistryTest(unittest.TestCase):
self.assertTrue(registry.forInterface(IDiscussionSettings)) self.assertTrue(registry.forInterface(IDiscussionSettings))
def test_discussion_controlpanel_view(self): def test_discussion_controlpanel_view(self):
view = getMultiAdapter((self.portal, self.portal.REQUEST), view = getMultiAdapter(
name="discussion-settings") (self.portal, self.portal.REQUEST),
name="discussion-settings"
)
view = view.__of__(self.portal) view = view.__of__(self.portal)
self.assertTrue(view()) self.assertTrue(view())
def test_discussion_in_controlpanel(self): def test_discussion_in_controlpanel(self):
# Check if discussion is in the control panel # Check if discussion is in the control panel
self.controlpanel = getToolByName(self.portal, "portal_controlpanel") self.controlpanel = getToolByName(self.portal, "portal_controlpanel")
self.assertTrue('discussion' in [a.getAction(self)['id'] self.assertTrue(
for a in self.controlpanel.listActions()]) 'discussion' in [
a.getAction(self)['id']
for a in self.controlpanel.listActions()
]
)
def test_globally_enabled(self): def test_globally_enabled(self):
# Check globally_enabled record # Check globally_enabled record
self.assertTrue('globally_enabled' in IDiscussionSettings) self.assertTrue('globally_enabled' in IDiscussionSettings)
self.assertEqual( self.assertEqual(
self.registry['plone.app.discussion.interfaces.' + self.registry[
'IDiscussionSettings.globally_enabled'], 'plone.app.discussion.interfaces.' +
False) 'IDiscussionSettings.globally_enabled'
],
False
)
def test_anonymous_comments(self): def test_anonymous_comments(self):
# Check anonymous_comments record # Check anonymous_comments record
self.assertTrue('anonymous_comments' in IDiscussionSettings) self.assertTrue('anonymous_comments' in IDiscussionSettings)
self.assertEqual(self.registry['plone.app.discussion.interfaces.' + self.assertEqual(
'IDiscussionSettings.anonymous_comments'], False) self.registry[
'plone.app.discussion.interfaces.' +
'IDiscussionSettings.anonymous_comments'
],
False
)
def test_moderation_enabled(self): def test_moderation_enabled(self):
# Check globally_enabled record # Check globally_enabled record
self.assertTrue('moderation_enabled' in IDiscussionSettings) self.assertTrue('moderation_enabled' in IDiscussionSettings)
self.assertEqual( self.assertEqual(
self.registry['plone.app.discussion.interfaces.' + self.registry[
'IDiscussionSettings.moderation_enabled'], 'plone.app.discussion.interfaces.' +
False) 'IDiscussionSettings.moderation_enabled'
],
False
)
def test_text_transform(self): def test_text_transform(self):
self.assertTrue('text_transform' in IDiscussionSettings) self.assertTrue('text_transform' in IDiscussionSettings)
self.assertEqual( self.assertEqual(
self.registry['plone.app.discussion.interfaces.' + self.registry[
'IDiscussionSettings.text_transform'], 'plone.app.discussion.interfaces.' +
'text/plain') 'IDiscussionSettings.text_transform'
],
'text/plain'
)
def test_captcha(self): def test_captcha(self):
# Check globally_enabled record # Check globally_enabled record
self.assertTrue('captcha' in IDiscussionSettings) self.assertTrue('captcha' in IDiscussionSettings)
self.assertEqual(self.registry['plone.app.discussion.interfaces.' + self.assertEqual(
'IDiscussionSettings.captcha'], self.registry[
'disabled') 'plone.app.discussion.interfaces.' +
'IDiscussionSettings.captcha'
],
'disabled'
)
def test_show_commenter_image(self): def test_show_commenter_image(self):
# Check show_commenter_image record # Check show_commenter_image record
self.assertTrue('show_commenter_image' in IDiscussionSettings) self.assertTrue('show_commenter_image' in IDiscussionSettings)
self.assertEqual(self.registry['plone.app.discussion.interfaces.' + self.assertEqual(
'IDiscussionSettings.show_commenter_image'], True) self.registry[
'plone.app.discussion.interfaces.' +
'IDiscussionSettings.show_commenter_image'
],
True
)
def test_moderator_notification_enabled(self): def test_moderator_notification_enabled(self):
# Check show_commenter_image record # Check show_commenter_image record
self.assertTrue('moderator_notification_enabled' in self.assertTrue(
IDiscussionSettings) 'moderator_notification_enabled' in IDiscussionSettings
self.assertEqual(self.registry['plone.app.discussion.interfaces.' + )
'IDiscussionSettings.moderator_notification_enabled'], False) self.assertEqual(
self.registry[
'plone.app.discussion.interfaces.' +
'IDiscussionSettings.moderator_notification_enabled'
],
False
)
#def test_user_notification_enabled(self): #def test_user_notification_enabled(self):
# # Check show_commenter_image record # # Check show_commenter_image record
@ -117,23 +152,32 @@ class ConfigurationChangedSubscriberTest(unittest.TestCase):
changes. changes.
""" """
# By default the one_state_workflow without moderation is enabled # By default the one_state_workflow without moderation is enabled
self.assertEqual(('one_state_workflow',), self.assertEqual(
self.portal.portal_workflow.getChainForPortalType( ('one_state_workflow',),
'Discussion Item')) self.portal.portal_workflow.getChainForPortalType(
'Discussion Item'
)
)
# Enable moderation in the discussion control panel # Enable moderation in the discussion control panel
self.settings.moderation_enabled = True self.settings.moderation_enabled = True
# Make sure the comment_review_workflow with moderation enabled is # Make sure the comment_review_workflow with moderation enabled is
# enabled # enabled
self.assertEqual(('comment_review_workflow',), self.assertEqual(
self.portal.portal_workflow.getChainForPortalType( ('comment_review_workflow',),
'Discussion Item')) self.portal.portal_workflow.getChainForPortalType(
'Discussion Item'
)
)
# And back # And back
self.settings.moderation_enabled = False self.settings.moderation_enabled = False
self.assertEqual(('one_state_workflow',), self.assertEqual(
self.portal.portal_workflow.getChainForPortalType( ('one_state_workflow',),
'Discussion Item')) self.portal.portal_workflow.getChainForPortalType(
'Discussion Item'
)
)
def test_change_workflow_in_types_control_panel(self): def test_change_workflow_in_types_control_panel(self):
"""Make sure the setting in the discussion control panel is changed """Make sure the setting in the discussion control panel is changed
@ -146,7 +190,8 @@ class ConfigurationChangedSubscriberTest(unittest.TestCase):
# Enable the 'comment_review_workflow' with moderation enabled # Enable the 'comment_review_workflow' with moderation enabled
self.portal.portal_workflow.setChainForPortalTypes( self.portal.portal_workflow.setChainForPortalTypes(
('Discussion Item',), ('Discussion Item',),
('comment_review_workflow',)) ('comment_review_workflow',)
)
# Make sure the moderation_enabled settings has changed # Make sure the moderation_enabled settings has changed
self.settings.moderation_enabled = True self.settings.moderation_enabled = True
@ -154,13 +199,15 @@ class ConfigurationChangedSubscriberTest(unittest.TestCase):
# Enable the 'comment_review_workflow' with moderation enabled # Enable the 'comment_review_workflow' with moderation enabled
self.portal.portal_workflow.setChainForPortalTypes( self.portal.portal_workflow.setChainForPortalTypes(
('Discussion Item',), ('Discussion Item',),
('one_state_workflow',)) ('one_state_workflow',)
)
self.settings.moderation_enabled = True self.settings.moderation_enabled = True
# Enable a 'custom' discussion workflow # Enable a 'custom' discussion workflow
self.portal.portal_workflow.setChainForPortalTypes( self.portal.portal_workflow.setChainForPortalTypes(
('Discussion Item',), ('Discussion Item',),
('intranet_workflow',)) ('intranet_workflow',)
)
# Setting has not changed. A Custom workflow disables the # Setting has not changed. A Custom workflow disables the
# enable_moderation checkbox in the discussion control panel. The # enable_moderation checkbox in the discussion control panel. The

View File

@ -15,8 +15,9 @@ from Products.CMFCore.utils import getToolByName
from plone.app.testing import TEST_USER_ID, setRoles from plone.app.testing import TEST_USER_ID, setRoles
from plone.app.discussion.testing import \ from plone.app.discussion.testing import (
PLONE_APP_DISCUSSION_INTEGRATION_TESTING PLONE_APP_DISCUSSION_INTEGRATION_TESTING
)
from plone.app.discussion import interfaces from plone.app.discussion import interfaces
from plone.app.discussion.interfaces import IConversation from plone.app.discussion.interfaces import IConversation
@ -25,7 +26,7 @@ from plone.app.discussion.interfaces import IReplies
from plone.app.discussion.interfaces import IDiscussionSettings from plone.app.discussion.interfaces import IDiscussionSettings
try: try:
import plone.dexterity from plone.dexterity.interfaces import IDexterityContent
DEXTERITY = True DEXTERITY = True
except: except:
DEXTERITY = False DEXTERITY = False
@ -44,9 +45,11 @@ class ConversationTest(unittest.TestCase):
typetool = self.portal.portal_types typetool = self.portal.portal_types
typetool.constructContent('Document', self.portal, 'doc1') typetool.constructContent('Document', self.portal, 'doc1')
self.typetool = typetool self.typetool = typetool
self.portal_discussion = getToolByName(self.portal, self.portal_discussion = getToolByName(
'portal_discussion', self.portal,
None) 'portal_discussion',
None,
)
# Allow discussion # Allow discussion
registry = queryUtility(IRegistry) registry = queryUtility(IRegistry)
settings = registry.forInterface(IDiscussionSettings) settings = registry.forInterface(IDiscussionSettings)
@ -68,14 +71,18 @@ class ConversationTest(unittest.TestCase):
# Check that the conversation methods return the correct data # Check that the conversation methods return the correct data
self.assertTrue(isinstance(comment.comment_id, long)) self.assertTrue(isinstance(comment.comment_id, long))
self.assertTrue(IComment.providedBy(conversation[new_id])) self.assertTrue(IComment.providedBy(conversation[new_id]))
self.assertEqual(aq_base(conversation[new_id].__parent__), self.assertEqual(
aq_base(conversation)) aq_base(conversation[new_id].__parent__),
aq_base(conversation)
)
self.assertEqual(new_id, comment.comment_id) self.assertEqual(new_id, comment.comment_id)
self.assertEqual(len(list(conversation.getComments())), 1) self.assertEqual(len(list(conversation.getComments())), 1)
self.assertEqual(len(tuple(conversation.getThreads())), 1) self.assertEqual(len(tuple(conversation.getThreads())), 1)
self.assertEqual(conversation.total_comments, 1) self.assertEqual(conversation.total_comments, 1)
self.assertTrue(conversation.last_comment_date - datetime.utcnow() < self.assertTrue(
timedelta(seconds=1)) conversation.last_comment_date - datetime.utcnow() <
timedelta(seconds=1)
)
def test_private_comment(self): def test_private_comment(self):
conversation = IConversation(self.portal.doc1) conversation = IConversation(self.portal.doc1)
@ -169,10 +176,10 @@ class ConversationTest(unittest.TestCase):
del conversation[new_id_1] del conversation[new_id_1]
self.assertEqual( self.assertEqual([
[{'comment': comment2, 'depth': 0, 'id': new_id_2}, {'comment': comment2, 'depth': 0, 'id': new_id_2},
{'comment': comment2_1, 'depth': 1, 'id': new_id_2_1}, {'comment': comment2_1, 'depth': 1, 'id': new_id_2_1},
], list(conversation.getThreads())) ], list(conversation.getThreads()))
def test_delete_comment_when_content_object_is_deleted(self): def test_delete_comment_when_content_object_is_deleted(self):
# Make sure all comments of a content object are deleted when the # Make sure all comments of a content object are deleted when the
@ -212,10 +219,14 @@ class ConversationTest(unittest.TestCase):
# By default, allow_discussion on newly created content objects is # By default, allow_discussion on newly created content objects is
# set to False # set to False
portal_discussion = getToolByName(self.portal, 'portal_discussion') portal_discussion = getToolByName(self.portal, 'portal_discussion')
self.assertEqual(portal_discussion.isDiscussionAllowedFor( self.assertEqual(
self.portal.doc1), False) portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
self.assertEqual(self.portal.doc1.getTypeInfo().allowDiscussion(), False
False) )
self.assertEqual(
self.portal.doc1.getTypeInfo().allowDiscussion(),
False
)
# The allow discussion flag is None by default # The allow discussion flag is None by default
self.assertFalse(getattr(self.portal.doc1, 'allow_discussion', None)) self.assertFalse(getattr(self.portal.doc1, 'allow_discussion', None))
@ -225,35 +236,51 @@ class ConversationTest(unittest.TestCase):
# type and check if the Document object allows discussion now. # type and check if the Document object allows discussion now.
document_fti = getattr(portal_types, 'Document') document_fti = getattr(portal_types, 'Document')
document_fti.manage_changeProperties(allow_discussion=True) document_fti.manage_changeProperties(allow_discussion=True)
self.assertEqual(portal_discussion.isDiscussionAllowedFor( self.assertEqual(
self.portal.doc1), True) portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
self.assertEqual(self.portal.doc1.getTypeInfo().allowDiscussion(), True
True) )
self.assertEqual(
self.portal.doc1.getTypeInfo().allowDiscussion(),
True
)
# We can also override the allow_discussion locally # We can also override the allow_discussion locally
self.portal_discussion.overrideDiscussionFor(self.portal.doc1, False) self.portal_discussion.overrideDiscussionFor(self.portal.doc1, False)
# Check if the Document discussion is disabled # Check if the Document discussion is disabled
self.assertEqual(portal_discussion.isDiscussionAllowedFor( self.assertEqual(
self.portal.doc1), False) portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
False
)
# Check that the local allow_discussion flag is now explicitly set to # Check that the local allow_discussion flag is now explicitly set to
# False # False
self.assertEqual(getattr(self.portal.doc1, 'allow_discussion', None), self.assertEqual(
False) getattr(self.portal.doc1, 'allow_discussion', None),
False
)
# Disallow discussion on the Document content type again # Disallow discussion on the Document content type again
document_fti.manage_changeProperties(allow_discussion=False) document_fti.manage_changeProperties(allow_discussion=False)
self.assertEqual(portal_discussion.isDiscussionAllowedFor( self.assertEqual(
self.portal.doc1), False) portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
self.assertEqual(self.portal.doc1.getTypeInfo().allowDiscussion(), False
False) )
self.assertEqual(
self.portal.doc1.getTypeInfo().allowDiscussion(),
False
)
# Now we override allow_discussion again (True) for the Document # Now we override allow_discussion again (True) for the Document
# content object # content object
self.portal_discussion.overrideDiscussionFor(self.portal.doc1, True) self.portal_discussion.overrideDiscussionFor(self.portal.doc1, True)
self.assertEqual(portal_discussion.isDiscussionAllowedFor( self.assertEqual(
self.portal.doc1), True) portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
self.assertEqual(getattr(self.portal.doc1, 'allow_discussion', None), True
True) )
self.assertEqual(
getattr(self.portal.doc1, 'allow_discussion', None),
True
)
def test_comments_enabled_on_doc_in_subfolder(self): def test_comments_enabled_on_doc_in_subfolder(self):
typetool = self.portal.portal_types typetool = self.portal.portal_types
@ -338,7 +365,8 @@ class ConversationTest(unittest.TestCase):
# Create a conversation. # Create a conversation.
conversation = self.portal.doc1.restrictedTraverse( conversation = self.portal.doc1.restrictedTraverse(
'@@conversation_view') '@@conversation_view'
)
# The Document content type is disabled by default # The Document content type is disabled by default
self.assertEqual(conversation.enabled(), False) self.assertEqual(conversation.enabled(), False)
@ -416,7 +444,8 @@ class ConversationTest(unittest.TestCase):
# Create a conversation. # Create a conversation.
conversation = self.portal.doc1.restrictedTraverse( conversation = self.portal.doc1.restrictedTraverse(
'@@conversation_view') '@@conversation_view'
)
# Discussion is disallowed by default # Discussion is disallowed by default
self.assertEqual(conversation.enabled(), False) self.assertEqual(conversation.enabled(), False)
@ -599,30 +628,42 @@ class ConversationTest(unittest.TestCase):
new_comment3_id = conversation.addComment(comment3) new_comment3_id = conversation.addComment(comment3)
# check if the latest comment is exactly one day old # check if the latest comment is exactly one day old
self.assertTrue(conversation.last_comment_date < datetime.utcnow() - self.assertTrue(
timedelta(hours=23, minutes=59, seconds=59)) conversation.last_comment_date < datetime.utcnow() -
self.assertTrue(conversation.last_comment_date > timedelta(hours=23, minutes=59, seconds=59)
datetime.utcnow() - timedelta(days=1, seconds=1)) )
self.assertTrue(
conversation.last_comment_date >
datetime.utcnow() - timedelta(days=1, seconds=1)
)
# remove the latest comment # remove the latest comment
del conversation[new_comment3_id] del conversation[new_comment3_id]
# check if the latest comment has been updated # check if the latest comment has been updated
# the latest comment should be exactly two days old # the latest comment should be exactly two days old
self.assertTrue(conversation.last_comment_date < datetime.utcnow() - self.assertTrue(
timedelta(days=1, hours=23, minutes=59, seconds=59)) conversation.last_comment_date < datetime.utcnow() -
self.assertTrue(conversation.last_comment_date > datetime.utcnow() - timedelta(days=1, hours=23, minutes=59, seconds=59)
timedelta(days=2, seconds=1)) )
self.assertTrue(
conversation.last_comment_date > datetime.utcnow() -
timedelta(days=2, seconds=1)
)
# remove the latest comment again # remove the latest comment again
del conversation[new_comment2_id] del conversation[new_comment2_id]
# check if the latest comment has been updated # check if the latest comment has been updated
# the latest comment should be exactly four days old # the latest comment should be exactly four days old
self.assertTrue(conversation.last_comment_date < datetime.utcnow() - self.assertTrue(
timedelta(days=3, hours=23, minutes=59, seconds=59)) conversation.last_comment_date < datetime.utcnow() -
self.assertTrue(conversation.last_comment_date > datetime.utcnow() - timedelta(days=3, hours=23, minutes=59, seconds=59)
timedelta(days=4, seconds=2)) )
self.assertTrue(
conversation.last_comment_date > datetime.utcnow() -
timedelta(days=4, seconds=2)
)
def test_get_comments_full(self): def test_get_comments_full(self):
pass pass
@ -685,14 +726,14 @@ class ConversationTest(unittest.TestCase):
# Get threads # Get threads
self.assertEqual( self.assertEqual([
[{'comment': comment1, 'depth': 0, 'id': new_id_1}, {'comment': comment1, 'depth': 0, 'id': new_id_1},
{'comment': comment1_1, 'depth': 1, 'id': new_id_1_1}, {'comment': comment1_1, 'depth': 1, 'id': new_id_1_1},
{'comment': comment1_1_1, 'depth': 2, 'id': new_id_1_1_1}, {'comment': comment1_1_1, 'depth': 2, 'id': new_id_1_1_1},
{'comment': comment1_2, 'depth': 1, 'id': new_id_1_2}, {'comment': comment1_2, 'depth': 1, 'id': new_id_1_2},
{'comment': comment2, 'depth': 0, 'id': new_id_2}, {'comment': comment2, 'depth': 0, 'id': new_id_2},
{'comment': comment2_1, 'depth': 1, 'id': new_id_2_1}, {'comment': comment2_1, 'depth': 1, 'id': new_id_2_1},
], list(conversation.getThreads())) ], list(conversation.getThreads()))
def test_get_threads_batched(self): def test_get_threads_batched(self):
# TODO: test start, size, root and depth arguments to getThreads() # TODO: test start, size, root and depth arguments to getThreads()
@ -703,20 +744,26 @@ class ConversationTest(unittest.TestCase):
# make sure we can traverse to conversations and get a URL and path # make sure we can traverse to conversations and get a URL and path
conversation = self.portal.doc1.restrictedTraverse( conversation = self.portal.doc1.restrictedTraverse(
'++conversation++default') '++conversation++default'
)
self.assertTrue(IConversation.providedBy(conversation)) self.assertTrue(IConversation.providedBy(conversation))
self.assertEqual(('', 'plone', 'doc1', '++conversation++default'), self.assertEqual(
conversation.getPhysicalPath()) ('', 'plone', 'doc1', '++conversation++default'),
self.assertEqual('http://nohost/plone/doc1/++conversation++default', conversation.getPhysicalPath()
conversation.absolute_url()) )
self.assertEqual(
'http://nohost/plone/doc1/++conversation++default',
conversation.absolute_url()
)
def test_unconvertible_id(self): def test_unconvertible_id(self):
# make sure the conversation view doesn't break when given comment id # make sure the conversation view doesn't break when given comment id
# can't be converted to long # can't be converted to long
conversation = self.portal.doc1.restrictedTraverse( conversation = self.portal.doc1.restrictedTraverse(
'++conversation++default/ThisCantBeRight') '++conversation++default/ThisCantBeRight'
)
self.assertEqual(conversation, None) self.assertEqual(conversation, None)
def test_parent(self): def test_parent(self):
@ -737,8 +784,10 @@ class ConversationTest(unittest.TestCase):
def test_no_comment(self): def test_no_comment(self):
IConversation(self.portal.doc1) IConversation(self.portal.doc1)
# Make sure no conversation has been created # Make sure no conversation has been created
self.assertTrue('plone.app.discussion:conversation' not in self.assertTrue(
IAnnotations(self.portal.doc1)) 'plone.app.discussion:conversation' not in
IAnnotations(self.portal.doc1)
)
class ConversationEnabledForDexterityTypesTest(unittest.TestCase): class ConversationEnabledForDexterityTypesTest(unittest.TestCase):
@ -750,15 +799,16 @@ class ConversationEnabledForDexterityTypesTest(unittest.TestCase):
setRoles(self.portal, TEST_USER_ID, ['Manager']) setRoles(self.portal, TEST_USER_ID, ['Manager'])
interface.alsoProvides( interface.alsoProvides(
self.portal.REQUEST, self.portal.REQUEST,
interfaces.IDiscussionLayer) interfaces.IDiscussionLayer
)
typetool = self.portal.portal_types typetool = self.portal.portal_types
typetool.constructContent('Document', self.portal, 'doc1') typetool.constructContent('Document', self.portal, 'doc1')
if DEXTERITY: if DEXTERITY:
from plone.dexterity.interfaces import IDexterityContent
interface.alsoProvides( interface.alsoProvides(
self.portal.doc1, self.portal.doc1,
IDexterityContent) IDexterityContent
)
def _makeOne(self, *args, **kw): def _makeOne(self, *args, **kw):
return self.portal.doc1.restrictedTraverse('@@conversation_view') return self.portal.doc1.restrictedTraverse('@@conversation_view')