Repository: fedora-infra/bodhi

Issue:
The Greenwave JavaScript uses the old Greenwave API
We need to refactor the [Greenwave JavaScript subject](https://github.com/fedora-infra/bodhi/blob/893a5d225fc941ec1d60c3d76e3912c6428994ba/bodhi/server/templates/update.html#L93) so that it passes objects for the NVRs and and update id, rather than just a plain list of build NVRs.

This [Python code](https://github.com/fedora-infra/bodhi/blob/893a5d225fc941ec1d60c3d76e3912c6428994ba/bodhi/server/scripts/check_policies.py#L44-L46) forms the correct subject for the current Greenwave API as an example of what the JavaScript needs to do:

```
        # See discussion on https://pagure.io/greenwave/issue/34 for why we use these subjects.
        subjects = [{'item': build.nvr, 'type': 'koji_build'} for build in update.builds]
        subjects.append({'item': update.alias, 'type': 'bodhi_update'})
```


Discussion:

Resolving patch:
diff --git a/bodhi/server/models.py b/bodhi/server/models.py
--- a/bodhi/server/models.py
+++ b/bodhi/server/models.py
@@ -1,5 +1,8 @@
-# encoding: utf-8
-
+# -*- coding: utf-8 -*-
+# Copyright © 2011-2017 Red Hat, Inc. and others.
+#
+# This file is part of Bodhi.
+#
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
 # as published by the Free Software Foundation; either version 2
@@ -1240,6 +1243,31 @@ def contains_critpath_component(builds, release_name):
 
         return False
 
+    @property
+    def greenwave_subject(self):
+        """
+        Form and return the proper Greenwave API subject field for this Update.
+
+        Returns:
+            list: A list of dictionaries that are appropriate to be passed to the Greenwave API
+                subject field for a decision about this Update.
+        """
+        # See discussion on https://pagure.io/greenwave/issue/34 for why we use these subjects.
+        subject = [{'item': build.nvr, 'type': 'koji_build'} for build in self.builds]
+        subject.append({'item': self.alias, 'type': 'bodhi_update'})
+        return subject
+
+    @property
+    def greenwave_subject_json(self):
+        """
+        Form and return the proper Greenwave API subject field for this Update as JSON.
+
+        Returns:
+            basestring: A JSON list of objects that are appropriate to be passed to the Greenwave
+                API subject field for a decision about this Update.
+        """
+        return json.dumps(self.greenwave_subject)
+
     @classmethod
     def new(cls, request, data):
         """ Create a new update """
diff --git a/bodhi/server/scripts/check_policies.py b/bodhi/server/scripts/check_policies.py
--- a/bodhi/server/scripts/check_policies.py
+++ b/bodhi/server/scripts/check_policies.py
@@ -41,13 +41,10 @@ def check():
         .filter(models.Update.status.in_(
                 [models.UpdateStatus.pending, models.UpdateStatus.testing]))
     for update in updates:
-        # See discussion on https://pagure.io/greenwave/issue/34 for why we use these subjects.
-        subjects = [{'item': build.nvr, 'type': 'koji_build'} for build in update.builds]
-        subjects.append({'item': update.alias, 'type': 'bodhi_update'})
         data = {
             'product_version': update.product_version,
             'decision_context': u'bodhi_update_push_stable',
-            'subject': subjects
+            'subject': update.greenwave_subject
         }
         api_url = '{}/decision'.format(
             config.config.get('greenwave_api_url').rstrip('/'))


Test patch:
diff --git a/bodhi/tests/server/test_models.py b/bodhi/tests/server/test_models.py
--- a/bodhi/tests/server/test_models.py
+++ b/bodhi/tests/server/test_models.py
@@ -697,6 +697,27 @@ def test_builds(self):
     def test_content_type(self):
         self.assertEqual(self.obj.content_type, model.ContentType.rpm)
 
+    def test_greenwave_subject(self):
+        """Ensure that the greenwave_subject property returns the correct value."""
+        self.obj.assign_alias()
+
+        self.assertEqual(
+            self.obj.greenwave_subject,
+            [{'item': u'TurboGears-1.0.8-3.fc11', 'type': 'koji_build'},
+             {'item': self.obj.alias, 'type': 'bodhi_update'}])
+
+    def test_greenwave_subject_json(self):
+        """Ensure that the greenwave_subject_json property returns the correct value."""
+        self.obj.assign_alias()
+
+        subject = self.obj.greenwave_subject_json
+
+        self.assertTrue(isinstance(subject, basestring))
+        self.assertEqual(
+            json.loads(subject),
+            [{'item': u'TurboGears-1.0.8-3.fc11', 'type': 'koji_build'},
+             {'item': self.obj.alias, 'type': 'bodhi_update'}])
+
     def test_mandatory_days_in_testing_critpath(self):
         """
         The Update.mandatory_days_in_testing method should be the configured value