269 lines
8.8 KiB
Python
269 lines
8.8 KiB
Python
import datetime
|
|
import json
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
from requests.exceptions import ConnectionError
|
|
from requests.models import Response
|
|
|
|
from chrono.agendas.models import Agenda, TimePeriod
|
|
from chrono.utils.date import get_weekday_index
|
|
from chrono.utils.lingo import CheckType, get_agenda_check_types
|
|
|
|
from .utils import build_agendas, build_meetings_agenda, build_virtual_agenda, paris, utc
|
|
|
|
|
|
def test_get_weekday_index():
|
|
for date in (
|
|
datetime.date(2021, 11, 1), # month starting a Monday
|
|
datetime.date(2021, 12, 1), # month starting a Wednesday
|
|
datetime.date(2021, 5, 1), # month starting a Sunday
|
|
):
|
|
assert get_weekday_index(date) == 1
|
|
assert get_weekday_index(date.replace(day=3)) == 1
|
|
assert get_weekday_index(date.replace(day=7)) == 1
|
|
assert get_weekday_index(date.replace(day=8)) == 2
|
|
assert get_weekday_index(date.replace(day=10)) == 2
|
|
assert get_weekday_index(date.replace(day=14)) == 2
|
|
assert get_weekday_index(date.replace(day=15)) == 3
|
|
assert get_weekday_index(date.replace(day=21)) == 3
|
|
assert get_weekday_index(date.replace(day=22)) == 4
|
|
assert get_weekday_index(date.replace(day=28)) == 4
|
|
assert get_weekday_index(date.replace(day=29)) == 5
|
|
assert get_weekday_index(date.replace(day=30)) == 5
|
|
|
|
|
|
CHECK_TYPES_DATA = [
|
|
{'id': 'bar-reason', 'kind': 'presence', 'text': 'Bar reason'},
|
|
{'id': 'foo-reason', 'kind': 'absence', 'text': 'Foo reason'},
|
|
]
|
|
|
|
|
|
class MockedRequestResponse(mock.Mock):
|
|
status_code = 200
|
|
|
|
def json(self):
|
|
return json.loads(self.content)
|
|
|
|
|
|
def test_get_agenda_check_types_no_service(settings):
|
|
agenda = Agenda(slug='foo')
|
|
|
|
settings.KNOWN_SERVICES = {}
|
|
assert get_agenda_check_types(agenda) == []
|
|
|
|
settings.KNOWN_SERVICES = {'other': []}
|
|
assert get_agenda_check_types(agenda) == []
|
|
|
|
|
|
def test_get_agenda_check_types():
|
|
agenda = Agenda(slug='foo')
|
|
|
|
with mock.patch('requests.Session.get') as requests_get:
|
|
requests_get.side_effect = ConnectionError()
|
|
assert get_agenda_check_types(agenda) == []
|
|
|
|
with mock.patch('requests.Session.get') as requests_get:
|
|
mock_resp = Response()
|
|
mock_resp.status_code = 500
|
|
requests_get.return_value = mock_resp
|
|
assert get_agenda_check_types(agenda) == []
|
|
|
|
with mock.patch('requests.Session.get') as requests_get:
|
|
mock_resp = Response()
|
|
mock_resp.status_code = 404
|
|
requests_get.return_value = mock_resp
|
|
assert get_agenda_check_types(agenda) == []
|
|
|
|
with mock.patch('requests.Session.get') as requests_get:
|
|
requests_get.return_value = MockedRequestResponse(content=json.dumps({'foo': 'bar'}))
|
|
assert get_agenda_check_types(agenda) == []
|
|
|
|
data = {'data': []}
|
|
with mock.patch('requests.Session.get') as requests_get:
|
|
requests_get.return_value = MockedRequestResponse(content=json.dumps(data))
|
|
assert get_agenda_check_types(agenda) == []
|
|
assert requests_get.call_args_list[0][0] == ('api/agenda/foo/check-types/',)
|
|
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://lingo.example.org'
|
|
|
|
data = {'data': CHECK_TYPES_DATA}
|
|
with mock.patch('requests.Session.get') as requests_get:
|
|
requests_get.return_value = MockedRequestResponse(content=json.dumps(data))
|
|
assert get_agenda_check_types(agenda) == [
|
|
CheckType(slug='bar-reason', label='Bar reason', kind='presence'),
|
|
CheckType(slug='foo-reason', label='Foo reason', kind='absence'),
|
|
]
|
|
|
|
|
|
def test_build_meetings_agenda(db):
|
|
agenda = build_meetings_agenda(
|
|
meeting_types=[30], resources=['Re1'], desks=('Desk 1', 'monday-friday 09:00-12:00 14:00-17:00')
|
|
)
|
|
assert agenda.slug == 'agenda'
|
|
assert agenda.label == 'Agenda'
|
|
assert agenda._mt_30
|
|
assert list(agenda.meetingtype_set.all()) == [agenda._mt_30]
|
|
assert agenda.desk_set.count() == 1
|
|
assert agenda.desk_set.all()[0].slug == 'desk-1'
|
|
timeperiods = agenda.desk_set.all()[0].timeperiod_set.all()
|
|
assert timeperiods.count() == 10
|
|
assert set(timeperiods.values_list('weekday', flat=True)) == set(range(0, 5))
|
|
assert set(timeperiods.values_list('start_time', 'end_time')) == {
|
|
(datetime.time(9), datetime.time(12)),
|
|
(datetime.time(14), datetime.time(17)),
|
|
}
|
|
assert agenda.resources.count() == 1
|
|
assert agenda.resources.get().label == 'Re1'
|
|
assert agenda.resources.get().slug == 're1'
|
|
|
|
|
|
def test_build_meetings_agenda_multiple_desks(db):
|
|
agenda = build_meetings_agenda(
|
|
meeting_types=[30],
|
|
desks={
|
|
'desk-1': ['monday-friday 09:00-12:00'],
|
|
'desk-2': ['monday-friday 14:00-17:00'],
|
|
},
|
|
)
|
|
desks = agenda.desk_set.all()
|
|
assert set(desks.values_list('slug', flat=True)) == {'desk-1', 'desk-2'}
|
|
assert agenda.desk_set.all()[0].slug == 'desk-1'
|
|
timeperiods = TimePeriod.objects.filter(desk__in=desks)
|
|
assert timeperiods.count() == 10
|
|
assert set(timeperiods.values_list('weekday', flat=True)) == set(range(0, 5))
|
|
assert set(timeperiods.values_list('start_time', 'end_time')) == {
|
|
(datetime.time(9), datetime.time(12)),
|
|
(datetime.time(14), datetime.time(17)),
|
|
}
|
|
|
|
|
|
def test_build_virtual_agenda(db):
|
|
agenda = build_virtual_agenda(
|
|
agendas={
|
|
'Agenda 1': {
|
|
'desks': ('Bureau 1', 'monday-friday 08:00-12:00 14:00-17:00'),
|
|
},
|
|
'Agenda 2': {
|
|
'desks': ('Bureau 1', 'monday,tuesday 09:00-12:00'),
|
|
},
|
|
'Agenda 3': {
|
|
'desks': ('Bureau 1', 'monday-friday 15:00-17:00'),
|
|
},
|
|
},
|
|
meeting_types=[30],
|
|
)
|
|
|
|
assert agenda._agenda_1
|
|
assert agenda._agenda_1._mt_30
|
|
assert agenda._agenda_2
|
|
assert agenda._agenda_3
|
|
assert agenda._mt_30
|
|
|
|
assert agenda.real_agendas.count() == 3
|
|
timeperiods = TimePeriod.objects.filter(desk__agenda__in=agenda.real_agendas.all())
|
|
assert timeperiods.count() == 17
|
|
assert set(timeperiods.values_list('weekday', flat=True)) == set(range(0, 5))
|
|
assert set(timeperiods.values_list('start_time', 'end_time')) == {
|
|
(datetime.time(8), datetime.time(12)),
|
|
(datetime.time(9), datetime.time(12)),
|
|
(datetime.time(14), datetime.time(17)),
|
|
(datetime.time(15), datetime.time(17)),
|
|
}
|
|
assert agenda._agenda_1
|
|
|
|
|
|
def test_build_agendas(db):
|
|
# pylint: disable=unused-variable
|
|
ICS_SAMPLE = """BEGIN:VCALENDAR
|
|
VERSION:2.0
|
|
PRODID:-//foo.bar//EN
|
|
BEGIN:VEVENT
|
|
DTSTAMP:20170824T082855Z
|
|
DTSTART:20170831T170800Z
|
|
DTEND:20170831T203400Z
|
|
SEQUENCE:1
|
|
SUMMARY:Événement 1
|
|
END:VEVENT
|
|
BEGIN:VEVENT
|
|
DTSTAMP:20170824T092855Z
|
|
DTSTART:20170830T180800Z
|
|
DTEND:20170831T223400Z
|
|
SEQUENCE:2
|
|
END:VEVENT
|
|
END:VCALENDAR"""
|
|
|
|
unavailability_calendar, agenda_1, agenda_2, virtual = build_agendas(
|
|
'''
|
|
unavailability-calendar Congés
|
|
exception Noël
|
|
start_datetime paris('2023-12-25T00:00:00 24h')
|
|
exception-source sample.ics ICS_SAMPLE
|
|
meetings "Agenda 1" maximal_booking_delay=15 30 45 # comment 1
|
|
# comment 2
|
|
desk "Desk 1"
|
|
timeperiod monday-friday 08:00-12:00
|
|
exception Grève
|
|
start_datetime paris('2023-04-01T01:01:01')
|
|
end_datetime paris('2023-04-01T01:01:01')
|
|
exception-source sample.ics ICS_SAMPLE
|
|
unavailability-calendar Congés
|
|
desk "Bureau 2"
|
|
timeperiod monday-friday 14:00-17:00
|
|
|
|
meetings 'Agenda 2' 30
|
|
desk "Desk 1" monday-friday 08:00-12:00
|
|
desk "Desk 2" monday,friday 14:00-17:00
|
|
|
|
virtual "Agenda 3" 30
|
|
meetings CNI
|
|
desk bureau1 monday-friday 10:00-12:00
|
|
meetings Passeport
|
|
desk bureau2 monday-friday 14:00-17:00
|
|
'''
|
|
)
|
|
assert unavailability_calendar.label == 'Congés'
|
|
assert unavailability_calendar._noel
|
|
assert unavailability_calendar._sample_ics
|
|
assert agenda_1.label == 'Agenda 1'
|
|
assert agenda_1.maximal_booking_delay == 15
|
|
assert agenda_1._desk_1._greve
|
|
assert agenda_1._desk_1._sample_ics
|
|
assert agenda_1._desk_1
|
|
assert agenda_1._desk_1._conges == unavailability_calendar
|
|
assert agenda_1._bureau_2
|
|
assert agenda_1._mt_30
|
|
assert agenda_1._mt_45
|
|
assert agenda_2.label == 'Agenda 2'
|
|
assert agenda_2._desk_1
|
|
assert agenda_2._desk_2
|
|
assert agenda_2._mt_30
|
|
assert virtual._cni._bureau1
|
|
assert virtual._cni._mt_30
|
|
assert virtual._mt_30
|
|
assert virtual._passeport._bureau2
|
|
assert virtual._passeport._mt_30
|
|
|
|
|
|
def test_build_agendas_indentation_mismatch(db):
|
|
with pytest.raises(SyntaxError, match=r'on line 5'):
|
|
build_agendas(
|
|
'''
|
|
agenda xxx
|
|
zobi dd
|
|
kkk
|
|
iii # here, bad indentation
|
|
|
|
agenda "Agenda 1" 30
|
|
desk 1
|
|
desk 2
|
|
'''
|
|
)
|
|
|
|
|
|
def test_paris():
|
|
assert paris('2023-04-19T11:00:00').isoformat() == '2023-04-19T11:00:00+02:00'
|
|
|
|
|
|
def test_utc():
|
|
assert utc('2023-04-19T11:00:00').isoformat() == '2023-04-19T11:00:00+00:00'
|