From 46769ec5cb2a015859353a7e126af4323f9989bd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Tue, 25 Jan 2022 16:14:56 +0100
Subject: [PATCH 3/3] api: first/last name and extra_data on subscription
 create (#61064)

---
 chrono/api/serializers.py      | 10 ++++++-
 chrono/api/views.py            |  5 +++-
 tests/api/test_subscription.py | 53 +++++++++++++++++++++++++++++++---
 3 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/chrono/api/serializers.py b/chrono/api/serializers.py
index a11d3fe..ef02869 100644
--- a/chrono/api/serializers.py
+++ b/chrono/api/serializers.py
@@ -334,7 +334,15 @@ class AgendaSerializer(serializers.ModelSerializer):
 class SubscriptionSerializer(serializers.ModelSerializer):
     class Meta:
         model = Subscription
-        fields = ['user_external_id', 'date_start', 'date_end']
+        fields = [
+            'user_external_id',
+            'user_first_name',
+            'user_last_name',
+            'user_email',
+            'user_phone_number',
+            'date_start',
+            'date_end',
+        ]
 
     def validate(self, attrs):
         super().validate(attrs)
diff --git a/chrono/api/views.py b/chrono/api/views.py
index 1cf44d6..8eb236d 100644
--- a/chrono/api/views.py
+++ b/chrono/api/views.py
@@ -1890,8 +1890,11 @@ class SubscriptionAPI(APIView):
         serializer = self.serializer_class(data=request.data)
         if not serializer.is_valid():
             raise APIErrorBadRequest(N_('invalid payload'), errors=serializer.errors)
+        extra_data = {k: v for k, v in request.data.items() if k not in serializer.validated_data}
 
-        subscription = Subscription.objects.create(agenda=agenda, **serializer.validated_data)
+        subscription = Subscription.objects.create(
+            agenda=agenda, extra_data=extra_data, **serializer.validated_data
+        )
         return Response({'err': 0, 'id': subscription.pk})
 
 
diff --git a/tests/api/test_subscription.py b/tests/api/test_subscription.py
index 4f4f73b..e694eb1 100644
--- a/tests/api/test_subscription.py
+++ b/tests/api/test_subscription.py
@@ -14,26 +14,71 @@ def test_api_create_subscription(app, user):
 
     app.authorization = ('Basic', ('john.doe', 'password'))
 
-    params = {'user_external_id': 'xxx', 'date_start': '2021-09-01', 'date_end': '2021-10-01'}
+    params = {
+        'user_external_id': 'xxx',
+        'user_first_name': 'Foo',
+        'user_last_name': 'BAR',
+        'user_email': 'foo@bar.com',
+        'user_phone_number': '06',
+        'date_start': '2021-09-01',
+        'date_end': '2021-10-01',
+        'foo': 'bar',
+    }
     resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params)
     subscription = Subscription.objects.get(pk=resp.json['id'])
     assert subscription.agenda == agenda
     assert subscription.user_external_id == 'xxx'
+    assert subscription.user_first_name == 'Foo'
+    assert subscription.user_last_name == 'BAR'
+    assert subscription.user_email == 'foo@bar.com'
+    assert subscription.user_phone_number == '06'
+    assert subscription.extra_data == {'foo': 'bar'}
+    assert subscription.date_start == datetime.date(year=2021, month=9, day=1)
+    assert subscription.date_end == datetime.date(year=2021, month=10, day=1)
+
+    params = {
+        'user_external_id': 'xxx',
+        'user_first_name': 'Foo',
+        'user_last_name': 'BAR',
+        'date_start': '2021-09-01',
+        'date_end': '2021-10-01',
+    }
+    resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params)
+    subscription = Subscription.objects.get(pk=resp.json['id'])
+    assert subscription.agenda == agenda
+    assert subscription.user_external_id == 'xxx'
+    assert subscription.user_first_name == 'Foo'
+    assert subscription.user_last_name == 'BAR'
+    assert subscription.user_email == ''
+    assert subscription.user_phone_number == ''
+    assert subscription.extra_data == {}
     assert subscription.date_start == datetime.date(year=2021, month=9, day=1)
     assert subscription.date_end == datetime.date(year=2021, month=10, day=1)
 
     # check errors
     resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params={}, status=400)
     assert resp.json['err_class'] == 'invalid payload'
-    for field in ('user_external_id', 'date_start', 'date_end'):
+    for field in ('user_external_id', 'user_first_name', 'user_last_name', 'date_start', 'date_end'):
         assert 'required' in resp.json['errors'][field][0]
 
-    params = {'user_external_id': 'xxx', 'date_start': 'wrong-format', 'date_end': 'wrong-format'}
+    params = {
+        'user_external_id': 'xxx',
+        'user_first_name': 'Foo',
+        'user_last_name': 'BAR',
+        'date_start': 'wrong-format',
+        'date_end': 'wrong-format',
+    }
     resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params, status=400)
     assert resp.json['err_class'] == 'invalid payload'
     assert 'wrong format' in resp.json['errors']['date_start'][0]
     assert 'wrong format' in resp.json['errors']['date_end'][0]
 
-    params = {'user_external_id': 'xxx', 'date_start': '2021-10-01', 'date_end': '2021-09-01'}
+    params = {
+        'user_external_id': 'xxx',
+        'user_first_name': 'Foo',
+        'user_last_name': 'BAR',
+        'date_start': '2021-10-01',
+        'date_end': '2021-09-01',
+    }
     resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params, status=400)
     assert resp.json['errors']['non_field_errors'][0] == 'start_datetime must be before end_datetime'
-- 
2.34.1

