From 49c6c45453e703cc82d97e541f2c1d0cfbc24342 Mon Sep 17 00:00:00 2001 From: Lennart Regebro Date: Sat, 16 May 2009 10:34:12 +0000 Subject: [PATCH] First running test. svn path=/plone.app.discussion/trunk/; revision=26962 --- plone/app/discussion/comment.py | 8 ++++--- plone/app/discussion/conversation.py | 31 +++++++++++++++++++------- plone/app/discussion/interfaces.py | 5 +++++ plone/app/discussion/tests/test_api.py | 29 +++++++++++++++++++----- 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/plone/app/discussion/comment.py b/plone/app/discussion/comment.py index b897730..97bfa3f 100644 --- a/plone/app/discussion/comment.py +++ b/plone/app/discussion/comment.py @@ -1,6 +1,6 @@ """The default comment class and factory. """ - +from datetime import datetime from zope.interface import implements from zope.component.factory import Factory @@ -26,6 +26,7 @@ class Comment(Explicit, Traversable, RoleManager, Owned): __parent__ = None comment_id = None # int + reply_to = None # int title = u"" @@ -44,14 +45,15 @@ class Comment(Explicit, Traversable, RoleManager, Owned): def __init__(self, id=0, conversation=None, **kw): self.comment_id = id self.__parent__ = conversation + self.creation_date = self.modification_date = datetime.now() - for k, v in kw: + for k, v in kw.items(): setattr(self, k, v) @property def in_reply_to(self): # TODO - return None + return self.reply_to @property def __name__(self): diff --git a/plone/app/discussion/conversation.py b/plone/app/discussion/conversation.py index 7e4a0a7..cfd35fe 100644 --- a/plone/app/discussion/conversation.py +++ b/plone/app/discussion/conversation.py @@ -60,26 +60,41 @@ class Conversation(Persistent, Explicit): @property def total_comments(self): # TODO - return 0 + return len(self._comments) @property def last_comment_date(self): # TODO - return None + return self._last_comment_date @property def commentators(self): # TODO: return set() - def getComments(start=0, size=None): - # TODO - pass + def getComments(self, start=0, size=None): + return self._comments.values() - def getThreads(start=0, size=None, root=None, depth=None): - # TODO - pass + def getThreads(self, start=0, size=None, root=None, depth=None): + return self._comments.values() + def addComment(self, comment): + id = len(self._comments) + 1 + self._comments[id] = comment + comment.comment_id = id + + commentator = comment.creator + if not commentator in self._commentators: + self._commentators[commentator] = 0 + self._commentators[commentator] += 1 + + self._last_comment_date = comment.creation_date + + reply_to = comment.in_reply_to + if not reply_to in self._children: + self._children[reply_to] = IISet() + self._children[reply_to].insert(id) + # Dict API # TODO: Update internal data structures when items added or removed diff --git a/plone/app/discussion/interfaces.py b/plone/app/discussion/interfaces.py index 315adf7..db2c8cc 100644 --- a/plone/app/discussion/interfaces.py +++ b/plone/app/discussion/interfaces.py @@ -73,6 +73,11 @@ class IConversation(IIterableMapping, IWriteMapping): in order to give enough context to show the full lineage of the starting comment. """ + + def addComment(comment): + """Adds a new comment to the list of comments, amd returns the + comment id that was assigned. + """ class IReplies(IIterableMapping, IWriteMapping): """A set of related comments in reply to a given content object or diff --git a/plone/app/discussion/tests/test_api.py b/plone/app/discussion/tests/test_api.py index 300354e..2e28195 100644 --- a/plone/app/discussion/tests/test_api.py +++ b/plone/app/discussion/tests/test_api.py @@ -1,5 +1,5 @@ import unittest - +from datetime import datetime, timedelta from base import TestCase from zope.testing import doctestunit @@ -13,7 +13,10 @@ from Products.Five import fiveconfigure from Products.PloneTestCase import PloneTestCase as ptc from Products.PloneTestCase.layer import PloneSite -class APITest(TestCase): +from plone.app.discussion.conversation import Conversation +from plone.app.discussion.comment import Comment + +class ConversationTest(TestCase): def afterSetUp(self): # XXX If we make this a layer, it only get run once... # First we need to create some content. @@ -21,13 +24,29 @@ class APITest(TestCase): typetool = self.portal.portal_types typetool.constructContent('Document', self.portal, 'doc1') - def test_test(self): - raise NotImplementedError + 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 = Conversation() + + # 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.assertEquals(comment.id, '1') + 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.TestSuite([ - unittest.makeSuite(APITest), + unittest.makeSuite(ConversationTest), ]) if __name__ == '__main__':