total_comments only counts published comments
Also migrate workflow state during migration.
This commit is contained in:
parent
5e08d3a33e
commit
53428fe5f6
10
CHANGES.txt
10
CHANGES.txt
@ -6,12 +6,22 @@ Changelog
|
|||||||
|
|
||||||
- Prune duplicated test code.
|
- Prune duplicated test code.
|
||||||
[pjstevns]
|
[pjstevns]
|
||||||
|
|
||||||
- Update version in buildout.cfg to allow development.
|
- Update version in buildout.cfg to allow development.
|
||||||
[pjstevns]
|
[pjstevns]
|
||||||
|
|
||||||
|
- Conversation.total_comments only counts published comments.
|
||||||
|
Fixes bug #11591.
|
||||||
|
[pjstevns]
|
||||||
|
|
||||||
|
- Set workflow status of comments during migration based on
|
||||||
|
the state of the Discussion Item.
|
||||||
|
[pjstevns]
|
||||||
|
|
||||||
|
|
||||||
2.1.6 (2012-05-30)
|
2.1.6 (2012-05-30)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Add Site Administrator role to Review comments permission.
|
- Add Site Administrator role to Review comments permission.
|
||||||
[gaudenz]
|
[gaudenz]
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@ from plone.app.discussion.interfaces import ICaptcha
|
|||||||
from plone.app.discussion.browser.validator import CaptchaValidator
|
from plone.app.discussion.browser.validator import CaptchaValidator
|
||||||
|
|
||||||
from plone.z3cform import z2
|
from plone.z3cform import z2
|
||||||
from plone.z3cform.widget import SingleCheckBoxWidget
|
|
||||||
from plone.z3cform.fieldsets import extensible
|
from plone.z3cform.fieldsets import extensible
|
||||||
|
|
||||||
|
|
||||||
@ -372,7 +371,7 @@ class CommentsViewlet(ViewletBase):
|
|||||||
yield r
|
yield r
|
||||||
|
|
||||||
# Return all direct replies
|
# Return all direct replies
|
||||||
if conversation.total_comments > 0:
|
if len(conversation.objectIds()):
|
||||||
if workflow_actions:
|
if workflow_actions:
|
||||||
return replies_with_workflow_actions()
|
return replies_with_workflow_actions()
|
||||||
else:
|
else:
|
||||||
|
@ -14,6 +14,9 @@ from plone.app.discussion.comment import CommentFactory
|
|||||||
|
|
||||||
from plone.app.discussion.interfaces import IConversation, IReplies, IComment
|
from plone.app.discussion.interfaces import IConversation, IReplies, IComment
|
||||||
|
|
||||||
|
from types import TupleType
|
||||||
|
from DateTime import DateTime
|
||||||
|
|
||||||
|
|
||||||
def DT2dt(DT):
|
def DT2dt(DT):
|
||||||
"""Convert a Zope DateTime (with timezone) into a Python datetime (GMT)."""
|
"""Convert a Zope DateTime (with timezone) into a Python datetime (GMT)."""
|
||||||
@ -64,8 +67,14 @@ class View(BrowserView):
|
|||||||
if len(replies) == 0:
|
if len(replies) == 0:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
for reply in replies:
|
workflow = context.portal_workflow
|
||||||
|
oldchain = workflow.getChainForPortalType('Discussion Item')
|
||||||
|
new_workflow = workflow.comment_review_workflow
|
||||||
|
|
||||||
|
if type(oldchain) == TupleType and len(oldchain) > 0:
|
||||||
|
oldchain = oldchain[0]
|
||||||
|
|
||||||
|
for reply in replies:
|
||||||
# log
|
# log
|
||||||
indent = " "
|
indent = " "
|
||||||
for i in range(depth):
|
for i in range(depth):
|
||||||
@ -80,7 +89,8 @@ class View(BrowserView):
|
|||||||
|
|
||||||
new_in_reply_to = None
|
new_in_reply_to = None
|
||||||
if should_migrate:
|
if should_migrate:
|
||||||
# create a reply object
|
|
||||||
|
# create a reply object
|
||||||
comment = CommentFactory()
|
comment = CommentFactory()
|
||||||
comment.title = reply.Title()
|
comment.title = reply.Title()
|
||||||
comment.text = reply.cooked_text
|
comment.text = reply.cooked_text
|
||||||
@ -105,6 +115,31 @@ class View(BrowserView):
|
|||||||
replies = IReplies(comment_to_reply_to)
|
replies = IReplies(comment_to_reply_to)
|
||||||
new_in_reply_to = replies.addComment(comment)
|
new_in_reply_to = replies.addComment(comment)
|
||||||
|
|
||||||
|
# migrate the review state
|
||||||
|
old_status = workflow.getStatusOf(oldchain, reply)
|
||||||
|
new_status = {
|
||||||
|
'action': None,
|
||||||
|
'actor': None,
|
||||||
|
'comment': 'Migrated workflow state',
|
||||||
|
'review_state': old_status.get(
|
||||||
|
'review_state',
|
||||||
|
new_workflow.initial_state),
|
||||||
|
'time': DateTime()
|
||||||
|
}
|
||||||
|
workflow.setStatusOf('comment_review_workflow',
|
||||||
|
comment,
|
||||||
|
new_status)
|
||||||
|
|
||||||
|
auto_transition = new_workflow._findAutomaticTransition(
|
||||||
|
comment,
|
||||||
|
new_workflow._getWorkflowStateOf(comment))
|
||||||
|
if auto_transition is not None:
|
||||||
|
new_workflow._changeStateOf(comment, auto_transition)
|
||||||
|
else:
|
||||||
|
new_workflow.updateRoleMappingsFor(comment)
|
||||||
|
comment.reindexObject(idxs=['allowedRolesAndUsers',
|
||||||
|
'review_state'])
|
||||||
|
|
||||||
self.total_comments_migrated += 1
|
self.total_comments_migrated += 1
|
||||||
|
|
||||||
# migrate all talkbacks of the reply
|
# migrate all talkbacks of the reply
|
||||||
|
@ -46,6 +46,8 @@ from plone.app.discussion.interfaces import IConversation
|
|||||||
from plone.app.discussion.interfaces import IReplies
|
from plone.app.discussion.interfaces import IReplies
|
||||||
from plone.app.discussion.comment import Comment
|
from plone.app.discussion.comment import Comment
|
||||||
|
|
||||||
|
from AccessControl.SpecialUsers import nobody as user_nobody
|
||||||
|
|
||||||
ANNOTATION_KEY = 'plone.app.discussion:conversation'
|
ANNOTATION_KEY = 'plone.app.discussion:conversation'
|
||||||
|
|
||||||
|
|
||||||
@ -85,7 +87,9 @@ class Conversation(Traversable, Persistent, Explicit):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def total_comments(self):
|
def total_comments(self):
|
||||||
return len(self._comments)
|
public_comments = [x for x in self._comments.values() if \
|
||||||
|
user_nobody.has_permission('View', x)]
|
||||||
|
return len(public_comments)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def last_comment_date(self):
|
def last_comment_date(self):
|
||||||
|
@ -21,6 +21,14 @@ class MigrationTest(unittest.TestCase):
|
|||||||
|
|
||||||
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
|
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
|
||||||
|
|
||||||
|
def _publish(self, reply):
|
||||||
|
# publish the reply
|
||||||
|
status = self.portal.portal_workflow.getStatusOf(
|
||||||
|
'comment_review_workflow', reply).copy()
|
||||||
|
status['review_state'] = 'published'
|
||||||
|
self.portal.portal_workflow.setStatusOf(
|
||||||
|
'comment_review_workflow', reply, status)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.portal = self.layer['portal']
|
self.portal = self.layer['portal']
|
||||||
self.request = self.layer['request']
|
self.request = self.layer['request']
|
||||||
@ -53,6 +61,8 @@ class MigrationTest(unittest.TestCase):
|
|||||||
reply.setReplyTo(self.doc)
|
reply.setReplyTo(self.doc)
|
||||||
reply.creation_date = DateTime(2003, 3, 11, 9, 28, 6, 'GMT')
|
reply.creation_date = DateTime(2003, 3, 11, 9, 28, 6, 'GMT')
|
||||||
reply.modification_date = DateTime(2009, 7, 12, 19, 38, 7, 'GMT')
|
reply.modification_date = DateTime(2009, 7, 12, 19, 38, 7, 'GMT')
|
||||||
|
|
||||||
|
self._publish(reply)
|
||||||
self.assertEqual(reply.Title(), 'My Title')
|
self.assertEqual(reply.Title(), 'My Title')
|
||||||
self.assertEqual(reply.EditableBody(), 'My Text')
|
self.assertEqual(reply.EditableBody(), 'My Text')
|
||||||
self.assertTrue('Jim' in reply.listCreators())
|
self.assertTrue('Jim' in reply.listCreators())
|
||||||
@ -104,12 +114,16 @@ class MigrationTest(unittest.TestCase):
|
|||||||
talkback.createReply(title='First comment',
|
talkback.createReply(title='First comment',
|
||||||
text='This is my first comment.')
|
text='This is my first comment.')
|
||||||
comment1 = talkback.getReplies()[0]
|
comment1 = talkback.getReplies()[0]
|
||||||
|
self._publish(comment1)
|
||||||
|
|
||||||
talkback_comment1 = self.discussion.getDiscussionFor(comment1)
|
talkback_comment1 = self.discussion.getDiscussionFor(comment1)
|
||||||
|
|
||||||
# Re: First comment
|
# Re: First comment
|
||||||
talkback_comment1.createReply(title='Re: First comment',
|
talkback_comment1.createReply(title='Re: First comment',
|
||||||
text='This is my first reply.')
|
text='This is my first reply.')
|
||||||
comment1_1 = talkback_comment1.getReplies()[0]
|
comment1_1 = talkback_comment1.getReplies()[0]
|
||||||
|
self._publish(comment1_1)
|
||||||
|
|
||||||
talkback_comment1_1 = self.discussion.getDiscussionFor(comment1_1)
|
talkback_comment1_1 = self.discussion.getDiscussionFor(comment1_1)
|
||||||
|
|
||||||
self.assertEqual(len(talkback.getReplies()), 1)
|
self.assertEqual(len(talkback.getReplies()), 1)
|
||||||
@ -120,27 +134,34 @@ class MigrationTest(unittest.TestCase):
|
|||||||
talkback_comment1_1.createReply(title='Re: Re: First comment',
|
talkback_comment1_1.createReply(title='Re: Re: First comment',
|
||||||
text='This is my first re-reply.')
|
text='This is my first re-reply.')
|
||||||
comment1_1_1 = talkback_comment1_1.getReplies()[0]
|
comment1_1_1 = talkback_comment1_1.getReplies()[0]
|
||||||
|
self._publish(comment1_1_1)
|
||||||
|
|
||||||
talkback_comment1_1_1 = self.discussion.getDiscussionFor(comment1_1_1)
|
talkback_comment1_1_1 = self.discussion.getDiscussionFor(comment1_1_1)
|
||||||
|
|
||||||
# Re: Re: Re: First comment
|
# Re: Re: Re: First comment
|
||||||
talkback_comment1_1_1.createReply(title='Re: Re: Re: First comment',
|
talkback_comment1_1_1.createReply(title='Re: Re: Re: First comment',
|
||||||
text='This is my first re-re-reply.')
|
text='This is my first re-re-reply.')
|
||||||
|
self._publish(talkback_comment1_1_1.getReplies()[0])
|
||||||
|
|
||||||
# Re: First comment (2)
|
# Re: First comment (2)
|
||||||
talkback_comment1.createReply(title='Re: First comment (2)',
|
talkback_comment1.createReply(title='Re: First comment (2)',
|
||||||
text='This is my first reply (2).')
|
text='This is my first reply (2).')
|
||||||
|
self._publish(talkback_comment1.getReplies()[1])
|
||||||
|
|
||||||
# Re: First comment (3)
|
# Re: First comment (3)
|
||||||
talkback_comment1.createReply(title='Re: First comment (3)',
|
talkback_comment1.createReply(title='Re: First comment (3)',
|
||||||
text='This is my first reply (3).')
|
text='This is my first reply (3).')
|
||||||
|
self._publish(talkback_comment1.getReplies()[2])
|
||||||
|
|
||||||
# Re: First comment (4)
|
# Re: First comment (4)
|
||||||
talkback_comment1.createReply(title='Re: First comment (4)',
|
talkback_comment1.createReply(title='Re: First comment (4)',
|
||||||
text='This is my first reply (4).')
|
text='This is my first reply (4).')
|
||||||
|
self._publish(talkback_comment1.getReplies()[3])
|
||||||
|
|
||||||
# Second comment
|
# Second comment
|
||||||
talkback.createReply(title='Second comment',
|
talkback.createReply(title='Second comment',
|
||||||
text='This is my second comment.')
|
text='This is my second comment.')
|
||||||
|
self._publish(talkback.getReplies()[1])
|
||||||
|
|
||||||
# Call migration script
|
# Call migration script
|
||||||
self.view()
|
self.view()
|
||||||
|
@ -171,7 +171,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
|
|||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
# Initially we have three comments
|
# Initially we have three comments
|
||||||
self.assertEqual(self.conversation.total_comments, 3)
|
self.assertEqual(len(self.conversation.objectIds()), 3)
|
||||||
# Delete two comments with bulk actions
|
# Delete two comments with bulk actions
|
||||||
self.request.set('form.select.BulkAction', 'delete')
|
self.request.set('form.select.BulkAction', 'delete')
|
||||||
self.request.set('paths', ['/'.join(self.comment1.getPhysicalPath()),
|
self.request.set('paths', ['/'.join(self.comment1.getPhysicalPath()),
|
||||||
@ -181,7 +181,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
|
|||||||
view()
|
view()
|
||||||
|
|
||||||
# Make sure that the two comments have been deleted
|
# Make sure that the two comments have been deleted
|
||||||
self.assertEqual(self.conversation.total_comments, 1)
|
self.assertEqual(len(self.conversation.objectIds()), 1)
|
||||||
comment = self.conversation.getComments().next()
|
comment = self.conversation.getComments().next()
|
||||||
self.assertTrue(comment)
|
self.assertTrue(comment)
|
||||||
self.assertEqual(comment, self.comment2)
|
self.assertEqual(comment, self.comment2)
|
||||||
|
Loading…
Reference in New Issue
Block a user