Merge commit 877f2d3e84 which has been accidentially purged.

This commit is contained in:
Timo Stollenwerk 2012-03-15 19:06:23 +01:00
commit c76ef0523e
3 changed files with 170 additions and 4 deletions

View File

@ -4,6 +4,11 @@ Changelog
2.1.5 (unreleased) 2.1.5 (unreleased)
------------------ ------------------
- Redirect to "/view" for Image, File and anything listed as requiring
a view in the url to properly display comments.
[eleddy]
- Make comments and controlpanel views more robust, so they don't break if no - Make comments and controlpanel views more robust, so they don't break if no
workflow is assigned to the 'Discussion Item' content type. workflow is assigned to the 'Discussion Item' content type.
[timo] [timo]

View File

@ -1,6 +1,7 @@
from Acquisition import aq_inner, aq_parent from Acquisition import aq_inner, aq_parent
from Products.Five.browser import BrowserView from Products.Five.browser import BrowserView
from Products.CMFCore.utils import getToolByName
class View(BrowserView): class View(BrowserView):
@ -22,7 +23,17 @@ class View(BrowserView):
def __call__(self): def __call__(self):
context = aq_inner(self.context) context = aq_inner(self.context)
self.request.response.redirect( ptool = getToolByName(context, 'portal_properties')
aq_parent(aq_parent(context)).absolute_url() + view_action_types = ptool.site_properties.typesUseViewActionInListings
'#' + str(context.id) obj = aq_parent(aq_parent(context))
) url = obj.absolute_url()
"""
Image and File types, as well as many other customized archetypes
require /view be appended to the url to see the comments, otherwise it
will redirect right to the binary object, bypassing comments.
"""
if obj.portal_type in view_action_types:
url = "%s/view" % url
self.request.response.redirect('%s#%s' % (url, context.id))

View File

@ -186,6 +186,156 @@ class CommentTest(unittest.TestCase):
self.assertEqual('http://nohost/plone/doc1/++conversation++default/' + self.assertEqual('http://nohost/plone/doc1/++conversation++default/' +
str(new_comment1_id), comment.absolute_url()) str(new_comment1_id), comment.absolute_url())
def test_view_blob_types(self):
"""
Make sure that traversal to images/files redirects to the
version of the url with a /view in it.
"""
self.portal.invokeFactory(id='image1',
title='Image',
type_name='Image')
conversation = IConversation(self.portal.image1)
comment1 = createObject('plone.Comment')
comment1.text = 'Comment text'
new_comment1_id = conversation.addComment(comment1)
comment = self.portal.image1.restrictedTraverse(
'++conversation++default/%s' % new_comment1_id)
view = View(comment, self.request)
View.__call__(view)
response = self.request.response
self.assertIn("/view", response.headers['location'])
def test_workflow(self):
"""Basic test for the 'comment_review_workflow'
"""
self.portal.portal_workflow.setChainForPortalTypes(
('Discussion Item',),
('comment_review_workflow,'))
conversation = IConversation(self.portal.doc1)
comment1 = createObject('plone.Comment')
new_comment1_id = conversation.addComment(comment1)
comment = conversation[new_comment1_id]
# Make sure comments use the 'comment_review_workflow'
chain = self.portal.portal_workflow.getChainFor(comment)
self.assertEqual(('comment_review_workflow',), chain)
# Ensure the initial state was entered and recorded
self.assertEqual(1,
len(comment.workflow_history['comment_review_workflow']))
self.assertEqual(None,
comment.workflow_history['comment_review_workflow'][0]['action'])
self.assertEqual('pending',
self.portal.portal_workflow.getInfoFor(comment, 'review_state'))
def test_fti(self):
# test that we can look up an FTI for Discussion Item
self.assertTrue("Discussion Item" in
self.portal.portal_types.objectIds())
comment1 = createObject('plone.Comment')
fti = self.portal.portal_types.getTypeInfo(comment1)
self.assertEqual('Discussion Item', fti.getTypeInfo(comment1).getId())
def test_view(self):
# make sure that the comment view is there and redirects to the right
# URL
# 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)
# Create a comment
comment1 = createObject('plone.Comment')
comment1.text = 'Comment text'
# Add comment to the conversation
new_comment1_id = conversation.addComment(comment1)
comment = self.portal.doc1.restrictedTraverse(
'++conversation++default/%s' % new_comment1_id)
# make sure the view is there
self.assertTrue(getMultiAdapter((comment, self.request),
name='view'))
# make sure the HTTP redirect (status code 302) works when a comment
# is called directly
view = View(comment, self.request)
View.__call__(view)
self.assertEqual(self.request.response.status, 302)
def test_workflow(self):
"""Basic test for the 'comment_review_workflow'
"""
self.portal.portal_workflow.setChainForPortalTypes(
('Discussion Item',),
('comment_review_workflow,'))
conversation = IConversation(self.portal.doc1)
comment1 = createObject('plone.Comment')
new_comment1_id = conversation.addComment(comment1)
comment = conversation[new_comment1_id]
# Make sure comments use the 'comment_review_workflow'
chain = self.portal.portal_workflow.getChainFor(comment)
self.assertEqual(('comment_review_workflow',), chain)
# Ensure the initial state was entered and recorded
self.assertEqual(1,
len(comment.workflow_history['comment_review_workflow']))
self.assertEqual(None,
comment.workflow_history['comment_review_workflow'][0]['action'])
self.assertEqual('pending',
self.portal.portal_workflow.getInfoFor(comment, 'review_state'))
def test_fti(self):
# test that we can look up an FTI for Discussion Item
self.assertTrue("Discussion Item" in
self.portal.portal_types.objectIds())
comment1 = createObject('plone.Comment')
fti = self.portal.portal_types.getTypeInfo(comment1)
self.assertEqual('Discussion Item', fti.getTypeInfo(comment1).getId())
def test_view(self):
# make sure that the comment view is there and redirects to the right
# URL
# 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)
# Create a comment
comment1 = createObject('plone.Comment')
comment1.text = 'Comment text'
# Add comment to the conversation
new_comment1_id = conversation.addComment(comment1)
comment = self.portal.doc1.restrictedTraverse(
'++conversation++default/%s' % new_comment1_id)
# make sure the view is there
self.assertTrue(getMultiAdapter((comment, self.request),
name='view'))
# make sure the HTTP redirect (status code 302) works when a comment
# is called directly
view = View(comment, self.request)
View.__call__(view)
def test_workflow(self): def test_workflow(self):
"""Basic test for the 'comment_review_workflow' """Basic test for the 'comment_review_workflow'
""" """