Repository: allura
Updated Branches:
  refs/heads/db/8132 [created] c620dab54


[#8132] thread messages by References: if missing In-Reply-To:


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/c620dab5
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/c620dab5
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/c620dab5

Branch: refs/heads/db/8132
Commit: c620dab5416011096baea72b6a74fddb461ec29b
Parents: 67b553c
Author: Dave Brondsema <d...@brondsema.net>
Authored: Wed Oct 5 13:59:16 2016 -0500
Committer: Dave Brondsema <d...@brondsema.net>
Committed: Wed Oct 5 14:10:00 2016 -0500

----------------------------------------------------------------------
 Allura/allura/app.py                            |  2 +-
 ForgeDiscussion/forgediscussion/model/forum.py  | 10 +++--
 .../tests/functional/test_forum.py              | 41 +++++++++++++++++---
 3 files changed, 43 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c620dab5/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index f155514..22190e6 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -703,7 +703,7 @@ class Application(object):
                 post_id=message_id,
                 artifact_id=message_id)
             return
-        # Handle duplicates
+        # Handle duplicates (from multipart mail messages)
         post = self.PostClass.query.get(_id=message_id)
         if post:
             log.info(

http://git-wip-us.apache.org/repos/asf/allura/blob/c620dab5/ForgeDiscussion/forgediscussion/model/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/model/forum.py 
b/ForgeDiscussion/forgediscussion/model/forum.py
index 675efa2..15125dd 100644
--- a/ForgeDiscussion/forgediscussion/model/forum.py
+++ b/ForgeDiscussion/forgediscussion/model/forum.py
@@ -113,11 +113,15 @@ class Forum(M.Discussion):
         subject = '[no subject]'
         parent_id = None
         if data is not None:
+            prev_msg = None
             in_reply_to = data.get('in_reply_to')
+            references = data.get('references')
             if in_reply_to:
-                parent_id = in_reply_to[0].split('/')[-1]
-            else:
-                parent_id = None
+                prev_msg = in_reply_to[0]
+            elif references:
+                prev_msg = references[-1]
+            if prev_msg:
+                parent_id = prev_msg.split('/')[-1]
             message_id = data.get('message_id') or ''
             subject = data['headers'].get('Subject', subject)
         if parent_id is not None:

http://git-wip-us.apache.org/repos/asf/allura/blob/c620dab5/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py 
b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index 99df83b..99648ca 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -25,6 +25,8 @@ from email.mime.image import MIMEImage
 from email.mime.multipart import MIMEMultipart
 
 import pkg_resources
+import pymongo
+
 from ming.odm import ThreadLocalORMSession
 from pylons import tmpl_context as c
 
@@ -129,7 +131,11 @@ class TestForumEmail(TestController):
         M.artifact_orm_session.flush()
 
 
-class TestForumAsync(TestController):
+class TestForumMessageHandling(TestController):
+    '''
+    Tests all the "handle_message" related logic, which is what inbound emails 
run through
+    '''
+
     def setUp(self):
         TestController.setUp(self)
         self.app.get('/discussion/')
@@ -166,17 +172,37 @@ class TestForumAsync(TestController):
         posts = FM.ForumPost.query.find()
         assert_equal(posts.count(), 1)
         assert_equal(FM.ForumThread.query.get().num_replies, 1)
-        assert_equal(FM.ForumThread.query.get()
-                     .first_post_id, 'test_re...@domain.net')
+        assert_equal(FM.ForumThread.query.get().first_post_id, 
'test_re...@domain.net')
 
         post = posts.first()
         self._post('testforum', 'Test Reply', 'Nothing here, either',
-                   message_id=post.thread.url() + post._id,
+                   message_id='test_reply-m...@domain.net',
                    in_reply_to=['test_re...@domain.net'])
         assert_equal(FM.ForumThread.query.find().count(), 1)
         assert_equal(FM.ForumPost.query.find().count(), 2)
-        assert_equal(FM.ForumThread.query.get()
-                     .first_post_id, 'test_re...@domain.net')
+        assert_equal(FM.ForumThread.query.get().first_post_id, 
'test_re...@domain.net')
+
+    def test_reply_only_references_headers(self):
+        # send message missing in-reply-to header, only References header
+        self._post('testforum', 'Test Thread', 'Nothing here',
+                   message_id='first-message-id')
+        prev_post = FM.ForumPost.query.find().first()
+        thread = FM.ForumThread.query.find().first()
+
+        refs = M.Notification._references(thread, prev_post) + 
['first-message-id']
+        self._post('testforum', 'Test Thread', 'Nothing here, yet',
+                   message_id='second-message-id',
+                   references=refs)
+        assert_equal(FM.ForumThread.query.find().count(), 1)
+        assert_equal(FM.ForumPost.query.find().count(), 2)
+
+        prev_post = FM.ForumPost.query.find().sort('timestamp', 
pymongo.DESCENDING).first()
+        refs = M.Notification._references(thread, prev_post) + 
['second-message-id']
+        self._post('testforum', 'Test Reply', 'Nothing here, either',
+                   message_id='third-message-id',
+                   references=refs)
+        assert_equal(FM.ForumThread.query.find().count(), 1)
+        assert_equal(FM.ForumPost.query.find().count(), 3)
 
     def test_attach(self):
         self._post('testforum', 'Attachment Thread', 'This is a text file',
@@ -255,6 +281,9 @@ class TestForumAsync(TestController):
                           params=dict(subject='', delete='on'))
 
     def _post(self, topic, subject, body, **kw):
+        '''
+        Submit a message very similar to how incoming email works
+        '''
         message_id = kw.pop('message_id', '%s...@test.com' % random.random())
         with h.push_config(c, user=self.user):
             c.app.handle_message(

Reply via email to