diff --git a/plone/app/discussion/tests/functional_test_comment_review_workflow.txt b/plone/app/discussion/tests/functional_test_comment_review_workflow.txt index ce88ad0..4628341 100644 --- a/plone/app/discussion/tests/functional_test_comment_review_workflow.txt +++ b/plone/app/discussion/tests/functional_test_comment_review_workflow.txt @@ -21,10 +21,10 @@ First we have to set up some things and login. >>> browser = Browser(app) >>> browser.handleErrors = False >>> browser.addHeader('Authorization', 'Basic admin:secret') - >>> portal = layer['portal'] + >>> portal = layer['portal'] >>> portal_url = 'http://nohost/plone' -By default, only HTTP error codes (e.g. 500 Server Side Error) are shown when an +By default, only HTTP error codes (e.g. 500 Server Side Error) are shown when an error occurs on the server. To see more details, set handleErrors to False: >>> browser.handleErrors = False @@ -46,9 +46,9 @@ Enable commenting. Enable comment review workflow ------------------------------ - + Enable the 'comment review workflow' for comments. - + >>> portal.portal_workflow.setChainForPortalTypes(('Discussion Item',), ('comment_review_workflow'),) >>> portal.portal_workflow.getChainForPortalType('Discussion Item') ('comment_review_workflow',) @@ -58,12 +58,12 @@ We need to commit the transaction, otherwise setting the workflow will not work. >>> import transaction >>> transaction.commit() -Enable anonymous comments +Enable anonymous comments + + >>> browser.open(portal_url+'/@@discussion-settings') + >>> browser.getControl(name='form.widgets.anonymous_comments:list').value = [True] + >>> browser.getControl(name='form.buttons.save').click() - >>> browser.open(portal_url+'/@@discussion-settings') - >>> browser.getControl(name='form.widgets.anonymous_comments:list').value = [True] - >>> browser.getControl(name='form.buttons.save').click() - Create a public page with comments allowed. >>> browser.open(portal_url) @@ -72,7 +72,7 @@ Create a public page with comments allowed. >>> browser.getControl(name='allowDiscussion:boolean').value = True >>> browser.getControl(name='form.button.save').click() >>> urldoc = browser.url - + Check that the form has been properly submitted >>> browser.url @@ -86,25 +86,25 @@ Post some comments as anonymous user: >>> unprivileged_browser.getControl(name='form.widgets.text').value = "Second anonymous comment" >>> unprivileged_browser.getControl(name='form.buttons.comment').click() -Make sure the user gets a notification that the comment awaits moderator -approval. +Make sure the user gets a notification that the comment awaits moderator +approval. >>> 'Your comment awaits moderator approval' in unprivileged_browser.contents True - + Administrators can see all posts and comment actions >>> browser.open(urldoc) - + >>> 'Moderate comments' in browser.contents True - + >>> 'First anonymous comment' in browser.contents True >>> 'form.button.DeleteComment' in browser.contents True - + >>> 'form.button.PublishComment' in browser.contents True @@ -114,18 +114,18 @@ Anonymous user can not see any posts or comment actions >>> 'Moderate comments' in unprivileged_browser.contents False - + >>> 'First anonymous comment' in unprivileged_browser.contents False >>> 'form.button.DeleteComment' in unprivileged_browser.contents False - + >>> 'form.button.PublishComment' in unprivileged_browser.contents False - + Users with 'Review comment' permission can see unapproved comments and comment -actions. +actions. >>> browser.open(portal_url + '/logout') >>> browser.open(portal_url + '/login_form') @@ -137,13 +137,13 @@ actions. >>> 'Moderate comments' in browser.contents True - + >>> 'First anonymous comment' in browser.contents True - + >>> 'form.button.DeleteComment' in browser.contents True - + >>> 'form.button.PublishComment' in browser.contents True @@ -151,19 +151,19 @@ actions. Publish a comment in the comments view -------------------------------------- -Publish the first anonymous comment in the main comments view. The publish call -on the comment currently raises an 404 error, because of a zope.testbrowser +Publish the first anonymous comment in the main comments view. The publish call +on the comment currently raises an 404 error, because of a zope.testbrowser flaw? Though, the comment is published properly. >>> browser.open(urldoc) >>> 'First anonymous comment' in unprivileged_browser.contents False - + >>> browser.open(urldoc) >>> browser.handleErrors = True >>> browser.raiseHttpErrors = False >>> browser.getControl('Approve', index=0).click() - + >>> 'Comment approved' in browser.contents True @@ -180,8 +180,8 @@ Make sure anonyous users see the approved comment, but not the unapproved ones. Delete a comment in the comments view ------------------------------------- -Delete the second anonymous comment in the main comments view. The delete call -on the comment currently raises an 404 error, because of a zope.testbrowser +Delete the second anonymous comment in the main comments view. The delete call +on the comment currently raises an 404 error, because of a zope.testbrowser flaw? Though, the comment is deleted properly. >>> browser.open(urldoc) @@ -192,7 +192,7 @@ flaw? Though, the comment is deleted properly. >>> browser.handleErrors = True >>> browser.raiseHttpErrors = False >>> browser.getControl('Delete', index=1).click() - + >>> browser.handleErrors = False >>> browser.raiseHttpErrors = True @@ -205,4 +205,4 @@ Make sure the second comment has been deleted. >>> 'Second anonymous comment' in browser.contents False - + diff --git a/plone/app/discussion/tests/functional_test_comments.txt b/plone/app/discussion/tests/functional_test_comments.txt index 275f2d9..143ac23 100644 --- a/plone/app/discussion/tests/functional_test_comments.txt +++ b/plone/app/discussion/tests/functional_test_comments.txt @@ -2,7 +2,7 @@ plone.app.discussion ====================== -This is a functional test for the plone.app.discussion comments viewlet. +This is a functional test for the plone.app.discussion comments viewlet. We use zope.testbrowser to simulate browser interaction in order to show how the plone.app.discussion commenting works. @@ -18,10 +18,10 @@ First we have to set up some things and login. >>> browser = Browser(app) >>> browser.handleErrors = False >>> browser.addHeader('Authorization', 'Basic admin:secret') - >>> portal = layer['portal'] + >>> portal = layer['portal'] >>> portal_url = 'http://nohost/plone' -By default, only HTTP error codes (e.g. 500 Server Side Error) are shown when an +By default, only HTTP error codes (e.g. 500 Server Side Error) are shown when an error occurs on the server. To see more details, set handleErrors to False: >>> browser.handleErrors = False @@ -47,10 +47,10 @@ Enable commenting. >>> registry = queryUtility(IRegistry) >>> settings = registry.forInterface(IDiscussionSettings) >>> settings.globally_enabled = True - + >>> import transaction - >>> transaction.commit() - + >>> transaction.commit() + Create a public page with comments allowed. >>> browser.open(portal_url) @@ -59,7 +59,7 @@ Create a public page with comments allowed. >>> browser.getControl(name='allowDiscussion:boolean').value = True >>> browser.getControl(name='form.button.save').click() >>> urldoc1 = browser.url - + Check that the form has been properly submitted >>> browser.url @@ -68,17 +68,17 @@ Check that the form has been properly submitted Comment Viewlet --------------- - + Check that the old comments viewlet does not show up - + >>> 'discussion_reply_form' in browser.contents False - + Check that the comment form/viewlet shows up >>> 'formfield-form-widgets-in_reply_to' in browser.contents True - + >>> 'formfield-form-widgets-text' in browser.contents True @@ -94,18 +94,18 @@ Login as admin. Post a comment as admin. - >>> browser.getControl(name='form.widgets.text').value = "Comment from admin" + >>> browser.getControl(name='form.widgets.text').value = "Comment from admin" >>> submit = browser.getControl(name='form.buttons.comment') - >>> submit.click() + >>> submit.click() Check if comment has been added properly. - + >>> 'admin' in browser.contents True - + >>> browser.contents '...admin...says:...' - + >>> "Comment from admin" in browser.contents True @@ -120,14 +120,14 @@ Login as user (without the 'Member' role). >>> browser.getControl(name='__ac_name').value = 'johndoe' >>> browser.getControl(name='__ac_password').value = 'secret' >>> browser.getControl(name='submit').click() - + Users without the 'Reply to item' permission will not see the comment form, because they don't have the 'Reply to item' permission. By default, this permission is only granted to the 'Member' role. >>> 'form.widgets.text' in browser.contents False - + >>> 'form.buttons.comment' in browser.contents False @@ -135,7 +135,7 @@ permission is only granted to the 'Member' role. Post a comment as member ------------------------ -Login as user 'jim'. +Login as user 'jim'. >>> browser.open(portal_url + '/logout') >>> browser.open(portal_url + '/login_form') @@ -146,9 +146,9 @@ Login as user 'jim'. Post a comment as user jim. >>> browser.open(urldoc1) - >>> browser.getControl(name='form.widgets.text').value = "Comment from Jim" + >>> browser.getControl(name='form.widgets.text').value = "Comment from Jim" >>> submit = browser.getControl(name='form.buttons.comment') - >>> submit.click() + >>> submit.click() Check if the comment has been added properly. @@ -161,24 +161,24 @@ Check if the comment has been added properly. Post a comment as anonymous user -------------------------------- - -Login and post comment as Anonymous - + +Login and post comment as Anonymous + >>> unprivileged_browser.open(urldoc1) - + >>> 'Log in to add comments' in unprivileged_browser.contents True -Enable anonymous comment +Enable anonymous comment >>> browser.open(portal_url + '/logout') >>> browser.open(portal_url + '/login_form') >>> browser.getControl(name='__ac_name').value = 'admin' >>> browser.getControl(name='__ac_password').value = 'secret' >>> browser.getControl(name='submit').click() - >>> browser.open(portal_url+'/@@discussion-settings') - >>> browser.getControl(name='form.widgets.anonymous_comments:list').value = [True] - >>> browser.getControl(name='form.buttons.save').click() + >>> browser.open(portal_url+'/@@discussion-settings') + >>> browser.getControl(name='form.widgets.anonymous_comments:list').value = [True] + >>> browser.getControl(name='form.buttons.save').click() >>> browser.open(portal_url + '/logout') Now we can post an anonymous comment. @@ -186,13 +186,13 @@ Now we can post an anonymous comment. >>> unprivileged_browser.open(urldoc1) >>> unprivileged_browser.getControl(name='form.widgets.text').value = "This is an anonymous comment" >>> unprivileged_browser.getControl(name='form.buttons.comment').click() - + >>> 'Anonymous' in unprivileged_browser.contents True - + >>> 'says' in unprivileged_browser.contents True - + >>> 'This is an anonymous comment' in unprivileged_browser.contents True @@ -206,10 +206,10 @@ Make sure special characters work as well. >>> tarek_fullname in unprivileged_browser.contents True - + >>> 'says' in unprivileged_browser.contents True - + >>> 'This is an äüö comment' in unprivileged_browser.contents True @@ -230,7 +230,7 @@ Find a comment id to reply to. >>> id = re.findall('"([^"]*)"', comment_div)[2] Post a reply to an existing comment. - + >>> browser.getControl(name='form.widgets.in_reply_to').value = id >>> browser.getControl(name='form.widgets.text').value = "Reply comment" >>> browser.getControl(name='form.buttons.comment').click() @@ -239,7 +239,7 @@ Check that the reply has been posted properly. >>> 'Reply comment' in browser.contents True - + >>> 'replyTreeLevel1' in browser.contents True @@ -248,7 +248,7 @@ Post a comment with comment review workflow enabled --------------------------------------------------- Enable the 'comment review workflow' for comments. - + >>> portal.portal_workflow.setChainForPortalTypes(('Discussion Item',), ('comment_review_workflow'),) >>> portal.portal_workflow.getChainForPortalType('Discussion Item') ('comment_review_workflow',) @@ -269,8 +269,8 @@ Make sure the comment has not been published. >>> 'Comment review workflow comment' not in unprivileged_browser.contents True -Make sure the user gets a notification that the comment awaits moderator -approval. +Make sure the user gets a notification that the comment awaits moderator +approval. >>> 'Your comment awaits moderator approval' in unprivileged_browser.contents True @@ -280,7 +280,7 @@ Edit the content object after a comment has been posted ------------------------------------------------------- Make sure we still can edit the content object after a comment has been posted. -This is a regression test for http://dev.plone.org/plone/ticket/11157 +This is a regression test for http://dev.plone.org/plone/ticket/11157 (TypeError: Can't pickle objects in acquisition wrappers). Login as admin. @@ -290,7 +290,7 @@ Login as admin. >>> browser.getControl(name='__ac_name').value = 'admin' >>> browser.getControl(name='__ac_password').value = 'secret' >>> browser.getControl(name='submit').click() - + Edit the content object. >>> browser.open(urldoc1 + "/edit") @@ -298,7 +298,7 @@ Edit the content object. >>> browser.getControl(name='form.button.save').click() Make sure the edit was successful. - + >>> 'Lorem ipsum' in browser.contents True diff --git a/plone/app/discussion/tests/jsTestDriver.conf b/plone/app/discussion/tests/jsTestDriver.conf index 91f5953..c5335fb 100644 --- a/plone/app/discussion/tests/jsTestDriver.conf +++ b/plone/app/discussion/tests/jsTestDriver.conf @@ -1,19 +1,18 @@ server: http://localhost:9876 - + load: # Add these lines to load the equiv function and adapter in order, before the # tests (assuming they are saved to tests/qunit/) - qunit/equiv.js - qunit/QUnitAdapter.js - + # This is where we load the qunit tests - javascripts/*.js - + # And this loads the source files we are testing - ../browser/javascripts/*.js - + plugin: - name: "coverage" jar: "../../../../parts/jstestdriver/coverage.jar" module: "com.google.jstestdriver.coverage.CoverageModule" - \ No newline at end of file diff --git a/plone/app/discussion/tests/test_catalog.py b/plone/app/discussion/tests/test_catalog.py index 0b3e94b..d4b4513 100644 --- a/plone/app/discussion/tests/test_catalog.py +++ b/plone/app/discussion/tests/test_catalog.py @@ -13,7 +13,8 @@ from Products.CMFCore.utils import getToolByName from plone.app.testing import TEST_USER_ID, setRoles -from plone.app.discussion.testing import PLONE_APP_DISCUSSION_INTEGRATION_TESTING +from plone.app.discussion.testing import \ + PLONE_APP_DISCUSSION_INTEGRATION_TESTING from plone.app.discussion.interfaces import IConversation @@ -24,7 +25,7 @@ class CatalogSetupTest(unittest.TestCase): def setUp(self): self.portal = self.layer['portal'] - + def test_catalog_installed(self): self.assertTrue('total_comments' in self.portal.portal_catalog.indexes()) @@ -34,7 +35,7 @@ class CatalogSetupTest(unittest.TestCase): self.portal.portal_catalog.schema()) self.assertTrue('in_response_to' in self.portal.portal_catalog.schema()) - + def test_collection_criteria_installed(self): try: self.portal.portal_atct.getIndex('commentators') @@ -54,7 +55,7 @@ class ConversationCatalogTest(unittest.TestCase): self.portal.invokeFactory(id='doc1', Title='Document 1', type_name='Document') - + self.catalog = getToolByName(self.portal, 'portal_catalog') conversation = IConversation(self.portal.doc1) comment1 = createObject('plone.Comment') @@ -69,26 +70,26 @@ class ConversationCatalogTest(unittest.TestCase): self.comment_id = new_comment1_id brains = self.catalog.searchResults(dict( - path={'query': - '/'.join(self.portal.doc1.getPhysicalPath()) }, - portal_type="Document" - )) + path={'query': + '/'.join(self.portal.doc1.getPhysicalPath()) }, + portal_type="Document" + )) self.conversation = conversation self.brains = brains self.doc1_brain = brains[0] self.comment1 = comment1 self.new_comment1_id = new_comment1_id - + def test_total_comments(self): self.assertTrue('total_comments' in self.doc1_brain) self.assertEqual(self.doc1_brain.total_comments, 1) - + comment2 = createObject('plone.Comment') comment2.title = 'Comment 2' comment2.text = 'Comment text' comment2.creator = 'Emma' new_comment2_id = self.conversation.addComment(comment2) - + comment2 = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_comment2_id) comment2.reindexObject() @@ -99,12 +100,12 @@ class ConversationCatalogTest(unittest.TestCase): )) doc1_brain = brains[0] self.assertEqual(doc1_brain.total_comments, 2) - + def test_last_comment_date(self): self.assertTrue('last_comment_date' in self.doc1_brain) self.assertEqual(self.doc1_brain.last_comment_date, datetime(2006, 9, 17, 14, 18, 12)) - + # Add another comment and check if last comment date is updated. comment2 = createObject('plone.Comment') comment2.title = 'Comment 2' @@ -113,7 +114,7 @@ class ConversationCatalogTest(unittest.TestCase): comment2.creation_date = datetime(2009, 9, 17, 14, 18, 12) comment2.modification_date = datetime(2009, 9, 17, 14, 18, 12) new_comment2_id = self.conversation.addComment(comment2) - + comment2 = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_comment2_id) comment2.reindexObject() @@ -125,10 +126,10 @@ class ConversationCatalogTest(unittest.TestCase): doc1_brain = brains[0] self.assertEqual(doc1_brain.last_comment_date, datetime(2009, 9, 17, 14, 18, 12)) - + # Remove the comment again del self.conversation[new_comment2_id] - + brains = self.catalog.searchResults(dict( path={'query': '/'.join(self.portal.doc1.getPhysicalPath()) }, @@ -137,7 +138,7 @@ class ConversationCatalogTest(unittest.TestCase): doc1_brain = brains[0] self.assertEqual(doc1_brain.last_comment_date, datetime(2006, 9, 17, 14, 18, 12)) - + # remove all comments del self.conversation[self.new_comment1_id] brains = self.catalog.searchResults(dict( @@ -147,11 +148,11 @@ class ConversationCatalogTest(unittest.TestCase): )) doc1_brain = brains[0] self.assertEqual(doc1_brain.last_comment_date, None) - + def test_commentators(self): self.assertTrue('commentators' in self.doc1_brain) self.assertEqual(self.doc1_brain.commentators, ('Jim',)) - + # add another comment with another author comment2 = createObject('plone.Comment') comment2.title = 'Comment 2' @@ -159,20 +160,20 @@ class ConversationCatalogTest(unittest.TestCase): comment2.creator = 'Emma' comment2.author_username = 'Emma' new_comment2_id = self.conversation.addComment(comment2) - + comment2 = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_comment2_id) comment2.reindexObject() - + brains = self.catalog.searchResults(dict( path={'query': '/'.join(self.portal.doc1.getPhysicalPath()) }, portal_type="Document" )) doc1_brain = brains[0] - + self.assertEqual(doc1_brain.commentators, ('Emma', 'Jim')) - + # remove one comments del self.conversation[new_comment2_id] brains = self.catalog.searchResults(dict( @@ -182,7 +183,7 @@ class ConversationCatalogTest(unittest.TestCase): )) doc1_brain = brains[0] self.assertEqual(doc1_brain.commentators, ('Jim',)) - + # remove all comments del self.conversation[self.new_comment1_id] brains = self.catalog.searchResults(dict( @@ -192,7 +193,7 @@ class ConversationCatalogTest(unittest.TestCase): )) doc1_brain = brains[0] self.assertEqual(doc1_brain.commentators, ()) - + def test_conversation_indexes_not_in_comments(self): brains = self.catalog.searchResults(dict( path={'query': @@ -206,9 +207,9 @@ class ConversationCatalogTest(unittest.TestCase): class CommentCatalogTest(unittest.TestCase): - + layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING - + def setUp(self): self.portal = self.layer['portal'] setRoles(self.portal, TEST_USER_ID, ['Manager']) @@ -216,16 +217,16 @@ class CommentCatalogTest(unittest.TestCase): title='Document 1', type_name='Document') self.catalog = getToolByName(self.portal, 'portal_catalog') - + conversation = IConversation(self.portal.doc1) self.conversation = conversation - + comment1 = createObject('plone.Comment') comment1.text = 'Comment text' comment1.creator = 'Jim' new_comment1_id = conversation.addComment(comment1) self.comment_id = new_comment1_id - + # Comment brain self.comment = self.portal.doc1.restrictedTraverse( '++conversation++default/%s' % new_comment1_id) @@ -233,10 +234,10 @@ class CommentCatalogTest(unittest.TestCase): path={'query': '/'.join(self.comment.getPhysicalPath())})) self.comment_brain = brains[0] - + def test_title(self): self.assertEqual(self.comment_brain.Title, 'Jim on Document 1') - + def test_no_name_title(self): comment = createObject('plone.Comment') comment.text = 'Comment text' @@ -289,7 +290,7 @@ class CommentCatalogTest(unittest.TestCase): self.portal.manage_delObjects(["doc1"]) brains = self.catalog.searchResults({'portal_type': 'Discussion Item'}) self.assertEqual(len(brains), 0) - + def test_move_comments_when_content_object_is_moved(self): # Create two folders and a content object with a comment self.portal.invokeFactory(id='folder1', @@ -300,43 +301,46 @@ class CommentCatalogTest(unittest.TestCase): type_name='Folder') self.portal.folder1.invokeFactory(id='moveme', title='Move Me', - type_name='Document') + type_name='Document') conversation = IConversation(self.portal.folder1.moveme) comment = createObject('plone.Comment') comment_id = conversation.addComment(comment) # We need to commit here so that _p_jar isn't None and move will work transaction.savepoint(optimistic=True) - + # Move moveme from folder1 to folder2 cp = self.portal.folder1.manage_cutObjects(ids=('moveme',)) self.portal.folder2.manage_pasteObjects(cp) - - # Make sure no old comment brains are + + # Make sure no old comment brains are brains = self.catalog.searchResults(dict( - portal_type="Discussion Item", - path={'query': '/'.join(self.portal.folder1.getPhysicalPath())} - )) + portal_type="Discussion Item", + path={'query': '/'.join(self.portal.folder1.getPhysicalPath())} + )) self.assertEquals(len(brains), 0) brains = self.catalog.searchResults(dict( portal_type="Discussion Item", - path={'query': '/'.join(self.portal.folder2.getPhysicalPath())} + path={ + 'query': '/'.join(self.portal.folder2.getPhysicalPath()) + } )) - self.assertEquals(len(brains), 1) - self.assertEquals(brains[0].getPath(), - '/plone/folder2/moveme/++conversation++default/' + + self.assertEquals(len(brains), 1) + self.assertEquals(brains[0].getPath(), + '/plone/folder2/moveme/++conversation++default/' + str(comment_id)) def test_update_comments_when_content_object_is_renamed(self): # We need to commit here so that _p_jar isn't None and move will work - transaction.savepoint(optimistic=True) - + transaction.savepoint(optimistic=True) + self.portal.manage_renameObject("doc1", "doc2") - - brains = self.catalog.searchResults(portal_type = 'Discussion Item') + + brains = self.catalog.searchResults( + portal_type='Discussion Item') self.assertEquals(len(brains), 1) - self.assertEquals(brains[0].getPath(), - '/plone/doc2/++conversation++default/' + + self.assertEquals(brains[0].getPath(), + '/plone/doc2/++conversation++default/' + str(self.comment_id)) def test_clear_and_rebuild_catalog(self): diff --git a/plone/app/discussion/tests/test_comment.py b/plone/app/discussion/tests/test_comment.py index 263a99c..47722ba 100644 --- a/plone/app/discussion/tests/test_comment.py +++ b/plone/app/discussion/tests/test_comment.py @@ -13,7 +13,8 @@ from Products.CMFCore.utils import getToolByName from plone.app.testing import TEST_USER_ID, setRoles -from plone.app.discussion.testing import PLONE_APP_DISCUSSION_INTEGRATION_TESTING +from plone.app.discussion.testing import \ + PLONE_APP_DISCUSSION_INTEGRATION_TESTING from plone.app.discussion.interfaces import IComment, IConversation, IReplies @@ -23,6 +24,7 @@ from plone.app.discussion.browser.comment import View logger = logging.getLogger('plone.app.discussion.tests') logger.addHandler(logging.StreamHandler()) + class CommentTest(unittest.TestCase): layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING @@ -37,14 +39,15 @@ class CommentTest(unittest.TestCase): type_name='Document') self.catalog = getToolByName(self.portal, 'portal_catalog') self.document_brain = self.catalog.searchResults( - portal_type = 'Document')[0] + portal_type='Document')[0] def test_factory(self): comment1 = createObject('plone.Comment') self.assertTrue(IComment.providedBy(comment1)) def test_UTCDates(self): - utc_to_local_diff = datetime.datetime.now() - datetime.datetime.utcnow() + utc_to_local_diff = \ + datetime.datetime.now() - datetime.datetime.utcnow() utc_to_local_diff = abs(utc_to_local_diff.seconds) if utc_to_local_diff < 60: logger.warning("Your computer is living in a timezone where local " @@ -71,7 +74,7 @@ class CommentTest(unittest.TestCase): comment1 = createObject('plone.Comment') conversation.addComment(comment1) comment_brain = self.catalog.searchResults( - portal_type = 'Discussion Item')[0] + portal_type='Discussion Item')[0] self.assertTrue(comment_brain.UID) def test_uid_is_unique(self): @@ -81,7 +84,7 @@ class CommentTest(unittest.TestCase): comment2 = createObject('plone.Comment') conversation.addComment(comment2) brains = self.catalog.searchResults( - portal_type = 'Discussion Item') + portal_type='Discussion Item') self.assertNotEqual(brains[0].UID, brains[1].UID) def test_comment_uid_differs_from_content_uid(self): @@ -89,7 +92,7 @@ class CommentTest(unittest.TestCase): comment1 = createObject('plone.Comment') conversation.addComment(comment1) comment_brain = self.catalog.searchResults( - portal_type = 'Discussion Item')[0] + portal_type='Discussion Item')[0] self.assertNotEqual(self.document_brain.UID, comment_brain.UID) def test_title(self): @@ -131,13 +134,13 @@ class CommentTest(unittest.TestCase): Second paragraph""" self.assertEqual(comment1.getText(), "

First paragraph

Second paragraph

") - + def test_getText_escapes_HTML(self): comment1 = createObject('plone.Comment') comment1.text = """Got HTML?""" self.assertEqual(comment1.getText(), "

<b>Got HTML?</b>

") - + def test_getText_with_non_ascii_characters(self): comment1 = createObject('plone.Comment') comment1.text = u"""Umlaute sind ä, ö und ü.""" @@ -149,13 +152,13 @@ class CommentTest(unittest.TestCase): comment1.text = "Go to http://www.plone.org" self.assertEqual(comment1.getText(), "

Go to http://www.plone.org

") - + def test_getText_uses_comment_mime_type(self): comment1 = createObject('plone.Comment') comment1.text = "Go to http://www.plone.org" comment1.mime_type = 'text/x-web-intelligent' self.assertEqual(comment1.getText(), - 'Go to http://www.plone.org') + 'Go to http://www.plone.org') def test_getText_w_custom_targetMimetype(self): comment1 = createObject('plone.Comment') diff --git a/plone/app/discussion/tests/test_comments_viewlet.py b/plone/app/discussion/tests/test_comments_viewlet.py index 1b90c4c..4b2e6a8 100644 --- a/plone/app/discussion/tests/test_comments_viewlet.py +++ b/plone/app/discussion/tests/test_comments_viewlet.py @@ -35,7 +35,8 @@ from plone.app.discussion.browser.comments import CommentsViewlet from plone.app.discussion.browser.comments import CommentForm from plone.app.discussion import interfaces from plone.app.discussion.interfaces import IConversation -from plone.app.discussion.testing import PLONE_APP_DISCUSSION_INTEGRATION_TESTING +from plone.app.discussion.testing import \ + PLONE_APP_DISCUSSION_INTEGRATION_TESTING from plone.app.discussion.interfaces import IDiscussionSettings @@ -49,7 +50,7 @@ class TestCommentForm(unittest.TestCase): setRoles(self.portal, TEST_USER_ID, ['Manager']) self.portal.invokeFactory('Folder', 'test-folder') self.folder = self.portal['test-folder'] - + interface.alsoProvides( self.portal.REQUEST, interfaces.IDiscussionLayer) @@ -227,10 +228,10 @@ class TestCommentsViewlet(unittest.TestCase): self.folder = self.portal['test-folder'] interface.alsoProvides( self.request, interfaces.IDiscussionLayer) - + self.workflowTool = getToolByName(self.portal, 'portal_workflow') self.workflowTool.setDefaultChain('one_state_workflow') - + typetool = self.portal.portal_types typetool.constructContent('Document', self.portal, 'doc1') self.portal_discussion = getToolByName(self.portal, diff --git a/plone/app/discussion/tests/test_migration.py b/plone/app/discussion/tests/test_migration.py index 15f9ecc..117f497 100644 --- a/plone/app/discussion/tests/test_migration.py +++ b/plone/app/discussion/tests/test_migration.py @@ -8,14 +8,15 @@ from zope.annotation.interfaces import IAnnotations from Products.CMFCore.utils import getToolByName from plone.app.testing import TEST_USER_ID, setRoles -from plone.app.testing import logout, login -from plone.app.discussion.testing import PLONE_APP_DISCUSSION_INTEGRATION_TESTING +from plone.app.discussion.testing import \ + PLONE_APP_DISCUSSION_INTEGRATION_TESTING from plone.app.discussion.browser.migration import View from plone.app.discussion.interfaces import IConversation, IComment + class MigrationTest(unittest.TestCase): layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING @@ -37,7 +38,6 @@ class MigrationTest(unittest.TestCase): self.workflowTool.doActionFor(self.portal.doc, 'publish') self.request.set("test", True) - context = getattr(self.portal, 'doc') self.view = View(self.portal, self.request) self.workflowTool.setChainForPortalTypes(('Discussion Item',), 'comment_review_workflow') @@ -80,9 +80,9 @@ class MigrationTest(unittest.TestCase): datetime(2003, 3, 11, 9, 28, 6)) self.assertEqual(comment1.modification_date, datetime(2009, 7, 12, 19, 38, 7)) - self.assertEqual( - [{'comment': comment1, 'depth': 0, 'id': long(comment1.id)},] - , list(conversation.getThreads())) + self.assertEqual([ + {'comment': comment1, 'depth': 0, 'id': long(comment1.id)} + ], list(conversation.getThreads())) self.assertFalse(self.doc.talkback) def test_migrate_nested_comments(self): diff --git a/plone/app/discussion/tests/test_moderation_view.py b/plone/app/discussion/tests/test_moderation_view.py index 89ecc29..01d7057 100644 --- a/plone/app/discussion/tests/test_moderation_view.py +++ b/plone/app/discussion/tests/test_moderation_view.py @@ -18,9 +18,9 @@ from plone.app.discussion.interfaces import IConversation class ModerationViewTest(unittest.TestCase): - + layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING - + def setUp(self): self.app = self.layer['app'] self.portal = self.layer['portal'] @@ -41,13 +41,13 @@ class ModerationViewTest(unittest.TestCase): self.portal.portal_workflow.setChainForPortalTypes( ('Discussion Item',), 'comment_review_workflow') self.wf_tool = self.portal.portal_workflow - + def test_moderation_enabled(self): """Make sure that moderation_enabled returns true if the comment workflow implements a 'pending' state. """ # If workflow is not set, enabled must return False - self.wf_tool.setChainForPortalTypes(('Discussion Item',),()) + self.wf_tool.setChainForPortalTypes(('Discussion Item',), ()) self.assertEqual(self.view.moderation_enabled(), False) # The one_state_workflow does not have a 'pending' state self.wf_tool.setChainForPortalTypes(('Discussion Item',), @@ -57,13 +57,15 @@ class ModerationViewTest(unittest.TestCase): self.wf_tool.setChainForPortalTypes(('Discussion Item',), ('comment_review_workflow,')) self.assertEqual(self.view.moderation_enabled(), True) - + def test_old_comments_not_shown_in_moderation_view(self): # Create old comment discussion = getToolByName(self.portal, 'portal_discussion', None) discussion.overrideDiscussionFor(self.portal.doc1, 1) talkback = discussion.getDiscussionFor(self.portal.doc1) - self.portal.doc1.talkback.createReply('My Title', 'My Text', Creator='Jim') + self.portal.doc1.talkback.createReply('My Title', + 'My Text', + Creator='Jim') reply = talkback.getReplies()[0] reply.setReplyTo(self.portal.doc1) reply.creation_date = DateTime(2003, 3, 11, 9, 28, 6) @@ -73,12 +75,13 @@ class ModerationViewTest(unittest.TestCase): self.assertTrue('Jim' in reply.listCreators()) self.assertEqual(talkback.replyCount(self.portal.doc1), 1) self.assertEqual(reply.inReplyTo(), self.portal.doc1) - + view = self.view() - + self.assertTrue('No comments to moderate' in view) self.assertEqual(len(self.view.comments), 0) + class ModerationBulkActionsViewTest(unittest.TestCase): layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING @@ -126,17 +129,17 @@ class ModerationBulkActionsViewTest(unittest.TestCase): # Make sure no error is raised when no bulk actions has been supplied self.request.set('form.select.BulkAction', '-1') self.request.set('paths', ['/'.join(self.comment1.getPhysicalPath())]) - + view = BulkActionsView(self.portal, self.request) - + self.assertFalse(view()) - + def test_retract(self): self.request.set('form.select.BulkAction', 'retract') self.request.set('paths', ['/'.join(self.comment1.getPhysicalPath())]) - + view = BulkActionsView(self.portal, self.request) - + self.assertRaises(NotImplementedError, view) @@ -144,9 +147,9 @@ class ModerationBulkActionsViewTest(unittest.TestCase): self.request.set('form.select.BulkAction', 'publish') self.request.set('paths', ['/'.join(self.comment1.getPhysicalPath())]) view = BulkActionsView(self.portal, self.request) - + view() - + # Count published comments published_comments = 0 for r in self.conversation.getThreads(): @@ -156,16 +159,16 @@ class ModerationBulkActionsViewTest(unittest.TestCase): published_comments += 1 # Make sure the comment has been published self.assertEqual(published_comments, 1) - + def test_mark_as_spam(self): self.request.set('form.select.BulkAction', 'mark_as_spam') self.request.set('paths', ['/'.join(self.comment1.getPhysicalPath())]) - + view = BulkActionsView(self.portal, self.request) - + self.assertRaises(NotImplementedError, view) - + def test_delete(self): # Initially we have three comments self.assertEqual(self.conversation.total_comments, 3) @@ -174,14 +177,15 @@ class ModerationBulkActionsViewTest(unittest.TestCase): self.request.set('paths', ['/'.join(self.comment1.getPhysicalPath()), '/'.join(self.comment3.getPhysicalPath())]) view = BulkActionsView(self.app, self.request) - + view() - + # Make sure that the two comments have been deleted self.assertEqual(self.conversation.total_comments, 1) comment = self.conversation.getComments().next() self.assertTrue(comment) self.assertEqual(comment, self.comment2) + def test_suite(): return unittest.defaultTestLoader.loadTestsFromName(__name__) diff --git a/plone/app/discussion/tests/test_notifications.py b/plone/app/discussion/tests/test_notifications.py index 25277de..5210170 100644 --- a/plone/app/discussion/tests/test_notifications.py +++ b/plone/app/discussion/tests/test_notifications.py @@ -24,7 +24,7 @@ from plone.app.discussion.testing import\ class TestUserNotificationUnit(unittest.TestCase): layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING - + def setUp(self): self.portal = self.layer['portal'] setRoles(self.portal, TEST_USER_ID, ['Manager']) @@ -46,16 +46,16 @@ class TestUserNotificationUnit(unittest.TestCase): self.portal_discussion = self.portal.portal_discussion # Archetypes content types store data as utf-8 encoded strings # The missing u in front of a string is therefor not missing - self.portal.doc1.title = 'Kölle Alaaf' # What is "Fasching"? + self.portal.doc1.title = 'Kölle Alaaf' # What is "Fasching"? self.conversation = IConversation(self.portal.doc1) - + def beforeTearDown(self): self.portal.MailHost = self.portal._original_MailHost sm = getSiteManager(context=self.portal) sm.unregisterUtility(provided=IMailHost) sm.registerUtility(aq_base(self.portal._original_MailHost), provided=IMailHost) - + def test_notify_user(self): # Add a comment with user notification enabled. Add another comment # and make sure an email is send to the user of the first comment. @@ -66,9 +66,9 @@ class TestUserNotificationUnit(unittest.TestCase): self.conversation.addComment(comment) comment = createObject('plone.Comment') comment.text = 'Comment text' - + comment_id = self.conversation.addComment(comment) - + self.assertEqual(len(self.mailhost.messages), 1) self.assertTrue(self.mailhost.messages[0]) msg = str(self.mailhost.messages[0]) @@ -84,13 +84,13 @@ class TestUserNotificationUnit(unittest.TestCase): "A comment on \'K=C3=B6lle Alaaf\' has been posted here:" in msg) self.assertTrue( - "http://nohost/plone/d=\noc1/view#%s" + "http://nohost/plone/d=\noc1/view#%s" % comment_id in msg) self.assertTrue('Comment text' in msg) self.assertFalse('Approve comment' in msg) self.assertFalse('Delete comment' in msg) - + def test_do_not_notify_user_when_notification_is_disabled(self): registry = queryUtility(IRegistry) registry['plone.app.discussion.interfaces.IDiscussionSettings.' + @@ -102,11 +102,11 @@ class TestUserNotificationUnit(unittest.TestCase): self.conversation.addComment(comment) comment = createObject('plone.Comment') comment.text = 'Comment text' - + self.conversation.addComment(comment) - + self.assertEqual(len(self.mailhost.messages), 0) - + def test_do_not_notify_user_when_email_address_is_given(self): comment = createObject('plone.Comment') comment.text = 'Comment text' @@ -114,11 +114,11 @@ class TestUserNotificationUnit(unittest.TestCase): self.conversation.addComment(comment) comment = createObject('plone.Comment') comment.text = 'Comment text' - + self.conversation.addComment(comment) - + self.assertEqual(len(self.mailhost.messages), 0) - + def test_do_not_notify_user_when_no_sender_is_available(self): # Set sender mail address to none and make sure no email is send to # the moderator. @@ -130,11 +130,11 @@ class TestUserNotificationUnit(unittest.TestCase): self.conversation.addComment(comment) comment = createObject('plone.Comment') comment.text = 'Comment text' - + self.conversation.addComment(comment) - + self.assertEqual(len(self.mailhost.messages), 0) - + def test_notify_only_once(self): # When a user has added two comments in a conversation and has # both times requested email notification, do not send him two @@ -148,9 +148,9 @@ class TestUserNotificationUnit(unittest.TestCase): comment.text = 'Comment text' comment.user_notification = True comment.author_email = "john@plone.test" - + self.conversation.addComment(comment) - + # Note that we might want to get rid of this message, as the # new comment is added by the same user. self.assertEqual(len(self.mailhost.messages), 1) @@ -161,7 +161,7 @@ class TestUserNotificationUnit(unittest.TestCase): class TestModeratorNotificationUnit(unittest.TestCase): layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING - + def setUp(self): self.portal = self.layer['portal'] setRoles(self.portal, TEST_USER_ID, ['Manager']) @@ -188,23 +188,23 @@ class TestModeratorNotificationUnit(unittest.TestCase): self.portal_discussion = self.portal.portal_discussion # Archetypes content types store data as utf-8 encoded strings # The missing u in front of a string is therefor not missing - self.portal.doc1.title = 'Kölle Alaaf' # What is "Fasching"? + self.portal.doc1.title = 'Kölle Alaaf' # What is "Fasching"? self.conversation = IConversation(self.portal.doc1) - + def beforeTearDown(self): self.portal.MailHost = self.portal._original_MailHost sm = getSiteManager(context=self.portal) sm.unregisterUtility(provided=IMailHost) sm.registerUtility(aq_base(self.portal._original_MailHost), provided=IMailHost) - + def test_notify_moderator(self): # Add a comment and make sure an email is send to the moderator. comment = createObject('plone.Comment') comment.text = 'Comment text' - + comment_id = self.conversation.addComment(comment) - + self.assertEqual(len(self.mailhost.messages), 1) self.assertTrue(self.mailhost.messages[0]) msg = self.mailhost.messages[0] @@ -220,7 +220,7 @@ class TestModeratorNotificationUnit(unittest.TestCase): "A comment on \'K=C3=B6lle Alaaf\' has been posted here:" in msg) self.assertTrue( - "http://nohost/plone/d=\noc1/view#%s" + "http://nohost/plone/d=\noc1/view#%s" % comment_id in msg) self.assertTrue('Comment text' in msg) @@ -230,7 +230,7 @@ class TestModeratorNotificationUnit(unittest.TestCase): self.assertTrue( 'Delete comment:\nhttp://nohost/plone/doc1/++conversation++default/%s/@@moderat=\ne-delete-comment' % comment_id in msg) - + def test_notify_moderator_specific_address(self): # A moderator email address can be specified in the control panel. registry = queryUtility(IRegistry) @@ -238,27 +238,27 @@ class TestModeratorNotificationUnit(unittest.TestCase): '.moderator_email'] = 'test@example.com' comment = createObject('plone.Comment') comment.text = 'Comment text' - + self.conversation.addComment(comment) - + self.assertEqual(len(self.mailhost.messages), 1) msg = self.mailhost.messages[0] if not isinstance(msg, str): self.assertTrue('test@example.com' in msg.mto) else: self.assertTrue('To: test@example.com' in msg) - + def test_do_not_notify_moderator_when_no_sender_is_available(self): # Set sender mail address to nonw and make sure no email is send to the # moderator. self.portal.email_from_address = None comment = createObject('plone.Comment') comment.text = 'Comment text' - + self.conversation.addComment(comment) - + self.assertEqual(len(self.mailhost.messages), 0) - + def test_do_not_notify_moderator_when_notification_is_disabled(self): # Disable moderator notification setting and make sure no email is send # to the moderator. @@ -267,10 +267,11 @@ class TestModeratorNotificationUnit(unittest.TestCase): 'moderator_notification_enabled'] = False comment = createObject('plone.Comment') comment.text = 'Comment text' - + self.conversation.addComment(comment) - + self.assertEqual(len(self.mailhost.messages), 0) + def test_suite(): return unittest.defaultTestLoader.loadTestsFromName(__name__) diff --git a/plone/app/discussion/tests/test_workflow.py b/plone/app/discussion/tests/test_workflow.py index becc3e7..27d10be 100644 --- a/plone/app/discussion/tests/test_workflow.py +++ b/plone/app/discussion/tests/test_workflow.py @@ -15,7 +15,8 @@ from Products.CMFCore.permissions import View from plone.app.testing import TEST_USER_ID, setRoles from plone.app.testing import logout, login -from plone.app.discussion.testing import PLONE_APP_DISCUSSION_INTEGRATION_TESTING +from plone.app.discussion.testing import \ + PLONE_APP_DISCUSSION_INTEGRATION_TESTING from plone.app.discussion.interfaces import IConversation, IDiscussionLayer @@ -105,7 +106,7 @@ class CommentOneStateWorkflowTest(unittest.TestCase): self.portal = self.layer['portal'] setRoles(self.portal, TEST_USER_ID, ['Manager']) self.portal.invokeFactory('Folder', 'test-folder') - self.folder = self.portal['test-folder'] + self.folder = self.portal['test-folder'] self.catalog = self.portal.portal_catalog self.workflow = self.portal.portal_workflow self.workflow.setChainForPortalTypes(['Document'], @@ -125,7 +126,7 @@ class CommentOneStateWorkflowTest(unittest.TestCase): self.portal.acl_users._doAddUser('member', 'secret', ['Member'], []) self.portal.acl_users._doAddUser('reviewer', 'secret', ['Reviewer'], []) self.portal.acl_users._doAddUser('manager', 'secret', ['Manager'], []) - self.portal.acl_users._doAddUser('editor' , ' secret', ['Editor'],[]) + self.portal.acl_users._doAddUser('editor', ' secret', ['Editor'], []) self.portal.acl_users._doAddUser('reader', 'secret', ['Reader'], []) def test_initial_workflow_state(self): @@ -163,12 +164,11 @@ class CommentReviewWorkflowTest(unittest.TestCase): layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING - def setUp(self): self.portal = self.layer['portal'] setRoles(self.portal, TEST_USER_ID, ['Manager']) self.portal.invokeFactory('Folder', 'test-folder') - self.folder = self.portal['test-folder'] + self.folder = self.portal['test-folder'] # Allow discussion on the Document content type self.portal.portal_types['Document'].allow_discussion = True