2022-03-22 16:30:55 +01:00
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
import vobject
|
|
|
|
|
from httmock import HTTMock, with_httmock
|
|
|
|
|
|
|
|
|
|
from passerelle.apps.holidays.models import Holidays
|
|
|
|
|
|
|
|
|
|
from .test_manager import login
|
|
|
|
|
|
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
|
|
|
|
|
|
with open(os.path.join(os.path.dirname(__file__), 'data/holidays/Zone-A.ics')) as fd:
|
|
|
|
|
RESPONSE_ZONE_A = fd.read()
|
|
|
|
|
|
|
|
|
|
with open(os.path.join(os.path.dirname(__file__), 'data/holidays/Zone-B.ics')) as fd:
|
|
|
|
|
RESPONSE_ZONE_B = fd.read()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def ics_data(url, request):
|
2022-05-31 14:19:00 +02:00
|
|
|
|
if url.path == '/openscol/fr-en-calendrier-scolaire/Zone-A.ics':
|
2022-03-22 16:30:55 +01:00
|
|
|
|
return {'content': RESPONSE_ZONE_A, 'request': request, 'status_code': 200}
|
2022-05-31 14:19:00 +02:00
|
|
|
|
if url.path == '/openscol/fr-en-calendrier-scolaire/Zone-B.ics':
|
2022-03-22 16:30:55 +01:00
|
|
|
|
return {'content': RESPONSE_ZONE_B, 'request': request, 'status_code': 200}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@with_httmock(ics_data)
|
|
|
|
|
def test_holidays_ics(app):
|
|
|
|
|
connector = Holidays.objects.create(slug='test', zone='a', holidays=[])
|
|
|
|
|
|
|
|
|
|
resp = app.get('/holidays/test/holidays.ics')
|
|
|
|
|
calendar = vobject.readOne(resp.text)
|
|
|
|
|
assert not 'vevent' in calendar.contents
|
|
|
|
|
|
|
|
|
|
connector.holidays.append('winter_holidays')
|
|
|
|
|
connector.save()
|
|
|
|
|
|
|
|
|
|
resp = app.get('/holidays/test/holidays.ics')
|
|
|
|
|
calendar = vobject.readOne(resp.text)
|
|
|
|
|
first_event = calendar.contents['vevent'][0]
|
|
|
|
|
assert first_event.uid.value == 'winter_holidays-2018'
|
|
|
|
|
assert first_event.summary.value == 'Vacances d’Hiver'
|
|
|
|
|
assert first_event.categories.value == ['winter_holidays']
|
|
|
|
|
assert str(first_event.dtstart.value) == '2018-02-10'
|
|
|
|
|
assert str(first_event.dtend.value) == '2018-02-26'
|
|
|
|
|
|
|
|
|
|
for i, event in enumerate(calendar.contents['vevent'][1:], start=2019):
|
|
|
|
|
assert event.uid.value == 'winter_holidays-%s' % i
|
|
|
|
|
assert event.summary.value == 'Vacances d’Hiver'
|
|
|
|
|
assert event.categories.value == ['winter_holidays']
|
|
|
|
|
|
|
|
|
|
connector.zone = 'b'
|
|
|
|
|
connector.save()
|
|
|
|
|
|
|
|
|
|
resp = app.get('/holidays/test/holidays.ics')
|
|
|
|
|
calendar = vobject.readOne(resp.text)
|
|
|
|
|
first_event = calendar.contents['vevent'][0]
|
|
|
|
|
assert first_event.uid.value == 'winter_holidays-2018'
|
|
|
|
|
assert str(first_event.dtstart.value) == '2018-02-24'
|
|
|
|
|
assert str(first_event.dtend.value) == '2018-03-12'
|
|
|
|
|
|
|
|
|
|
connector.holidays.append('summer_holidays')
|
|
|
|
|
connector.save()
|
|
|
|
|
|
|
|
|
|
resp = app.get('/holidays/test/holidays.ics')
|
|
|
|
|
calendar = vobject.readOne(resp.text)
|
|
|
|
|
assert calendar.contents['vevent'][0].uid.value == 'winter_holidays-2018'
|
|
|
|
|
first_summer_event = next(x for x in calendar.contents['vevent'] if x.uid.value.startswith('summer'))
|
|
|
|
|
assert first_summer_event.uid.value == 'summer_holidays-2018'
|
|
|
|
|
assert first_summer_event.summary.value == 'Vacances d’Été'
|
|
|
|
|
assert first_summer_event.categories.value == ['summer_holidays']
|
|
|
|
|
assert str(first_summer_event.dtstart.value) == '2018-07-07'
|
|
|
|
|
assert str(first_summer_event.dtend.value) == '2018-09-03'
|
|
|
|
|
|
|
|
|
|
connector.holidays = [
|
|
|
|
|
'winter_holidays',
|
|
|
|
|
'spring_holidays',
|
|
|
|
|
'summer_holidays',
|
|
|
|
|
'all_saints_holidays',
|
|
|
|
|
'christmas_holidays',
|
|
|
|
|
]
|
|
|
|
|
connector.save()
|
|
|
|
|
|
|
|
|
|
resp = app.get('/holidays/test/holidays.ics')
|
|
|
|
|
calendar = vobject.readOne(resp.text)
|
|
|
|
|
holiday_ids = {x.categories.value[0] for x in calendar.contents['vevent']}
|
|
|
|
|
assert all(holiday_id in holiday_ids for holiday_id in connector.holidays)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_holidays_ics_invalid_responses(app):
|
|
|
|
|
Holidays.objects.create(slug='test', zone='a', holidays=[])
|
|
|
|
|
|
|
|
|
|
def server_error(url, request):
|
|
|
|
|
return {'content': 'error', 'status_code': 500}
|
|
|
|
|
|
|
|
|
|
with HTTMock(server_error):
|
|
|
|
|
resp = app.get('/holidays/test/holidays.ics')
|
|
|
|
|
assert resp.json['err'] == 1
|
|
|
|
|
assert 'Error while getting ICS file' in resp.json['err_desc']
|
|
|
|
|
|
|
|
|
|
def invalid_file(url, request):
|
|
|
|
|
return {'content': 'invalid', 'status_code': 200}
|
|
|
|
|
|
|
|
|
|
with HTTMock(invalid_file):
|
|
|
|
|
resp = app.get('/holidays/test/holidays.ics')
|
|
|
|
|
assert resp.json['err'] == 1
|
|
|
|
|
assert 'Invalid ICS file' in resp.json['err_desc']
|
|
|
|
|
|
|
|
|
|
def empty_file(url, request):
|
|
|
|
|
return {
|
|
|
|
|
'content': 'BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//PYVOBJECT//NONSGML Version 1//EN\r\nEND:VCALENDAR\r\n',
|
|
|
|
|
'status_code': 200,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
with HTTMock(empty_file):
|
|
|
|
|
resp = app.get('/holidays/test/holidays.ics')
|
|
|
|
|
assert resp.json['err'] == 1
|
|
|
|
|
assert 'ICS file does not contain events' in resp.json['err_desc']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_holidays_manager(app, admin_user):
|
|
|
|
|
login(app)
|
|
|
|
|
|
|
|
|
|
resp = app.get('/manage/holidays/add')
|
|
|
|
|
resp.form['title'] = 'Holidays'
|
|
|
|
|
resp.form['slug'] = 'test'
|
|
|
|
|
resp.form['description'] = 'test'
|
|
|
|
|
resp.form['zone'] = 'c'
|
|
|
|
|
resp.form['holidays'] = ['summer_holidays', 'christmas_holidays']
|
|
|
|
|
|
|
|
|
|
resp = resp.form.submit().follow()
|
2022-09-29 17:54:55 +02:00
|
|
|
|
assert 'Holidays: Vacances d’Été, Vacances de Noël' in resp.text
|
|
|
|
|
assert 'Zone: C' in resp.text
|