253 lines
9.6 KiB
Python
253 lines
9.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import decimal
|
|
import httmock
|
|
import xml.etree.ElementTree as ET
|
|
import requests
|
|
|
|
from zoo.zoo_nanterre import utils
|
|
|
|
from django.utils.http import urlencode
|
|
from django.urls import reverse
|
|
|
|
|
|
def test_utils(db):
|
|
utils.set_saga_sequence(42)
|
|
assert utils.get_next_saga_sequence() == 42
|
|
|
|
|
|
def test_tiers_saga(app, settings, nanterre_classic_family, freezer):
|
|
freezer.move_to('2017-10-20')
|
|
|
|
settings.ZOO_NANTERRE_APPLICATIONS['saga']['url'] = 'http://saga.example.com/ws/'
|
|
settings.ZOO_NANTERRE_APPLICATIONS['saga']['base_uri'] = 'foobar'
|
|
settings.ZOO_NANTERRE_APPLICATIONS['saga']['num_service'] = '69'
|
|
|
|
f = nanterre_classic_family
|
|
|
|
def xml_literal(node, content):
|
|
elt = ET.Element('root')
|
|
elt.attrib['xmlns'] = 'ns'
|
|
sub = ET.SubElement(elt, node)
|
|
sub.text = content
|
|
return ET.tostring(elt)
|
|
|
|
f['jean'].content['cles_de_federation']['technocarte'] = '1234'
|
|
f['jean'].save()
|
|
|
|
f['marie'].content['cles_de_federation']['technocarte'] = '4567'
|
|
f['marie'].save()
|
|
|
|
assert 'saga_tiers' not in f['jean'].content['cles_de_federation']
|
|
|
|
# Définition du début de la séquence des codes tiers
|
|
utils.set_saga_sequence(42)
|
|
|
|
# Calcul du code tiers pour Jean
|
|
response = app.get(reverse('rsu-api-saga-tiers', kwargs={
|
|
'application': 'technocarte',
|
|
'identifier': '1234'
|
|
}))
|
|
assert response.json['code'] == 'RG0000000000042'
|
|
f['jean'].refresh_from_db()
|
|
assert 'saga_tiers' in f['jean'].content['cles_de_federation']
|
|
|
|
response = app.get(reverse('rsu-api-saga-tiers', kwargs={
|
|
'application': 'technocarte',
|
|
'identifier': '1234'
|
|
}))
|
|
assert response.json['code'] == 'RG0000000000042'
|
|
|
|
# Calcul du code tiers pour Marie
|
|
response = app.get(reverse('rsu-api-saga-tiers', kwargs={
|
|
'application': 'technocarte',
|
|
'identifier': '4567'
|
|
}))
|
|
assert response.json['code'] == 'RG0000000000043'
|
|
f['marie'].refresh_from_db()
|
|
assert 'saga_tiers' in f['marie'].content['cles_de_federation']
|
|
|
|
# Mock du web-service SAGA, répond vite celui là
|
|
@httmock.urlmatch()
|
|
def saga_ok(url, request):
|
|
assert url.netloc == 'saga.example.com'
|
|
assert url.path.startswith('/foobar/')
|
|
if '<num_service>' in request.body:
|
|
assert '<num_service>69</num_service>' in request.body
|
|
if 'codeTiersFedere' in request.body:
|
|
return xml_literal('codeTiersFedereReturn',
|
|
'<code_tiers_federe>XYZ</code_tiers_federe>')
|
|
elif 'etatFactureParTiersFedere' in request.body:
|
|
return xml_literal('etatFactureParTiersFedereReturn',
|
|
u'''
|
|
<factures>
|
|
<facture date_facture="10/10/2017" date_limite_recouvrement="20/10/2017"
|
|
etat="en cours" incident_paiement="paiement" montant_initial="10.00"
|
|
reste_a_payer="1.0" num="34">
|
|
<creances>
|
|
<creance imputation="1234" montant="1.2" libelle="PISCINE" num_creance="123"/>
|
|
</creances>
|
|
</facture>
|
|
<facture date_facture="10/10/2017" date_limite_recouvrement="18/10/2017"
|
|
etat="en cours" incident_paiement="paiement" montant_initial="10.00"
|
|
reste_a_payer="1.0" num="34">
|
|
<creances>
|
|
<creance imputation="1234" montant="1.2" libelle="PISCINE" num_creance="123"/>
|
|
</creances>
|
|
</facture>
|
|
<facture date_facture="10/10/2017" date_limite_recouvrement="20/10/2017"
|
|
etat="soldée" incident_paiement="paiement" montant_initial="10.00"
|
|
reste_a_payer="2.0" num="35">
|
|
<creances>
|
|
<creance imputation="1234" montant="3.2" libelle="PISCINE" num_creance="123"/>
|
|
</creances>
|
|
</facture>
|
|
<facture date_facture="10/10/2017" date_limite_recouvrement="20/10/2017"
|
|
etat="transmise" incident_paiement="paiement" montant_initial="10.00"
|
|
reste_a_payer="2.0" num="36">
|
|
<creances>
|
|
<creance imputation="1234" montant="3.2" libelle="PISCINE" num_creance="123"/>
|
|
</creances>
|
|
</facture>
|
|
<facture date_facture="10/10/2017" date_limite_recouvrement="20/10/2017"
|
|
etat="dépassée" incident_paiement="paiement" montant_initial="10.00"
|
|
reste_a_payer="2.0" num="37">
|
|
<creances>
|
|
<creance imputation="1234" montant="3.2" libelle="PISCINE" num_creance="123"/>
|
|
</creances>
|
|
</facture>
|
|
</factures>''')
|
|
elif 'Transaction' in request.body:
|
|
return xml_literal('TransactionReturn',
|
|
'<url>http://tipi.org/</url>')
|
|
elif 'PageRetourAsynchrone' in request.body:
|
|
return xml_literal('PageRetourAsynchroneReturn',
|
|
'''<ok code_tiers="A1" email="johndoe@example.com" etat="paye" num_service="22222">
|
|
<factures>
|
|
<facture montant_initial="16.00" num="00012-A1"/>
|
|
</factures>
|
|
</ok>''')
|
|
elif 'PageRetourSynchrone' in request.body:
|
|
return xml_literal('PageRetourSynchroneReturn',
|
|
'''<ok code_tiers="A1" email="johndoe@example.com" etat="paye" num_service="22222">
|
|
<factures>
|
|
<facture montant_initial="16.00" num="00013-A1"/>
|
|
</factures>
|
|
</ok>''')
|
|
else:
|
|
raise NotImplementedError
|
|
|
|
@httmock.urlmatch()
|
|
def saga_connection_error(url, request):
|
|
raise requests.ConnectionError('no DNS')
|
|
|
|
with httmock.HTTMock(saga_connection_error):
|
|
response = app.get(reverse('rsu-api-saga-factures', kwargs={
|
|
'identifier': f['jean'].id,
|
|
}))
|
|
assert response.json['err'] == 1
|
|
assert len(response.json['errors']) == 1
|
|
assert 'ConnectionError' in response.json['errors'][0]
|
|
|
|
with httmock.HTTMock(saga_ok):
|
|
response = app.get(reverse('rsu-api-saga-factures', kwargs={
|
|
'identifier': f['jean'].id,
|
|
}))
|
|
assert response.json['err'] == 0
|
|
assert len(response.json['data']) == 10
|
|
assert response.json['data'][0]['extra']['redevable']
|
|
num = response.json['data'][0]['num']
|
|
num2 = response.json['data'][1]['num']
|
|
|
|
response = app.get(reverse('rsu-api-saga-factures', kwargs={
|
|
'identifier': f['jean'].id,
|
|
}) + '?' + urlencode({'etats': u'tresorerie'}))
|
|
assert response.json['err'] == 0
|
|
assert len(response.json['data']) == 6
|
|
|
|
response = app.get(reverse('rsu-api-saga-factures', kwargs={
|
|
'identifier': f['jean'].id,
|
|
}) + '?' + urlencode([('etats', u'whatever'), ('etats', u'soldée')]))
|
|
assert response.json['err'] == 0
|
|
assert len(response.json['data']) == 2
|
|
|
|
response = app.post_json(
|
|
reverse('rsu-api-saga-transaction', kwargs={
|
|
'identifier': f['jean'].id,
|
|
}),
|
|
params={
|
|
'num_factures': [num, num2],
|
|
'urlretour_asynchrone': 'http://async.example.com/coin',
|
|
'urlretour_synchrone': 'http://async.example.com/coin',
|
|
'email': 'john.doe@example.com',
|
|
}
|
|
)
|
|
assert response.json['err'] == 0
|
|
assert 'tipi' in response.json['data']['url']
|
|
|
|
response = app.post_json(
|
|
reverse('rsu-api-saga-retour-asynchrone'),
|
|
params={
|
|
'idop': '1234',
|
|
}
|
|
)
|
|
assert response.json['err'] == 0
|
|
data = response.json['data']
|
|
assert data['code_tiers'] == 'A1'
|
|
assert data['email'] == 'johndoe@example.com'
|
|
assert data['num_service'] == '22222'
|
|
assert data['etat'] == 'paye'
|
|
assert data['factures']
|
|
assert len(data['factures']) == 1
|
|
assert data['factures'][0]['num'] == '00012-A1'
|
|
assert decimal.Decimal(data['factures'][0]['montant_initial']) == 16
|
|
|
|
response = app.post_json(
|
|
reverse('rsu-api-saga-retour-synchrone'),
|
|
params={
|
|
'idop': '1234',
|
|
}
|
|
)
|
|
assert response.json['err'] == 0
|
|
data = response.json['data']
|
|
assert data['code_tiers'] == 'A1'
|
|
assert data['email'] == 'johndoe@example.com'
|
|
assert data['num_service'] == '22222'
|
|
assert data['etat'] == 'paye'
|
|
assert data['factures']
|
|
assert len(data['factures']) == 1
|
|
assert data['factures'][0]['num'] == '00013-A1'
|
|
assert decimal.Decimal(data['factures'][0]['montant_initial']) == 16
|
|
|
|
@httmock.urlmatch()
|
|
def saga_retour_erreur(url, request):
|
|
assert url.netloc == 'saga.example.com'
|
|
assert url.path.startswith('/foobar/')
|
|
if 'PageRetourAsynchrone' in request.body:
|
|
return xml_literal('PageRetourAsynchroneReturn',
|
|
u'<erreur>Ça va pas du tout</erreur>')
|
|
elif 'PageRetourSynchrone' in request.body:
|
|
return xml_literal('PageRetourSynchroneReturn',
|
|
u'<erreur>Ça va pas du tout</erreur>')
|
|
else:
|
|
raise NotImplementedError
|
|
|
|
with httmock.HTTMock(saga_retour_erreur):
|
|
response = app.post_json(
|
|
reverse('rsu-api-saga-retour-synchrone'),
|
|
params={
|
|
'idop': '1234',
|
|
}
|
|
)
|
|
assert response.json['err'] == 1
|
|
assert response.json['errors'] == [u'SAGA erreur: Ça va pas du tout']
|
|
|
|
response = app.post_json(
|
|
reverse('rsu-api-saga-retour-asynchrone'),
|
|
params={
|
|
'idop': '1234',
|
|
}
|
|
)
|
|
assert response.json['err'] == 1
|
|
assert response.json['errors'] == [u'SAGA erreur: Ça va pas du tout']
|