4516 lines
190 KiB
Python
4516 lines
190 KiB
Python
# passerelle - uniform access to multiple data sources and services
|
|
# Copyright (C) 2020 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 copy
|
|
import datetime
|
|
import decimal
|
|
import json
|
|
import os
|
|
import xml.etree.ElementTree as ET
|
|
from contextlib import contextmanager
|
|
from unittest import mock
|
|
|
|
import freezegun
|
|
import jsonschema
|
|
import pytest
|
|
import xmlschema
|
|
from django.core.cache import cache
|
|
|
|
import tests.utils
|
|
from passerelle.contrib.toulouse_axel import schemas
|
|
from passerelle.contrib.toulouse_axel.models import Link, Lock, ToulouseAxel
|
|
from passerelle.contrib.toulouse_axel.utils import (
|
|
csp_mapping,
|
|
lien_parente_mapping,
|
|
regime_mapping,
|
|
situation_familiale_mapping,
|
|
type_regime_mapping,
|
|
upperize,
|
|
)
|
|
from passerelle.contrib.utils.axel import AxelError, OperationResult
|
|
from passerelle.utils.jsonresponse import APIError
|
|
from passerelle.utils.soap import SOAPError
|
|
|
|
|
|
@pytest.fixture
|
|
def resource(db):
|
|
return tests.utils.make_resource(
|
|
ToulouseAxel, slug='test', wsdl_url='http://example.net/AXEL_WS/AxelWS.php?wsdl'
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def link_params():
|
|
return {
|
|
'IDDUI': 'XXX',
|
|
'PRENOM': 'John',
|
|
'NOM': 'Doe',
|
|
'NAISSANCE': '2010-10-10',
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def update_params():
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/update_family_info.json')
|
|
with open(filepath) as jsonfile:
|
|
content = jsonfile.read()
|
|
return json.loads(content)
|
|
|
|
|
|
@pytest.fixture
|
|
def family_data():
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
resp = (
|
|
'''
|
|
<?xml version="1.0"?>
|
|
<PORTAILSERVICE>
|
|
<RESULTAT>
|
|
<TYPE>RefFamilleDui</TYPE>
|
|
<STATUS>OK</STATUS>
|
|
<DATE>10/10/2010 10:10:01</DATE>
|
|
<COMMENTAIRES><![CDATA[]]></COMMENTAIRES>
|
|
</RESULTAT>
|
|
<DATA>
|
|
%s
|
|
</DATA>
|
|
</PORTAILSERVICE>
|
|
'''.strip()
|
|
% content
|
|
)
|
|
return schemas.ref_famille_dui.response_converter.decode(ET.fromstring(resp))['DATA']['PORTAIL']['DUI']
|
|
|
|
|
|
@pytest.fixture
|
|
def child_activities_data():
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
resp = (
|
|
'''
|
|
<?xml version="1.0"?>
|
|
<PORTAILSERVICE>
|
|
<RESULTAT>
|
|
<TYPE>EnfantsActivites</TYPE>
|
|
<STATUS>OK</STATUS>
|
|
<DATE>10/10/2010 10:10:01</DATE>
|
|
<COMMENTAIRES><![CDATA[]]></COMMENTAIRES>
|
|
</RESULTAT>
|
|
<DATA>
|
|
%s
|
|
</DATA>
|
|
</PORTAILSERVICE>
|
|
'''.strip()
|
|
% content
|
|
)
|
|
return schemas.enfants_activites.response_converter.decode(ET.fromstring(resp))['DATA']['PORTAIL']['DUI']
|
|
|
|
|
|
@pytest.fixture
|
|
def flat_update_params():
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/flat_update_family_info.json')
|
|
with open(filepath) as jsonfile:
|
|
content = jsonfile.read()
|
|
return json.loads(content)
|
|
|
|
|
|
@pytest.fixture
|
|
def booking_params():
|
|
return {
|
|
'booking_start_date': '2020-04-13',
|
|
'booking_end_date': '2020-04-17',
|
|
'booking_list_MAT': [
|
|
'3535:MAT:A19P1M1:2020-04-13',
|
|
'3535:MAT:A19P1M1:2020-04-14',
|
|
'3535:MAT:A19P1M1:2020-04-16',
|
|
'3535:MAT:A19P1M1:2020-04-17',
|
|
],
|
|
'booking_list_MIDI': [
|
|
'3535:MIDI:A19P1M2:2020-04-13',
|
|
'3535:MIDI:A19P1M2:2020-04-14',
|
|
'3535:MIDI:A19P1M2:2020-04-16',
|
|
'3535:MIDI:A19P1M2:2020-04-17',
|
|
],
|
|
'booking_list_SOIR': ['3535:SOIR:A19P1M3:2020-04-13'],
|
|
'booking_list_GARD': ['3535:GARD:A19P1M4:2020-04-15'],
|
|
'child_id': '3535',
|
|
'regime': 'AV',
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def annual_booking_params():
|
|
return {
|
|
'booking_list_MAT': [
|
|
'3535:MAT:A19P1M1:monday',
|
|
'3535:MAT:A19P1M1:tuesday',
|
|
'3535:MAT:A19P1M1:thursday',
|
|
'3535:MAT:A19P1M1:friday',
|
|
],
|
|
'booking_list_MIDI': [
|
|
'3535:MIDI:A19P1M2:monday',
|
|
'3535:MIDI:A19P1M2:tuesday',
|
|
'3535:MIDI:A19P1M2:thursday',
|
|
'3535:MIDI:A19P1M2:friday',
|
|
],
|
|
'booking_list_SOIR': ['3535:SOIR:A19P1M3:monday'],
|
|
'booking_list_GARD': ['3535:GARD:A19P1M4:wednesday'],
|
|
'child_id': '3535',
|
|
'regime': 'AV',
|
|
'booking_date': '2019-08-01',
|
|
}
|
|
|
|
|
|
def test_lock(app, resource):
|
|
resp = app.get('/toulouse-axel/test/lock?key=&locker=', status=400)
|
|
assert resp.json['err_desc'] == "key is empty"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
assert Lock.objects.count() == 0
|
|
resp = app.get('/toulouse-axel/test/lock?key=foobar&locker=')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['key'] == 'foobar'
|
|
assert resp.json['locked'] is True
|
|
assert resp.json['locker'] == ''
|
|
assert resp.json['lock_date'] is not None
|
|
lock_date = resp.json['lock_date']
|
|
lock = Lock.objects.latest('pk')
|
|
assert lock.resource == resource
|
|
assert lock.key == 'foobar'
|
|
assert lock.locker == ''
|
|
|
|
# again
|
|
resp = app.get('/toulouse-axel/test/lock?key=foobar&locker=')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['key'] == 'foobar'
|
|
assert resp.json['locked'] is True
|
|
assert Lock.objects.count() == 1
|
|
assert resp.json['locker'] == ''
|
|
assert resp.json['lock_date'] == lock_date
|
|
|
|
|
|
def test_lock_with_locker(app, resource):
|
|
assert Lock.objects.count() == 0
|
|
resp = app.get('/toulouse-axel/test/lock?key=foobar&locker=something')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['key'] == 'foobar'
|
|
assert resp.json['locked'] is True
|
|
assert resp.json['locker'] == 'something'
|
|
assert resp.json['lock_date'] is not None
|
|
lock_date = resp.json['lock_date']
|
|
lock = Lock.objects.latest('pk')
|
|
assert lock.resource == resource
|
|
assert lock.key == 'foobar'
|
|
assert lock.locker == 'something'
|
|
|
|
# again
|
|
resp = app.get('/toulouse-axel/test/lock?key=foobar&locker=')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['key'] == 'foobar'
|
|
assert resp.json['locked'] is True
|
|
assert Lock.objects.count() == 1
|
|
assert resp.json['locker'] == 'something'
|
|
assert resp.json['lock_date'] == lock_date
|
|
|
|
|
|
def test_unlock(app, resource):
|
|
Lock.objects.create(resource=resource, key='foobar', locker='something')
|
|
resp = app.get('/toulouse-axel/test/unlock?key=foobar')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['key'] == 'foobar'
|
|
assert resp.json['locked'] is False
|
|
assert resp.json['locker'] == 'something'
|
|
assert resp.json['lock_date'] is not None
|
|
assert Lock.objects.count() == 0
|
|
|
|
# again
|
|
resp = app.get('/toulouse-axel/test/unlock?key=foobar')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['key'] == 'foobar'
|
|
assert resp.json['locked'] is False
|
|
assert 'locker' not in resp.json
|
|
assert 'lock_date' not in resp.json
|
|
assert Lock.objects.count() == 0
|
|
|
|
|
|
def test_locked(app, resource):
|
|
assert Lock.objects.count() == 0
|
|
resp = app.get('/toulouse-axel/test/locked?key=foobar')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['key'] == 'foobar'
|
|
assert resp.json['locked'] is False
|
|
assert 'locker' not in resp.json
|
|
assert 'lock_date' not in resp.json
|
|
|
|
Lock.objects.create(resource=resource, key='foobar', locker='something')
|
|
resp = app.get('/toulouse-axel/test/locked?key=foobar')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['key'] == 'foobar'
|
|
assert resp.json['locked'] is True
|
|
assert resp.json['locker'] == 'something'
|
|
assert resp.json['lock_date'] is not None
|
|
|
|
|
|
def test_operation_status_error(resource):
|
|
resp = '''
|
|
<?xml version="1.0"?>
|
|
<PORTAILSERVICE>
|
|
<RESULTAT>
|
|
<TYPE>RefVerifDui</TYPE>
|
|
<STATUS>NOK</STATUS>
|
|
<COMMENTAIRES><![CDATA[Foo reason]]></COMMENTAIRES>
|
|
</RESULTAT>
|
|
<DATA>
|
|
<PORTAIL/>
|
|
</DATA>
|
|
</PORTAILSERVICE>
|
|
'''.strip()
|
|
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.soap_client') as client:
|
|
client.return_value.service.getData.return_value = resp
|
|
with pytest.raises(AxelError, match='Foo reason'):
|
|
schemas.ref_verif_dui(
|
|
resource,
|
|
{
|
|
'PORTAIL': {
|
|
'DUI': {
|
|
'IDDUI': 'XXX',
|
|
'IDPERSONNE': '42',
|
|
'PRENOM': 'John',
|
|
'NOM': 'Doe',
|
|
'NAISSANCE': '2010-10-10',
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
@contextmanager
|
|
def mock_getdata(content, operation):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.soap_client') as client:
|
|
resp = '''
|
|
<?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>
|
|
'''.strip() % (
|
|
operation,
|
|
content,
|
|
)
|
|
client.return_value.service.getData.return_value = resp
|
|
yield
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
'<PORTAIL><DUIDATEGESTION/></PORTAIL>',
|
|
],
|
|
)
|
|
def test_operation_ref_date_gestion_dui(resource, content):
|
|
with mock_getdata(content, 'RefDateGestionDui'):
|
|
with pytest.raises(AxelError):
|
|
schemas.ref_date_gestion_dui(resource)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
'<PORTAIL><DUI/></PORTAIL>',
|
|
'<PORTAIL><DUI><CODE>foo</CODE></DUI></PORTAIL>',
|
|
'<PORTAIL><DUI><CODE>42</CODE></DUI></PORTAIL>',
|
|
],
|
|
)
|
|
def test_operation_ref_verif_dui(resource, content):
|
|
with mock_getdata(content, 'RefVerifDui'):
|
|
with pytest.raises(AxelError):
|
|
schemas.ref_verif_dui(
|
|
resource,
|
|
{
|
|
'PORTAIL': {
|
|
'DUI': {
|
|
'PRENOM': 'John',
|
|
'NOM': 'Doe',
|
|
'NAISSANCE': '2010-10-10',
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
'<PORTAIL><DUI/></PORTAIL>',
|
|
],
|
|
)
|
|
def test_operation_ref_famille_dui(resource, content):
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
with pytest.raises(AxelError):
|
|
schemas.ref_famille_dui(
|
|
resource,
|
|
{
|
|
'PORTAIL': {
|
|
'DUI': {
|
|
'IDDUI': 'XXX',
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
'<PORTAIL><DUI/></PORTAIL>',
|
|
],
|
|
)
|
|
def test_operation_form_maj_famille_dui(resource, content):
|
|
with mock_getdata(content, 'FormMajFamilleDui'):
|
|
with pytest.raises(AxelError):
|
|
schemas.form_maj_famille_dui(
|
|
resource,
|
|
{
|
|
'PORTAIL': {
|
|
'DUI': {
|
|
'IDDUI': 'XXX',
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
'<PORTAIL><DUI/></PORTAIL>',
|
|
],
|
|
)
|
|
def test_operation_ref_facture_a_payer(resource, content):
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
with pytest.raises(AxelError):
|
|
schemas.ref_facture_a_payer(
|
|
resource,
|
|
{
|
|
'PORTAIL': {
|
|
'DUI': {
|
|
'IDDUI': 'XXX',
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
'<PORTAIL><LISTFACTURE/></PORTAIL>',
|
|
],
|
|
)
|
|
def test_operation_list_dui_factures(resource, content):
|
|
with mock_getdata(content, 'ListeDuiFacturesPayeesRecettees'):
|
|
with pytest.raises(AxelError):
|
|
schemas.list_dui_factures(resource, {'LISTFACTURE': {'NUMDUI': 'XXX', 'DEBUT': '1970-01-01'}})
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
"<PORTAIL><PDF FOO='BAR'></PDF></PORTAIL>",
|
|
],
|
|
)
|
|
def test_operation_ref_facture_pdf(resource, content):
|
|
with mock_getdata(content, 'RefFacturePDF'):
|
|
with pytest.raises(AxelError):
|
|
schemas.ref_facture_pdf(
|
|
resource,
|
|
{
|
|
'PORTAIL': {
|
|
'FACTUREPDF': {
|
|
'IDFACTURE': 42,
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
'<PORTAIL><DUI/></PORTAIL>',
|
|
],
|
|
)
|
|
def test_operation_form_paiement_dui(resource, content):
|
|
with mock_getdata(content, 'FormPaiementDui'):
|
|
with pytest.raises(AxelError):
|
|
schemas.form_paiement_dui(
|
|
resource,
|
|
{
|
|
'PORTAIL': {
|
|
'DUI': {
|
|
'IDFACTURE': '42',
|
|
'IDREGIEENCAISSEMENT': '',
|
|
'MONTANTPAYE': '42.42',
|
|
'DATEPAIEMENT': '01/01/2020 12:12:12',
|
|
'REFERENCE': '42',
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
'<PORTAIL><DUI/></PORTAIL>',
|
|
],
|
|
)
|
|
def test_operation_enfants_activites(resource, content):
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with pytest.raises(AxelError):
|
|
schemas.enfants_activites(
|
|
resource,
|
|
{
|
|
'DUI': {
|
|
'IDDUI': 'XXX',
|
|
'ANNEEREFERENCE': '2042',
|
|
'TYPESACTIVITES': 'MAT,MIDI,SOIR,GARD',
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'content',
|
|
[
|
|
'<PORTAIL><DUI/></PORTAIL>',
|
|
],
|
|
)
|
|
def test_operation_reservation_periode(resource, content):
|
|
with mock_getdata(content, 'ReservationPeriode'):
|
|
with pytest.raises(AxelError):
|
|
schemas.reservation_periode(
|
|
resource,
|
|
{
|
|
'PORTAIL': {
|
|
'DUI': {
|
|
'IDDUI': 'XXX',
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
def test_management_dates_endpoint_axel_error(app, resource):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_date_gestion_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/management_dates')
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
assert resp.json['data'] == {'xml_request': None, 'xml_response': None}
|
|
|
|
|
|
def test_management_dates_endpoint(app, resource):
|
|
content = '''<PORTAIL>
|
|
<DUIDATEGESTION>
|
|
<REPORT-REVENUS>08/08/2019</REPORT-REVENUS>
|
|
<EXTRACTION-FAMILLES>18/10/2019</EXTRACTION-FAMILLES>
|
|
<EXTRACTION-CAFPRO>18/01/2020</EXTRACTION-CAFPRO>
|
|
</DUIDATEGESTION>
|
|
</PORTAIL>'''
|
|
with mock_getdata(content, 'RefDateGestionDui'):
|
|
resp = app.get('/toulouse-axel/test/management_dates')
|
|
assert set(resp.json.keys()) == {'err', 'data'}
|
|
assert resp.json['err'] == 0
|
|
assert set(resp.json['data'].keys()) == {
|
|
'REPORT-REVENUS',
|
|
'report_revenus',
|
|
'EXTRACTION-FAMILLES',
|
|
'extraction_familles',
|
|
'EXTRACTION-CAFPRO',
|
|
'extraction_cafpro',
|
|
}
|
|
|
|
# again - data are in cache
|
|
resp = app.get('/toulouse-axel/test/management_dates')
|
|
assert set(resp.json.keys()) == {'err', 'data'}
|
|
assert resp.json['err'] == 0
|
|
assert set(resp.json['data'].keys()) == {
|
|
'REPORT-REVENUS',
|
|
'report_revenus',
|
|
'EXTRACTION-FAMILLES',
|
|
'extraction_familles',
|
|
'EXTRACTION-CAFPRO',
|
|
'extraction_cafpro',
|
|
}
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_management_dates'
|
|
) as management_dates:
|
|
management_dates.return_value = {'foo': 'bar'}
|
|
resp = app.get('/toulouse-axel/test/management_dates')
|
|
assert set(resp.json.keys()) == {'err', 'data'}
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == {'foo': 'bar'}
|
|
|
|
|
|
def test_link_endpoint_nameid_empty(app, resource, link_params):
|
|
resp = app.post_json('/toulouse-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.toulouse_axel.schemas.ref_verif_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.post_json('/toulouse-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>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<IDPERSONNE />
|
|
<NOM>Doe</NOM>
|
|
<PRENOM>John</PRENOM>
|
|
<NAISSANCE>10/10/2010</NAISSANCE>
|
|
</DUI>
|
|
</PORTAIL>
|
|
"""
|
|
|
|
with mock_getdata('', 'RefVerifDui'):
|
|
with mock.patch('xmlschema.XMLSchema.validate') as xml_validate:
|
|
xml_validate.side_effect = xmlschema.XMLSchemaValidationError(None, None)
|
|
resp = app.post_json('/toulouse-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>RefVerifDui</TYPE>
|
|
<STATUS>NOK</STATUS>
|
|
<COMMENTAIRES>Foo reason</COMMENTAIRES>
|
|
</RESULTAT>
|
|
<DATA>
|
|
<PORTAIL />
|
|
</DATA>
|
|
</PORTAILSERVICE>"""
|
|
response = """
|
|
<?xml version="1.0"?>
|
|
<PORTAILSERVICE>
|
|
<RESULTAT>
|
|
<TYPE>RefVerifDui</TYPE>
|
|
<STATUS>NOK</STATUS>
|
|
<COMMENTAIRES><![CDATA[Foo reason]]></COMMENTAIRES>
|
|
</RESULTAT>
|
|
<DATA>
|
|
<PORTAIL/>
|
|
</DATA>
|
|
</PORTAILSERVICE>
|
|
""".strip()
|
|
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.soap_client') as client:
|
|
client.return_value.service.getData.return_value = response
|
|
resp = app.post_json('/toulouse-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>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<IDPERSONNE>42</IDPERSONNE>
|
|
<CODE>2</CODE>
|
|
</DUI>
|
|
</PORTAIL>"""
|
|
xml_response = (
|
|
"""<PORTAILSERVICE>
|
|
<RESULTAT>
|
|
<TYPE>RefVerifDui</TYPE>
|
|
<STATUS>OK</STATUS>
|
|
<DATE>10/10/2010 10:10:01</DATE>
|
|
<COMMENTAIRES />
|
|
</RESULTAT>
|
|
<DATA>
|
|
%s
|
|
</DATA>
|
|
</PORTAILSERVICE>"""
|
|
% content
|
|
)
|
|
with mock_getdata(content, 'RefVerifDui'):
|
|
with mock.patch('passerelle.contrib.utils.axel.AxelSchema.decode') as decode:
|
|
decode.side_effect = xmlschema.XMLSchemaValidationError(None, None)
|
|
resp = app.post_json('/toulouse-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.toulouse_axel.models.ToulouseAxel.soap_client') as client:
|
|
client.side_effect = SOAPError('SOAP service is down')
|
|
resp = app.post_json('/toulouse-axel/test/link?NameID=yyy', params=link_params)
|
|
assert resp.json['err_desc'] == "SOAP service is down"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'xml_response',
|
|
[
|
|
'<IDDUI>XXX</IDDUI><IDPERSONNE/><CODE>0</CODE>',
|
|
'<IDDUI>XXX</IDDUI><IDPERSONNE>42</IDPERSONNE><CODE>1</CODE>',
|
|
'<IDDUI>XXX</IDDUI><IDPERSONNE>42</IDPERSONNE><CODE>4</CODE>',
|
|
],
|
|
)
|
|
def test_link_endpoint_no_result(app, resource, link_params, xml_response):
|
|
content = (
|
|
'''<PORTAIL>
|
|
<DUI>
|
|
%s
|
|
</DUI>
|
|
</PORTAIL>'''
|
|
% xml_response
|
|
)
|
|
with mock_getdata(content, 'RefVerifDui'):
|
|
resp = app.post_json('/toulouse-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>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<IDPERSONNE>42</IDPERSONNE>
|
|
<CODE>2</CODE>
|
|
</DUI>
|
|
</PORTAIL>'''
|
|
# existing link but dui is wrong
|
|
link = Link.objects.create(resource=resource, name_id='yyy', dui='YYY', person_id='42')
|
|
with mock_getdata(content, 'RefVerifDui'):
|
|
resp = app.post_json('/toulouse-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.dui = 'XXX'
|
|
link.person_id = '35'
|
|
link.save()
|
|
with mock_getdata(content, 'RefVerifDui'):
|
|
resp = app.post_json('/toulouse-axel/test/link?NameID=yyy', params=link_params)
|
|
assert resp.json['err_desc'] == "Data conflict"
|
|
assert resp.json['err'] == 'conflict'
|
|
|
|
|
|
@pytest.mark.parametrize('code', [2, 3])
|
|
def test_link_endpoint(app, resource, link_params, code):
|
|
content = (
|
|
'''<PORTAIL>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<IDPERSONNE>42</IDPERSONNE>
|
|
<CODE>%s</CODE>
|
|
</DUI>
|
|
</PORTAIL>'''
|
|
% code
|
|
)
|
|
with mock_getdata(content, 'RefVerifDui'):
|
|
resp = app.post_json('/toulouse-axel/test/link?NameID=yyy', params=link_params)
|
|
assert set(resp.json.keys()) == {'err', 'link', 'created', 'dui', 'data'}
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['dui'] == 'XXX'
|
|
assert resp.json['created'] is True
|
|
assert 'xml_request' in resp.json['data']
|
|
assert 'xml_response' in resp.json['data']
|
|
|
|
# again
|
|
with mock_getdata(content, 'RefVerifDui'):
|
|
resp = app.post_json('/toulouse-axel/test/link?NameID=yyy', params=link_params)
|
|
assert set(resp.json.keys()) == {'err', 'link', 'created', 'dui', 'data'}
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['dui'] == 'XXX'
|
|
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_unlink_endpoint_no_result(app, resource):
|
|
resp = app.post('/toulouse-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', dui='XXX', person_id='42')
|
|
resp = app.post('/toulouse-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['dui'] == 'XXX'
|
|
assert resp.json['deleted'] is True
|
|
|
|
|
|
def test_active_dui_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_famille_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/active_dui?NameID=yyy')
|
|
assert resp.json['err_desc'] == "No family info"
|
|
assert resp.json['err'] == 'no-family-info'
|
|
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_verif_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/active_dui?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
def test_active_dui_endpoint_no_result(app, resource, family_data):
|
|
resp = app.get('/toulouse-axel/test/active_dui?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Unknown NameID"
|
|
assert resp.json['err'] == 'unknown'
|
|
|
|
|
|
def test_active_dui_endpoint_wrong_rl(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='1234')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/active_dui?NameID=yyy')
|
|
assert resp.json['err_desc'] == "No corresponding RL"
|
|
assert resp.json['err'] == 'no-rl'
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'xml_response,code',
|
|
[
|
|
('<IDDUI>XXX</IDDUI><IDPERSONNE/><CODE>0</CODE>', 0),
|
|
('<IDDUI>XXX</IDDUI><IDPERSONNE>42</IDPERSONNE><CODE>1</CODE>', 1),
|
|
('<IDDUI>XXX</IDDUI><IDPERSONNE>42</IDPERSONNE><CODE>4</CODE>', 4),
|
|
],
|
|
)
|
|
def test_active_dui_endpoint_wrong_dui_code(app, resource, family_data, xml_response, code):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
content = (
|
|
'''<PORTAIL>
|
|
<DUI>
|
|
%s
|
|
</DUI>
|
|
</PORTAIL>'''
|
|
% xml_response
|
|
)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
with mock_getdata(content, 'RefVerifDui'):
|
|
resp = app.get('/toulouse-axel/test/active_dui?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Wrong DUI status"
|
|
assert resp.json['err'] == 'dui-code-error-%s' % code
|
|
|
|
|
|
@pytest.mark.parametrize('code', [2, 3])
|
|
def test_active_dui_endpoint(app, resource, family_data, code):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
content = (
|
|
'''<PORTAIL>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<IDPERSONNE>42</IDPERSONNE>
|
|
<CODE>%s</CODE>
|
|
</DUI>
|
|
</PORTAIL>'''
|
|
% code
|
|
)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
with mock_getdata(content, 'RefVerifDui'):
|
|
resp = app.get('/toulouse-axel/test/active_dui?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert set(resp.json['data'].keys()) == {
|
|
'ADRESSE',
|
|
'CODEMISEAJOUR',
|
|
'DEMATFACTURES',
|
|
'ENFANT',
|
|
'IDDUI',
|
|
'NBENFANTACTIF',
|
|
'NBRLACTIF',
|
|
'REACTUALISATIONENLIGNE',
|
|
'REVENUS',
|
|
'RL1',
|
|
'RL2',
|
|
'SITUATIONFAMILIALE',
|
|
'TELFIXE',
|
|
}
|
|
|
|
|
|
def test_referential_endpoint_no_result(app, resource):
|
|
resp = app.get('/toulouse-axel/test/referential/foo/')
|
|
assert resp.json['err_desc'] == "Referential not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'code, mapping',
|
|
[
|
|
('situation_familiale', situation_familiale_mapping),
|
|
('csp', csp_mapping),
|
|
('lien_parente', lien_parente_mapping),
|
|
('type_regime', type_regime_mapping),
|
|
('regime', regime_mapping),
|
|
],
|
|
)
|
|
def test_referential_endpoint(app, resource, code, mapping):
|
|
resp = app.get('/toulouse-axel/test/referential/%s/' % code)
|
|
expected = [{'id': k, 'text': v} for k, v in mapping.items()]
|
|
assert resp.json['data'] == expected
|
|
|
|
|
|
def test_family_info_endpoint_axel_error(app, resource, family_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_famille_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_management_dates'
|
|
) as management_dates:
|
|
management_dates.side_effect = APIError('Axel error: FooBar')
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
|
|
|
|
def test_family_info_endpoint_no_result(app, resource):
|
|
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_famille_dui') as operation:
|
|
operation.return_value = OperationResult(
|
|
json_response={'DATA': {'PORTAIL': None}}, xml_request='', xml_response=''
|
|
)
|
|
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Family not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
@freezegun.freeze_time('2020-06-30')
|
|
def test_family_info_endpoint(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_management_dates'
|
|
) as management_dates:
|
|
management_dates.return_value = {'foo': 'bar'}
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert set(resp.json['data'].keys()) == {
|
|
'ADRESSE',
|
|
'CODEMISEAJOUR',
|
|
'DEMATFACTURES',
|
|
'ENFANT',
|
|
'IDDUI',
|
|
'NBENFANTACTIF',
|
|
'NBRLACTIF',
|
|
'REACTUALISATIONENLIGNE',
|
|
'REVENUS',
|
|
'RL1',
|
|
'RL2',
|
|
'SITUATIONFAMILIALE',
|
|
'SITUATIONFAMILIALE_label',
|
|
'TELFIXE',
|
|
'management_dates',
|
|
'annee_reference',
|
|
'annee_reference_short',
|
|
'annee_reference_label',
|
|
}
|
|
assert resp.json['data']['ENFANT'][0]['id'] == '4242'
|
|
assert resp.json['data']['ENFANT'][0]['text'] == 'foo foo'
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][0]['id'] == 0
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][0]['text'] == 'foo foo'
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][1]['id'] == 1
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][1]['text'] == 'foo2 foo2'
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][2]['id'] == 2
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][2]['text'] == 'foo3 foo3'
|
|
assert resp.json['data']['ENFANT'][1]['id'] == '3535'
|
|
assert resp.json['data']['ENFANT'][1]['text'] == 'foo foo'
|
|
assert resp.json['data']['management_dates'] == {'foo': 'bar'}
|
|
assert resp.json['data']['annee_reference'] == 2019
|
|
assert resp.json['data']['annee_reference_short'] == '19'
|
|
assert resp.json['data']['annee_reference_label'] == '2019/2020'
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.are_children_registered'
|
|
) as registered:
|
|
registered.return_value = {'4242': True}
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_management_dates'
|
|
) as management_dates:
|
|
management_dates.return_value = {'foo': 'bar'}
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data']['ENFANT'][0]['clae_cantine_current'] is True
|
|
assert resp.json['data']['ENFANT'][1]['clae_cantine_current'] is None
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.are_children_registered'
|
|
) as registered:
|
|
registered.return_value = {}
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_management_dates'
|
|
) as management_dates:
|
|
management_dates.return_value = {'foo': 'bar'}
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data']['ENFANT'][0]['clae_cantine_current'] is None
|
|
assert resp.json['data']['ENFANT'][1]['clae_cantine_current'] is None
|
|
|
|
assert resp.json['data']['SITUATIONFAMILIALE'] == 'S'
|
|
assert resp.json['data']['SITUATIONFAMILIALE_label'] == 'Séparé (e)'
|
|
assert resp.json['data']['RL1']['CSP'] == 'ETU'
|
|
assert resp.json['data']['RL1']['CSP_label'] == 'Etudiants'
|
|
assert resp.json['data']['RL2']['CSP'] == 'EMP'
|
|
assert resp.json['data']['RL2']['CSP_label'] == 'Employés'
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][0]['LIENPARENTE'] == 'GRP1'
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][0]['LIENPARENTE_label'] == 'Grands-parents paternels'
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][1]['LIENPARENTE'] is None
|
|
assert resp.json['data']['ENFANT'][0]['CONTACT'][1]['LIENPARENTE_label'] is None
|
|
assert resp.json['data']['REVENUS']['TYPEREGIME'] == 'GENE'
|
|
assert resp.json['data']['REVENUS']['TYPEREGIME_label'] == 'Régime général'
|
|
|
|
# a DUI with less data
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info_light.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_management_dates'
|
|
) as management_dates:
|
|
management_dates.return_value = {'foo': 'bar'}
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/family_info?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert set(resp.json['data'].keys()) == {
|
|
'ADRESSE',
|
|
'CODEMISEAJOUR',
|
|
'DEMATFACTURES',
|
|
'ENFANT',
|
|
'IDDUI',
|
|
'NBENFANTACTIF',
|
|
'NBRLACTIF',
|
|
'REACTUALISATIONENLIGNE',
|
|
'REVENUS',
|
|
'RL1',
|
|
'SITUATIONFAMILIALE',
|
|
'SITUATIONFAMILIALE_label',
|
|
'TELFIXE',
|
|
'management_dates',
|
|
'annee_reference',
|
|
'annee_reference_short',
|
|
'annee_reference_label',
|
|
}
|
|
assert resp.json['data']['ADRESSE'] is None
|
|
|
|
|
|
def test_children_info_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_famille_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-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('/toulouse-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', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/children_info?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 2
|
|
assert resp.json['data'][0]['id'] == '4242'
|
|
assert resp.json['data'][0]['text'] == 'foo foo'
|
|
assert resp.json['data'][0]['CONTACT'][0]['id'] == 0
|
|
assert resp.json['data'][0]['CONTACT'][0]['text'] == 'foo foo'
|
|
assert resp.json['data'][0]['CONTACT'][1]['id'] == 1
|
|
assert resp.json['data'][0]['CONTACT'][1]['text'] == 'foo2 foo2'
|
|
assert resp.json['data'][0]['CONTACT'][2]['id'] == 2
|
|
assert resp.json['data'][0]['CONTACT'][2]['text'] == 'foo3 foo3'
|
|
assert resp.json['data'][1]['id'] == '3535'
|
|
assert resp.json['data'][1]['text'] == 'foo foo'
|
|
|
|
|
|
def test_child_info_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_famille_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/child_info?NameID=yyy&idpersonne=zzz')
|
|
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('/toulouse-axel/test/child_info?NameID=yyy&idpersonne=zzz')
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-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', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/child_info?NameID=yyy&idpersonne=4242')
|
|
assert resp.json['err'] == 0
|
|
assert set(resp.json['data'].keys()) == {
|
|
'id',
|
|
'text',
|
|
'ASSURANCE',
|
|
'CONTACT',
|
|
'DATENAISSANCE',
|
|
'IDPERSONNE',
|
|
'PRENOM',
|
|
'PRENOMMERE',
|
|
'PRENOMPERE',
|
|
'NOM',
|
|
'NOMMERE',
|
|
'NOMPERE',
|
|
'RATTACHEAUTREDUI',
|
|
'SANITAIRE',
|
|
'SEXE',
|
|
'clae_cantine_current',
|
|
}
|
|
assert resp.json['data']['id'] == '4242'
|
|
assert resp.json['data']['text'] == 'foo foo'
|
|
assert resp.json['data']['CONTACT'][0]['id'] == 0
|
|
assert resp.json['data']['CONTACT'][0]['text'] == 'foo foo'
|
|
assert resp.json['data']['CONTACT'][1]['id'] == 1
|
|
assert resp.json['data']['CONTACT'][1]['text'] == 'foo2 foo2'
|
|
assert resp.json['data']['CONTACT'][2]['id'] == 2
|
|
assert resp.json['data']['CONTACT'][2]['text'] == 'foo3 foo3'
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.are_children_registered'
|
|
) as registered:
|
|
registered.return_value = {'4242': True}
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/child_info?NameID=yyy&idpersonne=4242')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data']['clae_cantine_current'] is True
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.are_children_registered'
|
|
) as registered:
|
|
registered.return_value = {}
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/child_info?NameID=yyy&idpersonne=4242')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data']['clae_cantine_current'] is None
|
|
|
|
assert resp.json['data']['CONTACT'][0]['LIENPARENTE'] == 'GRP1'
|
|
assert resp.json['data']['CONTACT'][0]['LIENPARENTE_label'] == 'Grands-parents paternels'
|
|
assert resp.json['data']['CONTACT'][1]['LIENPARENTE'] is None
|
|
assert resp.json['data']['CONTACT'][1]['LIENPARENTE_label'] is None
|
|
|
|
|
|
def test_child_contacts_info_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_famille_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/child_contacts_info?NameID=yyy&idpersonne=zzz')
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
def test_child_contacts_info_endpoint_no_result(app, resource):
|
|
resp = app.get('/toulouse-axel/test/child_contacts_info?NameID=yyy&idpersonne=zzz')
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/child_contacts_info?NameID=yyy&idpersonne=zzz')
|
|
assert resp.json['err_desc'] == "Child not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
def test_child_contacts_info_endpoint(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/child_contacts_info?NameID=yyy&idpersonne=4242')
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 3
|
|
assert resp.json['data'][0]['id'] == 0
|
|
assert resp.json['data'][0]['text'] == 'foo foo'
|
|
assert resp.json['data'][1]['id'] == 1
|
|
assert resp.json['data'][1]['text'] == 'foo2 foo2'
|
|
assert resp.json['data'][2]['id'] == 2
|
|
assert resp.json['data'][2]['text'] == 'foo3 foo3'
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/child_contacts_info?NameID=yyy&idpersonne=3535')
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 1
|
|
assert resp.json['data'][0]['id'] == 0
|
|
assert resp.json['data'][0]['text'] == 'foo foo'
|
|
|
|
|
|
def test_children_contacts_info_endpoint(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFamilleDui'):
|
|
resp = app.get('/toulouse-axel/test/children_contacts_info?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 3
|
|
assert {x['text'] for x in resp.json['data']} == {'foo foo', 'foo2 foo2', 'foo3 foo3'}
|
|
assert {x['id'] for x in resp.json['data']} == {0, 1, 2}
|
|
|
|
|
|
def test_update_family_info_endpoint_axel_error(app, resource, update_params, family_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.form_maj_famille_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resp = app.post_json('/toulouse-axel/test/update_family_info?NameID=yyy', params=update_params)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
assert 'error_post_data' in resp.json['data']
|
|
|
|
|
|
def test_update_family_info_endpoint_no_result(app, resource, update_params):
|
|
resp = app.post_json('/toulouse-axel/test/update_family_info?NameID=yyy', params=update_params)
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
def test_update_family_info_endpoint(app, resource, update_params, family_data):
|
|
link = Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
|
|
content = "<PORTAIL/>"
|
|
with mock_getdata(content, 'FormMajFamilleDui'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resp = app.post_json('/toulouse-axel/test/update_family_info?NameID=yyy', params=update_params)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['dui'] == 'XXX'
|
|
assert resp.json['updated'] is True
|
|
assert 'data' in resp.json
|
|
assert 'xml_request' in resp.json['data']
|
|
assert 'xml_response' in resp.json['data']
|
|
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.form_maj_famille_dui') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resp = app.post_json('/toulouse-axel/test/update_family_info?NameID=yyy', params=update_params)
|
|
assert operation.call_args_list[0][0][1]['PORTAIL']['DUI']['IDDUI'] == 'XXX'
|
|
assert operation.call_args_list[0][0][1]['PORTAIL']['DUI'][
|
|
'DATEDEMANDE'
|
|
] == datetime.date.today().strftime('%Y-%m-%d')
|
|
assert operation.call_args_list[0][0][1]['PORTAIL']['DUI']['QUIACTUALISEDUI'] == '1'
|
|
|
|
link.person_id = '35'
|
|
link.save()
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.form_maj_famille_dui') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resp = app.post_json('/toulouse-axel/test/update_family_info?NameID=yyy', params=update_params)
|
|
assert operation.call_args_list[0][0][1]['PORTAIL']['DUI']['IDDUI'] == 'XXX'
|
|
assert operation.call_args_list[0][0][1]['PORTAIL']['DUI'][
|
|
'DATEDEMANDE'
|
|
] == datetime.date.today().strftime('%Y-%m-%d')
|
|
assert operation.call_args_list[0][0][1]['PORTAIL']['DUI']['QUIACTUALISEDUI'] == '2'
|
|
|
|
|
|
def test_update_family_info_flat_endpoint(app, resource, flat_update_params, family_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
content = "<PORTAIL/>"
|
|
with mock_getdata(content, 'FormMajFamilleDui'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resp = app.post_json(
|
|
'/toulouse-axel/test/update_family_info?NameID=yyy', params=flat_update_params
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['dui'] == 'XXX'
|
|
assert resp.json['updated'] is True
|
|
assert 'data' in resp.json
|
|
assert 'xml_request' in resp.json['data']
|
|
assert 'xml_response' in resp.json['data']
|
|
|
|
|
|
def test_sanitize_update_family_data_missing_rl_fields(app, resource, update_params, family_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
full_update_params = copy.deepcopy(update_params)
|
|
for key in ['IDPERSONNE', 'NOM', 'PRENOM', 'NOMJEUNEFILLE', 'DATENAISSANCE', 'CIVILITE']:
|
|
assert key not in full_update_params['RL1']
|
|
assert key not in full_update_params['RL2']
|
|
|
|
resource.pre_sanitize_update_family_data(post_data=full_update_params)
|
|
jsonschema.validate(full_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=full_update_params)
|
|
for key in ['IDPERSONNE', 'NOM', 'PRENOM', 'NOMJEUNEFILLE', 'DATENAISSANCE', 'CIVILITE']:
|
|
assert full_update_params['RL1'][key] == family_data['RL1'][key]
|
|
assert full_update_params['RL2'][key] == family_data['RL2'][key]
|
|
assert full_update_params['RL1']['INDICATEURRL'] == '1'
|
|
assert full_update_params['RL2']['INDICATEURRL'] == '2'
|
|
|
|
|
|
def test_sanitize_update_family_data_missing_revenus_fields(app, resource, update_params, family_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
full_update_params = copy.deepcopy(update_params)
|
|
assert 'NBENFANTSACHARGE' not in update_params['REVENUS']
|
|
|
|
resource.pre_sanitize_update_family_data(post_data=full_update_params)
|
|
jsonschema.validate(full_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=full_update_params)
|
|
assert full_update_params['REVENUS']['NBENFANTSACHARGE'] == family_data['REVENUS']['NBENFANTSACHARGE']
|
|
|
|
# if revenus are not set in Axel
|
|
full_update_params = copy.deepcopy(update_params)
|
|
family_data.pop('REVENUS')
|
|
resource.pre_sanitize_update_family_data(post_data=full_update_params)
|
|
jsonschema.validate(full_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=full_update_params)
|
|
assert full_update_params['REVENUS']['NBENFANTSACHARGE'] is None
|
|
|
|
|
|
def test_pre_sanitize_update_upperize(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
def check_upper(data):
|
|
if isinstance(data, dict):
|
|
for val in data.values():
|
|
check_upper(val)
|
|
if isinstance(data, list):
|
|
for val in data:
|
|
check_upper(val)
|
|
if isinstance(data, str):
|
|
assert data == data.upper()
|
|
|
|
resource.pre_sanitize_update_family_data(post_data=update_params)
|
|
jsonschema.validate(update_params, json_schema)
|
|
check_upper(update_params)
|
|
|
|
assert upperize('something with an accent é') == 'SOMETHING WITH AN ACCENT E'
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_adresse(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:adresse
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:adresse'] = False
|
|
for key in partial_update_params['ADRESSE'].keys():
|
|
partial_update_params['ADRESSE'][key] = None # reset fields
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
for value in partial_update_params['ADRESSE'].values():
|
|
assert value is None
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_revenus(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:revenus
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:revenus'] = False
|
|
for key in partial_update_params['REVENUS'].keys():
|
|
partial_update_params['REVENUS'][key] = None # reset fields
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'REVENUS' not in partial_update_params
|
|
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:revenus'] = False
|
|
partial_update_params.pop('REVENUS')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'REVENUS' not in partial_update_params
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_rln(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:rln
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:rl1'] = False
|
|
for key in partial_update_params['RL1'].keys():
|
|
partial_update_params['RL1'][key] = None # reset fields
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'RL1' not in partial_update_params
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:rl2'] = False
|
|
for key in partial_update_params['RL2'].keys():
|
|
partial_update_params['RL2'][key] = None # reset fields
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'RL2' not in partial_update_params
|
|
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:rl1'] = False
|
|
partial_update_params['maj:rl2'] = False
|
|
partial_update_params.pop('RL1')
|
|
partial_update_params.pop('RL2')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'RL1' not in partial_update_params
|
|
assert 'RL2' not in partial_update_params
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_rln_adresse_employeur(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:rln_adresse_employeur
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:rl1_adresse_employeur'] = False
|
|
for key in partial_update_params['RL1']['ADREMPLOYEUR'].keys():
|
|
partial_update_params['RL1']['ADREMPLOYEUR'][key] = None # reset fields
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ADREMPLOYEUR' not in partial_update_params['RL1']
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:rl2_adresse_employeur'] = False
|
|
for key in partial_update_params['RL2']['ADREMPLOYEUR'].keys():
|
|
partial_update_params['RL2']['ADREMPLOYEUR'][key] = None # reset fields
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ADREMPLOYEUR' not in partial_update_params['RL2']
|
|
# combine with maj:rln
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:rl1'] = False
|
|
partial_update_params['maj:rl1_adresse_employeur'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'RL1' not in partial_update_params
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:rl2'] = False
|
|
partial_update_params['maj:rl2_adresse_employeur'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'RL2' not in partial_update_params
|
|
|
|
# test maj:rln_adresse_employeur not set
|
|
for val in [None, '']:
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:rl1_adresse_employeur'] = val
|
|
partial_update_params['RL1'].pop('ADREMPLOYEUR')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ADREMPLOYEUR' not in partial_update_params['RL1']
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:rl2_adresse_employeur'] = val
|
|
partial_update_params['RL2'].pop('ADREMPLOYEUR')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ADREMPLOYEUR' not in partial_update_params['RL2']
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_enfant_n(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:enfant_n
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0'] = False
|
|
for key in partial_update_params['ENFANT'][0].keys():
|
|
if key == 'IDPERSONNE':
|
|
continue
|
|
partial_update_params['ENFANT'][0][key] = None # reset fields
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
|
|
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
for key in partial_update_params['ENFANT'][1].keys():
|
|
if key == 'IDPERSONNE':
|
|
continue
|
|
partial_update_params['ENFANT'][1][key] = None # reset fields
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
|
|
|
|
# do not fill IDPERSONNE for the removed child
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
for key in partial_update_params['ENFANT'][1].keys():
|
|
partial_update_params['ENFANT'][1][key] = None # reset fields
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
|
|
|
|
# remove all children
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0'] = False
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params.pop('ENFANT')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ENFANT' not in partial_update_params
|
|
|
|
# unknown child
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_5'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 2
|
|
|
|
# missing IDPERSONNE
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['ENFANT'][0].pop('IDPERSONNE')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_enfant_n_assurance(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:enfant_n_assurance
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1_assurance'] = False
|
|
for key in partial_update_params['ENFANT'][1]['ASSURANCE'].keys():
|
|
partial_update_params['ENFANT'][1]['ASSURANCE'][key] = None # reset fields
|
|
partial_update_params['maj:enfant_0'] = False # check that ordering is not a problem
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
|
|
assert 'ASSURANCE' not in partial_update_params['ENFANT'][0]
|
|
# combine with maj:enfant_n
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['maj:enfant_1_assurance'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ENFANT' not in partial_update_params
|
|
|
|
# test maj:enfant_n_assurance not set
|
|
for val in [None, '']:
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1_assurance'] = val
|
|
partial_update_params['maj:enfant_0'] = False
|
|
partial_update_params['ENFANT'][0].pop('ASSURANCE')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ASSURANCE' not in partial_update_params['ENFANT'][0]
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_enfant_n_contact(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:enfant_n_contact
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_contact'] = False
|
|
for i, contact in enumerate(partial_update_params['ENFANT'][0]['CONTACT']):
|
|
for key in contact.keys():
|
|
partial_update_params['ENFANT'][0]['CONTACT'][i][key] = None # reset fields
|
|
partial_update_params['maj:enfant_1'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
|
|
assert 'CONTACT' not in partial_update_params['ENFANT'][0]
|
|
# combine with maj:enfant_n
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['maj:enfant_1_contact'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ENFANT' not in partial_update_params
|
|
|
|
# test maj:enfant_n_contact not set
|
|
for val in [None, '']:
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_contact'] = val
|
|
partial_update_params['ENFANT'][0].pop('CONTACT')
|
|
partial_update_params['maj:enfant_1'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'CONTACT' not in partial_update_params['ENFANT'][0]
|
|
|
|
# third contact of first child is not complete
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'CONTACT' in partial_update_params['ENFANT'][0]
|
|
assert len(partial_update_params['ENFANT'][0]['CONTACT']) == 2
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_enfant_n_sanitaire(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:enfant_n_sanitaire
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1_sanitaire'] = False
|
|
for key in partial_update_params['ENFANT'][1]['SANITAIRE'].keys():
|
|
partial_update_params['ENFANT'][1]['SANITAIRE'][key] = None # reset fields
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
|
|
assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
|
|
# combine with maj:enfant_n
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['maj:enfant_1_sanitaire'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ENFANT' not in partial_update_params
|
|
|
|
# test maj:enfant_n_sanitaire not set
|
|
for val in [None, '']:
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_sanitaire'] = val
|
|
partial_update_params['maj:enfant_1_sanitaire'] = val
|
|
partial_update_params['ENFANT'][0].pop('SANITAIRE')
|
|
partial_update_params['ENFANT'][1].pop('SANITAIRE')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
|
|
assert 'SANITAIRE' not in partial_update_params['ENFANT'][1]
|
|
|
|
|
|
def test_sanitize_update_family_data_enfant_n_sanitaire_allergie(app, resource, update_params, family_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:enfant_n_sanitaire_allergie
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_sanitaire_allergie'] = False
|
|
for key in partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE'].keys():
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE'][key] = None # reset fields
|
|
partial_update_params['maj:enfant_1'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert '_to_reset' in partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
|
|
assert 'ALLERGIE' in partial_update_params['ENFANT'][0]['SANITAIRE']
|
|
# fields were set with origin values found in Axel
|
|
new_values = partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']
|
|
old_values = family_data['ENFANT'][0]['SANITAIRE']['ALLERGIE']
|
|
assert new_values == old_values
|
|
# combine with maj:enfant_n_sanitaire
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1_sanitaire'] = False
|
|
partial_update_params['maj:enfant_1_sanitaire_allergie'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
|
|
assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
|
|
# combine with maj:enfant_n
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['maj:enfant_1_sanitaire_allergie'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert 'ENFANT' not in partial_update_params
|
|
|
|
# test maj:enfant_n_sanitaire_allergie not set
|
|
for val in [None, '']:
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_sanitaire_allergie'] = val
|
|
partial_update_params['maj:enfant_1'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
new_values = partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']
|
|
old_values = family_data['ENFANT'][0]['SANITAIRE']['ALLERGIE']
|
|
assert new_values == old_values
|
|
|
|
# allergie field is required
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_sanitaire_allergie'] = False
|
|
partial_update_params['ENFANT'][0]['SANITAIRE'].pop('ALLERGIE')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
with pytest.raises(jsonschema.exceptions.ValidationError, match="'ALLERGIE' is a required property"):
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
|
|
|
|
def test_sanitize_update_family_data_enfant_n_sanitaire_allergie_values(
|
|
app, resource, update_params, family_data
|
|
):
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
# check values
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ASTHME'] = 'NON'
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['MEDICAMENTEUSES'] = '0'
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ALIMENTAIRES'] = 'False'
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['AUTRES'] = ''
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert 'ALLERGIE' not in partial_update_params['ENFANT'][0]['SANITAIRE']
|
|
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ASTHME'] = False
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['MEDICAMENTEUSES'] = ''
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ALIMENTAIRES'] = None
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['AUTRES'] = ''
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert 'ALLERGIE' not in partial_update_params['ENFANT'][0]['SANITAIRE']
|
|
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ASTHME'] = 'OUI'
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['MEDICAMENTEUSES'] = '1'
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ALIMENTAIRES'] = 'True'
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['AUTRES'] = 'accariens'
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE'] == [
|
|
{'TYPE': 'ASTHME', 'ALLERGIQUE': 'OUI', 'NOMALLERGIE': None},
|
|
{'TYPE': 'MEDICAMENTEUSES', 'ALLERGIQUE': 'OUI', 'NOMALLERGIE': None},
|
|
{'TYPE': 'ALIMENTAIRES', 'ALLERGIQUE': 'OUI', 'NOMALLERGIE': None},
|
|
{'TYPE': 'AUTRES', 'ALLERGIQUE': 'OUI', 'NOMALLERGIE': 'ACCARIENS'},
|
|
]
|
|
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ASTHME'] = ''
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['MEDICAMENTEUSES'] = '1'
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['ALIMENTAIRES'] = 'True'
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']['AUTRES'] = ''
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE'] == [
|
|
{'TYPE': 'MEDICAMENTEUSES', 'ALLERGIQUE': 'OUI', 'NOMALLERGIE': None},
|
|
{'TYPE': 'ALIMENTAIRES', 'ALLERGIQUE': 'OUI', 'NOMALLERGIE': None},
|
|
]
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_enfant_n_sanitaire_medecin(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:enfant_n_sanitaire_medecin
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1_sanitaire_medecin'] = False
|
|
for key in partial_update_params['ENFANT'][1]['SANITAIRE']['MEDECIN'].keys():
|
|
partial_update_params['ENFANT'][1]['SANITAIRE']['MEDECIN'][key] = None # reset fields
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
|
|
assert 'MEDECIN' not in partial_update_params['ENFANT'][0]['SANITAIRE']
|
|
# combine with maj:enfant_n_sanitaire
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1_sanitaire'] = False
|
|
partial_update_params['maj:enfant_1_sanitaire_medecin'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
|
|
assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
|
|
# combine with maj:enfant_n
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['maj:enfant_1_sanitaire_medecin'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ENFANT' not in partial_update_params
|
|
|
|
# test maj:enfant_n_sanitaire_medecin not set
|
|
for val in [None, '']:
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_sanitaire_medecin'] = val
|
|
partial_update_params['maj:enfant_1_sanitaire_medecin'] = val
|
|
partial_update_params['ENFANT'][0]['SANITAIRE'].pop('MEDECIN')
|
|
partial_update_params['ENFANT'][1]['SANITAIRE'].pop('MEDECIN')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'MEDECIN' not in partial_update_params['ENFANT'][0]['SANITAIRE']
|
|
assert 'MEDECIN' not in partial_update_params['ENFANT'][1]['SANITAIRE']
|
|
|
|
|
|
def test_pre_sanitize_update_family_data_enfant_n_sanitaire_vaccin(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:enfant_n_sanitaire_vaccin
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1_sanitaire_vaccin'] = False
|
|
for key in partial_update_params['ENFANT'][1]['SANITAIRE']['VACCIN'].keys():
|
|
partial_update_params['ENFANT'][1]['SANITAIRE']['VACCIN'][key] = None # reset fields
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
|
|
assert 'VACCIN' not in partial_update_params['ENFANT'][0]['SANITAIRE']
|
|
# combine with maj:enfant_n_sanitaire
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1_sanitaire'] = False
|
|
partial_update_params['maj:enfant_1_sanitaire_vaccin'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
|
|
assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
|
|
# combine with maj:enfant_n
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['maj:enfant_1_sanitaire_vaccin'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'ENFANT' not in partial_update_params
|
|
|
|
# test maj:enfant_n_sanitaire_vaccin not set
|
|
for val in [None, '']:
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_sanitaire_vaccin'] = val
|
|
partial_update_params['maj:enfant_1_sanitaire_vaccin'] = val
|
|
partial_update_params['ENFANT'][0]['SANITAIRE'].pop('VACCIN')
|
|
partial_update_params['ENFANT'][1]['SANITAIRE'].pop('VACCIN')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert 'VACCIN' not in partial_update_params['ENFANT'][0]['SANITAIRE']
|
|
assert 'VACCIN' not in partial_update_params['ENFANT'][1]['SANITAIRE']
|
|
|
|
|
|
def test_sanitize_update_family_data_enfant_n_sanitaire_handicap(app, resource, update_params, family_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
# test maj:enfant_n_sanitaire_handicap
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_sanitaire_handicap'] = False
|
|
# reset fields
|
|
handicap_fields = [
|
|
'AUTREDIFFICULTE',
|
|
'ECOLESPECIALISEE',
|
|
'INDICATEURAUXILIAIREVS',
|
|
'INDICATEURECOLE',
|
|
'INDICATEURHANDICAP',
|
|
'INDICATEURNOTIFMDPH',
|
|
]
|
|
for key in handicap_fields:
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['HANDICAP'][key] = None
|
|
partial_update_params['maj:enfant_1'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
assert '_to_reset' in partial_update_params['ENFANT'][0]['SANITAIRE']['HANDICAP']
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
|
|
# fields were set with origin values found in Axel
|
|
new_values = partial_update_params['ENFANT'][0]['SANITAIRE']
|
|
for key in handicap_fields:
|
|
assert new_values[key] == family_data['ENFANT'][0]['SANITAIRE'][key]
|
|
assert '_to_reset' not in new_values
|
|
assert 'HANDICAP' not in new_values
|
|
# combine with maj:enfant_n_sanitaire
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1_sanitaire'] = False
|
|
partial_update_params['maj:enfant_1_sanitaire_handicap'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert len(partial_update_params['ENFANT']) == 1
|
|
assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
|
|
assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
|
|
# combine with maj:enfant_n
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_1'] = False
|
|
partial_update_params['maj:enfant_1_sanitaire_handicap'] = False
|
|
partial_update_params['maj:enfant_0'] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
assert 'ENFANT' not in partial_update_params
|
|
|
|
# test maj:enfant_n_sanitaire_handicap not set
|
|
for val in [None, '']:
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_sanitaire_handicap'] = val
|
|
partial_update_params['maj:enfant_1'] = False
|
|
# reset fields
|
|
for key in handicap_fields:
|
|
partial_update_params['ENFANT'][0]['SANITAIRE']['HANDICAP'][key] = None
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_family_data', return_value=family_data
|
|
):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
new_values = partial_update_params['ENFANT'][0]['SANITAIRE']
|
|
for key in handicap_fields:
|
|
assert new_values[key] == family_data['ENFANT'][0]['SANITAIRE'][key]
|
|
assert 'HANDICAP' not in new_values
|
|
|
|
# handicap field is required
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
partial_update_params['maj:enfant_0_sanitaire_handicap'] = False
|
|
partial_update_params['ENFANT'][0]['SANITAIRE'].pop('HANDICAP')
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
with pytest.raises(jsonschema.exceptions.ValidationError, match="'HANDICAP' is a required property"):
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'flags',
|
|
[
|
|
# get family data to fill handicap fields
|
|
['maj:enfant_0_sanitaire_handicap', 'maj:revenus', 'maj:rl1', 'maj:rl2'],
|
|
# get family data to fill revenus fields
|
|
['maj:rl1', 'maj:rl2'],
|
|
# get family data to fill rl1 fields
|
|
['maj:revenus', 'maj:rl2'],
|
|
# get family data to fill rl2 fields
|
|
['maj:revenus', 'maj:rl1'],
|
|
],
|
|
)
|
|
def test_sanitize_update_family_data_axel_error(app, resource, update_params, flags):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
json_schema = schemas.UPDATE_FAMILY_SCHEMA
|
|
|
|
partial_update_params = copy.deepcopy(update_params)
|
|
for flag in flags:
|
|
partial_update_params[flag] = False
|
|
resource.pre_sanitize_update_family_data(post_data=partial_update_params)
|
|
jsonschema.validate(partial_update_params, json_schema)
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_famille_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
with pytest.raises(APIError, match='Axel error: FooBar'):
|
|
resource.sanitize_update_family_data(dui='XXX', post_data=partial_update_params)
|
|
|
|
|
|
def test_update_family_info_endpoint_sanitize_axel_error(app, resource, update_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.sanitize_update_family_data'
|
|
) as sanitize:
|
|
sanitize.side_effect = APIError('Axel error: FooBar')
|
|
resp = app.post_json('/toulouse-axel/test/update_family_info?NameID=yyy', params=update_params)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
|
|
|
|
def test_invoices_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_facture_a_payer') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices?NameID=', status=400)
|
|
assert 'InvalidParameterValue' in resp.json['err_class']
|
|
assert resp.json['err'] == 1
|
|
|
|
|
|
def test_invoices_endpoint_no_result(app, resource):
|
|
resp = app.get('/toulouse-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_invoices(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
content = '''<PORTAIL>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<CHOIXDEMAT>0</CHOIXDEMAT>
|
|
<NBFACTURES>0</NBFACTURES>
|
|
</DUI>
|
|
</PORTAIL>'''
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == []
|
|
|
|
|
|
def test_invoices_endpoint(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-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': True,
|
|
'created': '2019-11-12',
|
|
'pay_limit_date': '2019-12-04',
|
|
'has_pdf': True,
|
|
'paid': False,
|
|
'vendor': {
|
|
'toulouse-axel': {
|
|
'IDFACTURATION': '4242-35AA',
|
|
'IDFACTURE': 42,
|
|
'IDREGIE': 'MAREGIE',
|
|
'DATEECHEANCE': '2019-12-04',
|
|
'DATEEMISSION': '2019-11-12',
|
|
'EXISTEPDF': '1',
|
|
'LIBELLE': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
|
|
'MONTANTTOTAL': '44.94',
|
|
'NUMFACTURE': 42,
|
|
'RESTEAPAYER': '4.94',
|
|
}
|
|
},
|
|
},
|
|
{
|
|
'id': 'XXX-43',
|
|
'display_id': '43',
|
|
'label': 'PRESTATIONS PERISCOLAIRES NOVEMBRE 2019',
|
|
'amount': '44.94',
|
|
'total_amount': '44.94',
|
|
'amount_paid': '',
|
|
'online_payment': True,
|
|
'created': '2019-12-12',
|
|
'pay_limit_date': '2020-01-04',
|
|
'has_pdf': False,
|
|
'paid': False,
|
|
'vendor': {
|
|
'toulouse-axel': {
|
|
'IDFACTURATION': '4243-35AA',
|
|
'IDFACTURE': 43,
|
|
'DATEECHEANCE': '2020-01-04',
|
|
'DATEEMISSION': '2019-12-12',
|
|
'EXISTEPDF': '0',
|
|
'IDREGIE': 'MAREGIE',
|
|
'LIBELLE': 'PRESTATIONS PERISCOLAIRES NOVEMBRE 2019',
|
|
'MONTANTTOTAL': '44.94',
|
|
'NUMFACTURE': 43,
|
|
'RESTEAPAYER': '44.94',
|
|
}
|
|
},
|
|
},
|
|
]
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-axel/test/regie/AUTREREGIE/invoices?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == [
|
|
{
|
|
'id': 'XXX-44',
|
|
'display_id': '44',
|
|
'label': 'PRESTATIONS PERISCOLAIRES DECEMBRE 2019',
|
|
'amount': '44.94',
|
|
'total_amount': '44.94',
|
|
'amount_paid': '',
|
|
'online_payment': True,
|
|
'created': '2020-01-12',
|
|
'pay_limit_date': '2020-01-15',
|
|
'has_pdf': True,
|
|
'paid': False,
|
|
'vendor': {
|
|
'toulouse-axel': {
|
|
'IDFACTURATION': '4244-35AA',
|
|
'IDFACTURE': 44,
|
|
'IDREGIE': 'AUTREREGIE',
|
|
'DATEECHEANCE': '2020-01-15',
|
|
'DATEEMISSION': '2020-01-12',
|
|
'EXISTEPDF': '1',
|
|
'LIBELLE': 'PRESTATIONS PERISCOLAIRES DECEMBRE 2019',
|
|
'MONTANTTOTAL': '44.94',
|
|
'NUMFACTURE': 44,
|
|
'RESTEAPAYER': '44.94',
|
|
}
|
|
},
|
|
}
|
|
]
|
|
|
|
|
|
def test_invoices_history_endpoint_empty_nameid_error(app, resource):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices/history?NameID=', status=400)
|
|
assert resp.json['err_desc'] == 'invalid value for parameter "NameID"'
|
|
assert resp.json['err'] == 1
|
|
|
|
|
|
def test_invoices_history_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.list_dui_factures') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
def test_invoices_history_endpoint_no_result(app, resource):
|
|
resp = app.get('/toulouse-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_invoices(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
content = '''<PORTAIL>
|
|
<LISTFACTURE>
|
|
<NBFACTURERESTANTE>0</NBFACTURERESTANTE>
|
|
</LISTFACTURE>
|
|
</PORTAIL>'''
|
|
with mock_getdata(content, 'ListeDuiFacturesPayeesRecettees'):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == []
|
|
|
|
|
|
def test_invoices_history_endpoint(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices_history.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'ListeDuiFacturesPayeesRecettees'):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == [
|
|
{
|
|
'amount': 0,
|
|
'created': '2017-03-23',
|
|
'display_id': '42',
|
|
'has_pdf': True,
|
|
'id': 'historical-XXX-42',
|
|
'label': 'PRESTATIONS SEPTEMBRE 2015',
|
|
'online_payment': False,
|
|
'paid': False,
|
|
'pay_limit_date': '',
|
|
'total_amount': '28.98',
|
|
'vendor': {
|
|
'toulouse-axel': {
|
|
'EMISSION': '2017-03-23',
|
|
'IDAXEL': 'AXEL',
|
|
'IDDIRECTION': 'DIR-A',
|
|
'IDFACTURE': 42,
|
|
'IDFAMILLE': 'XXX',
|
|
'IPDF': 'O',
|
|
'LIBDIRECTION': 'DIRECTION A',
|
|
'LIBELLE': 'PRESTATIONS SEPTEMBRE 2015',
|
|
'MONTANT': '28.98',
|
|
'NOFACTURE': 42,
|
|
'NUMDIRECTION': 10,
|
|
}
|
|
},
|
|
},
|
|
{
|
|
'amount': 0,
|
|
'created': '2017-03-23',
|
|
'display_id': '43',
|
|
'has_pdf': False,
|
|
'id': 'historical-XXX-43',
|
|
'label': 'PRESTATIONS OCTOBRE 2015',
|
|
'online_payment': False,
|
|
'paid': False,
|
|
'pay_limit_date': '',
|
|
'total_amount': '28.98',
|
|
'vendor': {
|
|
'toulouse-axel': {
|
|
'EMISSION': '2017-03-23',
|
|
'IDAXEL': 'AXEL',
|
|
'IDDIRECTION': 'DIR-B',
|
|
'IDFACTURE': 43,
|
|
'IDFAMILLE': 'XXX',
|
|
'IPDF': 'N',
|
|
'LIBDIRECTION': 'DIRECTION B',
|
|
'LIBELLE': 'PRESTATIONS OCTOBRE 2015',
|
|
'MONTANT': '28.98',
|
|
'NOFACTURE': 43,
|
|
'NUMDIRECTION': 11,
|
|
}
|
|
},
|
|
},
|
|
]
|
|
|
|
|
|
def test_invoice_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_facture_a_payer') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-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_no_result(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-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_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-44?NameID=yyy')
|
|
assert resp.json['err_desc'] == "Invoice not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
@pytest.mark.parametrize('dui', ['XXX', 'S-XXX'])
|
|
def test_invoice_endpoint(app, resource, dui):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui=dui, person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read().replace('XXX', dui)
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/%s-42?NameID=yyy' % dui)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == {
|
|
'id': '%s-42' % dui,
|
|
'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': {
|
|
'toulouse-axel': {
|
|
'IDFACTURATION': '4242-35AA',
|
|
'IDFACTURE': 42,
|
|
'IDREGIE': 'MAREGIE',
|
|
'DATEECHEANCE': '2019-12-04',
|
|
'DATEEMISSION': '2019-11-12',
|
|
'EXISTEPDF': '1',
|
|
'LIBELLE': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
|
|
'MONTANTTOTAL': '44.94',
|
|
'NUMFACTURE': 42,
|
|
'RESTEAPAYER': '4.94',
|
|
}
|
|
},
|
|
}
|
|
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices_history.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read().replace('XXX', dui)
|
|
with mock_getdata(content, 'ListeDuiFacturesPayeesRecettees'):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/historical-%s-42?NameID=yyy' % dui)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == {
|
|
'amount': 0,
|
|
'created': '2017-03-23',
|
|
'display_id': '42',
|
|
'has_pdf': True,
|
|
'id': 'historical-%s-42' % dui,
|
|
'label': 'PRESTATIONS SEPTEMBRE 2015',
|
|
'online_payment': False,
|
|
'paid': False,
|
|
'pay_limit_date': '',
|
|
'total_amount': '28.98',
|
|
'vendor': {
|
|
'toulouse-axel': {
|
|
'EMISSION': '2017-03-23',
|
|
'IDAXEL': 'AXEL',
|
|
'IDDIRECTION': 'DIR-A',
|
|
'IDFACTURE': 42,
|
|
'IDFAMILLE': dui,
|
|
'IPDF': 'O',
|
|
'LIBDIRECTION': 'DIRECTION A',
|
|
'LIBELLE': 'PRESTATIONS SEPTEMBRE 2015',
|
|
'MONTANT': '28.98',
|
|
'NOFACTURE': 42,
|
|
'NUMDIRECTION': 10,
|
|
}
|
|
},
|
|
}
|
|
|
|
|
|
@pytest.mark.parametrize('dui', ['XXX', 'S-XXX'])
|
|
def test_invoice_endpoint_anonymous(app, resource, dui):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui=dui, person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read().replace('XXX', dui)
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/%s-42' % dui)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == {
|
|
'id': '%s-42' % dui,
|
|
'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': {
|
|
'toulouse-axel': {
|
|
'IDFACTURATION': '4242-35AA',
|
|
'IDFACTURE': 42,
|
|
'IDREGIE': 'MAREGIE',
|
|
'DATEECHEANCE': '2019-12-04',
|
|
'DATEEMISSION': '2019-11-12',
|
|
'EXISTEPDF': '1',
|
|
'LIBELLE': 'PRESTATIONS PERISCOLAIRES SEPTEMBRE-OCTOBRE 2019',
|
|
'MONTANTTOTAL': '44.94',
|
|
'NUMFACTURE': 42,
|
|
'RESTEAPAYER': '4.94',
|
|
}
|
|
},
|
|
}
|
|
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices_history.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read().replace('XXX', dui)
|
|
with mock_getdata(content, 'ListeDuiFacturesPayeesRecettees'):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/historical-%s-42' % dui)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == {
|
|
'amount': 0,
|
|
'created': '2017-03-23',
|
|
'display_id': '42',
|
|
'has_pdf': True,
|
|
'id': 'historical-%s-42' % dui,
|
|
'label': 'PRESTATIONS SEPTEMBRE 2015',
|
|
'online_payment': False,
|
|
'paid': False,
|
|
'pay_limit_date': '',
|
|
'total_amount': '28.98',
|
|
'vendor': {
|
|
'toulouse-axel': {
|
|
'EMISSION': '2017-03-23',
|
|
'IDAXEL': 'AXEL',
|
|
'IDDIRECTION': 'DIR-A',
|
|
'IDFACTURE': 42,
|
|
'IDFAMILLE': dui,
|
|
'IPDF': 'O',
|
|
'LIBDIRECTION': 'DIRECTION A',
|
|
'LIBELLE': 'PRESTATIONS SEPTEMBRE 2015',
|
|
'MONTANT': '28.98',
|
|
'NOFACTURE': 42,
|
|
'NUMDIRECTION': 10,
|
|
}
|
|
},
|
|
}
|
|
|
|
|
|
def test_invoice_pdf_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_facture_a_payer') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-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/toulouse_axel/invoices.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_facture_pdf') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-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_no_result(app, resource):
|
|
resp = app.get('/toulouse-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', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-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_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-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_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.get('/toulouse-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>
|
|
<PDF FILE=''></PDF>
|
|
</PORTAIL>'''
|
|
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_invoice') as invoice:
|
|
invoice.return_value = {'has_pdf': True, 'display_id': '42'}
|
|
with mock_getdata(pdf_content, 'RefFacturePDF'):
|
|
resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-42/pdf?NameID=yyy', status=404)
|
|
assert resp.json['err_desc'] == "PDF error"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
@pytest.mark.parametrize('dui', ['XXX', 'S-XXX'])
|
|
def test_invoice_pdf_endpoint(app, resource, dui):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui=dui, person_id='42')
|
|
pdf_content = '''<PORTAIL>
|
|
<PDF FILE='aGVsbG8gd29ybGQ='></PDF>
|
|
</PORTAIL>'''
|
|
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_invoice') as invoice:
|
|
invoice.return_value = {'has_pdf': True, 'display_id': '42'}
|
|
with mock_getdata(pdf_content, 'RefFacturePDF'):
|
|
app.get('/toulouse-axel/test/regie/MAREGIE/invoice/%s-42/pdf?NameID=yyy' % dui)
|
|
assert invoice.call_args_list[0][1]['historical'] is False
|
|
|
|
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_invoice') as invoice:
|
|
invoice.return_value = {'has_pdf': True, 'display_id': '42'}
|
|
with mock_getdata(pdf_content, 'RefFacturePDF'):
|
|
app.get('/toulouse-axel/test/regie/MAREGIE/invoice/historical-%s-42/pdf?NameID=yyy' % dui)
|
|
assert invoice.call_args_list[0][1]['historical'] is True
|
|
|
|
|
|
def test_pay_invoice_endpoint_axel_error(app, resource):
|
|
payload = {
|
|
'transaction_date': '2020-01-01T12:00:00',
|
|
'transaction_id': 'foo',
|
|
}
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.ref_facture_a_payer') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.post_json(
|
|
'/toulouse-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/toulouse_axel/invoices.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.form_paiement_dui') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.post_json(
|
|
'/toulouse-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'
|
|
|
|
|
|
def test_pay_invoice_endpoint_no_result(app, resource):
|
|
payload = {
|
|
'transaction_date': '2020-01-01T12:00:00',
|
|
'transaction_id': 'foo',
|
|
}
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.post_json(
|
|
'/toulouse-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_getdata(content, 'RefFactureAPayer'):
|
|
resp = app.post_json(
|
|
'/toulouse-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'
|
|
|
|
|
|
@pytest.mark.parametrize('dui', ['XXX', 'S-XXX'])
|
|
def test_pay_invoice_endpoint(app, resource, dui):
|
|
payload = {
|
|
'transaction_date': '2020-01-01T12:00:00',
|
|
'transaction_id': 'foo',
|
|
}
|
|
Link.objects.create(resource=resource, name_id='yyy', dui=dui, person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read().replace('XXX', dui)
|
|
with mock_getdata(content, 'RefFactureAPayer'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.form_paiement_dui') as operation:
|
|
resp = app.post_json(
|
|
'/toulouse-axel/test/regie/MAREGIE/invoice/%s-42/pay?NameID=yyy' % dui, params=payload
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] is True
|
|
assert operation.call_args_list[0][0][1] == {
|
|
'PORTAIL': {
|
|
'DUI': {
|
|
'DATEPAIEMENT': '01/01/2020 13:00:00',
|
|
'IDFACTURE': 42,
|
|
'IDREGIEENCAISSEMENT': '',
|
|
'MONTANTPAYE': decimal.Decimal('4.94'),
|
|
'REFERENCE': 'foo',
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@freezegun.freeze_time('2020-06-30')
|
|
def test_clae_years_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=06-15')
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '15/06', '06'])
|
|
def test_clae_years_endpoint_bad_date_format(app, resource, value):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=%s' % value, status=400)
|
|
assert resp.json['err_desc'] == "bad date format, should be MM-DD"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
|
|
def test_clae_years_endpoint_no_result(app, resource):
|
|
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=06-15')
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'today,pivot,next_year,next_date',
|
|
[
|
|
('2019-08-01', '08-01', True, '2020-08-01'),
|
|
('2019-08-01', '08-02', False, None),
|
|
('2020-07-31', '07-31', True, '2021-07-31'),
|
|
('2020-07-30', '07-31', False, None),
|
|
('2020-06-14', '06-15', False, None),
|
|
('2020-06-15', '06-15', True, '2021-06-15'),
|
|
('2020-06-16', '06-15', True, '2021-06-16'),
|
|
('2020-02-29', '02-01', True, '2021-03-01'),
|
|
],
|
|
)
|
|
def test_clae_years_endpoint(app, resource, today, pivot, next_year, next_date):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with freezegun.freeze_time(today):
|
|
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=%s' % pivot)
|
|
assert resp.json['data'][0] == {'id': '2019', 'text': '2019/2020', 'type': 'encours', 'refdate': today}
|
|
if next_year:
|
|
assert len(resp.json['data']) == 2
|
|
assert resp.json['data'][1] == {
|
|
'id': '2020',
|
|
'text': '2020/2021',
|
|
'type': 'suivante',
|
|
'refdate': next_date,
|
|
}
|
|
else:
|
|
assert len(resp.json['data']) == 1
|
|
|
|
|
|
@freezegun.freeze_time('2020-06-30')
|
|
def test_clae_years_endpoint_noactivities(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_children_activities', return_value={}
|
|
) as mock_activities:
|
|
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=06-15')
|
|
assert mock_activities.call_args_list == [mock.call(dui='XXX', reference_year=2020)]
|
|
assert len(resp.json['data']) == 1
|
|
|
|
|
|
def test_clae_children_activities_info_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get('/toulouse-axel/test/clae_children_activities_info?NameID=yyy&booking_date=2020-01-20')
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
|
|
def test_clae_children_activities_info_endpoint_bad_date_format(app, resource, value):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_children_activities_info?NameID=yyy&booking_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_clae_children_activities_info_endpoint_no_result(app, resource):
|
|
resp = app.get('/toulouse-axel/test/clae_children_activities_info?NameID=yyy&booking_date=2020-01-20')
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
def test_clae_children_activities_info_endpoint(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
resp = app.get('/toulouse-axel/test/clae_children_activities_info?NameID=yyy&booking_date=2020-01-20')
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == [
|
|
{
|
|
'ACTIVITE': [
|
|
{
|
|
'COUTREVIENT': '99999',
|
|
'DATEDEBUT': '2019-08-01',
|
|
'DATEENTREE': '2019-08-01',
|
|
'DATEFIN': '2020-07-31',
|
|
'DATESORTIE': '2020-07-31',
|
|
'IDACTIVITE': 'A19P1M1',
|
|
'ISPAI': False,
|
|
'LIBELLEACTIVITE': 'Temps du matin',
|
|
'TARIF': '0.42',
|
|
'TYPEACTIVITE': 'MAT',
|
|
},
|
|
{
|
|
'COUTREVIENT': '99999',
|
|
'DATEDEBUT': '2019-08-01',
|
|
'DATEENTREE': '2019-08-01',
|
|
'DATEFIN': '2020-07-31',
|
|
'DATESORTIE': '2020-07-31',
|
|
'IDACTIVITE': 'A19P1M2',
|
|
'ISPAI': False,
|
|
'LIBELLEACTIVITE': 'Temps du midi',
|
|
'TARIF': '0.43',
|
|
'TYPEACTIVITE': 'MIDI',
|
|
},
|
|
{
|
|
'COUTREVIENT': '99999',
|
|
'DATEDEBUT': '2019-08-01',
|
|
'DATEENTREE': '2019-08-01',
|
|
'DATEFIN': '2020-07-31',
|
|
'DATESORTIE': '2020-07-31',
|
|
'IDACTIVITE': 'A19P1M3',
|
|
'ISPAI': False,
|
|
'LIBELLEACTIVITE': 'Temps du soir',
|
|
'TARIF': '0.44',
|
|
'TYPEACTIVITE': 'SOIR',
|
|
},
|
|
{
|
|
'COUTREVIENT': '99999',
|
|
'DATEDEBUT': '2019-08-01',
|
|
'DATEENTREE': '2019-08-01',
|
|
'DATEFIN': '2020-07-31',
|
|
'DATESORTIE': '2020-07-31',
|
|
'IDACTIVITE': 'A19P1M4',
|
|
'ISPAI': False,
|
|
'LIBELLEACTIVITE': 'Temps mercredi apr\xe8s midi',
|
|
'TARIF': '0.45',
|
|
'TYPEACTIVITE': 'GARD',
|
|
},
|
|
],
|
|
'DATENAISSANCE': '2019-01-01',
|
|
'IDPERSONNE': '3535',
|
|
'LIBELLEECOLE': 'MATERNELLE 1',
|
|
'NOM': 'foo',
|
|
'PRENOM': 'foo',
|
|
'REGIME': 'SV',
|
|
'REGIME_label': 'Menu sans viande',
|
|
'id': '3535',
|
|
'text': 'foo foo',
|
|
}
|
|
]
|
|
|
|
# again - data are in cache
|
|
resp = app.get('/toulouse-axel/test/clae_children_activities_info?NameID=yyy&booking_date=2020-01-20')
|
|
assert resp.json['err'] == 0
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'activities, expected',
|
|
[
|
|
# all activities except GARD - optional
|
|
(['MAT', 'MIDI', 'SOIR'], True),
|
|
# all activities
|
|
(['MAT', 'MIDI', 'SOIR', 'GARD'], True),
|
|
# duplicated activities
|
|
(['MAT', 'MAT', 'MIDI', 'SOIR', 'GARD'], False),
|
|
(['MAT', 'MIDI', 'MIDI', 'SOIR', 'GARD'], False),
|
|
(['MAT', 'MIDI', 'SOIR', 'SOIR', 'GARD'], False),
|
|
(['MAT', 'MIDI', 'SOIR', 'GARD', 'GARD'], False),
|
|
# missing activity
|
|
(['MIDI', 'SOIR'], False),
|
|
(['MAT', 'SOIR'], False),
|
|
(['MAT', 'MIDI'], False),
|
|
],
|
|
)
|
|
def test_clae_children_activities_info_check(app, resource, activities, expected):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
result = []
|
|
for activity in activities:
|
|
result.append({'IDACTIVITE': 'foo%s' % activity, 'TYPEACTIVITE': activity})
|
|
result = {
|
|
'DATA': {
|
|
'PORTAIL': {
|
|
'DUI': {
|
|
'ENFANT': [
|
|
{
|
|
'IDPERSONNE': '42',
|
|
'NOM': '',
|
|
'PRENOM': '',
|
|
'REGIME': '',
|
|
'LIBELLEECOLE': '',
|
|
'ACTIVITE': result,
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.return_value = OperationResult(json_response=result, xml_request='', xml_response='')
|
|
resp = app.get('/toulouse-axel/test/clae_children_activities_info?NameID=yyy&booking_date=2020-01-20')
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == int(expected)
|
|
|
|
|
|
def test_clae_booking_activities_info_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535&start_date=2020-01-20&end_date=2020-01-24'
|
|
)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_periode') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535&start_date=2020-01-20&end_date=2020-01-24'
|
|
)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
|
|
def test_clae_booking_activities_info_endpoint_bad_date_format(app, resource, value):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535&start_date=%s&end_date=2020-01-24'
|
|
% 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(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535&start_date=2020-01-20&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_clae_booking_activities_info_endpoint_no_result(app, resource, child_activities_data):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535&start_date=2020-01-20&end_date=2020-01-24'
|
|
)
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_periode') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=4242&start_date=2020-01-20&end_date=2020-01-24'
|
|
)
|
|
assert resp.json['err_desc'] == "Child not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
content = """<PORTAIL>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<ENFANT>
|
|
<IDPERSONNE>4242</IDPERSONNE>
|
|
<ACTIVITE>
|
|
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
|
<IDACTIVITE>A19P1M1</IDACTIVITE>
|
|
<JOUR>00000</JOUR>
|
|
</ACTIVITE>
|
|
</ENFANT>
|
|
</DUI>
|
|
</PORTAIL>"""
|
|
activities = child_activities_data['ENFANT'][0]
|
|
with mock_getdata(content, 'ReservationPeriode'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities',
|
|
return_value=activities,
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535&start_date=2020-01-20&end_date=2020-01-24'
|
|
)
|
|
assert resp.json['err_desc'] == "Child not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
def test_clae_booking_activities_info_endpoint(app, resource, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/booking_info.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
activities = copy.deepcopy(child_activities_data['ENFANT'][0])
|
|
with mock_getdata(content, 'ReservationPeriode'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities',
|
|
return_value=activities,
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535&start_date=2020-01-20&end_date=2020-01-24'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == [
|
|
{
|
|
'day': '2020-01-20',
|
|
'activity_id': 'A19P1M1',
|
|
'activity_type': 'MAT',
|
|
'activity_label': 'Temps du matin',
|
|
'booked': False,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-20',
|
|
'activity_id': 'A19P1M2',
|
|
'activity_type': 'MIDI',
|
|
'activity_label': 'Temps du midi',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-20',
|
|
'activity_id': 'A19P1M3',
|
|
'activity_type': 'SOIR',
|
|
'activity_label': 'Temps du soir',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-21',
|
|
'activity_id': 'A19P1M1',
|
|
'activity_type': 'MAT',
|
|
'activity_label': 'Temps du matin',
|
|
'booked': False,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-21',
|
|
'activity_id': 'A19P1M2',
|
|
'activity_type': 'MIDI',
|
|
'activity_label': 'Temps du midi',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-21',
|
|
'activity_id': 'A19P1M3',
|
|
'activity_type': 'SOIR',
|
|
'activity_label': 'Temps du soir',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-22',
|
|
'activity_id': 'A19P1M1',
|
|
'activity_type': 'MAT',
|
|
'activity_label': 'Temps du matin',
|
|
'booked': False,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-22',
|
|
'activity_id': 'A19P1M2',
|
|
'activity_type': 'MIDI',
|
|
'activity_label': 'Temps du midi',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-22',
|
|
'activity_id': 'A19P1M4',
|
|
'activity_type': 'GARD',
|
|
'activity_label': 'Temps mercredi après midi',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-23',
|
|
'activity_id': 'A19P1M1',
|
|
'activity_type': 'MAT',
|
|
'activity_label': 'Temps du matin',
|
|
'booked': False,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-23',
|
|
'activity_id': 'A19P1M2',
|
|
'activity_type': 'MIDI',
|
|
'activity_label': 'Temps du midi',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-23',
|
|
'activity_id': 'A19P1M3',
|
|
'activity_type': 'SOIR',
|
|
'activity_label': 'Temps du soir',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-24',
|
|
'activity_id': 'A19P1M1',
|
|
'activity_type': 'MAT',
|
|
'activity_label': 'Temps du matin',
|
|
'booked': False,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-24',
|
|
'activity_id': 'A19P1M2',
|
|
'activity_type': 'MIDI',
|
|
'activity_label': 'Temps du midi',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-24',
|
|
'activity_id': 'A19P1M3',
|
|
'activity_type': 'SOIR',
|
|
'activity_label': 'Temps du soir',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
]
|
|
|
|
content = """<PORTAIL>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<ENFANT>
|
|
<IDPERSONNE>3535</IDPERSONNE>
|
|
<ACTIVITE>
|
|
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
|
<IDACTIVITE>A19P1M1</IDACTIVITE>
|
|
<JOUR>10201</JOUR>
|
|
</ACTIVITE>
|
|
</ENFANT>
|
|
</DUI>
|
|
</PORTAIL>"""
|
|
cache.clear()
|
|
activities = copy.deepcopy(child_activities_data['ENFANT'][0])
|
|
activities['ACTIVITE'] = activities['ACTIVITE'][:1]
|
|
with mock_getdata(content, 'ReservationPeriode'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities',
|
|
return_value=activities,
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535&start_date=2020-01-20&end_date=2020-01-24'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == [
|
|
{
|
|
'day': '2020-01-20',
|
|
'activity_id': 'A19P1M1',
|
|
'activity_type': 'MAT',
|
|
'activity_label': 'Temps du matin',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-21',
|
|
'activity_id': 'A19P1M1',
|
|
'activity_type': 'MAT',
|
|
'activity_label': 'Temps du matin',
|
|
'booked': False,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-23',
|
|
'activity_id': 'A19P1M1',
|
|
'activity_type': 'MAT',
|
|
'activity_label': 'Temps du matin',
|
|
'booked': False,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
{
|
|
'day': '2020-01-24',
|
|
'activity_id': 'A19P1M1',
|
|
'activity_type': 'MAT',
|
|
'activity_label': 'Temps du matin',
|
|
'booked': True,
|
|
'bookable': False,
|
|
'week': 'week:2020-01-20:2020-01-24',
|
|
},
|
|
]
|
|
|
|
|
|
@freezegun.freeze_time('2020-03-26')
|
|
@pytest.mark.parametrize(
|
|
'start_date, end_date, last_date',
|
|
[
|
|
# end date is a not a friday
|
|
('2020-04-07', '2020-04-13', '2020-04-13'),
|
|
# except if end date is saturday or sunday => ends on previous friday
|
|
('2020-04-07', '2020-04-18', '2020-04-17'),
|
|
('2020-04-07', '2020-04-19', '2020-04-17'),
|
|
# start date is after end date, same week => result is empty
|
|
('2020-04-16', '2020-04-15', None),
|
|
# start date is after end date, not the same week => result is empty
|
|
('2020-04-16', '2020-04-12', None),
|
|
],
|
|
)
|
|
def test_clae_booking_activities_info_period(app, resource, start_date, end_date, last_date):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_booking_data'
|
|
) as activities_info:
|
|
activities_info.return_value = {
|
|
'ACTIVITE': [
|
|
{
|
|
'id': 'TOTO',
|
|
'booking': {
|
|
'days': {
|
|
'monday': True,
|
|
'tuesday': True,
|
|
'wednesday': True,
|
|
'thursday': True,
|
|
'friday': True,
|
|
}
|
|
},
|
|
'TYPEACTIVITE': 'MAT',
|
|
'LIBELLEACTIVITE': 'Matin',
|
|
}
|
|
]
|
|
}
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535'
|
|
'&start_date=%s&end_date=%s' % (start_date, end_date)
|
|
)
|
|
if last_date is None:
|
|
assert resp.json['data'] == []
|
|
else:
|
|
assert resp.json['data'][0]['day'] == start_date
|
|
assert resp.json['data'][-1]['day'] == last_date
|
|
|
|
|
|
@freezegun.freeze_time('2020-04-15')
|
|
def test_clae_booking_activities_info_bookable(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_booking_data'
|
|
) as activities_info:
|
|
activities_info.return_value = {
|
|
'ACTIVITE': [
|
|
{
|
|
'id': 'TOTO',
|
|
'booking': {
|
|
'days': {
|
|
'monday': True,
|
|
'tuesday': True,
|
|
'wednesday': True,
|
|
'thursday': True,
|
|
'friday': True,
|
|
}
|
|
},
|
|
'TYPEACTIVITE': 'MAT',
|
|
'LIBELLEACTIVITE': 'Matin',
|
|
}
|
|
]
|
|
}
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activities_info?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-04-01&end_date=2020-04-30'
|
|
)
|
|
|
|
activities = {a['day']: a['bookable'] for a in resp.json['data']}
|
|
assert activities['2020-04-01'] is False
|
|
assert activities['2020-04-02'] is False
|
|
assert activities['2020-04-03'] is False
|
|
assert activities['2020-04-06'] is False
|
|
assert activities['2020-04-07'] is False
|
|
assert activities['2020-04-08'] is False
|
|
assert activities['2020-04-09'] is False
|
|
assert activities['2020-04-10'] is False
|
|
assert activities['2020-04-13'] is False
|
|
assert activities['2020-04-14'] is False
|
|
assert activities['2020-04-15'] is False
|
|
assert activities['2020-04-16'] is False
|
|
assert activities['2020-04-17'] is False
|
|
assert activities['2020-04-20'] is False
|
|
assert activities['2020-04-21'] is False
|
|
assert activities['2020-04-22'] is False
|
|
assert activities['2020-04-23'] is True
|
|
assert activities['2020-04-24'] is True
|
|
assert activities['2020-04-27'] is True
|
|
assert activities['2020-04-28'] is True
|
|
assert activities['2020-04-29'] is True
|
|
assert activities['2020-04-30'] is True
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_possible_days_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_periode') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
|
|
def test_clae_booking_activity_possible_days_endpoint_bad_date_format(app, resource, value):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=%s&end_date=2020-01-24&activity_type=MAT' % 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(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-02-20&end_date=%s&activity_type=MAT' % value,
|
|
status=400,
|
|
)
|
|
assert resp.json['err_desc'] == "bad date format, should be YYYY-MM-DD"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_possible_days_endpoint_activity_type(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=FOO',
|
|
status=400,
|
|
)
|
|
assert resp.json['err_desc'] == "bad activity_type, should be MAT, MIDI, SOIR or GARD"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_possible_days_endpoint_no_result(app, resource, child_activities_data):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_periode') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=4242'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Child not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
content = """<PORTAIL>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<ENFANT>
|
|
<IDPERSONNE>4242</IDPERSONNE>
|
|
<ACTIVITE>
|
|
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
|
<IDACTIVITE>A19P1M1</IDACTIVITE>
|
|
<JOUR>00000</JOUR>
|
|
</ACTIVITE>
|
|
</ENFANT>
|
|
</DUI>
|
|
</PORTAIL>"""
|
|
activities = child_activities_data['ENFANT'][0]
|
|
with mock_getdata(content, 'ReservationPeriode'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities',
|
|
return_value=activities,
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Child not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_booking_data'
|
|
) as activities_info:
|
|
activities_info.return_value = {'ACTIVITE': []}
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == []
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_possible_days_endpoint(app, resource, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
content = """<PORTAIL>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<ENFANT>
|
|
<IDPERSONNE>3535</IDPERSONNE>
|
|
<ACTIVITE>
|
|
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
|
<IDACTIVITE>A19P1M1</IDACTIVITE>
|
|
<JOUR>00000</JOUR>
|
|
</ACTIVITE>
|
|
<ACTIVITE>
|
|
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
|
<IDACTIVITE>A19P1M2</IDACTIVITE>
|
|
<JOUR>10201</JOUR>
|
|
</ACTIVITE>
|
|
</ENFANT>
|
|
</DUI>
|
|
</PORTAIL>"""
|
|
activities = child_activities_data['ENFANT'][0]
|
|
with mock_getdata(content, 'ReservationPeriode'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities',
|
|
return_value=activities,
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MIDI'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 5
|
|
assert set(resp.json['data'][0].keys()) == {'id', 'text', 'disabled', 'prefill', 'details'}
|
|
assert resp.json['data'][0]['id'] == '3535:MIDI:A19P1M2:2020-01-20'
|
|
assert resp.json['data'][1]['id'] == '3535:MIDI:A19P1M2:2020-01-21'
|
|
assert resp.json['data'][2]['id'] == '3535:MIDI:A19P1M2:2020-01-22'
|
|
assert resp.json['data'][3]['id'] == '3535:MIDI:A19P1M2:2020-01-23'
|
|
assert resp.json['data'][4]['id'] == '3535:MIDI:A19P1M2:2020-01-24'
|
|
assert resp.json['data'][0]['text'] == 'Monday 20 January 2020'
|
|
assert resp.json['data'][1]['text'] == 'Tuesday 21 January 2020'
|
|
assert resp.json['data'][2]['text'] == 'Wednesday 22 January 2020'
|
|
assert resp.json['data'][3]['text'] == 'Thursday 23 January 2020'
|
|
assert resp.json['data'][4]['text'] == 'Friday 24 January 2020'
|
|
assert resp.json['data'][0]['disabled'] is False
|
|
assert resp.json['data'][1]['disabled'] is False
|
|
assert resp.json['data'][2]['disabled'] is True
|
|
assert resp.json['data'][3]['disabled'] is False
|
|
assert resp.json['data'][4]['disabled'] is False
|
|
assert resp.json['data'][0]['prefill'] is True
|
|
assert resp.json['data'][1]['prefill'] is False
|
|
assert resp.json['data'][2]['prefill'] is None
|
|
assert resp.json['data'][3]['prefill'] is False
|
|
assert resp.json['data'][4]['prefill'] is True
|
|
|
|
# again - data are in cache
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 5
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'today, start_date, first_date, end_date, last_date',
|
|
[
|
|
# today is start date -> + 8 days
|
|
('2020-03-26', '2020-03-26', '2020-04-03', '2020-04-17', '2020-04-17'),
|
|
# start date is a friday => starts friday
|
|
('2020-03-26', '2020-04-03', '2020-04-03', '2020-04-17', '2020-04-17'),
|
|
# start date is a saturday => starts on next monday
|
|
('2020-03-26', '2020-04-04', '2020-04-06', '2020-04-17', '2020-04-17'),
|
|
# start date is a sunday => starts on next monday
|
|
('2020-03-26', '2020-04-05', '2020-04-06', '2020-04-17', '2020-04-17'),
|
|
# start date is a monday => starts on monday
|
|
('2020-03-26', '2020-04-06', '2020-04-06', '2020-04-17', '2020-04-17'),
|
|
# start date is a tuesday => starts on tuesday
|
|
('2020-03-26', '2020-04-07', '2020-04-07', '2020-04-17', '2020-04-17'),
|
|
# end date is a not a friday
|
|
('2020-03-26', '2020-04-07', '2020-04-07', '2020-04-13', '2020-04-13'),
|
|
# except if end date is saturday or sunday => ends on previous friday
|
|
('2020-03-26', '2020-04-07', '2020-04-07', '2020-04-18', '2020-04-17'),
|
|
('2020-03-26', '2020-04-07', '2020-04-07', '2020-04-19', '2020-04-17'),
|
|
# start date is after end date, same week => result is empty
|
|
('2020-03-26', '2020-04-16', None, '2020-04-15', None),
|
|
# start date is after end date, not the same week => result is empty
|
|
('2020-03-26', '2020-04-16', None, '2020-04-12', None),
|
|
],
|
|
)
|
|
def test_clae_booking_activity_possible_days_period(
|
|
app, resource, today, start_date, first_date, end_date, last_date, child_activities_data
|
|
):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
activities = child_activities_data['ENFANT'][0]
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_booking_data'
|
|
) as activities_info:
|
|
activities_info.return_value = {
|
|
'ACTIVITE': [
|
|
{
|
|
'id': 'TOTO',
|
|
'TYPEACTIVITE': 'MAT',
|
|
'booking': {
|
|
'days': {
|
|
'monday': True,
|
|
'tuesday': True,
|
|
'wednesday': True,
|
|
'thursday': True,
|
|
'friday': True,
|
|
}
|
|
},
|
|
}
|
|
]
|
|
}
|
|
with freezegun.freeze_time(today):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=%s&end_date=%s&activity_type=MAT' % (start_date, end_date)
|
|
)
|
|
if first_date is None:
|
|
assert resp.json['data'] == []
|
|
else:
|
|
assert resp.json['data'][0]['id'] == '3535:MAT:TOTO:%s' % first_date
|
|
assert resp.json['data'][-1]['id'] == '3535:MAT:TOTO:%s' % last_date
|
|
|
|
|
|
def test_clae_booking_activity_possible_days_next_year(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with freezegun.freeze_time('2020-07-01'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities'
|
|
) as mock_activities:
|
|
mock_activities.return_value = {}
|
|
app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-09-01&end_date=2020-09-30&activity_type=MAT'
|
|
)
|
|
assert mock_activities.call_args_list == [
|
|
mock.call(child_id='3535', dui='XXX', reference_year=2020),
|
|
mock.call(child_id='3535', dui='XXX', reference_year=2020),
|
|
]
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_possible_days_endpoint_dates(app, resource, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
activities = child_activities_data['ENFANT'][0]
|
|
# second activity starts after 2019-08-01
|
|
activities['ACTIVITE'][1]['DATEENTREE'] = '2019-10-01'
|
|
# last activity ends before 2020-07-31
|
|
activities['ACTIVITE'][3]['DATESORTIE'] = '2020-06-30'
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_booking_data'
|
|
) as activities_info:
|
|
activities_info.return_value = {
|
|
'ACTIVITE': [
|
|
{
|
|
'id': 'TOTO',
|
|
'TYPEACTIVITE': 'MAT',
|
|
'booking': {
|
|
'days': {
|
|
'monday': True,
|
|
'tuesday': True,
|
|
'wednesday': True,
|
|
'thursday': True,
|
|
'friday': True,
|
|
}
|
|
},
|
|
}
|
|
]
|
|
}
|
|
# it is not possible to book before 2019-10-01
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities',
|
|
return_value=activities,
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2019-09-01&end_date=2019-10-11&activity_type=MAT'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 9
|
|
assert resp.json['data'][0]['id'] == '3535:MAT:TOTO:2019-10-01'
|
|
assert resp.json['data'][-1]['id'] == '3535:MAT:TOTO:2019-10-11'
|
|
# it is not possible to book after 2020-06-30
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities',
|
|
return_value=activities,
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-06-20&end_date=2020-07-15&activity_type=MAT'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert len(resp.json['data']) == 7
|
|
assert resp.json['data'][0]['id'] == '3535:MAT:TOTO:2020-06-22'
|
|
assert resp.json['data'][-1]['id'] == '3535:MAT:TOTO:2020-06-30'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_annual_possible_days_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=MAT&booking_date=2019-09-01'
|
|
)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
|
|
def test_clae_booking_activity_annual_possible_days_endpoint_bad_date_format(app, resource, value):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=MAT&booking_date=%s' % value,
|
|
status=400,
|
|
)
|
|
assert resp.json['err_desc'] == "bad date format, should be YYYY-MM-DD"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_annual_possible_days_endpoint_activity_type(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=FOO&booking_date=2019-09-01',
|
|
status=400,
|
|
)
|
|
assert resp.json['err_desc'] == "bad activity_type, should be MAT, MIDI, SOIR or GARD"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_annual_possible_days_endpoint_no_result(app, resource):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=MAT&booking_date=2019-09-01'
|
|
)
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=4242'
|
|
'&activity_type=MAT&booking_date=2019-09-01'
|
|
)
|
|
assert resp.json['err_desc'] == "Child not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities',
|
|
return_value={'ACTIVITE': []},
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=MAT&booking_date=2019-09-01'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == []
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_annual_possible_days_endpoint(app, resource, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
activities = child_activities_data['ENFANT'][0]
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=MAT&booking_date=2019-09-01'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == [
|
|
{
|
|
'id': '3535:MAT:A19P1M1:monday',
|
|
'text': 'Monday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:MAT:A19P1M1:tuesday',
|
|
'text': 'Tuesday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:MAT:A19P1M1:wednesday',
|
|
'text': 'Wednesday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:MAT:A19P1M1:thursday',
|
|
'text': 'Thursday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:MAT:A19P1M1:friday',
|
|
'text': 'Friday',
|
|
'disabled': False,
|
|
},
|
|
]
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=MIDI&booking_date=2019-09-01'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == [
|
|
{
|
|
'id': '3535:MIDI:A19P1M2:monday',
|
|
'text': 'Monday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:MIDI:A19P1M2:tuesday',
|
|
'text': 'Tuesday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:MIDI:A19P1M2:wednesday',
|
|
'text': 'Wednesday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:MIDI:A19P1M2:thursday',
|
|
'text': 'Thursday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:MIDI:A19P1M2:friday',
|
|
'text': 'Friday',
|
|
'disabled': False,
|
|
},
|
|
]
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=SOIR&booking_date=2019-09-01'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == [
|
|
{
|
|
'id': '3535:SOIR:A19P1M3:monday',
|
|
'text': 'Monday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:SOIR:A19P1M3:tuesday',
|
|
'text': 'Tuesday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:SOIR:A19P1M3:wednesday',
|
|
'text': 'Wednesday',
|
|
'disabled': True,
|
|
},
|
|
{
|
|
'id': '3535:SOIR:A19P1M3:thursday',
|
|
'text': 'Thursday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:SOIR:A19P1M3:friday',
|
|
'text': 'Friday',
|
|
'disabled': False,
|
|
},
|
|
]
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=GARD&booking_date=2019-09-01'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == [
|
|
{
|
|
'id': '3535:GARD:A19P1M4:monday',
|
|
'text': 'Monday',
|
|
'disabled': True,
|
|
},
|
|
{
|
|
'id': '3535:GARD:A19P1M4:tuesday',
|
|
'text': 'Tuesday',
|
|
'disabled': True,
|
|
},
|
|
{
|
|
'id': '3535:GARD:A19P1M4:wednesday',
|
|
'text': 'Wednesday',
|
|
'disabled': False,
|
|
},
|
|
{
|
|
'id': '3535:GARD:A19P1M4:thursday',
|
|
'text': 'Thursday',
|
|
'disabled': True,
|
|
},
|
|
{
|
|
'id': '3535:GARD:A19P1M4:friday',
|
|
'text': 'Friday',
|
|
'disabled': True,
|
|
},
|
|
]
|
|
|
|
|
|
def test_clae_booking_activity_annual_possible_days_next_year(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with freezegun.freeze_time('2020-07-01'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities'
|
|
) as mock_activities:
|
|
mock_activities.return_value = {}
|
|
app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_annual_possible_days?NameID=yyy&idpersonne=3535'
|
|
'&activity_type=GARD&booking_date=2020-09-01'
|
|
)
|
|
assert mock_activities.call_args_list == [
|
|
mock.call(child_id='3535', dui='XXX', reference_year=2020),
|
|
]
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_prefill_endpoint_axel_error(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_periode') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
|
|
def test_clae_booking_activity_prefill_endpoint_bad_date_format(app, resource, value):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=3535'
|
|
'&start_date=%s&end_date=2020-01-24&activity_type=MAT' % 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(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=%s&activity_type=MAT' % value,
|
|
status=400,
|
|
)
|
|
assert resp.json['err_desc'] == "bad date format, should be YYYY-MM-DD"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_prefill_endpoint_activity_type(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=FOO',
|
|
status=400,
|
|
)
|
|
assert resp.json['err_desc'] == "bad activity_type, should be MAT, MIDI, SOIR or GARD"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_activity_prefill_endpoint_no_result(app, resource, child_activities_data):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_periode') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=4242'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Child not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
content = """<PORTAIL>
|
|
<DUI>
|
|
<IDDUI>XXX</IDDUI>
|
|
<ENFANT>
|
|
<IDPERSONNE>4242</IDPERSONNE>
|
|
<ACTIVITE>
|
|
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
|
<IDACTIVITE>A19P1M1</IDACTIVITE>
|
|
<JOUR>00000</JOUR>
|
|
</ACTIVITE>
|
|
</ENFANT>
|
|
</DUI>
|
|
</PORTAIL>"""
|
|
activities = child_activities_data['ENFANT'][0]
|
|
with mock_getdata(content, 'ReservationPeriode'):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities',
|
|
return_value=activities,
|
|
):
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err_desc'] == "Child not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.clae_booking_activity_possible_days'
|
|
) as possible_days:
|
|
possible_days.return_value = {'data': []}
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == []
|
|
|
|
|
|
def test_clae_booking_activity_prefill_endpoint(app, resource):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.clae_booking_activity_possible_days'
|
|
) as possible_days:
|
|
possible_days.return_value = {
|
|
'data': [
|
|
{
|
|
'id': '3535:MAT:A19P1M1:2020-01-20',
|
|
'prefill': True,
|
|
},
|
|
{
|
|
'id': '3535:MAT:A19P1M1:2020-01-21',
|
|
'prefill': False,
|
|
},
|
|
{
|
|
'id': '3535:MAT:A19P1M1:2020-01-22',
|
|
'prefill': None,
|
|
},
|
|
{
|
|
'id': '3535:MAT:A19P1M1:2020-01-23',
|
|
'prefill': False,
|
|
},
|
|
{
|
|
'id': '3535:MAT:A19P1M1:2020-01-24',
|
|
'prefill': True,
|
|
},
|
|
]
|
|
}
|
|
resp = app.get(
|
|
'/toulouse-axel/test/clae_booking_activity_prefill?NameID=yyy&idpersonne=3535'
|
|
'&start_date=2020-01-20&end_date=2020-01-24&activity_type=MAT'
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['data'] == ['3535:MAT:A19P1M1:2020-01-20', '3535:MAT:A19P1M1:2020-01-24']
|
|
|
|
|
|
def test_are_children_registered_axel_error(resource):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
assert resource.are_children_registered(dui='XXX') == {}
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'date_value, expected',
|
|
[
|
|
('2019-08-01', {'3535': True}),
|
|
('2020-07-31', {'3535': True}),
|
|
],
|
|
)
|
|
def test_are_children_registered_reference_year(resource, date_value, expected):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_children_activities'
|
|
) as get_children_activities:
|
|
get_children_activities.return_value = {'3535': {'ACTIVITE': [{}]}}
|
|
with freezegun.freeze_time(date_value):
|
|
assert resource.are_children_registered(dui='XXX') == expected
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'activities, expected',
|
|
[
|
|
({}, {}),
|
|
({'3535': {'ACTIVITE': []}}, {'3535': False}),
|
|
({'3535': {'ACTIVITE': [{}]}}, {'3535': True}),
|
|
({'3535': {'ACTIVITE': [{}]}, '4242': {}}, {'3535': True, '4242': False}),
|
|
],
|
|
)
|
|
def test_are_children_registered(resource, activities, expected):
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_children_activities'
|
|
) as get_children_activities:
|
|
get_children_activities.return_value = activities
|
|
assert resource.are_children_registered(dui='XXX') == expected
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_endpoint_axel_error(app, resource, booking_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?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/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
def test_clae_booking_endpoint_date_error(app, resource, booking_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
# DATEDEBUT must be before DATEDFIN
|
|
booking_params['booking_start_date'] = '2020-02-01'
|
|
booking_params['booking_end_date'] = '2020-01-01'
|
|
with freezegun.freeze_time('2019-09-01'):
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params, status=400)
|
|
assert resp.json['err_desc'] == "booking_start_date should be before booking_end_date"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
# today + 8j rule
|
|
booking_params['booking_start_date'] = '2020-01-01'
|
|
booking_params['booking_end_date'] = '2020-07-31'
|
|
# date in the past
|
|
with freezegun.freeze_time('2020-01-01'):
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params, status=400)
|
|
assert resp.json['err_desc'] == "booking_start_date min value: 2020-01-09"
|
|
assert resp.json['err'] == 'bad-request'
|
|
# too soon
|
|
with freezegun.freeze_time('2019-12-25'):
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params, status=400)
|
|
assert resp.json['err_desc'] == "booking_start_date min value: 2020-01-02"
|
|
assert resp.json['err'] == 'bad-request'
|
|
with freezegun.freeze_time('2019-12-31'):
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params, status=400)
|
|
assert resp.json['err_desc'] == "booking_start_date min value: 2020-01-08"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
# bad reference year for end_date
|
|
booking_params['booking_start_date'] = '2020-01-01'
|
|
booking_params['booking_end_date'] = '2020-12-31'
|
|
with freezegun.freeze_time('2019-09-01'):
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params, status=400)
|
|
assert resp.json['err_desc'] == "booking_end_date max value: 2020-07-31"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
booking_params['booking_start_date'] = '2021-01-01'
|
|
booking_params['booking_end_date'] = '2021-12-31'
|
|
with freezegun.freeze_time('2019-09-01'):
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params, status=400)
|
|
assert resp.json['err_desc'] == "booking_end_date max value: 2021-07-31"
|
|
assert resp.json['err'] == 'bad-request'
|
|
|
|
|
|
def test_clae_booking_endpoint_no_result(app, resource, booking_params):
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params)
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_endpoint(app, resource, booking_params, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
activities = child_activities_data['ENFANT'][0]
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
content = "<PORTAIL/>"
|
|
with mock_getdata(content, 'ReservationAnnuelle'):
|
|
with mock.patch('django.core.cache.cache.delete') as mock_cache_delete:
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params)
|
|
assert mock_cache_delete.call_args_list == [
|
|
mock.call('toulouse-axel-%s-children-activities-XXX-2019' % resource.pk),
|
|
mock.call('toulouse-axel-%s-booking-data-XXX-3535-2020-04-13' % resource.pk),
|
|
]
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['updated'] is True
|
|
assert 'data' in resp.json
|
|
assert 'xml_request' in resp.json['data']
|
|
assert 'xml_response' in resp.json['data']
|
|
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert payload == {
|
|
'DATEDEMANDE': '2019-09-01',
|
|
'ENFANT': [
|
|
{
|
|
'IDPERSONNE': '3535',
|
|
'REGIME': 'AV',
|
|
'ACTIVITE': [
|
|
{
|
|
'IDACTIVITE': 'A19P1M1',
|
|
'ANNEEREFERENCE': '2019',
|
|
'PERIODE': [
|
|
{
|
|
'DATEDEBUT': '2020-04-13',
|
|
'DATEDFIN': '2020-04-17',
|
|
'SEMAINETYPE': '11011',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
'IDACTIVITE': 'A19P1M2',
|
|
'ANNEEREFERENCE': '2019',
|
|
'PERIODE': [
|
|
{
|
|
'DATEDEBUT': '2020-04-13',
|
|
'DATEDFIN': '2020-04-17',
|
|
'SEMAINETYPE': '11011',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
'IDACTIVITE': 'A19P1M3',
|
|
'ANNEEREFERENCE': '2019',
|
|
'PERIODE': [
|
|
{
|
|
'DATEDEBUT': '2020-04-13',
|
|
'DATEDFIN': '2020-04-17',
|
|
'SEMAINETYPE': '10000',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
'IDACTIVITE': 'A19P1M4',
|
|
'ANNEEREFERENCE': '2019',
|
|
'PERIODE': [
|
|
{
|
|
'DATEDEBUT': '2020-04-13',
|
|
'DATEDFIN': '2020-04-17',
|
|
'SEMAINETYPE': '00100',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
],
|
|
'IDDUI': 'XXX',
|
|
}
|
|
|
|
# empty list
|
|
new_booking_params = copy.deepcopy(booking_params)
|
|
new_booking_params['booking_list_MAT'] = ['42:MAT:A19P1M1:2020-04-15'] # wrong child, ignored
|
|
new_booking_params['booking_list_MIDI'] = []
|
|
new_booking_params['booking_list_SOIR'] = []
|
|
new_booking_params['booking_list_GARD'] = []
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=new_booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert len(payload['ENFANT']) == 1
|
|
assert payload['ENFANT'][0]['IDPERSONNE'] == '3535'
|
|
assert len(payload['ENFANT'][0]['ACTIVITE']) == 4
|
|
activity1 = payload['ENFANT'][0]['ACTIVITE'][0]
|
|
assert activity1['IDACTIVITE'] == 'A19P1M1'
|
|
assert len(activity1['PERIODE']) == 1
|
|
assert activity1['PERIODE'][0]['DATEDEBUT'] == '2020-04-13'
|
|
assert activity1['PERIODE'][0]['DATEDFIN'] == '2020-04-17'
|
|
assert activity1['PERIODE'][0]['SEMAINETYPE'] == '00000'
|
|
activity2 = payload['ENFANT'][0]['ACTIVITE'][1]
|
|
assert activity2['IDACTIVITE'] == 'A19P1M2'
|
|
assert len(activity2['PERIODE']) == 1
|
|
assert activity2['PERIODE'][0]['DATEDEBUT'] == '2020-04-13'
|
|
assert activity2['PERIODE'][0]['DATEDFIN'] == '2020-04-17'
|
|
assert activity2['PERIODE'][0]['SEMAINETYPE'] == '00000'
|
|
activity3 = payload['ENFANT'][0]['ACTIVITE'][2]
|
|
assert activity3['IDACTIVITE'] == 'A19P1M3'
|
|
assert len(activity3['PERIODE']) == 1
|
|
assert activity3['PERIODE'][0]['DATEDEBUT'] == '2020-04-13'
|
|
assert activity3['PERIODE'][0]['DATEDFIN'] == '2020-04-17'
|
|
assert activity3['PERIODE'][0]['SEMAINETYPE'] == '00000'
|
|
activity4 = payload['ENFANT'][0]['ACTIVITE'][3]
|
|
assert activity4['IDACTIVITE'] == 'A19P1M4'
|
|
assert len(activity4['PERIODE']) == 1
|
|
assert activity4['PERIODE'][0]['DATEDEBUT'] == '2020-04-13'
|
|
assert activity4['PERIODE'][0]['DATEDFIN'] == '2020-04-17'
|
|
assert activity4['PERIODE'][0]['SEMAINETYPE'] == '00000'
|
|
|
|
# null list
|
|
new_booking_params = copy.deepcopy(booking_params)
|
|
new_booking_params['booking_list_MAT'] = None
|
|
new_booking_params['booking_list_MIDI'] = None
|
|
new_booking_params['booking_list_SOIR'] = None
|
|
new_booking_params['booking_list_GARD'] = None
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=new_booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert 'ACTIVITE' not in payload['ENFANT'][0]
|
|
|
|
# many weeks => many periods
|
|
new_booking_params = copy.deepcopy(booking_params)
|
|
new_booking_params['booking_start_date'] = '2020-04-01'
|
|
new_booking_params['booking_end_date'] = '2020-04-30'
|
|
new_booking_params['booking_list_MAT'].append('3535:MAT:A19P1M1:2020-04-01')
|
|
new_booking_params['booking_list_MAT'].append(
|
|
'3535:MAT:A19P1M1:2020-03-31'
|
|
) # before the period, ignored
|
|
new_booking_params['booking_list_MAT'].append('3535:MAT:A19P1M1:2020-04-30')
|
|
new_booking_params['booking_list_MAT'].append(
|
|
'3535:MAT:A19P1M1:2020-05-01'
|
|
) # after the period, ignored
|
|
new_booking_params['booking_list_MAT'].append('4242:MAT:A19P1M1:2020-04-15') # wrong child, ignored
|
|
new_booking_params['booking_list_MAT'].append('3535:MAT:FOO:2020-04-15') # wrong activity id, ignored
|
|
new_booking_params['booking_list_MIDI'] = None
|
|
new_booking_params['booking_list_SOIR'] = None
|
|
new_booking_params['booking_list_GARD'] = None
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
with mock.patch('django.core.cache.cache.delete') as mock_cache_delete:
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=new_booking_params)
|
|
assert mock_cache_delete.call_args_list == [
|
|
mock.call('toulouse-axel-%s-children-activities-XXX-2019' % resource.pk),
|
|
mock.call('toulouse-axel-%s-booking-data-XXX-3535-2020-03-30' % resource.pk),
|
|
mock.call('toulouse-axel-%s-booking-data-XXX-3535-2020-04-06' % resource.pk),
|
|
mock.call('toulouse-axel-%s-booking-data-XXX-3535-2020-04-13' % resource.pk),
|
|
mock.call('toulouse-axel-%s-booking-data-XXX-3535-2020-04-20' % resource.pk),
|
|
mock.call('toulouse-axel-%s-booking-data-XXX-3535-2020-04-27' % resource.pk),
|
|
]
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert len(payload['ENFANT']) == 1
|
|
assert payload['ENFANT'][0]['IDPERSONNE'] == '3535'
|
|
assert len(payload['ENFANT'][0]['ACTIVITE']) == 1
|
|
activity = payload['ENFANT'][0]['ACTIVITE'][0]
|
|
assert activity['IDACTIVITE'] == 'A19P1M1'
|
|
assert len(activity['PERIODE']) == 5
|
|
assert activity['PERIODE'][0]['DATEDEBUT'] == '2020-04-01'
|
|
assert activity['PERIODE'][0]['DATEDFIN'] == '2020-04-03'
|
|
assert activity['PERIODE'][0]['SEMAINETYPE'] == '00100'
|
|
assert activity['PERIODE'][1]['DATEDEBUT'] == '2020-04-06'
|
|
assert activity['PERIODE'][1]['DATEDFIN'] == '2020-04-10'
|
|
assert activity['PERIODE'][1]['SEMAINETYPE'] == '00000'
|
|
assert activity['PERIODE'][2]['DATEDEBUT'] == '2020-04-13'
|
|
assert activity['PERIODE'][2]['DATEDFIN'] == '2020-04-17'
|
|
assert activity['PERIODE'][2]['SEMAINETYPE'] == '11011'
|
|
assert activity['PERIODE'][3]['DATEDEBUT'] == '2020-04-20'
|
|
assert activity['PERIODE'][3]['DATEDFIN'] == '2020-04-24'
|
|
assert activity['PERIODE'][3]['SEMAINETYPE'] == '00000'
|
|
assert activity['PERIODE'][4]['DATEDEBUT'] == '2020-04-27'
|
|
assert activity['PERIODE'][4]['DATEDFIN'] == '2020-04-30'
|
|
assert activity['PERIODE'][4]['SEMAINETYPE'] == '00010'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_regime(app, resource, booking_params, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
activities = child_activities_data['ENFANT'][0]
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
booking_params['regime'] = None
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert payload['ENFANT'][0]['REGIME'] == 'SV'
|
|
booking_params['regime'] = ''
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert payload['ENFANT'][0]['REGIME'] == 'SV'
|
|
del booking_params['regime']
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert payload['ENFANT'][0]['REGIME'] == 'SV'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_endpoint_next_year(app, resource, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
activities = child_activities_data['ENFANT'][0]
|
|
for activity in activities['ACTIVITE']:
|
|
activity['DATEDEBUT'] = '2020-08-01'
|
|
activity['DATEENTREE'] = '2020-08-01'
|
|
activity['DATEFIN'] = '2021-07-31'
|
|
activity['DATESORTIE'] = '2021-07-31'
|
|
booking_params = {
|
|
'booking_start_date': '2020-09-01',
|
|
'booking_end_date': '2020-09-04',
|
|
'booking_list_MAT': [],
|
|
'booking_list_MIDI': None,
|
|
'booking_list_SOIR': None,
|
|
'booking_list_GARD': None,
|
|
'child_id': '3535',
|
|
'regime': 'AV',
|
|
}
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities'
|
|
) as mock_activities:
|
|
mock_activities.return_value = activities
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
app.post_json('/toulouse-axel/test/clae_booking?NameID=yyy', params=booking_params)
|
|
assert mock_activities.call_args_list == [
|
|
mock.call(child_id='3535', dui='XXX', reference_year=2020),
|
|
]
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert len(payload['ENFANT']) == 1
|
|
assert payload['ENFANT'][0]['IDPERSONNE'] == '3535'
|
|
assert len(payload['ENFANT'][0]['ACTIVITE']) == 1
|
|
activity = payload['ENFANT'][0]['ACTIVITE'][0]
|
|
assert len(activity['PERIODE']) == 1
|
|
assert activity['PERIODE'][0]['DATEDEBUT'] == '2020-09-01'
|
|
assert activity['PERIODE'][0]['DATEDFIN'] == '2020-09-04'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_annual_endpoint_axel_error(app, resource, annual_booking_params):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.post_json(
|
|
'/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=annual_booking_params
|
|
)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
|
with open(filepath) as xml:
|
|
content = xml.read()
|
|
with mock_getdata(content, 'EnfantsActivites'):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.side_effect = AxelError('FooBar')
|
|
resp = app.post_json(
|
|
'/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=annual_booking_params
|
|
)
|
|
assert resp.json['err_desc'] == "Axel error: FooBar"
|
|
assert resp.json['err'] == 'error'
|
|
|
|
|
|
def test_clae_booking_annual_endpoint_no_result(app, resource, annual_booking_params):
|
|
resp = app.post_json('/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=annual_booking_params)
|
|
assert resp.json['err_desc'] == "Person not found"
|
|
assert resp.json['err'] == 'not-found'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_annual_endpoint(app, resource, annual_booking_params, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
activities = child_activities_data['ENFANT'][0]
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
content = "<PORTAIL/>"
|
|
with mock_getdata(content, 'ReservationAnnuelle'):
|
|
with mock.patch('django.core.cache.cache.delete') as mock_cache_delete:
|
|
resp = app.post_json(
|
|
'/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=annual_booking_params
|
|
)
|
|
assert len(mock_cache_delete.call_args_list) == 48
|
|
assert mock_cache_delete.call_args_list[0] == mock.call(
|
|
'toulouse-axel-%s-children-activities-XXX-2019' % resource.pk
|
|
)
|
|
assert mock_cache_delete.call_args_list[1] == mock.call(
|
|
'toulouse-axel-%s-booking-data-XXX-3535-2019-09-09' % resource.pk
|
|
)
|
|
assert mock_cache_delete.call_args_list[-1] == mock.call(
|
|
'toulouse-axel-%s-booking-data-XXX-3535-2020-07-27' % resource.pk
|
|
)
|
|
assert resp.json['err'] == 0
|
|
assert resp.json['updated'] is True
|
|
assert 'data' in resp.json
|
|
assert 'xml_request' in resp.json['data']
|
|
assert 'xml_response' in resp.json['data']
|
|
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
resp = app.post_json(
|
|
'/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=annual_booking_params
|
|
)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert payload == {
|
|
'DATEDEMANDE': '2019-09-01',
|
|
'ENFANT': [
|
|
{
|
|
'IDPERSONNE': '3535',
|
|
'REGIME': 'AV',
|
|
'ACTIVITE': [
|
|
{
|
|
'ANNEEREFERENCE': '2019',
|
|
'IDACTIVITE': 'A19P1M1',
|
|
'PERIODE': [
|
|
{'DATEDEBUT': '2019-09-09', 'DATEDFIN': '2020-07-31', 'SEMAINETYPE': '11011'}
|
|
],
|
|
},
|
|
{
|
|
'ANNEEREFERENCE': '2019',
|
|
'IDACTIVITE': 'A19P1M2',
|
|
'PERIODE': [
|
|
{'DATEDEBUT': '2019-09-09', 'DATEDFIN': '2020-07-31', 'SEMAINETYPE': '11011'}
|
|
],
|
|
},
|
|
{
|
|
'ANNEEREFERENCE': '2019',
|
|
'IDACTIVITE': 'A19P1M3',
|
|
'PERIODE': [
|
|
{'DATEDEBUT': '2019-09-09', 'DATEDFIN': '2020-07-31', 'SEMAINETYPE': '10000'}
|
|
],
|
|
},
|
|
{
|
|
'ANNEEREFERENCE': '2019',
|
|
'IDACTIVITE': 'A19P1M4',
|
|
'PERIODE': [
|
|
{'DATEDEBUT': '2019-09-09', 'DATEDFIN': '2020-07-31', 'SEMAINETYPE': '00100'}
|
|
],
|
|
},
|
|
],
|
|
}
|
|
],
|
|
'IDDUI': 'XXX',
|
|
}
|
|
|
|
# empty list
|
|
new_booking_params = copy.deepcopy(annual_booking_params)
|
|
new_booking_params['booking_list_MAT'] = ['42:MAT:A19P1M1:monday'] # wrong child, ignored
|
|
new_booking_params['booking_list_MIDI'] = []
|
|
new_booking_params['booking_list_SOIR'] = []
|
|
new_booking_params['booking_list_GARD'] = []
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
resp = app.post_json(
|
|
'/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=new_booking_params
|
|
)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert len(payload['ENFANT']) == 1
|
|
assert payload['ENFANT'][0]['IDPERSONNE'] == '3535'
|
|
assert len(payload['ENFANT'][0]['ACTIVITE']) == 4
|
|
activity1 = payload['ENFANT'][0]['ACTIVITE'][0]
|
|
assert activity1['IDACTIVITE'] == 'A19P1M1'
|
|
assert len(activity1['PERIODE']) == 1
|
|
assert activity1['PERIODE'][0]['DATEDEBUT'] == '2019-09-09'
|
|
assert activity1['PERIODE'][0]['DATEDFIN'] == '2020-07-31'
|
|
assert activity1['PERIODE'][0]['SEMAINETYPE'] == '00000'
|
|
activity2 = payload['ENFANT'][0]['ACTIVITE'][1]
|
|
assert activity2['IDACTIVITE'] == 'A19P1M2'
|
|
assert len(activity2['PERIODE']) == 1
|
|
assert activity2['PERIODE'][0]['DATEDEBUT'] == '2019-09-09'
|
|
assert activity2['PERIODE'][0]['DATEDFIN'] == '2020-07-31'
|
|
assert activity2['PERIODE'][0]['SEMAINETYPE'] == '00000'
|
|
activity3 = payload['ENFANT'][0]['ACTIVITE'][2]
|
|
assert activity3['IDACTIVITE'] == 'A19P1M3'
|
|
assert len(activity3['PERIODE']) == 1
|
|
assert activity3['PERIODE'][0]['DATEDEBUT'] == '2019-09-09'
|
|
assert activity3['PERIODE'][0]['DATEDFIN'] == '2020-07-31'
|
|
assert activity3['PERIODE'][0]['SEMAINETYPE'] == '00000'
|
|
activity4 = payload['ENFANT'][0]['ACTIVITE'][3]
|
|
assert activity4['IDACTIVITE'] == 'A19P1M4'
|
|
assert len(activity4['PERIODE']) == 1
|
|
assert activity4['PERIODE'][0]['DATEDEBUT'] == '2019-09-09'
|
|
assert activity4['PERIODE'][0]['DATEDFIN'] == '2020-07-31'
|
|
assert activity4['PERIODE'][0]['SEMAINETYPE'] == '00000'
|
|
|
|
# null list
|
|
new_booking_params = copy.deepcopy(annual_booking_params)
|
|
new_booking_params['booking_list_MAT'] = None
|
|
new_booking_params['booking_list_MIDI'] = None
|
|
new_booking_params['booking_list_SOIR'] = None
|
|
new_booking_params['booking_list_GARD'] = None
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
resp = app.post_json(
|
|
'/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=new_booking_params
|
|
)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert 'ACTIVITE' not in payload['ENFANT'][0]
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_annual_next_year(app, resource, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
activities = child_activities_data['ENFANT'][0]
|
|
for activity in activities['ACTIVITE']:
|
|
activity['DATEDEBUT'] = '2020-08-01'
|
|
activity['DATEENTREE'] = '2020-08-01'
|
|
activity['DATEFIN'] = '2021-07-31'
|
|
activity['DATESORTIE'] = '2021-07-31'
|
|
annual_booking_params = {
|
|
'booking_list_MAT': [],
|
|
'booking_list_MIDI': None,
|
|
'booking_list_SOIR': None,
|
|
'booking_list_GARD': None,
|
|
'child_id': '3535',
|
|
'regime': 'AV',
|
|
'booking_date': '2020-08-01',
|
|
}
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
app.post_json('/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=annual_booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert payload['ENFANT'][0]['ACTIVITE'][0]['PERIODE'][0]['DATEDEBUT'] == '2020-08-01'
|
|
assert payload['ENFANT'][0]['ACTIVITE'][0]['PERIODE'][0]['DATEDFIN'] == '2021-07-31'
|
|
|
|
|
|
@freezegun.freeze_time('2019-09-01')
|
|
def test_clae_booking_annual_regime(app, resource, annual_booking_params, child_activities_data):
|
|
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
|
activities = child_activities_data['ENFANT'][0]
|
|
with mock.patch(
|
|
'passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities
|
|
):
|
|
annual_booking_params['regime'] = None
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
app.post_json('/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=annual_booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert payload['ENFANT'][0]['REGIME'] == 'SV'
|
|
annual_booking_params['regime'] = ''
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
app.post_json('/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=annual_booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert payload['ENFANT'][0]['REGIME'] == 'SV'
|
|
del annual_booking_params['regime']
|
|
with mock.patch('passerelle.contrib.toulouse_axel.schemas.reservation_annuelle') as operation:
|
|
operation.return_value = OperationResult(json_response={}, xml_request='', xml_response='')
|
|
app.post_json('/toulouse-axel/test/clae_booking_annual?NameID=yyy', params=annual_booking_params)
|
|
payload = operation.call_args_list[0][0][1]['PORTAIL']['DUI']
|
|
assert payload['ENFANT'][0]['REGIME'] == 'SV'
|