Projet

Général

Profil

0002-api-make-recurring-events-list-endpoint-work-with-mu.patch

Valentin Deniaud, 21 octobre 2021 18:07

Télécharger (9,2 ko)

Voir les différences:

Subject: [PATCH 2/5] api: make recurring events list endpoint work with
 multiple agendas (#57957)

 chrono/api/urls.py          |  6 +--
 chrono/api/views.py         | 38 +++++++++----------
 tests/api/test_datetimes.py | 75 ++++++++++++++++++++++++++++++++-----
 3 files changed, 86 insertions(+), 33 deletions(-)
chrono/api/urls.py
21 21
urlpatterns = [
22 22
    url(r'^agenda/$', views.agendas),
23 23
    url(r'^agendas/datetimes/$', views.agendas_datetimes, name='api-agendas-datetimes'),
24
    url(r'^agendas/recurring-events/$', views.recurring_events_list, name='api-agenda-recurring-events'),
24 25
    url(
25 26
        r'^agendas/events/fillslots/$',
26 27
        views.agendas_events_fillslots,
......
39 40
        views.events_fillslots,
40 41
        name='api-agenda-events-fillslots',
41 42
    ),
42
    url(
43
        r'^agenda/(?P<agenda_identifier>[\w-]+)/recurring-events/$',
44
        views.recurring_events_list,
45
        name='api-agenda-recurring-events',
46
    ),
47 43
    url(
48 44
        r'^agenda/(?P<agenda_identifier>[\w-]+)/recurring-events/fillslots/$',
49 45
        views.recurring_fillslots,
chrono/api/views.py
1066 1066
        if not settings.ENABLE_RECURRING_EVENT_BOOKING:
1067 1067
            raise Http404()
1068 1068

  
1069
        agenda = get_object_or_404(Agenda, slug=agenda_identifier, kind='events')
1070
        entries = agenda.get_open_recurring_events()
1069
        agenda_slugs = get_agendas_from_request(request)
1070
        agendas = get_objects_from_slugs(agenda_slugs, qs=Agenda.objects.filter(kind='events'))
1071 1071

  
1072 1072
        events = []
1073
        for event in entries:
1074
            for day in event.recurrence_days:
1075
                slug = '%s:%s' % (event.slug, day)
1076
                events.append(
1077
                    {
1078
                        'id': slug,
1079
                        'text': get_event_text(event, agenda, day),
1080
                        'label': event.label or '',
1081
                        'day': WEEKDAYS[day].capitalize(),
1082
                        'date': format_response_date(event.start_datetime),
1083
                        'datetime': format_response_datetime(event.start_datetime),
1084
                        'description': event.description,
1085
                        'pricing': event.pricing,
1086
                        'url': event.url,
1087
                    }
1088
                )
1089

  
1073
        for agenda in agendas:
1074
            for event in agenda.get_open_recurring_events():
1075
                for day in event.recurrence_days:
1076
                    slug = '%s@%s:%s' % (agenda.slug, event.slug, day)
1077
                    events.append(
1078
                        {
1079
                            'id': slug,
1080
                            'text': get_event_text(event, agenda, day),
1081
                            'label': event.label or '',
1082
                            'day': WEEKDAYS[day].capitalize(),
1083
                            'date': format_response_date(event.start_datetime),
1084
                            'datetime': format_response_datetime(event.start_datetime),
1085
                            'description': event.description,
1086
                            'pricing': event.pricing,
1087
                            'url': event.url,
1088
                        }
1089
                    )
1090 1090
        return Response({'data': events})
1091 1091

  
1092 1092

  
tests/api/test_datetimes.py
1318 1318
def test_recurring_events_api_list(app, freezer):
1319 1319
    freezer.move_to('2021-09-06 12:00')
1320 1320
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
1321
    Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
1321 1322
    Event.objects.create(label='Normal event', start_datetime=now(), places=5, agenda=agenda)
1322 1323
    event = Event.objects.create(
1323 1324
        label='Example Event',
......
1327 1328
        agenda=agenda,
1328 1329
    )
1329 1330

  
1330
    resp = app.get('/api/agenda/xxx/recurring-events/', status=404)
1331
    resp = app.get('/api/agendas/recurring-events/', status=400)
1331 1332

  
1332 1333
    # recurring events without recurrence_end_date are not bookable
1333
    resp = app.get('/api/agenda/%s/recurring-events/' % agenda.slug)
1334
    resp = app.get('/api/agendas/recurring-events/?agendas=%s' % agenda.slug)
1334 1335
    assert len(resp.json['data']) == 0
1335 1336

  
1336 1337
    event.recurrence_end_date = now() + datetime.timedelta(days=30)
......
1345 1346
        recurrence_end_date=now() + datetime.timedelta(days=45),
1346 1347
    )
1347 1348

  
1348
    resp = app.get('/api/agenda/%s/recurring-events/' % agenda.slug)
1349
    resp = app.get('/api/agendas/recurring-events/?agendas=%s' % agenda.slug)
1349 1350
    assert len(resp.json['data']) == 4
1350
    assert resp.json['data'][0]['id'] == 'example-event:0'
1351
    assert resp.json['data'][0]['id'] == 'foo-bar@example-event:0'
1351 1352
    assert resp.json['data'][0]['text'] == 'Monday: Example Event'
1352 1353
    assert resp.json['data'][0]['label'] == 'Example Event'
1353 1354
    assert resp.json['data'][0]['day'] == 'Monday'
1354
    assert resp.json['data'][1]['id'] == 'example-event:3'
1355
    assert resp.json['data'][1]['id'] == 'foo-bar@example-event:3'
1355 1356
    assert resp.json['data'][1]['text'] == 'Thursday: Example Event'
1356 1357
    assert resp.json['data'][1]['label'] == 'Example Event'
1357 1358
    assert resp.json['data'][1]['day'] == 'Thursday'
1358
    assert resp.json['data'][2]['id'] == 'example-event:4'
1359
    assert resp.json['data'][2]['id'] == 'foo-bar@example-event:4'
1359 1360
    assert resp.json['data'][2]['text'] == 'Friday: Example Event'
1360 1361
    assert resp.json['data'][2]['label'] == 'Example Event'
1361 1362
    assert resp.json['data'][2]['day'] == 'Friday'
1362
    assert resp.json['data'][3]['id'] == 'other:1'
1363
    assert resp.json['data'][3]['id'] == 'foo-bar@other:1'
1363 1364
    assert resp.json['data'][3]['text'] == 'Tuesday: Other'
1364 1365
    assert resp.json['data'][3]['label'] == 'Other'
1365 1366
    assert resp.json['data'][3]['day'] == 'Tuesday'
1366 1367

  
1367 1368
    event.publication_datetime = now() + datetime.timedelta(days=2)
1368 1369
    event.save()
1369
    resp = app.get('/api/agenda/%s/recurring-events/' % agenda.slug)
1370
    resp = app.get('/api/agendas/recurring-events/?agendas=%s' % agenda.slug)
1370 1371
    assert len(resp.json['data']) == 1
1371 1372

  
1372 1373
    freezer.move_to(event.recurrence_end_date)
1373
    resp = app.get('/api/agenda/%s/recurring-events/' % agenda.slug)
1374
    resp = app.get('/api/agendas/recurring-events/?agendas=%s' % agenda.slug)
1374 1375
    assert len(resp.json['data']) == 1
1375 1376

  
1376 1377

  
1378
@pytest.mark.freeze_time('2021-09-06 12:00')
1379
def test_recurring_events_api_list_multiple_agendas(app):
1380
    agenda = Agenda.objects.create(label='First Agenda', kind='events')
1381
    Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
1382
    start, end = now(), now() + datetime.timedelta(days=30)
1383
    Event.objects.create(
1384
        label='A',
1385
        start_datetime=start,
1386
        places=2,
1387
        recurrence_end_date=end,
1388
        recurrence_days=[0, 2, 5],
1389
        agenda=agenda,
1390
    )
1391
    Event.objects.create(
1392
        label='B', start_datetime=start, places=2, recurrence_end_date=end, recurrence_days=[1], agenda=agenda
1393
    )
1394
    agenda2 = Agenda.objects.create(label='Second Agenda', kind='events')
1395
    Desk.objects.create(agenda=agenda2, slug='_exceptions_holder')
1396
    Event.objects.create(
1397
        label='C',
1398
        start_datetime=start,
1399
        places=2,
1400
        recurrence_end_date=end,
1401
        recurrence_days=[2, 3],
1402
        agenda=agenda2,
1403
    )
1404

  
1405
    resp = app.get('/api/agendas/recurring-events/?agendas=first-agenda,second-agenda')
1406
    assert [x['id'] for x in resp.json['data']] == [
1407
        'first-agenda@a:0',
1408
        'first-agenda@a:2',
1409
        'first-agenda@a:5',
1410
        'first-agenda@b:1',
1411
        'second-agenda@c:2',
1412
        'second-agenda@c:3',
1413
    ]
1414

  
1415
    resp = app.get('/api/agendas/recurring-events/?agendas=second-agenda')
1416
    assert [x['id'] for x in resp.json['data']] == ['second-agenda@c:2', 'second-agenda@c:3']
1417

  
1418

  
1419
@pytest.mark.freeze_time('2021-09-06 12:00')
1420
def test_recurring_events_api_list_multiple_agendas_queries(app):
1421
    for i in range(20):
1422
        agenda = Agenda.objects.create(slug=f'{i}', kind='events')
1423
        Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
1424
        start, end = now(), now() + datetime.timedelta(days=30)
1425
        Event.objects.create(
1426
            start_datetime=start, places=2, recurrence_end_date=end, recurrence_days=[1, 2], agenda=agenda
1427
        )
1428
    with CaptureQueriesContext(connection) as ctx:
1429
        resp = app.get('/api/agendas/recurring-events/?agendas=%s' % ','.join(str(i) for i in range(20)))
1430
        assert len(resp.json['data']) == 40
1431
        assert len(ctx.captured_queries) == 23
1432

  
1433

  
1377 1434
@pytest.mark.freeze_time('2021-05-06 14:00')
1378 1435
def test_datetimes_multiple_agendas(app):
1379 1436
    first_agenda = Agenda.objects.create(label='First agenda', kind='events')
1380
-