401 lines
14 KiB
Python
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)
|