Projet

Général

Profil

0003-api-use-check_types-from-lingo-66015.patch

Lauréline Guérin, 17 juin 2022 23:27

Télécharger (23,1 ko)

Voir les différences:

Subject: [PATCH 3/5] api: use check_types from lingo (#66015)

 chrono/api/serializers.py                     |  22 +-
 .../datetimes/test_events_multiple_agendas.py |   9 +-
 tests/api/test_booking.py                     | 200 ++++++------------
 3 files changed, 74 insertions(+), 157 deletions(-)
chrono/api/serializers.py
13 13
    Booking,
14 14
    BookingColor,
15 15
    Category,
16
    CheckType,
17 16
    Event,
18 17
    EventsType,
19 18
    Person,
......
23 22
    Subscription,
24 23
    TimePeriodExceptionGroup,
25 24
)
25
from chrono.utils.lingo import get_agenda_check_types
26 26

  
27 27

  
28 28
def get_objects_from_slugs(slugs, qs):
......
237 237
            'presence': _('unknown presence reason'),
238 238
        }
239 239

  
240
        if not self.instance.event.agenda.check_type_group:
241
            raise serializers.ValidationError(error_messages[kind])
242

  
243
        check_types_qs = self.instance.event.agenda.check_type_group.check_types.filter(
244
            kind=kind, disabled=False
245
        )
246
        try:
247
            return check_types_qs.get(slug=value)
248
        except CheckType.DoesNotExist:
249
            try:
250
                return check_types_qs.get(label=value)
251
            except (CheckType.DoesNotExist, CheckType.MultipleObjectsReturned):
252
                raise serializers.ValidationError(error_messages[kind])
240
        check_types = get_agenda_check_types(self.instance.event.agenda)
241
        for check_type in check_types:
242
            if check_type.kind != kind:
243
                continue
244
            if value in [check_type.slug, check_type.label]:
245
                return check_type
246
        raise serializers.ValidationError(error_messages[kind])
253 247

  
254 248
    def validate_user_absence_reason(self, value):
255 249
        return self._validate_check_type('absence', value)
tests/api/datetimes/test_events_multiple_agendas.py
9 9
    Agenda,
10 10
    Booking,
11 11
    Category,
12
    CheckType,
13
    CheckTypeGroup,
14 12
    Desk,
15 13
    Event,
16 14
    EventsType,
......
1200 1198

  
1201 1199

  
1202 1200
def test_datetimes_multiple_agendas_with_status(app):
1203
    group = CheckTypeGroup.objects.create(label='Foo bar')
1204
    check_type_absence = CheckType.objects.create(label='Foo reason', group=group, kind='absence')
1205
    check_type_presence = CheckType.objects.create(label='Foo reason', group=group, kind='presence')
1206 1201
    agenda = Agenda.objects.create(label='agenda', kind='events')
1207 1202
    Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
1208 1203
    event_booked = Event.objects.create(
......
1242 1237
        event=event_absence_with_reason,
1243 1238
        user_external_id='xxx',
1244 1239
        user_was_present=False,
1245
        user_check_type_slug=check_type_absence.slug,
1240
        user_check_type_slug='foo-reason',
1246 1241
    )
1247 1242
    event_presence = Event.objects.create(
1248 1243
        slug='event-presence',
......
1261 1256
        event=event_presence_with_reason,
1262 1257
        user_external_id='xxx',
1263 1258
        user_was_present=True,
1264
        user_check_type_slug=check_type_presence.slug,
1259
        user_check_type_slug='foo-reason',
1265 1260
    )
1266 1261
    event_booked_future = Event.objects.create(
1267 1262
        slug='event-booked-future',
tests/api/test_booking.py
6 6
from django.test.utils import CaptureQueriesContext
7 7
from django.utils.timezone import localtime, make_aware, now
8 8

  
9
from chrono.agendas.models import (
10
    Agenda,
11
    Booking,
12
    BookingColor,
13
    Category,
14
    CheckType,
15
    CheckTypeGroup,
16
    Desk,
17
    Event,
18
    MeetingType,
19
)
9
from chrono.agendas.models import Agenda, Booking, BookingColor, Category, Desk, Event, MeetingType
10
from chrono.utils.lingo import CheckType
20 11

  
21 12
pytestmark = pytest.mark.django_db
22 13

  
......
324 315

  
325 316

  
326 317
def test_bookings_api_filter_user_absence_reason(app, user):
327
    group = CheckTypeGroup.objects.create(label='Foo')
328
    check_type_absence = CheckType.objects.create(group=group, label='Foo bar', kind='absence')
329
    check_type_presence = CheckType.objects.create(group=group, label='Foo bar', kind='presence')
330 318
    agenda = Agenda.objects.create(label='Foo bar')
331 319
    event = Event.objects.create(
332 320
        agenda=agenda, start_datetime=make_aware(datetime.datetime(2017, 5, 22, 0, 0)), places=10
......
336 324
        event=event,
337 325
        user_external_id='42',
338 326
        user_was_present=False,
339
        user_check_type_slug=check_type_absence.slug,
340
        user_check_type_label=check_type_absence.label,
327
        user_check_type_slug='foo-bar',
328
        user_check_type_label='Foo bar',
341 329
    )
342 330
    Booking.objects.create(
343 331
        event=event,
344 332
        user_external_id='42',
345 333
        user_was_present=True,
346
        user_check_type_slug=check_type_presence.slug,
347
        user_check_type_label=check_type_presence.label,
334
        user_check_type_slug='foo-bar-2',
335
        user_check_type_label='Foo bar 2',
348 336
    )
349 337

  
350 338
    app.authorization = ('Basic', ('john.doe', 'password'))
351 339
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'foo'})
352 340
    assert resp.json['err'] == 0
353 341
    assert [b['id'] for b in resp.json['data']] == []
354
    resp = app.get(
355
        '/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': check_type_absence.slug}
356
    )
342
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'foo-bar'})
357 343
    assert resp.json['err'] == 0
358 344
    assert [b['id'] for b in resp.json['data']] == [booking2.pk]
359
    resp = app.get(
360
        '/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': check_type_absence.label}
361
    )
345
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'Foo bar'})
362 346
    assert resp.json['err'] == 0
363 347
    assert [b['id'] for b in resp.json['data']] == [booking2.pk]
364
    resp = app.get(
365
        '/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': check_type_presence.slug}
366
    )
348
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'foo-bar-2'})
367 349
    assert resp.json['err'] == 0
368 350
    assert [b['id'] for b in resp.json['data']] == []
369 351
    Booking.objects.update(user_was_present=True)
370
    resp = app.get(
371
        '/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': check_type_absence.label}
372
    )
352
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_absence_reason': 'Foo bar 2'})
373 353
    assert resp.json['err'] == 0
374 354
    assert [b['id'] for b in resp.json['data']] == []
375 355

  
376 356

  
377 357
def test_bookings_api_filter_user_presence_reason(app, user):
378
    group = CheckTypeGroup.objects.create(label='Foo')
379
    check_type_absence = CheckType.objects.create(group=group, label='Foo bar', kind='absence')
380
    check_type_presence = CheckType.objects.create(group=group, label='Foo bar', kind='presence')
381 358
    agenda = Agenda.objects.create(label='Foo bar')
382 359
    event = Event.objects.create(
383 360
        agenda=agenda, start_datetime=make_aware(datetime.datetime(2017, 5, 22, 0, 0)), places=10
......
387 364
        event=event,
388 365
        user_external_id='42',
389 366
        user_was_present=True,
390
        user_check_type_slug=check_type_presence.slug,
391
        user_check_type_label=check_type_presence.label,
367
        user_check_type_slug='foo-bar',
368
        user_check_type_label='Foo bar',
392 369
    )
393 370
    Booking.objects.create(
394 371
        event=event,
395 372
        user_external_id='42',
396 373
        user_was_present=False,
397
        user_check_type_slug=check_type_absence.slug,
398
        user_check_type_label=check_type_absence.label,
374
        user_check_type_slug='foo-bar-2',
375
        user_check_type_label='Foo bar 2',
399 376
    )
400 377

  
401 378
    app.authorization = ('Basic', ('john.doe', 'password'))
402 379
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'foo'})
403 380
    assert resp.json['err'] == 0
404 381
    assert [b['id'] for b in resp.json['data']] == []
405
    resp = app.get(
406
        '/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_presence.slug}
407
    )
382
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'foo-bar'})
408 383
    assert resp.json['err'] == 0
409 384
    assert [b['id'] for b in resp.json['data']] == [booking2.pk]
410
    resp = app.get(
411
        '/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_presence.label}
412
    )
385
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'Foo bar'})
413 386
    assert resp.json['err'] == 0
414 387
    assert [b['id'] for b in resp.json['data']] == [booking2.pk]
415
    resp = app.get(
416
        '/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_absence.slug}
417
    )
388
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'foo-bar-2'})
418 389
    assert resp.json['err'] == 0
419 390
    assert [b['id'] for b in resp.json['data']] == []
420 391
    Booking.objects.update(user_was_present=False)
421
    resp = app.get(
422
        '/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_presence.label}
423
    )
392
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'Foo bar 2'})
424 393
    assert resp.json['err'] == 0
425 394
    assert [b['id'] for b in resp.json['data']] == []
426 395

  
......
493 462

  
494 463
@pytest.mark.parametrize('flag', [True, False, None])
495 464
def test_booking_api_present(app, user, flag):
496
    group = CheckTypeGroup.objects.create(label='Foo')
497
    check_type = CheckType.objects.create(
498
        group=group, label='Foo bar', kind='presence' if flag else 'absence'
499
    )
500 465
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
501 466
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
502
    booking = Booking.objects.create(event=event, user_was_present=flag, user_check_type_slug=check_type.slug)
467
    booking = Booking.objects.create(event=event, user_was_present=flag, user_check_type_slug='foo-bar')
503 468

  
504 469
    app.authorization = ('Basic', ('john.doe', 'password'))
505 470
    resp = app.get('/api/booking/%s/' % booking.pk)
......
634 599
    assert resp.json['err'] == 0
635 600

  
636 601

  
637
def test_booking_patch_api_absence_reason(app, user):
602
@mock.patch('chrono.api.serializers.get_agenda_check_types')
603
def test_booking_patch_api_absence_reason(check_types, app, user):
604
    check_types.return_value = []
638 605
    agenda = Agenda.objects.create(kind='events')
639 606
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
640 607
    booking = Booking.objects.create(event=event, user_was_present=False)
......
648 615
    assert resp.json['err'] == 4
649 616
    assert resp.json['err_desc'] == 'invalid payload'
650 617

  
651
    group = CheckTypeGroup.objects.create(label='Foo')
652
    check_type_absence = CheckType.objects.create(group=group, label='Foo bar', kind='absence')
653
    check_type_presence = CheckType.objects.create(group=group, label='Foo baz', kind='presence')
654
    check_type_absence_disabled = CheckType.objects.create(
655
        label='disabled', group=group, kind='absence', disabled=True
656
    )
657

  
658 618
    resp = app.patch_json(
659 619
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foobar'}, status=400
660 620
    )
661 621
    assert resp.json['err'] == 4
662 622
    assert resp.json['err_desc'] == 'invalid payload'
663 623

  
664
    # wrong kind
665
    resp = app.patch_json(
666
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'Foo baz'}, status=400
667
    )
668
    assert resp.json['err'] == 4
669
    assert resp.json['err_desc'] == 'invalid payload'
670
    resp = app.patch_json(
671
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_presence.slug}, status=400
672
    )
673
    assert resp.json['err'] == 4
674
    assert resp.json['err_desc'] == 'invalid payload'
675

  
676 624
    # set check_type
677
    agenda.check_type_group = group
678
    agenda.save()
625
    check_types.return_value = [
626
        CheckType(slug='foo-bar', label='Foo bar', kind='absence'),
627
        CheckType(slug='foo-baz', label='Foo baz', kind='presence'),
628
    ]
679 629
    # it works with label
680 630
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'Foo bar'})
681 631
    booking.refresh_from_db()
682
    assert booking.user_check_type_slug == check_type_absence.slug
683
    assert booking.user_check_type_label == check_type_absence.label
632
    assert booking.user_check_type_slug == 'foo-bar'
633
    assert booking.user_check_type_label == 'Foo bar'
684 634

  
685
    # disabled
635
    # unknown
686 636
    resp = app.patch_json(
687 637
        '/api/booking/%s/' % booking.pk,
688
        params={'user_absence_reason': check_type_absence_disabled.slug},
638
        params={'user_presence_reason': 'unknown'},
689 639
        status=400,
690 640
    )
691 641
    assert resp.json['err'] == 4
......
708 658
    other_booking = Booking.objects.create(event=event)
709 659

  
710 660
    # it works also with slug
711
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug})
661
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'})
712 662
    booking.refresh_from_db()
713
    assert booking.user_check_type_slug == check_type_absence.slug
714
    assert booking.user_check_type_label == check_type_absence.label
663
    assert booking.user_check_type_slug == 'foo-bar'
664
    assert booking.user_check_type_label == 'Foo bar'
715 665
    # all secondary bookings are updated
716 666
    assert list(booking.secondary_booking_set.values_list('user_check_type_slug', flat=True)) == [
717
        check_type_absence.slug,
718
        check_type_absence.slug,
667
        'foo-bar',
668
        'foo-bar',
719 669
    ]
720 670
    other_booking.refresh_from_db()
721 671
    assert other_booking.user_check_type_slug is None  # not changed
......
724 674
    # user_was_present is True, can not set user_absence_reason
725 675
    Booking.objects.update(user_was_present=True)
726 676
    resp = app.patch_json(
727
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug}, status=400
677
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'}, status=400
728 678
    )
729 679
    assert resp.json['err'] == 6
730 680
    assert resp.json['err_desc'] == 'user is marked as present, can not set absence reason'
......
732 682
    # but it's ok if user_was_present is set to False
733 683
    resp = app.patch_json(
734 684
        '/api/booking/%s/' % booking.pk,
735
        params={'user_absence_reason': check_type_absence.slug, 'user_was_present': False},
685
        params={'user_absence_reason': 'foo-bar', 'user_was_present': False},
736 686
    )
737 687
    assert resp.json['err'] == 0
738 688
    booking.refresh_from_db()
739 689
    assert booking.user_was_present is False
740
    assert booking.user_check_type_slug == check_type_absence.slug
741
    assert booking.user_check_type_label == check_type_absence.label
690
    assert booking.user_check_type_slug == 'foo-bar'
691
    assert booking.user_check_type_label == 'Foo bar'
742 692

  
743 693
    # mark the event as checked
744 694
    event.checked = True
745 695
    event.save()
746
    resp = app.patch_json(
747
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug}
748
    )
696
    resp = app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'})
749 697
    assert resp.json['err'] == 0
750 698

  
751 699
    # now disable check update
752 700
    agenda.disable_check_update = True
753 701
    agenda.save()
754 702
    resp = app.patch_json(
755
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug}, status=400
703
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'}, status=400
756 704
    )
757 705
    assert resp.json['err'] == 5
758 706
    assert resp.json['err_desc'] == 'event is marked as checked'
......
760 708
    assert resp.json['err'] == 0
761 709

  
762 710

  
763
def test_booking_patch_api_presence_reason(app, user):
711
@mock.patch('chrono.api.serializers.get_agenda_check_types')
712
def test_booking_patch_api_presence_reason(check_types, app, user):
713
    check_types.return_value = []
764 714
    agenda = Agenda.objects.create(kind='events')
765 715
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
766 716
    booking = Booking.objects.create(event=event, user_was_present=True)
......
774 724
    assert resp.json['err'] == 4
775 725
    assert resp.json['err_desc'] == 'invalid payload'
776 726

  
777
    group = CheckTypeGroup.objects.create(label='Foo')
778
    check_type_presence = CheckType.objects.create(group=group, label='Foo bar', kind='presence')
779
    check_type_absence = CheckType.objects.create(group=group, label='Foo baz', kind='absence')
780
    check_type_presence_disabled = CheckType.objects.create(
781
        label='disabled', group=group, kind='presence', disabled=True
782
    )
783

  
784 727
    resp = app.patch_json(
785 728
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foobar'}, status=400
786 729
    )
787 730
    assert resp.json['err'] == 4
788 731
    assert resp.json['err_desc'] == 'invalid payload'
789 732

  
790
    # wrong kind
791
    resp = app.patch_json(
792
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'Foo baz'}, status=400
793
    )
794
    assert resp.json['err'] == 4
795
    assert resp.json['err_desc'] == 'invalid payload'
796
    resp = app.patch_json(
797
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_absence.slug}, status=400
798
    )
799
    assert resp.json['err'] == 4
800
    assert resp.json['err_desc'] == 'invalid payload'
801

  
802 733
    # set check_type
803
    agenda.check_type_group = group
804
    agenda.save()
734
    check_types.return_value = [
735
        CheckType(slug='foo-bar', label='Foo bar', kind='presence'),
736
        CheckType(slug='foo-baz', label='Foo baz', kind='absence'),
737
    ]
805 738
    # it works with label
806 739
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'Foo bar'})
807 740
    booking.refresh_from_db()
808
    assert booking.user_check_type_slug == check_type_presence.slug
809
    assert booking.user_check_type_label == check_type_presence.label
741
    assert booking.user_check_type_slug == 'foo-bar'
742
    assert booking.user_check_type_label == 'Foo bar'
810 743

  
811
    # disabled
744
    # unknown
812 745
    resp = app.patch_json(
813 746
        '/api/booking/%s/' % booking.pk,
814
        params={'user_presence_reason': check_type_presence_disabled.slug},
747
        params={'user_presence_reason': 'unknown'},
815 748
        status=400,
816 749
    )
817 750
    assert resp.json['err'] == 4
......
834 767
    other_booking = Booking.objects.create(event=event)
835 768

  
836 769
    # it works also with slug
837
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug})
770
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'})
838 771
    booking.refresh_from_db()
839
    assert booking.user_check_type_slug == check_type_presence.slug
840
    assert booking.user_check_type_label == check_type_presence.label
772
    assert booking.user_check_type_slug == 'foo-bar'
773
    assert booking.user_check_type_label == 'Foo bar'
841 774
    # all secondary bookings are updated
842 775
    assert list(booking.secondary_booking_set.values_list('user_check_type_slug', flat=True)) == [
843
        check_type_presence.slug,
844
        check_type_presence.slug,
776
        'foo-bar',
777
        'foo-bar',
845 778
    ]
846 779
    other_booking.refresh_from_db()
847 780
    assert other_booking.user_check_type_slug is None  # not changed
......
850 783
    # user_was_present is False, can not set user_presence_reason
851 784
    Booking.objects.update(user_was_present=False)
852 785
    resp = app.patch_json(
853
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug}, status=400
786
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'}, status=400
854 787
    )
855 788
    assert resp.json['err'] == 6
856 789
    assert resp.json['err_desc'] == 'user is marked as absent, can not set presence reason'
......
858 791
    # but it's ok if user_was_present is set to True
859 792
    resp = app.patch_json(
860 793
        '/api/booking/%s/' % booking.pk,
861
        params={'user_presence_reason': check_type_presence.slug, 'user_was_present': True},
794
        params={'user_presence_reason': 'foo-bar', 'user_was_present': True},
862 795
    )
863 796
    assert resp.json['err'] == 0
864 797
    booking.refresh_from_db()
865 798
    assert booking.user_was_present is True
866
    assert booking.user_check_type_slug == check_type_presence.slug
867
    assert booking.user_check_type_label == check_type_presence.label
799
    assert booking.user_check_type_slug == 'foo-bar'
800
    assert booking.user_check_type_label == 'Foo bar'
868 801

  
869 802
    # mark the event as checked
870 803
    event.checked = True
871 804
    event.save()
872
    resp = app.patch_json(
873
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug}
874
    )
805
    resp = app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'})
875 806
    assert resp.json['err'] == 0
876 807

  
877 808
    # now disable check update
878 809
    agenda.disable_check_update = True
879 810
    agenda.save()
880 811
    resp = app.patch_json(
881
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug}, status=400
812
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'}, status=400
882 813
    )
883 814
    assert resp.json['err'] == 5
884 815
    assert resp.json['err_desc'] == 'event is marked as checked'
......
887 818

  
888 819

  
889 820
def test_booking_patch_api_both_reasons(app, user):
890
    group = CheckTypeGroup.objects.create(label='Foo')
891
    CheckType.objects.create(group=group, label='Foo bar', kind='presence')
892
    CheckType.objects.create(group=group, label='Foo baz', kind='absence')
893
    agenda = Agenda.objects.create(kind='events', check_type_group=group)
821
    agenda = Agenda.objects.create(kind='events')
894 822
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
895 823
    booking = Booking.objects.create(event=event)
896 824

  
897
-