From ce823a944c83e6bbf608bdccd914ca322fd0b119 Mon Sep 17 00:00:00 2001
From: sidpremkumar <sid.premkumar@gmail.com>
Date: Jul 16 2019 15:01:47 +0000
Subject: [PATCH 1/3] adding another catch for updating descrtiption


---

diff --git a/sync2jira/downstream.py b/sync2jira/downstream.py
index f76f3c2..b054c14 100644
--- a/sync2jira/downstream.py
+++ b/sync2jira/downstream.py
@@ -862,7 +862,7 @@ def _update_description(existing, issue):
                            issue.content,
                            new_description[index1+index2+1:])
 
-    elif '] Upstream issue status:' in new_description:
+    elif '] Upstream issue status:' in new_description and '] Upstream Reporter:' not in new_description:
         # We need to add a upstream reporter and description field
         upstream_reporter = '[%s] Upstream Reporter: %s' % (
             issue.id,
@@ -877,6 +877,12 @@ def _update_description(existing, issue):
                            '\n' +
                            upstream_description +
                            new_description[index+1:])
+    elif '] Upstream issue status:' not in new_description and '] Upstream Reporter:' in new_description:
+        # We need to just add the description field
+        new_description = re.sub(
+            r'\[%s\] Upstream Reporter: %s (\w\W)*' % (issue.id, issue.reporter['fullname']),
+            r'[%s] Upstream Reporter: %s \nUpstream Description: {quote} %s {quote}' %
+            (issue.id, issue.reporter['fullname'], issue.content), new_description)
     else:
         # Just add reporter and description to the top
         upstream_reporter = '[%s] Upstream Reporter: %s' % (
@@ -891,7 +897,7 @@ def _update_description(existing, issue):
     # Now that we've updated the description (i.e. added
     # issue.id) we can delete the link in the description if its still there.
     new_description = re.sub(
-        r'\[%s\]' % issue.url,
+        r'%s' % issue.url,
         r'',
         new_description
     )

From dca62f1d643490c5b932827977fb1643e6db32d7 Mon Sep 17 00:00:00 2001
From: sidpremkumar <sid.premkumar@gmail.com>
Date: Jul 16 2019 17:11:34 +0000
Subject: [PATCH 2/3] adding regex matches to all description updates


---

diff --git a/sync2jira/downstream.py b/sync2jira/downstream.py
index b054c14..8d33ee2 100644
--- a/sync2jira/downstream.py
+++ b/sync2jira/downstream.py
@@ -844,6 +844,8 @@ def _update_tags(updates, existing, issue):
 
 def _update_description(existing, issue):
     new_description = existing.fields.description
+    if not new_description:
+        new_description = ''
     if 'Upstream description' in new_description:
         # If we just need to update the content of the description
         new_description = re.sub(
@@ -852,36 +854,31 @@ def _update_description(existing, issue):
             new_description)
     elif '] Upstream issue status:' in new_description and '] Upstream Reporter:' in new_description:
         # We need to add a description field
-        # Need to find the 2nd new line as we already have
-        # Reporter and Status
-        index1 = new_description.find('\n')
-        index2 = new_description[index1+1:].find('\n')
-        new_description = "%s \nUpstream description: " \
-                          "{quote}%s{quote}\n%s" % \
-                          (new_description[:index1+index2+1],
-                           issue.content,
-                           new_description[index1+index2+1:])
+        today = datetime.today()
+        new_description = re.sub(r'\[[\w\W]*\] Upstream issue status: %s\n\[%s\] Upstream Reporter: %s' % (
+            issue.status, issue.id, issue.reporter['fullname']),
+                                 r'[%s] Upstream issue status: %s\n[%s] Upstream Reporter: %s\n'
+                                 r'Upstream description: {quote}%s{quote}' % (
+                                     today.strftime("%a %b %y - %H:%M"), issue.status, issue.id,
+                                     issue.reporter['fullname'],
+                                     issue.content),
+                                 new_description)
 
     elif '] Upstream issue status:' in new_description and '] Upstream Reporter:' not in new_description:
         # We need to add a upstream reporter and description field
-        upstream_reporter = '[%s] Upstream Reporter: %s' % (
-            issue.id,
-            issue.reporter['fullname']
-        )
-        upstream_description = "%s \nUpstream description: " \
-                               "{quote}%s{quote}" % \
-                               (upstream_reporter, issue.content)
-        # Add it to the old description
-        index = new_description.find('\n')
-        new_description = (new_description[:index] +
-                           '\n' +
-                           upstream_description +
-                           new_description[index+1:])
+        today = datetime.today()
+        new_description = re.sub(r'\[[\w\W]*\] Upstream issue status: %s' % issue.status,
+                                 r'[%s] Upstream issue status: %s\n'
+                                 r'[%s] Upstream Reporter: %s\n'
+                                 r'Upstream description: {quote}%s{quote}' %
+                                 (today.strftime("%a %b %y - %H:%M"), issue.status, issue.id,
+                                  issue.reporter['fullname'], issue.content),
+                                 new_description)
     elif '] Upstream issue status:' not in new_description and '] Upstream Reporter:' in new_description:
         # We need to just add the description field
         new_description = re.sub(
-            r'\[%s\] Upstream Reporter: %s (\w\W)*' % (issue.id, issue.reporter['fullname']),
-            r'[%s] Upstream Reporter: %s \nUpstream Description: {quote} %s {quote}' %
+            r'\[%s\] Upstream Reporter: %s [\w\W]*' % (issue.id, issue.reporter['fullname']),
+            r'[%s] Upstream Reporter: %s \nUpstream description: {quote} %s {quote}' %
             (issue.id, issue.reporter['fullname'], issue.content), new_description)
     else:
         # Just add reporter and description to the top
diff --git a/tests/test_downstream.py b/tests/test_downstream.py
index ca729f3..6553428 100644
--- a/tests/test_downstream.py
+++ b/tests/test_downstream.py
@@ -832,12 +832,18 @@ class TestDownstream(unittest.TestCase):
             {'description': '[123] Upstream Reporter: mock_user \n'
                             'Upstream description: {quote}mock_content{quote}'})
 
-    def test_update_description_add_reporter(self):
+    @mock.patch(PATH + 'datetime')
+    def test_update_description_add_reporter(self,
+                                             mock_datetime):
         """
         This function tests '_update_description' where we have to add a description and upstream reporter field
         """
         # Set up return values
         self.mock_downstream.fields.description = '[123] Upstream issue status: Open\n'
+        self.mock_issue.status = 'Open'
+        self.mock_issue.id = '123'
+        self.mock_issue.reporter = {'fullname': 'mock_user'}
+        mock_datetime.today.return_value = self.mock_today
 
         # Call the function
         d._update_description(
@@ -845,7 +851,10 @@ class TestDownstream(unittest.TestCase):
             issue=self.mock_issue
         )
         # Assert all calls were made correctly
-        self.mock_downstream.update.assert_called_with({'description': '[123] Upstream issue status: Open\n[1234] Upstream Reporter: mock_user \nUpstream description: {quote}mock_content{quote}'})
+        self.mock_downstream.update.assert_called_with(
+            {'description': '[mock_today] Upstream issue status: Open\n[123]'
+                            ' Upstream Reporter: mock_user\nUpstream description:'
+                            ' {quote}mock_content{quote}\n'})
 
     def test_update_description_add_reporter_no_status(self):
         """
@@ -865,13 +874,19 @@ class TestDownstream(unittest.TestCase):
             {'description': '[1234] Upstream Reporter: mock_user \n'
                             'Upstream description: {quote}mock_content{quote} \n '})
 
-    def test_update_description_add_description(self):
+    @mock.patch(PATH + 'datetime')
+    def test_update_description_add_description(self,
+                                                mock_datetime):
         """
         This function tests '_update_description' where we have a reporter and status already
         """
         # Set up return values
         self.mock_downstream.fields.description = '[123] Upstream issue status: Open\n' \
                                                   '[123] Upstream Reporter: mock_user\n'
+        self.mock_issue.status = 'Open'
+        self.mock_issue.id = '123'
+        self.mock_issue.reporter = {'fullname': 'mock_user'}
+        mock_datetime.today.return_value = self.mock_today
 
         # Call the function
         d._update_description(
@@ -881,9 +896,9 @@ class TestDownstream(unittest.TestCase):
 
         # Assert all calls were made correctly
         self.mock_downstream.update.assert_called_with(
-            {'description': '[123] Upstream issue status: Open\n'
-                            '[123] Upstream Reporter: mock_user \n'
-                            'Upstream description: {quote}mock_content{quote}\n\n'})
+            {'description': '[mock_today] Upstream issue status: Open\n'
+                            '[123] Upstream Reporter: mock_user\n'
+                            'Upstream description: {quote}mock_content{quote}\n'})
 
     def test_verify_tags(self):
         """
@@ -1168,8 +1183,8 @@ class TestDownstream(unittest.TestCase):
 
 
     @mock.patch('jira.client.JIRA')
-    def check_comments_for_duplicates(self,
-                                      mock_client):
+    def test_check_comments_for_duplicates(self,
+                                           mock_client):
         """
         Tests 'check_comments_for_duplicates' function
         """
@@ -1182,7 +1197,7 @@ class TestDownstream(unittest.TestCase):
 
         # Call the function
         response = d.check_comments_for_duplicate(
-            client=self.mock_client,
+            client=mock_client,
             result=self.mock_downstream,
             username='mock_user'
         )

From 44b1f75bf901c0c2cd9920d41777426189b3e865 Mon Sep 17 00:00:00 2001
From: sidpremkumar <sid.premkumar@gmail.com>
Date: Jul 16 2019 17:28:52 +0000
Subject: [PATCH 3/3] Adding regex and upstream reporter to title update


---

diff --git a/sync2jira/downstream.py b/sync2jira/downstream.py
index 8d33ee2..042e7d9 100644
--- a/sync2jira/downstream.py
+++ b/sync2jira/downstream.py
@@ -627,9 +627,7 @@ def _update_jira_issue(existing, issue, client):
     if 'title' in updates:
         # Update the title if needed
         if issue.title != existing.fields.summary:
-            data = {'summary': issue.title}
-            existing.update(data)
-            log.info('   Updated title')
+            _update_title(issue, existing)
 
     # Only synchronize transition (status) for listings that op-in
     if any('transition' in item for item in updates):
@@ -703,6 +701,53 @@ def _update_transition(client, existing, issue):
             log.warning('   Could not update JIRA closed_status for %s' % issue.title)
 
 
+def _update_title(issue, existing):
+    """
+    Helper function to sync upstream/downstream title
+    Args:
+        issue (sync2jira.intermediary.Issue): Upstream issue
+        existing (jira.resource.Issue): Existing JIRA issue
+    Returns:
+        Nothing
+    """
+    new_description = existing.fields.description
+    if not new_description:
+        new_description = ''
+    if '] Upstream Reporter:' not in new_description:
+        # We have to add the issue ID to the description so we can find it again
+        if '] Upstream issue status:' in new_description:
+            # We have to use regex to update the upstream reporter
+            today = datetime.today()
+            new_description = re.sub(
+                r'\[[\w\W]*\] Upstream issue status: %s' % issue.status,
+                '[%s] Upstream issue status: %s\n[%s] Upstream Reporter: %s'
+                % (today.strftime("%a %b %y - %H:%M"),
+                   issue.status, issue.id, issue.reporter['fullname']),
+                new_description)
+        else:
+            # We can just add it to the top
+            new_description = '[%s] Upstream Repoter: %s' % \
+                              (issue.id, issue.reporter['fullname']) + new_description
+        # Update the description
+        # Now that we've updated the description (i.e. added
+        # issue.id) we can delete the link in the description if its still there.
+        new_description = re.sub(
+            r'%s' % issue.url,
+            r'',
+            new_description
+        )
+
+        # Now we can update the JIRA issue if we need to
+        if new_description != existing.fields.description:
+            data = {'description': new_description}
+            existing.update(data)
+            log.info('   Updated description')
+    # Then we can update the title
+    data = {'summary': issue.title}
+    existing.update(data)
+    log.info('   Updated title')
+
+
 def _update_comments(client, existing, issue):
     """
     Helper function to sync comments between existing JIRA issue and upstream issue

