From 4f71d95cd3a03baf75806deaa0f6c50d41f3cc58 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Thu, 15 Apr 2021 15:31:56 +0200
Subject: [PATCH 3/3] api: add absence reasons to agenda details (#53147)

---
 chrono/api/views.py | 11 ++++++++++-
 tests/test_api.py   | 36 ++++++++++++++++++++++++++++++------
 2 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/chrono/api/views.py b/chrono/api/views.py
index f395707..fa84f4c 100644
--- a/chrono/api/views.py
+++ b/chrono/api/views.py
@@ -349,6 +349,10 @@ def get_agenda_detail(request, agenda, check_events=False):
         }
         if check_events:
             agenda_detail['opened_events_available'] = bool(agenda.get_open_events(include_full=False))
+        if agenda.absence_reasons_group:
+            agenda_detail['absence_reasons'] = [
+                {'slug': r.slug, 'label': r.label} for r in agenda.absence_reasons_group.absence_reasons.all()
+            ]
     elif agenda.accept_meetings():
         agenda_detail['api'] = {
             'meetings_url': request.build_absolute_uri(
@@ -537,7 +541,12 @@ class Agendas(APIView):
     permission_classes = ()
 
     def get(self, request, format=None):
-        agendas_queryset = Agenda.objects.all().prefetch_related('resources').order_by('label')
+        agendas_queryset = (
+            Agenda.objects.all()
+            .select_related('absence_reasons_group')
+            .prefetch_related('resources', 'absence_reasons_group__absence_reasons')
+            .order_by('label')
+        )
 
         if 'q' in request.GET:
             if not request.GET['q']:
diff --git a/tests/test_api.py b/tests/test_api.py
index 272a961..7e9476d 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -130,8 +130,12 @@ def virtual_meetings_agenda(meetings_agenda):
 def test_agendas_api(app):
     category_a = Category.objects.create(label='Category A')
     category_b = Category.objects.create(label='Category B')
-    event_agenda = Agenda.objects.create(label='Foo bar', category=category_a)
+    group = AbsenceReasonGroup.objects.create(label='Foo')
+    reason = AbsenceReason.objects.create(group=group, label='Foo bar')
+    reason2 = AbsenceReason.objects.create(group=group, label='Foo bar baz')
+    event_agenda = Agenda.objects.create(label='Foo bar', category=category_a, absence_reasons_group=group)
     Agenda.objects.create(label='Foo bar 2', category=category_a)
+    Agenda.objects.create(label='Foo bar 3', absence_reasons_group=group)
     meetings_agenda1 = Agenda.objects.create(label='Foo bar Meeting', kind='meetings', category=category_b)
     Agenda.objects.create(label='Foo bar Meeting 2', kind='meetings')
     resource1 = Resource.objects.create(label='Resource 1', description='Foo bar Resource 1')
@@ -151,6 +155,10 @@ def test_agendas_api(app):
                 'kind': 'events',
                 'minimal_booking_delay': 1,
                 'maximal_booking_delay': 56,
+                'absence_reasons': [
+                    {'slug': reason.slug, 'label': reason.label},
+                    {'slug': reason2.slug, 'label': reason2.label},
+                ],
                 'api': {
                     'datetimes_url': 'http://testserver/api/agenda/foo-bar/datetimes/',
                     'fillslots_url': 'http://testserver/api/agenda/foo-bar/fillslots/',
@@ -168,6 +176,22 @@ def test_agendas_api(app):
                     'fillslots_url': 'http://testserver/api/agenda/foo-bar-2/fillslots/',
                 },
             },
+            {
+                'text': 'Foo bar 3',
+                'id': 'foo-bar-3',
+                'kind': 'events',
+                'slug': 'foo-bar-3',
+                'minimal_booking_delay': 1,
+                'maximal_booking_delay': 56,
+                'absence_reasons': [
+                    {'slug': reason.slug, 'label': reason.label},
+                    {'slug': reason2.slug, 'label': reason2.label},
+                ],
+                'api': {
+                    'datetimes_url': 'http://testserver/api/agenda/foo-bar-3/datetimes/',
+                    'fillslots_url': 'http://testserver/api/agenda/foo-bar-3/fillslots/',
+                },
+            },
             {
                 'text': 'Foo bar Meeting',
                 'id': 'foo-bar-meeting',
@@ -216,7 +240,7 @@ def test_agendas_api(app):
     }
 
     resp = app.get('/api/agenda/', params={'q': 'foo'})
-    assert len(resp.json['data']) == 4
+    assert len(resp.json['data']) == 5
     resp = app.get('/api/agenda/', params={'q': 'MEET'})
     assert len(resp.json['data']) == 2
     resp = app.get('/api/agenda/', params={'q': ''})
@@ -224,7 +248,7 @@ def test_agendas_api(app):
 
     with CaptureQueriesContext(connection) as ctx:
         resp = app.get('/api/agenda/')
-        assert len(ctx.captured_queries) == 3
+        assert len(ctx.captured_queries) == 4
     with CaptureQueriesContext(connection) as ctx:
         resp = app.get('/api/agenda/', params={'q': 'MEET'})
         assert len(ctx.captured_queries) == 2
@@ -233,9 +257,9 @@ def test_agendas_api(app):
     assert len(resp.json['data']) == 0
 
     resp = app.get('/api/agenda/', params={'category': ''})
-    assert len(resp.json['data']) == 5
+    assert len(resp.json['data']) == 6
     resp = app.get('/api/agenda/', params={'category': '__none__'})
-    assert len(resp.json['data']) == 2
+    assert len(resp.json['data']) == 3
     resp = app.get('/api/agenda/', params={'category': 'category-a'})
     assert len(resp.json['data']) == 2
     resp = app.get('/api/agenda/', params={'category': 'category-b'})
@@ -309,7 +333,7 @@ def test_agendas_api(app):
 
     with CaptureQueriesContext(connection) as ctx:
         resp = app.get('/api/agenda/', params={'with_open_events': '1'})
-        assert len(ctx.captured_queries) == 4
+        assert len(ctx.captured_queries) == 5
 
 
 def test_agendas_meetingtypes_api(app, some_data, meetings_agenda):
-- 
2.30.2

