passerelle/tests/test_caluire_axel.py

4476 lines
178 KiB
Python

# passerelle - uniform access to multiple data sources and services
# Copyright (C) 2021 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime
import os
import xml.etree.ElementTree as ET
from contextlib import contextmanager
from unittest import mock
import freezegun
import pytest
import xmlschema
import tests.utils
from passerelle.contrib.caluire_axel import schemas
from passerelle.contrib.caluire_axel.models import CaluireAxel, Link
from passerelle.contrib.utils.axel import AxelError, OperationResult, json_date_format, xml_date_format
from passerelle.utils.soap import SOAPError
XML_RESPONSE_TEMPLATE = '''<?xml version="1.0"?>
<PORTAILSERVICE>
<RESULTAT>
<TYPE>%s</TYPE>
<STATUS>OK</STATUS>
<DATE>10/10/2010 10:10:01</DATE>
<COMMENTAIRES><![CDATA[]]></COMMENTAIRES>
</RESULTAT>
<DATA>
%s
</DATA>
</PORTAILSERVICE>'''
@pytest.fixture
def resource(db):
return tests.utils.make_resource(
CaluireAxel, slug='test', wsdl_url='http://example.net/AXEL_WS/AxelWS.php?wsdl'
)
@pytest.fixture
def link_params():
return {
'IDENTFAMILLE': '12345',
'NOM': 'Doe',
'PRENOM': 'John',
}
@pytest.fixture
def family_data():
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
resp = XML_RESPONSE_TEMPLATE % ('GetFamilleIndividus', content)
return schemas.get_famille_individus.response_converter.decode(ET.fromstring(resp))['DATA']['PORTAIL'][
'GETFAMILLE'
]
@pytest.fixture
def register_activity_params():
return {
'activity_id': 'CANTINE',
'child_id': '50632',
'registration_start_date': '2020-09-01',
'registration_end_date': '2021-08-31',
}
@pytest.fixture
def activities():
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
resp = XML_RESPONSE_TEMPLATE % ('GetListActivites', content)
return schemas.get_list_activites.response_converter.decode(ET.fromstring(resp))['DATA']['PORTAIL'][
'GETLISTACTIVITES'
]
@pytest.fixture
def activities_full():
return {
'ACTIVITE': [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'GARDERIES',
'LIBELLEACTIVITE': 'Garderie',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ACCMAT',
'LIBELLEACTIVITE': 'Matin',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'CJ MER',
'LIBELLEACTIVITE': 'Mercredi',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ETUDES',
'LIBELLEACTIVITE': 'Etudes',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'CJ1',
'LIBELLEACTIVITE': 'Des vacances',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ECOLELEM',
'LIBELLEACTIVITE': 'Cantine',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'NAV MATIN',
'LIBELLEACTIVITE': 'Navette du matin',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'NAV SOIR',
'LIBELLEACTIVITE': 'Navette du soir',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'DECFOO',
'LIBELLEACTIVITE': 'Une classe découverte',
},
]
}
@pytest.fixture
def booking_params():
return {
'child_id': '50632',
'booking_list': [],
'start_date': '2020-09-01',
'end_date': '2021-08-31',
}
@pytest.fixture
def changes_params():
return {
'child_id': '50632',
'changes': [],
'start_date': '2020-09-01',
'end_date': '2021-08-31',
}
@pytest.fixture
def week_booking_params():
return {
'child_id': '50632',
'activity_id': 'ELEM',
'booking_list': [],
'start_date': '2020-09-01',
'end_date': '2021-08-31',
}
@pytest.fixture
def upload_attachments_params():
return {
'child_id': '50632',
'reference_date': '2020-09-01',
'attachments': [
{
'attachment_type': '1234',
'label': 'ID card',
'url': 'https://example.org/file1.pdf',
},
{
'attachment_type': '1234',
'label': 'Passport',
'url': 'https://example.org/file2.pdf',
},
],
}
@contextmanager
def mock_data(content, operation, data_method='getData'):
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.soap_client') as client:
resp = XML_RESPONSE_TEMPLATE % (operation, content)
getattr(client.return_value.service, data_method).return_value = resp
yield
def test_operation_status_error(resource):
resp = '''
<?xml version="1.0"?>
<PORTAILSERVICE>
<RESULTAT>
<TYPE>FindIndividus</TYPE>
<STATUS>NOK</STATUS>
<COMMENTAIRES><![CDATA[Foo reason]]></COMMENTAIRES>
</RESULTAT>
<DATA>
<PORTAIL/>
</DATA>
</PORTAILSERVICE>
'''.strip()
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.soap_client') as client:
client.return_value.service.getData.return_value = resp
with pytest.raises(AxelError, match='Foo reason'):
schemas.find_individus(
resource,
{
'PORTAIL': {
'FINDINDIVIDU': {
'NOM': 'Doe',
'PRENOM': 'John',
'NAISSANCE': None,
'CODEPOSTAL': None,
'VILLE': None,
'TEL': None,
'MAIL': None,
}
}
},
)
def test_link_endpoint_nameid_empty(app, resource, link_params):
resp = app.post_json('/caluire-axel/test/link?NameID=', params=link_params, status=400)
assert resp.json['err_desc'] == 'NameID is empty'
assert resp.json['err'] == 'bad-request'
def test_link_endpoint_axel_error(app, resource, link_params):
with mock.patch('passerelle.contrib.caluire_axel.schemas.find_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
assert resp.json['data'] == {'xml_request': None, 'xml_response': None}
# test xml_request and xml_response only for this endpoint
xml_request = """<PORTAIL>
<FINDINDIVIDU>
<NOM>Doe</NOM>
<PRENOM>John</PRENOM>
<NAISSANCE />
<CODEPOSTAL />
<VILLE />
<TEL />
<MAIL />
</FINDINDIVIDU>
</PORTAIL>
"""
with mock_data('', 'FindIndividus'):
with mock.patch('xmlschema.XMLSchema.validate') as xml_validate:
xml_validate.side_effect = xmlschema.XMLSchemaValidationError(None, None)
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert resp.json['err_desc'].startswith('Axel error: invalid request')
assert resp.json['err'] == 'error'
assert resp.json['data']['xml_request'] == xml_request
assert resp.json['data']['xml_response'] is None
xml_response = """<PORTAILSERVICE>
<RESULTAT>
<TYPE>FINDINDIVIDUS</TYPE>
<STATUS>NOK</STATUS>
<COMMENTAIRES>Foo reason</COMMENTAIRES>
</RESULTAT>
<DATA>
<PORTAIL />
</DATA>
</PORTAILSERVICE>"""
response = """
<?xml version="1.0"?>
<PORTAILSERVICE>
<RESULTAT>
<TYPE>FINDINDIVIDUS</TYPE>
<STATUS>NOK</STATUS>
<COMMENTAIRES><![CDATA[Foo reason]]></COMMENTAIRES>
</RESULTAT>
<DATA>
<PORTAIL/>
</DATA>
</PORTAILSERVICE>
""".strip()
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.soap_client') as client:
client.return_value.service.getData.return_value = response
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert resp.json['err_desc'] == 'Axel error: Foo reason'
assert resp.json['err'] == 'error'
assert resp.json['data']['xml_request'] == xml_request
assert resp.json['data']['xml_response'] == xml_response
content = """<PORTAIL>
<FINDINDIVIDUS>
<INDIVIDU>
<IDENT>123</IDENT>
<NOM>Doe</NOM>
<PRENOM>John</PRENOM>
<FAMILLE>
<IDENTFAMILLE>12345</IDENTFAMILLE>
<PLACE>2</PLACE>
</FAMILLE>
</INDIVIDU>
</FINDINDIVIDUS>
</PORTAIL>"""
xml_response = (
"""<PORTAILSERVICE>
<RESULTAT>
<TYPE>FindIndividus</TYPE>
<STATUS>OK</STATUS>
<DATE>10/10/2010 10:10:01</DATE>
<COMMENTAIRES />
</RESULTAT>
<DATA>
%s
</DATA>
</PORTAILSERVICE>"""
% content
)
with mock_data(content, 'FindIndividus'):
with mock.patch('passerelle.contrib.utils.axel.AxelSchema.decode') as decode:
decode.side_effect = xmlschema.XMLSchemaValidationError(None, None)
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert resp.json['err_desc'].startswith('Axel error: invalid response')
assert resp.json['err'] == 'error'
assert resp.json['data']['xml_request'] == xml_request
assert resp.json['data']['xml_response'] == xml_response
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.soap_client') as client:
client.side_effect = SOAPError('SOAP service is down')
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert resp.json['err_desc'] == 'SOAP service is down'
@pytest.mark.parametrize(
'xml_response',
[
'',
"""<INDIVIDU>
<IDENT>123</IDENT>
<CIVILITE/><NOM>A</NOM><PRENOM/><NAISSANCE/><SEXE/><NOMJF/><TELFIXE/><TELPORTABLE/><MAIL/><CSP/><EMPLOYEUR/><VILLEEMP/><PAI>N</PAI><GARDEALTERNEE/>
<FAMILLE>
<IDENTFAMILLE>12346</IDENTFAMILLE>
<PLACE>2</PLACE>
<SITUATION/>
</FAMILLE>
<FAMILLE>
<IDENTFAMILLE>12347</IDENTFAMILLE>
<PLACE>1</PLACE>
</FAMILLE>
</INDIVIDU>""",
"""<INDIVIDU>
<IDENT>123</IDENT>
<CIVILITE/><NOM>A</NOM><PRENOM/><NAISSANCE/><SEXE/><NOMJF/><TELFIXE/><TELPORTABLE/><MAIL/><CSP/><EMPLOYEUR/><VILLEEMP/><PAI>N</PAI><GARDEALTERNEE/>
<FAMILLE>
<IDENTFAMILLE>12345</IDENTFAMILLE>
<PLACE>3</PLACE>
<SITUATION/>
</FAMILLE>
</INDIVIDU>""",
],
)
def test_link_endpoint_no_result(app, resource, link_params, xml_response):
content = (
'''<PORTAIL>
<FINDINDIVIDUS>
<CODE>42</CODE>
%s
</FINDINDIVIDUS>
</PORTAIL>'''
% xml_response
)
with mock_data(content, 'FindIndividus'):
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
def test_link_endpoint_conflict(app, resource, link_params):
content = """<PORTAIL><FINDINDIVIDUS>
<CODE>42</CODE>
<INDIVIDU>
<IDENT>123</IDENT>
<CIVILITE/><NOM>A</NOM><PRENOM/><NAISSANCE/><SEXE/><NOMJF/><TELFIXE/><TELPORTABLE/><MAIL/><CSP/><EMPLOYEUR/><VILLEEMP/><PAI>N</PAI><GARDEALTERNEE/>
<FAMILLE>
<IDENTFAMILLE>12345</IDENTFAMILLE>
<PLACE>2</PLACE>
<SITUATION/>
</FAMILLE>
</INDIVIDU>
</FINDINDIVIDUS></PORTAIL>"""
# existing link but family_id is wrong
link = Link.objects.create(resource=resource, name_id='yyy', family_id='YYY', person_id='42')
with mock_data(content, 'FindIndividus'):
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert resp.json['err_desc'] == 'Data conflict'
assert resp.json['err'] == 'conflict'
# existing link but person_id is wrong
link.family_id = '12345'
link.person_id = '35'
link.save()
with mock_data(content, 'FindIndividus'):
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert resp.json['err_desc'] == 'Data conflict'
assert resp.json['err'] == 'conflict'
@pytest.mark.parametrize('place', [1, 2])
def test_link_endpoint(app, resource, link_params, place):
content = (
"""<PORTAIL><FINDINDIVIDUS>
<CODE>42</CODE>
<INDIVIDU>
<IDENT>123</IDENT>
<CIVILITE/><NOM>A</NOM><PRENOM/><NAISSANCE/><SEXE/><NOMJF/><TELFIXE/><TELPORTABLE/><MAIL/><CSP/><EMPLOYEUR/><VILLEEMP/><PAI>N</PAI><GARDEALTERNEE/>
<FAMILLE>
<IDENTFAMILLE>12345</IDENTFAMILLE>
<PLACE>%s</PLACE>
<SITUATION/>
</FAMILLE>
</INDIVIDU>
</FINDINDIVIDUS></PORTAIL>"""
% place
)
with mock_data(content, 'FindIndividus'):
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert set(resp.json.keys()) == {'err', 'link', 'created', 'family_id', 'data'}
assert resp.json['err'] == 0
assert resp.json['family_id'] == '12345'
assert resp.json['created'] is True
assert 'xml_request' in resp.json['data']
assert 'xml_response' in resp.json['data']
# again
with mock_data(content, 'FindIndividus'):
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert set(resp.json.keys()) == {'err', 'link', 'created', 'family_id', 'data'}
assert resp.json['err'] == 0
assert resp.json['family_id'] == '12345'
assert resp.json['created'] is False # link already exists
assert 'xml_request' in resp.json['data']
assert 'xml_response' in resp.json['data']
def test_link_endpoint_having_homonyme_with_empty_familly(app, resource, link_params):
content = """<PORTAIL><FINDINDIVIDUS>
<CODE>42</CODE>
<INDIVIDU>
<IDENT>123</IDENT>
<CIVILITE/><NOM>A</NOM><PRENOM/><NAISSANCE/><SEXE/><NOMJF/><TELFIXE/><TELPORTABLE/><MAIL/><CSP/><EMPLOYEUR/><VILLEEMP/><PAI>N</PAI><GARDEALTERNEE/>
</INDIVIDU>
<INDIVIDU>
<IDENT>456</IDENT>
<CIVILITE/><NOM>A</NOM><PRENOM/><NAISSANCE/><SEXE/><NOMJF/><TELFIXE/><TELPORTABLE/><MAIL/><CSP/><EMPLOYEUR/><VILLEEMP/><PAI>N</PAI><GARDEALTERNEE/>
<FAMILLE>
<IDENTFAMILLE>12345</IDENTFAMILLE>
<PLACE>2</PLACE>
<SITUATION/>
</FAMILLE>
</INDIVIDU>
</FINDINDIVIDUS></PORTAIL>"""
with mock_data(content, 'FindIndividus'):
resp = app.post_json('/caluire-axel/test/link?NameID=yyy', params=link_params)
assert resp.json['err'] == 0
assert resp.json['family_id'] == '12345'
assert resp.json['created'] is True
def test_unlink_endpoint_no_result(app, resource):
resp = app.post('/caluire-axel/test/unlink?NameID=yyy')
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
def test_unlink_endpoint(app, resource):
link = Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
resp = app.post('/caluire-axel/test/unlink?NameID=yyy')
assert Link.objects.exists() is False
assert resp.json['err'] == 0
assert resp.json['link'] == link.pk
assert resp.json['family_id'] == 'XXX'
assert resp.json['deleted'] is True
def test_family_info_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get('/caluire-axel/test/family_info?NameID=yyy')
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_family_info_endpoint_no_result(app, resource):
resp = app.get('/caluire-axel/test/family_info?NameID=yyy')
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
def test_family_info_endpoint(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get('/caluire-axel/test/family_info?NameID=yyy')
assert resp.json['err'] == 0
assert set(resp.json['data'].keys()) == {'family_id', 'CODE', 'MEMBRE', 'RESPONSABLE1', 'RESPONSABLE2'}
assert resp.json['data']['CODE'] == 0
assert resp.json['data']['family_id'] == 'XXX'
assert resp.json['data']['MEMBRE'][0]['id'] == '50632'
assert resp.json['data']['MEMBRE'][0]['text'] == 'Enfant 1 CALUIRE TEST'
assert resp.json['data']['MEMBRE'][1]['id'] == '50633'
assert resp.json['data']['MEMBRE'][1]['text'] == 'Enfant 2 CALUIRE TEST'
assert resp.json['data']['MEMBRE'][2]['id'] == '54621'
assert resp.json['data']['MEMBRE'][2]['text'] == 'Enfant 3 CALUIRE TEST'
assert resp.json['data']['MEMBRE'][3]['id'] == '59509'
assert resp.json['data']['MEMBRE'][3]['text'] == 'Enfant 5 CALUIRE TEST'
assert resp.json['data']['RESPONSABLE1']['IDENT'] == '50630'
# again - data are in cache
resp = app.get('/caluire-axel/test/family_info?NameID=yyy')
assert resp.json['err'] == 0
# misordered XML (one MEMBER before RESPONSABLE1)
Link.objects.create(resource=resource, name_id='bar', family_id='YYY', person_id='24')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info_misordered.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get('/caluire-axel/test/family_info?NameID=bar')
assert resp.json['err'] == 0
assert set(resp.json['data'].keys()) == {'family_id', 'CODE', 'MEMBRE', 'RESPONSABLE1', 'RESPONSABLE2'}
assert resp.json['data']['family_id'] == 'YYY'
assert resp.json['data']['MEMBRE'][0]['id'] == '11111'
assert resp.json['data']['MEMBRE'][0]['text'] == 'CALUIRE TEST'
assert resp.json['data']['MEMBRE'][1]['id'] == '22222'
assert resp.json['data']['MEMBRE'][1]['text'] == 'Enfant 2 CALUIRE TEST'
def test_children_info_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get('/caluire-axel/test/children_info?NameID=yyy')
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_children_info_endpoint_no_result(app, resource):
resp = app.get('/caluire-axel/test/children_info?NameID=yyy')
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
def test_children_info_endpoint(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get('/caluire-axel/test/children_info?NameID=yyy')
assert resp.json['err'] == 0
assert len(resp.json['data']) == 4
assert resp.json['data'][0]['id'] == '50632'
assert resp.json['data'][0]['text'] == 'Enfant 1 CALUIRE TEST'
assert resp.json['data'][1]['id'] == '50633'
assert resp.json['data'][1]['text'] == 'Enfant 2 CALUIRE TEST'
assert resp.json['data'][2]['id'] == '54621'
assert resp.json['data'][2]['text'] == 'Enfant 3 CALUIRE TEST'
assert resp.json['data'][3]['id'] == '59509'
assert resp.json['data'][3]['text'] == 'Enfant 5 CALUIRE TEST'
# again - data are in cache
resp = app.get('/caluire-axel/test/children_info?NameID=yyy')
assert resp.json['err'] == 0
def test_child_info_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get('/caluire-axel/test/child_info?NameID=yyy&idpersonne=50632')
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_child_info_endpoint_no_result(app, resource):
resp = app.get('/caluire-axel/test/child_info?NameID=yyy&idpersonne=50632')
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get('/caluire-axel/test/child_info?NameID=yyy&idpersonne=zzz')
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_child_info_endpoint(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get('/caluire-axel/test/child_info?NameID=yyy&idpersonne=50632')
assert resp.json['err'] == 0
assert set(resp.json['data'].keys()) == {
'ADRESSE',
'CIVILITE',
'FAMILLE',
'GARDEALTERNEE',
'IDENT',
'MAIL',
'NAISSANCE',
'NOM',
'NOMJF',
'PAI',
'PRENOM',
'SEXE',
'TELFIXE',
'TELPORTABLE',
'id',
'text',
}
assert resp.json['data']['id'] == '50632'
assert resp.json['data']['text'] == 'Enfant 1 CALUIRE TEST'
# again - data are in cache
resp = app.get('/caluire-axel/test/child_info?NameID=yyy&idpersonne=50632')
assert resp.json['err'] == 0
def test_school_list_endpoint_axel_error(app, resource):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_ecole') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/school_list?num=42&street=street=rue%20Pasteur&zipcode=69300&city=Caluire%20et%20Cuire&schooling_date=2021-05-10'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_school_list_endpoint(app, resource):
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/school_list.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListEcole'):
resp = app.get(
'/caluire-axel/test/school_list?num=42&street=street=rue%20Pasteur&zipcode=69300&city=Caluire%20et%20Cuire&schooling_date=2021-05-10'
)
assert resp.json['err'] == 0
assert set(resp.json['data'].keys()) == {'CODE', 'ECOLE'}
assert len(resp.json['data']['ECOLE']) == 2
assert resp.json['data']['ECOLE'][0]['id'] == 'MAT'
assert resp.json['data']['ECOLE'][0]['text'] == 'Ecole Maternelle'
assert resp.json['data']['ECOLE'][1]['id'] == 'ELEM'
assert resp.json['data']['ECOLE'][1]['text'] == 'Ecole Elémentaire'
def test_child_schooling_info_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&schooling_date=2021-05-10'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_individu') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&schooling_date=2021-05-10'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
def test_child_schooling_info_endpoint_bad_date_format(app, resource, value):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
resp = app.get(
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&schooling_date=%s' % value,
status=400,
)
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
assert resp.json['err'] == 'bad-request'
def test_child_schooling_info_endpoint_no_result(app, resource):
resp = app.get(
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&schooling_date=2021-05-10'
)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=zzz&schooling_date=2021-05-10'
)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_child_schooling_info(app, resource, family_data):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/schooling_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetIndividu'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
resp = app.get(
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&schooling_date=2021-05-10'
)
assert resp.json['err'] == 0
assert set(resp.json['data'].keys()) == {'CODE', 'INDIVIDU', 'SCOLAIRE'}
def test_child_activities_info_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/child_activities_info?NameID=yyy&idpersonne=50632&schooling_date=2021-05-10'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_activites') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/child_activities_info?NameID=yyy&idpersonne=50632&schooling_date=2021-05-10'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
def test_child_activities_info_endpoint_bad_date_format(app, resource, value):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
resp = app.get(
'/caluire-axel/test/child_activities_info?NameID=yyy&idpersonne=50632&schooling_date=%s' % value,
status=400,
)
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
assert resp.json['err'] == 'bad-request'
def test_child_activities_info_endpoint_no_result(app, resource):
resp = app.get(
'/caluire-axel/test/child_activities_info?NameID=yyy&idpersonne=50632&schooling_date=2021-05-10'
)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/child_activities_info?NameID=yyy&idpersonne=zzz&schooling_date=2021-05-10'
)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_child_activities_info(app, resource, family_data):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListActivites'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
resp = app.get(
'/caluire-axel/test/child_activities_info?NameID=yyy&idpersonne=50632&schooling_date=2021-05-10'
)
assert resp.json['err'] == 0
assert set(resp.json['data'].keys()) == {'CODE', 'ACTIVITE'}
# again - data are in cache
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
resp = app.get(
'/caluire-axel/test/child_activities_info?NameID=yyy&idpersonne=50632&schooling_date=2021-05-10'
)
assert resp.json['err'] == 0
def test_register_activity_endpoint_axel_error(app, resource, register_activity_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/register_activity?NameID=yyy', params=register_activity_params
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.create_inscription_activite') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/register_activity?NameID=yyy', params=register_activity_params
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_register_activity_endpoint_no_result(app, resource, register_activity_params):
register_activity_params['child_id'] = 'zzz'
resp = app.post_json('/caluire-axel/test/register_activity?NameID=yyy', params=register_activity_params)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.post_json(
'/caluire-axel/test/register_activity?NameID=yyy', params=register_activity_params
)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_register_activity_endpoint_date_error(app, resource, register_activity_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
register_activity_params['registration_start_date'] = '2021-09-01'
register_activity_params['registration_end_date'] = '2021-08-31'
resp = app.post_json(
'/caluire-axel/test/register_activity?NameID=yyy', params=register_activity_params, status=400
)
assert resp.json['err_desc'] == 'start_date should be before end_date'
assert resp.json['err'] == 'bad-request'
register_activity_params['registration_end_date'] = '2022-09-01'
resp = app.post_json(
'/caluire-axel/test/register_activity?NameID=yyy', params=register_activity_params, status=400
)
assert (
resp.json['err_desc'] == 'start_date and end_date are in different reference year (2021 != 2022)'
)
assert resp.json['err'] == 'bad-request'
def test_register_activity_endpoint(app, resource, family_data, register_activity_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<CREATEINSCRIPTIONACTIVITE>
<CODE>0</CODE>
<IDENTINDIVIDU>50632</IDENTINDIVIDU>
</CREATEINSCRIPTIONACTIVITE>
</PORTAIL>'''
with mock_data(content, 'CreateInscriptionActivite', data_method='setData'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch('django.core.cache.cache.delete') as mock_cache_delete:
resp = app.post_json(
'/caluire-axel/test/register_activity?NameID=yyy', params=register_activity_params
)
assert mock_cache_delete.call_args_list == [
mock.call('caluire-axel-%s-child-activities-50632-2020' % resource.pk),
]
assert resp.json['err'] == 0
assert resp.json['created'] is True
assert 'xml_request' in resp.json['data']
assert 'xml_response' in resp.json['data']
@pytest.mark.parametrize('code', [-1, -2, -3, -4])
def test_register_activity_endpoint_wrong_code(app, resource, family_data, register_activity_params, code):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = (
'''<PORTAIL>
<CREATEINSCRIPTIONACTIVITE>
<CODE>%s</CODE>
</CREATEINSCRIPTIONACTIVITE>
</PORTAIL>'''
% code
)
with mock_data(content, 'CreateInscriptionActivite', data_method='setData'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
resp = app.post_json(
'/caluire-axel/test/register_activity?NameID=yyy', params=register_activity_params
)
if code == -1:
assert resp.json['err'] == 0
assert resp.json['created'] is False
else:
assert resp.json['err_desc'] == 'Wrong register-activity status'
assert resp.json['err'] == 'register-activity-code-error-%s' % code
def test_get_agenda_endpoint_axel_error(app, resource, family_data):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=FOOBAR&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_activites') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=FOOBAR&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListActivites'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=ELEM&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
def test_get_agenda_endpoint_bad_date_format(app, resource, value):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=FOOBAR&start_date=%s&end_date=2021-08-31'
% value,
status=400,
)
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
assert resp.json['err'] == 'bad-request'
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=FOOBAR&start_date=2020-09-01&end_date=%s'
% value,
status=400,
)
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
assert resp.json['err'] == 'bad-request'
def test_get_agenda_endpoint_no_result(app, resource, family_data):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=FOOBAR&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=zzz&activity_id=FOOBAR&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListActivites'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=FOOBAR&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Activity not found'
assert resp.json['err'] == 'not-found'
def test_get_agenda_endpoint_date_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=FOOBAR&start_date=2021-05-31&end_date=2021-05-30',
status=400,
)
assert resp.json['err_desc'] == 'start_date should be before end_date'
assert resp.json['err'] == 'bad-request'
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=FOOBAR&start_date=2021-09-01&end_date=2022-09-01',
status=400,
)
assert (
resp.json['err_desc'] == 'start_date and end_date are in different reference year (2021 != 2022)'
)
assert resp.json['err'] == 'bad-request'
@freezegun.freeze_time('2020-09-01')
def test_get_agenda_endpoint(app, resource, family_data, activities):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>30/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=ELEM&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err'] == 0
assert resp.json['data'] == [
{
'id': '50632:ELEM:2020-10-30',
'text': 'Friday 30 October 2020',
'disabled': False,
'prefill': False,
'details': {
'JOURDATE': '2020-10-30',
'MATIN': '.',
'MIDI': None,
'APRESMIDI': None,
'FERME': False,
'status_color': 'white',
'out_of_delay': False,
'activity_id': 'ELEM',
'activity_label': 'Restaurant Elémentaire',
'activity_type': 'midi',
'child_id': '50632',
},
},
]
@pytest.mark.parametrize(
'value, ignored',
[
('O', True),
('N', False),
],
)
def test_get_agenda_endpoint_closed(app, resource, family_data, activities, value, ignored):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = (
'''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>30/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>%s</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
% value
)
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=ELEM&start_date=2020-09-01&end_date=2021-08-31'
)
if ignored:
assert len(resp.json['data']) == 0
else:
assert resp.json['data'][0]
@pytest.mark.parametrize(
'value, expected',
[
['<MATIN>X</MATIN>', True],
['<MATIN>H</MATIN>', True],
['<MATIN>R</MATIN>', True],
['<MATIN/>', False],
['<MATIN></MATIN>', False],
['<MATIN>.</MATIN>', False],
['<MATIN>F</MATIN>', False],
['<MATIN>S</MATIN>', False],
['<MATIN>T</MATIN>', False],
['<MATIN>D</MATIN>', False],
['<MATIN>C</MATIN>', False],
['<MATIN>M</MATIN>', False],
['<MATIN>A</MATIN>', False],
['<MATIN>N</MATIN>', False],
['<MATIN>Z</MATIN>', False], # unknown
],
)
@freezegun.freeze_time('2020-09-01')
def test_get_agenda_endpoint_prefill(app, resource, family_data, activities, value, expected):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = (
'''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>30/10/2020</JOURDATE>
%s
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
% value
)
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=ELEM&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['data'][0]['prefill'] == expected
@pytest.mark.parametrize(
'value, color, disabled_future',
[
['<MATIN>X</MATIN>', 'green', False],
['<MATIN>H</MATIN>', 'yellow', True],
['<MATIN>R</MATIN>', 'green', False],
['<MATIN/>', 'grey', True],
['<MATIN></MATIN>', 'grey', True],
['<MATIN>.</MATIN>', 'white', False],
['<MATIN>F</MATIN>', 'grey', True],
['<MATIN>S</MATIN>', 'grey', True],
['<MATIN>T</MATIN>', 'grey', True],
['<MATIN>D</MATIN>', 'orange', False],
['<MATIN>C</MATIN>', 'orange', True],
['<MATIN>M</MATIN>', 'orange', True],
['<MATIN>A</MATIN>', 'red', True],
['<MATIN>N</MATIN>', 'red', True],
['<MATIN>Z</MATIN>', 'grey', True], # unknown
],
)
def test_get_agenda_endpoint_status(app, resource, family_data, activities, value, color, disabled_future):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = (
'''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>30/10/2020</JOURDATE>
%s
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
% value
)
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
with freezegun.freeze_time('2020-10-31'):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=ELEM&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['data'][0]['details']['status_color'] == color
assert resp.json['data'][0]['disabled'] is True
assert resp.json['data'][0]['details']['out_of_delay'] is True
with freezegun.freeze_time('2020-10-20'):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=ELEM&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['data'][0]['details']['status_color'] == color
assert resp.json['data'][0]['disabled'] == disabled_future
assert resp.json['data'][0]['details']['out_of_delay'] is False
@pytest.mark.parametrize(
'today, hour, booking_date, out_of_delay',
[
# monday 12H => thursday
('2021-05-31', '09:59:59', '2021-06-03', False),
('2021-05-31', '10:00:00', '2021-06-03', True),
# tuesday 12H => friday
('2021-06-01', '09:59:59', '2021-06-04', False),
('2021-06-01', '10:00:00', '2021-06-04', True),
# wednesday => monday
('2021-06-02', '09:59:59', '2021-06-04', True),
('2021-06-02', '10:00:00', '2021-06-04', True),
('2021-06-02', '09:59:59', '2021-06-05', True),
('2021-06-02', '10:00:00', '2021-06-05', True),
('2021-06-02', '09:59:59', '2021-06-06', True),
('2021-06-02', '10:00:00', '2021-06-06', True),
('2021-06-02', '09:59:59', '2021-06-07', False),
('2021-06-02', '10:00:00', '2021-06-07', False),
# thursday 12H => monday
('2021-06-03', '09:59:59', '2021-06-07', False),
('2021-06-03', '10:00:00', '2021-06-07', True),
# friday 12H => tuesday
('2021-06-04', '09:59:59', '2021-06-08', False),
('2021-06-04', '10:00:00', '2021-06-08', True),
# saturday => thursday
('2021-06-05', '09:59:59', '2021-06-08', True),
('2021-06-05', '10:00:00', '2021-06-08', True),
('2021-06-05', '09:59:59', '2021-06-09', True),
('2021-06-05', '10:00:00', '2021-06-09', True),
('2021-06-05', '09:59:59', '2021-06-10', False),
('2021-06-05', '10:00:00', '2021-06-10', False),
# sunday => thursday
('2021-06-06', '09:59:59', '2021-06-08', True),
('2021-06-06', '10:00:00', '2021-06-08', True),
('2021-06-06', '09:59:59', '2021-06-09', True),
('2021-06-06', '10:00:00', '2021-06-09', True),
('2021-06-06', '09:59:59', '2021-06-10', False),
('2021-06-06', '10:00:00', '2021-06-10', False),
],
)
def test_get_agenda_endpoint_delay_periscolaire(
settings, app, resource, family_data, activities_full, today, hour, booking_date, out_of_delay
):
settings.TIME_ZONE = 'Europe/Paris'
settings.USE_TZ = True
booking = datetime.datetime.strptime(booking_date, json_date_format).date()
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>%s</JOURDATE>
<MATIN>X</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>''' % booking.strftime(
xml_date_format
)
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities_full,
):
with freezegun.freeze_time('%s %s' % (today, hour)):
for activity_id, activity_type in [
('ACCMAT', 'matin'),
('GARDERIES', 'soir'),
('ETUDES', 'soir'),
('ECOLELEM', 'midi'),
('NAV MATIN', 'matin'),
('NAV SOIR', 'soir'),
]:
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=%s&start_date=%s&end_date=%s'
% (activity_id, booking_date, booking_date)
)
assert resp.json['data'][0]['disabled'] == out_of_delay
assert resp.json['data'][0]['details']['out_of_delay'] == out_of_delay
assert resp.json['data'][0]['details']['activity_type'] == activity_type
@pytest.mark.parametrize(
'activity_id, activity_type',
[
('CJ MER', 'mercredi'),
('CJ1', 'vacances'),
],
)
def test_get_agenda_endpoint_delay_extrascolaire(
app, resource, family_data, activities_full, activity_id, activity_type
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>12/07/2021</JOURDATE>
<MATIN>X</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities_full,
):
# always disabled
with freezegun.freeze_time('2021-05-31'):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=%s&start_date=2021-06-02&end_date=2021-06-02'
% activity_id
)
assert resp.json['data'][0]['disabled'] is True
assert resp.json['data'][0]['details']['out_of_delay'] is True
assert resp.json['data'][0]['details']['activity_type'] == activity_type
with freezegun.freeze_time('2021-07-11'):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=%s&start_date=2021-06-02&end_date=2021-06-02'
% activity_id
)
assert resp.json['data'][0]['disabled'] is True
assert resp.json['data'][0]['details']['out_of_delay'] is True
assert resp.json['data'][0]['details']['activity_type'] == activity_type
def test_get_agenda_endpoint_delay_class_decouverte(app, resource, family_data, activities_full):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>12/07/2021</JOURDATE>
<MATIN>X</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities_full,
):
# always disabled
with freezegun.freeze_time('2021-05-31'):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=%s&start_date=2021-06-02&end_date=2021-06-02'
% 'DECFOO'
)
assert len(resp.json['data']) == 0
@pytest.mark.parametrize('code', [0, -1, -2, -3, -4])
def test_get_agenda_endpoint_wrong_code(app, resource, family_data, activities, code):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = (
'''<PORTAIL>
<GETAGENDA>
<CODE>%s</CODE>
</GETAGENDA>
</PORTAIL>'''
% code
)
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
resp = app.get(
'/caluire-axel/test/get_agenda?NameID=yyy&idpersonne=50632&activity_id=ELEM&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Wrong agenda status'
assert resp.json['err'] == 'agenda-code-error-%s' % code
def test_get_agenda_periscolaire_endpoint_axel_error(app, resource, family_data):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_activites') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListActivites'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
def test_get_agenda_periscolaire_endpoint_bad_date_format(app, resource, value):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=%s&end_date=2021-08-31'
% value,
status=400,
)
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
assert resp.json['err'] == 'bad-request'
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=%s'
% value,
status=400,
)
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
assert resp.json['err'] == 'bad-request'
def test_get_agenda_periscolaire_endpoint_no_result(app, resource):
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=zzz&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_get_agenda_periscolaire_endpoint_date_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=2021-05-31&end_date=2021-05-30',
status=400,
)
assert resp.json['err_desc'] == 'start_date should be before end_date'
assert resp.json['err'] == 'bad-request'
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=2021-09-01&end_date=2022-09-01',
status=400,
)
assert (
resp.json['err_desc'] == 'start_date and end_date are in different reference year (2021 != 2022)'
)
assert resp.json['err'] == 'bad-request'
def test_get_agenda_periscolaire_endpoint(app, resource, family_data, activities_full):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<GETAGENDA>
<CODE>7</CODE>
<JOUR>
<JOURDATE>26/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>27/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>28/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>29/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>30/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>31/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>01/11/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities_full,
):
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert len(resp.json['data']) == 24
assert resp.json['data'][0]['id'] == '50632:NAV MATIN:2020-10-26'
assert resp.json['data'][1]['id'] == '50632:ACCMAT:2020-10-26'
assert resp.json['data'][2]['id'] == '50632:ECOLELEM:2020-10-26'
assert resp.json['data'][3]['id'] == '50632:ETUDES:2020-10-26'
assert resp.json['data'][4]['id'] == '50632:GARDERIES:2020-10-26'
assert resp.json['data'][5]['id'] == '50632:NAV SOIR:2020-10-26'
assert resp.json['data'][6]['id'] == '50632:NAV MATIN:2020-10-27'
assert resp.json['data'][7]['id'] == '50632:ACCMAT:2020-10-27'
assert resp.json['data'][8]['id'] == '50632:ECOLELEM:2020-10-27'
assert resp.json['data'][9]['id'] == '50632:ETUDES:2020-10-27'
assert resp.json['data'][10]['id'] == '50632:GARDERIES:2020-10-27'
assert resp.json['data'][11]['id'] == '50632:NAV SOIR:2020-10-27'
assert resp.json['data'][12]['id'] == '50632:NAV MATIN:2020-10-29'
assert resp.json['data'][13]['id'] == '50632:ACCMAT:2020-10-29'
assert resp.json['data'][14]['id'] == '50632:ECOLELEM:2020-10-29'
assert resp.json['data'][15]['id'] == '50632:ETUDES:2020-10-29'
assert resp.json['data'][16]['id'] == '50632:GARDERIES:2020-10-29'
assert resp.json['data'][17]['id'] == '50632:NAV SOIR:2020-10-29'
assert resp.json['data'][18]['id'] == '50632:NAV MATIN:2020-10-30'
assert resp.json['data'][19]['id'] == '50632:ACCMAT:2020-10-30'
assert resp.json['data'][20]['id'] == '50632:ECOLELEM:2020-10-30'
assert resp.json['data'][21]['id'] == '50632:ETUDES:2020-10-30'
assert resp.json['data'][22]['id'] == '50632:GARDERIES:2020-10-30'
assert resp.json['data'][23]['id'] == '50632:NAV SOIR:2020-10-30'
@pytest.mark.parametrize('code', [0, -1, -2, -3, -4])
def test_get_agenda_periscolaire_endpoint_wrong_code(app, resource, family_data, activities, code):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = (
'''<PORTAIL>
<GETAGENDA>
<CODE>%s</CODE>
</GETAGENDA>
</PORTAIL>'''
% code
)
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
resp = app.get(
'/caluire-axel/test/get_agenda_periscolaire?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Wrong agenda status'
assert resp.json['err'] == 'agenda-code-error-%s' % code
def test_get_agenda_full_endpoint_axel_error(app, resource, family_data):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_activites') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListActivites'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
def test_get_agenda_full_endpoint_bad_date_format(app, resource, value):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=%s&end_date=2021-08-31'
% value,
status=400,
)
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
assert resp.json['err'] == 'bad-request'
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=%s'
% value,
status=400,
)
assert resp.json['err_desc'] == 'bad date format, should be YYYY-MM-DD'
assert resp.json['err'] == 'bad-request'
def test_get_agenda_full_endpoint_no_result(app, resource):
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=zzz&start_date=2020-09-01&end_date=2021-08-31'
)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_get_agenda_full_endpoint_date_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2021-05-31&end_date=2021-05-30',
status=400,
)
assert resp.json['err_desc'] == 'start_date should be before end_date'
assert resp.json['err'] == 'bad-request'
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2021-09-01&end_date=2022-09-01',
status=400,
)
assert (
resp.json['err_desc'] == 'start_date and end_date are in different reference year (2021 != 2022)'
)
assert resp.json['err'] == 'bad-request'
def test_get_agenda_full_endpoint(app, resource, family_data, activities_full):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<GETAGENDA>
<CODE>7</CODE>
<JOUR>
<JOURDATE>26/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>27/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>28/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>29/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>30/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>31/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
<JOUR>
<JOURDATE>01/11/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities_full,
):
resp = app.get(
'/caluire-axel/test/get_agenda_full?NameID=yyy&idpersonne=50632&start_date=2020-09-01&end_date=2021-08-31'
)
assert len(resp.json['data']) == 40
assert resp.json['data'][0]['id'] == '50632:NAV MATIN:2020-10-26'
assert resp.json['data'][1]['id'] == '50632:ACCMAT:2020-10-26'
assert resp.json['data'][2]['id'] == '50632:ECOLELEM:2020-10-26'
assert resp.json['data'][3]['id'] == '50632:ETUDES:2020-10-26'
assert resp.json['data'][4]['id'] == '50632:GARDERIES:2020-10-26'
assert resp.json['data'][5]['id'] == '50632:NAV SOIR:2020-10-26'
assert resp.json['data'][6]['id'] == '50632:CJ MER:2020-10-26'
assert resp.json['data'][7]['id'] == '50632:CJ1:2020-10-26'
assert resp.json['data'][8]['id'] == '50632:NAV MATIN:2020-10-27'
assert resp.json['data'][9]['id'] == '50632:ACCMAT:2020-10-27'
assert resp.json['data'][10]['id'] == '50632:ECOLELEM:2020-10-27'
assert resp.json['data'][11]['id'] == '50632:ETUDES:2020-10-27'
assert resp.json['data'][12]['id'] == '50632:GARDERIES:2020-10-27'
assert resp.json['data'][13]['id'] == '50632:NAV SOIR:2020-10-27'
assert resp.json['data'][14]['id'] == '50632:CJ MER:2020-10-27'
assert resp.json['data'][15]['id'] == '50632:CJ1:2020-10-27'
assert resp.json['data'][16]['id'] == '50632:NAV MATIN:2020-10-28'
assert resp.json['data'][17]['id'] == '50632:ACCMAT:2020-10-28'
assert resp.json['data'][18]['id'] == '50632:ECOLELEM:2020-10-28'
assert resp.json['data'][19]['id'] == '50632:ETUDES:2020-10-28'
assert resp.json['data'][20]['id'] == '50632:GARDERIES:2020-10-28'
assert resp.json['data'][21]['id'] == '50632:NAV SOIR:2020-10-28'
assert resp.json['data'][22]['id'] == '50632:CJ MER:2020-10-28'
assert resp.json['data'][23]['id'] == '50632:CJ1:2020-10-28'
assert resp.json['data'][24]['id'] == '50632:NAV MATIN:2020-10-29'
assert resp.json['data'][25]['id'] == '50632:ACCMAT:2020-10-29'
assert resp.json['data'][26]['id'] == '50632:ECOLELEM:2020-10-29'
assert resp.json['data'][27]['id'] == '50632:ETUDES:2020-10-29'
assert resp.json['data'][28]['id'] == '50632:GARDERIES:2020-10-29'
assert resp.json['data'][29]['id'] == '50632:NAV SOIR:2020-10-29'
assert resp.json['data'][30]['id'] == '50632:CJ MER:2020-10-29'
assert resp.json['data'][31]['id'] == '50632:CJ1:2020-10-29'
assert resp.json['data'][32]['id'] == '50632:NAV MATIN:2020-10-30'
assert resp.json['data'][33]['id'] == '50632:ACCMAT:2020-10-30'
assert resp.json['data'][34]['id'] == '50632:ECOLELEM:2020-10-30'
assert resp.json['data'][35]['id'] == '50632:ETUDES:2020-10-30'
assert resp.json['data'][36]['id'] == '50632:GARDERIES:2020-10-30'
assert resp.json['data'][37]['id'] == '50632:NAV SOIR:2020-10-30'
assert resp.json['data'][38]['id'] == '50632:CJ MER:2020-10-30'
assert resp.json['data'][39]['id'] == '50632:CJ1:2020-10-30'
@freezegun.freeze_time('2020-09-01')
def test_set_agenda_endpoint_axel_error(app, resource, family_data, activities, booking_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
booking_params['booking_list'] = ['50632:ELEM:2020-10-30']
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json('/caluire-axel/test/set_agenda?NameID=yyy', params=booking_params)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_activites') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json('/caluire-axel/test/set_agenda?NameID=yyy', params=booking_params)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListActivites'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json('/caluire-axel/test/set_agenda?NameID=yyy', params=booking_params)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
content = '''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>30/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json('/caluire-axel/test/set_agenda?NameID=yyy', params=booking_params)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_set_agenda_endpoint_no_result(app, resource, booking_params):
booking_params['child_id'] = 'zzz'
resp = app.post_json('/caluire-axel/test/set_agenda?NameID=yyy', params=booking_params)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.post_json('/caluire-axel/test/set_agenda?NameID=yyy', params=booking_params)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_set_agenda_endpoint_date_error(app, resource, booking_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
booking_params['start_date'] = '2021-09-01'
booking_params['end_date'] = '2021-08-31'
resp = app.post_json('/caluire-axel/test/set_agenda?NameID=yyy', params=booking_params, status=400)
assert resp.json['err_desc'] == 'start_date should be before end_date'
assert resp.json['err'] == 'bad-request'
booking_params['end_date'] = '2022-09-01'
resp = app.post_json('/caluire-axel/test/set_agenda?NameID=yyy', params=booking_params, status=400)
assert (
resp.json['err_desc'] == 'start_date and end_date are in different reference year (2021 != 2022)'
)
assert resp.json['err'] == 'bad-request'
def test_set_agenda_endpoint(app, resource, family_data, activities, booking_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
booking_params['end_date'] = '2020-09-01'
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=[],
):
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
assert resp.json['count'] == 0
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_endpoint_multi(app, resource, family_data, booking_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ACCMAT',
'LIBELLEACTIVITE': 'Matin',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ECOLELEM',
'LIBELLEACTIVITE': 'Cantine',
},
]
booking_params['end_date'] = '2020-09-11'
booking_params['booking_list'] = [
'50632:ACCMAT:2020-09-07',
'50632:ACCMAT:2020-09-08',
'50632:ECOLELEM:2020-09-07',
'50632:ECOLELEM:2020-09-10',
]
bookings = []
for activity_id in ['ACCMAT', 'ECOLELEM']:
for day in ['2020-09-07', '2020-09-08']:
bookings.append(
{
'id': '50632:%s:%s' % (activity_id, day),
'disabled': False,
'prefill': False,
}
)
for day in ['2020-09-10', '2020-09-11']:
bookings.append(
{
'id': '50632:%s:%s' % (activity_id, day),
'disabled': False,
'prefill': True,
}
)
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
assert resp.json['count'] == 6
assert resp.json['changes'] == [
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-07', 'booked': True},
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-08', 'booked': True},
{'activity_id': 'ECOLELEM', 'activity_label': 'Cantine', 'day': '2020-09-07', 'booked': True},
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-10', 'booked': False},
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-11', 'booked': False},
{'activity_id': 'ECOLELEM', 'activity_label': 'Cantine', 'day': '2020-09-11', 'booked': False},
]
assert len(operation.call_args_list) == 2
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE'] == 'ACCMAT'
assert len(operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 4
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
== '2020-09-07'
)
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN'] == 'X'
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][1]['JOURDATE']
== '2020-09-08'
)
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][1]['MATIN'] == 'X'
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][2]['JOURDATE']
== '2020-09-10'
)
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][2]['MATIN'] == 'D'
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][3]['JOURDATE']
== '2020-09-11'
)
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][3]['MATIN'] == 'D'
assert operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
assert (
operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE'] == 'ECOLELEM'
)
assert len(operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 2
assert (
operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
== '2020-09-07'
)
assert operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN'] == 'X'
assert (
operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][1]['JOURDATE']
== '2020-09-11'
)
assert operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][1]['MATIN'] == 'D'
@pytest.mark.parametrize(
'booked, ok',
[
([], True),
(['50632:ACCMAT:2020-09-07', '50632:CANTINE:2020-09-07'], True), # cantine & accmat are not exlusive
(['50632:ACCMAT:2020-09-07', '50632:ACCMAT:2020-09-07'], True), # same day sent twice
(['50642:ACCMAT:2020-09-07', '50632:NAV MATIN:2020-09-07'], True), # not the same child
(['50632:ACCMAT:2020-09-07', '50632:NAV MATIN:2020-09-07'], False),
],
)
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_endpoint_multi_matin(app, resource, family_data, booking_params, booked, ok):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'CANTINE',
'LIBELLEACTIVITE': 'Cantine',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ACCMAT',
'LIBELLEACTIVITE': 'Matin',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'NAV MATIN',
'LIBELLEACTIVITE': 'Navette du matin',
},
]
booking_params['end_date'] = '2020-09-07'
booking_params['booking_list'] = booked
bookings = []
for activity_id in ['ACCMAT', 'CANTINE', 'NAV MATIN']:
bookings.append(
{
'id': '50632:%s:2020-09-07' % activity_id,
'disabled': False,
'prefill': False,
}
)
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
if ok:
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err'] == 0
else:
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
status=400,
)
assert resp.json['err_desc'] == 'not possible to book %s the same day' % ' and '.join(
booked
)
assert resp.json['err'] == 'bad-request'
@pytest.mark.parametrize('prefill', [True, False])
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_endpoint_multi_matin_no_changes(app, resource, family_data, booking_params, prefill):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ACCMAT',
'LIBELLEACTIVITE': 'Matin',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'NAV MATIN',
'LIBELLEACTIVITE': 'Navette du matin',
},
]
booking_params['end_date'] = '2020-09-07'
booking_params['booking_list'] = ['50632:ACCMAT:2020-09-07', '50632:NAV MATIN:2020-09-07']
bookings = []
for activity_id in ['ACCMAT', 'NAV MATIN']:
bookings.append(
{
'id': '50632:%s:2020-09-07' % activity_id,
'disabled': False,
'prefill': prefill,
}
)
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
if prefill:
# was already booked, no changes => no error
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err'] == 0
else:
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
status=400,
)
assert resp.json['err_desc'] == 'not possible to book %s the same day' % ' and '.join(
booking_params['booking_list']
)
assert resp.json['err'] == 'bad-request'
@pytest.mark.parametrize(
'booked, ok',
[
([], True),
(['50632:ETUDES:2020-09-07', '50632:CANTINE:2020-09-07'], True), # cantine & etudes are not exlusive
(['50632:GARDERIES:2020-09-07', '50632:GARDERIES:2020-09-07'], True), # same day sent twice
(['50632:ETUDES:2020-09-07', '50642:GARDERIES:2020-09-07'], True), # not the same child
(['50632:ETUDES:2020-09-07', '50632:GARDERIES:2020-09-07'], False),
(['50632:ETUDES:2020-09-07', '50632:NAV SOIR:2020-09-07'], False),
(['50632:GARDERIES:2020-09-07', '50632:NAV SOIR:2020-09-07'], False),
(['50632:ETUDES:2020-09-07', '50632:GARDERIES:2020-09-07', '50632:NAV SOIR:2020-09-07'], False),
],
)
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_endpoint_multi_soir(app, resource, family_data, booking_params, booked, ok):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'CANTINE',
'LIBELLEACTIVITE': 'Cantine',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'GARDERIES',
'LIBELLEACTIVITE': 'Garderie',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ETUDES',
'LIBELLEACTIVITE': 'Etudes',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'NAV SOIR',
'LIBELLEACTIVITE': 'Navette du soir',
},
]
booking_params['end_date'] = '2020-09-07'
booking_params['booking_list'] = booked
bookings = []
for activity_id in ['GARDERIES', 'ETUDES', 'CANTINE', 'NAV SOIR']:
bookings.append(
{
'id': '50632:%s:2020-09-07' % activity_id,
'disabled': False,
'prefill': False,
}
)
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
if ok:
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err'] == 0
else:
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
status=400,
)
assert resp.json['err_desc'] == 'not possible to book %s the same day' % ' and '.join(
booked
)
assert resp.json['err'] == 'bad-request'
@pytest.mark.parametrize('prefill', [True, False])
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_endpoint_multi_soir_no_changes(app, resource, family_data, booking_params, prefill):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'GARDERIES',
'LIBELLEACTIVITE': 'Garderie',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ETUDES',
'LIBELLEACTIVITE': 'Etudes',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'NAV SOIR',
'LIBELLEACTIVITE': 'Navette du soir',
},
]
booking_params['end_date'] = '2020-09-07'
booking_params['booking_list'] = [
'50632:ETUDES:2020-09-07',
'50632:GARDERIES:2020-09-07',
'50632:NAV SOIR:2020-09-07',
]
bookings = []
for activity_id in ['GARDERIES', 'ETUDES', 'NAV SOIR']:
bookings.append(
{
'id': '50632:%s:2020-09-07' % activity_id,
'disabled': False,
'prefill': prefill,
}
)
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
if prefill:
# was already booked, no changes => no error
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err'] == 0
else:
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
status=400,
)
assert resp.json['err_desc'] == 'not possible to book %s the same day' % ' and '.join(
booking_params['booking_list']
)
assert resp.json['err'] == 'bad-request'
@pytest.mark.parametrize(
'prefill, wanted, expected',
[
(True, True, None), # no changes
(True, False, False),
(False, True, True),
(False, False, None), # no changes
],
)
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_endpoint_prefill_periscolaire(
app, resource, family_data, booking_params, prefill, wanted, expected
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
booking_params['end_date'] = '2020-09-01'
for activity_id in ['ACCMAT', 'GARDERIES', 'ETUDES', 'CANTINE', 'FOOBAR', 'NAV MATIN', 'NAV SOIR']:
activity = {
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': activity_id,
'LIBELLEACTIVITE': 'FOOBAR',
}
if wanted:
booking_params['booking_list'] = ['50632:%s:2020-09-01' % activity_id]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': [activity]},
):
bookings = [
{
'id': '50632:%s:2020-09-01' % activity_id,
'disabled': False,
'prefill': prefill,
},
]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
if expected is not None:
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE']
== activity_id
)
assert len(operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 1
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
== '2020-09-01'
)
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN']
== 'X'
if expected
else 'D'
)
else:
assert len(operation.call_args_list) == 0
@pytest.mark.parametrize('prefill', [True, False])
@pytest.mark.parametrize('wanted', [True, False])
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_endpoint_prefill_extrascolaire_and_classe_decouverte(
app, resource, family_data, booking_params, prefill, wanted
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
booking_params['end_date'] = '2020-09-01'
for activity_id in ['CJ MER', 'CJVACANCES', 'DECFOO']:
activity = {
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': activity_id,
'LIBELLEACTIVITE': 'FOOBAR',
}
if wanted:
booking_params['booking_list'] = ['50632:%s:2020-09-01' % activity_id]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': [activity]},
):
bookings = [
{
'id': '50632:%s:2020-09-01' % activity_id,
'disabled': False,
'prefill': prefill,
},
]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
assert len(operation.call_args_list) == 0 # not bookable
@pytest.mark.parametrize('disabled', [True, False, None])
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_endpoint_disabled(app, resource, family_data, booking_params, disabled):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activity = {
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'FOOBAR',
'LIBELLEACTIVITE': 'FOOBAR',
}
booking_params['end_date'] = '2020-09-01'
booking_params['booking_list'] = ['50632:FOOBAR:2020-09-01']
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': [activity]},
):
bookings = []
if disabled is not None:
bookings = [
{
'id': '50632:FOOBAR:2020-09-01',
'disabled': disabled,
'prefill': False,
},
]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
if disabled is False:
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE'] == 'FOOBAR'
)
assert len(operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 1
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
== '2020-09-01'
)
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN'] == 'X'
)
else:
assert len(operation.call_args_list) == 0
@pytest.mark.parametrize('code', [-1, -2, -3, -4])
def test_set_agenda_endpoint_wrong_code(app, resource, family_data, activities, booking_params, code):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
booking_params['end_date'] = '2020-09-01'
bookings = [
{
'id': '50632:ELEM:2020-09-01',
'disabled': False,
'prefill': True,
},
]
content = (
'''<PORTAIL>
<SETAGENDA>
<CODE>%s</CODE>
</SETAGENDA>
</PORTAIL>'''
% code
)
with mock_data(content, 'SetAgenda', data_method='setData'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
resp = app.post_json(
'/caluire-axel/test/set_agenda?NameID=yyy',
params=booking_params,
)
assert resp.json['err_desc'] == 'Wrong agenda status'
assert resp.json['err'] == 'agenda-code-error-%s' % code
@freezegun.freeze_time('2020-09-01')
def test_set_agenda_apply_changes_endpoint_axel_error(app, resource, family_data, changes_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
changes_params['changes'] = [
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-10-30', 'booked': True},
]
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json('/caluire-axel/test/set_agenda_apply_changes?NameID=yyy', params=changes_params)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_activites') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy', params=changes_params
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListActivites'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy', params=changes_params
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ACCMAT',
'LIBELLEACTIVITE': 'Matin',
},
]
content = '''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>30/10/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy', params=changes_params
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_set_agenda_apply_changes_endpoint_no_result(app, resource, changes_params):
changes_params['child_id'] = 'zzz'
resp = app.post_json('/caluire-axel/test/set_agenda_apply_changes?NameID=yyy', params=changes_params)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.post_json('/caluire-axel/test/set_agenda_apply_changes?NameID=yyy', params=changes_params)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_set_agenda_apply_changes_endpoint_date_error(app, resource, changes_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
changes_params['start_date'] = '2021-09-01'
changes_params['end_date'] = '2021-08-31'
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy', params=changes_params, status=400
)
assert resp.json['err_desc'] == 'start_date should be before end_date'
assert resp.json['err'] == 'bad-request'
changes_params['end_date'] = '2022-09-01'
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy', params=changes_params, status=400
)
assert (
resp.json['err_desc'] == 'start_date and end_date are in different reference year (2021 != 2022)'
)
assert resp.json['err'] == 'bad-request'
def test_set_agenda_apply_changes_endpoint(app, resource, family_data, activities, changes_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
changes_params['end_date'] = '2020-09-01'
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=[],
):
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy',
params=changes_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
assert resp.json['count'] == 0
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_apply_changes_endpoint_multi(app, resource, family_data, changes_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ACCMAT',
'LIBELLEACTIVITE': 'Matin',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ECOLELEM',
'LIBELLEACTIVITE': 'Cantine',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'CJ MER',
'LIBELLEACTIVITE': 'FOOBAR',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'CJVACANCES',
'LIBELLEACTIVITE': 'FOOBAR',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'DECFOO',
'LIBELLEACTIVITE': 'FOOBAR',
},
]
changes_params['end_date'] = '2020-09-11'
changes_params['changes'] = [
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-07', 'booked': False},
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-08', 'booked': True},
{
'activity_id': 'ECOLELEM2',
'activity_label': 'Cantine',
'day': '2020-09-07',
'booked': True,
}, # cantine, not the same id
{
'activity_id': 'ECOLELEM2',
'activity_label': 'Cantine',
'day': '2020-09-10',
'booked': False,
}, # cantine, not the same id
{'activity_id': 'CJ MER', 'activity_label': 'FOOBAR', 'day': '2020-09-08', 'booked': True}, # ignored
{
'activity_id': 'CJVACANCES',
'activity_label': 'FOOBAR',
'day': '2020-09-08',
'booked': True,
}, # ignored
{
'activity_id': 'DECFOO',
'activity_label': 'FOOBAR',
'day': '2020-09-08',
'booked': True,
}, # ignored
]
bookings = []
for activity_id in ['ACCMAT', 'ECOLELEM']:
for day in ['2020-09-07', '2020-09-08']:
bookings.append(
{
'id': '50632:%s:%s' % (activity_id, day),
'disabled': False,
'prefill': False,
}
)
for day in ['2020-09-10', '2020-09-11']:
bookings.append(
{
'id': '50632:%s:%s' % (activity_id, day),
'disabled': False,
'prefill': True,
}
)
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy',
params=changes_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
assert resp.json['count'] == 3
assert resp.json['changes'] == [
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-08', 'booked': True},
{'activity_id': 'ECOLELEM', 'activity_label': 'Cantine', 'day': '2020-09-07', 'booked': True},
{'activity_id': 'ECOLELEM', 'activity_label': 'Cantine', 'day': '2020-09-10', 'booked': False},
]
assert len(operation.call_args_list) == 2
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE'] == 'ACCMAT'
assert len(operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 1
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
== '2020-09-08'
)
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN'] == 'X'
assert operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
assert (
operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE'] == 'ECOLELEM'
)
assert len(operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 2
assert (
operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
== '2020-09-07'
)
assert operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN'] == 'X'
assert (
operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][1]['JOURDATE']
== '2020-09-10'
)
assert operation.call_args_list[1][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][1]['MATIN'] == 'D'
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_apply_changes_endpoint_multi_too_many_cantine_activities(
app, resource, family_data, changes_params
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
# more than one activity "midi"
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ECOLELEM',
'LIBELLEACTIVITE': 'Cantine',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ECOLELEM2',
'LIBELLEACTIVITE': 'Cantine',
},
]
changes_params['end_date'] = '2020-09-11'
changes_params['changes'] = [
{
'activity_id': 'ECOLELEM2',
'activity_label': 'Cantine',
'day': '2020-09-07',
'booked': True,
},
]
bookings = [
{
'id': '50632:MIDI:2020-09-07',
'disabled': False,
'prefill': False,
},
]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy',
params=changes_params,
status=400,
)
assert (
resp.json['err_desc']
== 'more than one activity cantine found for this child (ECOLELEM, ECOLELEM2)'
)
assert resp.json['err'] == 'bad-request'
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_apply_changes_endpoint_multi_unkown_activity(app, resource, family_data, changes_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ACCMAT',
'LIBELLEACTIVITE': 'Matin',
},
]
changes_params['end_date'] = '2020-09-11'
changes_params['changes'] = [
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-07', 'booked': False},
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-08', 'booked': True},
{
'activity_id': 'ECOLELEM2',
'activity_label': 'Cantine',
'day': '2020-09-07',
'booked': True,
}, # cantine, child is not registered
{
'activity_id': 'ECOLELEM2',
'activity_label': 'Cantine',
'day': '2020-09-10',
'booked': False,
}, # cantine, child is not registered
]
bookings = []
for day in ['2020-09-07', '2020-09-08']:
bookings.append(
{
'id': '50632:ACCMAT:%s' % day,
'disabled': False,
'prefill': False,
}
)
for day in ['2020-09-10', '2020-09-11']:
bookings.append(
{
'id': '50632:ACCMAT:%s' % day,
'disabled': False,
'prefill': True,
}
)
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy',
params=changes_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
assert resp.json['count'] == 1
assert resp.json['changes'] == [
{'activity_id': 'ACCMAT', 'activity_label': 'Matin', 'day': '2020-09-08', 'booked': True},
]
assert len(operation.call_args_list) == 1
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE'] == 'ACCMAT'
assert len(operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 1
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
== '2020-09-08'
)
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN'] == 'X'
@freezegun.freeze_time('2020-08-01')
def test_set_agenda_apply_changes_endpoint_multi_soir(app, resource, family_data, changes_params):
# just a little check, booking exclusivity is handled by _set_agenda method,
# already tested for set_agenda endpoint
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activities = [
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'GARDERIES',
'LIBELLEACTIVITE': 'Garderie',
},
{
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'ETUDES',
'LIBELLEACTIVITE': 'Etudes',
},
]
changes_params['end_date'] = '2020-09-11'
changes_params['changes'] = [
{'activity_id': 'GARDERIES', 'activity_label': 'Garderie', 'day': '2020-09-07', 'booked': True},
]
bookings = [
{
'id': '50632:GARDERIES:2020-09-07',
'disabled': False,
'prefill': False,
},
{
'id': '50632:ETUDES:2020-09-07',
'disabled': False,
'prefill': True,
},
]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy',
params=changes_params,
status=400,
)
assert (
resp.json['err_desc']
== 'not possible to book 50632:ETUDES:2020-09-07 and 50632:GARDERIES:2020-09-07 the same day'
)
assert resp.json['err'] == 'bad-request'
# already booked, no error
bookings = [
{
'id': '50632:GARDERIES:2020-09-07',
'disabled': False,
'prefill': True,
},
{
'id': '50632:ETUDES:2020-09-07',
'disabled': False,
'prefill': True,
},
]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': activities},
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_agenda_apply_changes?NameID=yyy',
params=changes_params,
)
assert resp.json['err'] == 0
@freezegun.freeze_time('2020-08-01')
def test_set_activity_agenda_typical_week_endpoint_axel_error(
app, resource, family_data, activities, week_booking_params
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
week_booking_params['booking_list'] = ['monday']
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy', params=week_booking_params
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_activites') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy', params=week_booking_params
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/activities_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetListActivites'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
params=week_booking_params,
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
content = '''<PORTAIL>
<GETAGENDA>
<CODE>1</CODE>
<JOUR>
<JOURDATE>07/09/2020</JOURDATE>
<MATIN>.</MATIN>
<MIDI></MIDI>
<APRESMIDI></APRESMIDI>
<FERME>N</FERME>
</JOUR>
</GETAGENDA>
</PORTAIL>'''
with mock_data(content, 'GetAgenda'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
params=week_booking_params,
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_set_activity_agenda_typical_week_endpoint_no_result(app, resource, week_booking_params):
week_booking_params['child_id'] = 'zzz'
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy', params=week_booking_params
)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy', params=week_booking_params
)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_set_activity_agenda_typical_week_endpoint_date_error(app, resource, week_booking_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'GetFamilleIndividus'):
week_booking_params['start_date'] = '2021-09-01'
week_booking_params['end_date'] = '2021-08-31'
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
params=week_booking_params,
status=400,
)
assert resp.json['err_desc'] == 'start_date should be before end_date'
assert resp.json['err'] == 'bad-request'
week_booking_params['end_date'] = '2022-09-01'
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
params=week_booking_params,
status=400,
)
assert (
resp.json['err_desc'] == 'start_date and end_date are in different reference year (2021 != 2022)'
)
assert resp.json['err'] == 'bad-request'
def test_set_activity_agenda_typical_week_endpoint(
app, resource, family_data, activities, week_booking_params
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=[],
):
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
params=week_booking_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
assert resp.json['count'] == 0
@pytest.mark.parametrize('prefill', [True, False])
@freezegun.freeze_time('2020-08-01')
def test_set_activity_agenda_typical_week_endpoint_prefill_periscolaire(
app, resource, family_data, week_booking_params, prefill
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
for activity_id in ['ACCMAT', 'GARDERIES', 'ETUDES', 'CANTINE', 'FOOBAR', 'NAV MATIN', 'NAV SOIR']:
activity = {
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': activity_id,
'LIBELLEACTIVITE': 'FOOBAR',
}
week_booking_params['booking_list'] = ['monday']
week_booking_params['activity_id'] = activity_id
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': [activity]},
):
bookings = [
{
'id': '50632:%s:2020-09-07' % activity_id,
'disabled': False,
'prefill': prefill,
},
{
'id': '50632:%s:2020-09-08' % activity_id,
'disabled': False,
'prefill': prefill,
},
{
'id': '50632:%s:2020-09-10' % activity_id,
'disabled': False,
'prefill': prefill,
},
{
'id': '50632:%s:2020-09-11' % activity_id,
'disabled': False,
'prefill': prefill,
},
]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
params=week_booking_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE']
== activity_id
)
if prefill is True:
assert len(operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 3
for i, day in enumerate(['2020-09-08', '2020-09-10', '2020-09-11']):
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][i][
'JOURDATE'
]
== day
)
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][i]['MATIN']
== 'D'
)
else:
assert len(operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 1
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
== '2020-09-07'
)
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN']
== 'X'
)
@freezegun.freeze_time('2020-08-01')
def test_set_activity_agenda_typical_week_endpoint_extrascolaire_and_classe_decouverte(
app,
resource,
family_data,
week_booking_params,
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
for activity_id in ['CJ MER', 'CJVACANCES', 'DECFOO']:
activity = {
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': activity_id,
'LIBELLEACTIVITE': 'FOOBAR',
}
week_booking_params['booking_list'] = ['monday']
week_booking_params['activity_id'] = activity_id
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': [activity]},
):
bookings = [
{
'id': '50632:%s:2020-09-07' % activity_id,
'disabled': False,
'prefill': False,
},
]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
params=week_booking_params,
status=400,
)
assert resp.json['err_desc'] == 'Not available for this activity'
assert resp.json['err'] == 'bad-request'
@pytest.mark.parametrize('disabled', [True, False, None])
@freezegun.freeze_time('2020-08-01')
def test_set_activity_agenda_typical_week_endpoint_disabled(
app, resource, family_data, week_booking_params, disabled
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
activity = {
'ENTREE': '2020-09-02',
'SORTIE': '2021-08-31',
'IDENTACTIVITE': 'FOOBAR',
'LIBELLEACTIVITE': 'FOOBAR',
}
week_booking_params['booking_list'] = ['monday']
week_booking_params['activity_id'] = 'FOOBAR'
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value={'ACTIVITE': [activity]},
):
bookings = []
if disabled is not None:
bookings = [
{
'id': '50632:FOOBAR:2020-09-07',
'disabled': disabled,
'prefill': False,
},
]
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_agenda') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETAGENDA': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
params=week_booking_params,
)
assert resp.json['err'] == 0
assert resp.json['updated'] is True
if disabled is False:
assert operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['IDENTINDIVIDU'] == '50632'
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['IDENTACTIVITE'] == 'FOOBAR'
)
assert len(operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR']) == 1
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['JOURDATE']
== '2020-09-07'
)
assert (
operation.call_args_list[0][0][1]['PORTAIL']['SETAGENDA']['ACTIVITE']['JOUR'][0]['MATIN'] == 'X'
)
else:
assert len(operation.call_args_list) == 0
@pytest.mark.parametrize('code', [-1, -2, -3, -4])
def test_set_activity_agenda_typical_week_endpoint_wrong_code(
app, resource, family_data, activities, week_booking_params, code
):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
bookings = [
{
'id': '50632:ELEM:2020-09-07',
'disabled': False,
'prefill': True,
},
]
content = (
'''<PORTAIL>
<SETAGENDA>
<CODE>%s</CODE>
</SETAGENDA>
</PORTAIL>'''
% code
)
with mock_data(content, 'SetAgenda', data_method='setData'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_child_activities',
return_value=activities,
):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_bookings',
return_value=bookings,
):
resp = app.post_json(
'/caluire-axel/test/set_activity_agenda_typical_week?NameID=yyy',
params=week_booking_params,
)
assert resp.json['err_desc'] == 'Wrong agenda status'
assert resp.json['err'] == 'agenda-code-error-%s' % code
def test_invoices_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_factures_a_payer') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices?NameID=yyy')
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
content = '''<PORTAIL>
<GETFACTURESAPAYER>
<CODE>-3</CODE>
</GETFACTURESAPAYER>
</PORTAIL>'''
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices?NameID=yyy')
assert resp.json['err_desc'] == 'Wrong get-invoices status'
assert resp.json['err'] == 'get-invoices-code-error--3'
def test_invoices_endpoint_no_result(app, resource):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices?NameID=yyy')
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
def test_invoices_endpoint_no_invoice(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<GETFACTURESAPAYER>
<CODE>0</CODE>
</GETFACTURESAPAYER>
</PORTAIL>'''
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices?NameID=yyy')
assert resp.json['err'] == 0
assert resp.json['data'] == []
@freezegun.freeze_time('2019-12-12')
def test_invoices_endpoint(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
content = (
'''
<PORTAIL>
<GETFACTURESAPAYER>
%s
</GETFACTURESAPAYER>
</PORTAIL>'''
% xml.read()
)
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices?NameID=yyy')
assert resp.json['err'] == 0
assert resp.json['data'] == [
{
'id': 'XXX-42',
'display_id': '42',
'label': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'amount': '4.94',
'total_amount': '44.94',
'amount_paid': '40.00',
'online_payment': False,
'created': '2019-11-12',
'pay_limit_date': '2019-12-04',
'has_pdf': True,
'paid': False,
'vendor': {
'caluire-axel': {
'IDFACTURE': 42,
'MONTANT': '44.94',
'ENCAISSE': '40.00',
'FACTURATION': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'ECHEANCE': '2019-12-04',
'EMISSION': '2019-11-12',
'EXISTEPDF': True,
}
},
},
{
'id': 'XXX-43',
'display_id': '43',
'label': 'PRESTATIONS PERISCOLAIRES NOVEMBRE 2019',
'amount': '44.94',
'total_amount': '44.94',
'amount_paid': '0.00',
'online_payment': True,
'created': '2019-12-12',
'pay_limit_date': '2020-01-04',
'has_pdf': False,
'paid': False,
'vendor': {
'caluire-axel': {
'IDFACTURE': 43,
'FACTURATION': 'PRESTATIONS PERISCOLAIRES NOVEMBRE 2019',
'MONTANT': '44.94',
'ENCAISSE': '0.00',
'ECHEANCE': '2020-01-04',
'EMISSION': '2019-12-12',
'EXISTEPDF': False,
}
},
},
]
def test_invoices_history_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_list_factures') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
content = '''<PORTAIL>
<GETLISTFACTURES>
<CODE>-3</CODE>
</GETLISTFACTURES>
</PORTAIL>'''
with mock_data(content, 'GetListFactures'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
assert resp.json['err_desc'] == 'Wrong get-historical-invoices status'
assert resp.json['err'] == 'get-historical-invoices-code-error--3'
def test_invoices_history_endpoint_bad_request(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock_data(None, 'GetListFactures'):
resp = app.get(
'/caluire-axel/test/regie/MAREGIE/invoices/history?NameID=yyy&nb_mounts_limit=not_a_number',
status=400,
)
assert resp.json['err_desc'] == 'nb_mounts_limit must be an integer'
assert resp.json['err'] == 'bad-request'
def test_invoices_history_endpoint_no_result(app, resource):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
def test_invoices_history_endpoint_no_invoice(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
content = '''<PORTAIL>
<GETLISTFACTURES>
<CODE>0</CODE>
</GETLISTFACTURES>
</PORTAIL>'''
with mock_data(content, 'GetListFactures'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
assert resp.json['err'] == 0
assert resp.json['data'] == []
@freezegun.freeze_time('2019-12-12')
def test_invoices_history_endpoint(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
content = (
'''<PORTAIL>
<GETLISTFACTURES>
%s
</GETLISTFACTURES>
</PORTAIL>'''
% xml.read()
)
with mock_data(content, 'GetListFactures'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
assert resp.json['err'] == 0
assert resp.json['data'] == [
{
'id': 'historical-XXX-42',
'display_id': '42',
'label': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'amount': 0,
'created': '2019-11-12',
'total_amount': '44.94',
'online_payment': False,
'pay_limit_date': '',
'has_pdf': True,
'paid': False,
'vendor': {
'caluire-axel': {
'IDFACTURE': 42,
'MONTANT': '44.94',
'ENCAISSE': '40.00',
'FACTURATION': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'ECHEANCE': '2019-12-04',
'EMISSION': '2019-11-12',
'EXISTEPDF': True,
}
},
},
{
'id': 'historical-XXX-43',
'display_id': '43',
'label': 'PRESTATIONS PERISCOLAIRES NOVEMBRE 2019',
'amount': 0,
'created': '2019-12-12',
'total_amount': '44.94',
'online_payment': False,
'pay_limit_date': '',
'has_pdf': False,
'paid': False,
'vendor': {
'caluire-axel': {
'IDFACTURE': 43,
'FACTURATION': 'PRESTATIONS PERISCOLAIRES NOVEMBRE 2019',
'MONTANT': '44.94',
'ENCAISSE': '0.00',
'ECHEANCE': '2020-01-04',
'EMISSION': '2019-12-12',
'EXISTEPDF': False,
}
},
},
]
def test_invoice_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_factures_a_payer') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42?NameID=yyy')
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_invoice_endpoint_bad_request(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock_data(None, 'GetListFactures'):
resp = app.get(
'/caluire-axel/test/regie/MAREGIE/invoice/historical-XXX-42?NameID=yyy&nb_mounts_limit=not_a_number',
status=400,
)
assert resp.json['err_desc'] == 'nb_mounts_limit must be an integer'
assert resp.json['err'] == 'bad-request'
content = '''<PORTAIL>
<GETFACTURESAPAYER>
<CODE>-3</CODE>
</GETFACTURESAPAYER>
</PORTAIL>'''
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42?NameID=yyy')
assert resp.json['err_desc'] == 'Wrong get-invoices status'
assert resp.json['err'] == 'get-invoices-code-error--3'
content = '''<PORTAIL>
<GETLISTFACTURES>
<CODE>-3</CODE>
</GETLISTFACTURES>
</PORTAIL>'''
with mock_data(content, 'GetListFactures'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/historical-XXX-42?NameID=yyy')
assert resp.json['err_desc'] == 'Wrong get-historical-invoices status'
assert resp.json['err'] == 'get-historical-invoices-code-error--3'
@freezegun.freeze_time('2019-12-12')
def test_invoice_endpoint_no_result(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
invoices = xml.read()
content = (
'''<PORTAIL>
<GETFACTURESAPAYER>
%s
</GETFACTURESAPAYER>
</PORTAIL>'''
% invoices
)
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-35?NameID=yyy')
assert resp.json['err_desc'] == 'Invoice not found'
assert resp.json['err'] == 'not-found'
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-44?NameID=yyy')
assert resp.json['err_desc'] == 'Invoice not found'
assert resp.json['err'] == 'not-found'
content = (
'''<PORTAIL>
<GETLISTFACTURES>
%s
</GETLISTFACTURES>
</PORTAIL>'''
% invoices
)
with mock_data(content, 'GetListFactures'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/historical-XXX-35?NameID=yyy')
assert resp.json['err_desc'] == 'Invoice not found'
assert resp.json['err'] == 'not-found'
with mock_data(content, 'GetListFactures'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/historical-XXX-44?NameID=yyy')
assert resp.json['err_desc'] == 'Invoice not found'
assert resp.json['err'] == 'not-found'
@freezegun.freeze_time('2019-12-04')
def test_invoice_endpoint(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
invoices = xml.read()
content = (
'''<PORTAIL>
<GETFACTURESAPAYER>
%s
</GETFACTURESAPAYER>
</PORTAIL>'''
% invoices
)
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42?NameID=yyy')
assert resp.json['err'] == 0
assert resp.json['data'] == {
'id': 'XXX-42',
'display_id': '42',
'label': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'amount': '4.94',
'total_amount': '44.94',
'amount_paid': '40.00',
'online_payment': True,
'created': '2019-11-12',
'pay_limit_date': '2019-12-04',
'has_pdf': True,
'paid': False,
'vendor': {
'caluire-axel': {
'IDFACTURE': 42,
'MONTANT': '44.94',
'ENCAISSE': '40.00',
'FACTURATION': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'ECHEANCE': '2019-12-04',
'EMISSION': '2019-11-12',
'EXISTEPDF': True,
}
},
}
content = (
'''<PORTAIL>
<GETLISTFACTURES>
%s
</GETLISTFACTURES>
</PORTAIL>'''
% invoices
)
with mock_data(content, 'GetListFactures'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/historical-XXX-42?NameID=yyy')
assert resp.json['err'] == 0
assert resp.json['data'] == {
'id': 'historical-XXX-42',
'display_id': '42',
'label': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'amount': 0,
'total_amount': '44.94',
'online_payment': False,
'created': '2019-11-12',
'pay_limit_date': '',
'has_pdf': True,
'paid': False,
'vendor': {
'caluire-axel': {
'IDFACTURE': 42,
'MONTANT': '44.94',
'ENCAISSE': '40.00',
'FACTURATION': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'ECHEANCE': '2019-12-04',
'EMISSION': '2019-11-12',
'EXISTEPDF': True,
},
},
}
@freezegun.freeze_time('2019-12-04')
def test_invoice_endpoint_anonymously(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
invoices = xml.read()
content = (
'''<PORTAIL>
<GETFACTURESAPAYER>
%s
</GETFACTURESAPAYER>
</PORTAIL>'''
% invoices
)
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42')
assert resp.json['err'] == 0
assert resp.json['data'] == {
'id': 'XXX-42',
'display_id': '42',
'label': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'amount': '4.94',
'total_amount': '44.94',
'amount_paid': '40.00',
'online_payment': True,
'created': '2019-11-12',
'pay_limit_date': '2019-12-04',
'has_pdf': True,
'paid': False,
'vendor': {
'caluire-axel': {
'IDFACTURE': 42,
'MONTANT': '44.94',
'ENCAISSE': '40.00',
'FACTURATION': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'ECHEANCE': '2019-12-04',
'EMISSION': '2019-11-12',
'EXISTEPDF': True,
}
},
}
content = (
'''<PORTAIL>
<GETLISTFACTURES>
%s
</GETLISTFACTURES>
</PORTAIL>'''
% invoices
)
with mock_data(content, 'GetListFactures'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/historical-XXX-42')
assert resp.json['err'] == 0
assert resp.json['data'] == {
'id': 'historical-XXX-42',
'display_id': '42',
'label': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'amount': 0,
'total_amount': '44.94',
'online_payment': False,
'created': '2019-11-12',
'pay_limit_date': '',
'has_pdf': True,
'paid': False,
'vendor': {
'caluire-axel': {
'IDFACTURE': 42,
'MONTANT': '44.94',
'ENCAISSE': '40.00',
'FACTURATION': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
'ECHEANCE': '2019-12-04',
'EMISSION': '2019-11-12',
'EXISTEPDF': True,
},
},
}
def test_invoice_pdf_endpoint_axel_error(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_factures_a_payer') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pdf?NameID=yyy', status=404)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
content = (
'''<PORTAIL>
<GETFACTURESAPAYER>
%s
</GETFACTURESAPAYER>
</PORTAIL>'''
% xml.read()
)
with mock_data(content, 'GetFacturesaPayer'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_pdf_facture') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pdf?NameID=yyy', status=404)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
def test_invoice_pdf_endpoint_bad_request(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock_data(None, 'GetListFactures'):
resp = app.get(
'/caluire-axel/test/regie/MAREGIE/invoice/historical-XXX-42/pdf?NameID=yyy&nb_mounts_limit=not_a_number',
status=404,
)
assert resp.json['err_desc'] == 'nb_mounts_limit must be an integer'
assert resp.json['err'] == 'bad-request'
@freezegun.freeze_time('2019-12-13')
def test_invoice_pdf_endpoint_no_result(app, resource):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pdf?NameID=yyy', status=404)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
content = (
'''<PORTAIL>
<GETFACTURESAPAYER>
%s
</GETFACTURESAPAYER>
</PORTAIL>'''
% xml.read()
)
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-35/pdf?NameID=yyy', status=404)
assert resp.json['err_desc'] == 'Invoice not found'
assert resp.json['err'] == 'not-found'
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-44/pdf?NameID=yyy', status=404)
assert resp.json['err_desc'] == 'Invoice not found'
assert resp.json['err'] == 'not-found'
with mock_data(content, 'GetFacturesaPayer'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-43/pdf?NameID=yyy', status=404)
assert resp.json['err_desc'] == 'PDF not available'
assert resp.json['err'] == 'not-available'
pdf_content = '''<PORTAIL>
<GETPDFFACTURE>
<CODE>1</CODE>
<FACTUREPDF></FACTUREPDF>
</GETPDFFACTURE>
</PORTAIL>'''
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.get_invoice') as invoice:
invoice.return_value = {'has_pdf': True, 'display_id': '42'}
with mock_data(pdf_content, 'GetPdfFacture'):
resp = app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pdf?NameID=yyy', status=404)
assert resp.json['err_desc'] == 'PDF error'
assert resp.json['err'] == 'error'
def test_invoice_pdf_endpoint(app, resource):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
pdf_content = '''<PORTAIL>
<GETPDFFACTURE>
<CODE>1</CODE>
<FACTUREPDF>aGVsbG8gd29ybGQ=</FACTUREPDF>
</GETPDFFACTURE>
</PORTAIL>'''
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.get_invoice') as invoice:
invoice.return_value = {'has_pdf': True, 'display_id': '42'}
with mock_data(pdf_content, 'GetPdfFacture'):
app.get('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pdf?NameID=yyy')
assert invoice.call_args_list[0][1]['historical'] is False
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.get_invoice') as invoice:
invoice.return_value = {'has_pdf': True, 'display_id': '42'}
with mock_data(pdf_content, 'GetPdfFacture'):
app.get('/caluire-axel/test/regie/MAREGIE/invoice/historical-XXX-42/pdf?NameID=yyy')
assert invoice.call_args_list[0][1]['historical'] is True
def test_pay_invoice_endpoint_axel_error(app, resource):
payload = {
'transaction_date': '2021-06-15T12:00:00',
'transaction_id': 'foo',
}
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_factures_a_payer') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pay?NameID=yyy', params=payload)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
content = (
'''<PORTAIL>
<GETFACTURESAPAYER>
%s
</GETFACTURESAPAYER>
</PORTAIL>'''
% xml.read()
)
with mock_data(content, 'GetFacturesaPayer'):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_paiement') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pay?NameID=yyy', params=payload
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
for key in ('xml_request', 'xml_response', 'regie_id', 'family_id', 'invoice', 'post_data', 'kwargs'):
assert key in resp.json['data'].keys()
content2 = '''
<PORTAIL>
<SETPAIEMENT>
<CODE>-3</CODE>
</SETPAIEMENT>
</PORTAIL>'''
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.soap_client') as client:
client.return_value.service.getData.return_value = XML_RESPONSE_TEMPLATE % (
'GetFacturesaPayer',
content,
)
client.return_value.service.setData.return_value = XML_RESPONSE_TEMPLATE % ('SetPaiement', content2)
resp = app.post_json('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pay?NameID=yyy', params=payload)
assert resp.json['err_desc'] == 'Wrong pay-invoice status'
assert resp.json['err'] == 'pay-invoice-code-error--3'
def test_pay_invoice_endpoint_bad_request(app, resource):
resp = app.post_json(
'/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pay?NameID=yyy', params={}, status=400
)
assert resp.json['err_desc'] == "'transaction_date' is a required property"
@freezegun.freeze_time('2019-12-04')
def test_pay_invoice_endpoint_no_result(app, resource):
payload = {
'transaction_date': '2021-06-15T12:00:00',
'transaction_id': 'foo',
}
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
content = (
'''<PORTAIL>
<GETFACTURESAPAYER>
%s
</GETFACTURESAPAYER>
</PORTAIL>'''
% xml.read()
)
with mock_data(content, 'GetFacturesaPayer'):
resp = app.post_json('/caluire-axel/test/regie/MAREGIE/invoice/XXX-35/pay?NameID=yyy', params=payload)
assert resp.json['err_desc'] == 'Invoice not found'
assert resp.json['err'] == 'not-found'
with mock_data(content, 'GetFacturesaPayer'):
resp = app.post_json('/caluire-axel/test/regie/MAREGIE/invoice/XXX-44/pay?NameID=yyy', params=payload)
assert resp.json['err_desc'] == 'Invoice not found'
assert resp.json['err'] == 'not-found'
def test_pay_invoice_endpoint_wrong_response(app, resource):
payload = {
'transaction_date': '2021-06-15T12:00:00',
'transaction_id': 'foo',
}
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_invoice',
return_value={'amount': '44.9'},
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_paiement') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pay?NameID=yyy',
params=payload,
status=500,
)
assert resp.json['err'] == 'pay-invoice-code-response-error'
assert resp.json['err_desc'] == 'Wrong pay-invoice response'
for key in 'regie_id', 'family_id', 'invoice', 'post_data', 'kwargs', 'result':
assert key in resp.json['data'].keys()
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_paiement') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETPAIEMENT': {'CODE': 'oups'}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pay?NameID=yyy',
params=payload,
status=500,
)
assert resp.json['err'] == 'pay-invoice-code-response-error'
assert resp.json['err_desc'] == 'Wrong pay-invoice response'
for key in 'regie_id', 'family_id', 'invoice', 'post_data', 'kwargs', 'result':
assert key in resp.json['data'].keys()
def test_pay_invoice_endpoint(app, resource):
payload = {
'transaction_date': '2021-06-15T12:00:00',
'transaction_id': 'foo',
}
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/invoices.xml')
with open(filepath) as xml:
content = (
'''
<PORTAIL>
<GETFACTURESAPAYER>
%s
</GETFACTURESAPAYER>
</PORTAIL>'''
% xml.read()
)
content2 = '''
<PORTAIL>
<SETPAIEMENT>
<CODE>0</CODE>
</SETPAIEMENT>
</PORTAIL>'''
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.soap_client') as client:
client.return_value.service.getData.return_value = XML_RESPONSE_TEMPLATE % (
'GetFacturesaPayer',
content,
)
client.return_value.service.setData.return_value = XML_RESPONSE_TEMPLATE % ('SetPaiement', content2)
resp = app.post_json('/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pay?NameID=yyy', params=payload)
assert resp.json['err'] == 0
assert resp.json['created'] is True
def test_pay_invoice_providing_mode_reglement(app, resource):
payload = {
'transaction_date': '2021-06-15T12:00:00',
'transaction_id': 'foo',
}
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_invoice',
return_value={'amount': '44.9'},
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_paiement') as operation:
operation.return_value = OperationResult(
json_response={'DATA': {'PORTAIL': {'SETPAIEMENT': {'CODE': 0}}}},
xml_request='',
xml_response='',
)
resp = app.post_json(
'/caluire-axel/test/regie/MAREGIE/invoice/XXX-42/pay?NameID=yyy', params=payload
)
assert operation.call_args[0][1]['PORTAIL']['SETPAIEMENT']['IDENTMODEREGLEMENT'] == 'INCB'
assert resp.json['err'] == 0
assert resp.json['created'] is True
def test_upload_attachments_endpoint_axel_error(app, resource, family_data, upload_attachments_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/upload_attachments?NameID=yyy', params=upload_attachments_params
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
with mock.patch('passerelle.contrib.caluire_axel.schemas.set_pieces') as operation:
operation.side_effect = AxelError('FooBar')
resp = app.post_json(
'/caluire-axel/test/upload_attachments?NameID=yyy', params=upload_attachments_params
)
assert resp.json['err_desc'] == 'Axel error: FooBar'
assert resp.json['err'] == 'error'
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
def test_upload_attachments_endpoint_bad_date_format(app, resource, upload_attachments_params, value):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
upload_attachments_params['reference_date'] = value
resp = app.post_json(
'/caluire-axel/test/upload_attachments?NameID=yyy',
params=upload_attachments_params,
status=400,
)
assert resp.json['err_desc'] == "reference_date: '%s' does not match '[0-9]{4}-[0-9]{2}-[0-9]{2}'" % value
assert resp.json['err'] == 1
def test_upload_attachments_endpoint_no_result(app, resource, family_data, upload_attachments_params):
resp = app.post_json('/caluire-axel/test/upload_attachments?NameID=yyy', params=upload_attachments_params)
assert resp.json['err_desc'] == 'Person not found'
assert resp.json['err'] == 'not-found'
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
upload_attachments_params['child_id'] = 'zzz'
resp = app.post_json(
'/caluire-axel/test/upload_attachments?NameID=yyy',
params=upload_attachments_params,
)
assert resp.json['err_desc'] == 'Child not found'
assert resp.json['err'] == 'not-found'
def test_upload_attachments(app, resource, family_data, upload_attachments_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/upload_attachments.xml')
with open(filepath) as xml:
content = xml.read()
with mock_data(content, 'SetPieces', data_method='setData'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
resp = app.post_json(
'/caluire-axel/test/upload_attachments?NameID=yyy',
params=upload_attachments_params,
)
assert resp.json['err'] == 0
assert resp.json['created']
def test_upload_attachments_wrong_code(app, resource, family_data, upload_attachments_params):
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42')
code = -1
content = (
'''
<PORTAIL>
<SETPIECES>
<PIECE>
<CODE>0</CODE>
<LIBELLE>ID card</LIBELLE>
</PIECE>
<PIECE>
<CODE>%s</CODE>
<LIBELLE>Passport</LIBELLE>
</PIECE>
</SETPIECES>
</PORTAIL>'''
% code
)
with mock_data(content, 'SetPieces', data_method='setData'):
with mock.patch(
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data',
return_value=family_data,
):
resp = app.post_json(
'/caluire-axel/test/upload_attachments?NameID=yyy',
params=upload_attachments_params,
)
assert resp.json['err_desc'] == 'Wrong upload-attachments status'
assert resp.json['err'] == 'upload-attachments-code-error-%s' % code