Projet

Général

Profil

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

Lauréline Guérin, 10 juin 2022 11:54

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):
......
201 201
            'presence': _('unknown presence reason'),
202 202
        }
203 203

  
204
        if not self.instance.event.agenda.check_type_group:
205
            raise serializers.ValidationError(error_messages[kind])
206

  
207
        check_types_qs = self.instance.event.agenda.check_type_group.check_types.filter(
208
            kind=kind, disabled=False
209
        )
210
        try:
211
            return check_types_qs.get(slug=value)
212
        except CheckType.DoesNotExist:
213
            try:
214
                return check_types_qs.get(label=value)
215
            except (CheckType.DoesNotExist, CheckType.MultipleObjectsReturned):
216
                raise serializers.ValidationError(error_messages[kind])
204
        check_types = get_agenda_check_types(self.instance.event.agenda)
205
        for check_type in check_types:
206
            if check_type.kind != kind:
207
                continue
208
            if value in [check_type.slug, check_type.label]:
209
                return check_type
210
        raise serializers.ValidationError(error_messages[kind])
217 211

  
218 212
    def validate_user_absence_reason(self, value):
219 213
        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 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

  
......
318 309

  
319 310

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

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

  
370 350

  
371 351
def test_bookings_api_filter_user_presence_reason(app, user):
372
    group = CheckTypeGroup.objects.create(label='Foo')
373
    check_type_absence = CheckType.objects.create(group=group, label='Foo bar', kind='absence')
374
    check_type_presence = CheckType.objects.create(group=group, label='Foo bar', kind='presence')
375 352
    agenda = Agenda.objects.create(label='Foo bar')
376 353
    event = Event.objects.create(
377 354
        agenda=agenda, start_datetime=make_aware(datetime.datetime(2017, 5, 22, 0, 0)), places=10
......
381 358
        event=event,
382 359
        user_external_id='42',
383 360
        user_was_present=True,
384
        user_check_type_slug=check_type_presence.slug,
385
        user_check_type_label=check_type_presence.label,
361
        user_check_type_slug='foo-bar',
362
        user_check_type_label='Foo bar',
386 363
    )
387 364
    Booking.objects.create(
388 365
        event=event,
389 366
        user_external_id='42',
390 367
        user_was_present=False,
391
        user_check_type_slug=check_type_absence.slug,
392
        user_check_type_label=check_type_absence.label,
368
        user_check_type_slug='foo-bar-2',
369
        user_check_type_label='Foo bar 2',
393 370
    )
394 371

  
395 372
    app.authorization = ('Basic', ('john.doe', 'password'))
396 373
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'foo'})
397 374
    assert resp.json['err'] == 0
398 375
    assert [b['id'] for b in resp.json['data']] == []
399
    resp = app.get(
400
        '/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_presence.slug}
401
    )
376
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'foo-bar'})
402 377
    assert resp.json['err'] == 0
403 378
    assert [b['id'] for b in resp.json['data']] == [booking2.pk]
404
    resp = app.get(
405
        '/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_presence.label}
406
    )
379
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'Foo bar'})
407 380
    assert resp.json['err'] == 0
408 381
    assert [b['id'] for b in resp.json['data']] == [booking2.pk]
409
    resp = app.get(
410
        '/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_absence.slug}
411
    )
382
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'foo-bar-2'})
412 383
    assert resp.json['err'] == 0
413 384
    assert [b['id'] for b in resp.json['data']] == []
414 385
    Booking.objects.update(user_was_present=False)
415
    resp = app.get(
416
        '/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': check_type_presence.label}
417
    )
386
    resp = app.get('/api/bookings/', params={'user_external_id': '42', 'user_presence_reason': 'Foo bar 2'})
418 387
    assert resp.json['err'] == 0
419 388
    assert [b['id'] for b in resp.json['data']] == []
420 389

  
......
487 456

  
488 457
@pytest.mark.parametrize('flag', [True, False, None])
489 458
def test_booking_api_present(app, user, flag):
490
    group = CheckTypeGroup.objects.create(label='Foo')
491
    check_type = CheckType.objects.create(
492
        group=group, label='Foo bar', kind='presence' if flag else 'absence'
493
    )
494 459
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
495 460
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
496
    booking = Booking.objects.create(event=event, user_was_present=flag, user_check_type_slug=check_type.slug)
461
    booking = Booking.objects.create(event=event, user_was_present=flag, user_check_type_slug='foo-bar')
497 462

  
498 463
    app.authorization = ('Basic', ('john.doe', 'password'))
499 464
    resp = app.get('/api/booking/%s/' % booking.pk)
......
628 593
    assert resp.json['err'] == 0
629 594

  
630 595

  
631
def test_booking_patch_api_absence_reason(app, user):
596
@mock.patch('chrono.api.serializers.get_agenda_check_types')
597
def test_booking_patch_api_absence_reason(check_types, app, user):
598
    check_types.return_value = []
632 599
    agenda = Agenda.objects.create(kind='events')
633 600
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
634 601
    booking = Booking.objects.create(event=event, user_was_present=False)
......
642 609
    assert resp.json['err'] == 4
643 610
    assert resp.json['err_desc'] == 'invalid payload'
644 611

  
645
    group = CheckTypeGroup.objects.create(label='Foo')
646
    check_type_absence = CheckType.objects.create(group=group, label='Foo bar', kind='absence')
647
    check_type_presence = CheckType.objects.create(group=group, label='Foo baz', kind='presence')
648
    check_type_absence_disabled = CheckType.objects.create(
649
        label='disabled', group=group, kind='absence', disabled=True
650
    )
651

  
652 612
    resp = app.patch_json(
653 613
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foobar'}, status=400
654 614
    )
655 615
    assert resp.json['err'] == 4
656 616
    assert resp.json['err_desc'] == 'invalid payload'
657 617

  
658
    # wrong kind
659
    resp = app.patch_json(
660
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'Foo baz'}, status=400
661
    )
662
    assert resp.json['err'] == 4
663
    assert resp.json['err_desc'] == 'invalid payload'
664
    resp = app.patch_json(
665
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_presence.slug}, status=400
666
    )
667
    assert resp.json['err'] == 4
668
    assert resp.json['err_desc'] == 'invalid payload'
669

  
670 618
    # set check_type
671
    agenda.check_type_group = group
672
    agenda.save()
619
    check_types.return_value = [
620
        CheckType(slug='foo-bar', label='Foo bar', kind='absence'),
621
        CheckType(slug='foo-baz', label='Foo baz', kind='presence'),
622
    ]
673 623
    # it works with label
674 624
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'Foo bar'})
675 625
    booking.refresh_from_db()
676
    assert booking.user_check_type_slug == check_type_absence.slug
677
    assert booking.user_check_type_label == check_type_absence.label
626
    assert booking.user_check_type_slug == 'foo-bar'
627
    assert booking.user_check_type_label == 'Foo bar'
678 628

  
679
    # disabled
629
    # unknown
680 630
    resp = app.patch_json(
681 631
        '/api/booking/%s/' % booking.pk,
682
        params={'user_absence_reason': check_type_absence_disabled.slug},
632
        params={'user_presence_reason': 'unknown'},
683 633
        status=400,
684 634
    )
685 635
    assert resp.json['err'] == 4
......
702 652
    other_booking = Booking.objects.create(event=event)
703 653

  
704 654
    # it works also with slug
705
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug})
655
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'})
706 656
    booking.refresh_from_db()
707
    assert booking.user_check_type_slug == check_type_absence.slug
708
    assert booking.user_check_type_label == check_type_absence.label
657
    assert booking.user_check_type_slug == 'foo-bar'
658
    assert booking.user_check_type_label == 'Foo bar'
709 659
    # all secondary bookings are updated
710 660
    assert list(booking.secondary_booking_set.values_list('user_check_type_slug', flat=True)) == [
711
        check_type_absence.slug,
712
        check_type_absence.slug,
661
        'foo-bar',
662
        'foo-bar',
713 663
    ]
714 664
    other_booking.refresh_from_db()
715 665
    assert other_booking.user_check_type_slug is None  # not changed
......
718 668
    # user_was_present is True, can not set user_absence_reason
719 669
    Booking.objects.update(user_was_present=True)
720 670
    resp = app.patch_json(
721
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug}, status=400
671
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'}, status=400
722 672
    )
723 673
    assert resp.json['err'] == 6
724 674
    assert resp.json['err_desc'] == 'user is marked as present, can not set absence reason'
......
726 676
    # but it's ok if user_was_present is set to False
727 677
    resp = app.patch_json(
728 678
        '/api/booking/%s/' % booking.pk,
729
        params={'user_absence_reason': check_type_absence.slug, 'user_was_present': False},
679
        params={'user_absence_reason': 'foo-bar', 'user_was_present': False},
730 680
    )
731 681
    assert resp.json['err'] == 0
732 682
    booking.refresh_from_db()
733 683
    assert booking.user_was_present is False
734
    assert booking.user_check_type_slug == check_type_absence.slug
735
    assert booking.user_check_type_label == check_type_absence.label
684
    assert booking.user_check_type_slug == 'foo-bar'
685
    assert booking.user_check_type_label == 'Foo bar'
736 686

  
737 687
    # mark the event as checked
738 688
    event.checked = True
739 689
    event.save()
740
    resp = app.patch_json(
741
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug}
742
    )
690
    resp = app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'})
743 691
    assert resp.json['err'] == 0
744 692

  
745 693
    # now disable check update
746 694
    agenda.disable_check_update = True
747 695
    agenda.save()
748 696
    resp = app.patch_json(
749
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug}, status=400
697
        '/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foo-bar'}, status=400
750 698
    )
751 699
    assert resp.json['err'] == 5
752 700
    assert resp.json['err_desc'] == 'event is marked as checked'
......
754 702
    assert resp.json['err'] == 0
755 703

  
756 704

  
757
def test_booking_patch_api_presence_reason(app, user):
705
@mock.patch('chrono.api.serializers.get_agenda_check_types')
706
def test_booking_patch_api_presence_reason(check_types, app, user):
707
    check_types.return_value = []
758 708
    agenda = Agenda.objects.create(kind='events')
759 709
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
760 710
    booking = Booking.objects.create(event=event, user_was_present=True)
......
768 718
    assert resp.json['err'] == 4
769 719
    assert resp.json['err_desc'] == 'invalid payload'
770 720

  
771
    group = CheckTypeGroup.objects.create(label='Foo')
772
    check_type_presence = CheckType.objects.create(group=group, label='Foo bar', kind='presence')
773
    check_type_absence = CheckType.objects.create(group=group, label='Foo baz', kind='absence')
774
    check_type_presence_disabled = CheckType.objects.create(
775
        label='disabled', group=group, kind='presence', disabled=True
776
    )
777

  
778 721
    resp = app.patch_json(
779 722
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foobar'}, status=400
780 723
    )
781 724
    assert resp.json['err'] == 4
782 725
    assert resp.json['err_desc'] == 'invalid payload'
783 726

  
784
    # wrong kind
785
    resp = app.patch_json(
786
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'Foo baz'}, status=400
787
    )
788
    assert resp.json['err'] == 4
789
    assert resp.json['err_desc'] == 'invalid payload'
790
    resp = app.patch_json(
791
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_absence.slug}, status=400
792
    )
793
    assert resp.json['err'] == 4
794
    assert resp.json['err_desc'] == 'invalid payload'
795

  
796 727
    # set check_type
797
    agenda.check_type_group = group
798
    agenda.save()
728
    check_types.return_value = [
729
        CheckType(slug='foo-bar', label='Foo bar', kind='presence'),
730
        CheckType(slug='foo-baz', label='Foo baz', kind='absence'),
731
    ]
799 732
    # it works with label
800 733
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'Foo bar'})
801 734
    booking.refresh_from_db()
802
    assert booking.user_check_type_slug == check_type_presence.slug
803
    assert booking.user_check_type_label == check_type_presence.label
735
    assert booking.user_check_type_slug == 'foo-bar'
736
    assert booking.user_check_type_label == 'Foo bar'
804 737

  
805
    # disabled
738
    # unknown
806 739
    resp = app.patch_json(
807 740
        '/api/booking/%s/' % booking.pk,
808
        params={'user_presence_reason': check_type_presence_disabled.slug},
741
        params={'user_presence_reason': 'unknown'},
809 742
        status=400,
810 743
    )
811 744
    assert resp.json['err'] == 4
......
828 761
    other_booking = Booking.objects.create(event=event)
829 762

  
830 763
    # it works also with slug
831
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug})
764
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'})
832 765
    booking.refresh_from_db()
833
    assert booking.user_check_type_slug == check_type_presence.slug
834
    assert booking.user_check_type_label == check_type_presence.label
766
    assert booking.user_check_type_slug == 'foo-bar'
767
    assert booking.user_check_type_label == 'Foo bar'
835 768
    # all secondary bookings are updated
836 769
    assert list(booking.secondary_booking_set.values_list('user_check_type_slug', flat=True)) == [
837
        check_type_presence.slug,
838
        check_type_presence.slug,
770
        'foo-bar',
771
        'foo-bar',
839 772
    ]
840 773
    other_booking.refresh_from_db()
841 774
    assert other_booking.user_check_type_slug is None  # not changed
......
844 777
    # user_was_present is False, can not set user_presence_reason
845 778
    Booking.objects.update(user_was_present=False)
846 779
    resp = app.patch_json(
847
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug}, status=400
780
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'}, status=400
848 781
    )
849 782
    assert resp.json['err'] == 6
850 783
    assert resp.json['err_desc'] == 'user is marked as absent, can not set presence reason'
......
852 785
    # but it's ok if user_was_present is set to True
853 786
    resp = app.patch_json(
854 787
        '/api/booking/%s/' % booking.pk,
855
        params={'user_presence_reason': check_type_presence.slug, 'user_was_present': True},
788
        params={'user_presence_reason': 'foo-bar', 'user_was_present': True},
856 789
    )
857 790
    assert resp.json['err'] == 0
858 791
    booking.refresh_from_db()
859 792
    assert booking.user_was_present is True
860
    assert booking.user_check_type_slug == check_type_presence.slug
861
    assert booking.user_check_type_label == check_type_presence.label
793
    assert booking.user_check_type_slug == 'foo-bar'
794
    assert booking.user_check_type_label == 'Foo bar'
862 795

  
863 796
    # mark the event as checked
864 797
    event.checked = True
865 798
    event.save()
866
    resp = app.patch_json(
867
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug}
868
    )
799
    resp = app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'})
869 800
    assert resp.json['err'] == 0
870 801

  
871 802
    # now disable check update
872 803
    agenda.disable_check_update = True
873 804
    agenda.save()
874 805
    resp = app.patch_json(
875
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug}, status=400
806
        '/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foo-bar'}, status=400
876 807
    )
877 808
    assert resp.json['err'] == 5
878 809
    assert resp.json['err_desc'] == 'event is marked as checked'
......
881 812

  
882 813

  
883 814
def test_booking_patch_api_both_reasons(app, user):
884
    group = CheckTypeGroup.objects.create(label='Foo')
885
    CheckType.objects.create(group=group, label='Foo bar', kind='presence')
886
    CheckType.objects.create(group=group, label='Foo baz', kind='absence')
887
    agenda = Agenda.objects.create(kind='events', check_type_group=group)
815
    agenda = Agenda.objects.create(kind='events')
888 816
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
889 817
    booking = Booking.objects.create(event=event)
890 818

  
891
-