agendas: stop adding event recurrences on the fly (#62635)

This commit is contained in:
Valentin Deniaud 2022-03-16 15:13:14 +01:00
parent ba38629af3
commit 11fa0802ec
11 changed files with 205 additions and 381 deletions

View File

@ -711,8 +711,8 @@ class Agenda(models.Model):
else:
# recurring events are never opened
entries = self.event_set.filter(recurrence_days__isnull=True)
# exclude canceled events except for event recurrences
entries = entries.filter(Q(cancelled=False) | Q(primary_event__isnull=False))
# exclude canceled events
entries = entries.filter(cancelled=False)
# we never want to allow booking for past events.
entries = entries.filter(start_datetime__gte=localtime(now()))
# exclude non published events
@ -743,25 +743,6 @@ class Agenda(models.Model):
if user_external_id and not prefetched_queryset:
entries = Event.annotate_queryset_for_user(entries, user_external_id)
if max_start:
min_start = max(min_start or localtime(now()), localtime(now()))
entries = self.add_event_recurrences(
entries,
min_start,
max_start,
include_full=include_full,
prefetched_queryset=prefetched_queryset,
)
if show_only_subscribed:
filtered_entries = []
for e in entries:
e_start_date = localtime(e.start_datetime).date()
for s in self.prefetched_subscriptions:
if s.date_start <= e_start_date < s.date_end:
filtered_entries.append(e)
break
entries = filtered_entries
return entries
def get_past_events(
@ -781,8 +762,8 @@ class Agenda(models.Model):
else:
# no recurring events
entries = self.event_set.filter(recurrence_days__isnull=True)
# exclude canceled events except for event recurrences
entries = entries.filter(Q(cancelled=False) | Q(primary_event__isnull=False))
# exclude canceled events
entries = entries.filter(cancelled=False)
# we want only past events
entries = entries.filter(start_datetime__lt=localtime(now()))
@ -795,23 +776,6 @@ class Agenda(models.Model):
if user_external_id:
entries = Event.annotate_queryset_for_user(entries, user_external_id)
if min_start:
entries = self.add_event_recurrences(
entries,
min_start,
min(max_start or localtime(now()), localtime(now())),
prefetched_queryset=prefetched_queryset,
)
if show_only_subscribed:
filtered_entries = []
for e in entries:
e_start_date = localtime(e.start_datetime).date()
for s in self.prefetched_subscriptions:
if s.date_start <= e_start_date < s.date_end:
filtered_entries.append(e)
break
entries = filtered_entries
return entries
def get_open_recurring_events(self):
@ -821,52 +785,6 @@ class Agenda(models.Model):
if e.recurrence_end_date and e.recurrence_end_date > localtime(now()).date()
]
def add_event_recurrences(
self,
events,
min_start,
max_start,
include_full=True,
include_cancelled=False,
prefetched_queryset=False,
):
excluded_datetimes = collections.defaultdict(list)
for event in events:
if event.primary_event_id:
excluded_datetimes[event.primary_event_id].append(event.datetime_slug)
events = [
e for e in events if (not e.cancelled or include_cancelled) and (not e.full or include_full)
]
if prefetched_queryset:
recurring_events = self.prefetched_recurring_events
exceptions = self.prefetched_exceptions
else:
recurring_events = self.event_set.filter(
Q(publication_datetime__isnull=True) | Q(publication_datetime__lte=now()),
recurrence_days__isnull=False,
)
exceptions = self.get_recurrence_exceptions(min_start, max_start)
for event in recurring_events:
events.extend(
event.get_recurrences(
min_start,
max_start,
excluded_datetimes.get(event.pk),
exceptions,
slug_separator=':',
shared_custody_rules=getattr(self, 'prefetched_custody_rules', None),
shared_custody_periods=getattr(self, 'prefetched_custody_periods', None),
)
)
events.sort(
key=lambda x: [(getattr(x, field) is None, getattr(x, field)) for field in Event._meta.ordering]
)
return events
@transaction.atomic
def update_event_recurrences(self):
recurring_events = self.event_set.filter(recurrence_days__isnull=False)
@ -1843,7 +1761,6 @@ class Event(models.Model):
max_datetime,
excluded_datetimes=None,
exceptions=None,
slug_separator='--',
shared_custody_rules=None,
shared_custody_periods=None,
):
@ -1915,9 +1832,8 @@ class Event(models.Model):
event = copy.copy(event_base)
# add timezone back
aware_start_datetime = make_aware(start_datetime)
event.slug = '%s%s%s' % (
event.slug = '%s--%s' % (
event.slug,
slug_separator,
aware_start_datetime.strftime('%Y-%m-%d-%H%M'),
)
event.start_datetime = aware_start_datetime.astimezone(utc)

View File

@ -502,17 +502,9 @@ def get_event_detail(
}
)
else:
if not event.pk and ':' in event.slug:
backoffice_url = request.build_absolute_uri(
reverse(
'chrono-manager-event-create-recurrence',
kwargs={'pk': agenda.pk, 'event_identifier': event.slug},
)
)
else:
backoffice_url = request.build_absolute_uri(
reverse('chrono-manager-event-view', kwargs={'pk': agenda.pk, 'event_pk': event.pk})
)
backoffice_url = request.build_absolute_uri(
reverse('chrono-manager-event-view', kwargs={'pk': agenda.pk, 'event_pk': event.pk})
)
details.update(
{
'disabled': is_event_disabled(

View File

@ -504,16 +504,16 @@ class EventsTimesheetForm(forms.Form):
max_start = max_start + datetime.timedelta(days=1)
# fetch all events in this range
events_qs = (
all_events = (
self.agenda.event_set.filter(
recurrence_days__isnull=True,
start_datetime__gte=min_start,
start_datetime__lt=max_start,
cancelled=False,
)
.select_related('primary_event')
.order_by('start_datetime', 'label')
)
all_events = self.agenda.add_event_recurrences(events_qs, min_start, max_start)
dates = set()
events = []
dates_per_event_id = defaultdict(list)

View File

@ -1183,16 +1183,6 @@ class AgendaDayView(AgendaDateView, DayArchiveView):
return qs
return qs.order_by('start_datetime', 'label')
def get_dated_items(self):
date_list, object_list, extra_context = super().get_dated_items()
if self.agenda.kind == 'events':
min_start = make_aware(datetime.datetime.combine(self.date.date(), datetime.time(0, 0)))
max_start = min_start + datetime.timedelta(days=1)
object_list = self.agenda.add_event_recurrences(
object_list, min_start, max_start, include_cancelled=True
)
return date_list, object_list, extra_context
def get_template_names(self):
if self.agenda.kind == 'virtual':
return ['chrono/manager_meetings_agenda_day_view.html']
@ -1325,9 +1315,6 @@ class AgendaMonthView(AgendaDateView, MonthArchiveView):
max_start = make_aware(
datetime.datetime.combine(extra_context['next_month'], datetime.time(0, 0))
)
object_list = self.agenda.add_event_recurrences(
object_list, min_start, max_start, include_cancelled=True
)
exceptions = TimePeriodException.objects.filter(
desk__agenda=self.agenda, start_datetime__gte=min_start, end_datetime__lt=max_start
).annotate(is_exception=Value(True, BooleanField()))

View File

@ -271,12 +271,15 @@ def test_agendas_api(app):
assert len(resp.json['data']) == 0
# event recurrences are available
Event.objects.create(
event = Event.objects.create(
start_datetime=now(),
places=10,
agenda=event_agenda,
recurrence_days=list(range(7)),
recurrence_end_date=now() + datetime.timedelta(days=15),
)
event.create_all_recurrences()
assert len(event_agenda.get_open_events()) == 2
resp = app.get('/api/agenda/', params={'with_open_events': '1'})
assert len(resp.json['data']) == 1
@ -284,9 +287,14 @@ def test_agendas_api(app):
for _ in range(10):
event_agenda = Agenda.objects.create(label='Foo bar', category=category_a)
Desk.objects.create(agenda=event_agenda, slug='_exceptions_holder')
Event.objects.create(
start_datetime=now(), places=10, agenda=event_agenda, recurrence_days=[now().weekday()]
event = Event.objects.create(
start_datetime=now(),
places=10,
agenda=event_agenda,
recurrence_days=[now().weekday()],
recurrence_end_date=now() + datetime.timedelta(days=15),
)
event.create_all_recurrences()
TimePeriodException.objects.create(
desk=event_agenda.desk_set.get(),
start_datetime=now(),

View File

@ -188,29 +188,6 @@ def test_datetime_api_backoffice_url(app, admin_user):
assert urlparse.urlparse(url).path == '/manage/agendas/%s/events/%s/' % (agenda.pk, event.pk)
assert event.label in app.get(url).text
event.delete()
# recurring event
Event.objects.create(
label='Example Event',
start_datetime=now() + datetime.timedelta(days=5),
recurrence_days=list(range(7)),
places=5,
agenda=agenda,
)
assert Event.objects.count() == 1
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
url = resp.json['data'][0]['api']['backoffice_url']
assert urlparse.urlparse(url).path.startswith(
'/manage/agendas/%s/create_event_recurrence/%s:'
% (
agenda.pk,
event.slug,
)
)
assert event.label in app.get(url).follow().text
assert Event.objects.count() == 2
def test_datetime_api_min_places(app):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
@ -268,15 +245,17 @@ def test_datetimes_api_exclude_slots(app):
slug='recurrent',
start_datetime=start_datetime,
recurrence_days=[start_datetime.weekday()],
recurrence_end_date=start_datetime + datetime.timedelta(days=15),
places=2,
agenda=agenda,
)
event.create_all_recurrences()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert resp.json['data'][0]['id'] == 'recurrent:2021-02-23-1200'
assert resp.json['data'][0]['id'] == 'recurrent--2021-02-23-1200'
assert resp.json['data'][0]['places']['full'] is False
assert resp.json['data'][0]['disabled'] is False
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'exclude_user_external_id': '42'})
assert resp.json['data'][0]['id'] == 'recurrent:2021-02-23-1200'
assert resp.json['data'][0]['id'] == 'recurrent--2021-02-23-1200'
assert resp.json['data'][0]['places']['full'] is False
assert resp.json['data'][0]['disabled'] is False
@ -350,9 +329,11 @@ def test_datetimes_api_user_external_id(app):
slug='recurrent',
start_datetime=start_datetime,
recurrence_days=[start_datetime.weekday()],
recurrence_end_date=start_datetime + datetime.timedelta(days=15),
places=2,
agenda=agenda,
)
event.create_all_recurrences()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert 'booked_for_external_user' not in resp.json['data'][0]
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'user_external_id': '42'})
@ -638,14 +619,16 @@ def test_datetimes_api_meta(app, freezer):
# recurring event
Event.objects.all().delete()
Event.objects.create(
event = Event.objects.create(
slug='abc',
label='Test',
start_datetime=localtime(),
recurrence_days=[localtime().weekday()],
recurrence_end_date=localtime() + datetime.timedelta(days=15),
places=5,
agenda=agenda,
)
event.create_all_recurrences()
resp = app.get(api_url)
assert resp.json['meta']['first_bookable_slot']['text'] == 'Test (May 27, 2017, 1:12 a.m.)'
@ -660,18 +643,20 @@ def test_recurring_events_api(app, user, freezer):
label="Rock'n roll",
start_datetime=localtime(),
recurrence_days=[localtime().weekday()],
recurrence_end_date=localtime() + datetime.timedelta(days=30),
places=5,
agenda=agenda,
)
base_event.create_all_recurrences()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
data = resp.json['data']
assert len(data) == 4
assert data[0]['id'] == 'abc:2021-01-19-1305'
assert data[0]['id'] == 'abc--2021-01-19-1305'
assert data[0]['datetime'] == '2021-01-19 13:05:00'
assert data[0]['text'] == "Rock'n roll (Jan. 19, 2021, 1:05 p.m.)"
assert data[3]['id'] == 'abc:2021-02-09-1305'
assert Event.objects.count() == 1
assert data[3]['id'] == 'abc--2021-02-09-1305'
assert Event.objects.count() == 6
fillslot_url = data[0]['api']['fillslot_url']
app.authorization = ('Basic', ('john.doe', 'password'))
@ -679,74 +664,36 @@ def test_recurring_events_api(app, user, freezer):
# book first event
resp = app.post(fillslot_url)
assert resp.json['err'] == 0
assert Event.objects.count() == 2
event = Booking.objects.get(pk=resp.json['booking_id']).event
assert event.slug == 'abc--2021-01-19-1305'
# first event is now a real event in datetimes
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
data = resp.json['data']
assert len(data) == 4
assert data[0]['id'] == event.slug
new_fillslot_url = data[0]['api']['fillslot_url']
# booking again with both old and new urls works
resp = app.post(fillslot_url)
assert resp.json['err'] == 0
resp = app.post(new_fillslot_url)
assert resp.json['err'] == 0
assert Event.objects.count() == 2
assert event.booking_set.count() == 3
# status and bookings api also create a real event
status_url = data[1]['api']['status_url']
resp = app.get(status_url)
assert resp.json['places']['total'] == 5
assert Event.objects.count() == 3
bookings_url = data[2]['api']['bookings_url']
resp = app.get(bookings_url, params={'user_external_id': '42'})
assert resp.json['data'] == []
assert Event.objects.count() == 4
# cancelled recurrences do not appear
event.cancel()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['id'] == 'abc--2021-01-26-1305'
# publication date is accounted for
Event.objects.filter(primary_event=base_event).delete()
base_event.publication_datetime = now().replace(day=27)
base_event.save()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(resp.json['data']) == 0
# check querysets
with CaptureQueriesContext(connection) as ctx:
app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(ctx.captured_queries) == 3
# events follow agenda display template
Event.objects.all().update(publication_datetime=None)
agenda.event_display_template = '{{ event.label }} - {{ event.start_datetime }}'
agenda.save()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert resp.json['data'][0]['text'] == "Rock'n roll - Jan. 19, 2021, 1:05 p.m."
# check querysets
agenda.event_display_template = ''
agenda.save()
base_event.publication_datetime = None
base_event.recurrence_end_date = datetime.date.today() + datetime.timedelta(days=365)
base_event.save()
base_event.create_all_recurrences()
with CaptureQueriesContext(connection) as ctx:
app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(ctx.captured_queries) == 5
assert resp.json['data'][0]['text'] == "Rock'n roll - Jan. 26, 2021, 1:05 p.m."
# check delays
base_event.recurrence_end_date += datetime.timedelta(days=30)
base_event.save()
agenda.update_event_recurrences()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(resp.json['data']) == 4
assert [e['disabled'] for e in resp.json['data']] == [False] * 4
assert len(resp.json['data']) == 3
assert [e['disabled'] for e in resp.json['data']] == [False] * 3
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'bypass_delays': True})
assert len(resp.json['data']) == 53
assert [e['disabled'] for e in resp.json['data']] == [False] * 53
assert len(resp.json['data']) == 8
assert [e['disabled'] for e in resp.json['data']] == [False] * 8
agenda.minimal_booking_delay = 10
agenda.mmaximal_booking_delay = 20
agenda.save()
@ -754,8 +701,8 @@ def test_recurring_events_api(app, user, freezer):
assert len(resp.json['data']) == 3
assert [e['disabled'] for e in resp.json['data']] == [False] * 3
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'bypass_delays': True})
assert len(resp.json['data']) == 53
assert [e['disabled'] for e in resp.json['data']] == [False] * 53
assert len(resp.json['data']) == 8
assert [e['disabled'] for e in resp.json['data']] == [False] * 8
def test_recurring_events_api_various_times(app, user, mock_now):
@ -766,10 +713,11 @@ def test_recurring_events_api_various_times(app, user, mock_now):
slug='abc',
start_datetime=localtime(),
recurrence_days=[localtime().weekday()],
recurrence_end_date=localtime() + datetime.timedelta(days=30),
places=5,
agenda=agenda,
)
event.refresh_from_db()
event.create_all_recurrences()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(resp.json['data']) == 5
@ -809,13 +757,15 @@ def test_recurring_events_api_exceptions(app, user, freezer):
label='Foo bar', kind='events', minimal_booking_delay=1, maximal_booking_delay=30
)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
Event.objects.create(
event = Event.objects.create(
slug='abc',
start_datetime=localtime(),
recurrence_days=[localtime().weekday()],
recurrence_end_date=localtime() + datetime.timedelta(days=30),
places=5,
agenda=agenda,
)
event.create_all_recurrences()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
data = resp.json['data']
@ -827,6 +777,7 @@ def test_recurring_events_api_exceptions(app, user, freezer):
start_datetime=datetime.date(year=2021, month=1, day=18),
end_datetime=datetime.date(year=2021, month=1, day=20),
)
agenda.update_event_recurrences()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['datetime'] == '2021-01-26 13:05:00'
@ -1266,9 +1217,11 @@ def test_past_datetimes_recurring_event(app, user):
label='Recurring',
start_datetime=start_datetime,
recurrence_days=[start_datetime.weekday()],
recurrence_end_date=start_datetime + datetime.timedelta(days=60),
places=5,
agenda=agenda,
)
event.create_all_recurrences()
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'future'})
data = resp.json['data']
@ -1280,31 +1233,20 @@ def test_past_datetimes_recurring_event(app, user):
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'past'})
data = resp.json['data']
assert len(data) == 0 # no date_start, not possible to compute recurring events in past
resp = app.get(
'/api/agenda/%s/datetimes/' % agenda.slug,
params={'events': 'past', 'date_start': localtime(now() - datetime.timedelta(days=6 * 7))},
)
data = resp.json['data']
assert len(data) == 4
assert data[0]['disabled'] is False
assert data[1]['disabled'] is False
assert data[2]['disabled'] is False
assert data[3]['disabled'] is False
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'all'})
data = resp.json['data']
assert len(data) == 4 # no date_start, not possible to compute recurring events in past
assert data[0]['disabled'] is False
assert data[1]['disabled'] is False
assert data[2]['disabled'] is False
assert data[3]['disabled'] is False
# same result with explicit date_start
resp = app.get(
'/api/agenda/%s/datetimes/' % agenda.slug,
params={'events': 'all', 'date_start': localtime(now() - datetime.timedelta(days=6 * 7))},
params={'events': 'past', 'date_start': localtime(now() - datetime.timedelta(days=6 * 7))},
)
assert resp.json['data'] == data
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug, params={'events': 'all'})
data = resp.json['data']
assert len(data) == 8
assert data[0]['disabled'] is False
@ -1316,6 +1258,14 @@ def test_past_datetimes_recurring_event(app, user):
assert data[6]['disabled'] is False
assert data[7]['disabled'] is False
# same result with explicit date_start
resp = app.get(
'/api/agenda/%s/datetimes/' % agenda.slug,
params={'events': 'all', 'date_start': localtime(now() - datetime.timedelta(days=6 * 7))},
)
assert resp.json['data'] == data
# same result with explicit date_start and date_end
resp = app.get(
'/api/agenda/%s/datetimes/' % agenda.slug,
params={
@ -1324,16 +1274,7 @@ def test_past_datetimes_recurring_event(app, user):
'date_end': localtime(now() + datetime.timedelta(days=6 * 7)),
},
)
data = resp.json['data']
assert len(data) == 8
assert data[0]['disabled'] is False
assert data[1]['disabled'] is False
assert data[2]['disabled'] is False
assert data[3]['disabled'] is False
assert data[4]['disabled'] is False
assert data[5]['disabled'] is False
assert data[6]['disabled'] is False
assert data[7]['disabled'] is False
assert resp.json['data'] == data
# check user_external_id
first_recurrence = event.get_or_create_event_recurrence(event.start_datetime)
@ -1668,14 +1609,15 @@ def test_datetimes_multiple_agendas(app):
places=5,
agenda=first_agenda,
)
Event.objects.create( # base recurring event not visible in datetimes api
event = Event.objects.create( # base recurring event not visible in datetimes api
slug='recurring',
start_datetime=now() + datetime.timedelta(hours=1),
recurrence_days=[localtime().weekday()],
recurrence_end_date=now() + datetime.timedelta(days=15),
places=5,
agenda=first_agenda,
) # recurrences do not exist in DB
)
event.create_all_recurrences()
second_agenda = Agenda.objects.create(
label='Second agenda', kind='events', minimal_booking_delay=0, maximal_booking_delay=45
)
@ -1691,7 +1633,7 @@ def test_datetimes_multiple_agendas(app):
agenda_slugs = '%s,%s' % (first_agenda.slug, second_agenda.slug)
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs})
assert len(resp.json['data']) == 5
assert resp.json['data'][0]['id'] == 'first-agenda@recurring:2021-05-06-1700'
assert resp.json['data'][0]['id'] == 'first-agenda@recurring--2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'first-agenda@event'
assert resp.json['data'][1]['text'] == 'May 11, 2021, 4 p.m.'
assert resp.json['data'][1]['places']['available'] == 5
@ -1700,8 +1642,8 @@ def test_datetimes_multiple_agendas(app):
assert resp.json['data'][2]['text'] == 'May 12, 2021, 4 p.m.'
assert resp.json['data'][2]['places']['available'] == 4
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700'
assert resp.json['data'][4]['id'] == 'first-agenda@recurring:2021-05-20-1700'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring--2021-05-13-1700'
assert resp.json['data'][4]['id'] == 'first-agenda@recurring--2021-05-20-1700'
# check user_external_id
Booking.objects.create(event=event, user_external_id='user')
@ -1740,14 +1682,14 @@ def test_datetimes_multiple_agendas(app):
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'date_start': date_start})
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['id'] == 'second-agenda@event'
assert resp.json['data'][1]['id'] == 'first-agenda@recurring:2021-05-13-1700'
assert resp.json['data'][2]['id'] == 'first-agenda@recurring:2021-05-20-1700'
assert resp.json['data'][1]['id'] == 'first-agenda@recurring--2021-05-13-1700'
assert resp.json['data'][2]['id'] == 'first-agenda@recurring--2021-05-20-1700'
# check date_end
date_end = localtime() + datetime.timedelta(days=5, hours=1)
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'date_end': date_end})
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == 'first-agenda@recurring:2021-05-06-1700'
assert resp.json['data'][0]['id'] == 'first-agenda@recurring--2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'first-agenda@event'
resp = app.get(
@ -1763,17 +1705,17 @@ def test_datetimes_multiple_agendas(app):
assert len(resp.json['data']) == 2
assert [d['disabled'] for d in resp.json['data']] == [False, False]
assert resp.json['data'][0]['id'] == 'second-agenda@event'
assert resp.json['data'][1]['id'] == 'first-agenda@recurring:2021-05-13-1700'
assert resp.json['data'][1]['id'] == 'first-agenda@recurring--2021-05-13-1700'
resp = app.get(
'/api/agendas/datetimes/',
params={'agendas': agenda_slugs, 'date_end': date_end, 'bypass_delays': True},
)
assert len(resp.json['data']) == 5
assert resp.json['data'][0]['id'] == 'first-agenda@recurring:2021-05-06-1700'
assert resp.json['data'][0]['id'] == 'first-agenda@recurring--2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'first-agenda@event'
assert resp.json['data'][2]['id'] == 'second-agenda@event'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700'
assert resp.json['data'][4]['id'] == 'first-agenda@recurring:2021-05-20-1700'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring--2021-05-13-1700'
assert resp.json['data'][4]['id'] == 'first-agenda@recurring--2021-05-20-1700'
assert [d['disabled'] for d in resp.json['data']] == [False, False, False, False, False]
Agenda.objects.update(minimal_booking_delay=0, maximal_booking_delay=45)
@ -1791,21 +1733,21 @@ def test_datetimes_multiple_agendas(app):
# it's possible to show past events
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'show_past_events': True})
assert len(resp.json['data']) == 5
assert resp.json['data'][0]['id'] == 'first-agenda@recurring:2021-05-06-1700'
assert resp.json['data'][0]['id'] == 'first-agenda@recurring--2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'first-agenda@event'
assert resp.json['data'][2]['id'] == 'second-agenda@event'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700'
assert resp.json['data'][4]['id'] == 'first-agenda@recurring:2021-05-20-1700'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring--2021-05-13-1700'
assert resp.json['data'][4]['id'] == 'first-agenda@recurring--2021-05-20-1700'
assert [d['disabled'] for d in resp.json['data']] == [False, False, False, False, False]
# and events out of minimal_booking_delay
Agenda.objects.update(minimal_booking_delay=6, maximal_booking_delay=14)
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'show_past_events': True})
assert len(resp.json['data']) == 4
assert resp.json['data'][0]['id'] == 'first-agenda@recurring:2021-05-06-1700'
assert resp.json['data'][0]['id'] == 'first-agenda@recurring--2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'first-agenda@event'
assert resp.json['data'][2]['id'] == 'second-agenda@event'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring:2021-05-13-1700'
assert resp.json['data'][3]['id'] == 'first-agenda@recurring--2021-05-13-1700'
assert [d['disabled'] for d in resp.json['data']] == [True, True, False, False]
Agenda.objects.update(minimal_booking_delay=0, maximal_booking_delay=45)
@ -1815,26 +1757,29 @@ def test_datetimes_multiple_agendas(app):
places=5,
agenda=first_agenda,
)
Event.objects.create( # base recurrring event not visible in datetimes api
event = Event.objects.create( # base recurrring event not visible in datetimes api
slug='recurring-in-past',
start_datetime=now() - datetime.timedelta(days=15, hours=1),
recurrence_days=[localtime().weekday()],
recurrence_end_date=now(),
places=5,
agenda=first_agenda,
) # recurrences do not exist in DB
)
event.create_all_recurrences()
resp = app.get('/api/agendas/datetimes/', params={'agendas': agenda_slugs, 'show_past_events': True})
assert len(resp.json['data']) == 6
assert len(resp.json['data']) == 8
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@recurring-in-past--2021-04-22-1500',
'first-agenda@recurring-in-past--2021-04-29-1500',
'first-agenda@event-in-past',
'first-agenda@recurring:2021-05-06-1700',
'first-agenda@recurring--2021-05-06-1700',
'first-agenda@event',
'second-agenda@event',
'first-agenda@recurring:2021-05-13-1700',
'first-agenda@recurring:2021-05-20-1700',
'first-agenda@recurring--2021-05-13-1700',
'first-agenda@recurring--2021-05-20-1700',
]
assert [d['disabled'] for d in resp.json['data']] == [True, False, False, False, False, False]
assert [d['disabled'] for d in resp.json['data']] == [True, True, True, False, False, False, False, False]
date_start = localtime() - datetime.timedelta(days=10)
resp = app.get(
@ -1843,13 +1788,13 @@ def test_datetimes_multiple_agendas(app):
)
assert len(resp.json['data']) == 7
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@recurring-in-past:2021-04-29-1500',
'first-agenda@recurring-in-past--2021-04-29-1500',
'first-agenda@event-in-past',
'first-agenda@recurring:2021-05-06-1700',
'first-agenda@recurring--2021-05-06-1700',
'first-agenda@event',
'second-agenda@event',
'first-agenda@recurring:2021-05-13-1700',
'first-agenda@recurring:2021-05-20-1700',
'first-agenda@recurring--2021-05-13-1700',
'first-agenda@recurring--2021-05-20-1700',
]
date_start = localtime() - datetime.timedelta(days=4)
resp = app.get(
@ -1858,11 +1803,11 @@ def test_datetimes_multiple_agendas(app):
)
assert len(resp.json['data']) == 5
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@recurring:2021-05-06-1700',
'first-agenda@recurring--2021-05-06-1700',
'first-agenda@event',
'second-agenda@event',
'first-agenda@recurring:2021-05-13-1700',
'first-agenda@recurring:2021-05-20-1700',
'first-agenda@recurring--2021-05-13-1700',
'first-agenda@recurring--2021-05-20-1700',
]
date_start = localtime() - datetime.timedelta(days=30) # with a date start to have past recurring events
@ -1878,10 +1823,10 @@ def test_datetimes_multiple_agendas(app):
)
assert len(resp.json['data']) == 5
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@recurring-in-past:2021-04-22-1500',
'first-agenda@recurring-in-past:2021-04-29-1500',
'first-agenda@recurring-in-past--2021-04-22-1500',
'first-agenda@recurring-in-past--2021-04-29-1500',
'first-agenda@event-in-past',
'first-agenda@recurring:2021-05-06-1700',
'first-agenda@recurring--2021-05-06-1700',
'first-agenda@event',
]
@ -1897,7 +1842,7 @@ def test_datetimes_multiple_agendas(app):
)
assert len(resp.json['data']) == 1
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@recurring-in-past:2021-04-22-1500',
'first-agenda@recurring-in-past--2021-04-22-1500',
]
date_end = localtime() - datetime.timedelta(days=5)
@ -1912,8 +1857,8 @@ def test_datetimes_multiple_agendas(app):
)
assert len(resp.json['data']) == 2
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@recurring-in-past:2021-04-22-1500',
'first-agenda@recurring-in-past:2021-04-29-1500',
'first-agenda@recurring-in-past--2021-04-22-1500',
'first-agenda@recurring-in-past--2021-04-29-1500',
]
@ -2207,6 +2152,7 @@ def test_datetimes_multiple_agendas_recurring_subscribed_dates(app):
places=5,
agenda=agenda,
)
event.create_all_recurrences()
resp = app.get('/api/agendas/datetimes/', params={'subscribed': 'all', 'user_external_id': 'xxx'})
assert len(resp.json['data']) == 0
@ -2219,8 +2165,8 @@ def test_datetimes_multiple_agendas_recurring_subscribed_dates(app):
resp = app.get('/api/agendas/datetimes/', params={'subscribed': 'all', 'user_external_id': 'xxx'})
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == 'agenda@recurring:2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring:2021-05-13-1700'
assert resp.json['data'][0]['id'] == 'agenda@recurring--2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring--2021-05-13-1700'
resp = app.get(
'/api/agendas/datetimes/',
@ -2236,9 +2182,10 @@ def test_datetimes_multiple_agendas_recurring_subscribed_dates(app):
'/api/agendas/datetimes/',
params={'subscribed': 'all', 'user_external_id': 'xxx', 'show_past_events': True},
)
assert len(resp.json['data']) == 2 # no start_date
assert resp.json['data'][0]['id'] == 'agenda@recurring:2021-05-06-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring:2021-05-13-1700'
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['id'] == 'agenda@recurring--2021-04-29-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring--2021-05-06-1700'
assert resp.json['data'][2]['id'] == 'agenda@recurring--2021-05-13-1700'
resp = app.get(
'/api/agendas/datetimes/',
@ -2250,9 +2197,9 @@ def test_datetimes_multiple_agendas_recurring_subscribed_dates(app):
},
)
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['id'] == 'agenda@recurring:2021-04-29-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring:2021-05-06-1700'
assert resp.json['data'][2]['id'] == 'agenda@recurring:2021-05-13-1700'
assert resp.json['data'][0]['id'] == 'agenda@recurring--2021-04-29-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring--2021-05-06-1700'
assert resp.json['data'][2]['id'] == 'agenda@recurring--2021-05-13-1700'
# date_start before subscription's period,
# date_end after subscription's period
@ -2267,9 +2214,9 @@ def test_datetimes_multiple_agendas_recurring_subscribed_dates(app):
},
)
assert len(resp.json['data']) == 3
assert resp.json['data'][0]['id'] == 'agenda@recurring:2021-04-29-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring:2021-05-06-1700'
assert resp.json['data'][2]['id'] == 'agenda@recurring:2021-05-13-1700'
assert resp.json['data'][0]['id'] == 'agenda@recurring--2021-04-29-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring--2021-05-06-1700'
assert resp.json['data'][2]['id'] == 'agenda@recurring--2021-05-13-1700'
# test subscription's limits
subscription.date_start = datetime.date(2021, 4, 29)
@ -2286,8 +2233,8 @@ def test_datetimes_multiple_agendas_recurring_subscribed_dates(app):
},
)
assert len(resp.json['data']) == 2
assert resp.json['data'][0]['id'] == 'agenda@recurring:2021-04-29-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring:2021-05-06-1700'
assert resp.json['data'][0]['id'] == 'agenda@recurring--2021-04-29-1700'
assert resp.json['data'][1]['id'] == 'agenda@recurring--2021-05-06-1700'
@pytest.mark.freeze_time('2022-03-07 14:00') # Monday of 10th week
@ -2502,24 +2449,30 @@ def test_datetimes_multiple_agendas_shared_custody_other_rules(app):
@pytest.mark.freeze_time('2022-03-07 14:00') # Monday of 10th week
def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
agenda = Agenda.objects.create(label='First agenda', kind='events', maximal_booking_delay=30)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
event_agenda = Agenda.objects.create(label='First agenda', kind='events', maximal_booking_delay=30)
Desk.objects.create(agenda=event_agenda, slug='_exceptions_holder')
start_datetime = make_aware(datetime.datetime(year=2022, month=3, day=9, hour=14, minute=0))
wednesday_event = Event.objects.create(
slug='event-wednesday',
start_datetime=make_aware(datetime.datetime(year=2022, month=3, day=9, hour=14, minute=0)),
start_datetime=start_datetime,
recurrence_days=[2],
recurrence_end_date=start_datetime + datetime.timedelta(days=30),
places=5,
agenda=agenda,
agenda=event_agenda,
)
wednesday_event.create_all_recurrences()
start_datetime = make_aware(datetime.datetime(year=2022, month=3, day=10, hour=14, minute=0))
thursday_event = Event.objects.create(
slug='event-thursday',
start_datetime=make_aware(datetime.datetime(year=2022, month=3, day=10, hour=14, minute=0)),
start_datetime=start_datetime,
recurrence_days=[3],
recurrence_end_date=start_datetime + datetime.timedelta(days=30),
places=5,
agenda=agenda,
agenda=event_agenda,
)
thursday_event.create_all_recurrences()
Subscription.objects.create(
agenda=agenda,
agenda=event_agenda,
user_external_id='child_id',
date_start=now(),
date_end=now() + datetime.timedelta(days=30),
@ -2543,14 +2496,14 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-09-1400',
'first-agenda@event-thursday:2022-03-10-1400',
'first-agenda@event-wednesday:2022-03-16-1400',
'first-agenda@event-thursday:2022-03-17-1400',
'first-agenda@event-wednesday:2022-03-23-1400',
'first-agenda@event-thursday:2022-03-24-1400',
'first-agenda@event-wednesday:2022-03-30-1400',
'first-agenda@event-thursday:2022-03-31-1400',
'first-agenda@event-wednesday--2022-03-09-1400',
'first-agenda@event-thursday--2022-03-10-1400',
'first-agenda@event-wednesday--2022-03-16-1400',
'first-agenda@event-thursday--2022-03-17-1400',
'first-agenda@event-wednesday--2022-03-23-1400',
'first-agenda@event-thursday--2022-03-24-1400',
'first-agenda@event-wednesday--2022-03-30-1400',
'first-agenda@event-thursday--2022-03-31-1400',
]
resp = app.get(
@ -2558,10 +2511,10 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'father_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-09-1400',
'first-agenda@event-thursday:2022-03-10-1400',
'first-agenda@event-wednesday:2022-03-23-1400',
'first-agenda@event-thursday:2022-03-24-1400',
'first-agenda@event-wednesday--2022-03-09-1400',
'first-agenda@event-thursday--2022-03-10-1400',
'first-agenda@event-wednesday--2022-03-23-1400',
'first-agenda@event-thursday--2022-03-24-1400',
]
resp = app.get(
@ -2569,10 +2522,10 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'mother_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-16-1400',
'first-agenda@event-thursday:2022-03-17-1400',
'first-agenda@event-wednesday:2022-03-30-1400',
'first-agenda@event-thursday:2022-03-31-1400',
'first-agenda@event-wednesday--2022-03-16-1400',
'first-agenda@event-thursday--2022-03-17-1400',
'first-agenda@event-wednesday--2022-03-30-1400',
'first-agenda@event-thursday--2022-03-31-1400',
]
# add father custody period spanning odd week event
@ -2588,12 +2541,12 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'father_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-09-1400',
'first-agenda@event-thursday:2022-03-10-1400',
'first-agenda@event-wednesday:2022-03-16-1400',
'first-agenda@event-thursday:2022-03-17-1400',
'first-agenda@event-wednesday:2022-03-23-1400',
'first-agenda@event-thursday:2022-03-24-1400',
'first-agenda@event-wednesday--2022-03-09-1400',
'first-agenda@event-thursday--2022-03-10-1400',
'first-agenda@event-wednesday--2022-03-16-1400',
'first-agenda@event-thursday--2022-03-17-1400',
'first-agenda@event-wednesday--2022-03-23-1400',
'first-agenda@event-thursday--2022-03-24-1400',
]
resp = app.get(
@ -2601,8 +2554,8 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'mother_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-30-1400',
'first-agenda@event-thursday:2022-03-31-1400',
'first-agenda@event-wednesday--2022-03-30-1400',
'first-agenda@event-thursday--2022-03-31-1400',
]
# check date_start/date_end
@ -2617,7 +2570,7 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-16-1400',
'first-agenda@event-wednesday--2022-03-16-1400',
]
resp = app.get(
@ -2631,7 +2584,7 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-thursday:2022-03-17-1400',
'first-agenda@event-thursday--2022-03-17-1400',
]
# weirder rules
@ -2649,11 +2602,11 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'father_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-09-1400',
'first-agenda@event-wednesday:2022-03-16-1400',
'first-agenda@event-thursday:2022-03-17-1400',
'first-agenda@event-wednesday:2022-03-23-1400',
'first-agenda@event-wednesday:2022-03-30-1400',
'first-agenda@event-wednesday--2022-03-09-1400',
'first-agenda@event-wednesday--2022-03-16-1400',
'first-agenda@event-thursday--2022-03-17-1400',
'first-agenda@event-wednesday--2022-03-23-1400',
'first-agenda@event-wednesday--2022-03-30-1400',
]
resp = app.get(
@ -2661,19 +2614,20 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'mother_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-thursday:2022-03-10-1400',
'first-agenda@event-thursday:2022-03-24-1400',
'first-agenda@event-thursday:2022-03-31-1400',
'first-agenda@event-thursday--2022-03-10-1400',
'first-agenda@event-thursday--2022-03-24-1400',
'first-agenda@event-thursday--2022-03-31-1400',
]
thursday_event.delete()
wednesday_event.recurrence_week_interval = 2
wednesday_event.save()
event_agenda.update_event_recurrences()
resp = app.get('/api/agendas/datetimes/', params={'subscribed': 'all', 'user_external_id': 'child_id'})
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-09-1400',
'first-agenda@event-wednesday:2022-03-23-1400',
'first-agenda@event-wednesday--2022-03-09-1400',
'first-agenda@event-wednesday--2022-03-23-1400',
]
resp = app.get(
@ -2681,8 +2635,8 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'father_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-09-1400',
'first-agenda@event-wednesday:2022-03-23-1400',
'first-agenda@event-wednesday--2022-03-09-1400',
'first-agenda@event-wednesday--2022-03-23-1400',
]
# add mother custody period spanning even week event
@ -2698,7 +2652,7 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'father_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-23-1400',
'first-agenda@event-wednesday--2022-03-23-1400',
]
resp = app.get(
@ -2706,5 +2660,5 @@ def test_datetimes_multiple_agendas_shared_custody_recurring_event(app):
params={'subscribed': 'all', 'user_external_id': 'child_id', 'guardian_external_id': 'mother_id'},
)
assert [d['id'] for d in resp.json['data']] == [
'first-agenda@event-wednesday:2022-03-09-1400',
'first-agenda@event-wednesday--2022-03-09-1400',
]

View File

@ -961,7 +961,7 @@ def test_booking_api_available(app, user):
with CaptureQueriesContext(connection) as ctx:
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
assert len(ctx.captured_queries) == 4
assert len(ctx.captured_queries) == 3
assert resp.json['data'][-1]['places']['total'] == 20
assert resp.json['data'][-1]['places']['available'] == 20
assert resp.json['data'][-1]['places']['reserved'] == 0

View File

@ -1011,22 +1011,18 @@ def test_agenda_events_day_view(app, admin_user):
places=10,
agenda=agenda,
recurrence_days=[recurring_start_datetime.weekday()],
recurrence_end_date=recurring_start_datetime + datetime.timedelta(days=15),
)
event.create_all_recurrences()
with CaptureQueriesContext(connection) as ctx:
resp = app.get('/manage/agendas/%s/2020/11/11/' % agenda.pk)
assert len(ctx.captured_queries) == 6
assert len(ctx.captured_queries) == 4
assert len(resp.pyquery.find('.event-info')) == 2
assert 'abc' in resp.pyquery.find('.event-info')[0].text
assert 'xyz' in resp.pyquery.find('.event-info')[1].text
# trying to access event recurrence creates it
event_count = Event.objects.count()
time = localtime(event.start_datetime).strftime('%H%M')
resp = resp.click(href='abc:2020-11-11-%s' % time)
assert Event.objects.count() == event_count + 1
resp = app.get('/manage/agendas/%s/2020/11/11/' % agenda.pk)
assert len(resp.pyquery.find('.event-info')) == 2
@ -1038,9 +1034,10 @@ def test_agenda_events_day_view(app, admin_user):
places=10,
agenda=agenda,
recurrence_days=[start_datetime.weekday()],
recurrence_end_date=start_datetime + datetime.timedelta(days=15),
)
event.create_all_recurrences()
resp = app.get('/manage/agendas/%s/2020/11/11/' % agenda.pk)
# the event occurence in DB does not hide recurrence of the second recurrent event
assert len(resp.pyquery.find('.event-info')) == 3
@ -1083,11 +1080,13 @@ def test_agenda_events_month_view(app, admin_user):
places=10,
agenda=agenda,
recurrence_days=[start_datetime.weekday()],
recurrence_end_date=start_datetime + datetime.timedelta(days=60),
)
event.create_all_recurrences()
with CaptureQueriesContext(connection) as ctx:
resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, 2020, 11))
assert len(ctx.captured_queries) == 9
assert len(ctx.captured_queries) == 7
assert len(resp.pyquery.find('.event-info')) == 5
assert 'abc' in resp.pyquery.find('.event-info')[0].text
assert 'abc' in resp.pyquery.find('.event-info')[1].text
@ -1100,6 +1099,7 @@ def test_agenda_events_month_view(app, admin_user):
start_datetime=start_datetime + datetime.timedelta(days=6),
end_datetime=start_datetime + datetime.timedelta(days=8),
)
agenda.update_event_recurrences()
resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, 2020, 11))
assert len(resp.pyquery.find('.event-info')) == 4
assert 'abc' in resp.pyquery.find('li')[5].text_content()
@ -1110,15 +1110,6 @@ def test_agenda_events_month_view(app, admin_user):
resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, 2020, 12))
assert len(resp.pyquery.find('.event-info')) == 5
# trying to access event recurrence creates it
event_count = Event.objects.count()
time = localtime(event.start_datetime).strftime('%H%M')
resp = resp.click(href='abc:2020-12-02-%s' % time).follow()
assert Event.objects.count() == event_count + 1
resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, 2020, 12))
assert len(resp.pyquery.find('.event-info')) == 5
# create another event with recurrence, the same day/time
start_datetime = localtime().replace(day=4, month=11, year=2020)
event = Event.objects.create(
@ -1127,15 +1118,18 @@ def test_agenda_events_month_view(app, admin_user):
places=10,
agenda=agenda,
recurrence_days=[start_datetime.weekday()],
recurrence_end_date=start_datetime + datetime.timedelta(days=60),
)
event.create_all_recurrences()
resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, 2020, 12))
# the event occurence in DB does not hide recurrence of the second recurrent event
assert len(resp.pyquery.find('.event-info')) == 10
resp = resp.click(href='abc:2020-12-09-%s' % time).follow()
time = localtime(event.start_datetime).strftime('%H%M')
resp = resp.click('Dec. 9, 2020, 1 a.m.', index=1)
resp = resp.click('Options')
resp.form['start_datetime_1'] = '13:12'
resp = resp.form.submit(status=302).follow()
agenda.update_event_recurrences()
resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, 2020, 12))
assert len(resp.pyquery.find('.event-info')) == 10
@ -1210,13 +1204,14 @@ def test_agenda_open_events_view(app, admin_user, manager_user):
)
# weekly recurring event, first recurrence is in the past but second is in range
start_datetime = now() - datetime.timedelta(days=3)
Event.objects.create(
event = Event.objects.create(
label='event G',
start_datetime=start_datetime,
places=10,
agenda=agenda,
recurrence_days=[start_datetime.weekday()],
recurrence_end_date=start_datetime + datetime.timedelta(days=30),
)
event.create_all_recurrences()
resp = app.get('/manage/agendas/%s/events/open/' % agenda.pk)
assert 'event A' not in resp.text
assert 'event B' not in resp.text

View File

@ -2266,7 +2266,7 @@ def test_events_timesheet_slots(app, admin_user):
resp.form['date_end'] = '2022-02-28'
with CaptureQueriesContext(connection) as ctx:
resp = resp.form.submit()
assert len(ctx.captured_queries) == 9
assert len(ctx.captured_queries) == 7
slots = resp.context['form'].get_slots()
assert slots['dates'] == [

View File

@ -1287,12 +1287,14 @@ def test_recurring_events_manage_exceptions(settings, app, admin_user, freezer):
assert agenda.desk_set.count() == 1
desk = agenda.desk_set.get(slug='_exceptions_holder')
event = Event.objects.create(start_datetime=now(), places=10, agenda=agenda)
event = Event.objects.create(start_datetime=now() + datetime.timedelta(hours=1), places=10, agenda=agenda)
resp = app.get('/manage/agendas/%s/settings' % agenda.id)
assert 'Recurrence exceptions' not in resp.text
event.recurrence_days = list(range(7))
event.recurrence_end_date = now() + datetime.timedelta(days=31)
event.save()
event.create_all_recurrences()
resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, 2021, 7))
assert len(resp.pyquery.find('.event-info')) == 31
@ -1307,6 +1309,7 @@ def test_recurring_events_manage_exceptions(settings, app, admin_user, freezer):
resp.form['end_datetime_1'] = (now() + datetime.timedelta(days=7)).strftime('%H:%M')
resp = resp.form.submit().follow()
assert desk.timeperiodexception_set.count() == 1
agenda.update_event_recurrences()
resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, 2021, 7))
assert len(resp.pyquery.find('.event-info')) == 24
@ -1316,18 +1319,11 @@ def test_recurring_events_manage_exceptions(settings, app, admin_user, freezer):
resp = resp.click('enable').follow()
assert TimePeriodException.objects.count() > 1
assert 'Bastille Day' in resp.text
agenda.update_event_recurrences()
resp = app.get('/manage/agendas/%s/%s/%s/' % (agenda.id, 2021, 7))
assert len(resp.pyquery.find('.event-info')) == 23
# add recurrence end date, which lead to recurrences creation
resp = app.get('/manage/agendas/%s/events/%s/edit' % (agenda.id, event.id))
resp.form['recurrence_end_date'] = (now() + datetime.timedelta(days=31)).strftime('%Y-%m-%d')
resp = resp.form.submit()
# recurrences corresponding to exceptions have not been created
assert Event.objects.count() == 24
def test_recurring_events_exceptions_report(settings, app, admin_user, freezer):
freezer.move_to('2021-07-01 12:10')

View File

@ -2278,30 +2278,6 @@ def test_recurring_events_with_end_date():
assert recurrences[-1].start_datetime == start_datetime + datetime.timedelta(days=4)
def test_recurring_events_sort(freezer):
freezer.move_to('2021-01-06 12:00') # Wednesday
agenda = Agenda.objects.create(label='Agenda', kind='events')
Event.objects.create(
agenda=agenda, slug='a', start_datetime=now(), recurrence_days=list(range(7)), places=5
)
Event.objects.create(
agenda=agenda, slug='b', start_datetime=now(), recurrence_days=list(range(7)), duration=10, places=5
)
Event.objects.create(
agenda=agenda, slug='c', start_datetime=now(), recurrence_days=list(range(7)), duration=5, places=5
)
Event.objects.create(
agenda=agenda,
slug='d',
start_datetime=now() + datetime.timedelta(hours=1),
recurrence_days=list(range(7)),
places=5,
)
events = agenda.get_open_events()[:8]
assert [e.primary_event.slug for e in events] == ['c', 'b', 'a', 'd', 'c', 'b', 'a', 'd']
@override_settings(
EXCEPTIONS_SOURCES={
'holidays': {'class': 'workalendar.europe.France', 'label': 'Holidays'},