Projet

Général

Profil

0003-api-cancel-booking-in-agendas-events-fillslots-inste.patch

Lauréline Guérin, 07 février 2022 17:35

Télécharger (18,3 ko)

Voir les différences:

Subject: [PATCH 3/3] api: cancel booking in agendas events fillslots - instead
 of delete (#61066)

 chrono/api/views.py        |   6 +-
 tests/api/test_fillslot.py | 205 +++++++++++++++++++++++++++++--------
 2 files changed, 168 insertions(+), 43 deletions(-)
chrono/api/views.py
1918 1918
        return events
1919 1919

  
1920 1920
    def get_already_booked_events(self, user_external_id):
1921
        return Event.objects.filter(agenda__in=self.agendas, booking__user_external_id=user_external_id)
1921
        return Event.objects.filter(
1922
            agenda__in=self.agendas,
1923
            booking__user_external_id=user_external_id,
1924
            booking__cancellation_datetime__isnull=True,
1925
        )
1922 1926

  
1923 1927
    def get_agendas_by_ids(self):
1924 1928
        return {a.pk: a for a in self.agendas}
tests/api/test_fillslot.py
3560 3560
    assert resp.json['booking_count'] == 0
3561 3561
    assert resp.json['cancelled_booking_count'] == 1
3562 3562
    assert event.booking_set.count() == 1
3563
    assert second_event.booking_set.count() == 0
3563
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
3564 3564

  
3565 3565

  
3566 3566
@pytest.mark.freeze_time('2021-09-06 12:00')
......
3588 3588
    resp = app.post_json(fillslots_url, params=params)
3589 3589
    assert resp.json['booking_count'] == 0
3590 3590
    assert resp.json['cancelled_booking_count'] == 0
3591
    assert event.booking_set.count() == 1
3592
    assert second_event.booking_set.count() == 1
3591
    assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3592
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3593 3593
    booking = event.booking_set.get()
3594 3594
    # except if we want to bypass delays
3595 3595
    params = {'user_external_id': 'user_id', 'slots': 'event-2', 'bypass_delays': True}
3596 3596
    resp = app.post_json(fillslots_url, params=params)
3597 3597
    assert resp.json['booking_count'] == 0
3598 3598
    assert resp.json['cancelled_booking_count'] == 1
3599
    assert event.booking_set.count() == 0
3600
    assert second_event.booking_set.count() == 1
3599
    assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
3600
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3601 3601
    booking.save()  # reset
3602 3602

  
3603 3603
    # cancel all bookings in delays
......
3606 3606
    assert resp.json['booking_count'] == 0
3607 3607
    assert resp.json['cancelled_booking_count'] == 1
3608 3608
    assert event.booking_set.count() == 1
3609
    assert second_event.booking_set.count() == 0
3609
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
3610 3610
    # bypass delays
3611 3611
    params = {'user_external_id': 'user_id', 'slots': '', 'bypass_delays': True}
3612 3612
    resp = app.post_json(fillslots_url, params=params)
3613 3613
    assert resp.json['booking_count'] == 0
3614 3614
    assert resp.json['cancelled_booking_count'] == 1
3615
    assert event.booking_set.count() == 0
3616
    assert second_event.booking_set.count() == 0
3615
    assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
3616
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
3617 3617
    booking.save()  # reset
3618 3618

  
3619 3619
    # book only second event while first event is out of delay with multiple agendas API
......
3628 3628
    resp = app.post_json('/api/agendas/events/fillslots/?agendas=foo-bar', params=params)
3629 3629
    assert resp.json['booking_count'] == 0
3630 3630
    assert resp.json['cancelled_booking_count'] == 1
3631
    assert event.booking_set.count() == 0
3632
    assert second_event.booking_set.count() == 1
3631
    assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
3632
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3633 3633
    booking.save()  # reset
3634 3634

  
3635 3635
    # book only first event while second event is out of delay
......
3638 3638
    resp = app.post_json(fillslots_url, params=params)
3639 3639
    assert resp.json['booking_count'] == 0
3640 3640
    assert resp.json['cancelled_booking_count'] == 0
3641
    assert event.booking_set.count() == 1
3642
    assert second_event.booking_set.count() == 1
3641
    assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3642
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3643 3643
    # bypass_delays has no effect on maximal_booking_delay
3644 3644
    params = {'user_external_id': 'user_id', 'slots': 'event', 'bypass_delays': True}
3645 3645
    resp = app.post_json(fillslots_url, params=params)
3646 3646
    assert resp.json['booking_count'] == 0
3647 3647
    assert resp.json['cancelled_booking_count'] == 0
3648
    assert event.booking_set.count() == 1
3649
    assert second_event.booking_set.count() == 1
3648
    assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3649
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3650 3650

  
3651 3651
    # cancel all bookings in delays
3652 3652
    params = {'user_external_id': 'user_id', 'slots': ''}
3653 3653
    resp = app.post_json(fillslots_url, params=params)
3654 3654
    assert resp.json['booking_count'] == 0
3655 3655
    assert resp.json['cancelled_booking_count'] == 1
3656
    assert event.booking_set.count() == 0
3657
    assert second_event.booking_set.count() == 1
3656
    assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
3657
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3658 3658

  
3659 3659
    # book only first event while second event is out of delay with multiple agendas API
3660 3660
    params = {'user_external_id': 'user_id', 'slots': 'foo-bar@event'}
3661 3661
    resp = app.post_json('/api/agendas/events/fillslots/?agendas=foo-bar', params=params)
3662 3662
    assert resp.json['booking_count'] == 1
3663 3663
    assert resp.json['cancelled_booking_count'] == 0
3664
    assert event.booking_set.count() == 1
3665
    assert second_event.booking_set.count() == 1
3664
    assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3665
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3666 3666
    # bypass_delays has no effect on maximal_booking_delay
3667 3667
    params = {'user_external_id': 'user_id', 'slots': 'foo-bar@event', 'bypass_delays': True}
3668 3668
    resp = app.post_json('/api/agendas/events/fillslots/?agendas=foo-bar', params=params)
3669 3669
    assert resp.json['booking_count'] == 0
3670 3670
    assert resp.json['cancelled_booking_count'] == 0
3671
    assert event.booking_set.count() == 1
3672
    assert second_event.booking_set.count() == 1
3671
    assert event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3672
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3673 3673

  
3674 3674

  
3675 3675
@pytest.mark.freeze_time('2021-09-06 12:00')
......
3703 3703
    assert len(resp.json['booked_events']) == 2
3704 3704
    assert resp.json['booked_events'][0]['id'] == 'first-agenda@event'
3705 3705
    assert resp.json['booked_events'][1]['id'] == 'second-agenda@event'
3706
    assert first_event.booking_set.count() == 1
3707
    assert second_event.booking_set.count() == 1
3706
    assert first_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3707
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3708 3708

  
3709 3709
    # booking modification
3710 3710
    params = {'user_external_id': 'user_id', 'slots': 'first-agenda@event'}
......
3712 3712
    assert resp.json['booking_count'] == 0
3713 3713
    assert len(resp.json['booked_events']) == 0
3714 3714
    assert resp.json['cancelled_booking_count'] == 1
3715
    assert first_event.booking_set.count() == 1
3716
    assert second_event.booking_set.count() == 0
3715
    assert first_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3716
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 0
3717 3717

  
3718 3718
    params = {'user_external_id': 'user_id_2', 'slots': event_slugs}
3719 3719
    resp = app.post_json('/api/agendas/events/fillslots/?agendas=%s' % agenda_slugs, params=params)
......
3721 3721
    assert len(resp.json['booked_events']) == 2
3722 3722
    assert resp.json['booked_events'][0]['id'] == 'first-agenda@event'
3723 3723
    assert resp.json['booked_events'][1]['id'] == 'second-agenda@event'
3724
    assert first_event.booking_set.count() == 2
3725
    assert second_event.booking_set.count() == 1
3724
    assert first_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 2
3725
    assert second_event.booking_set.filter(cancellation_datetime__isnull=True).count() == 1
3726 3726

  
3727 3727
    params = {'user_external_id': 'user_id_3', 'slots': event_slugs}
3728 3728
    resp = app.post_json('/api/agendas/events/fillslots/?agendas=%s' % agenda_slugs, params=params)
......
3771 3771
    assert resp.json['errors']['slots'] == ['Missing agenda slug in slot @event']
3772 3772

  
3773 3773

  
3774
@pytest.mark.freeze_time('2021-09-06 12:00')
3775
def test_api_events_fillslots_multiple_agendas_with_cancelled(app, user):
3776
    agenda_1 = Agenda.objects.create(label='Agenda 1', kind='events')
3777
    Desk.objects.create(agenda=agenda_1, slug='_exceptions_holder')
3778
    event_1 = Event.objects.create(
3779
        label='Event 1',
3780
        start_datetime=now() + datetime.timedelta(days=1),
3781
        places=2,
3782
        agenda=agenda_1,
3783
    )
3784
    agenda_2 = Agenda.objects.create(label='Agenda 2', kind='events')
3785
    Desk.objects.create(agenda=agenda_2, slug='_exceptions_holder')
3786
    event_2 = Event.objects.create(
3787
        label='Event 2',
3788
        start_datetime=now() + datetime.timedelta(days=2),
3789
        places=2,
3790
        agenda=agenda_2,
3791
    )
3792
    Event.objects.create(
3793
        label='Event 3',
3794
        start_datetime=now() + datetime.timedelta(days=3),
3795
        places=2,
3796
        agenda=agenda_2,
3797
    )
3798

  
3799
    # create cancelled booking for the user
3800
    booking_1 = Booking.objects.create(event=event_1, user_external_id='user_id')
3801
    booking_1.cancel()
3802
    assert booking_1.cancellation_datetime is not None
3803
    # and non cancelled booking for the user
3804
    booking_2 = Booking.objects.create(event=event_2, user_external_id='user_id')
3805
    assert booking_2.cancellation_datetime is None
3806
    # and bookings for another user
3807
    Booking.objects.create(event=event_1, user_external_id='user_id_foobar')
3808
    other_booking = Booking.objects.create(event=event_2, user_external_id='user_id_foobar')
3809
    other_booking.cancel()
3810

  
3811
    app.authorization = ('Basic', ('john.doe', 'password'))
3812
    fillslots_url = '/api/agendas/events/fillslots/?agendas=%s,%s' % (agenda_1.slug, agenda_2.slug)
3813

  
3814
    params = {'user_external_id': 'user_id', 'slots': 'agenda-1@event-1,agenda-2@event-2,agenda-2@event-3'}
3815
    resp = app.post_json(fillslots_url, params=params)
3816
    assert resp.json['booking_count'] == 2
3817
    assert len(resp.json['booked_events']) == 2
3818
    assert resp.json['cancelled_booking_count'] == 0
3819
    assert resp.json['booked_events'][0]['id'] == 'agenda-1@event-1'
3820
    assert resp.json['booked_events'][1]['id'] == 'agenda-2@event-3'
3821
    assert Booking.objects.filter(user_external_id='user_id').count() == 3
3822
    assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 3
3823

  
3824
    assert Booking.objects.filter(pk=booking_1.pk).exists() is False  # cancelled booking deleted
3825
    booking_2.refresh_from_db()
3826
    assert booking_2.cancellation_datetime is None
3827

  
3828
    params = {'user_external_id': 'user_id', 'slots': 'agenda-2@event-3'}
3829
    resp = app.post_json(fillslots_url, params=params)
3830
    assert resp.json['booking_count'] == 0
3831
    assert resp.json['cancelled_booking_count'] == 2
3832
    assert Booking.objects.filter(user_external_id='user_id').count() == 3
3833
    assert Booking.objects.filter(user_external_id='user_id', cancellation_datetime__isnull=True).count() == 1
3834

  
3835
    assert Booking.objects.filter(pk=booking_1.pk).exists() is False  # cancelled booking deleted
3836
    booking_2.refresh_from_db()
3837
    assert booking_2.cancellation_datetime is not None
3838

  
3839

  
3774 3840
def test_api_events_fillslots_multiple_agendas_check_delays(app, user):
3775 3841
    agenda = Agenda.objects.create(
3776 3842
        label='Foo bar', kind='events', minimal_booking_delay=0, maximal_booking_delay=7
......
3858 3924
    params = {'user_external_id': 'xxx', 'slots': 'first-agenda@event,second-agenda@event'}
3859 3925
    resp = app.post_json('/api/agendas/events/fillslots/?subscribed=category-a', params=params)
3860 3926
    assert resp.json['booking_count'] == 2
3861
    assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 1
3862
    assert Event.objects.get(agenda=second_agenda, slug='event').booking_set.count() == 1
3863
    assert Booking.objects.count() == 2
3927
    assert (
3928
        Event.objects.get(agenda=first_agenda, slug='event')
3929
        .booking_set.filter(cancellation_datetime__isnull=True)
3930
        .count()
3931
        == 1
3932
    )
3933
    assert (
3934
        Event.objects.get(agenda=second_agenda, slug='event')
3935
        .booking_set.filter(cancellation_datetime__isnull=True)
3936
        .count()
3937
        == 1
3938
    )
3939
    assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 2
3864 3940

  
3865 3941
    # update bookings for category-a
3866 3942
    params = {'user_external_id': 'xxx', 'slots': 'second-agenda@event'}
3867 3943
    resp = app.post_json('/api/agendas/events/fillslots/?subscribed=category-a', params=params)
3868 3944
    assert resp.json['booking_count'] == 0
3869 3945
    assert resp.json['cancelled_booking_count'] == 1
3870
    assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 0
3871
    assert Event.objects.get(agenda=second_agenda, slug='event').booking_set.count() == 1
3872
    assert Booking.objects.count() == 1
3946
    assert (
3947
        Event.objects.get(agenda=first_agenda, slug='event')
3948
        .booking_set.filter(cancellation_datetime__isnull=True)
3949
        .count()
3950
        == 0
3951
    )
3952
    assert (
3953
        Event.objects.get(agenda=second_agenda, slug='event')
3954
        .booking_set.filter(cancellation_datetime__isnull=True)
3955
        .count()
3956
        == 1
3957
    )
3958
    assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 1
3873 3959

  
3874 3960
    # try to book event from agenda with no subscription TODO messages
3875 3961
    params = {'user_external_id': 'xxx', 'slots': 'third-agenda@event'}
......
3890 3976
    params = {'user_external_id': 'xxx', 'slots': 'third-agenda@event'}
3891 3977
    resp = app.post_json('/api/agendas/events/fillslots/?subscribed=category-b', params=params)
3892 3978
    assert resp.json['booking_count'] == 1
3893
    assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 0
3894
    assert Event.objects.get(agenda=second_agenda, slug='event').booking_set.count() == 1
3895
    assert Event.objects.get(agenda=third_agenda, slug='event').booking_set.count() == 1
3896
    assert Booking.objects.count() == 2
3979
    assert (
3980
        Event.objects.get(agenda=first_agenda, slug='event')
3981
        .booking_set.filter(cancellation_datetime__isnull=True)
3982
        .count()
3983
        == 0
3984
    )
3985
    assert (
3986
        Event.objects.get(agenda=second_agenda, slug='event')
3987
        .booking_set.filter(cancellation_datetime__isnull=True)
3988
        .count()
3989
        == 1
3990
    )
3991
    assert (
3992
        Event.objects.get(agenda=third_agenda, slug='event')
3993
        .booking_set.filter(cancellation_datetime__isnull=True)
3994
        .count()
3995
        == 1
3996
    )
3997
    assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 2
3897 3998

  
3898 3999
    # add subscription to first agenda (disjoint) spanning event-2
3899 4000
    for agenda in (first_agenda, second_agenda):
......
3908 4009
    resp = app.post_json('/api/agendas/events/fillslots/?subscribed=all', params=params)
3909 4010
    assert resp.json['booking_count'] == 2
3910 4011
    assert resp.json['cancelled_booking_count'] == 2
3911
    assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 1
3912
    assert Event.objects.get(agenda=second_agenda, slug='event-2').booking_set.count() == 1
3913
    assert Booking.objects.count() == 2
4012
    assert (
4013
        Event.objects.get(agenda=first_agenda, slug='event')
4014
        .booking_set.filter(cancellation_datetime__isnull=True)
4015
        .count()
4016
        == 1
4017
    )
4018
    assert (
4019
        Event.objects.get(agenda=second_agenda, slug='event-2')
4020
        .booking_set.filter(cancellation_datetime__isnull=True)
4021
        .count()
4022
        == 1
4023
    )
4024
    assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 2
3914 4025

  
3915 4026
    # other user
3916 4027
    for agenda in (first_agenda, second_agenda):
......
3924 4035
    resp = app.post_json('/api/agendas/events/fillslots/?subscribed=all', params=params)
3925 4036
    assert resp.json['booking_count'] == 2
3926 4037
    assert resp.json['cancelled_booking_count'] == 0
3927
    assert Event.objects.get(agenda=first_agenda, slug='event').booking_set.count() == 2
3928
    assert Event.objects.get(agenda=second_agenda, slug='event-2').booking_set.count() == 2
3929
    assert Booking.objects.count() == 4
4038
    assert (
4039
        Event.objects.get(agenda=first_agenda, slug='event')
4040
        .booking_set.filter(cancellation_datetime__isnull=True)
4041
        .count()
4042
        == 2
4043
    )
4044
    assert (
4045
        Event.objects.get(agenda=second_agenda, slug='event-2')
4046
        .booking_set.filter(cancellation_datetime__isnull=True)
4047
        .count()
4048
        == 2
4049
    )
4050
    assert Booking.objects.filter(cancellation_datetime__isnull=True).count() == 4
3930 4051

  
3931 4052
    # try to book event outside subscription date range
3932 4053
    params = {'user_external_id': 'xxx', 'slots': 'third-agenda@event-2'}
3933
-