Projet

Général

Profil

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

Valentin Deniaud, 01 décembre 2021 15:21

Télécharger (5,84 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 | 70 +++++++++++++++++++++++++++++++++++++
 3 files changed, 81 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
    # Desk.objects.create(agenda=first_agenda, slug='_exceptions_holder')
1469
    category = Category.objects.create(label='Category B')
1470
    second_agenda = Agenda.objects.create(label='Second agenda', kind='events', category=category)
1471
    # Desk.objects.create(agenda=second_agenda, slug='_exceptions_holder')
1472
    event = Event.objects.create(
1473
        slug='event',
1474
        start_datetime=now(),
1475
        recurrence_days=[0, 1, 3, 4],  # Monday, Tuesday, Thursday, Friday
1476
        places=2,
1477
        waiting_list_places=1,
1478
        agenda=first_agenda,
1479
        recurrence_end_date=now() + datetime.timedelta(days=364),
1480
    )
1481
    sunday_event = Event.objects.create(
1482
        slug='sunday-event',
1483
        start_datetime=now(),
1484
        recurrence_days=[6],
1485
        places=2,
1486
        waiting_list_places=1,
1487
        agenda=second_agenda,
1488
        recurrence_end_date=now() + datetime.timedelta(days=364),
1489
    )
1490

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

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

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

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

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

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

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

  
1533

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