Refactor tests to use the PLONE_APP_CONTENTTYPES_FIXTURE instead of the PLONE_FIXTURE. This fixes all test p.a.discussion test failures.

This commit is contained in:
Timo Stollenwerk 2013-08-29 22:20:47 +02:00
parent 645bbb0a95
commit 9049368cba
7 changed files with 149 additions and 247 deletions

View File

@ -2,7 +2,7 @@ from Products.CMFCore.utils import getToolByName
from plone.app.testing import PloneSandboxLayer from plone.app.testing import PloneSandboxLayer
from plone.app.testing import applyProfile from plone.app.testing import applyProfile
from plone.app.testing import PLONE_FIXTURE from plone.app.contenttypes.testing import PLONE_APP_CONTENTTYPES_FIXTURE
from plone.app.testing import IntegrationTesting from plone.app.testing import IntegrationTesting
from plone.app.testing import FunctionalTesting from plone.app.testing import FunctionalTesting
@ -17,7 +17,7 @@ except:
class PloneAppDiscussion(PloneSandboxLayer): class PloneAppDiscussion(PloneSandboxLayer):
defaultBases = (PLONE_FIXTURE,) defaultBases = (PLONE_APP_CONTENTTYPES_FIXTURE,)
USER_NAME = 'johndoe' USER_NAME = 'johndoe'
USER_PASSWORD = 'secret' USER_PASSWORD = 'secret'

View File

@ -0,0 +1,93 @@
XXX: This functional test part has been removed due to the removal of
ATContentTypes from PLONE_FIXTURE. We have to rewrite this test as a robot
test because the dexterity collections do not work without js.
List comments in a collection
-----------------------------
Create a collection.
>>> from plone.app.testing import setRoles
>>> from plone.app.testing import TEST_USER_NAME
>>> setRoles(portal, 'manager', ['Manager'])
>>> browser.open(portal.absolute_url())
>>> from plone.app.discussion.testing import COLLECTION_TYPE
>>> browser.getLink(url='++add++' + COLLECTION_TYPE).click()
>>> open('/tmp/testbrowser.html', 'w').write(browser.contents)
>>> import pdb; pdb.set_trace()
>>> browser.getControl('form.widgets.IDublinCore.title').value = 'Foo Comment Collection'
>>> browser.getControl('Save').click()
>>> print browser.contents
<...Changes saved...
>>> topic_url = browser.url
Set the collection criteria.
>>> browser.open(topic_url + "/edit")
>>> if COLLECTION_TYPE == "Collection":
... browser.getControl(name="addindex").value = ['portal_type']
... browser.getControl(name="form.button.addcriteria").click()
... browser.getControl(name="addoperator").value = ['plone.app.querystring.operation.selection.is']
... browser.getControl(name="form.button.addcriteria").click()
... browser.getControl(name="query.v:records:list").value = ["Discussion Item"]
... browser.getControl(name="form.button.save").click()
... else:
... browser.getLink('Criteria').click()
... browser.getControl('Item Type', index=0).selected = True
... browser.getControl('Select content types').selected = True
... browser.getControl('Add criteria').click()
... browser.getControl('Comment').selected = True
... browser.getControl('Save', index=0).click()
>>> print browser.contents
<...Changes saved...
View the collection listing.
>>> browser.getLink('View').click()
>>> browser.getLink('admin on Doc1', index=0)
<Link text='admin on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink('admin on Doc1', index=1)
<Link text='admin on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink('Anonymous on Doc1', index=0)
<Link text='Anonymous on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink('Anonymous on Doc1', index=1)
<Link text='Anonymous on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink(tarek_fullname + ' on Doc1')
<Link text='Tarek Ziad\xc3\xa9 on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink(jim_fullname + ' on Doc1')
<Link text='Jim Fult\xc3\xb8rn on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
Comments are unindexed when the content is deleted
--------------------------------------------------
Delete the commented content.
>>> browser.open(urldoc1)
>>> browser.getLink('Delete').click()
>>> browser.getControl('Delete').click()
>>> print browser.contents
<...Doc1 has been deleted...
The comments are no longer in the catalog.
>>> browser.open(topic_url)
>>> browser.getLink('admin on Doc1', index=0)
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink('admin on Doc1', index=1)
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink('Anonymous on Doc1', index=0)
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink('Anonymous on Doc1', index=1)
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink(tarek_fullname + ' on Doc1')
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink(jim_fullname + ' on Doc1')
Traceback (most recent call last):
LinkNotFoundError

View File

@ -33,6 +33,7 @@ We also keep another testbrowser handy for testing how tiles are rendered if
you're not logged in:: you're not logged in::
>>> unprivileged_browser = Browser(app) >>> unprivileged_browser = Browser(app)
>>> unprivileged_browser.handleErrors = False
Enable commenting. Enable commenting.
@ -61,22 +62,28 @@ We need to commit the transaction, otherwise setting the workflow will not work.
Enable anonymous comments Enable anonymous comments
>>> browser.open(portal_url+'/@@discussion-settings') >>> browser.open(portal_url+'/@@discussion-settings')
>>> browser.getControl(name='form.widgets.anonymous_comments:list').value = [True] >>> browser.getControl(name='form.widgets.anonymous_comments:list').value = True
>>> browser.getControl(name='form.buttons.save').click() >>> browser.getControl(name='form.buttons.save').click()
Create a public page with comments allowed. Create a public page with comments allowed.
>>> browser.open(portal_url) >>> browser.open(portal_url)
>>> browser.getLink(id='document').click() >>> browser.getLink(id='document').click()
>>> browser.getControl(name='title').value = "Doc" >>> browser.getControl(name='form.widgets.IDublinCore.title').value = "Doc"
>>> browser.getControl(name='allowDiscussion:boolean').value = True >>> browser.getControl(name='form.widgets.IAllowDiscussion.allow_discussion:list').value = ['True']
>>> browser.getControl(name='form.button.save').click() >>> browser.getControl('Save').click()
>>> urldoc = browser.url >>> urldoc = browser.url
Check that the form has been properly submitted Check that the form has been properly submitted
>>> browser.url >>> browser.url
'http://nohost/plone/doc' 'http://nohost/plone/doc/view'
Make sure the document is published:
>>> browser.getLink("Publish").click()
>>> 'Published' in browser.contents
True
Post some comments as anonymous user: Post some comments as anonymous user:
@ -223,4 +230,3 @@ Make sure the catalog has been updated properly.
>>> portal.portal_catalog.searchResults(id='doc', total_comments=0) >>> portal.portal_catalog.searchResults(id='doc', total_comments=0)
[<Products...] [<Products...]

View File

@ -30,6 +30,8 @@ We also keep another testbrowser handy for testing how tiles are rendered if
you're not logged in:: you're not logged in::
>>> unprivileged_browser = Browser(app) >>> unprivileged_browser = Browser(app)
>>> browser_member = Browser(app)
>>> browser_user = Browser(app)
Make sure we have a test user from the layer and it uses fancy characters: Make sure we have a test user from the layer and it uses fancy characters:
@ -55,11 +57,17 @@ Create a public page with comments allowed.
>>> browser.open(portal_url) >>> browser.open(portal_url)
>>> browser.getLink(id='document').click() >>> browser.getLink(id='document').click()
>>> browser.getControl(name='title').value = "Doc1" >>> browser.getControl(name='form.widgets.IDublinCore.title').value = "Doc1"
>>> browser.getControl(name='allowDiscussion:boolean').value = True >>> browser.getControl(name='form.widgets.IAllowDiscussion.allow_discussion:list').value = ['True']
>>> browser.getControl(name='form.button.save').click() >>> browser.getControl('Save').click()
>>> urldoc1 = browser.url >>> urldoc1 = browser.url
Make sure the document is published:
>>> browser.getLink("Publish").click()
>>> 'Published' in browser.contents
True
Check that the form has been properly submitted Check that the form has been properly submitted
>>> browser.url >>> browser.url
@ -115,20 +123,19 @@ Post a comment as user
Login as user (without the 'Member' role). Login as user (without the 'Member' role).
>>> browser.open(portal_url + '/logout') >>> browser_user.open(portal_url + '/login_form')
>>> browser.open(portal_url + '/login_form') >>> browser_user.getControl(name='__ac_name').value = 'johndoe'
>>> browser.getControl(name='__ac_name').value = 'johndoe' >>> browser_user.getControl(name='__ac_password').value = 'secret'
>>> browser.getControl(name='__ac_password').value = 'secret' >>> browser_user.getControl(name='submit').click()
>>> browser.getControl(name='submit').click()
Users without the 'Reply to item' permission will not see the comment form, 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 because they don't have the 'Reply to item' permission. By default, this
permission is only granted to the 'Member' role. permission is only granted to the 'Member' role.
>>> 'form.widgets.text' in browser.contents >>> 'form.widgets.text' in browser_user.contents
False False
>>> 'form.buttons.comment' in browser.contents >>> 'form.buttons.comment' in browser_user.contents
False False
@ -137,25 +144,24 @@ Post a comment as member
Login as user 'jim'. Login as user 'jim'.
>>> browser.open(portal_url + '/logout') >>> browser_member.open(portal_url + '/login_form')
>>> browser.open(portal_url + '/login_form') >>> browser_member.getControl(name='__ac_name').value = 'jim'
>>> browser.getControl(name='__ac_name').value = 'jim' >>> browser_member.getControl(name='__ac_password').value = 'secret'
>>> browser.getControl(name='__ac_password').value = 'secret' >>> browser_member.getControl(name='submit').click()
>>> browser.getControl(name='submit').click()
Post a comment as user jim. Post a comment as user jim.
>>> browser.open(urldoc1) >>> browser_member.open(urldoc1)
>>> browser.getControl(name='form.widgets.text').value = "Comment from Jim" >>> browser_member.getControl(name='form.widgets.text').value = "Comment from Jim"
>>> submit = browser.getControl(name='form.buttons.comment') >>> submit = browser_member.getControl(name='form.buttons.comment')
>>> submit.click() >>> submit.click()
Check if the comment has been added properly. Check if the comment has been added properly.
>>> browser.contents >>> browser_member.contents
'...<a href="http://nohost/plone/author/jim">Jim Fult\xc3\xb8rn</a>...says:...' '...<a href="http://nohost/plone/author/jim">Jim Fult\xc3\xb8rn</a>...says:...'
>>> "Comment from Jim" in browser.contents >>> "Comment from Jim" in browser_member.contents
True True
@ -285,7 +291,6 @@ This is a regression test for http://dev.plone.org/plone/ticket/11157
Login as admin. Login as admin.
>>> browser.open(portal_url + '/logout')
>>> browser.open(portal_url + '/login_form') >>> browser.open(portal_url + '/login_form')
>>> browser.getControl(name='__ac_name').value = 'admin' >>> browser.getControl(name='__ac_name').value = 'admin'
>>> browser.getControl(name='__ac_password').value = 'secret' >>> browser.getControl(name='__ac_password').value = 'secret'
@ -293,100 +298,11 @@ Login as admin.
Edit the content object. Edit the content object.
>>> browser.open(urldoc1 + "/edit") >>> browser.open("http://nohost/plone/doc1/edit")
>>> browser.getControl(name='text').value = "Lorem ipsum" >>> browser.getControl(name='form.widgets.text').value = "Lorem ipsum"
>>> browser.getControl(name='form.button.save').click() >>> browser.getControl('Save').click()
Make sure the edit was successful. Make sure the edit was successful.
>>> 'Lorem ipsum' in browser.contents >>> 'Lorem ipsum' in browser.contents
True True
List comments in a collection
-----------------------------
Create a collection.
>>> from plone.app.testing import setRoles
>>> from plone.app.testing import TEST_USER_NAME
>>> setRoles(portal, 'manager', ['Manager'])
>>> browser.open(portal.absolute_url())
>>> from plone.app.discussion.testing import COLLECTION_TYPE
>>> browser.getLink(url='createObject?type_name=' + COLLECTION_TYPE).click()
>>> browser.getControl('Title', index=0
... ).value = 'Foo Comment Collection'
>>> browser.getControl('Save').click()
>>> print browser.contents
<...Changes saved...
>>> topic_url = browser.url
Set the collection criteria.
>>> browser.open(topic_url + "/edit")
>>> if COLLECTION_TYPE == "Collection":
... browser.getControl(name="addindex").value = ['portal_type']
... browser.getControl(name="form.button.addcriteria").click()
... browser.getControl(name="addoperator").value = ['plone.app.querystring.operation.selection.is']
... browser.getControl(name="form.button.addcriteria").click()
... browser.getControl(name="query.v:records:list").value = ["Discussion Item"]
... browser.getControl(name="form.button.save").click()
... else:
... browser.getLink('Criteria').click()
... browser.getControl('Item Type', index=0).selected = True
... browser.getControl('Select content types').selected = True
... browser.getControl('Add criteria').click()
... browser.getControl('Comment').selected = True
... browser.getControl('Save', index=0).click()
>>> print browser.contents
<...Changes saved...
View the collection listing.
>>> browser.getLink('View').click()
>>> browser.getLink('admin on Doc1', index=0)
<Link text='admin on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink('admin on Doc1', index=1)
<Link text='admin on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink('Anonymous on Doc1', index=0)
<Link text='Anonymous on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink('Anonymous on Doc1', index=1)
<Link text='Anonymous on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink(tarek_fullname + ' on Doc1')
<Link text='Tarek Ziad\xc3\xa9 on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
>>> browser.getLink(jim_fullname + ' on Doc1')
<Link text='Jim Fult\xc3\xb8rn on Doc1' url='http://nohost/plone/doc1/++conversation++default/...'>
Comments are unindexed when the content is deleted
--------------------------------------------------
Delete the commented content.
>>> browser.open(urldoc1)
>>> browser.getLink('Delete').click()
>>> browser.getControl('Delete').click()
>>> print browser.contents
<...Doc1 has been deleted...
The comments are no longer in the catalog.
>>> browser.open(topic_url)
>>> browser.getLink('admin on Doc1', index=0)
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink('admin on Doc1', index=1)
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink('Anonymous on Doc1', index=0)
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink('Anonymous on Doc1', index=1)
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink(tarek_fullname + ' on Doc1')
Traceback (most recent call last):
LinkNotFoundError
>>> browser.getLink(jim_fullname + ' on Doc1')
Traceback (most recent call last):
LinkNotFoundError

View File

@ -59,6 +59,8 @@ class TestCommentForm(unittest.TestCase):
typetool = self.portal.portal_types typetool = self.portal.portal_types
typetool.constructContent('Document', self.portal, 'doc1') typetool.constructContent('Document', self.portal, 'doc1')
wftool = getToolByName(self.portal, "portal_workflow")
wftool.doActionFor(self.portal.doc1, action='publish')
self.discussionTool = getToolByName( self.discussionTool = getToolByName(
self.portal, self.portal,
'portal_discussion', 'portal_discussion',
@ -536,7 +538,8 @@ class TestCommentsViewlet(unittest.TestCase):
*time.gmtime(time.mktime(python_time.timetuple()))[:7] *time.gmtime(time.mktime(python_time.timetuple()))[:7]
) )
localized_time = self.viewlet.format_time(python_time) localized_time = self.viewlet.format_time(python_time)
self.assertEqual(localized_time, 'Feb 01, 2009 11:32 PM') self.assertTrue(
localized_time in ['Feb 01, 2009 11:32 PM', '2009-02-01 23:32'])
def test_suite(): def test_suite():

View File

@ -197,102 +197,16 @@ class ConversationTest(unittest.TestCase):
self.assertEqual(len(tuple(conversation.getThreads())), 0) self.assertEqual(len(tuple(conversation.getThreads())), 0)
self.assertEqual(conversation.total_comments, 0) self.assertEqual(conversation.total_comments, 0)
def test_allow_discussion(self):
# This is not a real test! It's only there to understand the
# allow discussion attribute. Maybe we should remove this at
# some point.
# 1) allow_discussion attribute: Every content object in Plone
# has a allow_discussion attribute. By default it is set to None.
# Create a conversation.
IConversation(self.portal.doc1)
# By default, discussion is disabled for all content types
portal_types = getToolByName(self.portal, 'portal_types')
for type in list(portal_types):
type_fti = getattr(portal_types, type)
if type not in BAD_TYPES:
if type != 'Discussion Item':
self.assertFalse(type_fti.allowDiscussion())
# By default, allow_discussion on newly created content objects is
# set to False
portal_discussion = getToolByName(self.portal, 'portal_discussion')
self.assertEqual(
portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
False
)
self.assertEqual(
self.portal.doc1.getTypeInfo().allowDiscussion(),
False
)
# The allow discussion flag is None by default
self.assertFalse(getattr(self.portal.doc1, 'allow_discussion', None))
# But isDiscussionAllowedFor, also checks if discussion is allowed on
# the content type. So we allow discussion on the Document content
# type and check if the Document object allows discussion now.
document_fti = getattr(portal_types, 'Document')
document_fti.manage_changeProperties(allow_discussion=True)
self.assertEqual(
portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
True
)
self.assertEqual(
self.portal.doc1.getTypeInfo().allowDiscussion(),
True
)
# We can also override the allow_discussion locally
self.portal_discussion.overrideDiscussionFor(self.portal.doc1, False)
# Check if the Document discussion is disabled
self.assertEqual(
portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
False
)
# Check that the local allow_discussion flag is now explicitly set to
# False
self.assertEqual(
getattr(self.portal.doc1, 'allow_discussion', None),
False
)
# Disallow discussion on the Document content type again
document_fti.manage_changeProperties(allow_discussion=False)
self.assertEqual(
portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
False
)
self.assertEqual(
self.portal.doc1.getTypeInfo().allowDiscussion(),
False
)
# Now we override allow_discussion again (True) for the Document
# content object
self.portal_discussion.overrideDiscussionFor(self.portal.doc1, True)
self.assertEqual(
portal_discussion.isDiscussionAllowedFor(self.portal.doc1),
True
)
self.assertEqual(
getattr(self.portal.doc1, 'allow_discussion', None),
True
)
def test_comments_enabled_on_doc_in_subfolder(self): def test_comments_enabled_on_doc_in_subfolder(self):
typetool = self.portal.portal_types typetool = self.portal.portal_types
typetool.constructContent('Folder', self.portal, 'folder1') typetool.constructContent('Folder', self.portal, 'folder1')
typetool.constructContent('Document', self.portal.folder1, 'doc2') typetool.constructContent('Document', self.portal.folder1, 'doc2')
folder = self.portal.folder1 folder = self.portal.folder1
folder.allowDiscussion(False)
self.assertFalse(hasattr(aq_base(folder), 'allow_discussion')) folder.allow_discussion = True
folder.allowDiscussion(True)
self.assertTrue(aq_base(folder).allow_discussion) self.assertTrue(aq_base(folder).allow_discussion)
folder.allowDiscussion(False) folder.allow_discussion = False
self.assertFalse(aq_base(folder).allow_discussion) self.assertFalse(aq_base(folder).allow_discussion)
doc = self.portal.folder1.doc2 doc = self.portal.folder1.doc2
@ -388,10 +302,11 @@ class ConversationTest(unittest.TestCase):
self.assertEqual(conversation.enabled(), False) self.assertEqual(conversation.enabled(), False)
def test_allow_discussion_on_folder(self): def test_allow_discussion_on_folder(self):
# The enabled method should always return False for the folder # The ATContentTypes based allow_discussion method did not allow to
# itself. # allow discussion on a folder. The dexerity behavior shipped with
# plone.app.contenttypes does not have this restriction any longer.
# Create a folderp # Create a folder
self.typetool.constructContent('Folder', self.portal, 'f1') self.typetool.constructContent('Folder', self.portal, 'f1')
f1 = self.portal.f1 f1 = self.portal.f1
# Usually we don't create a conversation on a folder # Usually we don't create a conversation on a folder
@ -405,39 +320,7 @@ class ConversationTest(unittest.TestCase):
document_fti = getattr(portal_types, 'Folder') document_fti = getattr(portal_types, 'Folder')
document_fti.manage_changeProperties(allow_discussion=True) document_fti.manage_changeProperties(allow_discussion=True)
# Always return False self.assertTrue(conversation.enabled())
self.assertFalse(conversation.enabled())
def test_is_discussion_allowed_for_folder(self):
# When a content item provides IFolderish from CMF and
# does not provide INonStructuralFolder from Plone,
# allow_discussion acts as an on/off flag for all items
# in that folder, overriding settings for any parent folders,
# and the for the FTI, but is overridden by child items and
# folders further down.
# Create a folder
self.typetool.constructContent('Folder', self.portal, 'f1')
f1 = self.portal.f1
# Create a document inside the folder
self.typetool.constructContent('Document', f1, 'doc1')
doc1 = self.portal.f1.doc1
doc1_conversation = doc1.restrictedTraverse('@@conversation_view')
self.assertEqual(doc1_conversation.enabled(), False)
# Allow commenting for the folder
self.portal_discussion.overrideDiscussionFor(f1, True)
# Check if the content objects allows discussion
self.assertEqual(doc1_conversation.enabled(), True)
# Turn commenting for the folder off
self.portal_discussion.overrideDiscussionFor(f1, False)
# Check if content objects do not allow discussion anymore
self.assertEqual(doc1_conversation.enabled(), False)
def test_is_discussion_allowed_on_content_object(self): def test_is_discussion_allowed_on_content_object(self):
# Allow discussion on a single content object # Allow discussion on a single content object

View File

@ -52,6 +52,7 @@ setup(name='plone.app.discussion',
'test': [ 'test': [
'plone.app.testing', 'plone.app.testing',
'interlude', 'interlude',
'plone.app.contenttypes',
] ]
}, },
entry_points=""" entry_points="""