Projet

Général

Profil

0003-api-filter-by-subscriptions-in-recurring-events-list.patch

Valentin Deniaud, 02 décembre 2021 15:28

Télécharger (5,67 ko)

Voir les différences:

Subject: [PATCH 3/4] api: filter by subscriptions in recurring events list
 (#58446)

 chrono/api/serializers.py   |  1 +
 chrono/api/views.py         | 15 +++++---
 tests/api/test_datetimes.py | 68 +++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+), 5 deletions(-)
chrono/api/serializers.py
205 205
    subscribed = CommaSeparatedStringField(
206 206
        required=False, child=serializers.SlugField(max_length=160, allow_blank=False)
207 207
    )
208
    user_external_id = serializers.CharField(required=False, max_length=250, allow_blank=False)
208 209

  
209 210
    def validate(self, attrs):
210 211
        super().validate(attrs)
chrono/api/views.py
1060 1060
        if not settings.ENABLE_RECURRING_EVENT_BOOKING:
1061 1061
            raise Http404()
1062 1062

  
1063
        agenda_slugs = get_agendas_from_request(request)
1064
        agendas = get_objects_from_slugs(agenda_slugs, qs=Agenda.objects.filter(kind='events'))
1065
        agendas = Agenda.prefetch_recurring_events(agendas)
1063
        serializer = serializers.AgendaOrSubscribedSlugsSerializer(data=request.query_params)
1064
        if not serializer.is_valid():
1065
            raise APIErrorBadRequest(N_('invalid payload'), errors=serializer.errors)
1066
        data = serializer.validated_data
1066 1067

  
1068
        agendas = Agenda.prefetch_recurring_events(data['agendas'])
1067 1069
        events = []
1068 1070
        for agenda in agendas:
1069 1071
            for event in agenda.get_open_recurring_events():
......
1072 1074
                    event.day = day
1073 1075
                    events.append(event)
1074 1076

  
1075
        agenda_querystring_indexes = {agenda_slug: i for i, agenda_slug in enumerate(agenda_slugs)}
1076
        events.sort(key=lambda event: (event.day, agenda_querystring_indexes[event.agenda.slug]))
1077
        if 'agendas' in request.query_params:
1078
            agenda_querystring_indexes = {
1079
                agenda_slug: i for i, agenda_slug in enumerate(data['agenda_slugs'])
1080
            }
1081
            events.sort(key=lambda event: (event.day, agenda_querystring_indexes[event.agenda.slug]))
1077 1082

  
1078 1083
        return Response(
1079 1084
            {
tests/api/test_datetimes.py
1461 1461
        assert len(ctx.captured_queries) == 3
1462 1462

  
1463 1463

  
1464
@pytest.mark.freeze_time('2021-09-06 12:00')
1465
def test_recurring_events_api_list_subscribed(app, user):
1466
    category = Category.objects.create(label='Category A')
1467
    first_agenda = Agenda.objects.create(label='First agenda', kind='events', category=category)
1468
    category = Category.objects.create(label='Category B')
1469
    second_agenda = Agenda.objects.create(label='Second agenda', kind='events', category=category)
1470
    Event.objects.create(
1471
        slug='event',
1472
        start_datetime=now(),
1473
        recurrence_days=[0, 1, 3, 4],  # Monday, Tuesday, Thursday, Friday
1474
        places=2,
1475
        waiting_list_places=1,
1476
        agenda=first_agenda,
1477
        recurrence_end_date=now() + datetime.timedelta(days=364),
1478
    )
1479
    Event.objects.create(
1480
        slug='sunday-event',
1481
        start_datetime=now(),
1482
        recurrence_days=[6],
1483
        places=2,
1484
        waiting_list_places=1,
1485
        agenda=second_agenda,
1486
        recurrence_end_date=now() + datetime.timedelta(days=364),
1487
    )
1488

  
1489
    Subscription.objects.create(
1490
        agenda=first_agenda,
1491
        user_external_id='xxx',
1492
        date_start=now(),
1493
        date_end=now() + datetime.timedelta(days=30),
1494
    )
1495
    resp = app.get('/api/agendas/recurring-events/?user_external_id=xxx&subscribed=all')
1496
    assert len(resp.json['data']) == 4
1497
    assert all(event['id'].startswith('first-agenda') for event in resp.json['data'])
1498

  
1499
    resp = app.get('/api/agendas/recurring-events/?user_external_id=xxx&subscribed=category-a')
1500
    assert len(resp.json['data']) == 4
1501
    assert all(event['id'].startswith('first-agenda') for event in resp.json['data'])
1502

  
1503
    resp = app.get('/api/agendas/recurring-events/?user_external_id=xxx&subscribed=category-b')
1504
    assert len(resp.json['data']) == 0
1505

  
1506
    Subscription.objects.create(
1507
        agenda=second_agenda,
1508
        user_external_id='xxx',
1509
        date_start=now(),
1510
        date_end=now() + datetime.timedelta(days=30),
1511
    )
1512
    resp = app.get('/api/agendas/recurring-events/?user_external_id=xxx&subscribed=all')
1513
    assert len(resp.json['data']) == 5
1514

  
1515
    resp = app.get('/api/agendas/recurring-events/?user_external_id=xxx&subscribed=category-b')
1516
    assert len(resp.json['data']) == 1
1517

  
1518
    # other user
1519
    resp = app.get('/api/agendas/recurring-events/?user_external_id=yyy&subscribed=all')
1520
    assert len(resp.json['data']) == 0
1521

  
1522
    Subscription.objects.create(
1523
        agenda=second_agenda,
1524
        user_external_id='yyy',
1525
        date_start=now(),
1526
        date_end=now() + datetime.timedelta(days=30),
1527
    )
1528
    resp = app.get('/api/agendas/recurring-events/?user_external_id=yyy&subscribed=all')
1529
    assert len(resp.json['data']) == 1
1530

  
1531

  
1464 1532
@pytest.mark.freeze_time('2021-05-06 14:00')
1465 1533
def test_datetimes_multiple_agendas(app):
1466 1534
    first_agenda = Agenda.objects.create(
1467
-