0001-caluire-axel-child_schooling_info-enpoint-53853.patch
functests/caluire_axel/test_caluire_axel.py | ||
---|---|---|
1 |
import datetime |
|
1 | 2 |
import pprint |
2 | 3 | |
3 | 4 |
import requests |
... | ... | |
48 | 49 |
assert res['err'] == 0 |
49 | 50 |
print('\n') |
50 | 51 | |
52 |
print("and GET school info") |
|
53 |
url = conn + '/child_schooling_info?NameID=%s&idpersonne=%s&booking_date=%s' % ( |
|
54 |
name_id, |
|
55 |
child['IDENT'], |
|
56 |
datetime.date.today().strftime('%Y-%m-%d'), |
|
57 |
) |
|
58 |
resp = requests.get(url) |
|
59 |
resp.raise_for_status() |
|
60 |
res = resp.json() |
|
61 |
pprint.pprint(res) |
|
62 |
assert res['err'] == 0 |
|
63 |
print('\n') |
|
64 | ||
51 | 65 |
print("Deleting link") |
52 | 66 |
url = conn + '/unlink?NameID=%s' % name_id |
53 | 67 |
resp = requests.post(url) |
passerelle/contrib/caluire_axel/models.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
import datetime |
|
18 | ||
17 | 19 |
from django.db import models |
18 | 20 |
from django.utils.translation import ugettext_lazy as _ |
19 | 21 | |
... | ... | |
22 | 24 |
from passerelle.utils.api import endpoint |
23 | 25 |
from passerelle.utils.jsonresponse import APIError |
24 | 26 | |
25 |
from . import schemas |
|
27 |
from . import schemas, utils
|
|
26 | 28 | |
27 | 29 | |
28 | 30 |
class CaluireAxel(BaseResource): |
... | ... | |
32 | 34 |
) |
33 | 35 | |
34 | 36 |
category = _('Business Process Connectors') |
35 |
_category_ordering = [_('Family account')] |
|
37 |
_category_ordering = [_('Family account'), _('Schooling')]
|
|
36 | 38 | |
37 | 39 |
class Meta: |
38 | 40 |
verbose_name = _('Caluire Axel') |
... | ... | |
150 | 152 | |
151 | 153 |
return family_data |
152 | 154 | |
155 |
def get_child_data(self, family_id, child_id): |
|
156 |
family_data = self.get_family_data(family_id) |
|
157 |
for child in family_data.get('MEMBRE', []): |
|
158 |
if child['IDENT'] == child_id: |
|
159 |
return child |
|
160 |
return None |
|
161 | ||
153 | 162 |
@endpoint( |
154 | 163 |
display_category=_('Family account'), |
155 | 164 |
display_order=3, |
... | ... | |
188 | 197 |
'idpersonne': {'description': _('Child ID')}, |
189 | 198 |
}, |
190 | 199 |
) |
191 |
def child_info(self, request, idpersonne, NameID):
|
|
200 |
def child_info(self, request, NameID, idpersonne):
|
|
192 | 201 |
link = self.get_link(NameID) |
193 |
family_data = self.get_family_data(link.family_id) |
|
202 |
child_data = self.get_child_data(link.family_id, idpersonne) |
|
203 |
if child_data is None: |
|
204 |
raise APIError('Child not found', err_code='not-found') |
|
205 |
return {'data': child_data} |
|
194 | 206 | |
195 |
for child in family_data.get('MEMBRE', []): |
|
196 |
if child['IDENT'] == idpersonne: |
|
197 |
return {'data': child} |
|
207 |
@endpoint( |
|
208 |
display_category=_('Schooling'), |
|
209 |
display_order=1, |
|
210 |
description=_("Get information about schooling of a child"), |
|
211 |
perm='can_access', |
|
212 |
parameters={ |
|
213 |
'NameID': {'description': _('Publik ID')}, |
|
214 |
'idpersonne': {'description': _('Child ID')}, |
|
215 |
'booking_date': {'description': _('Booking date (to get reference year)')}, |
|
216 |
}, |
|
217 |
) |
|
218 |
def child_schooling_info(self, request, NameID, idpersonne, booking_date): |
|
219 |
link = self.get_link(NameID) |
|
220 |
try: |
|
221 |
booking_date = datetime.datetime.strptime(booking_date, axel.json_date_format) |
|
222 |
except ValueError: |
|
223 |
raise APIError('bad date format, should be YYYY-MM-DD', err_code='bad-request', http_status=400) |
|
224 | ||
225 |
child_data = self.get_child_data(link.family_id, idpersonne) |
|
226 |
if child_data is None: |
|
227 |
raise APIError('Child not found', err_code='not-found') |
|
228 | ||
229 |
reference_year = utils.get_reference_year_from_date(booking_date) |
|
230 |
try: |
|
231 |
result = schemas.get_individu( |
|
232 |
self, |
|
233 |
{'PORTAIL': {'GETINDIVIDU': {'IDENTINDIVIDU': idpersonne, 'ANNEE': str(reference_year)}}}, |
|
234 |
) |
|
235 |
except axel.AxelError as e: |
|
236 |
raise APIError( |
|
237 |
'Axel error: %s' % e, |
|
238 |
err_code='error', |
|
239 |
data={'xml_request': e.xml_request, 'xml_response': e.xml_response}, |
|
240 |
) |
|
241 | ||
242 |
schooling_data = result.json_response['DATA']['PORTAIL']['GETINDIVIDU'] |
|
198 | 243 | |
199 |
raise APIError('Child not found', err_code='not-found')
|
|
244 |
return {'data': schooling_data}
|
|
200 | 245 | |
201 | 246 | |
202 | 247 |
class Link(models.Model): |
passerelle/contrib/caluire_axel/schemas.py | ||
---|---|---|
74 | 74 | |
75 | 75 |
find_individus = Operation('FindIndividus') |
76 | 76 |
get_famille_individus = Operation('GetFamilleIndividus') |
77 |
get_individu = Operation('GetIndividu') |
|
77 | 78 | |
78 | 79 | |
79 | 80 |
LINK_SCHEMA = copy.deepcopy( |
passerelle/contrib/caluire_axel/utils.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
# passerelle - uniform access to multiple data sources and services |
|
3 |
# Copyright (C) 2021 Entr'ouvert |
|
4 |
# |
|
5 |
# This program is free software: you can redistribute it and/or modify it |
|
6 |
# under the terms of the GNU Affero General Public License as published |
|
7 |
# by the Free Software Foundation, either version 3 of the License, or |
|
8 |
# (at your option) any later version. |
|
9 |
# |
|
10 |
# This program is distributed in the hope that it will be useful, |
|
11 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 |
# GNU Affero General Public License for more details. |
|
14 |
# |
|
15 |
# You should have received a copy of the GNU Affero General Public License |
|
16 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 | ||
18 | ||
19 |
def get_reference_year_from_date(booking_date): |
|
20 |
if booking_date.month <= 8: |
|
21 |
# between january and august, reference year is the year just before |
|
22 |
return booking_date.year - 1 |
|
23 |
return booking_date.year |
passerelle/contrib/caluire_axel/xsd/Q_GetIndividu.xsd | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8" ?> |
|
2 |
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:all="urn:AllAxelTypes"> |
|
3 |
|
|
4 |
<xsd:import schemaLocation="./AllAxelTypes.xsd" namespace="urn:AllAxelTypes" /> |
|
5 |
|
|
6 |
<xsd:complexType name="PORTAILType"> |
|
7 |
<xsd:sequence> |
|
8 |
<xsd:element ref="GETINDIVIDU" minOccurs="0" maxOccurs="1"/> |
|
9 |
</xsd:sequence> |
|
10 |
</xsd:complexType> |
|
11 |
|
|
12 |
<xsd:complexType name="GETINDIVIDUType"> |
|
13 |
<xsd:sequence> |
|
14 |
<xsd:element ref="IDENTINDIVIDU" /> |
|
15 |
<xsd:element ref="ANNEE" /> |
|
16 |
</xsd:sequence> |
|
17 |
</xsd:complexType> |
|
18 |
|
|
19 |
<xsd:element name="IDENTINDIVIDU" type="all:IDENTREQUIREDType"/> |
|
20 |
<xsd:element name="ANNEE" type="all:ANNEEType"/> |
|
21 |
|
|
22 |
<xsd:element name="GETINDIVIDU" type="GETINDIVIDUType"/> |
|
23 |
|
|
24 |
<xsd:element name="PORTAIL" type="PORTAILType"/> |
|
25 |
|
|
26 |
</xsd:schema> |
passerelle/contrib/caluire_axel/xsd/R_GetIndividu.xsd | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8" ?> |
|
2 |
<xsd:schema xmlns:all="urn:AllAxelTypes" xmlns:ind="urn:Individu" xmlns:xsd="http://www.w3.org/2001/XMLSchema" > |
|
3 |
|
|
4 |
<xsd:import schemaLocation="./Individu.xsd" namespace="urn:Individu" /> |
|
5 |
<xsd:import schemaLocation="./AllAxelTypes.xsd" namespace="urn:AllAxelTypes" /> |
|
6 |
|
|
7 |
<xsd:redefine schemaLocation="./R_ShemaResultat.xsd"> |
|
8 |
<xsd:simpleType name="TYPEType"> |
|
9 |
<xsd:restriction base="TYPEType"> |
|
10 |
<xsd:enumeration value="GetIndividu" /> |
|
11 |
</xsd:restriction> |
|
12 |
</xsd:simpleType> |
|
13 |
|
|
14 |
<xsd:complexType name="PORTAILType"> |
|
15 |
<xsd:complexContent> |
|
16 |
<xsd:extension base="PORTAILType"> |
|
17 |
<xsd:sequence> |
|
18 |
<xsd:element ref="GETINDIVIDU" minOccurs="0" maxOccurs="1"/> |
|
19 |
</xsd:sequence> |
|
20 |
</xsd:extension> |
|
21 |
</xsd:complexContent> |
|
22 |
</xsd:complexType> |
|
23 |
</xsd:redefine> |
|
24 |
|
|
25 |
<xsd:complexType name="SCOLAIREType"> |
|
26 |
<xsd:sequence> |
|
27 |
<xsd:element ref="IDENTECOLE" /> |
|
28 |
<xsd:element ref="LIBELLEECOLE"/> |
|
29 |
<xsd:element ref="IDENTNIVEAU"/> |
|
30 |
<xsd:element ref="LIBELLENIVEAU"/> |
|
31 |
</xsd:sequence> |
|
32 |
</xsd:complexType> |
|
33 |
|
|
34 |
<xsd:simpleType name="PLACEType"> |
|
35 |
<xsd:restriction base="xsd:string"> |
|
36 |
<xsd:enumeration value="" /> |
|
37 |
<xsd:enumeration value="1" /> |
|
38 |
<xsd:enumeration value="2" /> |
|
39 |
<xsd:enumeration value="3" /> |
|
40 |
</xsd:restriction> |
|
41 |
</xsd:simpleType> |
|
42 |
|
|
43 |
<xsd:complexType name="GETINDIVIDUType"> |
|
44 |
<xsd:sequence> |
|
45 |
<xsd:element ref="CODE" /> |
|
46 |
<xsd:element ref="SCOLAIRE" minOccurs="0" maxOccurs="1" /> |
|
47 |
<xsd:element ref="INDIVIDU" minOccurs="0" maxOccurs="1" /> |
|
48 |
</xsd:sequence> |
|
49 |
</xsd:complexType> |
|
50 |
|
|
51 |
<xsd:element name="CODE" type="xsd:integer"/> |
|
52 |
<xsd:element name="INDIVIDU" type="ind:INDIVIDUType"/> |
|
53 |
<xsd:element name="IDENTFAMILLE" type="all:IDENTType"/> |
|
54 |
<xsd:element name="SCOLAIRE" type="SCOLAIREType"/> |
|
55 |
<xsd:element name="PLACE" type="PLACEType"/> |
|
56 |
<xsd:element name="IDENTECOLE" type="all:IDType"/> |
|
57 |
<xsd:element name="IDENTNIVEAU" type="all:IDType"/> |
|
58 |
<xsd:element name="LIBELLEECOLE" type="all:LIBELLEType"/> |
|
59 |
<xsd:element name="LIBELLENIVEAU" type="all:LIBELLEType"/> |
|
60 |
|
|
61 |
<xsd:element name="GETINDIVIDU" type="GETINDIVIDUType"/> |
|
62 |
|
|
63 |
</xsd:schema> |
tests/data/caluire_axel/schooling_info.xml | ||
---|---|---|
1 |
<PORTAIL> |
|
2 |
<GETINDIVIDU> |
|
3 |
<CODE>0</CODE> |
|
4 |
<SCOLAIRE> |
|
5 |
<IDENTECOLE>ECOLE1</IDENTECOLE> |
|
6 |
<LIBELLEECOLE>Ecole Elémentaire</LIBELLEECOLE> |
|
7 |
<IDENTNIVEAU>CE2</IDENTNIVEAU> |
|
8 |
<LIBELLENIVEAU>Cours élémentaire 2ème année</LIBELLENIVEAU> |
|
9 |
</SCOLAIRE> |
|
10 |
<INDIVIDU> |
|
11 |
<IDENT>50632</IDENT> |
|
12 |
<CIVILITE /> |
|
13 |
<NOM>CALUIRE TEST</NOM> |
|
14 |
<PRENOM>Enfant 1 </PRENOM> |
|
15 |
<NAISSANCE>10/10/2013</NAISSANCE> |
|
16 |
<SEXE>M</SEXE> |
|
17 |
<NOMJF /> |
|
18 |
<TELFIXE /> |
|
19 |
<TELPORTABLE /> |
|
20 |
<MAIL /> |
|
21 |
<PAI>N</PAI> |
|
22 |
<GARDEALTERNEE>O</GARDEALTERNEE> |
|
23 |
<ADRESSE> |
|
24 |
<ADRESSE3 /> |
|
25 |
<ADRESSE4 /> |
|
26 |
<NORUE>30</NORUE> |
|
27 |
<ADRESSE1>RUE PASTEUR</ADRESSE1> |
|
28 |
<ADRESSE2 /> |
|
29 |
<CODEPOSTAL>69300</CODEPOSTAL> |
|
30 |
<VILLE>CALUIRE ET CUIRE</VILLE> |
|
31 |
<PAYS /> |
|
32 |
<NPAI /> |
|
33 |
</ADRESSE> |
|
34 |
</INDIVIDU> |
|
35 |
</GETINDIVIDU> |
|
36 |
</PORTAIL> |
tests/test_caluire_axel.py | ||
---|---|---|
16 | 16 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | |
18 | 18 |
import os |
19 |
import xml.etree.ElementTree as ET |
|
19 | 20 |
from contextlib import contextmanager |
20 | 21 | |
21 | 22 |
import mock |
... | ... | |
45 | 46 |
} |
46 | 47 | |
47 | 48 | |
49 |
@pytest.fixture |
|
50 |
def family_data(): |
|
51 |
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml') |
|
52 |
with open(filepath) as xml: |
|
53 |
content = xml.read() |
|
54 |
resp = ( |
|
55 |
''' |
|
56 |
<?xml version="1.0"?> |
|
57 |
<PORTAILSERVICE> |
|
58 |
<RESULTAT> |
|
59 |
<TYPE>GetFamilleIndividus</TYPE> |
|
60 |
<STATUS>OK</STATUS> |
|
61 |
<DATE>10/10/2010 10:10:01</DATE> |
|
62 |
<COMMENTAIRES><![CDATA[]]></COMMENTAIRES> |
|
63 |
</RESULTAT> |
|
64 |
<DATA> |
|
65 |
%s |
|
66 |
</DATA> |
|
67 |
</PORTAILSERVICE> |
|
68 |
'''.strip() |
|
69 |
% content |
|
70 |
) |
|
71 |
return schemas.get_famille_individus.response_converter.decode(ET.fromstring(resp))['DATA']['PORTAIL'][ |
|
72 |
'GETFAMILLE' |
|
73 |
] |
|
74 | ||
75 | ||
48 | 76 |
@contextmanager |
49 | 77 |
def mock_getdata(content, operation): |
50 | 78 |
with mock.patch('passerelle.contrib.caluire_axel.models.CaluireAxel.soap_client') as client: |
... | ... | |
131 | 159 |
) |
132 | 160 | |
133 | 161 | |
162 |
@pytest.mark.parametrize( |
|
163 |
'content', |
|
164 |
[ |
|
165 |
'<PORTAIL><GETFAMILLE/></PORTAIL>', |
|
166 |
], |
|
167 |
) |
|
168 |
def test_operation_get_famille_individus(resource, content): |
|
169 |
with mock_getdata(content, 'GetFamilleIndividus'): |
|
170 |
with pytest.raises(AxelError): |
|
171 |
schemas.get_famille_individus( |
|
172 |
resource, |
|
173 |
{ |
|
174 |
'PORTAIL': { |
|
175 |
'GETFAMILLE': { |
|
176 |
'IDENTFAMILLE': 'XXX', |
|
177 |
} |
|
178 |
} |
|
179 |
}, |
|
180 |
) |
|
181 | ||
182 | ||
183 |
@pytest.mark.parametrize( |
|
184 |
'content', |
|
185 |
[ |
|
186 |
'<PORTAIL><GETINDIVIDU/></PORTAIL>', |
|
187 |
], |
|
188 |
) |
|
189 |
def test_operation_get_individu(resource, content): |
|
190 |
with mock_getdata(content, 'GetIndividu'): |
|
191 |
with pytest.raises(AxelError): |
|
192 |
schemas.get_individu( |
|
193 |
resource, |
|
194 |
{ |
|
195 |
'PORTAIL': { |
|
196 |
'GETINDIVIDU': { |
|
197 |
'IDENTINDIVIDU': 'XXX', |
|
198 |
} |
|
199 |
} |
|
200 |
}, |
|
201 |
) |
|
202 | ||
203 | ||
134 | 204 |
def test_link_endpoint_nameid_empty(app, resource, link_params): |
135 | 205 |
resp = app.post_json('/caluire-axel/test/link?NameID=', params=link_params, status=400) |
136 | 206 |
assert resp.json['err_desc'] == "NameID is empty" |
... | ... | |
440 | 510 |
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42') |
441 | 511 |
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation: |
442 | 512 |
operation.side_effect = AxelError('FooBar') |
443 |
resp = app.get('/caluire-axel/test/child_info?NameID=yyy&idpersonne=zzz')
|
|
513 |
resp = app.get('/caluire-axel/test/child_info?NameID=yyy&idpersonne=50632')
|
|
444 | 514 |
assert resp.json['err_desc'] == "Axel error: FooBar" |
445 | 515 |
assert resp.json['err'] == 'error' |
446 | 516 | |
447 | 517 | |
448 | 518 |
def test_child_info_endpoint_no_result(app, resource): |
449 |
resp = app.get('/caluire-axel/test/child_info?NameID=yyy&idpersonne=zzz')
|
|
519 |
resp = app.get('/caluire-axel/test/child_info?NameID=yyy&idpersonne=50632')
|
|
450 | 520 |
assert resp.json['err_desc'] == "Person not found" |
451 | 521 |
assert resp.json['err'] == 'not-found' |
452 | 522 | |
... | ... | |
490 | 560 |
) |
491 | 561 |
assert resp.json['data']['id'] == '50632' |
492 | 562 |
assert resp.json['data']['text'] == 'Enfant 1 CALUIRE TEST' |
563 | ||
564 | ||
565 |
def test_child_schooling_info_endpoint_axel_error(app, resource): |
|
566 |
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42') |
|
567 |
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_famille_individus') as operation: |
|
568 |
operation.side_effect = AxelError('FooBar') |
|
569 |
resp = app.get( |
|
570 |
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&booking_date=2021-05-10' |
|
571 |
) |
|
572 |
assert resp.json['err_desc'] == "Axel error: FooBar" |
|
573 |
assert resp.json['err'] == 'error' |
|
574 | ||
575 |
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml') |
|
576 |
with open(filepath) as xml: |
|
577 |
content = xml.read() |
|
578 |
with mock_getdata(content, 'GetFamilleIndividus'): |
|
579 |
with mock.patch('passerelle.contrib.caluire_axel.schemas.get_individu') as operation: |
|
580 |
operation.side_effect = AxelError('FooBar') |
|
581 |
resp = app.get( |
|
582 |
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&booking_date=2021-05-10' |
|
583 |
) |
|
584 |
assert resp.json['err_desc'] == "Axel error: FooBar" |
|
585 |
assert resp.json['err'] == 'error' |
|
586 | ||
587 | ||
588 |
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020']) |
|
589 |
def test_child_schooling_info_endpoint_bad_date_format(app, resource, value): |
|
590 |
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42') |
|
591 |
resp = app.get( |
|
592 |
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&booking_date=%s' % value, |
|
593 |
status=400, |
|
594 |
) |
|
595 |
assert resp.json['err_desc'] == "bad date format, should be YYYY-MM-DD" |
|
596 |
assert resp.json['err'] == 'bad-request' |
|
597 | ||
598 | ||
599 |
def test_child_schooling_info_endpoint_no_result(app, resource): |
|
600 |
resp = app.get( |
|
601 |
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&booking_date=2021-05-10' |
|
602 |
) |
|
603 |
assert resp.json['err_desc'] == "Person not found" |
|
604 |
assert resp.json['err'] == 'not-found' |
|
605 | ||
606 |
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42') |
|
607 |
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/family_info.xml') |
|
608 |
with open(filepath) as xml: |
|
609 |
content = xml.read() |
|
610 |
with mock_getdata(content, 'GetFamilleIndividus'): |
|
611 |
resp = app.get( |
|
612 |
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=zzz&booking_date=2021-05-10' |
|
613 |
) |
|
614 |
assert resp.json['err_desc'] == "Child not found" |
|
615 |
assert resp.json['err'] == 'not-found' |
|
616 | ||
617 | ||
618 |
def test_child_schooling_info(app, resource, family_data): |
|
619 |
Link.objects.create(resource=resource, name_id='yyy', family_id='XXX', person_id='42') |
|
620 |
filepath = os.path.join(os.path.dirname(__file__), 'data/caluire_axel/schooling_info.xml') |
|
621 |
with open(filepath) as xml: |
|
622 |
content = xml.read() |
|
623 |
with mock_getdata(content, 'GetIndividu'): |
|
624 |
with mock.patch( |
|
625 |
'passerelle.contrib.caluire_axel.models.CaluireAxel.get_family_data', |
|
626 |
return_value=family_data, |
|
627 |
): |
|
628 |
resp = app.get( |
|
629 |
'/caluire-axel/test/child_schooling_info?NameID=yyy&idpersonne=50632&booking_date=2021-05-10' |
|
630 |
) |
|
631 |
assert resp.json['err'] == 0 |
|
632 |
assert set(resp.json['data'].keys()) == set(['CODE', 'INDIVIDU', 'SCOLAIRE']) |
tests/test_caluire_axel_utils.py | ||
---|---|---|
1 |
# passerelle - uniform access to multiple data sources and services |
|
2 |
# Copyright (C) 2021 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
import datetime |
|
18 | ||
19 |
import pytest |
|
20 | ||
21 |
from passerelle.contrib.caluire_axel.utils import get_reference_year_from_date |
|
22 |
from passerelle.contrib.utils.axel import json_date_format |
|
23 | ||
24 | ||
25 |
@pytest.mark.parametrize( |
|
26 |
'value, expected', |
|
27 |
[ |
|
28 |
('2021-01-01', 2020), |
|
29 |
('2021-08-31', 2020), |
|
30 |
('2021-09-01', 2021), |
|
31 |
('2021-12-31', 2021), |
|
32 |
], |
|
33 |
) |
|
34 |
def test_get_reference_year_from_date(value, expected): |
|
35 |
in_date = datetime.datetime.strptime(value, json_date_format) |
|
36 |
assert get_reference_year_from_date(in_date) == expected |
|
0 |
- |