Explorar o código

fix(api): properly return mandate reference for donations, fixes #530

The response is generated from serializer.data, which is based on only
request data until .save() is called.  After that, is contains a
representation of the instance created during the .save() call.

This commit moves the instance creation from the view to the .save()
call so that the .data logistics works properly (without actually
saving anything).
Peter Thomassen %!s(int64=4) %!d(string=hai) anos
pai
achega
888dcc0a2a
Modificáronse 3 ficheiros con 27 adicións e 2 borrados
  1. 3 0
      api/desecapi/serializers.py
  2. 23 1
      api/desecapi/tests/test_donations.py
  3. 1 1
      api/desecapi/views.py

+ 3 - 0
api/desecapi/serializers.py

@@ -601,6 +601,9 @@ class DonationSerializer(serializers.ModelSerializer):
     def validate_iban(value):
     def validate_iban(value):
         return re.sub(r'[\s]', '', value)
         return re.sub(r'[\s]', '', value)
 
 
+    def create(self, validated_data):
+        return self.Meta.model(**validated_data)
+
 
 
 class UserSerializer(serializers.ModelSerializer):
 class UserSerializer(serializers.ModelSerializer):
 
 

+ 23 - 1
api/desecapi/tests/test_donations.py

@@ -12,7 +12,26 @@ class DonationTests(DesecTestCase):
             response = method(reverse('v1:donation'))
             response = method(reverse('v1:donation'))
             self.assertStatus(response, status.HTTP_405_METHOD_NOT_ALLOWED)
             self.assertStatus(response, status.HTTP_405_METHOD_NOT_ALLOWED)
 
 
-    def test_create_donation(self):
+    def test_create_donation_minimal(self):
+        url = reverse('v1:donation')
+        data = {
+            'name': 'Name',
+            'iban': 'DE89370400440532013000',
+            'amount': 123.45,
+        }
+        response = self.client.post(url, data)
+        self.assertTrue(mail.outbox)
+        email_internal = str(mail.outbox[0].message())
+        direct_debit = str(mail.outbox[0].attachments[0][1])
+        self.assertStatus(response, status.HTTP_201_CREATED)
+        self.assertEqual(len(mail.outbox), 1)
+        self.assertEqual(response.data['iban'], data['iban'])
+        self.assertEqual(response.data['interval'], 0)
+        self.assertIn('ONDON1', response.data['mref'])
+        self.assertTrue('Name' in direct_debit)
+        self.assertTrue(data['iban'] in email_internal)
+
+    def test_create_donation_verbose(self):
         url = reverse('v1:donation')
         url = reverse('v1:donation')
         data = {
         data = {
             'name': 'Komplizierter Vörnämü-ßßß 马大为',
             'name': 'Komplizierter Vörnämü-ßßß 马大为',
@@ -21,6 +40,7 @@ class DonationTests(DesecTestCase):
             'amount': 123.45,
             'amount': 123.45,
             'message': 'hi there, thank you. Also, some random chars:  ™ • ½ ¼ ¾ ⅓ ⅔ † ‡ µ ¢ £ € « » ♤ ♧ ♥ ♢ ¿ ',
             'message': 'hi there, thank you. Also, some random chars:  ™ • ½ ¼ ¾ ⅓ ⅔ † ‡ µ ¢ £ € « » ♤ ♧ ♥ ♢ ¿ ',
             'email': 'email@example.com',
             'email': 'email@example.com',
+            'interval': 3,
         }
         }
         response = self.client.post(url, data)
         response = self.client.post(url, data)
         self.assertTrue(mail.outbox)
         self.assertTrue(mail.outbox)
@@ -29,5 +49,7 @@ class DonationTests(DesecTestCase):
         self.assertStatus(response, status.HTTP_201_CREATED)
         self.assertStatus(response, status.HTTP_201_CREATED)
         self.assertEqual(len(mail.outbox), 2)
         self.assertEqual(len(mail.outbox), 2)
         self.assertEqual(response.data['iban'], data['iban'])
         self.assertEqual(response.data['iban'], data['iban'])
+        self.assertEqual(response.data['interval'], 3)
+        self.assertIn('ONDON1', response.data['mref'])
         self.assertTrue('Komplizierter Vornamu' in direct_debit)
         self.assertTrue('Komplizierter Vornamu' in direct_debit)
         self.assertTrue(data['iban'] in email_internal)
         self.assertTrue(data['iban'] in email_internal)

+ 1 - 1
api/desecapi/views.py

@@ -391,7 +391,7 @@ class DonationList(generics.CreateAPIView):
     serializer_class = serializers.DonationSerializer
     serializer_class = serializers.DonationSerializer
 
 
     def perform_create(self, serializer):
     def perform_create(self, serializer):
-        instance = self.serializer_class.Meta.model(**serializer.validated_data)
+        instance = serializer.save()
 
 
         context = {
         context = {
             'donation': instance,
             'donation': instance,