Projet

Général

Profil

0004-api-remove-user-bookings-on-subscription-date-change.patch

Lauréline Guérin, 10 février 2022 12:06

Télécharger (14,6 ko)

Voir les différences:

Subject: [PATCH 4/5] api: remove user bookings on subscription date changes
 (#61065)

 chrono/api/views.py            |  42 +++--
 tests/api/test_subscription.py | 303 +++++++++++++++++++++++++++++++++
 2 files changed, 333 insertions(+), 12 deletions(-)
chrono/api/views.py
1967 1967
        response.update({'err': 0})
1968 1968
        return Response(response)
1969 1969

  
1970
    def delete_out_of_period_bookings(self, date_start, date_end):
1971
        booking_qs = Booking.objects.filter(
1972
            # remove user bookings for this agenda
1973
            event__agenda=self.subscription.agenda,
1974
            user_external_id=self.subscription.user_external_id,
1975
            # in the requested period
1976
            event__start_datetime__gt=date_start,
1977
            event__start_datetime__lt=date_end + datetime.timedelta(days=1),
1978
        ).filter(
1979
            # but only in the future
1980
            event__start_datetime__gt=now(),
1981
        )
1982
        booking_qs.delete()
1983

  
1970 1984
    def patch(self, request, *args, **kwargs):
1971 1985
        serializer = self.serializer_class(self.subscription, data=request.data, partial=True)
1972 1986
        old_date_start = self.subscription.date_start
......
2006 2020
            self.subscription.extra_data.update(extra_data)
2007 2021
            self.subscription.save()
2008 2022

  
2023
        if old_date_start > self.subscription.date_end or old_date_end < self.subscription.date_start:
2024
            # new period does not overlaps the old one, delete all bookings in the old period
2025
            self.delete_out_of_period_bookings(old_date_start, old_date_end)
2026
        else:
2027
            if old_date_start < self.subscription.date_start:
2028
                # date start has been postponed, remove all bookings from old start to new start
2029
                self.delete_out_of_period_bookings(
2030
                    old_date_start, self.subscription.date_start - datetime.timedelta(days=1)
2031
                )
2032
            if old_date_end > self.subscription.date_end:
2033
                # date end has been brought forward, remove all bookings from new end to old end
2034
                self.delete_out_of_period_bookings(
2035
                    self.subscription.date_end + datetime.timedelta(days=1), old_date_end
2036
                )
2037

  
2009 2038
        return self.get(request, *args, **kwargs)
2010 2039

  
2011 2040
    def delete(self, request, *args, **kwargs):
2012
        booking_qs = Booking.objects.filter(
2013
            # remove user bookings for this agenda
2014
            event__agenda=self.subscription.agenda,
2015
            user_external_id=self.subscription.user_external_id,
2016
            # in the period of the deleted subscription
2017
            event__start_datetime__gt=self.subscription.date_start,
2018
            event__start_datetime__lt=self.subscription.date_end + datetime.timedelta(days=1),
2019
        ).filter(
2020
            # but only in the future
2021
            event__start_datetime__gt=now(),
2022
        )
2023
        booking_qs.delete()
2041
        self.delete_out_of_period_bookings(self.subscription.date_start, self.subscription.date_end)
2024 2042
        self.subscription.delete()
2025 2043
        response = {'err': 0}
2026 2044
        return Response(response)
tests/api/test_subscription.py
729 729
        '/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
730 730
    )
731 731
    assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
732

  
733

  
734
@pytest.mark.parametrize(
735
    'date_now, event_date, user_id, in_waiting_list, cancelled, deleted',
736
    [
737
        # event in the future, but no booking for the user
738
        ('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'yyy', False, False, False),
739
        # event in the future
740
        ('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'xxx', False, False, True),
741
        ('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'xxx', True, False, True),
742
        ('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'xxx', False, True, True),
743
        # event in the past
744
        ('2021-09-04 10:00', (2021, 9, 4, 12, 0), 'xxx', False, False, False),
745
        # event in the future, before the period
746
        ('2021-08-01 10:00', (2021, 8, 14, 12, 0), 'xxx', False, False, False),
747
        ('2021-08-01 10:00', (2021, 8, 31, 12, 0), 'xxx', False, False, False),
748
        # event in the future, after the period
749
        ('2021-08-01 10:00', (2021, 10, 1, 12, 0), 'xxx', False, False, False),
750
        ('2021-08-01 10:00', (2021, 10, 16, 12, 0), 'xxx', False, False, False),
751
    ],
752
)
753
def test_api_patch_subscription_date_changes_delete_bookings(
754
    app, user, freezer, date_now, event_date, user_id, in_waiting_list, cancelled, deleted
755
):
756
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
757
    subscription = Subscription.objects.create(
758
        agenda=agenda,
759
        user_external_id='xxx',
760
        date_start=datetime.date(year=2021, month=9, day=1),
761
        date_end=datetime.date(year=2021, month=9, day=30),
762
    )
763
    Subscription.objects.create(
764
        agenda=agenda,
765
        user_external_id='zzz',  # another user
766
        date_start=datetime.date(year=2021, month=9, day=1),
767
        date_end=datetime.date(year=2021, month=9, day=30),
768
    )
769

  
770
    other_agenda = Agenda.objects.create(label='Foo bar', kind='events')
771
    Subscription.objects.create(
772
        agenda=other_agenda,
773
        user_external_id='xxx',
774
        date_start=datetime.date(year=2021, month=9, day=1),
775
        date_end=datetime.date(year=2021, month=10, day=1),
776
    )
777

  
778
    app.authorization = ('Basic', ('john.doe', 'password'))
779

  
780
    freezer.move_to(date_now)
781
    event = Event.objects.create(
782
        agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
783
    )
784
    booking = Booking.objects.create(
785
        event=event,
786
        user_external_id=user_id,
787
        in_waiting_list=in_waiting_list,
788
        cancellation_datetime=(now() if cancelled else None),
789
    )
790

  
791
    # date_start is postponed, date_end is brought forward
792
    params = {
793
        'date_start': '2021-09-05',
794
        'date_end': '2021-09-25',
795
    }
796
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
797
    assert resp.json['err'] == 0
798
    assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
799

  
800

  
801
@pytest.mark.parametrize(
802
    'event_date, deleted',
803
    [
804
        # just before old first day
805
        ((2021, 8, 31, 12, 00), False),
806
        # old first day
807
        ((2021, 9, 1, 12, 00), True),
808
        # old last day
809
        ((2021, 9, 30, 12, 00), True),
810
        # just after old last day
811
        ((2021, 10, 1, 12, 00), False),
812
    ],
813
)
814
def test_api_patch_subscription_date_changes_delete_bookings_forwards_no_overlaps(
815
    app, user, freezer, event_date, deleted
816
):
817
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
818
    subscription = Subscription.objects.create(
819
        agenda=agenda,
820
        user_external_id='xxx',
821
        date_start=datetime.date(year=2021, month=9, day=1),
822
        date_end=datetime.date(year=2021, month=9, day=30),
823
    )
824

  
825
    app.authorization = ('Basic', ('john.doe', 'password'))
826

  
827
    freezer.move_to('2021-08-01 10:00')
828
    event = Event.objects.create(
829
        agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
830
    )
831
    booking = Booking.objects.create(
832
        event=event,
833
        user_external_id='xxx',
834
    )
835
    # subscription moved forwards, no overlaps
836
    params = {
837
        'date_start': '2021-11-01',
838
        'date_end': '2021-11-30',
839
    }
840
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
841
    assert resp.json['err'] == 0
842
    assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
843

  
844

  
845
@pytest.mark.parametrize(
846
    'event_date, deleted',
847
    [
848
        # just before old first day
849
        ((2021, 8, 31, 12, 00), False),
850
        # old first day
851
        ((2021, 9, 1, 12, 00), True),
852
        # old last day
853
        ((2021, 9, 30, 12, 00), True),
854
        # just after old last day
855
        ((2021, 10, 1, 12, 00), False),
856
    ],
857
)
858
def test_api_patch_subscription_date_changes_delete_bookings_backwards_no_overlaps(
859
    app, user, freezer, event_date, deleted
860
):
861
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
862
    subscription = Subscription.objects.create(
863
        agenda=agenda,
864
        user_external_id='xxx',
865
        date_start=datetime.date(year=2021, month=9, day=1),
866
        date_end=datetime.date(year=2021, month=9, day=30),
867
    )
868

  
869
    app.authorization = ('Basic', ('john.doe', 'password'))
870

  
871
    freezer.move_to('2021-06-01 10:00')
872
    event = Event.objects.create(
873
        agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
874
    )
875
    booking = Booking.objects.create(
876
        event=event,
877
        user_external_id='xxx',
878
    )
879
    # subscription moved backwards, no overlaps
880
    params = {
881
        'date_start': '2021-07-01',
882
        'date_end': '2021-07-31',
883
    }
884
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
885
    assert resp.json['err'] == 0
886
    assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
887

  
888

  
889
@pytest.mark.parametrize(
890
    'event_date, deleted',
891
    [
892
        # just before old first day
893
        ((2021, 8, 31, 12, 00), False),
894
        # old first day
895
        ((2021, 9, 1, 12, 00), True),
896
        # just before new first day
897
        ((2021, 9, 4, 12, 00), True),
898
        # new first day
899
        ((2021, 9, 5, 12, 00), False),
900
        # new last day
901
        ((2021, 9, 25, 12, 00), False),
902
        # just after new last day
903
        ((2021, 9, 26, 12, 00), True),
904
        # old last day
905
        ((2021, 9, 30, 12, 00), True),
906
        # just after old last day
907
        ((2021, 10, 1, 12, 00), False),
908
    ],
909
)
910
def test_api_patch_subscription_date_changes_delete_bookings_shorter_period(
911
    app, user, freezer, event_date, deleted
912
):
913
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
914
    subscription = Subscription.objects.create(
915
        agenda=agenda,
916
        user_external_id='xxx',
917
        date_start=datetime.date(year=2021, month=9, day=1),
918
        date_end=datetime.date(year=2021, month=9, day=30),
919
    )
920

  
921
    app.authorization = ('Basic', ('john.doe', 'password'))
922

  
923
    freezer.move_to('2021-08-01 10:00')
924
    event = Event.objects.create(
925
        agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
926
    )
927
    booking = Booking.objects.create(
928
        event=event,
929
        user_external_id='xxx',
930
    )
931
    # date_start is postponed, date_end is brought forward
932
    params = {
933
        'date_start': '2021-09-05',
934
        'date_end': '2021-09-25',
935
    }
936
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
937
    assert resp.json['err'] == 0
938
    assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
939

  
940

  
941
@pytest.mark.parametrize(
942
    'event_date, deleted',
943
    [
944
        # just before old first day
945
        ((2021, 8, 31, 12, 00), False),
946
        # old first day
947
        ((2021, 9, 1, 12, 00), True),
948
        # just before new first day
949
        ((2021, 9, 14, 12, 00), True),
950
        # new first day
951
        ((2021, 9, 15, 12, 00), False),
952
        # old last day
953
        ((2021, 9, 30, 12, 00), False),
954
        # just after old last day
955
        ((2021, 10, 1, 12, 00), False),
956
    ],
957
)
958
def test_api_patch_subscription_date_changes_delete_bookings_forwards_with_overlaps(
959
    app, user, freezer, event_date, deleted
960
):
961
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
962
    subscription = Subscription.objects.create(
963
        agenda=agenda,
964
        user_external_id='xxx',
965
        date_start=datetime.date(year=2021, month=9, day=1),
966
        date_end=datetime.date(year=2021, month=9, day=30),
967
    )
968

  
969
    app.authorization = ('Basic', ('john.doe', 'password'))
970

  
971
    freezer.move_to('2021-08-01 10:00')
972
    event = Event.objects.create(
973
        agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
974
    )
975
    booking = Booking.objects.create(
976
        event=event,
977
        user_external_id='xxx',
978
    )
979
    # subscription moved forwards, with overlaps
980
    params = {
981
        'date_start': '2021-09-15',
982
        'date_end': '2021-10-15',
983
    }
984
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
985
    assert resp.json['err'] == 0
986
    assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
987

  
988

  
989
@pytest.mark.parametrize(
990
    'event_date, deleted',
991
    [
992
        # just before old first day
993
        ((2021, 8, 31, 12, 00), False),
994
        # old first day
995
        ((2021, 9, 1, 12, 00), False),
996
        # new last day
997
        ((2021, 9, 15, 12, 00), False),
998
        # just after new last day
999
        ((2021, 9, 16, 12, 00), True),
1000
        # old last day
1001
        ((2021, 9, 30, 12, 00), True),
1002
        # just after old last day
1003
        ((2021, 10, 1, 12, 00), False),
1004
    ],
1005
)
1006
def test_api_patch_subscription_date_changes_delete_bookings_backwards_with_overlaps(
1007
    app, user, freezer, event_date, deleted
1008
):
1009
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
1010
    subscription = Subscription.objects.create(
1011
        agenda=agenda,
1012
        user_external_id='xxx',
1013
        date_start=datetime.date(year=2021, month=9, day=1),
1014
        date_end=datetime.date(year=2021, month=9, day=30),
1015
    )
1016

  
1017
    app.authorization = ('Basic', ('john.doe', 'password'))
1018

  
1019
    freezer.move_to('2021-08-01 10:00')
1020
    event = Event.objects.create(
1021
        agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
1022
    )
1023
    booking = Booking.objects.create(
1024
        event=event,
1025
        user_external_id='xxx',
1026
    )
1027
    # subscription moved backwards, with overlaps
1028
    params = {
1029
        'date_start': '2021-08-15',
1030
        'date_end': '2021-09-15',
1031
    }
1032
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
1033
    assert resp.json['err'] == 0
1034
    assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
732
-