chrono/tests/test_time_periods.py

194 lines
8.2 KiB
Python

# -*- coding: utf-8 -*-
import datetime
import pytest
from django.test import override_settings
from django.utils.encoding import force_text
from django.utils.timezone import localtime, make_aware
from chrono.agendas.models import Agenda, TimePeriod, TimePeriodException, MeetingType, Desk
pytestmark = pytest.mark.django_db
def test_timeperiod_time_slots():
agenda = Agenda(label=u'Foo bar', slug='bar')
agenda.save()
desk = Desk.objects.create(label='Desk 1', agenda=agenda)
meeting_type = MeetingType(duration=60, agenda=agenda)
meeting_type.save()
timeperiod = TimePeriod(desk=desk, weekday=0,
start_time=datetime.time(9, 0),
end_time=datetime.time(12, 0))
events = timeperiod.get_time_slots(
min_datetime=make_aware(datetime.datetime(2016, 9, 1)),
max_datetime=make_aware(datetime.datetime(2016, 10, 1)),
meeting_type=meeting_type)
events = list(sorted(events, key=lambda x: x.start_datetime))
assert events[0].start_datetime.timetuple()[:5] == (2016, 9, 5, 9, 0)
assert events[1].start_datetime.timetuple()[:5] == (2016, 9, 5, 10, 0)
assert events[2].start_datetime.timetuple()[:5] == (2016, 9, 5, 11, 0)
assert events[3].start_datetime.timetuple()[:5] == (2016, 9, 12, 9, 0)
assert events[4].start_datetime.timetuple()[:5] == (2016, 9, 12, 10, 0)
assert events[-1].start_datetime.timetuple()[:5] == (2016, 9, 26, 11, 0)
assert len(events) == 12
# another start before the timeperiod
timeperiod = TimePeriod(desk=desk, weekday=1,
start_time=datetime.time(9, 0),
end_time=datetime.time(12, 0))
events = timeperiod.get_time_slots(
min_datetime=make_aware(datetime.datetime(2016, 9, 1)),
max_datetime=make_aware(datetime.datetime(2016, 10, 1)),
meeting_type=meeting_type)
events = list(sorted(events, key=lambda x: x.start_datetime))
assert events[0].start_datetime.timetuple()[:5] == (2016, 9, 6, 9, 0)
assert events[-1].start_datetime.timetuple()[:5] == (2016, 9, 27, 11, 0)
assert len(events) == 12
# a start on the day of the timeperiod
timeperiod = TimePeriod(desk=desk, weekday=3,
start_time=datetime.time(9, 0),
end_time=datetime.time(12, 0))
events = timeperiod.get_time_slots(
min_datetime=make_aware(datetime.datetime(2016, 9, 1)),
max_datetime=make_aware(datetime.datetime(2016, 10, 1)),
meeting_type=meeting_type)
events = list(sorted(events, key=lambda x: x.start_datetime))
assert events[0].start_datetime.timetuple()[:5] == (2016, 9, 1, 9, 0)
assert events[-1].start_datetime.timetuple()[:5] == (2016, 9, 29, 11, 0)
assert len(events) == 15
# a start after the day of the timeperiod
timeperiod = TimePeriod(desk=desk, weekday=4,
start_time=datetime.time(9, 0),
end_time=datetime.time(12, 0))
events = timeperiod.get_time_slots(
min_datetime=make_aware(datetime.datetime(2016, 9, 1)),
max_datetime=make_aware(datetime.datetime(2016, 10, 1)),
meeting_type=meeting_type)
events = list(sorted(events, key=lambda x: x.start_datetime))
assert events[0].start_datetime.timetuple()[:5] == (2016, 9, 2, 9, 0)
assert events[-1].start_datetime.timetuple()[:5] == (2016, 9, 30, 11, 0)
assert len(events) == 15
# another start after the day of the timeperiod
timeperiod = TimePeriod(desk=desk, weekday=5,
start_time=datetime.time(9, 0),
end_time=datetime.time(12, 0))
events = timeperiod.get_time_slots(
min_datetime=make_aware(datetime.datetime(2016, 9, 1)),
max_datetime=make_aware(datetime.datetime(2016, 10, 1)),
meeting_type=meeting_type)
events = list(sorted(events, key=lambda x: x.start_datetime))
assert events[0].start_datetime.timetuple()[:5] == (2016, 9, 3, 9, 0)
assert events[-1].start_datetime.timetuple()[:5] == (2016, 9, 24, 11, 0)
assert len(events) == 12
# shorter duration -> double the events
meeting_type.duration = 30
meeting_type.save()
timeperiod = TimePeriod(desk=desk, weekday=5,
start_time=datetime.time(9, 0),
end_time=datetime.time(12, 0))
events = timeperiod.get_time_slots(
min_datetime=make_aware(datetime.datetime(2016, 9, 1)),
max_datetime=make_aware(datetime.datetime(2016, 10, 1)),
meeting_type=meeting_type)
events = list(sorted(events, key=lambda x: x.start_datetime))
assert events[0].start_datetime.timetuple()[:5] == (2016, 9, 3, 9, 0)
assert events[-1].start_datetime.timetuple()[:5] == (2016, 9, 24, 11, 30)
assert len(events) == 24
@override_settings(LANGUAGE_CODE='fr-fr')
def test_time_period_exception_as_string():
# single day
assert force_text(TimePeriodException(
start_datetime=make_aware(datetime.datetime(2018, 1, 18)),
end_datetime=make_aware(datetime.datetime(2018, 1, 19)))
) == u'18 jan. 2018'
# multiple full days
assert force_text(TimePeriodException(
start_datetime=make_aware(datetime.datetime(2018, 1, 18)),
end_datetime=make_aware(datetime.datetime(2018, 1, 20)))
) == u'18 jan. 2018 → 20 jan. 2018'
# a few hours in a day
assert force_text(TimePeriodException(
start_datetime=make_aware(datetime.datetime(2018, 1, 18, 10, 0)),
end_datetime=make_aware(datetime.datetime(2018, 1, 18, 12, 0)))
) == u'18 jan. 2018 10:00 → 12:00'
# multiple days and different times
assert force_text(TimePeriodException(
start_datetime=make_aware(datetime.datetime(2018, 1, 18, 10, 0)),
end_datetime=make_aware(datetime.datetime(2018, 1, 20, 12, 0)))
) == u'18 jan. 2018 10:00 → 20 jan. 2018 12:00'
def test_desk_opening_hours():
agenda = Agenda(label=u'Foo bar', slug='bar')
agenda.save()
desk = Desk.objects.create(label='Desk 1', agenda=agenda)
# nothing yet
hours = list(desk.get_opening_hours(datetime.date(2018, 1, 22)))
assert len(hours) == 0
# morning
TimePeriod(desk=desk, weekday=0,
start_time=datetime.time(9, 0),
end_time=datetime.time(12, 0)).save()
hours = list(desk.get_opening_hours(datetime.date(2018, 1, 22)))
assert len(hours) == 1
assert hours[0].begin.time() == datetime.time(9, 0)
assert hours[0].end.time() == datetime.time(12, 0)
# and afternoon
TimePeriod(desk=desk, weekday=0,
start_time=datetime.time(14, 0),
end_time=datetime.time(17, 0)).save()
hours = list(desk.get_opening_hours(datetime.date(2018, 1, 22)))
assert len(hours) == 2
assert hours[0].begin.time() == datetime.time(9, 0)
assert hours[0].end.time() == datetime.time(12, 0)
assert hours[1].begin.time() == datetime.time(14, 0)
assert hours[1].end.time() == datetime.time(17, 0)
# full day exception
exception = TimePeriodException(
desk=desk,
start_datetime=make_aware(datetime.datetime(2018, 1, 22)),
end_datetime=make_aware(datetime.datetime(2018, 1, 23)))
exception.save()
hours = list(desk.get_opening_hours(datetime.date(2018, 1, 22)))
assert len(hours) == 0
# closed from 11am
exception.start_datetime = make_aware(datetime.datetime(2018, 1, 22, 11, 0))
exception.save()
hours = list(desk.get_opening_hours(datetime.date(2018, 1, 22)))
assert len(hours) == 1
assert localtime(hours[0].begin).time() == datetime.time(9, 0)
assert localtime(hours[0].end).time() == datetime.time(11, 0)
# closed in the middle
exception.start_datetime = make_aware(datetime.datetime(2018, 1, 22, 10, 0))
exception.end_datetime = make_aware(datetime.datetime(2018, 1, 22, 11, 0))
exception.save()
hours = list(desk.get_opening_hours(datetime.date(2018, 1, 22)))
assert len(hours) == 3
assert localtime(hours[0].begin).time() == datetime.time(9, 0)
assert localtime(hours[0].end).time() == datetime.time(10, 0)
assert localtime(hours[1].begin).time() == datetime.time(11, 0)
assert localtime(hours[1].end).time() == datetime.time(12, 0)
assert localtime(hours[2].begin).time() == datetime.time(14, 0)
assert localtime(hours[2].end).time() == datetime.time(17, 0)