]> git.ipfire.org Git - thirdparty/patchwork.git/commitdiff
api: Show all headers with the same key
authorVeronika Kabatova <vkabatov@redhat.com>
Fri, 6 Apr 2018 11:24:49 +0000 (13:24 +0200)
committerStephen Finucane <stephen@that.guru>
Wed, 25 Apr 2018 20:04:23 +0000 (21:04 +0100)
While the code on our side returns all (key, value) pairs for email
headers, Django's REST framework probably uses dictionaries behind the
scenes. This means that having multiple headers with same key (eg
'Received', which is totally valid and common situation), only one of
these headers is visible in the REST API.

Let's hack around this by returning a list of values in case the key is
present multiple times.

Signed-off-by: Veronika Kabatova <vkabatov@redhat.com>
Reviewed-by: Stephen Finucane <stephen@that.guru>
patchwork/api/cover.py
patchwork/api/patch.py
patchwork/tests/api/test_cover.py
patchwork/tests/api/test_patch.py

index fc7ae97ba8f2de523eb96c467f688210e0e70376..46eab870e34eb8faa60049185ad40214e1defb29 100644 (file)
@@ -60,8 +60,18 @@ class CoverLetterDetailSerializer(CoverLetterListSerializer):
     headers = SerializerMethodField()
 
     def get_headers(self, instance):
+        headers = {}
+
         if instance.headers:
-            return email.parser.Parser().parsestr(instance.headers, True)
+            parsed = email.parser.Parser().parsestr(instance.headers, True)
+            for key in parsed.keys():
+                headers[key] = parsed.get_all(key)
+                # Let's return a single string instead of a list if only one
+                # header with this key is present
+                if len(headers[key]) == 1:
+                    headers[key] = headers[key][0]
+
+        return headers
 
     class Meta:
         model = CoverLetter
index 115feffae74b64385a1bbe80fd910b6fc866da68..645b0e9de2c1a1ff658ad13e78fe456459181f40 100644 (file)
@@ -123,8 +123,18 @@ class PatchDetailSerializer(PatchListSerializer):
     prefixes = SerializerMethodField()
 
     def get_headers(self, patch):
+        headers = {}
+
         if patch.headers:
-            return email.parser.Parser().parsestr(patch.headers, True)
+            parsed = email.parser.Parser().parsestr(patch.headers, True)
+            for key in parsed.keys():
+                headers[key] = parsed.get_all(key)
+                # Let's return a single string instead of a list if only one
+                # header with this key is present
+                if len(headers[key]) == 1:
+                    headers[key] = headers[key][0]
+
+        return headers
 
     def get_prefixes(self, instance):
         return clean_subject(instance.name)[1]
index 3135b7e66bb3a8402665587ef93ff01a2c95525c..4c0c5284dd4e8b2334320a5633a8e3ca076e2e6e 100644 (file)
@@ -17,6 +17,7 @@
 # along with Patchwork; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+import email.parser
 import unittest
 
 from django.conf import settings
@@ -109,12 +110,21 @@ class TestCoverLetterAPI(APITestCase):
 
     def test_detail(self):
         """Validate we can get a specific cover letter."""
-        cover_obj = create_cover()
+        cover_obj = create_cover(
+            headers='Received: from somewhere\nReceived: from another place'
+        )
 
         resp = self.client.get(self.api_url(cover_obj.id))
         self.assertEqual(status.HTTP_200_OK, resp.status_code)
         self.assertSerialized(cover_obj, resp.data)
 
+        # Make sure we don't regress and all headers with the same key are
+        # included in the response
+        parsed_headers = email.parser.Parser().parsestr(cover_obj.headers,
+                                                        True)
+        for key, value in parsed_headers.items():
+            self.assertIn(value, resp.data['headers'][key])
+
     def test_create_update_delete(self):
         user = create_maintainer()
         user.is_superuser = True
index 909c1eb420b2da1fd7b4590ac1c62f2b38c80652..40ca777166b91db43ba71d8cd3b411233563c576 100644 (file)
@@ -17,6 +17,7 @@
 # along with Patchwork; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+import email.parser
 from email.utils import make_msgid
 import unittest
 
@@ -120,12 +121,20 @@ class TestPatchAPI(APITestCase):
     def test_detail(self):
         """Validate we can get a specific patch."""
         patch = create_patch(
-            content='Reviewed-by: Test User <test@example.com>\n')
+            content='Reviewed-by: Test User <test@example.com>\n',
+            headers='Received: from somewhere\nReceived: from another place'
+        )
 
         resp = self.client.get(self.api_url(patch.id))
         self.assertEqual(status.HTTP_200_OK, resp.status_code)
         self.assertSerialized(patch, resp.data)
-        self.assertEqual(patch.headers, resp.data['headers'] or '')
+
+        # Make sure we don't regress and all headers with the same key are
+        # included in the response
+        parsed_headers = email.parser.Parser().parsestr(patch.headers, True)
+        for key, value in parsed_headers.items():
+            self.assertIn(value, resp.data['headers'][key])
+
         self.assertEqual(patch.content, resp.data['content'])
         self.assertEqual(patch.diff, resp.data['diff'])
         self.assertEqual(0, len(resp.data['tags']))