From e306ec331d7c605ff6780ae9460bb8130f653d0b Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Fri, 8 Oct 2021 09:19:54 +0200
Subject: [PATCH 4/5] api: add category parameter on add agenda endpoint
 (#57670)

---
 chrono/api/serializers.py | 10 +++++++++-
 tests/api/test_all.py     |  7 +++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/chrono/api/serializers.py b/chrono/api/serializers.py
index 2974ea4..198d9eb 100644
--- a/chrono/api/serializers.py
+++ b/chrono/api/serializers.py
@@ -1,14 +1,14 @@
 from django.contrib.auth.models import Group
 from django.utils.translation import ugettext_lazy as _
 from rest_framework import serializers
 from rest_framework.exceptions import ValidationError
 
-from chrono.agendas.models import AbsenceReason, Agenda, Booking, Event
+from chrono.agendas.models import AbsenceReason, Agenda, Booking, Category, Event
 
 
 class StringOrListField(serializers.ListField):
     def to_internal_value(self, data):
         if isinstance(data, str):
             data = [s.strip() for s in data.split(',') if s.strip()]
         return super().to_internal_value(data)
 
@@ -158,43 +158,51 @@ class EventSerializer(serializers.ModelSerializer):
             'pricing',
             'url',
         ]
 
 
 class AgendaSerializer(serializers.ModelSerializer):
     edit_role = serializers.CharField(required=False, max_length=150)
     view_role = serializers.CharField(required=False, max_length=150)
+    category = serializers.SlugField(required=False, max_length=160)
 
     class Meta:
         model = Agenda
         fields = [
             'slug',
             'label',
             'kind',
             'minimal_booking_delay',
             'minimal_booking_delay_in_working_days',
             'maximal_booking_delay',
             'anonymize_delay',
             'edit_role',
             'view_role',
+            'category',
         ]
 
     def get_role(self, value):
         try:
             return Group.objects.get(name=value)
         except Group.DoesNotExist:
             raise serializers.ValidationError(_('unknown role: %s' % value))
 
     def validate_edit_role(self, value):
         return self.get_role(value)
 
     def validate_view_role(self, value):
         return self.get_role(value)
 
+    def validate_category(self, value):
+        try:
+            return Category.objects.get(slug=value)
+        except Category.DoesNotExist:
+            raise serializers.ValidationError(_('unknown category: %s' % value))
+
     def validate(self, attrs):
         super().validate(attrs)
         if attrs['minimal_booking_delay_in_working_days'] and attrs.get('kind', 'events') != 'events':
             raise ValidationError(
                 {
                     'minimal_booking_delay_in_working_days': _('Option not available on %s agenda')
                     % attrs['kind']
                 }
diff --git a/tests/api/test_all.py b/tests/api/test_all.py
index 6cd4430..071a46a 100644
--- a/tests/api/test_all.py
+++ b/tests/api/test_all.py
@@ -598,16 +598,17 @@ def test_virtual_agendas_meetingtypes_api(app):
                 },
             },
         ]
     }
 
 
 @pytest.mark.freeze_time('2021-07-09')
 def test_add_agenda(app, user, settings):
+    category_a = Category.objects.create(label='Category A')
     api_url = '/api/agenda/'
 
     # no authentication
     resp = app.post(api_url, status=401)
     assert resp.json['detail'] == 'Authentication credentials were not provided.'
 
     # wrong password
     app.authorization = ('Basic', ('john.doe', 'wrong'))
@@ -626,26 +627,28 @@ def test_add_agenda(app, user, settings):
         'label': 'foo',
         'slug': 'foo',
         'kind': 'oups',
         'minimal_booking_delay': 'oups',
         'minimal_booking_delay_in_working_days': 'oups',
         'anonymize_delay': 'oups',
         'edit_role': 'oups',
         'view_role': 'plop',
+        'category': 'oups',
     }
     resp = app.post(api_url, params=params, status=400)
     assert resp.json['err']
     assert resp.json['errors'] == {
         'kind': ['"oups" is not a valid choice.'],
         'minimal_booking_delay': ['A valid integer is required.'],
         'minimal_booking_delay_in_working_days': ['Must be a valid boolean.'],
         'anonymize_delay': ['A valid integer is required.'],
         'edit_role': ['unknown role: oups'],
         'view_role': ['unknown role: plop'],
+        'category': ['unknown category: oups'],
     }
 
     # slug already used
     meeting_agenda = Agenda(label='Foo bar Meeting', kind='meetings')
     meeting_agenda.save()
     params = {
         'label': 'foo',
         'slug': meeting_agenda.slug,
@@ -687,36 +690,40 @@ def test_add_agenda(app, user, settings):
         'label': 'foo Meetings',
         'slug': 'foo-meetings',
         'kind': 'meetings',
         'minimal_booking_delay': 1,
         'maximal_booking_delay': 3,
         'anonymize_delay': 30,
         'edit_role': 'Edit',
         'view_role': 'View',
+        'category': 'category-a',
     }
     resp = app.post(api_url, params=params)
     assert not resp.json['err']
     assert len(resp.json['data']) == 1
     agenda = Agenda.objects.get(slug='foo-meetings')
     assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)
     assert agenda.edit_role == edit_group
     assert agenda.view_role == view_group
+    assert agenda.category == category_a
 
     # add an events agenda
     params = {
         'label': 'foo Events',
         'slug': 'foo-events',
         'kind': 'events',
         'minimal_booking_delay': 1,
         'minimal_booking_delay_in_working_days': True,
         'maximal_booking_delay': 3,
         'anonymize_delay': 30,
         'edit_role': 'Edit',
         'view_role': 'View',
+        'category': 'category-a',
     }
     resp = app.post(api_url, params=params)
     assert not resp.json['err']
     assert len(resp.json['data']) == 1
     agenda = Agenda.objects.get(slug='foo-events')
     assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 12)
     assert agenda.edit_role == edit_group
     assert agenda.view_role == view_group
+    assert agenda.category == category_a
-- 
2.30.2

