incubator-allura-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From john...@apache.org
Subject [10/42] git commit: [#6328] ticket:448 Set Message-ID for first ticket notification
Date Tue, 29 Oct 2013 22:23:11 GMT
[#6328] ticket:448 Set Message-ID for first ticket notification

When ticket is created set Message-ID: in corresponding notification to
ticket.message_id().  Thus later we can use this value in top-level
comments notifications as In-Reply-To: and References: to group emails
in one thread.


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

Branch: refs/heads/cj/6692
Commit: 0b5ceda03e77c34b9c860d66fb95a46f7a402fce
Parents: 734bf8a
Author: Igor Bondarenko <jetmind2@gmail.com>
Authored: Wed Oct 23 08:36:22 2013 +0000
Committer: Cory Johns <cjohns@slashdotmedia.com>
Committed: Thu Oct 24 18:59:28 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/mail_util.py                  |  1 +
 Allura/allura/model/notification.py             |  3 +-
 ForgeTracker/forgetracker/model/ticket.py       |  9 ++-
 .../forgetracker/tests/functional/test_root.py  | 62 +++++++++++++++++++-
 4 files changed, 70 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0b5ceda0/Allura/allura/lib/mail_util.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py
index db7ddb3..3a67e10 100644
--- a/Allura/allura/lib/mail_util.py
+++ b/Allura/allura/lib/mail_util.py
@@ -195,6 +195,7 @@ class SMTPClient(object):
             if not isinstance(in_reply_to, basestring):
                 raise TypeError('Only strings are supported now, not lists')
             message['In-Reply-To'] = Header(u'<%s>' % in_reply_to)
+            message['References'] = message['In-Reply-To']
         content = message.as_string()
         smtp_addrs = map(_parse_smtp_addr, addrs)
         smtp_addrs = [ a for a in smtp_addrs if isvalid(a) ]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0b5ceda0/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index 95b51ba..718a60f 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -184,13 +184,14 @@ class Notification(MappedClass):
                 h.get_first(idx, 'title'),
                 getattr(artifact, 'email_address', u'noreply@in.sf.net'))
             d = dict(
-                message_id=artifact.message_id(),
                 from_address=reply_to,
                 reply_to_address=reply_to,
                 subject=subject_prefix + subject,
                 text=kwargs.pop('text', subject),
                 author_id=c.user._id,
                 pubdate=datetime.utcnow())
+            if kwargs.get('message_id'):
+                d['_id'] = kwargs['message_id']
             if c.user.get_pref('email_address'):
                 d['from_address'] = '"%s" <%s>' % (
                     c.user.get_pref('display_name'),

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0b5ceda0/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index d580c43..5bd7788 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -799,7 +799,14 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
             subject = self.email_subject
             Thread.new(discussion_id=self.app_config.discussion_id,
                    ref_id=self.index_id())
-            n = Notification.post(artifact=self, topic='metadata', text=description, subject=subject)
+            # First ticket notification. Use persistend Message-ID (self.message_id()).
+            # Thus we can group notification emails in one thread later.
+            n = Notification.post(
+                    message_id=self.message_id(),
+                    artifact=self,
+                    topic='metadata',
+                    text=description,
+                    subject=subject)
             if monitoring_email and n and (not self.private or
                     self.app.config.options.get('TicketMonitoringType') in (
                         'NewTicketsOnly', 'AllTicketChanges')):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0b5ceda0/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index cfd2a61..d524563 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -2684,10 +2684,10 @@ class TestStats(TrackerTestController):
         assert_in('# tickets: 0', r.body)
 
 
-class TestNotifications(TrackerTestController):
+class TestNotificationEmailGrouping(TrackerTestController):
 
-    def test_notification_email_grouping(self):
-        ticket_view = self.new_ticket(summary='Test Ticket')
+    def test_new_ticket_message_id(self):
+        self.new_ticket(summary='Test Ticket')
         ThreadLocalORMSession.flush_all()
         M.MonQTask.run_ready()
         ThreadLocalORMSession.flush_all()
@@ -2695,3 +2695,59 @@ class TestNotifications(TrackerTestController):
         ticket = tm.Ticket.query.get(ticket_num=1)
         assert_equal(email.kwargs.message_id, ticket.message_id())
         assert_equal(email.kwargs.in_reply_to, None)
+
+    def test_comments(self):
+        ticket_view = self.new_ticket(summary='Test Ticket').follow()
+        ThreadLocalORMSession.flush_all()
+        M.MonQTask.query.remove()
+        ThreadLocalORMSession.flush_all()
+        # Messy code to add a comment
+        for f in ticket_view.html.findAll('form'):
+            if f.get('action', '').endswith('/post'):
+                break
+        post_content = 'top-level comment'
+        params = dict()
+        inputs = f.findAll('input')
+        for field in inputs:
+            if field.has_key('name'):
+                params[field['name']] = field.has_key('value') and field['value'] or ''
+        params[f.find('textarea')['name']] = post_content
+        r = self.app.post(f['action'].encode('utf-8'), params=params,
+                          headers={'Referer': '/bugs/1/'.encode("utf-8")})
+        ThreadLocalORMSession.flush_all()
+        M.MonQTask.run_ready()
+        ThreadLocalORMSession.flush_all()
+        # Check that comment notification refers ticket's message id
+        email = M.MonQTask.query.find(dict(task_name='allura.tasks.mail_tasks.sendmail')).first()
+        ticket = tm.Ticket.query.get(ticket_num=1)
+        top_level_comment = ticket.discussion_thread.posts[0]
+        top_level_comment_msg_id = ticket.url() + top_level_comment._id
+        assert_equal(email.kwargs.message_id, top_level_comment_msg_id)
+        assert_equal(email.kwargs.in_reply_to, ticket.message_id())
+
+        ThreadLocalORMSession.flush_all()
+        M.MonQTask.query.remove()
+        ThreadLocalORMSession.flush_all()
+        # Messy code to add reply
+        r = self.app.get('/bugs/1/')
+        post_link = str(r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
+        post_form = r.html.find('form', {'action': post_link + 'reply'})
+        params = dict()
+        inputs = post_form.findAll('input')
+        for field in inputs:
+            if field.has_key('name'):
+                params[field['name']] = field.has_key('value') and field['value'] or ''
+        reply_text = 'Reply to top-level-comment'
+        params[post_form.find('textarea')['name']] = reply_text
+        r = self.app.post(post_link + 'reply',
+            params=params,
+            headers={'Referer':post_link.encode("utf-8")})
+        ThreadLocalORMSession.flush_all()
+        M.MonQTask.run_ready()
+        ThreadLocalORMSession.flush_all()
+        # Check that reply notification refers top-level comment's message id
+        email = M.MonQTask.query.find(dict(task_name='allura.tasks.mail_tasks.sendmail')).first()
+        ticket = tm.Ticket.query.get(ticket_num=1)
+        reply = [post for post in ticket.discussion_thread.posts if post.text == reply_text][0]
+        assert_equal(email.kwargs.message_id, ticket.url() + reply._id)
+        assert_equal(email.kwargs.in_reply_to, top_level_comment_msg_id)


Mime
View raw message