Projet

Général

Profil

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

Lauréline Guérin, 30 novembre 2020 10:01

Télécharger (9,75 ko)

Voir les différences:

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

 .../migrations/0070_booking_attendance.py     |  15 +++
 chrono/agendas/models.py                      |   2 +
 chrono/api/views.py                           |  71 ++++++++++-
 tests/test_api.py                             | 111 ++++++++++++++++++
 4 files changed, 196 insertions(+), 3 deletions(-)
 create mode 100644 chrono/agendas/migrations/0070_booking_attendance.py
chrono/agendas/migrations/0070_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', '0069_translate_holidays'),
11
    ]
12

  
13
    operations = [
14
        migrations.AddField(model_name='booking', name='user_was_present', field=models.NullBooleanField(),),
15
    ]
chrono/agendas/models.py
1042 1042
    user_name = models.CharField(max_length=250, blank=True)
1043 1043
    user_email = models.EmailField(blank=True)
1044 1044
    user_phone_number = models.CharField(max_length=16, blank=True)
1045
    user_was_present = models.NullBooleanField()
1046

  
1045 1047
    form_url = models.URLField(blank=True)
1046 1048
    backoffice_url = models.URLField(blank=True)
1047 1049
    cancel_callback_url = models.URLField(blank=True)
chrono/api/views.py
1144 1144
fillslot = Fillslot.as_view()
1145 1145

  
1146 1146

  
1147
class BookingSerializer(serializers.ModelSerializer):
1148
    class Meta:
1149
        model = Booking
1150
        fields = ['user_was_present']
1151

  
1152

  
1147 1153
class BookingAPI(APIView):
1148 1154
    permission_classes = (permissions.IsAuthenticated,)
1155
    serializer_class = BookingSerializer
1149 1156

  
1150 1157
    def initial(self, request, *args, **kwargs):
1151
        super(BookingAPI, self).initial(request, *args, **kwargs)
1152
        self.booking = Booking.objects.get(id=kwargs.get('booking_pk'), cancellation_datetime__isnull=True)
1158
        super().initial(request, *args, **kwargs)
1159
        self.booking = get_object_or_404(Booking, pk=kwargs.get('booking_pk'))
1160

  
1161
    def check_booking(self, check_waiting_list=False):
1162
        if self.booking.cancellation_datetime:
1163
            return Response(
1164
                {'err': 1, 'err_class': 'booking is cancelled', 'err_desc': _('booking is cancelled')}
1165
            )
1166

  
1167
        if self.booking.primary_booking is not None:
1168
            return Response({'err': 2, 'err_class': 'secondary booking', 'err_desc': _('secondary booking')})
1169

  
1170
        if check_waiting_list and self.booking.in_waiting_list:
1171
            response = {
1172
                'err': 3,
1173
                'err_class': 'booking is in waiting list',
1174
                'err_desc': _('booking is in waiting list'),
1175
            }
1176
            return Response(response)
1177

  
1178
    def get(self, request, *args, **kwargs):
1179
        response = self.check_booking()
1180
        if response:
1181
            return response
1182

  
1183
        response = {
1184
            'err': 0,
1185
            'booking_id': self.booking.pk,
1186
            'in_waiting_list': self.booking.in_waiting_list,
1187
            'user_was_present': self.booking.user_was_present,
1188
        }
1189
        return Response(response)
1190

  
1191
    def patch(self, request, *args, **kwargs):
1192
        response = self.check_booking(check_waiting_list=True)
1193
        if response:
1194
            return response
1195

  
1196
        serializer = self.serializer_class(self.booking, data=request.data, partial=True)
1197

  
1198
        if not serializer.is_valid():
1199
            return Response(
1200
                {
1201
                    'err': 4,
1202
                    'err_class': 'invalid payload',
1203
                    'err_desc': _('invalid payload'),
1204
                    'errors': serializer.errors,
1205
                },
1206
                status=status.HTTP_400_BAD_REQUEST,
1207
            )
1208

  
1209
        serializer.save()
1210
        self.booking.secondary_booking_set.update(user_was_present=self.booking.user_was_present)
1211

  
1212
        response = {'err': 0, 'booking_id': self.booking.pk}
1213
        return Response(response)
1153 1214

  
1154 1215
    def delete(self, request, *args, **kwargs):
1216
        response = self.check_booking()
1217
        if response:
1218
            return response
1219

  
1155 1220
        self.booking.cancel()
1156
        response = {'err': 0, 'booking_id': self.booking.id}
1221
        response = {'err': 0, 'booking_id': self.booking.pk}
1157 1222
        return Response(response)
1158 1223

  
1159 1224

  
tests/test_api.py
1804 1804
    assert Booking.objects.count() == 6
1805 1805

  
1806 1806

  
1807
@pytest.mark.parametrize('flag', [True, False, None])
1808
def test_booking_api_present(app, user, flag):
1809
    agenda = Agenda.objects.create(kind='events')
1810
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1811
    booking = Booking.objects.create(event=event, user_was_present=flag)
1812

  
1813
    app.authorization = ('Basic', ('john.doe', 'password'))
1814
    resp = app.get('/api/booking/%s/' % booking.pk)
1815
    assert resp.json['booking_id'] == booking.pk
1816
    assert resp.json['user_was_present'] == flag
1817

  
1818

  
1819
@pytest.mark.parametrize('flag', [True, False])
1820
def test_booking_api_waiting_list(app, user, flag):
1821
    agenda = Agenda.objects.create(kind='events')
1822
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1823
    booking = Booking.objects.create(event=event, in_waiting_list=flag)
1824

  
1825
    app.authorization = ('Basic', ('john.doe', 'password'))
1826

  
1827
    resp = app.get('/api/booking/%s/' % booking.pk)
1828
    assert resp.json['booking_id'] == booking.pk
1829
    assert resp.json['in_waiting_list'] == flag
1830

  
1831

  
1832
def test_booking_api_error(app, user):
1833
    agenda = Agenda.objects.create(kind='events')
1834
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1835
    booking = Booking.objects.create(event=event)
1836

  
1837
    app.authorization = ('Basic', ('john.doe', 'password'))
1838

  
1839
    # unknown
1840
    booking.cancel()
1841
    for method in ['get', 'delete', 'patch']:
1842
        getattr(app, method)('/api/booking/0/', status=404)
1843

  
1844
    # cancelled
1845
    booking.cancel()
1846
    for method in ['get', 'delete', 'patch']:
1847
        resp = getattr(app, method)('/api/booking/%s/' % booking.pk)
1848
        assert resp.json['err'] == 1
1849
        assert resp.json['err_desc'] == 'booking is cancelled'
1850

  
1851
    # not a primary booking
1852
    secondary = Booking.objects.create(event=event, primary_booking=booking)
1853
    for method in ['get', 'delete', 'patch']:
1854
        resp = getattr(app, method)('/api/booking/%s/' % secondary.pk)
1855
        assert resp.json['err'] == 2
1856
        assert resp.json['err_desc'] == 'secondary booking'
1857

  
1858
    # in waiting list
1859
    booking.cancellation_datetime = None
1860
    booking.in_waiting_list = True
1861
    booking.save()
1862
    resp = app.get('/api/booking/%s/' % booking.pk)
1863
    assert resp.json['err'] == 0
1864
    resp = app.patch('/api/booking/%s/' % booking.pk)
1865
    assert resp.json['err'] == 3
1866
    assert resp.json['err_desc'] == 'booking is in waiting list'
1867
    resp = app.delete('/api/booking/%s/' % booking.pk)
1868
    assert resp.json['err'] == 0
1869

  
1870

  
1871
def test_booking_patch_api(app, user):
1872
    agenda = Agenda.objects.create(kind='events')
1873
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1874
    booking = Booking.objects.create(event=event)
1875

  
1876
    app.authorization = ('Basic', ('john.doe', 'password'))
1877

  
1878
    resp = app.patch('/api/booking/%s/' % booking.pk)
1879
    assert resp.json['err'] == 0
1880
    resp = app.patch('/api/booking/%s/' % booking.pk, params={'user_was_present': 'foobar'}, status=400)
1881
    assert resp.json['err'] == 4
1882
    assert resp.json['err_desc'] == 'invalid payload'
1883

  
1884

  
1885
@pytest.mark.parametrize('flag', [True, False, None])
1886
def test_booking_patch_api_present(app, user, flag):
1887
    agenda = Agenda.objects.create(kind='events')
1888
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
1889
    booking = Booking.objects.create(event=event)
1890

  
1891
    app.authorization = ('Basic', ('john.doe', 'password'))
1892

  
1893
    # set flag
1894
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_was_present': flag})
1895
    booking.refresh_from_db()
1896
    assert booking.user_was_present == flag
1897

  
1898
    # reset
1899
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_was_present': None})
1900
    booking.refresh_from_db()
1901
    assert booking.user_was_present is None
1902

  
1903
    # make secondary bookings
1904
    Booking.objects.create(event=event, primary_booking=booking)
1905
    Booking.objects.create(event=event, primary_booking=booking)
1906
    # and other booking
1907
    other_booking = Booking.objects.create(event=event)
1908

  
1909
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_was_present': flag})
1910
    booking.refresh_from_db()
1911
    assert booking.user_was_present == flag
1912
    # all secondary bookings are upadted
1913
    assert list(booking.secondary_booking_set.values_list('user_was_present', flat=True)) == [flag, flag]
1914
    other_booking.refresh_from_db()
1915
    assert other_booking.user_was_present is None  # not changed
1916

  
1917

  
1807 1918
def test_booking_cancellation_api(app, some_data, user):
1808 1919
    agenda = Agenda.objects.filter(label=u'Foo bar')[0]
1809 1920
    event = [x for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()][0]
1810
-