- Add "create" method to MessageManager so that it calls save_mbox()
- Fix nested writable serializer issue
- Add test for the create
---
api/models.py | 19 +++++++
api/rest.py | 20 ++++---
tests/test_rest.py | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 185 insertions(+), 7 deletions(-)
diff --git a/api/models.py b/api/models.py
index e161325..e043f09 100644
--- a/api/models.py
+++ b/api/models.py
@@ -247,6 +247,25 @@ class MessageManager(models.Manager):
self.delete_subthread(r)
msg.delete()
+ def create(self, project, **validated_data):
+ mbox = validated_data.pop('mbox')
+ m = MboxMessage(mbox)
+ msg = Message(**validated_data)
+ if 'in_reply_to' not in validated_data:
+ msg.in_reply_to = m.get_in_reply_to() or ""
+ msg.stripped_subject = m.get_subject(strip_tags=True)
+ msg.version = m.get_version()
+ msg.prefixes = m.get_prefixes()
+ msg.is_series_head = m.is_series_head()
+ msg.is_patch = m.is_patch()
+ msg.patch_num = m.get_num()[0]
+ msg.project = project
+ msg.mbox = mbox
+ msg.save_mbox(mbox)
+ msg.save()
+ emit_event("MessageAdded", message=msg)
+ return msg
+
def add_message_from_mbox(self, mbox, user, project_name=None):
def find_message_projects(m):
diff --git a/api/rest.py b/api/rest.py
index fc10b46..ed40a10 100644
--- a/api/rest.py
+++ b/api/rest.py
@@ -121,6 +121,7 @@ class HyperlinkedMessageField(HyperlinkedIdentityField):
class AddressSerializer(serializers.Serializer):
name = CharField(required=False)
address = EmailField()
+
def to_representation(self, obj):
if obj[0] != obj[1]:
return {"name": obj[0], "address": obj[1]}
@@ -140,9 +141,13 @@ class BaseMessageSerializer(serializers.ModelSerializer):
fields = ('resource_uri', 'message_id', 'subject', 'date', 'sender', 'recipients')
resource_uri = HyperlinkedMessageField(view_name='messages-detail')
-
recipients = AddressSerializer(many=True)
sender = AddressSerializer()
+
+ def create(self, validated_data):
+ validated_data['recipients'] = self.fields['recipients'].create(validated_data['recipients'])
+ validated_data['sender'] = self.fields['sender'].create(validated_data['sender'])
+ return Message.objects.create(project=self.context['project'], **validated_data)
# a message_id is *not* unique, so we can only list
class BaseMessageViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
@@ -157,6 +162,11 @@ class ProjectMessagesViewSetMixin(mixins.RetrieveModelMixin):
def get_queryset(self):
return self.queryset.filter(project=self.kwargs['projects_pk'])
+ def get_serializer_context(self):
+ try:
+ return {'project': Project.objects.get(id=self.kwargs['projects_pk']), 'request': self.request}
+ except:
+ return Http404
# Series
class ReplySerializer(BaseMessageSerializer):
@@ -287,10 +297,7 @@ class MessageSerializer(BaseMessageSerializer):
class Meta:
model = Message
fields = BaseMessageSerializer.Meta.fields + ('mbox', )
-
- def get_mbox(self, obj):
- return obj.get_mbox()
- mbox = SerializerMethodField()
+ mbox = CharField()
def get_fields(self):
fields = super(MessageSerializer, self).get_fields()
@@ -312,9 +319,8 @@ class StaticTextRenderer(renderers.BaseRenderer):
return data
class MessagesViewSet(ProjectMessagesViewSetMixin,
- BaseMessageViewSet):
+ BaseMessageViewSet, mixins.CreateModelMixin):
serializer_class = MessageSerializer
-
@detail_route(renderer_classes=[StaticTextRenderer])
def mbox(self, request, *args, **kwargs):
message = self.get_object()
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 21bc2b9..a002865 100755
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -18,6 +18,7 @@ from patchewtest import PatchewTestCase, main
from api.models import Message
from api.rest import AddressSerializer
from collections import OrderedDict
+import json
class RestTest(PatchewTestCase):
def setUp(self):
@@ -256,6 +257,158 @@ class RestTest(PatchewTestCase):
self.assertEqual(resp_after.status_code, 404)
self.assertEqual(resp_reply_after.status_code, 404)
+ def test_create_message(self):
+ data = {
+ "message_id": "20171023201055.21973-11-andrew.smirnov@gmail.com",
+ "subject": "[Qemu-devel] [PATCH v2 10/27] imx_fec: Reserve full 4K "
+ "page for the register file",
+ "date": "2017-10-23T20:10:38",
+ "sender": {
+ "name": "Andrey Smirnov",
+ "address": "andrew.smirnov@gmail.com"
+ },
+ "recipients": [
+ {
+ "address": "qemu-arm@nongnu.org"
+ },
+ {
+ "name": "Peter Maydell",
+ "address": "peter.maydell@linaro.org"
+ },
+ {
+ "name": "Andrey Smirnov",
+ "address": "andrew.smirnov@gmail.com"
+ },
+ {
+ "name": "Jason Wang",
+ "address": "jasowang@redhat.com"
+ },
+ {
+ "name": "Philippe Mathieu-Daudé",
+ "address": "f4bug@amsat.org"
+ },
+ {
+ "address": "qemu-devel@nongnu.org"
+ },
+ {
+ "address": "yurovsky@gmail.com"
+ }
+ ],
+ "mbox": "From andrew.smirnov@gmail.com Mon Oct 23 20:10:38 2017\nDelivered"
+ "-To: importer@patchew.org\nReceived-SPF: temperror (zoho.com: Err"
+ "or in retrieving data from DNS) client-ip=208.118.235.17; envelop"
+ "e-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=l"
+ "ists.gnu.org;\nAuthentication-Results: mx.zohomail.com;\n\tdkim=f"
+ "ail;\n\tspf=temperror (zoho.com: Error in retrieving data from DN"
+ "S) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu."
+ "org\nReturn-Path: <qemu-devel-bounces+importer=patchew.org@nongnu"
+ ".org>\nReceived: from lists.gnu.org (208.118.235.17 [208.118.235."
+ "17]) by mx.zohomail.com\n\twith SMTPS id 1508790023478635.2925706"
+ "919272; Mon, 23 Oct 2017 13:20:23 -0700 (PDT)\nReceived: from loc"
+ "alhost ([::1]:40414 helo=lists.gnu.org)\n\tby lists.gnu.org with "
+ "esmtp (Exim 4.71)\n\t(envelope-from <qemu-devel-bounces+importer="
+ "patchew.org@nongnu.org>)\n\tid 1e6jCo-0007Cr-Ed\n\tfor importer@p"
+ "atchew.org; Mon, 23 Oct 2017 16:20:14 -0400\nReceived: from eggs."
+ "gnu.org ([2001:4830:134:3::10]:46254)\n\tby lists.gnu.org with es"
+ "mtp (Exim 4.71)\n\t(envelope-from <andrew.smirnov@gmail.com>) id "
+ "1e6j4M-0000Ia-AF\n\tfor qemu-devel@nongnu.org; Mon, 23 Oct 2017 1"
+ "6:11:32 -0400\nReceived: from Debian-exim by eggs.gnu.org with sp"
+ "am-scanned (Exim 4.71)\n\t(envelope-from <andrew.smirnov@gmail.co"
+ "m>) id 1e6j4L-0002WU-ES\n\tfor qemu-devel@nongnu.org; Mon, 23 Oct"
+ " 2017 16:11:30 -0400\nReceived: from mail-pf0-x241.google.com ([2"
+ "607:f8b0:400e:c00::241]:47361)\n\tby eggs.gnu.org with esmtps (TL"
+ "S1.0:RSA_AES_128_CBC_SHA1:16)\n\t(Exim 4.71) (envelope-from <andr"
+ "ew.smirnov@gmail.com>)\n\tid 1e6j4J-0002VQ-5h; Mon, 23 Oct 2017 1"
+ "6:11:27 -0400\nReceived: by mail-pf0-x241.google.com with SMTP id"
+ " z11so17896780pfk.4;\n\tMon, 23 Oct 2017 13:11:27 -0700 (PDT)\nRe"
+ "ceived: from squirtle.westlake.spaceflightindustries.com ([173.22"
+ "6.206.194])\n\tby smtp.gmail.com with ESMTPSA id\n\tj1sm15181623p"
+ "fj.108.2017.10.23.13.11.24\n\t(version=TLS1_2 cipher=ECDHE-RSA-CH"
+ "ACHA20-POLY1305 bits=256/256);\n\tMon, 23 Oct 2017 13:11:25 -0700"
+ " (PDT)\nDKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=g"
+ "mail.com; s=20161025;\n\th=from:to:cc:subject:date:message-id:in-"
+ "reply-to:references\n\t:mime-version:content-transfer-encoding;\n"
+ "\tbh=zmFol33kPLVHCkj7Ro+lVg1LTAQod/G9dNqJXtckibI=;\n\tb=D49+KCtse"
+ "bdshdA2kxqNqCWLEOTSRXI61CbfBrS3YYbGspt/3vTIRCLSKNhICr2UOc\n\t7BhL"
+ "XRtMKhn2gomHPqqSHOSp+hB5XtMmBNpBpkQyXMHoGkgmjg0IIF02Vzn4i2QzP8C9"
+ "\n\t0SDZb6VYnz70J5HY0KZwVfQ+Rc5qgJEfcTHzuzZ4qHcbXxPHYCGYo1yDG6bEU"
+ "LNp2sRB\n\tGekoCKine5V1Uc+8aKmIeQA3zTXj2BLYqIQFi3UdiEemj94Gs3UFkE"
+ "kV3kTtCBwBVYep\n\tCvtbjBMI4Kb2Rcyb7taNS1PwjoXo4nzyPqSftf5CtxE3FYQ"
+ "6pSHkU8H1cqi4os4RgACQ\n\t6rrA==\nX-Google-DKIM-Signature: v=1; a="
+ "rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x"
+ "-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to"
+ "\n\t:references:mime-version:content-transfer-encoding;\n\tbh=zmF"
+ "ol33kPLVHCkj7Ro+lVg1LTAQod/G9dNqJXtckibI=;\n\tb=kG94Z4+JpBMpVNtWI"
+ "ASASHAaqcxeUgqF149vlfmPjsUsUZoE69zK/Xq8lz25p+TskP\n\tu+sFtsuT//gI"
+ "M/gFEeFYPBUEECFh+cSu6vYqjvy7W+o1dt0CkQS0K4sG2a6PDeXTc7Dw\n\tYOmEE"
+ "gzEW+JtEp27yE8L5Yiur7k9cMnq6AGsLtrNa4leHN8KfnBLpZDJ1w2BTVAST/Mt\n"
+ "\tp5OmcBALM2s2PfVxV2AqFIC03+BUkFo78Yl0dJkT95uUWQvXOrYnhrJGikBOpxf"
+ "e2GEl\n\tdX/N0knNvw1ILQigiiD7mTg2pWBXXdi9ncxWFbWGav3NFgMuMj9Le7dh"
+ "Merg+f0Pqzqq\n\tuMRw==\nX-Gm-Message-State: AMCzsaVtdnaUNbjj5huOS"
+ "I8ibhSVAiVnF57PiIS4oVle1IVoBcH6i/W4\n\tsAtvFi/nF5bYIYfQxgZMU93rvm"
+ "Mn\nX-Google-Smtp-Source: ABhQp+Tw1GtSPaSw51tZkI3AfiuyluStPI8C5/3"
+ "esBqFkirOMfsjtlRNoBcr8lgEf/55RwhQLiI5mQ==\nX-Received: by 10.98.6"
+ "5.218 with SMTP id g87mr14269292pfd.105.1508789486104;\n\tMon, 23"
+ " Oct 2017 13:11:26 -0700 (PDT)\nFrom: Andrey Smirnov <andrew.smir"
+ "nov@gmail.com>\nTo: qemu-arm@nongnu.org\nDate: Mon, 23 Oct 2017 1"
+ "3:10:38 -0700\nMessage-Id: <20171023201055.21973-11-andrew.smirno"
+ "v@gmail.com>\nX-Mailer: git-send-email 2.13.5\nIn-Reply-To: <2017"
+ "1023201055.21973-1-andrew.smirnov@gmail.com>\nReferences: <201710"
+ "23201055.21973-1-andrew.smirnov@gmail.com>\nMIME-Version: 1.0\nCo"
+ "ntent-Type: text/plain; charset=\"utf-8\"\nContent-Transfer-Encod"
+ "ing: base64\nX-detected-operating-system: by eggs.gnu.org: Genre "
+ "and OS details not\n\trecognized.\nX-Received-From: 2607:f8b0:400"
+ "e:c00::241\nSubject: [Qemu-devel] [PATCH v2 10/27] imx_fec: Reser"
+ "ve full 4K page for the\n register file\nX-BeenThere: qemu-devel@"
+ "nongnu.org\nX-Mailman-Version: 2.1.21\nPrecedence: list\nList-Id:"
+ " <qemu-devel.nongnu.org>\nList-Unsubscribe: <https://lists.nongnu"
+ ".org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@n"
+ "ongnu.org?subject=unsubscribe>\nList-Archive: <http://lists.nongn"
+ "u.org/archive/html/qemu-devel/>\nList-Post: <mailto:qemu-devel@no"
+ "ngnu.org>\nList-Help: <mailto:qemu-devel-request@nongnu.org?subje"
+ "ct=help>\nList-Subscribe: <https://lists.nongnu.org/mailman/listi"
+ "nfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject"
+ "=subscribe>\nCc: Peter Maydell <peter.maydell@linaro.org>,\n\tAnd"
+ "rey Smirnov <andrew.smirnov@gmail.com>,\n\tJason Wang <jasowang@r"
+ "edhat.com>,\n\t=?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <f4bug@a"
+ "msat.org>,\n\tqemu-devel@nongnu.org, yurovsky@gmail.com\nErrors-T"
+ "o: qemu-devel-bounces+importer=patchew.org@nongnu.org\nSender: \""
+ "Qemu-devel\" <qemu-devel-bounces+importer=patchew.org@nongnu.org>"
+ "\nX-ZohoMail-DKIM: fail (Header signature does not verify)\nX-Zoh"
+ "oMail: RDKM_2 RSF_6 Z_629925259 SPT_0\n\nU29tZSBpLk1YIFNvQ3MgKG"
+ "UuZy4gaS5NWDcpIGhhdmUgRkVDIHJlZ2lzdGVycyBnb2luZyBhcyBm\nYXIgYXMgb"
+ "2Zmc2V0CjB4NjE0LCBzbyB0byBhdm9pZCBnZXR0aW5nIGFib3J0cyB3aGVuIGFjY2"
+ "Vz\nc2luZyB0aG9zZSBvbiBRRU1VLCBleHRlbmQKdGhlIHJlZ2lzdGVyIGZpbGUgd"
+ "G8gY292ZXIgNEtC\nIG9mIGFkZHJlc3Mgc3BhY2UgaW5zdGVhZCBvZiBqdXN0IDFL"
+ "LgoKQ2M6IFBldGVyIE1heWRlbGwg\nPHBldGVyLm1heWRlbGxAbGluYXJvLm9yZz4"
+ "KQ2M6IEphc29uIFdhbmcgPGphc293YW5nQHJlZGhh\ndC5jb20+CkNjOiBQaGlsaX"
+ "BwZSBNYXRoaWV1LURhdWTDqSA8ZjRidWdAYW1zYXQub3JnPgpDYzog\ncWVtdS1kZ"
+ "XZlbEBub25nbnUub3JnCkNjOiBxZW11LWFybUBub25nbnUub3JnCkNjOiB5dXJvdn"
+ "Nr\neUBnbWFpbC5jb20KU2lnbmVkLW9mZi1ieTogQW5kcmV5IFNtaXJub3YgPGFuZ"
+ "HJldy5zbWlybm92\nQGdtYWlsLmNvbT4KLS0tCiBody9uZXQvaW14X2ZlYy5jIHwg"
+ "MiArLQogMSBmaWxlIGNoYW5nZWQs\nIDEgaW5zZXJ0aW9uKCspLCAxIGRlbGV0aW9"
+ "uKC0pCgpkaWZmIC0tZ2l0IGEvaHcvbmV0L2lteF9m\nZWMuYyBiL2h3L25ldC9pbX"
+ "hfZmVjLmMKaW5kZXggNDhkMDEyY2FkNi4uZTIzNmJjOTMzYyAxMDA2\nNDQKLS0tI"
+ "GEvaHcvbmV0L2lteF9mZWMuYworKysgYi9ody9uZXQvaW14X2ZlYy5jCkBAIC0xMj"
+ "Uy\nLDcgKzEyNTIsNyBAQCBzdGF0aWMgdm9pZCBpbXhfZXRoX3JlYWxpemUoRGV2a"
+ "WNlU3RhdGUgKmRl\ndiwgRXJyb3IgKiplcnJwKQogICAgIFN5c0J1c0RldmljZSAq"
+ "c2JkID0gU1lTX0JVU19ERVZJQ0Uo\nZGV2KTsKIAogICAgIG1lbW9yeV9yZWdpb25"
+ "faW5pdF9pbygmcy0+aW9tZW0sIE9CSkVDVChkZXYp\nLCAmaW14X2V0aF9vcHMsIH"
+ "MsCi0gICAgICAgICAgICAgICAgICAgICAgICAgIFRZUEVfSU1YX0ZF\nQywgMHg0M"
+ "DApOworICAgICAgICAgICAgICAgICAgICAgICAgICBUWVBFX0lNWF9GRUMsIDB4MT"
+ "Aw\nMCk7CiAgICAgc3lzYnVzX2luaXRfbW1pbyhzYmQsICZzLT5pb21lbSk7CiAgI"
+ "CAgc3lzYnVzX2lu\naXRfaXJxKHNiZCwgJnMtPmlycVswXSk7CiAgICAgc3lzYnVz"
+ "X2luaXRfaXJxKHNiZCwgJnMtPmly\ncVsxXSk7Ci0tIAoyLjEzLjUKCgo=\n\n"
+ }
+
+ resp = self.api_client.post(self.PROJECT_BASE + "messages/", json.dumps(data), content_type='application/json')
+ self.assertEqual(resp.status_code, 201)
+ resp_get = self.api_client.get(self.PROJECT_BASE + "messages/20171023201055.21973-11-andrew.smirnov@gmail.com/")
+ self.assertEqual(resp_get.status_code, 200)
+ self.assertEqual(resp.data['subject'], "[Qemu-devel] [PATCH v2 10/27] imx_fec: Reserve full 4K "
+ "page for the register file")
+
+
def test_message(self):
series = self.apply_and_retrieve('0001-simple-patch.mbox.gz',
self.p.id, '20160628014747.20971-1-famz@redhat.com')
--
2.14.3 (Apple Git-98)
_______________________________________________
Patchew-devel mailing list
Patchew-devel@redhat.com
https://www.redhat.com/mailman/listinfo/patchew-devel
On 08/05/2018 13:50, Shubham Jain wrote: > - Add "create" method to MessageManager so that it calls save_mbox() > - Fix nested writable serializer issue > - Add test for the create A better commit message could be "Creation of a message is handled by the new "create" method in MessageManager, which also takes care of calling save_mbox(). The code currently has some code duplication with add_message_from_mbox(), which will be fixed soon. The "create" name follows Django idioms more closely and is what DRF expects. However, due to the nested AddressSerializer, the CreateModelMixin is not enough, we have to define a "create" method in BaseMessageSerializer too." The idea is to describe what you are actually doing and also say why you're doing. Paolo > --- > api/models.py | 19 +++++++ > api/rest.py | 20 ++++--- > tests/test_rest.py | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 185 insertions(+), 7 deletions(-) _______________________________________________ Patchew-devel mailing list Patchew-devel@redhat.com https://www.redhat.com/mailman/listinfo/patchew-devel
Alright. Will keep this in mind from next time. :) On Tue, May 8, 2018 at 6:50 PM Paolo Bonzini <pbonzini@redhat.com> wrote: > On 08/05/2018 13:50, Shubham Jain wrote: > > - Add "create" method to MessageManager so that it calls save_mbox() > > - Fix nested writable serializer issue > > - Add test for the create > > A better commit message could be > > "Creation of a message is handled by the new "create" method in > MessageManager, which also takes care of calling save_mbox(). The code > currently has some code duplication with add_message_from_mbox(), which > will be fixed soon. The "create" name follows Django idioms more > closely and is what DRF expects. > > However, due to the nested AddressSerializer, the CreateModelMixin is > not enough, we have to define a "create" method in BaseMessageSerializer > too." > > The idea is to describe what you are actually doing and also say why > you're doing. > > Paolo > > > --- > > api/models.py | 19 +++++++ > > api/rest.py | 20 ++++--- > > tests/test_rest.py | 153 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 185 insertions(+), 7 deletions(-) > > _______________________________________________ Patchew-devel mailing list Patchew-devel@redhat.com https://www.redhat.com/mailman/listinfo/patchew-devel
© 2016 - 2024 Red Hat, Inc.