Projet

Général

Profil

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

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

Télécharger (6,65 ko)

Voir les différences:

Subject: [PATCH 5/5] 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
......
2014 2016
            raise APIErrorBadRequest(N_('it is not possible to change user_external_id value'))
2015 2017

  
2016 2018
        serializer.save()
2017
        extra_data = {k: v for k, v in request.data.items() if k not in serializer.validated_data}
2018
        if extra_data:
2019
            self.subscription.extra_data = self.subscription.extra_data or {}
2020
            self.subscription.extra_data.update(extra_data)
2021
            self.subscription.save()
2022 2019

  
2023 2020
        if old_date_start > self.subscription.date_end or old_date_end < self.subscription.date_start:
2024 2021
            # new period does not overlaps the old one, delete all bookings in the old period
......
2035 2032
                    self.subscription.date_end + datetime.timedelta(days=1), old_date_end
2036 2033
                )
2037 2034

  
2035
        extra_data = {k: v for k, v in request.data.items() if k not in serializer.validated_data}
2036
        if extra_data:
2037
            self.subscription.extra_data = self.subscription.extra_data or {}
2038
            self.subscription.extra_data.update(extra_data)
2039
            self.subscription.save()
2040
            # update bookings inside the new period (other bookings were deleted)
2041
            Booking.objects.filter(
2042
                # remove user bookings for this agenda
2043
                event__agenda=self.subscription.agenda,
2044
                user_external_id=self.subscription.user_external_id,
2045
                # in the period of the subscription
2046
                event__start_datetime__gt=self.subscription.date_start,
2047
                event__start_datetime__lt=self.subscription.date_end + datetime.timedelta(days=1),
2048
            ).filter(
2049
                # but only in the future
2050
                event__start_datetime__gt=now(),
2051
            ).update(
2052
                extra_data=RawSQL("COALESCE(extra_data, '{}'::jsonb) || %s::jsonb", (json.dumps(extra_data),))
2053
            )
2054

  
2038 2055
        return self.get(request, *args, **kwargs)
2039 2056

  
2040 2057
    def delete(self, request, *args, **kwargs):
tests/api/test_subscription.py
1032 1032
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
1033 1033
    assert resp.json['err'] == 0
1034 1034
    assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
1035

  
1036

  
1037
@pytest.mark.parametrize(
1038
    'date_now, event_date, user_id, in_waiting_list, cancelled, updated',
1039
    [
1040
        # event in the future, but no booking for the user
1041
        ('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'yyy', False, False, False),
1042
        # event in the future
1043
        ('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', False, False, True),
1044
        ('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', True, False, True),
1045
        ('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', False, True, True),
1046
        # event in the past
1047
        ('2021-09-01 10:00', (2021, 9, 1, 12, 0), 'xxx', False, False, False),
1048
        # event in the future
1049
        ('2021-08-01 10:00', (2021, 9, 1, 12, 0), 'xxx', False, False, True),
1050
        ('2021-08-01 10:00', (2021, 9, 30, 12, 0), 'xxx', False, False, True),
1051
        # event in the future, before the period
1052
        ('2021-08-01 10:00', (2021, 8, 31, 12, 0), 'xxx', False, False, False),
1053
        # event in the future, after the period
1054
        ('2021-08-01 10:00', (2021, 10, 1, 12, 0), 'xxx', False, False, False),
1055
    ],
1056
)
1057
def test_api_patch_subscription_update_bookings_extra_data(
1058
    app, user, freezer, date_now, event_date, user_id, in_waiting_list, cancelled, updated
1059
):
1060
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
1061
    subscription = Subscription.objects.create(
1062
        agenda=agenda,
1063
        user_external_id='xxx',
1064
        date_start=datetime.date(year=2021, month=9, day=1),
1065
        date_end=datetime.date(year=2021, month=9, day=30),
1066
    )
1067

  
1068
    app.authorization = ('Basic', ('john.doe', 'password'))
1069

  
1070
    freezer.move_to(date_now)
1071
    event = Event.objects.create(
1072
        agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
1073
    )
1074
    booking = Booking.objects.create(
1075
        event=event,
1076
        user_external_id=user_id,
1077
        in_waiting_list=in_waiting_list,
1078
        cancellation_datetime=(now() if cancelled else None),
1079
    )
1080

  
1081
    # extra_data is None
1082
    params = {
1083
        'foo': 'bar',
1084
    }
1085
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
1086
    assert resp.json['err'] == 0
1087
    booking.refresh_from_db()
1088
    if updated:
1089
        assert booking.extra_data == {'foo': 'bar'}
1090
    else:
1091
        assert booking.extra_data is None
1092
    booking.extra_data = {'some': 'thing'}
1093
    booking.save()
1094

  
1095
    # extra_data is not None, update
1096
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
1097
    assert resp.json['err'] == 0
1098
    booking.refresh_from_db()
1099
    if updated:
1100
        assert booking.extra_data == {'foo': 'bar', 'some': 'thing'}
1101
    else:
1102
        assert booking.extra_data == {'some': 'thing'}
1103

  
1104
    # extra_data is not None, merge
1105
    params = {
1106
        'foo': 'bar2',
1107
    }
1108
    resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
1109
    assert resp.json['err'] == 0
1110
    booking.refresh_from_db()
1111
    if updated:
1112
        assert booking.extra_data == {'foo': 'bar2', 'some': 'thing'}
1113
    else:
1114
        assert booking.extra_data == {'some': 'thing'}
1035
-