From 8daef40780975bc8b54afd57724123f191eaa5f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Mon, 25 May 2020 10:09:41 +0200
Subject: [PATCH 5/8] api: add resources list on agenda details (#38942)

---
 chrono/api/views.py |  6 +++-
 tests/test_api.py   | 74 ++++++++++++++++++++++++++++++++-------------
 2 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/chrono/api/views.py b/chrono/api/views.py
index 0d6c7e5..6452b78 100644
--- a/chrono/api/views.py
+++ b/chrono/api/views.py
@@ -233,6 +233,10 @@ def get_agenda_detail(request, agenda):
         'maximal_booking_delay': agenda.maximal_booking_delay,
     }
 
+    if agenda.kind == 'meetings':
+        agenda_detail['resources'] = [
+            {'id': r.slug, 'text': r.label, 'description': r.description} for r in agenda.resources.all()
+        ]
     if agenda.kind == 'events':
         agenda_detail['api'] = {
             'datetimes_url': request.build_absolute_uri(
@@ -279,7 +283,7 @@ class Agendas(APIView):
     permission_classes = ()
 
     def get(self, request, format=None):
-        agendas_queryset = Agenda.objects.all().order_by('label')
+        agendas_queryset = Agenda.objects.all().prefetch_related('resources').order_by('label')
         if 'q' in request.GET:
             if not request.GET['q']:
                 return Response({'data': []})
diff --git a/tests/test_api.py b/tests/test_api.py
index 69d5f99..1ab577b 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -14,11 +14,12 @@ from django.utils.timezone import now, make_aware, localtime
 
 from chrono.agendas.models import (
     Agenda,
-    Event,
     Booking,
+    Desk,
+    Event,
     MeetingType,
+    Resource,
     TimePeriod,
-    Desk,
     TimePeriodException,
     VirtualMember,
 )
@@ -127,10 +128,16 @@ def virtual_meetings_agenda(meetings_agenda):
     return agenda
 
 
-def test_agendas_api(app, some_data, meetings_agenda):
-    agenda1 = Agenda.objects.filter(label=u'Foo bar')[0]
-    agenda2 = Agenda.objects.filter(label=u'Foo bar 2')[0]
-    virtual_agenda = Agenda.objects.create(
+def test_agendas_api(app):
+    Agenda.objects.create(label='Foo bar')
+    Agenda.objects.create(label='Foo bar 2')
+    meetings_agenda1 = Agenda.objects.create(label='Foo bar Meeting', kind='meetings')
+    Agenda.objects.create(label='Foo bar Meeting 2', kind='meetings')
+    resource1 = Resource.objects.create(label='Resource 1', description='Foo bar Resource 1')
+    resource2 = Resource.objects.create(label='Resource 2', description='Foo bar Resource 2')
+    Resource.objects.create(label='Resource 3')
+    meetings_agenda1.resources.add(resource1, resource2)
+    Agenda.objects.create(
         label='Virtual Agenda', kind='virtual', minimal_booking_delay=1, maximal_booking_delay=56
     )
     resp = app.get('/api/agenda/')
@@ -138,39 +145,57 @@ def test_agendas_api(app, some_data, meetings_agenda):
         'data': [
             {
                 'text': 'Foo bar',
-                'id': u'foo-bar',
+                'id': 'foo-bar',
                 'slug': 'foo-bar',
                 'kind': 'events',
                 'minimal_booking_delay': 1,
                 'maximal_booking_delay': 56,
                 'api': {
-                    'datetimes_url': 'http://testserver/api/agenda/%s/datetimes/' % agenda1.slug,
-                    'fillslots_url': 'http://testserver/api/agenda/%s/fillslots/' % agenda1.slug,
+                    'datetimes_url': 'http://testserver/api/agenda/foo-bar/datetimes/',
+                    'fillslots_url': 'http://testserver/api/agenda/foo-bar/fillslots/',
                 },
             },
             {
                 'text': 'Foo bar 2',
-                'id': u'foo-bar-2',
+                'id': 'foo-bar-2',
                 'kind': 'events',
                 'slug': 'foo-bar-2',
                 'minimal_booking_delay': 1,
                 'maximal_booking_delay': 56,
                 'api': {
-                    'datetimes_url': 'http://testserver/api/agenda/%s/datetimes/' % agenda2.slug,
-                    'fillslots_url': 'http://testserver/api/agenda/%s/fillslots/' % agenda2.slug,
+                    'datetimes_url': 'http://testserver/api/agenda/foo-bar-2/datetimes/',
+                    'fillslots_url': 'http://testserver/api/agenda/foo-bar-2/fillslots/',
                 },
             },
             {
                 'text': 'Foo bar Meeting',
-                'id': u'foo-bar-meeting',
+                'id': 'foo-bar-meeting',
                 'slug': 'foo-bar-meeting',
                 'minimal_booking_delay': 1,
                 'maximal_booking_delay': 56,
                 'kind': 'meetings',
+                'resources': [
+                    {'id': 'resource-1', 'text': 'Resource 1', 'description': 'Foo bar Resource 1'},
+                    {'id': 'resource-2', 'text': 'Resource 2', 'description': 'Foo bar Resource 2'},
+                ],
                 'api': {
-                    'meetings_url': 'http://testserver/api/agenda/%s/meetings/' % meetings_agenda.slug,
-                    'desks_url': 'http://testserver/api/agenda/%s/desks/' % meetings_agenda.slug,
-                    'fillslots_url': 'http://testserver/api/agenda/%s/fillslots/' % meetings_agenda.slug,
+                    'meetings_url': 'http://testserver/api/agenda/foo-bar-meeting/meetings/',
+                    'desks_url': 'http://testserver/api/agenda/foo-bar-meeting/desks/',
+                    'fillslots_url': 'http://testserver/api/agenda/foo-bar-meeting/fillslots/',
+                },
+            },
+            {
+                'text': 'Foo bar Meeting 2',
+                'id': 'foo-bar-meeting-2',
+                'slug': 'foo-bar-meeting-2',
+                'minimal_booking_delay': 1,
+                'maximal_booking_delay': 56,
+                'kind': 'meetings',
+                'resources': [],
+                'api': {
+                    'meetings_url': 'http://testserver/api/agenda/foo-bar-meeting-2/meetings/',
+                    'desks_url': 'http://testserver/api/agenda/foo-bar-meeting-2/desks/',
+                    'fillslots_url': 'http://testserver/api/agenda/foo-bar-meeting-2/fillslots/',
                 },
             },
             {
@@ -181,21 +206,28 @@ def test_agendas_api(app, some_data, meetings_agenda):
                 'maximal_booking_delay': 56,
                 'kind': 'virtual',
                 'api': {
-                    'meetings_url': 'http://testserver/api/agenda/%s/meetings/' % virtual_agenda.slug,
-                    'desks_url': 'http://testserver/api/agenda/%s/desks/' % virtual_agenda.slug,
-                    'fillslots_url': 'http://testserver/api/agenda/%s/fillslots/' % virtual_agenda.slug,
+                    'meetings_url': 'http://testserver/api/agenda/virtual-agenda/meetings/',
+                    'desks_url': 'http://testserver/api/agenda/virtual-agenda/desks/',
+                    'fillslots_url': 'http://testserver/api/agenda/virtual-agenda/fillslots/',
                 },
             },
         ]
     }
 
     resp = app.get('/api/agenda/', params={'q': 'foo'})
-    assert len(resp.json['data']) == 3
+    assert len(resp.json['data']) == 4
     resp = app.get('/api/agenda/', params={'q': 'MEET'})
-    assert len(resp.json['data']) == 1
+    assert len(resp.json['data']) == 2
     resp = app.get('/api/agenda/', params={'q': ''})
     assert len(resp.json['data']) == 0
 
+    with CaptureQueriesContext(connection) as ctx:
+        resp = app.get('/api/agenda/')
+        assert len(ctx.captured_queries) == 3
+    with CaptureQueriesContext(connection) as ctx:
+        resp = app.get('/api/agenda/', params={'q': 'MEET'})
+        assert len(ctx.captured_queries) == 2
+
 
 def test_agendas_meetingtypes_api(app, some_data, meetings_agenda):
     resp = app.get('/api/agenda/%s/meetings/' % meetings_agenda.slug)
-- 
2.20.1

