api: get event status and fillslot with event pk or slug (#15726)
This commit is contained in:
parent
0f4040f9a5
commit
90dfb10afa
|
@ -23,11 +23,11 @@ urlpatterns = [
|
|||
url(r'agenda/(?P<agenda_identifier>[\w-]+)/$', views.agenda_detail),
|
||||
|
||||
url(r'agenda/(?P<agenda_identifier>[\w-]+)/datetimes/$', views.datetimes, name='api-agenda-datetimes'),
|
||||
url(r'agenda/(?P<agenda_identifier>[\w-]+)/fillslot/(?P<event_pk>[\w:-]+)/$',
|
||||
url(r'agenda/(?P<agenda_identifier>[\w-]+)/fillslot/(?P<event_identifier>[\w:-]+)/$',
|
||||
views.fillslot, name='api-fillslot'),
|
||||
url(r'agenda/(?P<agenda_identifier>[\w-]+)/fillslots/$',
|
||||
views.fillslots, name='api-agenda-fillslots'),
|
||||
url(r'agenda/(?P<agenda_identifier>[\w-]+)/status/(?P<event_pk>\d+)/$', views.slot_status,
|
||||
url(r'agenda/(?P<agenda_identifier>[\w-]+)/status/(?P<event_identifier>[\w-]+)/$', views.slot_status,
|
||||
name='api-event-status'),
|
||||
|
||||
url(r'agenda/meetings/(?P<meeting_identifier>[\w-]+)/datetimes/$',
|
||||
|
|
|
@ -185,6 +185,7 @@ class Datetimes(APIView):
|
|||
datetime.datetime.combine(parse_date(request.GET['date_end']), datetime.time(0, 0))))
|
||||
|
||||
response = {'data': [{'id': x.id,
|
||||
'slug': x.slug,
|
||||
'text': force_text(x),
|
||||
'datetime': format_response_datetime(x.start_datetime),
|
||||
'description': x.description,
|
||||
|
@ -194,13 +195,13 @@ class Datetimes(APIView):
|
|||
reverse('api-fillslot',
|
||||
kwargs={
|
||||
'agenda_identifier': agenda.slug,
|
||||
'event_pk': x.id,
|
||||
'event_identifier': x.slug,
|
||||
})),
|
||||
'status_url': request.build_absolute_uri(
|
||||
reverse('api-event-status',
|
||||
kwargs={
|
||||
'agenda_identifier': agenda.slug,
|
||||
'event_pk': x.id,
|
||||
'event_identifier': x.slug,
|
||||
}))
|
||||
},
|
||||
} for x in entries]}
|
||||
|
@ -240,12 +241,12 @@ class MeetingDatetimes(APIView):
|
|||
|
||||
# create fillslot API URL as a template, to avoid expensive calls
|
||||
# to request.build_absolute_uri()
|
||||
fake_event_pk = '__event_id__'
|
||||
fake_event_identifier = '__event_identifier__'
|
||||
fillslot_url = request.build_absolute_uri(
|
||||
reverse('api-fillslot',
|
||||
kwargs={
|
||||
'agenda_identifier': agenda.slug,
|
||||
'event_pk': fake_event_pk,
|
||||
'event_identifier': fake_event_identifier,
|
||||
}))
|
||||
|
||||
response = {'data': [{'id': x.id,
|
||||
|
@ -253,7 +254,7 @@ class MeetingDatetimes(APIView):
|
|||
'text': force_text(x),
|
||||
'disabled': bool(x.full),
|
||||
'api': {
|
||||
'fillslot_url': fillslot_url.replace(fake_event_pk, str(x.id)),
|
||||
'fillslot_url': fillslot_url.replace(fake_event_identifier, str(x.id)),
|
||||
},
|
||||
} for x in slots]}
|
||||
return Response(response)
|
||||
|
@ -333,7 +334,7 @@ class Fillslots(APIView):
|
|||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = SlotsSerializer
|
||||
|
||||
def post(self, request, agenda_identifier=None, event_pk=None, format=None):
|
||||
def post(self, request, agenda_identifier=None, event_identifier=None, format=None):
|
||||
return self.fillslot(request=request, agenda_identifier=agenda_identifier,
|
||||
format=format)
|
||||
|
||||
|
@ -467,7 +468,10 @@ class Fillslots(APIView):
|
|||
full=False, places=1,
|
||||
desk=available_desk))
|
||||
else:
|
||||
events = Event.objects.filter(id__in=slots).order_by('start_datetime')
|
||||
try:
|
||||
events = Event.objects.filter(id__in=[int(s) for s in slots]).order_by('start_datetime')
|
||||
except ValueError:
|
||||
events = Event.objects.filter(slug__in=slots).order_by('start_datetime')
|
||||
|
||||
# search free places. Switch to waiting list if necessary.
|
||||
in_waiting_list = False
|
||||
|
@ -538,10 +542,10 @@ fillslots = Fillslots.as_view()
|
|||
class Fillslot(Fillslots):
|
||||
serializer_class = SlotSerializer
|
||||
|
||||
def post(self, request, agenda_identifier=None, event_pk=None, format=None):
|
||||
def post(self, request, agenda_identifier=None, event_identifier=None, format=None):
|
||||
return self.fillslot(request=request,
|
||||
agenda_identifier=agenda_identifier,
|
||||
slots=[event_pk], # fill a "list on one slot"
|
||||
slots=[event_identifier], # fill a "list on one slot"
|
||||
format=format)
|
||||
|
||||
fillslot = Fillslot.as_view()
|
||||
|
@ -610,8 +614,18 @@ accept_booking = AcceptBooking.as_view()
|
|||
class SlotStatus(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get(self, request, agenda_identifier=None, event_pk=None, format=None):
|
||||
event = get_object_or_404(Event, id=event_pk)
|
||||
def get_object(self, event_identifier):
|
||||
try:
|
||||
return Event.objects.get(slug=event_identifier)
|
||||
except Event.DoesNotExist:
|
||||
try:
|
||||
# legacy access by event id
|
||||
return Event.objects.get(pk=int(event_identifier))
|
||||
except (ValueError, Event.DoesNotExist):
|
||||
raise Http404()
|
||||
|
||||
def get(self, request, agenda_identifier=None, event_identifier=None, format=None):
|
||||
event = self.get_object(event_identifier)
|
||||
response = {
|
||||
'err': 0,
|
||||
'places': {
|
||||
|
@ -626,6 +640,7 @@ class SlotStatus(APIView):
|
|||
response['places']['waiting_list_available'] = (event.waiting_list_places - event.waiting_list)
|
||||
return Response(response)
|
||||
|
||||
|
||||
slot_status = SlotStatus.as_view()
|
||||
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ def test_datetime_api_status_url(app, some_data):
|
|||
agenda = Agenda.objects.get(label=u'Foo bar2')
|
||||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
|
||||
for datum in resp.json['data']:
|
||||
assert urlparse.urlparse(datum['api']['status_url']).path == '/api/agenda/%s/status/%s/' % (agenda.slug, datum['id'])
|
||||
assert urlparse.urlparse(datum['api']['status_url']).path == '/api/agenda/%s/status/%s/' % (agenda.slug, datum['slug'])
|
||||
|
||||
def test_datetimes_api_meetings_agenda(app, meetings_agenda):
|
||||
meeting_type = MeetingType.objects.get(agenda=meetings_agenda)
|
||||
|
@ -333,7 +333,7 @@ def test_booking_api(app, some_data, user):
|
|||
for agenda_key in (agenda.slug, agenda.id): # acces datetimes via agenda slug or id (legacy)
|
||||
resp_datetimes = app.get('/api/agenda/%s/datetimes/' % agenda_key)
|
||||
event_fillslot_url = [x for x in resp_datetimes.json['data'] if x['id'] == event.id][0]['api']['fillslot_url']
|
||||
assert urlparse.urlparse(event_fillslot_url).path == '/api/agenda/%s/fillslot/%s/' % (agenda.slug, event.id)
|
||||
assert urlparse.urlparse(event_fillslot_url).path == '/api/agenda/%s/fillslot/%s/' % (agenda.slug, event.slug)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda.slug, event.id))
|
||||
|
@ -346,7 +346,8 @@ def test_booking_api(app, some_data, user):
|
|||
assert urlparse.urlparse(resp.json['api']['ics_url']).netloc
|
||||
assert Booking.objects.count() == 1
|
||||
|
||||
resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda.id, event.id))
|
||||
# access by slug
|
||||
resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda.id, event.slug))
|
||||
assert Booking.objects.count() == 2
|
||||
assert Booking.objects.filter(event__agenda=agenda).count() == 2
|
||||
|
||||
|
@ -467,6 +468,7 @@ def test_booking_ics(app, some_data, meetings_agenda, user):
|
|||
def test_booking_api_fillslots(app, some_data, user):
|
||||
agenda = Agenda.objects.filter(label=u'Foo bar')[0]
|
||||
events_ids = [x.id for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()]
|
||||
events_slugs = [x.slug for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()]
|
||||
assert len(events_ids) == 3
|
||||
event = [x for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()][0] # first event
|
||||
|
||||
|
@ -495,7 +497,8 @@ def test_booking_api_fillslots(app, some_data, user):
|
|||
assert bookings[1].primary_booking.id == bookings[0].id == primary_booking_id
|
||||
assert bookings[2].primary_booking.id == bookings[0].id == primary_booking_id
|
||||
|
||||
resp = app.post('/api/agenda/%s/fillslots/' % agenda.slug, params={'slots': events_ids})
|
||||
# access by slug
|
||||
resp = app.post('/api/agenda/%s/fillslots/' % agenda.slug, params={'slots': events_slugs})
|
||||
primary_booking_id_2 = resp.json['booking_id']
|
||||
assert Booking.objects.count() == 6
|
||||
assert Booking.objects.filter(event__agenda=agenda).count() == 6
|
||||
|
@ -915,6 +918,12 @@ def test_status(app, some_data, user):
|
|||
assert resp.json['places']['waiting_list_available'] == 4
|
||||
assert resp.json['places']['waiting_list_reserved'] == 1
|
||||
|
||||
# access by slug
|
||||
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)
|
||||
|
||||
|
||||
def test_waiting_list_datetimes(app, some_data, user):
|
||||
agenda_id = Agenda.objects.filter(label=u'Foo bar')[0].id
|
||||
event = Event.objects.filter(agenda_id=agenda_id).exclude(start_datetime__lt=now())[0]
|
||||
|
@ -1343,7 +1352,8 @@ def test_agenda_meeting_api_multiple_desk(app, meetings_agenda, user):
|
|||
booking_url = event_data['api']['fillslot_url']
|
||||
with CaptureQueriesContext(connection) as ctx:
|
||||
app.post(booking_url)
|
||||
assert len(ctx.captured_queries) == queries_count_fillslot1
|
||||
# 2 + idx: because of slug unicity
|
||||
assert len(ctx.captured_queries) == queries_count_fillslot1 + 2 + idx
|
||||
|
||||
with CaptureQueriesContext(connection) as ctx:
|
||||
app.get('/api/agenda/meetings/%s/datetimes/' % meeting_type.id)
|
||||
|
|
Loading…
Reference in New Issue