Projet

Général

Profil

0001-api-return-err_desc-reason-in-case-of-error-24025.patch

Lauréline Guérin, 31 octobre 2019 15:31

Télécharger (26,9 ko)

Voir les différences:

Subject: [PATCH] api: return err_desc & reason in case of error (#24025)

 chrono/api/utils.py     |  26 +++++++++
 chrono/api/views.py     |  67 +++++++++++++++++-----
 tests/test_api.py       | 124 ++++++++++++++++++++++++++++++----------
 tests/test_api_utils.py |  15 +++++
 4 files changed, 186 insertions(+), 46 deletions(-)
 create mode 100644 chrono/api/utils.py
 create mode 100644 tests/test_api_utils.py
chrono/api/utils.py
1
# -*- coding: utf-8 -*-
2
# chrono - agendas system
3
# Copyright (C) 2019  Entr'ouvert
4
#
5
# This program is free software: you can redistribute it and/or modify it
6
# under the terms of the GNU Affero General Public License as published
7
# by the Free Software Foundation, either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU Affero General Public License for more details.
14
#
15
# You should have received a copy of the GNU Affero General Public License
16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17

  
18
from rest_framework.response import Response as DRFResponse
19

  
20

  
21
class Response(DRFResponse):
22
    def __init__(self, data=None, *args, **kwargs):
23
        # add reason for compatibility (https://dev.entrouvert.org/issues/24025)
24
        if data is not None and 'err_class' in data:
25
            data['reason'] = data['err_class']
26
        super(Response, self).__init__(data=data, *args, **kwargs)
chrono/api/views.py
24 24
from django.utils.dateparse import parse_date
25 25
from django.utils.encoding import force_text
26 26
from django.utils.timezone import now, make_aware, localtime
27
from django.utils.translation import ugettext_lazy as _
27 28

  
28 29
from rest_framework import permissions, serializers, status
29
from rest_framework.response import Response
30

  
30 31
from rest_framework.views import APIView
31 32

  
33
from chrono.api.utils import Response
32 34
from ..agendas.models import (Agenda, Event, Booking, MeetingType,
33 35
                              TimePeriod, Desk)
34 36
from ..interval import Intervals
......
351 353
        if not serializer.is_valid():
352 354
            return Response({
353 355
                'err': 1,
354
                'reason': 'invalid payload',
356
                'err_class': 'invalid payload',
357
                'err_desc': _('invalid payload'),
355 358
                'errors': serializer.errors
356 359
            }, status=status.HTTP_400_BAD_REQUEST)
357 360
        payload = serializer.validated_data
......
361 364
        if not slots:
362 365
            return Response({
363 366
                'err': 1,
364
                'reason': 'slots list cannot be empty',
367
                'err_class': 'slots list cannot be empty',
368
                'err_desc': _('slots list cannot be empty'),
365 369
            }, status=status.HTTP_400_BAD_REQUEST)
366 370

  
367 371
        if 'count' in payload:
......
373 377
            except ValueError:
374 378
                return Response({
375 379
                    'err': 1,
376
                    'reason': 'invalid value for count (%s)' % request.query_params['count'],
380
                    'err_class': 'invalid value for count (%s)' % request.query_params['count'],
381
                    'err_desc': _('invalid value for count (%s)') % request.query_params['count'],
377 382
                }, status=status.HTTP_400_BAD_REQUEST)
378 383
        else:
379 384
            places_count = 1
......
381 386
        if places_count <= 0:
382 387
            return Response({
383 388
                'err': 1,
384
                'reason': 'count cannot be less than or equal to zero'
389
                'err_class': 'count cannot be less than or equal to zero',
390
                'err_desc': _('count cannot be less than or equal to zero'),
385 391
            }, status=status.HTTP_400_BAD_REQUEST)
386 392

  
387 393
        to_cancel_booking = None
......
392 398
            except (ValueError, TypeError):
393 399
                return Response({
394 400
                    'err': 1,
395
                    'reason': 'cancel_booking_id is not an integer'
401
                    'err_class': 'cancel_booking_id is not an integer',
402
                    'err_desc': _('cancel_booking_id is not an integer'),
396 403
                }, status=status.HTTP_400_BAD_REQUEST)
397 404

  
398 405
        if cancel_booking_id is not None:
......
409 416
                cancel_error = 'cancel booking: booking does no exist'
410 417

  
411 418
            if cancel_error:
412
                return Response({'err': 1, 'reason': cancel_error})
419
                return Response({
420
                    'err': 1,
421
                    'err_class': cancel_error,
422
                    'err_desc': _(cancel_error),
423
                })
413 424

  
414 425
        extra_data = {}
415 426
        for k, v in request.data.items():
......
429 440
                except ValueError:
430 441
                    return Response({
431 442
                        'err': 1,
432
                        'reason': 'invalid slot: %s' % slot,
443
                        'err_class': 'invalid slot: %s' % slot,
444
                        'err_desc': _('invalid slot: %s') % slot,
433 445
                    }, status=status.HTTP_400_BAD_REQUEST)
434 446
                if meeting_type_id_ != meeting_type_id:
435 447
                    return Response({
436 448
                        'err': 1,
437
                        'reason': 'all slots must have the same meeting type id (%s)' % meeting_type_id
449
                        'err_class': 'all slots must have the same meeting type id (%s)' % meeting_type_id,
450
                        'err_desc': _('all slots must have the same meeting type id (%s)') % meeting_type_id,
438 451
                    }, status=status.HTTP_400_BAD_REQUEST)
439 452
                datetimes.add(make_aware(datetime.datetime.strptime(datetime_str, '%Y-%m-%d-%H%M')))
440 453

  
......
451 464
                    available_desk = Desk.objects.get(id=available_desk_id)
452 465
                    break
453 466
            else:
454
                return Response({'err': 1, 'reason': 'no more desk available'})
467
                return Response({
468
                    'err': 1,
469
                    'err_class': 'no more desk available',
470
                    'err_desc': _('no more desk available'),
471
                })
455 472

  
456 473
            # all datetimes are free, book them in order
457 474
            datetimes = list(datetimes)
......
478 495
                    # in the waiting list.
479 496
                    in_waiting_list = True
480 497
                    if (event.waiting_list + places_count) > event.waiting_list_places:
481
                        return Response({'err': 1, 'reason': 'sold out'})
498
                        return Response({
499
                            'err': 1,
500
                            'err_class': 'sold out',
501
                            'err_desc': _('sold out'),
502
                        })
482 503
            else:
483 504
                if (event.booked_places + places_count) > event.places:
484
                    return Response({'err': 1, 'reason': 'sold out'})
505
                    return Response({
506
                        'err': 1,
507
                        'err_class': 'sold out',
508
                        'err_desc': _('sold out')
509
                    })
485 510

  
486 511
        with transaction.atomic():
487 512
            if to_cancel_booking:
......
574 599
    def post(self, request, booking_pk=None, format=None):
575 600
        booking = get_object_or_404(Booking, id=booking_pk)
576 601
        if booking.cancellation_datetime:
577
            response = {'err': 1, 'reason': 'already cancelled'}
602
            response = {
603
                'err': 1,
604
                'err_class': 'already cancelled',
605
                'err_desc': _('already cancelled'),
606
            }
578 607
            return Response(response)
579 608
        booking.cancel()
580 609
        response = {'err': 0, 'booking_id': booking.id}
......
595 624
    def post(self, request, booking_pk=None, format=None):
596 625
        booking = get_object_or_404(Booking, id=booking_pk)
597 626
        if booking.cancellation_datetime:
598
            response = {'err': 1, 'reason': 'booking is cancelled'}
627
            response = {
628
                'err': 1,
629
                'err_class': 'booking is cancelled',
630
                'err_desc': _('booking is cancelled'),
631
            }
599 632
            return Response(response)
600 633
        if not booking.in_waiting_list:
601
            response = {'err': 2, 'reason': 'booking is not in waiting list'}
634
            response = {
635
                'err': 2,
636
                'err_class': 'booking is not in waiting list',
637
                'err_desc': _('booking is not in waiting list'),
638
            }
602 639
            return Response(response)
603 640
        booking.accept()
604 641
        response = {'err': 0, 'booking_id': booking.id}
tests/test_api.py
316 316
    app.authorization = ('Basic', ('john.doe', 'password'))
317 317
    resp = app.post(fillslot_url)
318 318
    assert resp.json['err'] == 1
319
    assert resp.json['reason'] == 'no more desk available'
319
    assert resp.json['reason'] == 'no more desk available'  # legacy
320
    assert resp.json['err_class'] == 'no more desk available'
321
    assert resp.json['err_desc'] == 'no more desk available'
320 322
    # booking the two slots fails too
321 323
    fillslots_url = '/api/agenda/%s/fillslots/' % meeting_type.agenda.slug
322 324
    resp = app.post(fillslots_url, params={'slots': two_slots})
323 325
    assert resp.json['err'] == 1
324
    assert resp.json['reason'] == 'no more desk available'
326
    assert resp.json['reason'] == 'no more desk available'  # legacy
327
    assert resp.json['err_class'] == 'no more desk available'
328
    assert resp.json['err_desc'] == 'no more desk available'
325 329

  
326 330
def test_booking_api(app, some_data, user):
327 331
    agenda = Agenda.objects.filter(label=u'Foo bar')[0]
......
376 380
    resp = app.post_json('/api/agenda/%s/fillslot/%s/' % (agenda.id, event.id),
377 381
            params={'user_name': {'foo': 'bar'}}, status=400)
378 382
    assert resp.json['err'] == 1
379
    assert resp.json['reason'] == 'invalid payload'
383
    assert resp.json['reason'] == 'invalid payload'  # legacy
384
    assert resp.json['err_class'] == 'invalid payload'
385
    assert resp.json['err_desc'] == 'invalid payload'
380 386
    assert len(resp.json['errors']) == 1
381 387
    assert 'user_name' in resp.json['errors']
382 388

  
......
538 544
            params={'slots': events_ids,
539 545
                    'user_name': {'foo': 'bar'}}, status=400)
540 546
    assert resp.json['err'] == 1
541
    assert resp.json['reason'] == 'invalid payload'
547
    assert resp.json['reason'] == 'invalid payload'  # legacy
548
    assert resp.json['err_class'] == 'invalid payload'
549
    assert resp.json['err_desc'] == 'invalid payload'
542 550
    assert len(resp.json['errors']) == 1
543 551
    assert 'user_name' in resp.json['errors']
544 552

  
545 553
    # empty or missing slots
546 554
    resp = app.post_json('/api/agenda/%s/fillslots/' % agenda.id, params={'slots': []}, status=400)
547 555
    assert resp.json['err'] == 1
548
    assert resp.json['reason'] == 'slots list cannot be empty'
556
    assert resp.json['reason'] == 'slots list cannot be empty'  # legacy
557
    assert resp.json['err_class'] == 'slots list cannot be empty'
558
    assert resp.json['err_desc'] == 'slots list cannot be empty'
549 559
    resp = app.post_json('/api/agenda/%s/fillslots/' % agenda.id, status=400)
550 560
    assert resp.json['err'] == 1
551
    assert resp.json['reason'] == 'slots list cannot be empty'
561
    assert resp.json['reason'] == 'slots list cannot be empty'  # legacy
562
    assert resp.json['err_class'] == 'slots list cannot be empty'
563
    assert resp.json['err_desc'] == 'slots list cannot be empty'
552 564
    # invalid slots format
553 565
    resp = app.post_json('/api/agenda/%s/fillslots/' % agenda.id, params={'slots': 'foobar'}, status=400)
554 566
    assert resp.json['err'] == 1
555
    assert resp.json['reason'] == 'invalid payload'
567
    assert resp.json['reason'] == 'invalid payload'  # legacy
568
    assert resp.json['err_class'] == 'invalid payload'
569
    assert resp.json['err_desc'] == 'invalid payload'
556 570
    assert len(resp.json['errors']) == 1
557 571
    assert 'slots' in resp.json['errors']
558 572

  
......
589 603
    # try booking the same timeslot
590 604
    resp2 = app.post('/api/agenda/%s/fillslot/%s/' % (agenda_id, event_id))
591 605
    assert resp2.json['err'] == 1
592
    assert resp2.json['reason'] == 'no more desk available'
606
    assert resp2.json['reason'] == 'no more desk available'  # legacy
607
    assert resp2.json['err_class'] == 'no more desk available'
608
    assert resp2.json['err_desc'] == 'no more desk available'
593 609

  
594 610
    # try booking another timeslot
595 611
    event_id = resp.json['data'][3]['id']
......
619 635
    # try booking the same timeslots
620 636
    resp2 = app.post('/api/agenda/%s/fillslots/' % agenda_id, params={'slots': slots})
621 637
    assert resp2.json['err'] == 1
622
    assert resp2.json['reason'] == 'no more desk available'
638
    assert resp2.json['reason'] == 'no more desk available'  # legacy
639
    assert resp2.json['err_class'] == 'no more desk available'
640
    assert resp2.json['err_desc'] == 'no more desk available'
623 641

  
624 642
    # try booking partially free timeslots (one free, one busy)
625 643
    nonfree_slots = [resp.json['data'][0]['id'], resp.json['data'][2]['id']]
626 644
    resp2 = app.post('/api/agenda/%s/fillslots/' % agenda_id, params={'slots': nonfree_slots})
627 645
    assert resp2.json['err'] == 1
628
    assert resp2.json['reason'] == 'no more desk available'
646
    assert resp2.json['reason'] == 'no more desk available'  # legacy
647
    assert resp2.json['err_class'] == 'no more desk available'
648
    assert resp2.json['err_desc'] == 'no more desk available'
629 649

  
630 650
    # booking other free timeslots
631 651
    free_slots = [resp.json['data'][3]['id'], resp.json['data'][2]['id']]
......
647 667
                    params={'slots': impossible_slots},
648 668
                    status=400)
649 669
    assert resp.json['err'] == 1
650
    assert resp.json['reason'] == 'all slots must have the same meeting type id (1)'
670
    assert resp.json['reason'] == 'all slots must have the same meeting type id (1)'  # legacy
671
    assert resp.json['err_class'] == 'all slots must have the same meeting type id (1)'
672
    assert resp.json['err_desc'] == 'all slots must have the same meeting type id (1)'
651 673

  
652 674
def test_booking_api_meeting_across_daylight_saving_time(app, meetings_agenda, user):
653 675
    meetings_agenda.maximal_booking_delay = 365
......
762 784
        params={'cancel_booking_id': first_booking.pk}
763 785
    )
764 786
    assert resp.json['err'] == 1
765
    assert resp.json['reason'] == 'cancel booking: booking already cancelled'
787
    assert resp.json['reason'] == 'cancel booking: booking already cancelled'  # legacy
788
    assert resp.json['err_class'] == 'cancel booking: booking already cancelled'
789
    assert resp.json['err_desc'] == 'cancel booking: booking already cancelled'
766 790
    assert Booking.objects.count() == 2
767 791

  
768 792
    # Cancelling a non existent booking returns an error
......
771 795
        params={'cancel_booking_id': '-1'}
772 796
    )
773 797
    assert resp.json['err'] == 1
774
    assert resp.json['reason'] == 'cancel booking: booking does no exist'
798
    assert resp.json['reason'] == 'cancel booking: booking does no exist'  # legacy
799
    assert resp.json['err_class'] == 'cancel booking: booking does no exist'
800
    assert resp.json['err_desc'] == 'cancel booking: booking does no exist'
775 801
    assert Booking.objects.count() == 2
776 802

  
777 803
    # Cancelling booking with different count than new booking
......
788 814
        params={'cancel_booking_id': booking_id, 'count': 1}
789 815
    )
790 816
    assert resp.json['err'] == 1
791
    assert resp.json['reason'] == 'cancel booking: count is different'
817
    assert resp.json['reason'] == 'cancel booking: count is different'  # legacy
818
    assert resp.json['err_class'] == 'cancel booking: count is different'
819
    assert resp.json['err_desc'] == 'cancel booking: count is different'
792 820
    assert Booking.objects.count() == 4
793 821

  
794 822
    # cancel_booking_id must be an integer
......
887 915
    app.authorization = ('Basic', ('john.doe', 'password'))
888 916
    resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda_id, event.id), status=200)
889 917
    assert resp.json['err'] == 1
890
    assert resp.json['reason'] == 'sold out'
918
    assert resp.json['reason'] == 'sold out'  # legacy
919
    assert resp.json['err_class'] == 'sold out'
920
    assert resp.json['err_desc'] == 'sold out'
891 921

  
892 922
def test_status(app, some_data, user):
893 923
    agenda_id = Agenda.objects.filter(label=u'Foo bar')[0].id
......
980 1010
    app.authorization = ('Basic', ('john.doe', 'password'))
981 1011
    resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda_id, event.id), status=200)
982 1012
    assert resp.json['err'] == 1
983
    assert resp.json['reason'] == 'sold out'
1013
    assert resp.json['reason'] == 'sold out'  # legacy
1014
    assert resp.json['err_class'] == 'sold out'
1015
    assert resp.json['err_desc'] == 'sold out'
984 1016

  
985 1017
def test_accept_booking(app, some_data, user):
986 1018
    agenda_id = Agenda.objects.filter(label=u'Foo bar')[0].id
......
1025 1057
    app.authorization = ('Basic', ('john.doe', 'password'))
1026 1058
    resp = app.post('/api/agenda/%s/fillslot/%s/?count=NaN' % (agenda.slug, event.id), status=400)
1027 1059
    assert resp.json['err'] == 1
1028
    assert resp.json['reason'] == "invalid value for count (NaN)"
1060
    assert resp.json['reason'] == "invalid value for count (NaN)"  # legacy
1061
    assert resp.json['err_class'] == "invalid value for count (NaN)"
1062
    assert resp.json['err_desc'] == "invalid value for count (NaN)"
1029 1063

  
1030 1064
    app.authorization = ('Basic', ('john.doe', 'password'))
1031 1065
    resp = app.post('/api/agenda/%s/fillslot/%s/?count=0' % (agenda.slug, event.id), status=400)
1032 1066
    assert resp.json['err'] == 1
1033
    assert resp.json['reason'] == "count cannot be less than or equal to zero"
1067
    assert resp.json['reason'] == "count cannot be less than or equal to zero"  # legacy
1068
    assert resp.json['err_class'] == "count cannot be less than or equal to zero"
1069
    assert resp.json['err_desc'] == "count cannot be less than or equal to zero"
1034 1070

  
1035 1071
    app.authorization = ('Basic', ('john.doe', 'password'))
1036 1072
    resp = app.post('/api/agenda/%s/fillslot/%s/?count=-3' % (agenda.slug, event.id), status=400)
1037 1073
    assert resp.json['err'] == 1
1038
    assert resp.json['reason'] == "count cannot be less than or equal to zero"
1074
    assert resp.json['reason'] == "count cannot be less than or equal to zero"  # legacy
1075
    assert resp.json['err_class'] == "count cannot be less than or equal to zero"
1076
    assert resp.json['err_desc'] == "count cannot be less than or equal to zero"
1039 1077

  
1040 1078
    resp = app.post('/api/agenda/%s/fillslot/%s/?count=3' % (agenda.slug, event.id))
1041 1079
    Booking.objects.get(id=resp.json['booking_id'])
......
1062 1100
    # check waiting list overflow
1063 1101
    resp = app.post('/api/agenda/%s/fillslot/%s/?count=5' % (agenda.slug, event.id))
1064 1102
    assert resp.json['err'] == 1
1065
    assert resp.json['reason'] == 'sold out'
1103
    assert resp.json['reason'] == 'sold out'  # legacy
1104
    assert resp.json['err_class'] == 'sold out'
1105
    assert resp.json['err_desc'] == 'sold out'
1066 1106
    assert Event.objects.get(id=event.id).booked_places == 2
1067 1107
    assert Event.objects.get(id=event.id).waiting_list == 5
1068 1108

  
......
1079 1119

  
1080 1120
    resp = app.post('/api/agenda/%s/fillslot/%s/?count=5' % (agenda.slug, event.id))
1081 1121
    assert resp.json['err'] == 1
1082
    assert resp.json['reason'] == 'sold out'
1122
    assert resp.json['reason'] == 'sold out'  # legacy
1123
    assert resp.json['err_class'] == 'sold out'
1124
    assert resp.json['err_desc'] == 'sold out'
1083 1125

  
1084 1126
    resp = app.post('/api/agenda/%s/fillslot/%s/?count=3' % (agenda.slug, event.id))
1085 1127
    assert resp.json['err'] == 0
......
1088 1130

  
1089 1131
    resp = app.post('/api/agenda/%s/fillslot/%s/?count=3' % (agenda.slug, event.id))
1090 1132
    assert resp.json['err'] == 1
1091
    assert resp.json['reason'] == 'sold out'
1133
    assert resp.json['reason'] == 'sold out'  # legacy
1134
    assert resp.json['err_class'] == 'sold out'
1135
    assert resp.json['err_desc'] == 'sold out'
1092 1136

  
1093 1137
    resp = app.post('/api/agenda/%s/fillslot/%s/?count=2' % (agenda.slug, event.id))
1094 1138
    assert resp.json['err'] == 0
......
1106 1150
    app.authorization = ('Basic', ('john.doe', 'password'))
1107 1151
    resp = app.post('/api/agenda/%s/fillslots/?count=NaN' % agenda.slug, params={'slots': slots}, status=400)
1108 1152
    assert resp.json['err'] == 1
1109
    assert resp.json['reason'] == "invalid value for count (NaN)"
1153
    assert resp.json['reason'] == "invalid value for count (NaN)"  # legacy
1154
    assert resp.json['err_class'] == "invalid value for count (NaN)"
1155
    assert resp.json['err_desc'] == "invalid value for count (NaN)"
1110 1156

  
1111 1157
    resp = app.post('/api/agenda/%s/fillslots/' % agenda.slug,
1112 1158
                    params={'slots': slots, 'count': 'NaN'}, status=400)
1113 1159
    assert resp.json['err'] == 1
1114
    assert resp.json['reason'] == "invalid payload"
1160
    assert resp.json['reason'] == "invalid payload"  # legacy
1161
    assert resp.json['err_class'] == "invalid payload"
1162
    assert resp.json['err_desc'] == "invalid payload"
1115 1163
    assert 'count' in resp.json['errors']
1116 1164

  
1117 1165
    # get 3 places on 2 slots
......
1155 1203
    resp = app.post('/api/agenda/%s/fillslots/' % agenda.slug,
1156 1204
                    params={'slots': slots, 'count': 5})
1157 1205
    assert resp.json['err'] == 1
1158
    assert resp.json['reason'] == 'sold out'
1206
    assert resp.json['reason'] == 'sold out'  # legacy
1207
    assert resp.json['err_class'] == 'sold out'
1208
    assert resp.json['err_desc'] == 'sold out'
1159 1209
    for event in events:
1160 1210
        assert Event.objects.get(id=event.id).booked_places == 2
1161 1211
        assert Event.objects.get(id=event.id).waiting_list == 5
......
1176 1226
    resp = app.post('/api/agenda/%s/fillslots/' % agenda.slug,
1177 1227
                    params={'slots': slots, 'count': 5})
1178 1228
    assert resp.json['err'] == 1
1179
    assert resp.json['reason'] == 'sold out'
1229
    assert resp.json['reason'] == 'sold out'  # legacy
1230
    assert resp.json['err_class'] == 'sold out'
1231
    assert resp.json['err_desc'] == 'sold out'
1180 1232

  
1181 1233
    resp = app.post('/api/agenda/%s/fillslots/' % agenda.slug,
1182 1234
                    params={'slots': slots, 'count': 3})
......
1188 1240
    resp = app.post('/api/agenda/%s/fillslots/' % agenda.slug,
1189 1241
                    params={'slots': slots, 'count': 3})
1190 1242
    assert resp.json['err'] == 1
1191
    assert resp.json['reason'] == 'sold out'
1243
    assert resp.json['reason'] == 'sold out'  # legacy
1244
    assert resp.json['err_class'] == 'sold out'
1245
    assert resp.json['err_desc'] == 'sold out'
1192 1246

  
1193 1247
    resp = app.post('/api/agenda/%s/fillslots/' % agenda.slug,
1194 1248
                    params={'slots': slots, 'count': '2'})
......
1299 1353
    resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda_id, event_id))
1300 1354
    assert Booking.objects.count() == 2
1301 1355
    assert resp.json['err'] == 1
1302
    assert resp.json['reason'] == 'no more desk available'
1356
    assert resp.json['reason'] == 'no more desk available'  # legacy
1357
    assert resp.json['err_class'] == 'no more desk available'
1358
    assert resp.json['err_desc'] == 'no more desk available'
1303 1359

  
1304 1360
    # cancel first booking and retry
1305 1361
    resp = app.post(cancel_url)
......
1336 1392
    # try booking the same timeslot again and fail
1337 1393
    resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda_id, event_id))
1338 1394
    assert resp.json['err'] == 1
1339
    assert resp.json['reason'] == 'no more desk available'
1395
    assert resp.json['reason'] == 'no more desk available'  # legacy
1396
    assert resp.json['err_class'] == 'no more desk available'
1397
    assert resp.json['err_desc'] == 'no more desk available'
1340 1398

  
1341 1399
    # fill the agenda and make sure big O is O(1)
1342 1400
    for idx, event_data in enumerate(resp2.json['data'][2:10]):
......
1387 1445
    # try booking again: no desk available
1388 1446
    resp = app.post(fillslots_url, params={'slots': slots})
1389 1447
    assert resp.json['err'] == 1
1390
    assert resp.json['reason'] == 'no more desk available'
1448
    assert resp.json['reason'] == 'no more desk available'  # legacy
1449
    assert resp.json['err_class'] == 'no more desk available'
1450
    assert resp.json['err_desc'] == 'no more desk available'
1391 1451
    assert get_free_places() == start_free_places - len(slots)
1392 1452

  
1393 1453
    # cancel desk 1 booking
......
1406 1466
    # try booking the 3 slots again: no desk available, one slot is not fully available
1407 1467
    resp = app.post(fillslots_url, params={'slots': slots})
1408 1468
    assert resp.json['err'] == 1
1409
    assert resp.json['reason'] == 'no more desk available'
1469
    assert resp.json['reason'] == 'no more desk available'  # legacy
1470
    assert resp.json['err_class'] == 'no more desk available'
1471
    assert resp.json['err_desc'] == 'no more desk available'
1410 1472

  
1411 1473
    # cancel last signel slot booking, desk1 will be free
1412 1474
    resp = app.post(cancel_url)
tests/test_api_utils.py
1
import pytest
2

  
3
from chrono.api.utils import Response
4

  
5

  
6
@pytest.mark.parametrize('data, expected', [
7
    (None, None),
8
    ({}, {}),
9
    ({'reason': 'foo'}, {'reason': 'foo'}),
10
    ({'err_class': 'foo'}, {'err_class': 'foo', 'reason': 'foo'}),
11
    ({'bar': 'foo'}, {'bar': 'foo'}),
12
])
13
def test_response_data(data, expected):
14
    resp = Response(data=data)
15
    assert resp.data == expected
0
-