Projet

Général

Profil

0002-api-return-end_datetime-on-booking-events-37352.patch

Nicolas Roche, 02 juin 2020 11:29

Télécharger (9,49 ko)

Voir les différences:

Subject: [PATCH 2/2] api: return end_datetime on booking events (#37352)

 chrono/agendas/models.py |  6 +--
 chrono/api/views.py      |  5 +++
 tests/test_api.py        | 84 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 89 insertions(+), 6 deletions(-)
chrono/agendas/models.py
841 841
            self.event.agenda.pk,
842 842
            self.pk,
843 843
        )
844 844

  
845 845
        vevent.add('summary').value = self.user_display_label or self.label
846 846
        vevent.add('dtstart').value = self.event.start_datetime
847 847
        if self.user_name:
848 848
            vevent.add('attendee').value = self.user_name
849
        if self.event.meeting_type:
850
            vevent.add('dtend').value = self.event.start_datetime + datetime.timedelta(
851
                minutes=self.event.meeting_type.duration
852
            )
849
        if self.event.end_datetime:
850
            vevent.add('dtend').value = self.event.end_datetime
853 851

  
854 852
        for field in ('description', 'location', 'comment', 'url'):
855 853
            field_value = request and request.GET.get(field) or self.extra_data.get(field)
856 854
            if field_value:
857 855
                vevent.add(field).value = field_value
858 856
        ics.add(vevent)
859 857
        return ics.serialize()
860 858

  
chrono/api/views.py
907 907
            response['desk'] = {'label': available_desk.label, 'slug': available_desk.slug}
908 908
        if to_cancel_booking:
909 909
            response['cancelled_booking_id'] = cancelled_booking_id
910 910
        if agenda.kind == 'events' and not multiple_booking:
911 911
            event = events[0]
912 912
            # event.full is not up to date, it might have been changed by previous new_booking.save().
913 913
            event.refresh_from_db()
914 914
            response['places'] = get_event_places(event)
915
            if event.end_datetime:
916
                response['end_datetime'] = format_response_datetime(event.end_datetime)
917
            else:
918
                response['end_datetime'] = None
915 919
        if agenda.kind == 'events' and multiple_booking:
916 920
            response['events'] = [
917 921
                {
918 922
                    'slug': x.slug,
919 923
                    'text': str(x),
920 924
                    'datetime': format_response_datetime(x.start_datetime),
925
                    'end_datetime': format_response_datetime(x.end_datetime) if x.end_datetime else None,
921 926
                    'description': x.description,
922 927
                }
923 928
                for x in events
924 929
            ]
925 930

  
926 931
        return Response(response)
927 932

  
928 933

  
tests/test_api.py
67 67

  
68 68

  
69 69
@pytest.fixture
70 70
def some_data(time_zone, mock_now):
71 71
    agenda = Agenda(label=u'Foo bar')
72 72
    agenda.save()
73 73
    first_date = localtime(now()).replace(hour=17, minute=0, second=0, microsecond=0)
74 74
    first_date += datetime.timedelta(days=1)
75
    durations = [None, 0, 45]
75 76
    for i in range(3):
76
        event = Event(start_datetime=first_date + datetime.timedelta(days=i), places=20, agenda=agenda)
77
        event = Event(start_datetime=first_date + datetime.timedelta(days=i), duration=durations[i],
78
                      places=20, agenda=agenda)
77 79
        event.save()
78 80

  
79 81
    agenda2 = Agenda(label=u'Foo bar 2')
80 82
    agenda2.save()
81 83
    first_date = localtime(now()).replace(hour=20, minute=0, second=0, microsecond=0)
82 84
    first_date += datetime.timedelta(days=1)
83 85
    for i in range(2):
84 86
        event = Event(start_datetime=first_date + datetime.timedelta(days=i), places=20, agenda=agenda2)
......
536 538
    formatted_start_date = event.start_datetime.strftime('%Y%m%dT%H%M%S')
537 539
    booking_ics = Booking.objects.get(id=resp.json['booking_id']).get_ics()
538 540
    assert (
539 541
        'UID:%s-%s-%s\r\n' % (event.start_datetime.isoformat(), agenda.pk, resp.json['booking_id'])
540 542
        in booking_ics
541 543
    )
542 544
    assert 'SUMMARY:\r\n' in booking_ics
543 545
    assert 'DTSTART:%sZ\r\n' % formatted_start_date in booking_ics
544
    assert 'DTEDND:' not in booking_ics
546
    assert 'DTEND:' not in booking_ics
545 547

  
546 548
    # test with additional data
547 549
    resp = app.post_json(
548 550
        '/api/agenda/%s/fillslot/%s/' % (agenda.id, event.id),
549 551
        params={
550 552
            'label': 'foo',
551 553
            'user_name': 'bar',
552 554
            'backoffice_url': 'http://example.net/',
......
3264 3266
        )
3265 3267
        if next_agenda:
3266 3268
            assert booking.event.agenda == next_agenda
3267 3269

  
3268 3270
    foo_num_bookings = Booking.objects.filter(event__desk__agenda=foo_agenda).count()
3269 3271
    bar_num_bookings = Booking.objects.filter(event__desk__agenda=bar_agenda).count()
3270 3272
    assert foo_num_bookings == 2
3271 3273
    assert bar_num_bookings == 4
3274

  
3275

  
3276
def test_duration_on_booking_api_fillslot_response(app, some_data, user):
3277
    agenda = Agenda.objects.filter(label=u'Foo bar')[0]
3278
    evts = [x for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()]
3279
    assert evts[0].duration is None
3280
    assert evts[0].end_datetime is None
3281
    assert evts[1].duration == 0
3282
    assert evts[1].end_datetime == evts[1].start_datetime
3283
    assert evts[2].duration == 45
3284
    assert evts[2].end_datetime == evts[2].start_datetime + datetime.timedelta(minutes=45)
3285
    app.authorization = ('Basic', ('john.doe', 'password'))
3286

  
3287
    resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda.slug, evts[0].id))
3288
    formatted_start_date = localtime(evts[0].start_datetime).strftime('%Y-%m-%d %H:%M:%S')
3289
    assert resp.json['datetime'] == formatted_start_date
3290
    assert resp.json['end_datetime'] is None
3291
    assert 'ics_url' in resp.json['api']
3292
    ics = app.get(resp.json['api']['ics_url']).text
3293
    assert 'DTSTART:%sZ\r\n' % evts[0].start_datetime.strftime('%Y%m%dT%H%M%S') in ics
3294
    assert 'DTEND:' not in ics
3295

  
3296
    resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda.slug, evts[1].id))
3297
    assert resp.json['datetime'] == localtime(evts[1].start_datetime).strftime('%Y-%m-%d %H:%M:%S')
3298
    assert resp.json['end_datetime'] == resp.json['datetime']
3299
    assert 'ics_url' in resp.json['api']
3300
    ics = app.get(resp.json['api']['ics_url']).text
3301
    assert 'DTSTART:%sZ\r\n' % evts[1].start_datetime.strftime('%Y%m%dT%H%M%S') in ics
3302
    assert 'DTEND:%sZ\r\n' % evts[1].start_datetime.strftime('%Y%m%dT%H%M%S') in ics
3303

  
3304
    resp = app.post('/api/agenda/%s/fillslot/%s/' % (agenda.slug, evts[2].id))
3305
    assert resp.json['datetime'] == localtime(evts[2].start_datetime).strftime('%Y-%m-%d %H:%M:%S')
3306
    assert resp.json['end_datetime'] == localtime(evts[2].end_datetime).strftime('%Y-%m-%d %H:%M:%S')
3307
    assert 'ics_url' in resp.json['api']
3308
    ics = app.get(resp.json['api']['ics_url']).text
3309
    assert 'DTSTART:%sZ\r\n' % evts[2].start_datetime.strftime('%Y%m%dT%H%M%S') in ics
3310
    assert 'DTEND:%sZ\r\n' % evts[2].end_datetime.strftime('%Y%m%dT%H%M%S') in ics
3311

  
3312

  
3313
def test_duration_on_booking_api_fillslots_response(app, some_data, user):
3314
    agenda = Agenda.objects.filter(label=u'Foo bar')[0]
3315
    evts = [x for x in Event.objects.filter(agenda=agenda) if x.in_bookable_period()]
3316
    assert evts[0].duration is None
3317
    assert evts[0].end_datetime is None
3318
    assert evts[1].duration == 0
3319
    assert evts[1].end_datetime == evts[1].start_datetime
3320
    assert evts[2].duration == 45
3321
    assert evts[2].end_datetime == evts[2].start_datetime + datetime.timedelta(minutes=45)
3322
    app.authorization = ('Basic', ('john.doe', 'password'))
3323

  
3324
    # first event having null duration
3325
    string_param = ','.join([str(e.id) for e in evts[::-1]])  # unordered parameters
3326
    resp = app.post_json('/api/agenda/%s/fillslots/' % agenda.slug, params={'slots': string_param})
3327
    r_evts = resp.json['events']
3328

  
3329
    assert r_evts[0]['datetime'] == localtime(evts[0].start_datetime).strftime('%Y-%m-%d %H:%M:%S')
3330
    assert r_evts[0]['end_datetime'] is None
3331
    assert r_evts[1]['datetime'] == localtime(evts[1].start_datetime).strftime('%Y-%m-%d %H:%M:%S')
3332
    assert r_evts[1]['end_datetime'] == r_evts[1]['datetime']
3333
    assert r_evts[2]['datetime'] == localtime(evts[2].start_datetime).strftime('%Y-%m-%d %H:%M:%S')
3334
    assert r_evts[2]['end_datetime'] == localtime(evts[2].end_datetime).strftime('%Y-%m-%d %H:%M:%S')
3335
    assert 'ics_url' in resp.json['api']
3336
    ics = app.get(resp.json['api']['ics_url']).text
3337
    assert 'DTSTART:%sZ\r\n' % evts[0].start_datetime.strftime('%Y%m%dT%H%M%S') in ics
3338
    assert 'DTEND:' not in ics
3339

  
3340
    # first event having duration
3341
    evts[0].duration = 90
3342
    evts[0].save()
3343
    resp = app.post_json('/api/agenda/%s/fillslots/' % agenda.slug, params={'slots': string_param})
3344
    r_evts = resp.json['events']
3345

  
3346
    assert r_evts[0]['datetime'] == localtime(evts[0].start_datetime).strftime('%Y-%m-%d %H:%M:%S')
3347
    assert r_evts[0]['end_datetime'] == localtime(evts[0].end_datetime).strftime('%Y-%m-%d %H:%M:%S')
3348
    assert 'ics_url' in resp.json['api']
3349
    ics = app.get(resp.json['api']['ics_url']).text
3350
    assert 'DTSTART:%sZ\r\n' % evts[0].start_datetime.strftime('%Y%m%dT%H%M%S') in ics
3351
    assert 'DTEND:%sZ\r\n' % evts[0].end_datetime.strftime('%Y%m%dT%H%M%S') in ics
3272
-