Refactor tests and add a lot of skeleton tests we really ought to have

svn path=/plone.app.discussion/trunk/; revision=27012
This commit is contained in:
Martin Aspeli 2009-05-18 15:15:36 +00:00
parent f5a781501b
commit 250b556428
8 changed files with 252 additions and 69 deletions

View File

@ -42,15 +42,13 @@ class Comment(Explicit, Traversable, RoleManager, Owned):
author_name = None author_name = None
author_email = None author_email = None
def __init__(self, conversation=None, **kw): # Note: we want to use zope.component.createObject() to instantiate
self.comment_id = None # will be set by IConversation.addComment() # comments as far as possible. comment_id and __parent__ are set via
# IConversation.addComment().
self.__parent__ = conversation
def __init__(self):
self.creation_date = self.modification_date = datetime.now() self.creation_date = self.modification_date = datetime.now()
for k, v in kw.items():
setattr(self, k, v)
@property @property
def __name__(self): def __name__(self):
return self.comment_id and unicode(self.comment_id) or None return self.comment_id and unicode(self.comment_id) or None

View File

@ -22,9 +22,10 @@
<require attributes="Title Creator getId" permission="zope2.View" /> <require attributes="Title Creator getId" permission="zope2.View" />
</class> </class>
<utility factory=".comment.CommentFactory" <utility
provides="plone.app.discussion.interfaces.IComment" component=".comment.CommentFactory"
name="Discussion Item" /> name="plone.Comment"
/>
<!-- Conversations --> <!-- Conversations -->
<class class=".conversation.Conversation"> <class class=".conversation.Conversation">

View File

@ -126,7 +126,9 @@ class Conversation(Traversable, Persistent, Explicit):
notify(ObjectWillBeAddedEvent(comment, self, id)) notify(ObjectWillBeAddedEvent(comment, self, id))
self._comments[id] = comment self._comments[id] = comment
# for logged in users only comment.__parent__ = self
# Record unique users who've commented (for logged in users only)
commentator = comment.author_username commentator = comment.author_username
if commentator: if commentator:
if not commentator in self._commentators: if not commentator in self._commentators:
@ -147,6 +149,8 @@ class Conversation(Traversable, Persistent, Explicit):
notify(ObjectAddedEvent(comment.__of__(self), self, id)) notify(ObjectAddedEvent(comment.__of__(self), self, id))
notify(ContainerModifiedEvent(self)) notify(ContainerModifiedEvent(self))
return id
# Dict API # Dict API
def __len__(self): def __len__(self):
@ -155,12 +159,10 @@ class Conversation(Traversable, Persistent, Explicit):
def __contains__(self, key): def __contains__(self, key):
return long(key) in self._comments return long(key) in self._comments
# TODO: Should __getitem__, get, __iter__, values(), items() and iter* return aq-wrapped comments?
def __getitem__(self, key): def __getitem__(self, key):
"""Get an item by its long key """Get an item by its long key
""" """
return self._comments[long(key)] return self._comments[long(key)].__of__(self)
def __delitem__(self, key): def __delitem__(self, key):
"""Delete an item by its long key """Delete an item by its long key
@ -168,7 +170,7 @@ class Conversation(Traversable, Persistent, Explicit):
key = long(key) key = long(key)
comment = self[key] comment = self[key].__of__(self)
commentator = comment.author_username commentator = comment.author_username
notify(ObjectWillBeRemovedEvent(comment, self, key)) notify(ObjectWillBeRemovedEvent(comment, self, key))
@ -187,25 +189,30 @@ class Conversation(Traversable, Persistent, Explicit):
return iter(self._comments) return iter(self._comments)
def get(self, key, default=None): def get(self, key, default=None):
return self._comments.get(long(key), default) comment = self._comments.get(long(key), default)
if comment is default:
return default
return comment.__of__(self)
def keys(self): def keys(self):
return self._comments.keys() return self._comments.keys()
def items(self): def items(self):
return self._comments.items() return [(i[0], i[1].__of__(self),) for i in self._comments.items()]
def values(self): def values(self):
return self._comments.values() return [v.__of__(self) for v in self._comments.values()]
def iterkeys(self): def iterkeys(self):
return self._comments.iterkeys() return self._comments.iterkeys()
def itervalues(self): def itervalues(self):
return self._comments.itervalues() for v in self._comments.itervalues():
yield v.__of__(self)
def iteritems(self): def iteritems(self):
return self._comments.iteritems() for k, v in self._comments.iteritems():
yield (k, v.__of__(self),)
@implementer(IConversation) @implementer(IConversation)
@adapter(IAnnotatable) @adapter(IAnnotatable)

View File

@ -1,45 +0,0 @@
import unittest
from datetime import datetime, timedelta
from Products.PloneTestCase.ptc import PloneTestCase
from plone.app.discussion.tests.layer import DiscussionLayer
from plone.app.discussion.conversation import Conversation
from plone.app.discussion.comment import Comment
from plone.app.discussion.interfaces import ICommentingTool, IConversation
class ConversationTest(PloneTestCase):
layer = DiscussionLayer
def afterSetUp(self):
# XXX If we make this a layer, it only get run once...
# First we need to create some content.
self.loginAsPortalOwner()
typetool = self.portal.portal_types
typetool.constructContent('Document', self.portal, 'doc1')
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)
# Pretend that we have traversed to the comment by aq wrapping it.
# XXX implement traversal to commenting and change this:
conversation = conversation.__of__(self.portal.doc1)
# Add a comment. reply_to=0 means it's not a reply
comment = Comment(conversation=conversation, reply_to=0)
comment.title = 'Comment 1'
comment.text = 'Comment text'
conversation.addComment(comment)
# Check that the conversation methods return the correct data
self.assert_(isinstance(comment.comment_id, long))
self.assertEquals(len(conversation.getComments()), 1)
self.assertEquals(len(conversation.getThreads()), 1)
self.assertEquals(conversation.total_comments, 1)
self.assert_(conversation.last_comment_date - datetime.now() < timedelta(seconds=1))
def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__)

View File

@ -0,0 +1,71 @@
import unittest
from zope.component import createObject
from Products.PloneTestCase.ptc import PloneTestCase
from plone.app.discussion.tests.layer import DiscussionLayer
from plone.app.discussion.interfaces import IComment, IConversation
from plone.app.discussion.comment import Comment
class CommentTest(PloneTestCase):
layer = DiscussionLayer
def afterSetUp(self):
# First we need to create some content.
self.loginAsPortalOwner()
typetool = self.portal.portal_types
typetool.constructContent('Document', self.portal, 'doc1')
def test_factory(self):
# test with createObject()
pass
def test_id(self):
# relationship between id, getId(), __name__
pass
def test_title(self):
pass
def test_creator(self):
pass
def test_traversal(self):
# make sure comments are traversable, have an id, absolute_url and physical path
pass
def test_workflow(self):
# ensure that we can assign a workflow to the comment type and perform
# workflow operations
pass
def test_fti(self):
# test that we can look up an FTI for Discussion Item
pass
class RepliesTest(PloneTestCase):
# test the IReplies adapter on a comment
layer = DiscussionLayer
def afterSetUp(self):
# First we need to create some content.
self.loginAsPortalOwner()
typetool = self.portal.portal_types
typetool.constructContent('Document', self.portal, 'doc1')
def test_add_comment(self):
pass
def test_delete_comment(self):
pass
def test_dict_api(self):
# ensure all operations use only top-level comments
pass
def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__)

View File

@ -0,0 +1,103 @@
import unittest
from datetime import datetime, timedelta
from zope.component import createObject
from Acquisition import aq_base
from Products.PloneTestCase.ptc import PloneTestCase
from plone.app.discussion.tests.layer import DiscussionLayer
from plone.app.discussion.interfaces import IConversation, IComment
class ConversationTest(PloneTestCase):
layer = DiscussionLayer
def afterSetUp(self):
# First we need to create some content.
self.loginAsPortalOwner()
typetool = self.portal.portal_types
typetool.constructContent('Document', self.portal, 'doc1')
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)
# Pretend that we have traversed to the comment by aq wrapping it.
conversation = conversation.__of__(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.title = 'Comment 1'
comment.text = 'Comment text'
new_id = conversation.addComment(comment)
# Check that the conversation methods return the correct data
self.assert_(isinstance(comment.comment_id, long))
self.assert_(IComment.providedBy(conversation[new_id]))
self.assertEquals(aq_base(conversation[new_id].__parent__), aq_base(conversation))
self.assertEquals(new_id, comment.comment_id)
self.assertEquals(len(conversation.getComments()), 1)
self.assertEquals(len(conversation.getThreads()), 1)
self.assertEquals(conversation.total_comments, 1)
self.assert_(conversation.last_comment_date - datetime.now() < timedelta(seconds=1))
def test_delete(self):
pass
def test_dict_operations(self):
# test dict operations and acquisition wrapping
pass
def test_total_comments(self):
pass
def test_commentators(self):
# add and remove a few comments to make sure the commenetators
# property returns a true set
pass
def test_last_comment_date(self):
pass
def test_get_comments_flat(self):
pass
def test_get_comments_batched(self):
pass
def test_get_threads(self):
pass
def test_get_threads_batched(self):
pass
class RepliesTest(PloneTestCase):
# test the IReplies adapter on a conversation
layer = DiscussionLayer
def afterSetUp(self):
# First we need to create some content.
self.loginAsPortalOwner()
typetool = self.portal.portal_types
typetool.constructContent('Document', self.portal, 'doc1')
def test_add_comment(self):
pass
def test_delete_comment(self):
pass
def test_dict_api(self):
# ensure all operations use only top-level comments
pass
def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__)

View File

@ -0,0 +1,42 @@
import unittest
from Products.PloneTestCase.ptc import PloneTestCase
from plone.app.discussion.tests.layer import DiscussionLayer
class TestIndexers(PloneTestCase):
layer = DiscussionLayer
def test_title(self):
pass
def test_description(self):
pass
def test_dates(self):
# created, modified, effective etc
pass
def test_searchable_text(self):
pass
def test_creator(self):
pass
def test_title(self):
pass
def test_in_reply_to(self):
pass
def test_path(self):
pass
def test_review_state(self):
pass
def test_object_provides(self):
pass
def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__)

View File

@ -1,11 +1,10 @@
import unittest import unittest
from zope.component import getUtility from zope.component import getUtility, createObject
from Products.PloneTestCase.ptc import PloneTestCase from Products.PloneTestCase.ptc import PloneTestCase
from plone.app.discussion.tests.layer import DiscussionLayer from plone.app.discussion.tests.layer import DiscussionLayer
from plone.app.discussion.comment import Comment
from plone.app.discussion.interfaces import ICommentingTool, IConversation from plone.app.discussion.interfaces import ICommentingTool, IConversation
class ToolTest(PloneTestCase): class ToolTest(PloneTestCase):
@ -27,8 +26,8 @@ class ToolTest(PloneTestCase):
# XXX implement traversal to commenting and change this: # XXX implement traversal to commenting and change this:
conversation = conversation.__of__(self.portal.doc1) conversation = conversation.__of__(self.portal.doc1)
# Add a comment. reply_to=0 means it's not a reply # Add a comment.
comment = Comment(conversation=conversation, reply_to=0) comment = createObject('plone.Comment')
comment.title = 'Comment 1' comment.title = 'Comment 1'
comment.text = 'Comment text' comment.text = 'Comment text'
@ -41,5 +40,12 @@ class ToolTest(PloneTestCase):
" %s results in the search" % len(comment)) " %s results in the search" % len(comment))
self.assertEquals(comment[0].Title, 'Comment 1') self.assertEquals(comment[0].Title, 'Comment 1')
def test_unindexing(self):
pass
def test_search(self):
# search returns only comments
pass
def test_suite(): def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__) return unittest.defaultTestLoader.loadTestsFromName(__name__)