Projet

Général

Profil

0004-api-list-subscriptions-endpoint-61079.patch

Lauréline Guérin, 27 janvier 2022 16:43

Télécharger (9,17 ko)

Voir les différences:

Subject: [PATCH 4/4] api: list subscriptions endpoint (#61079)

 chrono/api/serializers.py      |   3 +
 chrono/api/views.py            |  38 +++++++++-
 tests/api/test_subscription.py | 127 +++++++++++++++++++++++++++++++++
 3 files changed, 165 insertions(+), 3 deletions(-)
chrono/api/serializers.py
335 335
    class Meta:
336 336
        model = Subscription
337 337
        fields = [
338
            'id',
338 339
            'user_external_id',
339 340
            'user_first_name',
340 341
            'user_last_name',
......
342 343
            'user_phone_number',
343 344
            'date_start',
344 345
            'date_end',
346
            'extra_data',
345 347
        ]
348
        read_only_fields = ['id', 'extra_data']
346 349

  
347 350
    def validate(self, attrs):
348 351
        super().validate(attrs)
chrono/api/views.py
1880 1880
agendas_events_fillslots = MultipleAgendasEventsFillslots.as_view()
1881 1881

  
1882 1882

  
1883
class SubscriptionAPI(APIView):
1883
class SubscriptionFilter(filters.FilterSet):
1884
    date_start = filters.DateFilter(lookup_expr='gte')
1885
    date_end = filters.DateFilter(lookup_expr='lte')
1886

  
1887
    class Meta:
1888
        model = Subscription
1889
        fields = [
1890
            'user_external_id',
1891
            'date_start',
1892
            'date_end',
1893
        ]
1894

  
1895

  
1896
class SubscriptionAPI(ListAPIView):
1897
    filter_backends = (filters.DjangoFilterBackend,)
1884 1898
    serializer_class = serializers.SubscriptionSerializer
1899
    filterset_class = SubscriptionFilter
1885 1900
    permission_classes = (permissions.IsAuthenticated,)
1886 1901

  
1902
    def get_agenda(self, agenda_identifier):
1903
        return get_object_or_404(Agenda, slug=agenda_identifier, kind='events')
1904

  
1905
    def get(self, request, agenda_identifier):
1906
        self.agenda = self.get_agenda(agenda_identifier)
1907

  
1908
        try:
1909
            subscriptions = self.filter_queryset(self.get_queryset())
1910
        except ValidationError as e:
1911
            raise APIErrorBadRequest(N_('invalid filters'), errors=e.detail)
1912

  
1913
        serializer = self.serializer_class(subscriptions, many=True)
1914
        return Response({'err': 0, 'data': serializer.data})
1915

  
1916
    def get_queryset(self):
1917
        return self.agenda.subscriptions.order_by('date_start', 'date_end', 'user_external_id', 'pk')
1918

  
1887 1919
    def post(self, request, agenda_identifier):
1888
        agenda = get_object_or_404(Agenda, slug=agenda_identifier, kind='events')
1920
        self.agenda = self.get_agenda(agenda_identifier)
1889 1921

  
1890 1922
        serializer = self.serializer_class(data=request.data)
1891 1923
        if not serializer.is_valid():
......
1893 1925
        extra_data = {k: v for k, v in request.data.items() if k not in serializer.validated_data}
1894 1926

  
1895 1927
        subscription = Subscription.objects.create(
1896
            agenda=agenda, extra_data=extra_data, **serializer.validated_data
1928
            agenda=self.agenda, extra_data=extra_data, **serializer.validated_data
1897 1929
        )
1898 1930
        return Response({'err': 0, 'id': subscription.pk})
1899 1931

  
tests/api/test_subscription.py
7 7
pytestmark = pytest.mark.django_db
8 8

  
9 9

  
10
def test_api_list_subscription(app, user):
11
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
12
    subscription = Subscription.objects.create(
13
        agenda=agenda,
14
        user_external_id='xxx',
15
        user_first_name='Foo',
16
        user_last_name='BAR',
17
        user_email='foo@bar.com',
18
        user_phone_number='06',
19
        extra_data={'foo': 'bar'},
20
        date_start=datetime.date(year=2021, month=9, day=1),
21
        date_end=datetime.date(year=2021, month=10, day=1),
22
    )
23

  
24
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, status=401)
25

  
26
    app.authorization = ('Basic', ('john.doe', 'password'))
27

  
28
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug)
29
    assert len(resp.json['data']) == 1
30
    assert resp.json['data'][0] == {
31
        'id': subscription.pk,
32
        'user_external_id': 'xxx',
33
        'user_first_name': 'Foo',
34
        'user_last_name': 'BAR',
35
        'user_email': 'foo@bar.com',
36
        'user_phone_number': '06',
37
        'date_start': '2021-09-01',
38
        'date_end': '2021-10-01',
39
        'extra_data': {
40
            'foo': 'bar',
41
        },
42
    }
43

  
44

  
45
def test_api_list_subscription_filter_user_external_id(app, user):
46
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
47
    subscription1 = Subscription.objects.create(
48
        agenda=agenda,
49
        user_external_id='xxx',
50
        date_start=datetime.date(year=2021, month=9, day=1),
51
        date_end=datetime.date(year=2021, month=10, day=1),
52
    )
53
    subscription2 = Subscription.objects.create(
54
        agenda=agenda,
55
        user_external_id='yyy',
56
        date_start=datetime.date(year=2021, month=9, day=1),
57
        date_end=datetime.date(year=2021, month=10, day=1),
58
    )
59
    other_agenda = Agenda.objects.create(label='Foo bar 2', kind='events')
60
    Subscription.objects.create(
61
        agenda=other_agenda,
62
        user_external_id='xxx',
63
        date_start=datetime.date(year=2000, month=1, day=1),
64
        date_end=datetime.date(year=2099, month=12, day=31),
65
    )
66

  
67
    app.authorization = ('Basic', ('john.doe', 'password'))
68

  
69
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'user_external_id': 'xxx'})
70
    assert [d['id'] for d in resp.json['data']] == [subscription1.pk]
71
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'user_external_id': 'yyy'})
72
    assert [d['id'] for d in resp.json['data']] == [subscription2.pk]
73
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'user_external_id': 'zzz'})
74
    assert [d['id'] for d in resp.json['data']] == []
75

  
76

  
77
def test_api_list_subscription_filter_date_start(app, user):
78
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
79
    subscription1 = Subscription.objects.create(
80
        agenda=agenda,
81
        user_external_id='xxx',
82
        date_start=datetime.date(year=2021, month=9, day=1),
83
        date_end=datetime.date(year=2021, month=10, day=1),
84
    )
85
    subscription2 = Subscription.objects.create(
86
        agenda=agenda,
87
        user_external_id='xxx',
88
        date_start=datetime.date(year=2022, month=9, day=1),
89
        date_end=datetime.date(year=2022, month=10, day=1),
90
    )
91

  
92
    app.authorization = ('Basic', ('john.doe', 'password'))
93

  
94
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'date_start': '2021-08-31'})
95
    assert [d['id'] for d in resp.json['data']] == [subscription1.pk, subscription2.pk]
96
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'date_start': '2021-09-02'})
97
    assert [d['id'] for d in resp.json['data']] == [subscription2.pk]
98
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'date_start': '2022-09-02'})
99
    assert [d['id'] for d in resp.json['data']] == []
100

  
101
    resp = app.get(
102
        '/api/agenda/%s/subscription/' % agenda.slug, params={'date_start': 'wrong-format'}, status=400
103
    )
104
    assert resp.json['err_class'] == 'invalid filters'
105

  
106

  
107
def test_api_list_subscription_filter_date_end(app, user):
108
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
109
    subscription1 = Subscription.objects.create(
110
        agenda=agenda,
111
        user_external_id='xxx',
112
        date_start=datetime.date(year=2021, month=9, day=1),
113
        date_end=datetime.date(year=2021, month=10, day=1),
114
    )
115
    subscription2 = Subscription.objects.create(
116
        agenda=agenda,
117
        user_external_id='xxx',
118
        date_start=datetime.date(year=2022, month=9, day=1),
119
        date_end=datetime.date(year=2022, month=10, day=1),
120
    )
121

  
122
    app.authorization = ('Basic', ('john.doe', 'password'))
123

  
124
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'date_end': '2022-10-02'})
125
    assert [d['id'] for d in resp.json['data']] == [subscription1.pk, subscription2.pk]
126
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'date_end': '2021-10-02'})
127
    assert [d['id'] for d in resp.json['data']] == [subscription1.pk]
128
    resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'date_end': '2021-09-30'})
129
    assert [d['id'] for d in resp.json['data']] == []
130

  
131
    resp = app.get(
132
        '/api/agenda/%s/subscription/' % agenda.slug, params={'date_end': 'wrong-format'}, status=400
133
    )
134
    assert resp.json['err_class'] == 'invalid filters'
135

  
136

  
10 137
def test_api_create_subscription(app, user):
11 138
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
12 139

  
13
-