Repository: pycontribs/jira

Issue:
Support new ability to suppress notifications on update
In [JRA-34423](https://jira.atlassian.com/browse/JRA-34423), Atlassian added the ability to suppress notifications on a per-update basis.  The implementation appears to be via a query string parameter (notifyUsers=false) on the update POST, per [the docs](https://docs.atlassian.com/jira/REST/cloud/#api/2/issue-editIssue).  It would be great if we could toggle that switch via the issue.update() method.



Discussion:
Sure, PR are welcomed.

Should this be part of the update method?  Or should it be it's own method, e.g. issue.set_notify_user(False)?


Resolving patch:
diff --git a/examples/basic_use.py b/examples/basic_use.py
--- a/examples/basic_use.py
+++ b/examples/basic_use.py
@@ -30,6 +30,9 @@
 issue.update(
     summary="I'm different!", description='Changed the summary to be different.')
 
+# Change the issue without sending updates
+issue.update(notify=False, description='Quiet summary update.')
+
 # You can update the entire labels field like this
 issue.update(labels=['AAA', 'BBB'])
 
diff --git a/jira/resources.py b/jira/resources.py
--- a/jira/resources.py
+++ b/jira/resources.py
@@ -172,7 +172,7 @@ def _get_url(self, path):
         options.update({'path': path})
         return self._base_url.format(**options)
 
-    def update(self, fields=None, async=None, jira=None, **kwargs):
+    def update(self, fields=None, async=None, jira=None, notify=True, **kwargs):
         """
         Update this resource on the server. Keyword arguments are marshalled into a dict before being sent. If this
         resource doesn't support ``PUT``, a :py:exc:`.JIRAError` will be raised; subclasses that specialize this method
@@ -190,8 +190,13 @@ def update(self, fields=None, async=None, jira=None, **kwargs):
 
         data = json.dumps(data)
 
+        if not notify:
+            querystring = "?notifyUsers=false"
+        else:
+            querystring = ""
+
         r = self._session.put(
-            self.self, data=data)
+            self.self + querystring, data=data)
         if 'autofix' in self._options and \
                 r.status_code == 400:
             user = None
@@ -399,7 +404,7 @@ def __init__(self, options, session, raw=None):
         if raw:
             self._parse_raw(raw)
 
-    def update(self, fields=None, update=None, async=None, jira=None, **fieldargs):
+    def update(self, fields=None, update=None, async=None, jira=None, notify=True, **fieldargs):
         """
         Update this issue on the server.
 
@@ -448,7 +453,7 @@ def update(self, fields=None, update=None, async=None, jira=None, **fieldargs):
             else:
                 fields_dict[field] = value
 
-        super(Issue, self).update(async=async, jira=jira, fields=data)
+        super(Issue, self).update(async=async, jira=jira, notify=notify, fields=data)
 
     def add_field_value(self, field, value):
         """


Test patch:
diff --git a/tests/tests.py b/tests/tests.py
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -768,6 +768,16 @@ def test_update_with_bad_label(self):
 
         self.assertRaises(JIRAError, issue.update, fields=fields)
 
+    @not_on_custom_jira_instance
+    def test_update_with_notify_false(self):
+        issue = self.jira.create_issue(project=self.project_b,
+                                       summary='Test issue for updating',
+                                       description='Will be updated shortly',
+                                       issuetype={'name': 'Bug'})
+        issue.update(notify=False, description='Now updated, but silently')
+        self.assertEqual(issue.fields.description, 'Now updated, but silently')
+        issue.delete()
+
     def test_delete(self):
         issue = self.jira.create_issue(project=self.project_b,
                                        summary='Test issue created',