0001-agendas-event-publication_datetime-56634.patch
chrono/agendas/migrations/0101_publication_datetime.py | ||
---|---|---|
1 |
from django.db import migrations, models |
|
2 | ||
3 | ||
4 |
class Migration(migrations.Migration): |
|
5 | ||
6 |
dependencies = [ |
|
7 |
('agendas', '0100_event_dml'), |
|
8 |
] |
|
9 | ||
10 |
operations = [ |
|
11 |
migrations.AddField( |
|
12 |
model_name='event', |
|
13 |
name='publication_datetime', |
|
14 |
field=models.DateTimeField(blank=True, null=True, verbose_name='Publication date/time'), |
|
15 |
), |
|
16 |
] |
chrono/agendas/migrations/0102_publication_datetime.py | ||
---|---|---|
1 |
import datetime |
|
2 | ||
3 |
from django.db import migrations |
|
4 |
from django.utils.timezone import localtime, make_aware |
|
5 | ||
6 | ||
7 |
def forwards(apps, schema_editor): |
|
8 |
Event = apps.get_model('agendas', 'Event') |
|
9 |
for event in Event.objects.filter(publication_date__isnull=False): |
|
10 |
event.publication_datetime = make_aware( |
|
11 |
datetime.datetime.combine(event.publication_date, datetime.time(0, 0)) |
|
12 |
) |
|
13 |
event.save() |
|
14 | ||
15 | ||
16 |
def backwards(apps, schema_editor): |
|
17 |
Event = apps.get_model('agendas', 'Event') |
|
18 |
for event in Event.objects.filter(publication_datetime__isnull=False): |
|
19 |
event.publication_date = localtime(event.publication_datetime).date() |
|
20 |
event.save() |
|
21 | ||
22 | ||
23 |
class Migration(migrations.Migration): |
|
24 | ||
25 |
dependencies = [ |
|
26 |
('agendas', '0101_publication_datetime'), |
|
27 |
] |
|
28 | ||
29 |
operations = [ |
|
30 |
migrations.RunPython(forwards, reverse_code=backwards), |
|
31 |
] |
chrono/agendas/migrations/0103_publication_datetime.py | ||
---|---|---|
1 |
from django.db import migrations |
|
2 | ||
3 | ||
4 |
class Migration(migrations.Migration): |
|
5 | ||
6 |
dependencies = [ |
|
7 |
('agendas', '0102_publication_datetime'), |
|
8 |
] |
|
9 | ||
10 |
operations = [ |
|
11 |
migrations.RemoveField( |
|
12 |
model_name='event', |
|
13 |
name='publication_date', |
|
14 |
), |
|
15 |
] |
chrono/agendas/models.py | ||
---|---|---|
133 | 133 |
def event_template_validator(value): |
134 | 134 |
example_event = Event( |
135 | 135 |
start_datetime=now(), |
136 |
publication_date=now().date(),
|
|
136 |
publication_datetime=now(),
|
|
137 | 137 |
recurrence_end_date=now().date(), |
138 | 138 |
places=1, |
139 | 139 |
duration=1, |
... | ... | |
666 | 666 |
entries = entries.filter(start_datetime__gte=localtime(now())) |
667 | 667 |
# exclude non published events |
668 | 668 |
entries = entries.filter( |
669 |
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date())
|
|
669 |
Q(publication_datetime__isnull=True) | Q(publication_datetime__lte=now())
|
|
670 | 670 |
) |
671 | 671 |
if not include_full: |
672 | 672 |
entries = entries.filter(Q(full=False) | Q(primary_event__isnull=False)) |
... | ... | |
745 | 745 | |
746 | 746 |
def get_open_recurring_events(self): |
747 | 747 |
return self.event_set.filter( |
748 |
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date()),
|
|
748 |
Q(publication_datetime__isnull=True) | Q(publication_datetime__lte=now()),
|
|
749 | 749 |
recurrence_days__isnull=False, |
750 | 750 |
recurrence_end_date__gt=localtime(now()).date(), |
751 | 751 |
) |
... | ... | |
773 | 773 |
exceptions = self.prefetched_exceptions |
774 | 774 |
else: |
775 | 775 |
recurring_events = self.event_set.filter( |
776 |
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date()),
|
|
776 |
Q(publication_datetime__isnull=True) | Q(publication_datetime__lte=now()),
|
|
777 | 777 |
recurrence_days__isnull=False, |
778 | 778 |
) |
779 | 779 |
exceptions = self.get_recurrence_exceptions(min_start, max_start) |
... | ... | |
884 | 884 |
qs, user_external_id=None, show_past_events=False, min_start=None, max_start=None |
885 | 885 |
): |
886 | 886 |
event_queryset = Event.objects.filter( |
887 |
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date()),
|
|
887 |
Q(publication_datetime__isnull=True) | Q(publication_datetime__lte=now()),
|
|
888 | 888 |
recurrence_days__isnull=True, |
889 | 889 |
cancelled=False, |
890 | 890 |
).order_by() |
... | ... | |
899 | 899 |
event_queryset = event_queryset.filter(start_datetime__lt=max_start) |
900 | 900 | |
901 | 901 |
recurring_event_queryset = Event.objects.filter( |
902 |
Q(publication_date__isnull=True) | Q(publication_date__lte=localtime(now()).date()),
|
|
902 |
Q(publication_datetime__isnull=True) | Q(publication_datetime__lte=now()),
|
|
903 | 903 |
recurrence_days__isnull=False, |
904 | 904 |
) |
905 | 905 |
exceptions_desk = Desk.objects.filter(slug='_exceptions_holder').prefetch_related( |
... | ... | |
1355 | 1355 |
recurrence_end_date = models.DateField(_('Recurrence end date'), null=True, blank=True) |
1356 | 1356 |
primary_event = models.ForeignKey('self', null=True, on_delete=models.CASCADE, related_name='recurrences') |
1357 | 1357 |
duration = models.PositiveIntegerField(_('Duration (in minutes)'), default=None, null=True, blank=True) |
1358 |
publication_date = models.DateField(_('Publication date'), blank=True, null=True)
|
|
1358 |
publication_datetime = models.DateTimeField(_('Publication date/time'), blank=True, null=True)
|
|
1359 | 1359 |
places = models.PositiveIntegerField(_('Places')) |
1360 | 1360 |
waiting_list_places = models.PositiveIntegerField(_('Places in waiting list'), default=0) |
1361 | 1361 |
label = models.CharField( |
... | ... | |
1451 | 1451 |
self.save(update_fields=['checked']) |
1452 | 1452 | |
1453 | 1453 |
def in_bookable_period(self): |
1454 |
if self.publication_date and localtime(now()).date() < self.publication_date:
|
|
1454 |
if self.publication_datetime and now() < self.publication_datetime:
|
|
1455 | 1455 |
return False |
1456 | 1456 |
if self.agenda.maximal_booking_delay and self.start_datetime > self.agenda.max_booking_datetime: |
1457 | 1457 |
return False |
... | ... | |
1545 | 1545 |
for field in [ |
1546 | 1546 |
'label', |
1547 | 1547 |
'duration', |
1548 |
'publication_date', |
|
1548 |
'publication_datetime',
|
|
1549 | 1549 |
'places', |
1550 | 1550 |
'waiting_list_places', |
1551 | 1551 |
'description', |
... | ... | |
1565 | 1565 |
) |
1566 | 1566 |
return { |
1567 | 1567 |
'start_datetime': make_naive(self.start_datetime).strftime('%Y-%m-%d %H:%M:%S'), |
1568 |
'publication_date': self.publication_date.strftime('%Y-%m-%d') if self.publication_date else None, |
|
1568 |
'publication_datetime': make_naive(self.publication_datetime).strftime('%Y-%m-%d %H:%M:%S') |
|
1569 |
if self.publication_datetime |
|
1570 |
else None, |
|
1569 | 1571 |
'recurrence_days': self.recurrence_days, |
1570 | 1572 |
'recurrence_week_interval': self.recurrence_week_interval, |
1571 | 1573 |
'recurrence_end_date': recurrence_end_date, |
... | ... | |
1659 | 1661 |
duration=self.duration, |
1660 | 1662 |
places=self.places, |
1661 | 1663 |
waiting_list_places=self.waiting_list_places, |
1662 |
publication_date=self.publication_date,
|
|
1664 |
publication_datetime=self.publication_datetime,
|
|
1663 | 1665 |
label=self.label, |
1664 | 1666 |
description=self.description, |
1665 | 1667 |
pricing=self.pricing, |
chrono/api/serializers.py | ||
---|---|---|
150 | 150 |
'recurrence_week_interval', |
151 | 151 |
'recurrence_end_date', |
152 | 152 |
'duration', |
153 |
'publication_date', |
|
153 |
'publication_datetime',
|
|
154 | 154 |
'places', |
155 | 155 |
'waiting_list_places', |
156 | 156 |
'label', |
chrono/api/views.py | ||
---|---|---|
2259 | 2259 |
for field in changed_data: |
2260 | 2260 |
if field in ( |
2261 | 2261 |
'recurrence_end_date', |
2262 |
'publication_date', |
|
2262 |
'publication_datetime',
|
|
2263 | 2263 |
'recurrence_days', |
2264 | 2264 |
'recurrence_week_interval', |
2265 | 2265 |
): |
chrono/manager/forms.py | ||
---|---|---|
216 | 216 |
class Meta: |
217 | 217 |
model = Event |
218 | 218 |
widgets = { |
219 |
'publication_date': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'), |
|
220 | 219 |
'recurrence_end_date': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'), |
221 | 220 |
} |
222 | 221 |
fields = [ |
... | ... | |
228 | 227 |
'recurrence_week_interval', |
229 | 228 |
'recurrence_end_date', |
230 | 229 |
'duration', |
231 |
'publication_date', |
|
230 |
'publication_datetime',
|
|
232 | 231 |
'places', |
233 | 232 |
'waiting_list_places', |
234 | 233 |
'description', |
... | ... | |
237 | 236 |
] |
238 | 237 |
field_classes = { |
239 | 238 |
'start_datetime': SplitDateTimeField, |
239 |
'publication_datetime': SplitDateTimeField, |
|
240 | 240 |
} |
241 | 241 | |
242 | 242 |
def __init__(self, *args, **kwargs): |
... | ... | |
252 | 252 |
for field in ( |
253 | 253 |
'slug', |
254 | 254 |
'recurrence_end_date', |
255 |
'publication_date', |
|
255 |
'publication_datetime',
|
|
256 | 256 |
'frequency', |
257 | 257 |
'recurrence_days', |
258 | 258 |
'recurrence_week_interval', |
... | ... | |
706 | 706 |
column_index += 1 |
707 | 707 | |
708 | 708 |
if len(csvline) >= 10 and csvline[9]: # publication date is optional |
709 |
for date_fmt in ('%Y-%m-%d', '%d/%m/%Y'): |
|
709 |
for datetime_fmt in ( |
|
710 |
'%Y-%m-%d', |
|
711 |
'%d/%m/%Y', |
|
712 |
'%Y-%m-%d %H:%M', |
|
713 |
'%d/%m/%Y %H:%M', |
|
714 |
'%d/%m/%Y %Hh%M', |
|
715 |
'%Y-%m-%d %H:%M:%S', |
|
716 |
'%d/%m/%Y %H:%M:%S', |
|
717 |
): |
|
710 | 718 |
try: |
711 |
event.publication_date = datetime.datetime.strptime(csvline[9], date_fmt).date() |
|
719 |
event.publication_datetime = make_aware( |
|
720 |
datetime.datetime.strptime(csvline[9], datetime_fmt) |
|
721 |
) |
|
712 | 722 |
break |
713 | 723 |
except ValueError: |
714 | 724 |
continue |
715 | 725 |
else: |
716 |
raise ValidationError(_('Invalid file format. (date format, line %d)') % (i + 1)) |
|
726 |
raise ValidationError(_('Invalid file format. (date/time format, line %d)') % (i + 1))
|
|
717 | 727 | |
718 | 728 |
if len(csvline) >= 11 and csvline[10]: # duration is optional |
719 | 729 |
try: |
chrono/manager/templates/chrono/manager_agenda_event_fragment.html | ||
---|---|---|
43 | 43 |
{% blocktrans with places=event.waiting_list_places count booked_places=event.booked_waiting_list_places %}{{ booked_places }}/{{ places }} booking{% plural %}{{ booked_places }}/{{ places }} bookings{% endblocktrans %}) |
44 | 44 |
{% endif %} |
45 | 45 |
{% endif %} |
46 |
{% if view_mode == 'settings_view' and event.publication_date %} |
|
47 |
({% trans "publication date:" %} {{ event.publication_date }}) |
|
46 |
{% if view_mode == 'settings_view' and event.publication_datetime %}
|
|
47 |
({% trans "publication date:" %} {{ event.publication_datetime }})
|
|
48 | 48 |
{% endif %} |
49 | 49 |
{% if not event.in_bookable_period %} |
50 | 50 |
({% trans "out of bookable period" %}) |
chrono/manager/templates/chrono/manager_event_detail_fragment.html | ||
---|---|---|
5 | 5 |
{% if object.description %}{{ object.description|linebreaks }}{% endif %} |
6 | 6 |
{% if object.pricing %}<p>{% trans "Pricing:" %} {{ object.pricing }}</p>{% endif %} |
7 | 7 |
{% if object.url %}<p><a href="{{ object.url }}">{{ object.url|truncatechars:100 }}</a></p>{% endif %} |
8 |
{% if object.publication_date %}<p>{% trans "Publication date:" %} {{ object.publication_date }}</p>{% endif %}
|
|
8 |
{% if object.publication_datetime %}<p>{% trans "Publication date:" %} {{ object.publication_datetime }}</p>{% endif %}
|
|
9 | 9 |
</div> |
10 | 10 |
</div> |
11 | 11 |
{% endif %} |
chrono/manager/templates/chrono/manager_sample_events.txt | ||
---|---|---|
1 |
{% load i18n %}{% trans 'date' %},{% trans 'time' %},{% trans 'number of places' %},{% trans 'number of places in waiting list' %},{% trans 'label' %},{% trans 'identifier' %},{% trans 'description' %},{% trans 'pricing' %},{% trans 'URL' %},{% trans 'publication date' %},{% trans 'duration' %} |
|
2 |
{{ some_future_date|date:"Y-m-d" }},{{ some_future_date|date:"H:i" }},15,0,{% trans "example event" as label %}{{ label }},{{ label|slugify }},,,https://www.example.net,{{ some_future_date|date:"Y-m-d" }},30 |
|
1 |
{% load i18n %}{% trans 'date' %},{% trans 'time' %},{% trans 'number of places' %},{% trans 'number of places in waiting list' %},{% trans 'label' %},{% trans 'identifier' %},{% trans 'description' %},{% trans 'pricing' %},{% trans 'URL' %},{% trans 'publication date/time' %},{% trans 'duration' %} |
|
2 |
{{ some_future_date|date:"Y-m-d" }},{{ some_future_date|date:"H:i" }},15,0,{% trans "example event" as label %}{{ label }},{{ label|slugify }},,,https://www.example.net,{{ some_future_date|date:"Y-m-d H:i" }},30 |
chrono/manager/views.py | ||
---|---|---|
1804 | 1804 |
_('description'), |
1805 | 1805 |
_('pricing'), |
1806 | 1806 |
_('URL'), |
1807 |
_('publication date'), |
|
1807 |
_('publication date/time'),
|
|
1808 | 1808 |
_('duration'), |
1809 | 1809 |
] |
1810 | 1810 |
) |
1811 | 1811 |
for event in self.agenda.event_set.all(): |
1812 | 1812 |
start_datetime = localtime(event.start_datetime) |
1813 |
publication_datetime = ( |
|
1814 |
localtime(event.publication_datetime) if event.publication_datetime else None |
|
1815 |
) |
|
1813 | 1816 |
writer.writerow( |
1814 | 1817 |
[ |
1815 | 1818 |
start_datetime.strftime('%Y-%m-%d'), |
... | ... | |
1821 | 1824 |
event.description, |
1822 | 1825 |
event.pricing, |
1823 | 1826 |
event.url, |
1824 |
event.publication_date.strftime('%Y-%m-%d') if event.publication_date else '',
|
|
1827 |
publication_datetime.strftime('%Y-%m-%d %H:%M') if publication_datetime else '',
|
|
1825 | 1828 |
event.duration, |
1826 | 1829 |
] |
1827 | 1830 |
) |
tests/api/test_all.py | ||
---|---|---|
255 | 255 |
event2.booking_set.all().delete() |
256 | 256 |
event2.refresh_from_db() |
257 | 257 |
assert event2.full is False |
258 |
event_agenda.event_set.update(publication_date=now().date() + datetime.timedelta(days=20))
|
|
258 |
event_agenda.event_set.update(publication_datetime=now() + datetime.timedelta(days=20))
|
|
259 | 259 |
assert list(event_agenda.get_open_events()) == [] |
260 | 260 |
resp = app.get('/api/agenda/', params={'with_open_events': '1'}) |
261 | 261 |
assert len(resp.json['data']) == 0 |
... | ... | |
470 | 470 |
event2.booking_set.all().delete() |
471 | 471 |
event2.refresh_from_db() |
472 | 472 |
assert event2.full is False |
473 |
agenda.event_set.update(publication_date=now().date() + datetime.timedelta(days=20))
|
|
473 |
agenda.event_set.update(publication_datetime=now() + datetime.timedelta(days=20))
|
|
474 | 474 |
resp = app.get('/api/agenda/%s/' % agenda.slug) |
475 | 475 |
assert list(agenda.get_open_events()) == [] |
476 | 476 |
assert resp.json['data']['opened_events_available'] is False |
tests/api/test_datetimes.py | ||
---|---|---|
50 | 50 |
check_bookability(resp.json['data']) |
51 | 51 |
assert resp.json['data'][0]['description'] is None |
52 | 52 | |
53 |
agenda.event_set.update(publication_date=localtime(now()).date() + datetime.timedelta(days=1))
|
|
53 |
agenda.event_set.update(publication_datetime=now() + datetime.timedelta(minutes=1))
|
|
54 | 54 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
55 | 55 |
assert len(resp.json['data']) == 0 |
56 | 56 |
check_bookability(resp.json['data']) |
57 | 57 | |
58 |
agenda.event_set.update(publication_date=localtime(now()).date())
|
|
58 |
agenda.event_set.update(publication_datetime=now())
|
|
59 | 59 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
60 | 60 |
assert len(resp.json['data']) == 2 |
61 | 61 |
check_bookability(resp.json['data']) |
... | ... | |
662 | 662 | |
663 | 663 |
# publication date is accounted for |
664 | 664 |
Event.objects.filter(primary_event=base_event).delete() |
665 |
base_event.publication_date = now().replace(day=27) |
|
665 |
base_event.publication_datetime = now().replace(day=27)
|
|
666 | 666 |
base_event.save() |
667 | 667 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
668 | 668 |
assert len(resp.json['data']) == 0 |
669 | 669 | |
670 | 670 |
# events follow agenda display template |
671 |
Event.objects.all().update(publication_date=None) |
|
671 |
Event.objects.all().update(publication_datetime=None)
|
|
672 | 672 |
agenda.event_display_template = '{{ event.label }} - {{ event.start_datetime }}' |
673 | 673 |
agenda.save() |
674 | 674 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
... | ... | |
677 | 677 |
# check querysets |
678 | 678 |
agenda.event_display_template = '' |
679 | 679 |
agenda.save() |
680 |
base_event.publication_date = None |
|
680 |
base_event.publication_datetime = None
|
|
681 | 681 |
base_event.recurrence_end_date = datetime.date.today() + datetime.timedelta(days=365) |
682 | 682 |
base_event.save() |
683 | 683 |
base_event.create_all_recurrences() |
... | ... | |
1356 | 1356 |
assert resp.json['data'][3]['id'] == 'other:1' |
1357 | 1357 |
assert resp.json['data'][3]['text'] == 'Tuesday: Other' |
1358 | 1358 | |
1359 |
event.publication_date = now() + datetime.timedelta(days=2) |
|
1359 |
event.publication_datetime = now() + datetime.timedelta(days=2)
|
|
1360 | 1360 |
event.save() |
1361 | 1361 |
resp = app.get('/api/agenda/%s/recurring-events/' % agenda.slug) |
1362 | 1362 |
assert len(resp.json['data']) == 1 |
tests/api/test_event.py | ||
---|---|---|
224 | 224 |
assert str(event.start_datetime) == '2021-11-15 14:38:00+00:00' |
225 | 225 |
assert str(event.start_datetime.tzinfo) == 'UTC' |
226 | 226 |
assert event.places == 10 |
227 |
assert event.publication_date is None |
|
227 |
assert event.publication_datetime is None
|
|
228 | 228 | |
229 | 229 |
# add with almost all optional managed fields |
230 | 230 |
params = { |
231 | 231 |
'start_datetime': '2021-11-15 15:38', |
232 | 232 |
'duration': 42, |
233 |
'publication_date': '2021-09-20',
|
|
233 |
'publication_datetime': '2021-09-20 10:00',
|
|
234 | 234 |
'places': 11, |
235 | 235 |
'waiting_list_places': 3, |
236 | 236 |
'label': 'FOO camp', |
... | ... | |
252 | 252 |
assert event.description == 'An event' |
253 | 253 |
assert event.pricing == 'free' |
254 | 254 |
assert event.url == 'http://example.org/foo/bar/?' |
255 |
assert str(event.publication_datetime) == '2021-09-20 08:00:00+00:00' |
|
256 |
assert str(event.publication_datetime.tzinfo) == 'UTC' |
|
255 | 257 | |
256 | 258 |
# add with errors in recurrence_days list |
257 | 259 |
params = { |
... | ... | |
389 | 391 |
params = { |
390 | 392 |
'start_datetime': '2021-11-15 15:38', |
391 | 393 |
'duration': 42, |
392 |
'publication_date': '2021-09-20',
|
|
394 |
'publication_datetime': '2021-09-20 12:00',
|
|
393 | 395 |
'places': 8, |
394 | 396 |
'waiting_list_places': 3, |
395 | 397 |
'label': 'FOO camp', |
... | ... | |
407 | 409 |
assert event.description == 'An event' |
408 | 410 |
assert event.pricing == 'free' |
409 | 411 |
assert event.url == 'http://example.org/foo/bar/?' |
412 |
assert str(event.publication_datetime) == '2021-09-20 10:00:00+00:00' |
|
413 |
assert str(event.publication_datetime.tzinfo) == 'UTC' |
|
410 | 414 | |
411 | 415 |
# update event as a recurring event |
412 | 416 |
params = { |
... | ... | |
448 | 452 | |
449 | 453 |
# try to update protected fields of one of the event recurrencies |
450 | 454 |
params = { |
451 |
'publication_date': '2021-11-15',
|
|
455 |
'publication_datetime': '2021-11-15 12:00',
|
|
452 | 456 |
} |
453 | 457 |
resp = app.patch(recurrence_url, params=params, status=400) |
454 | 458 |
assert resp.json['err'] |
tests/manager/test_all.py | ||
---|---|---|
1553 | 1553 |
agenda=agenda, |
1554 | 1554 |
label='event E', |
1555 | 1555 |
start_datetime=now() + datetime.timedelta(days=3), |
1556 |
publication_date=today + datetime.timedelta(days=1),
|
|
1556 |
publication_datetime=now() + datetime.timedelta(days=1),
|
|
1557 | 1557 |
places=42, |
1558 | 1558 |
) |
1559 | 1559 |
# publication date in past |
... | ... | |
1561 | 1561 |
agenda=agenda, |
1562 | 1562 |
label='event F', |
1563 | 1563 |
start_datetime=now() + datetime.timedelta(days=3), |
1564 |
publication_date=today - datetime.timedelta(days=1),
|
|
1564 |
publication_datetime=now() - datetime.timedelta(days=1),
|
|
1565 | 1565 |
places=42, |
1566 | 1566 |
) |
1567 | 1567 |
# weekly recurring event, first recurrence is in the past but second is in range |
... | ... | |
1591 | 1591 |
agenda=agenda, |
1592 | 1592 |
label='event H', |
1593 | 1593 |
start_datetime=now().replace(year=today.year + 2, month=1, day=15), |
1594 |
publication_date=today - datetime.timedelta(days=1),
|
|
1594 |
publication_datetime=now() - datetime.timedelta(days=1),
|
|
1595 | 1595 |
places=42, |
1596 | 1596 |
) |
1597 | 1597 |
start_datetime = localtime(now().replace(year=today.year + 2, month=2, day=1)).replace(hour=0, minute=0) |
... | ... | |
1599 | 1599 |
agenda=agenda, |
1600 | 1600 |
label='event H', |
1601 | 1601 |
start_datetime=start_datetime, |
1602 |
publication_date=today - datetime.timedelta(days=1),
|
|
1602 |
publication_datetime=now() - datetime.timedelta(days=1),
|
|
1603 | 1603 |
places=42, |
1604 | 1604 |
) |
1605 | 1605 |
resp = app.get('/manage/agendas/%s/events/open/' % agenda.pk) |
tests/manager/test_event.py | ||
---|---|---|
33 | 33 |
resp = resp.form.submit() |
34 | 34 |
resp = resp.follow() |
35 | 35 |
event = Event.objects.get(places=10) |
36 |
assert event.publication_date is None |
|
36 |
assert event.publication_datetime is None
|
|
37 | 37 |
assert "This agenda doesn't have any event yet." not in resp.text |
38 | 38 |
assert '/manage/agendas/%s/events/%s/' % (agenda.id, event.id) in resp.text |
39 | 39 |
assert ('Feb. 15, %s, 5 p.m.' % year) in resp.text |
... | ... | |
137 | 137 |
resp = app.get('/manage/agendas/%s/events/%s/edit' % (agenda.pk, event.pk)) |
138 | 138 |
assert resp.form['start_datetime_0'].value == '2016-02-15' |
139 | 139 |
assert resp.form['start_datetime_1'].value == '17:00' |
140 |
assert resp.form['publication_date'].value == '' |
|
140 |
assert resp.form['publication_datetime_0'].value == '' |
|
141 |
assert resp.form['publication_datetime_1'].value == '' |
|
141 | 142 |
assert resp.form['duration'].value == '' |
142 | 143 |
assert resp.form['description'].value == '' |
143 | 144 |
resp.form['start_datetime_0'] = '2016-02-16' |
144 | 145 |
resp.form['start_datetime_1'] = '17:00' |
145 |
resp.form['publication_date'] = '2020-05-11' |
|
146 |
resp.form['publication_datetime_0'] = '2020-05-11' |
|
147 |
resp.form['publication_datetime_1'] = '12:00' |
|
146 | 148 |
resp.form['duration'].value = 45 |
147 | 149 |
resp.form['places'] = 20 |
148 | 150 |
resp.form['description'] = 'A description' |
... | ... | |
153 | 155 |
assert 'Feb. 16, 2016, 5 p.m.' in resp.text |
154 | 156 |
event.refresh_from_db() |
155 | 157 |
assert event.places == 20 |
156 |
assert event.publication_date == datetime.date(2020, 5, 11) |
|
158 |
assert str(event.publication_datetime) == '2020-05-11 10:00:00+00:00' |
|
159 |
assert str(event.publication_datetime.tzinfo) == 'UTC' |
|
157 | 160 |
assert event.duration == 45 |
158 | 161 |
assert event.end_datetime == event.start_datetime + datetime.timedelta(minutes=45) |
159 | 162 |
assert event.description == 'A description' |
... | ... | |
193 | 196 |
start_datetime=make_aware(datetime.datetime(2016, 2, 15, 17, 0)), |
194 | 197 |
places=20, |
195 | 198 |
agenda=agenda, |
196 |
publication_date=datetime.date(2020, 5, 11),
|
|
199 |
publication_datetime=make_aware(datetime.datetime(2020, 5, 11)),
|
|
197 | 200 |
) |
198 | 201 |
app = login(app, username='manager', password='manager') |
199 | 202 |
resp = app.get('/manage/agendas/%s/events/%s/edit' % (agenda.id, event.id), status=403) |
... | ... | |
204 | 207 |
resp = resp.click('Feb. 15, 2016, 5 p.m.') |
205 | 208 |
assert resp.form['start_datetime_0'].value == '2016-02-15' |
206 | 209 |
assert resp.form['start_datetime_1'].value == '17:00' |
207 |
assert resp.form['publication_date'].value == '2020-05-11' |
|
210 |
assert resp.form['publication_datetime_0'].value == '2020-05-11' |
|
211 |
assert resp.form['publication_datetime_1'].value == '00:00' |
|
208 | 212 |
resp.form['start_datetime_0'] = '2016-02-16' |
209 | 213 |
resp.form['start_datetime_1'] = '17:00' |
210 |
resp.form['publication_date'] = '' |
|
214 |
resp.form['publication_datetime_0'] = '' |
|
215 |
resp.form['publication_datetime_1'] = '' |
|
211 | 216 |
resp.form['places'] = 20 |
212 | 217 |
resp = resp.form.submit() |
213 | 218 |
resp = resp.follow() |
214 | 219 |
assert '/manage/agendas/%s/events/%s/edit' % (agenda.id, event.id) in resp.text |
215 | 220 |
assert 'Feb. 16, 2016, 5 p.m.' in resp.text |
216 | 221 |
event.refresh_from_db() |
217 |
assert event.publication_date is None |
|
222 |
assert event.publication_datetime is None
|
|
218 | 223 | |
219 | 224 | |
220 | 225 |
def test_edit_recurring_event(settings, app, admin_user, freezer): |
... | ... | |
301 | 306 |
'recurrence_days', |
302 | 307 |
'recurence_weekly_interval', |
303 | 308 |
'recurrence_end_date', |
304 |
'publication_date', |
|
309 |
'publication_datetime_0', |
|
310 |
'publication_datetime_1', |
|
305 | 311 |
}.isdisjoint(resp.form.fields) |
306 | 312 | |
307 | 313 | |
... | ... | |
537 | 543 |
csv_export = resp.text |
538 | 544 |
assert ( |
539 | 545 |
csv_export |
540 |
== 'date,time,number of places,number of places in waiting list,label,identifier,description,pricing,URL,publication date,duration\r\n' |
|
546 |
== 'date,time,number of places,number of places in waiting list,label,identifier,description,pricing,URL,publication date/time,duration\r\n'
|
|
541 | 547 |
) |
542 | 548 | |
543 | 549 |
resp = app.get('/manage/agendas/%s/import-events' % agenda.id) |
... | ... | |
548 | 554 |
csv_export = resp.text |
549 | 555 |
assert ( |
550 | 556 |
csv_export |
551 |
== 'date,time,number of places,number of places in waiting list,label,identifier,description,pricing,URL,publication date,duration\r\n' |
|
557 |
== 'date,time,number of places,number of places in waiting list,label,identifier,description,pricing,URL,publication date/time,duration\r\n'
|
|
552 | 558 |
'2016-09-16,00:30,10,0,,foo-bar-event,,,,,\r\n' |
553 | 559 |
) |
554 | 560 | |
555 | 561 |
resp = app.get('/manage/agendas/%s/import-events' % agenda.id) |
556 | 562 |
resp.form['events_csv_file'] = Upload( |
557 | 563 |
't.csv', |
558 |
b'2016-09-16,23:30,10,5,label,slug,"description\nfoobar",pricing,url,2016-10-16,90', |
|
564 |
b'2016-09-16,23:30,10,5,label,slug,"description\nfoobar",pricing,url,2016-10-16 00:00,90',
|
|
559 | 565 |
'text/csv', |
560 | 566 |
) |
561 | 567 |
resp.form.submit(status=302) |
... | ... | |
563 | 569 |
csv_export = resp.text |
564 | 570 |
assert ( |
565 | 571 |
csv_export |
566 |
== 'date,time,number of places,number of places in waiting list,label,identifier,description,pricing,URL,publication date,duration\r\n' |
|
572 |
== 'date,time,number of places,number of places in waiting list,label,identifier,description,pricing,URL,publication date/time,duration\r\n'
|
|
567 | 573 |
'2016-09-16,00:30,10,0,,foo-bar-event,,,,,\r\n' |
568 |
'2016-09-16,23:30,10,5,label,slug,"description\nfoobar",pricing,url,2016-10-16,90\r\n' |
|
574 |
'2016-09-16,23:30,10,5,label,slug,"description\nfoobar",pricing,url,2016-10-16 00:00,90\r\n'
|
|
569 | 575 |
) |
570 | 576 | |
571 | 577 | |
... | ... | |
738 | 744 |
assert event.description == '' |
739 | 745 |
assert event.pricing == '' |
740 | 746 |
assert event.url == '' |
741 |
assert event.publication_date is None |
|
747 |
assert event.publication_datetime is None
|
|
742 | 748 |
assert event.duration is None |
743 | 749 |
Event.objects.all().delete() |
744 | 750 |
resp = app.get('/manage/agendas/%s/import-events' % agenda.id, status=200) |
... | ... | |
753 | 759 |
assert event.description == 'description\nfoobar' |
754 | 760 |
assert event.pricing == 'pricing' |
755 | 761 |
assert event.url == 'url' |
756 |
assert event.publication_date == datetime.date(2016, 10, 16) |
|
762 |
assert str(event.publication_datetime) == '2016-10-15 22:00:00+00:00' |
|
763 |
assert str(event.publication_datetime.tzinfo) == 'UTC' |
|
764 |
assert event.duration == 90 |
|
765 |
Event.objects.all().delete() |
|
766 |
resp = app.get('/manage/agendas/%s/import-events' % agenda.id, status=200) |
|
767 |
resp.form['events_csv_file'] = Upload( |
|
768 |
't.csv', |
|
769 |
b'2016-09-16,18:00,10,5,label,slug,"description\nfoobar",pricing,url,2016-10-16 10:00,90', |
|
770 |
'text/csv', |
|
771 |
) |
|
772 |
resp = resp.form.submit(status=302) |
|
773 |
assert Event.objects.count() == 1 |
|
774 |
event = Event.objects.get() |
|
775 |
assert event.description == 'description\nfoobar' |
|
776 |
assert event.pricing == 'pricing' |
|
777 |
assert event.url == 'url' |
|
778 |
assert str(event.publication_datetime) == '2016-10-16 08:00:00+00:00' |
|
779 |
assert str(event.publication_datetime.tzinfo) == 'UTC' |
|
757 | 780 |
assert event.duration == 90 |
758 | 781 | |
759 |
# publication date bad format |
|
782 |
# publication date/time bad format
|
|
760 | 783 |
resp = app.get('/manage/agendas/%s/import-events' % agenda.id, status=200) |
761 | 784 |
resp.form['events_csv_file'] = Upload( |
762 | 785 |
't.csv', b'2016-09-16,18:00,10,5,label,slug,description,pricing,url,foobar', 'text/csv' |
763 | 786 |
) |
764 | 787 |
resp = resp.form.submit(status=200) |
765 |
assert 'Invalid file format. (date format' in resp.text |
|
788 |
assert 'Invalid file format. (date/time format' in resp.text
|
|
766 | 789 | |
767 | 790 |
# duration bad format |
768 | 791 |
resp = app.get('/manage/agendas/%s/import-events' % agenda.id, status=200) |
tests/test_agendas.py | ||
---|---|---|
446 | 446 |
[ |
447 | 447 |
# no delay |
448 | 448 |
(10, 0, 0, 0, None, True), |
449 |
# test publication_date |
|
449 |
# test publication_datetime
|
|
450 | 450 |
(10, 0, 0, 0, 1, False), |
451 | 451 |
(10, 0, 0, 0, 0, True), |
452 | 452 |
# test min and max delays |
... | ... | |
464 | 464 |
) |
465 | 465 |
event = Event.objects.create( |
466 | 466 |
start_datetime=localtime() + datetime.timedelta(days=start_days, minutes=start_minutes), |
467 |
publication_date=(localtime().date() + datetime.timedelta(days=pub_days)) if pub_days else None,
|
|
467 |
publication_datetime=(localtime() + datetime.timedelta(days=pub_days)) if pub_days else None,
|
|
468 | 468 |
places=10, |
469 | 469 |
agenda=agenda, |
470 | 470 |
) |
tests/test_import_export.py | ||
---|---|---|
183 | 183 |
description='description', |
184 | 184 |
pricing='100', |
185 | 185 |
url='https://example.net/', |
186 |
publication_date=datetime.date(2020, 5, 11),
|
|
186 |
publication_datetime=make_aware(datetime.datetime(2020, 5, 11)),
|
|
187 | 187 |
places=42, |
188 | 188 |
start_datetime=now(), |
189 | 189 |
duration=30, |
... | ... | |
214 | 214 |
assert first_imported_event.description == 'description' |
215 | 215 |
assert first_imported_event.pricing == '100' |
216 | 216 |
assert first_imported_event.url == 'https://example.net/' |
217 |
assert first_imported_event.publication_date == datetime.date(2020, 5, 11) |
|
217 |
assert str(first_imported_event.publication_datetime) == '2020-05-10 22:00:00+00:00' |
|
218 |
assert str(first_imported_event.publication_datetime.tzinfo) == 'UTC' |
|
218 | 219 |
assert first_imported_event.duration == 30 |
219 | 220 |
assert Agenda.objects.get(label='Foo Bar 2').event_set.first().slug == 'event' |
220 | 221 | |
221 |
- |