api: mark user as present or not (#38678)
This commit is contained in:
parent
96d1618186
commit
d0bc3146d6
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('agendas', '0070_auto_20201202_1834'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='booking',
|
||||
name='user_was_present',
|
||||
field=models.NullBooleanField(),
|
||||
),
|
||||
]
|
|
@ -1098,6 +1098,8 @@ class Booking(models.Model):
|
|||
user_name = models.CharField(max_length=250, blank=True)
|
||||
user_email = models.EmailField(blank=True)
|
||||
user_phone_number = models.CharField(max_length=16, blank=True)
|
||||
user_was_present = models.NullBooleanField()
|
||||
|
||||
form_url = models.URLField(blank=True)
|
||||
backoffice_url = models.URLField(blank=True)
|
||||
cancel_callback_url = models.URLField(blank=True)
|
||||
|
|
|
@ -55,7 +55,7 @@ urlpatterns = [
|
|||
views.meeting_datetimes,
|
||||
name='api-agenda-meeting-datetimes',
|
||||
),
|
||||
url(r'^booking/(?P<booking_pk>\w+)/$', views.booking),
|
||||
url(r'^booking/(?P<booking_pk>\w+)/$', views.booking, name='api-booking'),
|
||||
url(r'^booking/(?P<booking_pk>\w+)/cancel/$', views.cancel_booking, name='api-cancel-booking'),
|
||||
url(r'^booking/(?P<booking_pk>\w+)/accept/$', views.accept_booking, name='api-accept-booking'),
|
||||
url(r'^booking/(?P<booking_pk>\w+)/suspend/$', views.suspend_booking, name='api-suspend-booking'),
|
||||
|
|
|
@ -1093,6 +1093,9 @@ class Fillslots(APIView):
|
|||
'slug': primary_booking.event.agenda.slug,
|
||||
},
|
||||
'api': {
|
||||
'booking_url': request.build_absolute_uri(
|
||||
reverse('api-booking', kwargs={'booking_pk': primary_booking.id})
|
||||
),
|
||||
'cancel_url': request.build_absolute_uri(
|
||||
reverse('api-cancel-booking', kwargs={'booking_pk': primary_booking.id})
|
||||
),
|
||||
|
@ -1162,16 +1165,81 @@ class Fillslot(Fillslots):
|
|||
fillslot = Fillslot.as_view()
|
||||
|
||||
|
||||
class BookingSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Booking
|
||||
fields = ['user_was_present']
|
||||
|
||||
|
||||
class BookingAPI(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
serializer_class = BookingSerializer
|
||||
|
||||
def initial(self, request, *args, **kwargs):
|
||||
super(BookingAPI, self).initial(request, *args, **kwargs)
|
||||
self.booking = Booking.objects.get(id=kwargs.get('booking_pk'), cancellation_datetime__isnull=True)
|
||||
super().initial(request, *args, **kwargs)
|
||||
self.booking = get_object_or_404(Booking, pk=kwargs.get('booking_pk'))
|
||||
|
||||
def check_booking(self, check_waiting_list=False):
|
||||
if self.booking.cancellation_datetime:
|
||||
return Response(
|
||||
{'err': 1, 'err_class': 'booking is cancelled', 'err_desc': _('booking is cancelled')}
|
||||
)
|
||||
|
||||
if self.booking.primary_booking is not None:
|
||||
return Response({'err': 2, 'err_class': 'secondary booking', 'err_desc': _('secondary booking')})
|
||||
|
||||
if check_waiting_list and self.booking.in_waiting_list:
|
||||
response = {
|
||||
'err': 3,
|
||||
'err_class': 'booking is in waiting list',
|
||||
'err_desc': _('booking is in waiting list'),
|
||||
}
|
||||
return Response(response)
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
response = self.check_booking()
|
||||
if response:
|
||||
return response
|
||||
|
||||
response = {
|
||||
'err': 0,
|
||||
'booking_id': self.booking.pk,
|
||||
'in_waiting_list': self.booking.in_waiting_list,
|
||||
'user_was_present': self.booking.user_was_present,
|
||||
}
|
||||
return Response(response)
|
||||
|
||||
def patch(self, request, *args, **kwargs):
|
||||
response = self.check_booking(check_waiting_list=True)
|
||||
if response:
|
||||
return response
|
||||
|
||||
serializer = self.serializer_class(self.booking, data=request.data, partial=True)
|
||||
|
||||
if not serializer.is_valid():
|
||||
return Response(
|
||||
{
|
||||
'err': 4,
|
||||
'err_class': 'invalid payload',
|
||||
'err_desc': _('invalid payload'),
|
||||
'errors': serializer.errors,
|
||||
},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
serializer.save()
|
||||
self.booking.secondary_booking_set.update(user_was_present=self.booking.user_was_present)
|
||||
|
||||
response = {'err': 0, 'booking_id': self.booking.pk}
|
||||
return Response(response)
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
response = self.check_booking()
|
||||
if response:
|
||||
return response
|
||||
|
||||
self.booking.cancel()
|
||||
response = {'err': 0, 'booking_id': self.booking.id}
|
||||
response = {'err': 0, 'booking_id': self.booking.pk}
|
||||
return Response(response)
|
||||
|
||||
|
||||
|
|
|
@ -909,10 +909,13 @@ def test_booking_api(app, some_data, user):
|
|||
resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda.slug, event.id))
|
||||
Booking.objects.get(id=resp.json['booking_id'])
|
||||
assert resp.json['datetime'] == localtime(event.start_datetime).strftime('%Y-%m-%d %H:%M:%S')
|
||||
assert 'booking_url' in resp.json['api']
|
||||
assert 'accept_url' in resp.json['api']
|
||||
assert 'suspend_url' in resp.json['api']
|
||||
assert 'cancel_url' in resp.json['api']
|
||||
assert 'ics_url' in resp.json['api']
|
||||
assert urlparse.urlparse(resp.json['api']['booking_url']).netloc
|
||||
assert urlparse.urlparse(resp.json['api']['accept_url']).netloc
|
||||
assert urlparse.urlparse(resp.json['api']['suspend_url']).netloc
|
||||
assert urlparse.urlparse(resp.json['api']['cancel_url']).netloc
|
||||
assert urlparse.urlparse(resp.json['api']['ics_url']).netloc
|
||||
|
@ -1117,9 +1120,12 @@ def test_booking_api_fillslots(app, some_data, user):
|
|||
primary_booking_id = resp.json['booking_id']
|
||||
Booking.objects.get(id=primary_booking_id)
|
||||
assert resp.json['datetime'] == localtime(event.start_datetime).strftime('%Y-%m-%d %H:%M:%S')
|
||||
assert 'booking_url' in resp.json['api']
|
||||
assert 'accept_url' in resp.json['api']
|
||||
assert 'suspend_url' in resp.json['api']
|
||||
assert 'cancel_url' in resp.json['api']
|
||||
assert urlparse.urlparse(resp.json['api']['booking_url']).netloc
|
||||
assert urlparse.urlparse(resp.json['api']['accept_url']).netloc
|
||||
assert urlparse.urlparse(resp.json['api']['suspend_url']).netloc
|
||||
assert urlparse.urlparse(resp.json['api']['cancel_url']).netloc
|
||||
assert Booking.objects.count() == 3
|
||||
|
@ -1904,6 +1910,117 @@ def test_booking_api_with_cancel_booking(app, some_data, user):
|
|||
assert Booking.objects.count() == 6
|
||||
|
||||
|
||||
@pytest.mark.parametrize('flag', [True, False, None])
|
||||
def test_booking_api_present(app, user, flag):
|
||||
agenda = Agenda.objects.create(kind='events')
|
||||
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
|
||||
booking = Booking.objects.create(event=event, user_was_present=flag)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
resp = app.get('/api/booking/%s/' % booking.pk)
|
||||
assert resp.json['booking_id'] == booking.pk
|
||||
assert resp.json['user_was_present'] == flag
|
||||
|
||||
|
||||
@pytest.mark.parametrize('flag', [True, False])
|
||||
def test_booking_api_waiting_list(app, user, flag):
|
||||
agenda = Agenda.objects.create(kind='events')
|
||||
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
|
||||
booking = Booking.objects.create(event=event, in_waiting_list=flag)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
resp = app.get('/api/booking/%s/' % booking.pk)
|
||||
assert resp.json['booking_id'] == booking.pk
|
||||
assert resp.json['in_waiting_list'] == flag
|
||||
|
||||
|
||||
def test_booking_api_error(app, user):
|
||||
agenda = Agenda.objects.create(kind='events')
|
||||
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
|
||||
booking = Booking.objects.create(event=event)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
# unknown
|
||||
booking.cancel()
|
||||
for method in ['get', 'delete', 'patch']:
|
||||
getattr(app, method)('/api/booking/0/', status=404)
|
||||
|
||||
# cancelled
|
||||
booking.cancel()
|
||||
for method in ['get', 'delete', 'patch']:
|
||||
resp = getattr(app, method)('/api/booking/%s/' % booking.pk)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == 'booking is cancelled'
|
||||
|
||||
# not a primary booking
|
||||
secondary = Booking.objects.create(event=event, primary_booking=booking)
|
||||
for method in ['get', 'delete', 'patch']:
|
||||
resp = getattr(app, method)('/api/booking/%s/' % secondary.pk)
|
||||
assert resp.json['err'] == 2
|
||||
assert resp.json['err_desc'] == 'secondary booking'
|
||||
|
||||
# in waiting list
|
||||
booking.cancellation_datetime = None
|
||||
booking.in_waiting_list = True
|
||||
booking.save()
|
||||
resp = app.get('/api/booking/%s/' % booking.pk)
|
||||
assert resp.json['err'] == 0
|
||||
resp = app.patch('/api/booking/%s/' % booking.pk)
|
||||
assert resp.json['err'] == 3
|
||||
assert resp.json['err_desc'] == 'booking is in waiting list'
|
||||
resp = app.delete('/api/booking/%s/' % booking.pk)
|
||||
assert resp.json['err'] == 0
|
||||
|
||||
|
||||
def test_booking_patch_api(app, user):
|
||||
agenda = Agenda.objects.create(kind='events')
|
||||
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
|
||||
booking = Booking.objects.create(event=event)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
resp = app.patch('/api/booking/%s/' % booking.pk)
|
||||
assert resp.json['err'] == 0
|
||||
resp = app.patch('/api/booking/%s/' % booking.pk, params={'user_was_present': 'foobar'}, status=400)
|
||||
assert resp.json['err'] == 4
|
||||
assert resp.json['err_desc'] == 'invalid payload'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('flag', [True, False, None])
|
||||
def test_booking_patch_api_present(app, user, flag):
|
||||
agenda = Agenda.objects.create(kind='events')
|
||||
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
|
||||
booking = Booking.objects.create(event=event)
|
||||
|
||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||
|
||||
# set flag
|
||||
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_was_present': flag})
|
||||
booking.refresh_from_db()
|
||||
assert booking.user_was_present == flag
|
||||
|
||||
# reset
|
||||
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_was_present': None})
|
||||
booking.refresh_from_db()
|
||||
assert booking.user_was_present is None
|
||||
|
||||
# make secondary bookings
|
||||
Booking.objects.create(event=event, primary_booking=booking)
|
||||
Booking.objects.create(event=event, primary_booking=booking)
|
||||
# and other booking
|
||||
other_booking = Booking.objects.create(event=event)
|
||||
|
||||
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_was_present': flag})
|
||||
booking.refresh_from_db()
|
||||
assert booking.user_was_present == flag
|
||||
# all secondary bookings are upadted
|
||||
assert list(booking.secondary_booking_set.values_list('user_was_present', flat=True)) == [flag, flag]
|
||||
other_booking.refresh_from_db()
|
||||
assert other_booking.user_was_present is None # not changed
|
||||
|
||||
|
||||
def test_booking_cancellation_api(app, some_data, user):
|
||||
agenda = Agenda.objects.filter(label=u'Foo bar')[0]
|
||||
event = [x for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()][0]
|
||||
|
|
Loading…
Reference in New Issue