Projet

Général

Profil

0001-agendas-allow-custom-event-api-text-53661.patch

Valentin Deniaud, 19 mai 2021 14:45

Télécharger (7,83 ko)

Voir les différences:

Subject: [PATCH] agendas: allow custom event api text (#53661)

 .../0088_agenda_event_display_template.py     | 23 ++++++++++++++++++
 chrono/agendas/models.py                      |  8 +++++++
 chrono/api/views.py                           |  5 +++-
 chrono/manager/forms.py                       |  2 ++
 tests/manager/test_all.py                     |  3 +++
 tests/test_api.py                             | 24 +++++++++++++++++--
 6 files changed, 62 insertions(+), 3 deletions(-)
 create mode 100644 chrono/agendas/migrations/0088_agenda_event_display_template.py
chrono/agendas/migrations/0088_agenda_event_display_template.py
1
# Generated by Django 2.2.19 on 2021-05-19 12:23
2

  
3
from django.db import migrations, models
4

  
5

  
6
class Migration(migrations.Migration):
7

  
8
    dependencies = [
9
        ('agendas', '0087_booking_user_name'),
10
    ]
11

  
12
    operations = [
13
        migrations.AddField(
14
            model_name='agenda',
15
            name='event_display_template',
16
            field=models.CharField(
17
                blank=True,
18
                help_text='By default event labels will be displayed to users. This allows for a custom template to include additional informations. For example, "{{ event.label }} - {{ event.start_datetime }}" will show event datetime after label.',
19
                max_length=256,
20
                verbose_name='Event display template',
21
            ),
22
        ),
23
    ]
chrono/agendas/models.py
211 211
        blank=True,
212 212
        validators=[django_template_validator],
213 213
    )
214
    event_display_template = models.CharField(
215
        _('Event display template'),
216
        max_length=256,
217
        blank=True,
218
        help_text=_(
219
            'By default event labels will be displayed to users. This allows for a custom template to include additional informations. For example, "{{ event.label }} - {{ event.start_datetime }}" will show event datetime after label.'
220
        ),
221
    )
214 222

  
215 223
    class Meta:
216 224
        ordering = ['label']
chrono/api/views.py
23 23
from django.db.models import Prefetch, Q
24 24
from django.http import Http404, HttpResponse
25 25
from django.shortcuts import get_object_or_404
26
from django.template import Context, Template
26 27
from django.urls import reverse
27 28
from django.utils.dateparse import parse_date, parse_datetime
28 29
from django.utils.encoding import force_text
......
414 415
def get_event_detail(request, event, agenda=None, min_places=1):
415 416
    agenda = agenda or event.agenda
416 417
    event_text = force_text(event)
417
    if event.label and event.primary_event is not None:
418
    if agenda.event_display_template:
419
        event_text = Template(agenda.event_display_template).render(Context({'event': event}))
420
    elif event.label and event.primary_event is not None:
418 421
        event_text = '%s (%s)' % (
419 422
            event.label,
420 423
            date_format(localtime(event.start_datetime), 'DATETIME_FORMAT'),
chrono/manager/forms.py
101 101
            'anonymize_delay',
102 102
            'default_view',
103 103
            'booking_form_url',
104
            'event_display_template',
104 105
        ]
105 106

  
106 107
    def __init__(self, *args, **kwargs):
107 108
        super(AgendaEditForm, self).__init__(*args, **kwargs)
108 109
        if kwargs['instance'].kind != 'events':
109 110
            del self.fields['booking_form_url']
111
            del self.fields['event_display_template']
110 112
            self.fields['default_view'].choices = [
111 113
                (k, v) for k, v in self.fields['default_view'].choices if k != 'open_events'
112 114
            ]
tests/manager/test_all.py
469 469
    assert resp.context['form'].initial['default_view'] == 'month'
470 470
    assert 'open_events' in [k for k, v in resp.context['form'].fields['default_view'].choices]
471 471
    assert 'booking_form_url' in resp.context['form'].fields
472
    assert 'event_display_template' in resp.context['form'].fields
472 473
    resp = resp.form.submit()
473 474
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda_events.pk)
474 475
    resp = resp.follow()
......
482 483
    assert 'default_view' in resp.context['form'].fields
483 484
    assert 'open_events' not in [k for k, v in resp.context['form'].fields['default_view'].choices]
484 485
    assert 'booking_form_url' not in resp.context['form'].fields
486
    assert 'event_display_template' not in resp.context['form'].fields
485 487

  
486 488
    resp.form['default_view'] = 'month'
487 489
    resp.form.submit()
......
492 494
    assert resp.form['default_view'].value == 'month'
493 495
    assert 'default_view' in resp.context['form'].fields
494 496
    assert 'booking_form_url' not in resp.context['form'].fields
497
    assert 'event_display_template' not in resp.context['form'].fields
495 498
    assert 'open_events' not in [k for k, v in resp.context['form'].fields['default_view'].choices]
496 499

  
497 500

  
tests/test_api.py
540 540
        assert 'data' in resp.json
541 541

  
542 542

  
543
@pytest.mark.freeze_time('2021-05-06 14:00')
543 544
def test_datetime_api_label(app):
544 545
    agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0)
545
    Event.objects.create(
546
    event = Event.objects.create(
546 547
        label='Hello world',
547 548
        slug='event-slug',
548 549
        start_datetime=(now() + datetime.timedelta(days=1)),
......
550 551
        agenda=agenda,
551 552
    )
552 553
    resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
553
    assert 'Hello world' in [x['text'] for x in resp.json['data']]
554
    assert 'Hello world' == resp.json['data'][0]['text']
555

  
556
    agenda.event_display_template = '{{ event.label }} - {{ event.start_datetime }}'
557
    agenda.save()
558
    resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
559
    assert resp.json['data'][0]['text'] == 'Hello world - May 7, 2021, 4 p.m.'
560

  
561
    Booking.objects.create(event=event)
562
    agenda.event_display_template = (
563
        '{{ event.label }} ({{ event.remaining_places }}/{{ event.places }} places remaining)'
564
    )
565
    agenda.save()
566
    resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
567
    assert resp.json['data'][0]['text'] == 'Hello world (4/5 places remaining)'
554 568

  
555 569

  
556 570
def test_datetime_api_urls(app):
......
6338 6352
    assert len(resp.json['data']) == 2
6339 6353
    assert resp.json['data'][0]['id'] == 'abc:2021-02-02-1305'
6340 6354

  
6355
    # events follow agenda display template
6356
    agenda.event_display_template = '{{ event.label }} - {{ event.start_datetime }}'
6357
    agenda.save()
6358
    resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
6359
    assert resp.json['data'][0]['text'] == 'Test - Feb. 2, 2021, 1:05 p.m.'
6360

  
6341 6361

  
6342 6362
def test_recurring_events_api_various_times(app, user, mock_now):
6343 6363
    agenda = Agenda.objects.create(
6344
-