Projet

Général

Profil

0002-api-add-a-suspend-action-on-Booking-40018.patch

Lauréline Guérin, 21 février 2020 16:16

Télécharger (7 ko)

Voir les différences:

Subject: [PATCH 2/2] api: add a suspend action on Booking (#40018)

 chrono/agendas/models.py |  6 ++++++
 chrono/api/urls.py       |  1 +
 chrono/api/views.py      | 38 ++++++++++++++++++++++++++++++++++++++
 tests/test_api.py        | 35 +++++++++++++++++++++++++++++++++++
 4 files changed, 80 insertions(+)
chrono/agendas/models.py
475 475
            self.secondary_booking_set.update(in_waiting_list=False)
476 476
            self.save()
477 477

  
478
    def suspend(self):
479
        self.in_waiting_list = True
480
        with transaction.atomic():
481
            self.secondary_booking_set.update(in_waiting_list=True)
482
            self.save()
483

  
478 484
    def get_ics(self, request=None):
479 485
        ics = vobject.iCalendar()
480 486
        ics.add('prodid').value = '-//Entr\'ouvert//NON SGML Publik'
chrono/api/urls.py
48 48
    url(r'^booking/(?P<booking_pk>\w+)/$', views.booking),
49 49
    url(r'^booking/(?P<booking_pk>\w+)/cancel/$', views.cancel_booking, name='api-cancel-booking'),
50 50
    url(r'^booking/(?P<booking_pk>\w+)/accept/$', views.accept_booking, name='api-accept-booking'),
51
    url(r'^booking/(?P<booking_pk>\w+)/suspend/$', views.suspend_booking, name='api-suspend-booking'),
51 52
    url(r'^booking/(?P<booking_pk>\w+)/ics/$', views.booking_ics, name='api-booking-ics'),
52 53
]
chrono/api/views.py
658 658
            response['api']['accept_url'] = request.build_absolute_uri(
659 659
                reverse('api-accept-booking', kwargs={'booking_pk': primary_booking.id})
660 660
            )
661
        else:
662
            response['api']['suspend_url'] = request.build_absolute_uri(
663
                reverse('api-suspend-booking', kwargs={'booking_pk': primary_booking.pk})
664
            )
661 665
        if agenda.kind == 'meetings':
662 666
            response['end_datetime'] = format_response_datetime(events[-1].end_datetime)
663 667
            response['duration'] = (events[-1].end_datetime - events[-1].start_datetime).seconds // 60
......
776 780
accept_booking = AcceptBooking.as_view()
777 781

  
778 782

  
783
class SuspendBooking(APIView):
784
    '''
785
    Suspend a accepted booking.
786

  
787
    It will return error codes if the booking was cancelled before (code 1) and
788
    if the bookingis already in waiting list (code 2).
789
    '''
790

  
791
    permission_classes = (permissions.IsAuthenticated,)
792

  
793
    def post(self, request, booking_pk=None, format=None):
794
        booking = get_object_or_404(Booking, pk=booking_pk)
795
        if booking.cancellation_datetime:
796
            response = {
797
                'err': 1,
798
                'err_class': 'booking is cancelled',
799
                'err_desc': _('booking is cancelled'),
800
            }
801
            return Response(response)
802
        if booking.in_waiting_list:
803
            response = {
804
                'err': 2,
805
                'err_class': 'booking is already in waiting list',
806
                'err_desc': _('booking is already in waiting list'),
807
            }
808
            return Response(response)
809
        booking.suspend()
810
        response = {'err': 0, 'booking_id': booking.pk}
811
        return Response(response)
812

  
813

  
814
suspend_booking = SuspendBooking.as_view()
815

  
816

  
779 817
class SlotStatus(APIView):
780 818
    permission_classes = (permissions.IsAuthenticated,)
781 819

  
tests/test_api.py
410 410
    Booking.objects.get(id=resp.json['booking_id'])
411 411
    assert resp.json['datetime'] == localtime(event.start_datetime).strftime('%Y-%m-%d %H:%M:%S')
412 412
    assert 'accept_url' not in resp.json['api']
413
    assert 'suspend_url' in resp.json['api']
413 414
    assert 'cancel_url' in resp.json['api']
414 415
    assert 'ics_url' in resp.json['api']
416
    assert urlparse.urlparse(resp.json['api']['suspend_url']).netloc
415 417
    assert urlparse.urlparse(resp.json['api']['cancel_url']).netloc
416 418
    assert urlparse.urlparse(resp.json['api']['ics_url']).netloc
417 419
    assert Booking.objects.count() == 1
......
606 608
    Booking.objects.get(id=primary_booking_id)
607 609
    assert resp.json['datetime'] == localtime(event.start_datetime).strftime('%Y-%m-%d %H:%M:%S')
608 610
    assert 'accept_url' not in resp.json['api']
611
    assert 'suspend_url' in resp.json['api']
609 612
    assert 'cancel_url' in resp.json['api']
613
    assert urlparse.urlparse(resp.json['api']['suspend_url']).netloc
610 614
    assert urlparse.urlparse(resp.json['api']['cancel_url']).netloc
611 615
    assert Booking.objects.count() == 3
612 616
    # these 3 bookings are related, the first is the primary one
......
1201 1205
    assert resp.json['err'] == 0
1202 1206
    assert resp.json['in_waiting_list'] is True
1203 1207
    assert 'accept_url' in resp.json['api']
1208
    assert 'suspend_url' not in resp.json['api']
1204 1209
    assert 'cancel_url' in resp.json['api']
1205 1210
    assert 'ics_url' in resp.json['api']
1206 1211
    assert urlparse.urlparse(resp.json['api']['accept_url']).netloc
......
1263 1268
    assert Booking.objects.filter(in_waiting_list=False).count() == 0
1264 1269

  
1265 1270

  
1271
def test_suspend_booking(app, some_data, user):
1272
    agenda_id = Agenda.objects.filter(label=u'Foo bar')[0].id
1273
    event = Event.objects.filter(agenda_id=agenda_id).exclude(start_datetime__lt=now())[0]
1274
    event.waiting_list_places = 5
1275
    event.save()
1276

  
1277
    # create a booking not on the waiting list
1278
    booking = Booking.objects.create(event=event, in_waiting_list=False)
1279
    assert booking.in_waiting_list is False
1280

  
1281
    app.authorization = ('Basic', ('john.doe', 'password'))
1282
    resp = app.post('/api/booking/%s/suspend/' % booking.pk)
1283
    booking.refresh_from_db()
1284
    assert booking.in_waiting_list is True
1285

  
1286
    # suspend a booking that doesn't exist
1287
    resp = app.post('/api/booking/0/suspend/', status=404)
1288

  
1289
    # suspend a booking that is in the waiting list
1290
    resp = app.post('/api/booking/%s/suspend/' % booking.pk, status=200)
1291
    assert resp.json['err'] == 2
1292

  
1293
    # suspend a booking that was cancelled before
1294
    booking.in_waiting_list = False
1295
    booking.cancel()
1296
    resp = app.post('/api/booking/%s/suspend/' % booking.pk, status=200)
1297
    assert resp.json['err'] == 1
1298
    assert booking.in_waiting_list is False
1299

  
1300

  
1266 1301
def test_multiple_booking_api(app, some_data, user):
1267 1302
    agenda = Agenda.objects.filter(label=u'Foo bar')[0]
1268 1303
    event = [x for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()][0]
1269
-