barbacompta/tests/test_conges.py

436 lines
16 KiB
Python

import datetime
from unittest import mock
import pytest
import vobject
from django.utils.html import escape
from eo_gestion.eo_conges.views import ReportError
from .utils import login
@pytest.fixture
def events():
with mock.patch('caldav.davclient.DAVClient.principal') as mocked_principal:
mocked_principal.side_effet = FakePrincipal()
yield
def get_event(summary, start, end, category='Congés'):
event = vobject.newFromBehavior('vevent')
event = event.transformToNative()
event.add('summary').value = summary
event.add('dtstart').value = start
event.add('dtend').value = end
event.add('categories').value = [category]
return event
def test_conges_redirect(app, settings):
login(app)
resp = app.get('/conges/')
assert resp.location == '/conges/2019/1/'
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
events = mocked_get_events.return_value = []
login(app)
resp = app.get('/conges/2023/01/')
assert [x.text for x in resp.pyquery('.worker span')] == [
'Jean Dupont (matricule 42)',
'Tickets restaurant : 19 tickets de 8 euros',
'Congés : 0.',
]
assert '/conges/2022/12/' in resp.text
assert '/conges/2023/2/' in resp.text
events.append(
get_event('Jean', datetime.datetime(2023, 1, 2, 8, 00), datetime.datetime(2023, 1, 2, 18, 00))
)
resp = app.get('/conges/2023/01/')
assert [x.text for x in resp.pyquery('.worker span')] == [
'Jean Dupont (matricule 42)',
'Tickets restaurant : 19 tickets de 8 euros',
'Congés : le 02/01.',
]
events += [
# one day, using dates
get_event('Jean', datetime.date(2023, 1, 4), datetime.date(2023, 1, 5)),
# two days range, using mixed date/datetimes
get_event('Jean', datetime.datetime(2023, 1, 10, 8, 00), datetime.datetime(2023, 1, 11)),
# two days range, using dates
get_event('Jean', datetime.date(2023, 1, 12), datetime.date(2023, 1, 14)),
# 4 days range, using dates
get_event('Jean', datetime.date(2023, 1, 16), datetime.date(2023, 1, 20)),
# only morning
get_event('Jean', datetime.datetime(2023, 1, 23, 8, 00), datetime.datetime(2023, 1, 23, 14, 00)),
# only afternoon
get_event('Jean', datetime.datetime(2023, 1, 24, 14, 00), datetime.datetime(2023, 1, 24, 18, 00)),
]
# 6 days range, using rrule
event = get_event('Jean', datetime.date(2023, 1, 25), datetime.date(2023, 1, 26))
event.add('rrule').value = 'FREQ=DAILY;UNTIL=20230131'
events.append(event)
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == (
'Congés : le 02/01, le 04/01, les 10 et 11/01, les 12 et 13/01, du 16 au 19/01, 0,5j le 23/01, '
'0,5j le 24/01, du 25 au 31/01.'
)
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_fatal_errors(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
mocked_get_events.side_effect = ReportError('Error xxx')
login(app)
resp = app.get('/conges/2023/01/')
assert 'Error xxx' in resp.text
app.get('/conges/2023/42/', status=404)
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_multiple_match_error(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
{'username': 'jdurand', 'display_name': 'Jean Durand', 'number': 43},
]
mocked_get_events.return_value = [
get_event('Jean', datetime.date(2023, 1, 6), datetime.date(2023, 1, 10)),
]
login(app)
resp = app.get('/conges/2023/01/')
assert (
escape("L'évènement Jean correspond à plusieurs coopérateurices : jdurand et jdupont.") in resp.text
)
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_no_match_error(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
mocked_get_events.return_value = [
get_event('Jean', datetime.date(2023, 1, 6), datetime.date(2023, 1, 7)),
get_event('xxx', datetime.date(2023, 1, 8), datetime.date(2023, 1, 9)),
get_event('yyy', datetime.date(2023, 1, 8), datetime.date(2023, 1, 9)),
]
login(app)
resp = app.get('/conges/2023/01/')
assert escape('Aucun·e coopérateurice trouvé·e pour les évènements : xxx, yyy') in resp.text
assert 'le 06/01' in resp.text
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_day_off_error(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
mocked_get_events.return_value = []
login(app)
resp = app.get('/conges/2023/01/')
assert escape("Jean Dupont n'a pas de jour off.") in resp.text
ev1 = get_event('Jean off', datetime.date(2023, 1, 6), datetime.date(2023, 1, 7), category='Journées off')
ev1.add('rrule').value = 'FREQ=WEEKLY;BYDAY=MO'
ev2 = get_event(
'Jean off 2', datetime.date(2023, 1, 8), datetime.date(2023, 1, 9), category='Journées off'
)
ev2.add('rrule').value = 'FREQ=WEEKLY;BYDAY=WE'
mocked_get_events.return_value = [ev1, ev2]
resp = app.get('/conges/2023/01/')
assert 'Jean Dupont a trop de jours off : Jean off, Jean off 2.' in resp.text
ev1.dtstart.value = datetime.datetime(2023, 1, 6, 8, 0)
ev1.dtend.value = datetime.datetime(2023, 1, 6, 13, 0)
ev2.dtstart.value = datetime.datetime(2023, 1, 9, 14, 0)
ev2.dtend.value = datetime.datetime(2023, 1, 9, 19, 0)
resp = app.get('/conges/2023/01/')
assert 'Jean Dupont a trop de jours off' not in resp.text
ev3 = get_event(
'Jean off 3',
datetime.datetime(2023, 1, 9, 14, 0),
datetime.datetime(2023, 1, 10, 19, 0),
category='Journées off',
)
ev3.add('rrule').value = 'FREQ=WEEKLY;BYDAY=TH'
mocked_get_events.return_value.append(ev3)
resp = app.get('/conges/2023/01/')
assert 'Jean Dupont a trop de jours off : Jean off, Jean off 2, Jean off 3.' in resp.text
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_is_parisian(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
mocked_get_events.return_value = []
login(app)
resp = app.get('/conges/2023/01/')
assert 'Carte transport Paris 50%' not in resp.text
settings.WORKERS_CALENDAR_CONFIG['workers'][0]['is_parisian'] = True
resp = app.get('/conges/2023/01/')
assert 'Carte transport Paris 50%' in resp.text
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_ignored_workers(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
{'username': 'lmichel', 'display_name': 'Louise Michel', 'number': 0, 'ignore': True},
]
mocked_get_events.return_value = [
get_event('congés jdupont', datetime.date(2023, 1, 2), datetime.date(2023, 1, 3)),
get_event('congés lmichel', datetime.date(2023, 1, 3), datetime.date(2023, 1, 4)),
]
login(app)
resp = app.get('/conges/2023/01/')
assert 'Jean' in resp.text
assert 'Louise' not in resp.text
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_worker_possible_names(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
{'username': 'jmartin', 'display_name': 'Jean Martin', 'number': 43, 'aliases': ['Jeannot']},
]
mocked_get_events.return_value = [
get_event('congés jdupont', datetime.date(2023, 1, 2), datetime.date(2023, 1, 3)),
get_event('Jeannot en vacances', datetime.date(2023, 1, 3), datetime.date(2023, 1, 4)),
get_event('congés JD', datetime.date(2023, 1, 5), datetime.date(2023, 1, 6)),
get_event('JeanM', datetime.date(2023, 1, 6), datetime.date(2023, 1, 7)),
]
login(app)
resp = app.get('/conges/2023/01/')
assert [x.text for x in resp.pyquery('.worker span.holidays')] == [
'Congés : le 02/01, le 05/01.',
'Congés : le 03/01, le 06/01.',
]
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_strip_weekend(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
mocked_get_events.return_value = [
# starts friday, ends monday
get_event('Jean', datetime.date(2023, 1, 6), datetime.date(2023, 1, 10)),
# start saturday, ends sunday next week
get_event('Jean', datetime.date(2023, 1, 14), datetime.date(2023, 1, 23)),
# two days of weekend
get_event('Jean', datetime.date(2023, 1, 28), datetime.date(2023, 1, 30)),
]
login(app)
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : du 06 au 09/01, du 16 au 20/01.'
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_month_span(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
mocked_get_events.return_value = [
# starts in december
get_event('Jean', datetime.date(2022, 12, 25), datetime.date(2023, 1, 5)),
# ends in february
get_event('Jean', datetime.date(2023, 1, 30), datetime.date(2023, 2, 10)),
]
login(app)
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : du 02 au 04/01, les 30 et 31/01.'
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_split_on_day_off(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
holidays = get_event('Jean', datetime.date(2023, 1, 2), datetime.date(2023, 1, 7))
events = mocked_get_events.return_value = [holidays]
login(app)
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : du 02 au 06/01.'
# off on wednesday, holidays split in half
event = get_event('Jean', datetime.date(2023, 1, 4), datetime.date(2023, 1, 5), category='Journées off')
event.add('rrule').value = 'FREQ=WEEKLY;BYDAY=WE'
events.append(event)
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : les 02 et 03/01, les 05 et 06/01.'
# off on friday, holidays end one day sooner
event.rrule.value = 'FREQ=WEEKLY;BYDAY=FR'
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : du 02 au 05/01.'
# off on monday, holidays start one day later
event.rrule.value = 'FREQ=WEEKLY;BYDAY=MO'
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : du 03 au 06/01.'
# long holidays get split multiple times
holidays.dtend.value = datetime.date(2023, 1, 21)
resp = app.get('/conges/2023/01/')
assert (
resp.pyquery('.worker span.holidays').text()
== 'Congés : du 03 au 06/01, du 10 au 13/01, du 17 au 20/01.'
)
# split on wednesday
event.rrule.value = 'FREQ=WEEKLY;BYDAY=WE'
resp = app.get('/conges/2023/01/')
assert (
resp.pyquery('.worker span.holidays').text()
== 'Congés : les 02 et 03/01, du 05 au 10/01, du 12 au 17/01, les 19 et 20/01.'
)
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_split_on_multiple_days_off(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
holidays = get_event('Jean', datetime.date(2023, 1, 2), datetime.date(2023, 1, 7))
events = mocked_get_events.return_value = [holidays]
login(app)
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : du 02 au 06/01.'
ev1 = get_event(
'Jean off lundi matin',
datetime.datetime(2023, 1, 6, 8, 0),
datetime.datetime(2023, 1, 6, 13, 0),
category='Journées off',
)
ev1.add('rrule').value = 'FREQ=WEEKLY;BYDAY=MO'
ev2 = get_event(
'Jean off mercredi aprem',
datetime.datetime(2023, 1, 9, 14, 0),
datetime.datetime(2023, 1, 9, 19, 0),
category='Journées off',
)
ev2.add('rrule').value = 'FREQ=WEEKLY;BYDAY=WE'
mocked_get_events.return_value += [ev1, ev2]
resp = app.get('/conges/2023/01/')
assert (
resp.pyquery('.worker span.holidays').text()
== 'Congés : 0,5j le 02/01, le 03/01, 0,5j le 04/01, les 05 et 06/01.'
)
# long holidays get split multiple times
holidays.dtend.value = datetime.date(2023, 1, 14)
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == (
'Congés : 0,5j le 02/01, le 03/01, 0,5j le 04/01, les 05 et 06/01, 0,5j le 09/01, '
'le 10/01, 0,5j le 11/01, les 12 et 13/01.'
)
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_split_on_day_off_single_day(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
# off on wednesday
off_event = get_event(
'Jean', datetime.date(2023, 1, 4), datetime.date(2023, 1, 5), category='Journées off'
)
off_event.add('rrule').value = 'FREQ=WEEKLY;BYDAY=WE'
mocked_get_events.return_value = [
off_event,
# holidays on monday
get_event('Jean', datetime.date(2023, 1, 2), datetime.date(2023, 1, 3)),
]
login(app)
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : le 02/01.'
# off on monday
off_event.rrule.value = 'FREQ=WEEKLY;BYDAY=MO'
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : 0.'
@mock.patch('eo_gestion.eo_conges.views.WorkersMonthlyReport.get_events')
def test_conges_split_on_multiple_days_off_single_day(mocked_get_events, app, settings):
settings.WORKERS_CALENDAR_CONFIG['workers'] = [
{'username': 'jdupont', 'display_name': 'Jean Dupont', 'number': 42},
]
ev1 = get_event(
'Jean off lundi matin',
datetime.datetime(2023, 1, 6, 8, 0),
datetime.datetime(2023, 1, 6, 13, 0),
category='Journées off',
)
ev1.add('rrule').value = 'FREQ=WEEKLY;BYDAY=MO'
ev2 = get_event(
'Jean off mercredi aprem',
datetime.datetime(2023, 1, 9, 14, 0),
datetime.datetime(2023, 1, 9, 19, 0),
category='Journées off',
)
ev2.add('rrule').value = 'FREQ=WEEKLY;BYDAY=WE'
mocked_get_events.return_value = [
ev1,
ev2,
# holidays on monday
get_event('Jean', datetime.date(2023, 1, 2), datetime.date(2023, 1, 3)),
]
login(app)
resp = app.get('/conges/2023/01/')
assert resp.pyquery('.worker span.holidays').text() == 'Congés : 0,5j le 02/01.'