Projet

Général

Profil

0003-api-update-user-bookings-extra_data-on-subscription-.patch

Lauréline Guérin, 03 février 2022 16:55

Télécharger (6,65 ko)

Voir les différences:

Subject: [PATCH 3/3] api: update user bookings extra_data on subscription
 update (#61065)

 chrono/api/views.py            | 27 +++++++++---
 tests/api/test_subscription.py | 80 ++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+), 5 deletions(-)
chrono/api/views.py
18 18
import copy
19 19
import datetime
20 20
import itertools
21
import json
21 22
import uuid
22 23

  
23 24
from django.conf import settings
24 25
from django.db import transaction
25 26
from django.db.models import BooleanField, Count, ExpressionWrapper, F, Prefetch, Q
27
from django.db.models.expressions import RawSQL
26 28
from django.db.models.functions import TruncDay
27 29
from django.http import Http404, HttpResponse
28 30
from django.shortcuts import get_object_or_404
......
1986 1988
            raise APIErrorBadRequest(N_('invalid payload'), errors=serializer.errors, err=4)
1987 1989

  
1988 1990
        serializer.save()
1989
        extra_data = {k: v for k, v in request.data.items() if k not in serializer.validated_data}
1990
        if extra_data:
1991
            self.subscription.extra_data = self.subscription.extra_data or {}
1992
            self.subscription.extra_data.update(extra_data)
1993
            self.subscription.save()
1994 1991

  
1995 1992
        if old_date_start > self.subscription.date_end or old_date_end < self.subscription.date_start:
1996 1993
            # new period does not overlaps the old one, delete all bookings in the old period
......
2007 2004
                    self.subscription.date_end + datetime.timedelta(days=1), old_date_end
2008 2005
                )
2009 2006

  
2007
        extra_data = {k: v for k, v in request.data.items() if k not in serializer.validated_data}
2008
        if extra_data:
2009
            self.subscription.extra_data = self.subscription.extra_data or {}
2010
            self.subscription.extra_data.update(extra_data)
2011
            self.subscription.save()
2012
            # update bookings inside the new period (other bookings were deleted)
2013
            Booking.objects.filter(
2014
                # remove user bookings for this agenda
2015
                event__agenda=self.subscription.agenda,
2016
                user_external_id=self.subscription.user_external_id,
2017
                # in the period of the deleted subscription
2018
                event__start_datetime__gt=self.subscription.date_start,
2019
                event__start_datetime__lt=self.subscription.date_end + datetime.timedelta(days=1),
2020
            ).filter(
2021
                # but only in the future
2022
                event__start_datetime__gt=now(),
2023
            ).update(
2024
                extra_data=RawSQL("COALESCE(extra_data, '{}'::jsonb) || %s::jsonb", (json.dumps(extra_data),))
2025
            )
2026

  
2010 2027
        return self.get(request, *args, **kwargs)
2011 2028

  
2012 2029
    def delete(self, request, *args, **kwargs):
tests/api/test_subscription.py
870 870
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
871 871
    assert resp.json['err'] == 0
872 872
    assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
873

  
874

  
875
@pytest.mark.parametrize(
876
    'date_now, event_date, user_id, in_waiting_list, cancelled, updated',
877
    [
878
        # event in the future, but no booking for the user
879
        ('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'yyy', False, False, False),
880
        # event in the future
881
        ('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', False, False, True),
882
        ('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', True, False, True),
883
        ('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', False, True, True),
884
        # event in the past
885
        ('2021-09-01 10:00', (2021, 9, 1, 12, 0), 'xxx', False, False, False),
886
        # event in the future
887
        ('2021-08-01 10:00', (2021, 9, 1, 12, 0), 'xxx', False, False, True),
888
        ('2021-08-01 10:00', (2021, 9, 30, 12, 0), 'xxx', False, False, True),
889
        # event in the future, before the period
890
        ('2021-08-01 10:00', (2021, 8, 31, 12, 0), 'xxx', False, False, False),
891
        # event in the future, after the period
892
        ('2021-08-01 10:00', (2021, 10, 1, 12, 0), 'xxx', False, False, False),
893
    ],
894
)
895
def test_api_patch_subscription_update_bookings_extra_data(
896
    app, user, freezer, date_now, event_date, user_id, in_waiting_list, cancelled, updated
897
):
898
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
899
    subscription = Subscription.objects.create(
900
        agenda=agenda,
901
        user_external_id='xxx',
902
        date_start=datetime.date(year=2021, month=9, day=1),
903
        date_end=datetime.date(year=2021, month=9, day=30),
904
    )
905

  
906
    app.authorization = ('Basic', ('john.doe', 'password'))
907

  
908
    freezer.move_to(date_now)
909
    event = Event.objects.create(
910
        agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
911
    )
912
    booking = Booking.objects.create(
913
        event=event,
914
        user_external_id=user_id,
915
        in_waiting_list=in_waiting_list,
916
        cancellation_datetime=(now() if cancelled else None),
917
    )
918

  
919
    # extra_data is None
920
    params = {
921
        'foo': 'bar',
922
    }
923
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
924
    assert resp.json['err'] == 0
925
    booking.refresh_from_db()
926
    if updated:
927
        assert booking.extra_data == {'foo': 'bar'}
928
    else:
929
        assert booking.extra_data is None
930
    booking.extra_data = {'some': 'thing'}
931
    booking.save()
932

  
933
    # extra_data is not None, update
934
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
935
    assert resp.json['err'] == 0
936
    booking.refresh_from_db()
937
    if updated:
938
        assert booking.extra_data == {'foo': 'bar', 'some': 'thing'}
939
    else:
940
        assert booking.extra_data == {'some': 'thing'}
941

  
942
    # extra_data is not None, merge
943
    params = {
944
        'foo': 'bar2',
945
    }
946
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
947
    assert resp.json['err'] == 0
948
    booking.refresh_from_db()
949
    if updated:
950
        assert booking.extra_data == {'foo': 'bar2', 'some': 'thing'}
951
    else:
952
        assert booking.extra_data == {'some': 'thing'}
873
-