Projet

Général

Profil

0001-api-mark-user-as-present-or-not-38678.patch

Lauréline Guérin, 04 janvier 2021 10:31

Télécharger (9,8 ko)

Voir les différences:

Subject: [PATCH] api: mark user as present or not (#38678)

 .../migrations/0071_booking_attendance.py     |  19 +++
 chrono/agendas/models.py                      |   2 +
 chrono/api/views.py                           |  71 ++++++++++-
 tests/test_api.py                             | 111 ++++++++++++++++++
 4 files changed, 200 insertions(+), 3 deletions(-)
 create mode 100644 chrono/agendas/migrations/0071_booking_attendance.py
chrono/agendas/migrations/0071_booking_attendance.py
1
# -*- coding: utf-8 -*-
2
from __future__ import unicode_literals
3

  
4
from django.db import migrations, models
5

  
6

  
7
class Migration(migrations.Migration):
8

  
9
    dependencies = [
10
        ('agendas', '0070_auto_20201202_1834'),
11
    ]
12

  
13
    operations = [
14
        migrations.AddField(
15
            model_name='booking',
16
            name='user_was_present',
17
            field=models.NullBooleanField(),
18
        ),
19
    ]
chrono/agendas/models.py
1098 1098
    user_name = models.CharField(max_length=250, blank=True)
1099 1099
    user_email = models.EmailField(blank=True)
1100 1100
    user_phone_number = models.CharField(max_length=16, blank=True)
1101
    user_was_present = models.NullBooleanField()
1102

  
1101 1103
    form_url = models.URLField(blank=True)
1102 1104
    backoffice_url = models.URLField(blank=True)
1103 1105
    cancel_callback_url = models.URLField(blank=True)
chrono/api/views.py
1162 1162
fillslot = Fillslot.as_view()
1163 1163

  
1164 1164

  
1165
class BookingSerializer(serializers.ModelSerializer):
1166
    class Meta:
1167
        model = Booking
1168
        fields = ['user_was_present']
1169

  
1170

  
1165 1171
class BookingAPI(APIView):
1166 1172
    permission_classes = (permissions.IsAuthenticated,)
1173
    serializer_class = BookingSerializer
1167 1174

  
1168 1175
    def initial(self, request, *args, **kwargs):
1169
        super(BookingAPI, self).initial(request, *args, **kwargs)
1170
        self.booking = Booking.objects.get(id=kwargs.get('booking_pk'), cancellation_datetime__isnull=True)
1176
        super().initial(request, *args, **kwargs)
1177
        self.booking = get_object_or_404(Booking, pk=kwargs.get('booking_pk'))
1178

  
1179
    def check_booking(self, check_waiting_list=False):
1180
        if self.booking.cancellation_datetime:
1181
            return Response(
1182
                {'err': 1, 'err_class': 'booking is cancelled', 'err_desc': _('booking is cancelled')}
1183
            )
1184

  
1185
        if self.booking.primary_booking is not None:
1186
            return Response({'err': 2, 'err_class': 'secondary booking', 'err_desc': _('secondary booking')})
1187

  
1188
        if check_waiting_list and self.booking.in_waiting_list:
1189
            response = {
1190
                'err': 3,
1191
                'err_class': 'booking is in waiting list',
1192
                'err_desc': _('booking is in waiting list'),
1193
            }
1194
            return Response(response)
1195

  
1196
    def get(self, request, *args, **kwargs):
1197
        response = self.check_booking()
1198
        if response:
1199
            return response
1200

  
1201
        response = {
1202
            'err': 0,
1203
            'booking_id': self.booking.pk,
1204
            'in_waiting_list': self.booking.in_waiting_list,
1205
            'user_was_present': self.booking.user_was_present,
1206
        }
1207
        return Response(response)
1208

  
1209
    def patch(self, request, *args, **kwargs):
1210
        response = self.check_booking(check_waiting_list=True)
1211
        if response:
1212
            return response
1213

  
1214
        serializer = self.serializer_class(self.booking, data=request.data, partial=True)
1215

  
1216
        if not serializer.is_valid():
1217
            return Response(
1218
                {
1219
                    'err': 4,
1220
                    'err_class': 'invalid payload',
1221
                    'err_desc': _('invalid payload'),
1222
                    'errors': serializer.errors,
1223
                },
1224
                status=status.HTTP_400_BAD_REQUEST,
1225
            )
1226

  
1227
        serializer.save()
1228
        self.booking.secondary_booking_set.update(user_was_present=self.booking.user_was_present)
1229

  
1230
        response = {'err': 0, 'booking_id': self.booking.pk}
1231
        return Response(response)
1171 1232

  
1172 1233
    def delete(self, request, *args, **kwargs):
1234
        response = self.check_booking()
1235
        if response:
1236
            return response
1237

  
1173 1238
        self.booking.cancel()
1174
        response = {'err': 0, 'booking_id': self.booking.id}
1239
        response = {'err': 0, 'booking_id': self.booking.pk}
1175 1240
        return Response(response)
1176 1241

  
1177 1242

  
tests/test_api.py
1904 1904
    assert Booking.objects.count() == 6
1905 1905

  
1906 1906

  
1907
@pytest.mark.parametrize('flag', [True, False, None])
1908
def test_booking_api_present(app, user, flag):
1909
    agenda = Agenda.objects.create(kind='events')
1910
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1911
    booking = Booking.objects.create(event=event, user_was_present=flag)
1912

  
1913
    app.authorization = ('Basic', ('john.doe', 'password'))
1914
    resp = app.get('/api/booking/%s/' % booking.pk)
1915
    assert resp.json['booking_id'] == booking.pk
1916
    assert resp.json['user_was_present'] == flag
1917

  
1918

  
1919
@pytest.mark.parametrize('flag', [True, False])
1920
def test_booking_api_waiting_list(app, user, flag):
1921
    agenda = Agenda.objects.create(kind='events')
1922
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1923
    booking = Booking.objects.create(event=event, in_waiting_list=flag)
1924

  
1925
    app.authorization = ('Basic', ('john.doe', 'password'))
1926

  
1927
    resp = app.get('/api/booking/%s/' % booking.pk)
1928
    assert resp.json['booking_id'] == booking.pk
1929
    assert resp.json['in_waiting_list'] == flag
1930

  
1931

  
1932
def test_booking_api_error(app, user):
1933
    agenda = Agenda.objects.create(kind='events')
1934
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1935
    booking = Booking.objects.create(event=event)
1936

  
1937
    app.authorization = ('Basic', ('john.doe', 'password'))
1938

  
1939
    # unknown
1940
    booking.cancel()
1941
    for method in ['get', 'delete', 'patch']:
1942
        getattr(app, method)('/api/booking/0/', status=404)
1943

  
1944
    # cancelled
1945
    booking.cancel()
1946
    for method in ['get', 'delete', 'patch']:
1947
        resp = getattr(app, method)('/api/booking/%s/' % booking.pk)
1948
        assert resp.json['err'] == 1
1949
        assert resp.json['err_desc'] == 'booking is cancelled'
1950

  
1951
    # not a primary booking
1952
    secondary = Booking.objects.create(event=event, primary_booking=booking)
1953
    for method in ['get', 'delete', 'patch']:
1954
        resp = getattr(app, method)('/api/booking/%s/' % secondary.pk)
1955
        assert resp.json['err'] == 2
1956
        assert resp.json['err_desc'] == 'secondary booking'
1957

  
1958
    # in waiting list
1959
    booking.cancellation_datetime = None
1960
    booking.in_waiting_list = True
1961
    booking.save()
1962
    resp = app.get('/api/booking/%s/' % booking.pk)
1963
    assert resp.json['err'] == 0
1964
    resp = app.patch('/api/booking/%s/' % booking.pk)
1965
    assert resp.json['err'] == 3
1966
    assert resp.json['err_desc'] == 'booking is in waiting list'
1967
    resp = app.delete('/api/booking/%s/' % booking.pk)
1968
    assert resp.json['err'] == 0
1969

  
1970

  
1971
def test_booking_patch_api(app, user):
1972
    agenda = Agenda.objects.create(kind='events')
1973
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1974
    booking = Booking.objects.create(event=event)
1975

  
1976
    app.authorization = ('Basic', ('john.doe', 'password'))
1977

  
1978
    resp = app.patch('/api/booking/%s/' % booking.pk)
1979
    assert resp.json['err'] == 0
1980
    resp = app.patch('/api/booking/%s/' % booking.pk, params={'user_was_present': 'foobar'}, status=400)
1981
    assert resp.json['err'] == 4
1982
    assert resp.json['err_desc'] == 'invalid payload'
1983

  
1984

  
1985
@pytest.mark.parametrize('flag', [True, False, None])
1986
def test_booking_patch_api_present(app, user, flag):
1987
    agenda = Agenda.objects.create(kind='events')
1988
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1989
    booking = Booking.objects.create(event=event)
1990

  
1991
    app.authorization = ('Basic', ('john.doe', 'password'))
1992

  
1993
    # set flag
1994
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_was_present': flag})
1995
    booking.refresh_from_db()
1996
    assert booking.user_was_present == flag
1997

  
1998
    # reset
1999
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_was_present': None})
2000
    booking.refresh_from_db()
2001
    assert booking.user_was_present is None
2002

  
2003
    # make secondary bookings
2004
    Booking.objects.create(event=event, primary_booking=booking)
2005
    Booking.objects.create(event=event, primary_booking=booking)
2006
    # and other booking
2007
    other_booking = Booking.objects.create(event=event)
2008

  
2009
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_was_present': flag})
2010
    booking.refresh_from_db()
2011
    assert booking.user_was_present == flag
2012
    # all secondary bookings are upadted
2013
    assert list(booking.secondary_booking_set.values_list('user_was_present', flat=True)) == [flag, flag]
2014
    other_booking.refresh_from_db()
2015
    assert other_booking.user_was_present is None  # not changed
2016

  
2017

  
1907 2018
def test_booking_cancellation_api(app, some_data, user):
1908 2019
    agenda = Agenda.objects.filter(label=u'Foo bar')[0]
1909 2020
    event = [x for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()][0]
1910
-