From fd4c321b81a152c04691d79f88d152042016431e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Mon, 24 Aug 2020 14:45:20 +0200
Subject: [PATCH] api: status view, get Event by slug and agenda (#45520)

---
 chrono/api/views.py | 12 ++++---
 tests/test_api.py   | 77 ++++++++++++++++++++++++++++++---------------
 2 files changed, 59 insertions(+), 30 deletions(-)

diff --git a/chrono/api/views.py b/chrono/api/views.py
index f0a27f0..3af9372 100644
--- a/chrono/api/views.py
+++ b/chrono/api/views.py
@@ -1332,18 +1332,22 @@ resize_booking = ResizeBooking.as_view()
 class SlotStatus(APIView):
     permission_classes = (permissions.IsAuthenticated,)
 
-    def get_object(self, event_identifier):
+    def get_object(self, agenda_identifier, event_identifier):
         try:
-            return Event.objects.get(slug=event_identifier)
+            return Event.objects.get(
+                slug=event_identifier, agenda__slug=agenda_identifier, agenda__kind='events'
+            )
         except Event.DoesNotExist:
             try:
                 # legacy access by event id
-                return Event.objects.get(pk=int(event_identifier))
+                return Event.objects.get(
+                    pk=int(event_identifier), agenda=int(agenda_identifier), agenda__kind='events'
+                )
             except (ValueError, Event.DoesNotExist):
                 raise Http404()
 
     def get(self, request, agenda_identifier=None, event_identifier=None, format=None):
-        event = self.get_object(event_identifier)
+        event = self.get_object(agenda_identifier, event_identifier)
         response = {
             'err': 0,
             'places': get_event_places(event),
diff --git a/tests/test_api.py b/tests/test_api.py
index 780dc9d..9c62223 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -1706,38 +1706,61 @@ def test_soldout(app, some_data, user):
     assert resp.json['err_desc'] == 'sold out'
 
 
-def test_status(app, some_data, user):
-    agenda_id = Agenda.objects.filter(label=u'Foo bar')[0].id
-    event = Event.objects.filter(agenda_id=agenda_id)[0]
-    Booking(event=event).save()
+def test_status(app, user):
+    agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0)
+    event = Event.objects.create(
+        slug='event-slug',
+        start_datetime=(now() + datetime.timedelta(days=5)).replace(hour=10, minute=0),
+        places=10,
+        agenda=agenda,
+    )
+    agenda2 = Agenda.objects.create(label='Foo bar2', kind='events', minimal_booking_delay=0)
+    # other event with the same slug but in another agenda
+    Event.objects.create(
+        slug='event-slug',
+        start_datetime=(now() + datetime.timedelta(days=5)).replace(hour=10, minute=0),
+        places=5,
+        agenda=agenda2,
+    )
+    Booking.objects.create(event=event)
 
-    resp = app.get('/api/agenda/%s/status/%s/' % (agenda_id, event.id), status=401)
+    app.get('/api/agenda/%s/status/%s/' % (agenda.pk, event.pk), status=401)
 
     app.authorization = ('Basic', ('john.doe', 'password'))
-    resp = app.get('/api/agenda/%s/status/%s/' % (agenda_id, 0), status=404)
-    resp = app.get('/api/agenda/%s/status/%s/' % (agenda_id, 'xx'), status=404)
+    app.get('/api/agenda/%s/status/%s/' % (agenda.pk, 0), status=404)
+    app.get('/api/agenda/%s/status/%s/' % (agenda.pk, 'xx'), status=404)
 
-    resp = app.get('/api/agenda/%s/status/%s/' % (agenda_id, event.id))
+    resp = app.get('/api/agenda/%s/status/%s/' % (agenda.pk, event.pk))
     assert resp.json['err'] == 0
     assert resp.json['places']['total'] == 10
     assert resp.json['places']['available'] == 9
     assert resp.json['places']['reserved'] == 1
-    assert not 'waiting_list_total' in resp.json['places']
+    assert 'waiting_list_total' not in resp.json['places']
 
     Booking(event=event, in_waiting_list=True).save()
     event.waiting_list_places = 5
     event.save()
-    resp = app.get('/api/agenda/%s/status/%s/' % (agenda_id, event.id))
+    resp = app.get('/api/agenda/%s/status/%s/' % (agenda.pk, event.pk))
     assert resp.json['places']['waiting_list_total'] == 5
     assert resp.json['places']['waiting_list_available'] == 4
     assert resp.json['places']['waiting_list_reserved'] == 1
 
-    # access by slug
-    event.slug = 'bar'
-    event.save()
-    resp = app.get('/api/agenda/%s/status/%s/' % (agenda_id, event.slug))
-    # not found event
-    resp = app.get('/api/agenda/%s/status/%s/' % (agenda_id, 'unknown'), status=404)
+    # unknown agenda
+    app.get('/api/agenda/0/status/%s/' % (event.pk), params={'user_external_id': '42'}, status=404)
+    app.get('/api/agenda/foobar/status/%s/' % (event.slug), params={'user_external_id': '42'}, status=404)
+    # unknown event
+    app.get('/api/agenda/%s/status/0/' % (agenda.pk), params={'user_external_id': '42'}, status=404)
+    app.get('/api/agenda/%s/status/foobar/' % (agenda.slug), params={'user_external_id': '42'}, status=404)
+
+    # wrong kind
+    agenda.kind = 'meetings'
+    agenda.save()
+    app.get(
+        '/api/agenda/%s/status/%s/' % (agenda.pk, event.pk), status=404,
+    )
+    app.get(
+        '/api/agenda/%s/status/%s/' % (agenda.slug, event.slug), status=404,
+    )
 
 
 def test_bookings(app, user):
@@ -1749,6 +1772,14 @@ def test_bookings(app, user):
         waiting_list_places=5,
         agenda=agenda,
     )
+    agenda2 = Agenda.objects.create(label='Foo bar2', kind='events', minimal_booking_delay=0)
+    # other event with the same slug but in another agenda
+    Event.objects.create(
+        slug='event-slug',
+        start_datetime=(now() + datetime.timedelta(days=5)).replace(hour=10, minute=0),
+        places=5,
+        agenda=agenda2,
+    )
 
     # create a booking not on the waiting list
     primary1 = Booking.objects.create(event=event, in_waiting_list=False, user_external_id='42')
@@ -1762,16 +1793,10 @@ def test_bookings(app, user):
     app.authorization = ('Basic', ('john.doe', 'password'))
 
     # unknown agenda
-    resp = app.get(
-        '/api/agenda/foobar/bookings/%s/' % (event.pk), params={'user_external_id': '42'}, status=404
-    )
+    app.get('/api/agenda/foobar/bookings/%s/' % (event.pk), params={'user_external_id': '42'}, status=404)
     # unknown event
-    resp = app.get(
-        '/api/agenda/%s/bookings/0/' % (agenda.slug), params={'user_external_id': '42'}, status=404
-    )
-    resp = app.get(
-        '/api/agenda/%s/bookings/foobar/' % (agenda.slug), params={'user_external_id': '42'}, status=404
-    )
+    app.get('/api/agenda/%s/bookings/0/' % (agenda.slug), params={'user_external_id': '42'}, status=404)
+    app.get('/api/agenda/%s/bookings/foobar/' % (agenda.slug), params={'user_external_id': '42'}, status=404)
 
     # search for '42' external user
     resp = app.get(
@@ -1819,7 +1844,7 @@ def test_bookings(app, user):
     # wrong kind
     agenda.kind = 'meetings'
     agenda.save()
-    resp = app.get(
+    app.get(
         '/api/agenda/%s/bookings/%s/' % (agenda.slug, event.slug),
         params={'user_external_id': '42'},
         status=404,
-- 
2.27.0

