chrono/tests/manager/test_meetings_agenda_option...

401 lines
14 KiB
Python

import datetime
import pytest
from django.db import connection
from django.test import override_settings
from django.test.utils import CaptureQueriesContext
from django.utils.timezone import localtime, now
from chrono.agendas.models import (
Agenda,
Desk,
Event,
MeetingType,
Resource,
TimePeriod,
TimePeriodException,
TimePeriodExceptionSource,
UnavailabilityCalendar,
)
from tests.utils import login
pytestmark = pytest.mark.django_db
def test_options_meetings_agenda_delays(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings', maximal_booking_delay=2)
assert agenda.maximal_booking_delay == 2
app = login(app)
url = '/manage/agendas/%s/booking-delays' % agenda.pk
resp = app.get(url)
assert 'minimal_booking_delay_in_working_days' not in resp.context['form'].fields
resp.form['maximal_booking_delay'] = None
resp = resp.form.submit()
agenda.refresh_from_db()
assert agenda.maximal_booking_delay == 2
def test_options_meetings_agenda_num_queries(app, admin_user, managers_group):
agenda = Agenda.objects.create(
label='Agenda', kind='meetings', edit_role=managers_group, view_role=managers_group
)
resource = Resource.objects.create(label='Resource')
agenda.resources.add(resource)
for i in range(0, 10):
MeetingType.objects.create(agenda=agenda, label='MT %s' % i)
desk = Desk.objects.create(agenda=agenda, label='Desk')
source = TimePeriodExceptionSource.objects.create(desk=desk, ics_url='https://example.com/test.ics')
calendar = UnavailabilityCalendar.objects.create(label='foo')
calendar.desks.add(desk)
for weekday in (0, 6):
TimePeriod.objects.create(
weekday=weekday, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
)
desk2 = desk.duplicate()
assert agenda.is_available_for_simple_management() is True
app = login(app)
with CaptureQueriesContext(connection) as ctx:
app.get('/manage/agendas/%s/settings' % agenda.pk)
assert len(ctx.captured_queries) == 13
# check with different kind of exceptions:
# exception starts and ends in the past
exception = TimePeriodException.objects.create(
desk=desk,
start_datetime=now() - datetime.timedelta(days=2),
end_datetime=now() - datetime.timedelta(days=1),
)
desk2.delete()
desk2 = desk.duplicate()
assert agenda.is_available_for_simple_management() is True
with CaptureQueriesContext(connection) as ctx:
app.get('/manage/agendas/%s/settings' % agenda.pk)
assert len(ctx.captured_queries) == 13
# exception starts in the past but ends in the futur
exception.delete()
exception = TimePeriodException.objects.create(
desk=desk,
source=source,
start_datetime=now() - datetime.timedelta(days=1),
end_datetime=now() + datetime.timedelta(days=1),
)
desk2.delete()
desk2 = desk.duplicate()
assert agenda.is_available_for_simple_management() is True
with CaptureQueriesContext(connection) as ctx:
app.get('/manage/agendas/%s/settings' % agenda.pk)
assert len(ctx.captured_queries) == 13
# exception in more than 2 weeks
exception.delete()
exception = TimePeriodException.objects.create(
unavailability_calendar=calendar,
start_datetime=now() + datetime.timedelta(days=20),
end_datetime=now() + datetime.timedelta(days=21),
)
desk2.delete()
desk2 = desk.duplicate()
assert agenda.is_available_for_simple_management() is True
with CaptureQueriesContext(connection) as ctx:
app.get('/manage/agendas/%s/settings' % agenda.pk)
assert len(ctx.captured_queries) == 13
def test_meetings_agenda_add_meeting_type(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
assert "This agenda doesn't have any meeting type yet." in resp.text
resp = resp.click('New Meeting Type')
resp.form['label'] = 'Blah'
resp.form['duration'] = '0'
assert 'deleted' not in resp.form.fields
resp = resp.form.submit()
assert 'Ensure this value is greater than or equal to 1.' in resp.text
assert not MeetingType.objects.exists()
resp.form['duration'] = '60'
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings#open:meeting-types' % agenda.pk)
meeting_type = MeetingType.objects.get(agenda=agenda)
assert meeting_type.label == 'Blah'
assert meeting_type.duration == 60
assert meeting_type.deleted is False
resp = resp.follow()
assert 'Blah' in resp.text
def test_meetings_agenda_edit_meeting_type(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
meeting_type = MeetingType.objects.create(agenda=agenda, label='Blah')
meeting_type2 = MeetingType.objects.create(agenda=agenda, label='Other')
other_agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
other_meeting_type = MeetingType.objects.create(agenda=other_agenda, label='Blah')
assert meeting_type.slug == other_meeting_type.slug
app = login(app)
resp = app.get('/manage/meetingtypes/%s/edit' % meeting_type.pk)
resp.form['label'] = 'Foo'
resp.form['duration'] = '120'
assert 'deleted' not in resp.form.fields
resp.form.submit().follow()
meeting_type.refresh_from_db()
assert meeting_type.label == 'Foo'
assert meeting_type.slug == other_meeting_type.slug
assert meeting_type.duration == 120
assert meeting_type.deleted is False
# check slug edition
resp = app.get('/manage/meetingtypes/%s/edit' % meeting_type.pk)
resp.form['slug'] = meeting_type2.slug
resp = resp.form.submit()
assert resp.context['form'].errors['slug'] == ['Another meeting type exists with the same identifier.']
# check duration change
desk = Desk.objects.create(agenda=agenda, label='Desk A')
for hour in [12, 14]:
Event.objects.create(
agenda=agenda,
places=1,
desk=desk,
meeting_type=meeting_type,
start_datetime=localtime(now()).replace(hour=hour, minute=00),
)
resp = app.get('/manage/meetingtypes/%s/edit' % meeting_type.pk)
resp.form['duration'] = '180'
resp = resp.form.submit()
assert resp.context['form'].errors['duration'] == [
'Not possible to change duration: existing events will overlap.'
]
# no errors
resp = app.get('/manage/meetingtypes/%s/edit' % meeting_type.pk)
resp.form['duration'] = '120'
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings#open:meeting-types' % agenda.pk)
resp = app.get('/manage/meetingtypes/%s/edit' % meeting_type.pk)
resp.form['duration'] = '90'
resp = resp.form.submit().follow()
resp = app.get('/manage/meetingtypes/%s/edit' % meeting_type.pk)
resp.form['duration'] = '120'
resp = resp.form.submit().follow()
def test_meetings_agenda_delete_meeting_type(app, admin_user):
agenda = Agenda(label='Foo bar', kind='meetings')
agenda.save()
meeting_type = MeetingType(agenda=agenda, label='Blah')
meeting_type.save()
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.click('Blah')
resp = resp.click('Delete')
assert 'Are you sure you want to delete this?' in resp.text
assert 'disabled' not in resp.text
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings#open:meeting-types' % agenda.pk)
meeting_type.refresh_from_db()
assert meeting_type.deleted is True
assert '__deleted__' in meeting_type.slug
# meeting type not showing up anymore
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
assert 'Meeting Type Foo' not in resp.text
# it is possible to add a new meeting type with the same slug
new_meeting_type = MeetingType.objects.create(agenda=agenda, label='Blah')
assert new_meeting_type.slug == 'blah'
def test_meetings_agenda_add_desk(app, admin_user):
app = login(app)
resp = app.get('/manage/', status=200)
resp = resp.click('New')
resp.form['label'] = 'Foo bar'
resp.form['kind'] = 'meetings'
resp = resp.form.submit()
assert Desk.objects.count() == 1
assert str(Desk.objects.first()) == 'Desk 1'
agenda = Agenda.objects.get(slug='foo-bar')
agenda.desk_simple_management = False
agenda.save()
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.click('New Desk')
resp.form['label'] = 'Desk A'
resp = resp.form.submit().follow()
assert Desk.objects.count() == 2
desk = Desk.objects.latest('pk')
TimePeriod.objects.create(
weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
)
resp = resp.click('New Desk')
resp.form['label'] = 'Desk A'
resp = resp.form.submit().follow()
assert Desk.objects.count() == 3
assert Desk.objects.filter(slug='desk-a-1').count() == 1
assert 'Desk A' in resp.text
new_desk = Desk.objects.latest('pk')
assert new_desk.timeperiod_set.count() == 0
# unknown pk
app.get('/manage/agendas/0/add-desk', status=404)
# wrong kind
agenda.kind = 'virtual'
agenda.save()
app.get('/manage/agendas/%s/add-desk' % agenda.pk, status=404)
agenda.kind = 'events'
agenda.save()
app.get('/manage/agendas/%s/add-desk' % agenda.pk, status=404)
@override_settings(
EXCEPTIONS_SOURCES={
'holidays': {'class': 'workalendar.europe.France', 'label': 'Holidays'},
}
)
def test_meetings_agenda_add_desk_from_another(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(agenda=agenda, label='Desk A')
TimePeriod.objects.create(
weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
)
assert Desk.objects.count() == 1
assert desk.timeperiodexceptionsource_set.count() == 0
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.click('New Desk')
resp.form['label'] = 'Desk B'
resp.form['copy_from'] = desk.pk
resp = resp.form.submit().follow()
assert Desk.objects.count() == 2
new_desk = Desk.objects.latest('pk')
assert new_desk.label == 'Desk B'
assert new_desk.timeperiod_set.count() == 1
assert (
new_desk.timeperiodexceptionsource_set.count() == 0
) # holidays not automatically added via duplication
@override_settings(
EXCEPTIONS_SOURCES={
'holidays': {'class': 'workalendar.europe.France', 'label': 'Holidays'},
}
)
def test_meetings_agenda_add_desk_simple_management(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings', desk_simple_management=True)
desk = Desk.objects.create(agenda=agenda, label='Desk A')
TimePeriod.objects.create(
weekday=1, desk=desk, start_time=datetime.time(10, 0), end_time=datetime.time(12, 0)
)
assert Desk.objects.count() == 1
assert desk.timeperiodexceptionsource_set.count() == 0
app = login(app)
resp = app.get('/manage/agendas/%s/add-desk' % agenda.pk)
resp.form['label'] = 'Desk B'
assert 'copy_from' not in resp.context['form'].fields
resp = resp.form.submit().follow()
assert Desk.objects.count() == 2
new_desk = Desk.objects.latest('pk')
assert new_desk.label == 'Desk B'
assert new_desk.timeperiod_set.count() == 1
assert (
new_desk.timeperiodexceptionsource_set.count() == 0
) # holidays not automatically added via duplication
# ok if no desks (should not happen)
Desk.objects.all().delete()
resp = app.get('/manage/agendas/%s/add-desk' % agenda.pk)
resp.form['label'] = 'Desk'
assert 'copy_from' not in resp.context['form'].fields
resp = resp.form.submit().follow()
assert Desk.objects.count() == 1
new_desk = Desk.objects.latest('pk')
assert new_desk.timeperiodexceptionsource_set.count() == 1
def test_meetings_agenda_edit_desk(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(agenda=agenda, label='Desk A')
desk2 = Desk.objects.create(agenda=agenda, label='Desk B')
other_agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
other_desk = Desk.objects.create(agenda=other_agenda, label='Desk A')
assert other_desk.slug == desk.slug
app = login(app)
resp = app.get('/manage/desks/%s/edit' % desk.pk)
resp.form['label'] = 'Desk C'
resp.form['slug'] = desk.slug
resp = resp.form.submit().follow()
assert 'Desk A' not in resp.text
assert 'Desk B' in resp.text
assert 'Desk C' in resp.text
desk.refresh_from_db()
assert desk.label == 'Desk C'
assert desk.slug == other_desk.slug
# check slug edition
resp = app.get('/manage/desks/%s/edit' % desk.pk)
resp.form['slug'] = desk2.slug
resp = resp.form.submit()
assert resp.context['form'].errors['slug'] == ['Another desk exists with the same identifier.']
# unknown pk
app.get('/manage/desks/0/edit', status=404)
# wrong kind
agenda.kind = 'virtual'
agenda.save()
app.get('/manage/desks/%s/edit' % desk.pk, status=404)
agenda.kind = 'events'
agenda.save()
app.get('/manage/desks/%s/edit' % desk.pk, status=404)
def test_meetings_agenda_delete_desk(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
Desk.objects.create(agenda=agenda, label='Desk A')
desk_b = Desk.objects.create(agenda=agenda, label='Desk B')
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.click('Desk A')
resp = resp.click('Delete')
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings#open:desks' % agenda.pk)
assert Desk.objects.count() == 1
# only one desk
app.get('/manage/desks/%s/delete' % desk_b.pk, status=404)
desk_a = Desk.objects.create(agenda=agenda, label='Desk A')
# unknown pk
app.get('/manage/desks/0/delete', status=404)
# wrong kind
agenda.kind = 'virtual'
agenda.save()
app.get('/manage/desks/%s/delete' % desk_a.pk, status=404)
agenda.kind = 'events'
agenda.save()
app.get('/manage/desks/%s/delete' % desk_a.pk, status=404)