enabled property code added to conversation.

svn path=/plone.app.discussion/trunk/; revision=27380
This commit is contained in:
Timo Stollenwerk 2009-06-11 10:14:44 +00:00
parent 0f7d05566a
commit e465d73c95
2 changed files with 136 additions and 21 deletions

View File

@ -14,14 +14,18 @@ import time
from persistent import Persistent
from plone.registry.interfaces import IRegistry
from zope.app.component.hooks import getSite
from zope.interface import implements, implementer
from zope.component import adapts, adapter
from zope.component import adapts, adapter, queryUtility
from zope.annotation.interfaces import IAnnotations, IAnnotatable
from zope.event import notify
from Acquisition import aq_base
from Acquisition import aq_base, aq_inner
from Acquisition import Explicit
from OFS.Traversable import Traversable
@ -29,6 +33,8 @@ from OFS.Traversable import Traversable
from OFS.event import ObjectWillBeAddedEvent
from OFS.event import ObjectWillBeRemovedEvent
from Products.CMFCore.utils import getToolByName
from zope.app.container.contained import ContainerModifiedEvent
from zope.app.container.contained import ObjectAddedEvent
@ -44,7 +50,7 @@ except ImportError:
from BTrees.OOBTree import OOBTree as LOBTree
from BTrees.OOBTree import OOSet as LLSet
from plone.app.discussion.interfaces import IConversation, IReplies
from plone.app.discussion.interfaces import IConversation, IReplies, IDiscussionSettings
from plone.app.discussion.comment import Comment
ANNOTATION_KEY = 'plone.app.discussion:conversation'
@ -80,7 +86,29 @@ class Conversation(Traversable, Persistent, Explicit):
@property
def enabled(self):
# TODO - check __parent__'s settings + global settings
# Returns True if discussion is allowed
# Fetch discussion registry
registry = queryUtility(IRegistry)
settings = registry.for_interface(IDiscussionSettings)
# Check if discussion is allowed globally
if not settings.globally_enabled:
return False
# Check if discussion is allowed on the content type
site = getSite()
portal_types = getToolByName(site, 'portal_types')
portal_type = self.__parent__.portal_type
document_fti = getattr(portal_types, 'Document')
if not document_fti.getProperty('allow_discussion'):
# If discussion is not allowed on the content type,
# check if 'allow discussion' is overridden on the content object.
#if hasattr( aq_base(self.__parent__), 'allow_discussion' ):
portal_discussion = getToolByName(site, 'portal_discussion')
if not portal_discussion.isDiscussionAllowedFor(aq_inner(self.__parent__)):
return False
return True
@property
@ -279,6 +307,7 @@ def conversationAdapterFactory(content):
conversation = Conversation()
annotions[ANNOTATION_KEY] = conversation
conversation = annotions[ANNOTATION_KEY]
conversation.__parent__ = aq_base(content)
return conversation
class ConversationReplies(object):

View File

@ -1,14 +1,14 @@
import unittest
from datetime import datetime, timedelta
from plone.registry import Registry
from zope.component import createObject
from zope.component import createObject, queryUtility
from Acquisition import aq_base, aq_parent, aq_inner
from plone.app.vocabularies.types import BAD_TYPES
from plone.registry.interfaces import IRegistry
from Products.CMFCore.utils import getToolByName
from Products.PloneTestCase.ptc import PloneTestCase
from plone.app.discussion.tests.layer import DiscussionLayer
@ -155,6 +155,82 @@ class ConversationTest(PloneTestCase):
{'comment': comment2_1, 'depth': 1, 'id': new_id_2_1},
], list(conversation.getThreads()))
def test_disable_commenting_globally(self):
# Create a conversation.
conversation = IConversation(self.portal.doc1)
# We have to allow discussion on Document content type, since
# otherwise allow_discussion will always return False
portal_types = getToolByName(self.portal, 'portal_types')
document_fti = getattr(portal_types, 'Document')
document_fti.manage_changeProperties(allow_discussion = True)
# Check if conversation is enabled now
self.assertEquals(conversation.enabled, True)
# Disable commenting in the registry
registry = queryUtility(IRegistry)
settings = registry.for_interface(IDiscussionSettings)
settings.globally_enabled = False
# Check if commenting is disabled on the conversation
self.assertEquals(conversation.enabled, False)
# Enable discussion again
settings.globally_enabled = True
self.assertEquals(conversation.enabled, True)
def test_disable_commenting_for_content_type(self):
# Create a conversation.
conversation = IConversation(self.portal.doc1)
# The Document content type is disabled by default
self.assertEquals(conversation.enabled, False)
# Allow discussion on Document content type
portal_types = getToolByName(self.portal, 'portal_types')
document_fti = getattr(portal_types, 'Document')
document_fti.manage_changeProperties(allow_discussion = True)
# Check if conversation is enabled now
self.assertEquals(conversation.enabled, True)
# Disallow discussion on Document content type
portal_types = getToolByName(self.portal, 'portal_types')
document_fti = getattr(portal_types, 'Document')
document_fti.manage_changeProperties(allow_discussion = False)
# Check if conversation is enabled now
self.assertEquals(conversation.enabled, False)
def test_is_discussion_allowed_for_folder(self):
# Create a folder with two content objects. Change allow_discussion
# and check if the content objects inside the folder are commentable.
pass
def test_is_discussion_allowed_on_content_object(self):
# Allow discussion on a single content object
registry = queryUtility(IRegistry)
settings = registry.for_interface(IDiscussionSettings)
# Create a conversation.
conversation = IConversation(self.portal.doc1)
# Discussion is disallowed by default
self.assertEquals(conversation.enabled, False)
# Allow discussion on content object
self.portal_discussion.overrideDiscussionFor(self.portal.doc1, True)
# Check if discussion is now allowed on the content object
self.assertEquals(conversation.enabled, True)
self.portal_discussion.overrideDiscussionFor(self.portal.doc1, False)
self.assertEquals(conversation.enabled, False)
def test_dict_operations(self):
# test dict operations and acquisition wrapping
@ -459,6 +535,16 @@ class ConversationTest(PloneTestCase):
self.assertEquals(('', 'plone', 'doc1', '++conversation++default'), conversation.getPhysicalPath())
self.assertEquals('plone/doc1/%2B%2Bconversation%2B%2Bdefault', conversation.absolute_url())
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.failUnless(conversation.__parent__)
self.assertEquals(conversation.__parent__.getId(), 'doc1')
def test_discussion_item_not_in_bad_types(self):
self.failIf('Discussion Item' in BAD_TYPES)