diff --git a/CHANGES.txt b/CHANGES.txt
index 81c7da2..7329c5d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,10 @@ Changelog
2.0b2 (Unreleased)
------------------
+- Fix unindexing of comments when deleting content resulting from
+ iterating over a BTree while modifying it. Fixes #11402.
+ [rossp]
+
- Fix Missing.Value for Creator in the catalog. Fixes #11634.
[rossp]
diff --git a/plone/app/discussion/comment.py b/plone/app/discussion/comment.py
index 98d8d39..e924b60 100644
--- a/plone/app/discussion/comment.py
+++ b/plone/app/discussion/comment.py
@@ -195,14 +195,16 @@ def notify_content_object(obj, event):
'last_comment_date',
'commentators',))
+
def notify_content_object_deleted(obj, event):
"""Remove all comments of a content object when the content object has been
deleted.
"""
if IAnnotatable.providedBy(obj):
conversation = IConversation(obj)
- for comment in conversation.getComments():
- del conversation[comment.id]
+ while conversation:
+ del conversation[conversation.keys()[0]]
+
def notify_user(obj, event):
"""Tell users when a comment has been added.
diff --git a/plone/app/discussion/tests/functional_test_comments.txt b/plone/app/discussion/tests/functional_test_comments.txt
index ff96f0d..33f675e 100644
--- a/plone/app/discussion/tests/functional_test_comments.txt
+++ b/plone/app/discussion/tests/functional_test_comments.txt
@@ -35,7 +35,8 @@ Make sure we have a test user from the layer and it uses fancy characters:
>>> from Products.CMFCore.utils import getToolByName
>>> mtool = getToolByName(portal, 'portal_membership', None)
- >>> mtool.getMemberById('jim').getProperty('fullname')
+ >>> jim_fullname = mtool.getMemberById('jim').getProperty('fullname')
+ >>> jim_fullname
'Jim Fult\xc3\xb8rn'
Enable commenting.
@@ -198,11 +199,12 @@ Now we can post an anonymous comment.
Make sure special characters work as well.
>>> unprivileged_browser.open(urldoc1)
- >>> unprivileged_browser.getControl(name='form.widgets.author_name').value = "Tarek Ziadé"
+ >>> tarek_fullname = "Tarek Ziadé"
+ >>> unprivileged_browser.getControl(name='form.widgets.author_name').value = tarek_fullname
>>> unprivileged_browser.getControl(name='form.widgets.text').value = "This is an äüö comment"
>>> unprivileged_browser.getControl(name='form.buttons.comment').click()
- >>> 'Tarek Ziadé' in unprivileged_browser.contents
+ >>> tarek_fullname in unprivileged_browser.contents
True
>>> 'says' in unprivileged_browser.contents
@@ -313,6 +315,7 @@ Create a collection.
>>> browser.getControl('Save').click()
>>> print browser.contents
<...Changes saved...
+ >>> topic_url = browser.url
Set the collection criteria.
@@ -339,7 +342,40 @@ View the collection listing.
>>> browser.getLink('Anonymous on Doc1', index=1)
- >>> browser.getLink('Tarek Ziadé on Doc1')
+ >>> browser.getLink(tarek_fullname + ' on Doc1')
- >>> browser.getLink('Jim Fultørn on Doc1')
+ >>> browser.getLink(jim_fullname + ' on Doc1')
+
+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