chrono/tests/manager/test_timeperiod.py

414 lines
17 KiB
Python

import datetime
import pytest
from chrono.agendas.models import Agenda, Desk, MeetingType, TimePeriod
from chrono.apps.snapshot.models import AgendaSnapshot
from tests.utils import login
pytestmark = pytest.mark.django_db
def test_meetings_agenda_add_time_period(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')
MeetingType.objects.create(agenda=agenda, label='Blah')
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.click('Add repeating periods', index=0)
resp.form.get('weekdays', index=2).checked = True
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '17:00'
resp = resp.form.submit()
assert TimePeriod.objects.get(desk=desk).weekday == 2
assert TimePeriod.objects.get(desk=desk).start_time.hour == 10
assert TimePeriod.objects.get(desk=desk).start_time.minute == 0
assert TimePeriod.objects.get(desk=desk).end_time.hour == 17
assert TimePeriod.objects.get(desk=desk).end_time.minute == 0
assert TimePeriod.objects.get(desk=desk).weekday_indexes is None
assert desk2.timeperiod_set.exists() is False
resp = resp.follow()
assert AgendaSnapshot.objects.count() == 1
# add a second time period
resp = resp.click('Add repeating periods', index=0)
resp.form.get('weekdays', index=0).checked = True
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '13:00'
resp.form['repeat'] = 'custom'
resp.form['weekday_indexes'] = [1, 3]
resp = resp.form.submit()
resp = resp.follow()
assert 'Monday (1st, 3rd of the month) / 10 a.m. → 1 p.m.' in resp.text
assert 'Wednesday / 10 a.m. → 5 p.m.' in resp.text
assert resp.text.index('Monday') < resp.text.index('Wednesday')
# invert start and end
resp2 = resp.click('Add repeating periods', index=0)
resp2.form.get('weekdays', index=0).checked = True
resp2.form['start_time'] = '13:00'
resp2.form['end_time'] = '10:00'
resp2 = resp2.form.submit()
assert 'End time must come after start time.' in resp2.text
# and add same time periods on multiple days
resp = resp.click('Add repeating periods', index=0)
resp.form.get('weekdays', index=4).checked = True
resp.form.get('weekdays', index=5).checked = True
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '13:00'
resp = resp.form.submit()
assert TimePeriod.objects.filter(desk=desk).count() == 4
def test_meetings_agenda_add_time_period_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')
desk2 = Desk.objects.create(agenda=agenda, label='Desk B')
assert agenda.is_available_for_simple_management() is True
app = login(app)
resp = app.get('/manage/agendas/%s/desk/%s/add-time-period' % (agenda.pk, desk.pk))
resp.form.get('weekdays', index=0).checked = True
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '13:00'
resp.form.submit()
assert AgendaSnapshot.objects.count() == 1
assert TimePeriod.objects.filter(desk=desk).count() == 1
assert TimePeriod.objects.filter(desk=desk2).count() == 1
assert agenda.is_available_for_simple_management() is True
def test_meetings_agenda_add_time_period_on_missing_desk(app, admin_user):
app = login(app)
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
app.get('/manage/agendas/%s/desk/0/add-time-period' % agenda.pk, status=404)
def test_meetings_agenda_add_time_period_as_manager(app, manager_user):
agenda = Agenda(label='Foo bar', kind='meetings')
agenda.view_role = manager_user.groups.all()[0]
agenda.save()
desk = Desk.objects.create(agenda=agenda, label='Desk A')
app = login(app, username='manager', password='manager')
resp = app.get('/manage/agendas/%d/' % agenda.id)
assert 'Settings' not in resp.text
resp = app.get('/manage/agendas/%d/settings' % agenda.id, status=403)
MeetingType(agenda=agenda, label='Blah').save()
app.get('/manage/agendas/%d/desk/%d/add-time-period' % (agenda.id, desk.id), status=403)
time_period = TimePeriod(
desk=desk, weekday=0, start_time=datetime.time(9, 0), end_time=datetime.time(12, 0)
)
time_period.save()
resp = app.get('/manage/agendas/%d/' % agenda.id)
app.get('/manage/timeperiods/%d/edit' % time_period.id, status=403)
app.get('/manage/timeperiods/%d/delete' % time_period.id, status=403)
# grant edit right to manager
agenda.edit_role = manager_user.groups.all()[0]
agenda.save()
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
assert 'Add repeating periods' in resp.text
assert '/manage/timeperiods/%s/edit' % time_period.id in resp.text
assert '/manage/timeperiods/%s/delete' % time_period.id in resp.text
app.get('/manage/agendas/%d/desk/%d/add-time-period' % (agenda.id, desk.id), status=200)
app.get('/manage/timeperiods/%d/edit' % time_period.id, status=200)
def test_meetings_agenda_edit_time_period(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(agenda=agenda, label='Desk A')
time_period = TimePeriod.objects.create(
desk=desk, weekday=0, start_time=datetime.time(9, 0), end_time=datetime.time(12, 0)
)
desk2 = desk.duplicate()
time_period2 = desk2.timeperiod_set.get()
app = login(app)
# edit
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.click('Monday / 9 a.m. → noon', index=0)
assert 'Repeating period' in resp.text
resp.form['start_time'] = '10:00'
resp = resp.form.submit()
resp = resp.follow()
time_period.refresh_from_db()
assert time_period.start_time.hour == 10
time_period2.refresh_from_db()
assert time_period2.start_time.hour == 9
assert AgendaSnapshot.objects.count() == 1
resp = resp.click('Monday / 10 a.m. → noon')
resp.form['repeat'] = 'custom'
resp.form['weekday_indexes'] = [5]
resp = resp.form.submit().follow()
time_period.refresh_from_db()
assert time_period.weekday_indexes == [5]
resp = resp.click('Monday \\(5th of the month\\) / 10 a.m. → noon')
resp.form['repeat'] = 'every-week'
resp = resp.form.submit().follow()
time_period.refresh_from_db()
assert time_period.weekday_indexes is None
# edit with inverted start/end
resp2 = resp.click('Monday / 10 a.m. → noon')
resp2.form['start_time'] = '18:00'
resp2 = resp2.form.submit()
assert 'End time must come after start time.' in resp2.text
def test_meetings_agenda_edit_time_period_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')
time_period = TimePeriod.objects.create(
desk=desk, weekday=0, start_time=datetime.time(9, 0), end_time=datetime.time(12, 0)
)
desk2 = desk.duplicate()
time_period2 = desk2.timeperiod_set.get()
assert agenda.is_available_for_simple_management() is True
app = login(app)
resp = app.get('/manage/timeperiods/%s/edit' % time_period.pk)
resp.form['weekday'] = 3
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '11:00'
resp.form.submit()
time_period.refresh_from_db()
time_period2.refresh_from_db()
assert time_period.weekday == 3
assert time_period.start_time.hour == 10
assert time_period.end_time.hour == 11
assert time_period2.weekday == 3
assert time_period2.start_time.hour == 10
assert time_period2.end_time.hour == 11
assert agenda.is_available_for_simple_management() is True
assert AgendaSnapshot.objects.count() == 1
# should not happen: corresponding time period does not exist
time_period2.delete()
resp = app.get('/manage/timeperiods/%s/edit' % time_period.pk)
resp.form['weekday'] = 3
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '11:00'
# no error
resp.form.submit()
time_period.refresh_from_db()
assert time_period.weekday == 3
assert time_period.start_time.hour == 10
assert time_period.end_time.hour == 11
def test_meetings_agenda_delete_time_period(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(agenda=agenda, label='Desk A')
TimePeriod.objects.create(
desk=desk, weekday=2, start_time=datetime.time(10, 0), end_time=datetime.time(18, 0)
)
desk.duplicate()
assert TimePeriod.objects.count() == 2
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
resp = resp.click('Wednesday', index=0)
resp = resp.click('Delete')
resp = resp.form.submit()
assert resp.location.endswith('/manage/agendas/%s/settings#open:time-periods' % agenda.id)
assert TimePeriod.objects.count() == 1
assert AgendaSnapshot.objects.count() == 1
def test_meetings_agenda_delete_time_period_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')
time_period = TimePeriod.objects.create(
desk=desk, weekday=0, start_time=datetime.time(9, 0), end_time=datetime.time(12, 0)
)
desk.duplicate()
assert TimePeriod.objects.count() == 2
assert agenda.is_available_for_simple_management() is True
app = login(app)
resp = app.get('/manage/timeperiods/%s/delete' % time_period.pk)
resp.form.submit()
assert TimePeriod.objects.count() == 0
assert agenda.is_available_for_simple_management() is True
assert AgendaSnapshot.objects.count() == 1
# should not happen: corresponding time period does not exist
time_period = TimePeriod.objects.create(
desk=desk, weekday=0, start_time=datetime.time(9, 0), end_time=datetime.time(12, 0)
)
resp = app.get('/manage/timeperiods/%s/delete' % time_period.pk)
resp.form.submit()
assert TimePeriod.objects.count() == 0
@pytest.mark.freeze_time('2022-10-24 10:00')
def test_meetings_agenda_date_time_period(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')
MeetingType.objects.create(agenda=agenda, label='Blah')
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.click('Add a unique period', index=0)
assert 'repeat' not in resp.form.fields
assert 'weekday' not in resp.form.fields
resp.form['date'] = '2022-10-24'
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '17:00'
resp = resp.form.submit()
assert TimePeriod.objects.get(desk=desk).date == datetime.date(2022, 10, 24)
assert TimePeriod.objects.get(desk=desk).start_time.hour == 10
assert TimePeriod.objects.get(desk=desk).start_time.minute == 0
assert TimePeriod.objects.get(desk=desk).end_time.hour == 17
assert TimePeriod.objects.get(desk=desk).end_time.minute == 0
assert desk2.timeperiod_set.exists() is False
resp = resp.follow()
assert AgendaSnapshot.objects.count() == 1
# invert start and end
resp = resp.click('Add a unique period', index=0)
resp.form['date'] = '2022-10-24'
resp.form['start_time'] = '13:00'
resp.form['end_time'] = '10:00'
resp = resp.form.submit()
assert 'End time must come after start time.' in resp.text
# edit
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
resp = resp.click('Monday 24 October 2022 / 10 a.m. → 5 p.m.', index=0)
assert 'Unique period' in resp.text
resp.form['date'] = '2022-10-25'
resp = resp.form.submit().follow()
assert 'Tuesday 25' in resp.text
# delete
resp = resp.click('remove', href='timeperiods')
resp = resp.form.submit().follow()
assert 'Tuesday 25' not in resp.text
@pytest.mark.freeze_time('2022-10-24 10:00')
def test_meetings_agenda_date_time_period_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')
desk2 = Desk.objects.create(agenda=agenda, label='Desk B')
assert agenda.is_available_for_simple_management() is True
app = login(app)
resp = app.get('/manage/agendas/%s/desk/%s/add-date-time-period' % (agenda.pk, desk.pk))
resp.form['date'] = '2022-10-24'
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '13:00'
resp = resp.form.submit().follow()
assert TimePeriod.objects.filter(desk=desk).count() == 1
assert TimePeriod.objects.filter(desk=desk2).count() == 1
assert AgendaSnapshot.objects.count() == 1
# edit
resp = resp.click('Monday 24')
resp.form['date'] = '2022-10-25'
resp.form['start_time'] = '11:00'
resp = resp.form.submit().follow()
assert TimePeriod.objects.filter(desk=desk, date__day=25, start_time__hour=11).count() == 1
assert TimePeriod.objects.filter(desk=desk2, date__day=25, start_time__hour=11).count() == 1
# delete
resp = resp.click('remove', href='timeperiods')
resp = resp.form.submit().follow()
assert TimePeriod.objects.count() == 0
@pytest.mark.freeze_time('2022-10-24 10:00')
def test_meetings_agenda_date_time_period_third_millennium(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')
assert agenda.is_available_for_simple_management() is True
assert TimePeriod.objects.filter(desk=desk).count() == 0
app = login(app)
resp = app.get('/manage/agendas/%s/desk/%s/add-date-time-period' % (agenda.pk, desk.pk))
resp.form['date'] = '0022-10-24'
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '13:00'
resp = resp.form.submit()
assert resp.context['form'].errors['date'] == ['Year must be after 2000.']
assert TimePeriod.objects.filter(desk=desk).count() == 0
@pytest.mark.freeze_time('2022-10-23')
def test_meetings_agenda_date_time_period_display(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(agenda=agenda, label='Desk A')
TimePeriod.objects.create(
desk=desk, weekday=6, start_time=datetime.time(14, 0), end_time=datetime.time(16, 0)
) # repeating period on Sunday
TimePeriod.objects.create(
desk=desk,
date=datetime.date(2022, 10, 24),
start_time=datetime.time(10, 0),
end_time=datetime.time(12, 0),
) # unique period on next Monday
TimePeriod.objects.create(
desk=desk,
date=datetime.date(2022, 10, 25),
start_time=datetime.time(8, 0),
end_time=datetime.time(10, 0),
) # unique period on next Tuesday
TimePeriod.objects.create(
desk=desk,
date=datetime.date(2022, 10, 17),
start_time=datetime.time(8, 0),
end_time=datetime.time(10, 0),
) # unique period on past Monday
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
assert 'Sunday / 2 p.m. → 4 p.m.' in resp.text
assert 'Monday 24 October 2022 / 10 a.m. → noon' in resp.text
assert 'Tuesday 25 October 2022 / 8 a.m. → 10 a.m.' in resp.text
# past unique periods are not displayed
assert '17 October' not in resp.text
# unique periods are displayed after repeating periods
assert resp.text.index('Sunday') < resp.text.index('Monday') < resp.text.index('Tuesday')
@pytest.mark.freeze_time('2022-10-23')
def test_meetings_agenda_date_time_period_list(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
desk = Desk.objects.create(agenda=agenda, label='Desk A')
TimePeriod.objects.create(
desk=desk,
date=datetime.date(2022, 10, 24),
start_time=datetime.time(10, 0),
end_time=datetime.time(12, 0),
) # unique period on next Monday
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
assert 'Monday 24 October 2022 / 10 a.m. → noon' in resp.text
assert not 'see all unique periods' in resp.text
TimePeriod.objects.create(
desk=desk,
date=datetime.date(2022, 10, 17),
start_time=datetime.time(10, 0),
end_time=datetime.time(12, 0),
) # unique period on past Monday
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
assert '17 October' not in resp.text
resp = resp.click('see all unique periods')
assert 'Monday 24 October 2022 / 10 a.m. → noon' in resp.text
assert 'Monday 17 October 2022 / 10 a.m. → noon' in resp.text
assert resp.text.index('24 October') < resp.text.index('17 October')