import base64 import os import xml.etree.ElementTree as ET from unittest import mock import pytest from django.utils.encoding import force_str from zeep.exceptions import Fault as WebFault from zeep.exceptions import TransportError from passerelle.contrib.dpark.models import DPark, Pairing from passerelle.utils.conversion import to_pdf from passerelle.utils.jsonresponse import APIError from tests.utils import ResponsesSoap, make_resource SLUG = 'test' WSDL_URL = 'https://example.net/dpark?wsdl' SERVICE_URL = 'https://example.net/dpark' with open(os.path.join(os.path.dirname(__file__), 'data/dpark.awws.wsdl')) as f: WSDL_CONTENT = f.read() with open(os.path.join(os.path.dirname(__file__), 'data/small.jpg'), 'rb') as f: JPEG_CONTENT = f.read() def make_response(name, items): base = ''' ''' root = ET.fromstring(base) body = root.find('{http://schemas.xmlsoap.org/soap/envelope/}Body') response_tag_name = '{urn:Webservice_Residants}PLS_%sResponse' % name result_tag_name = 'PLS_%sResult' % name response = ET.SubElement(body, response_tag_name) result = ET.SubElement(response, result_tag_name) for key, value in items: elt = ET.SubElement(result, key) if value: elt.text = value return ET.tostring(root) @pytest.fixture def dpark(db): resource = make_resource( DPark, **{ 'slug': SLUG, 'wsdl_url': WSDL_URL, 'operation_url': SERVICE_URL, }, ) return resource @pytest.fixture def soap_mock(dpark): responses_soap = ResponsesSoap(WSDL_URL, WSDL_CONTENT, address=SERVICE_URL) with responses_soap() as soap_mock: yield soap_mock class ReplyDataClass(dict): def __init__(self, **kwargs): self.__dict__.update(kwargs) super().__init__(**kwargs) class WebFaultHavingLatin1(WebFault): pass class MockedService: def __init__(self, success=True, error_class=None, replydata=None): self.success = success self.error_class = error_class self.replydata = replydata def raise_error(self): if self.error_class is WebFault: raise self.error_class(mock.Mock(faulstring='Error %s raised' % self.error_class.__name__), None) if self.error_class is TransportError: raise self.error_class('connection error occured', None) if self.error_class is WebFaultHavingLatin1: raise WebFault(message='éêè') raise Exception('random error') def return_response(self, *args, **kwargs): return ReplyDataClass(**self.replydata) def __getattr__(self, name): if self.error_class: self.raise_error() return self.return_response @pytest.fixture def get_service(): with mock.patch('passerelle.contrib.dpark.models.get_service') as get_service: yield get_service def test_call_service_error(dpark, app, get_service): get_service.return_value = MockedService(error_class=WebFault) resp = app.get('/dpark/test/ping/') assert 'ServiceError: ' in resp.json['err_desc'] get_service.return_value = MockedService(error_class=TransportError) resp = app.get('/dpark/test/ping/') assert 'Error: connection error occured' in resp.json['err_desc'] get_service.return_value = MockedService(error_class=Exception) resp = app.get('/dpark/test/ping/') assert 'Error: random error' in resp.json['err_desc'] get_service.return_value = MockedService(error_class=WebFaultHavingLatin1) resp = app.get('/dpark/test/ping/') assert 'ServiceError: éêè' in resp.json['err_desc'] def test_ping(dpark, app, get_service): get_service.return_value = MockedService(replydata={'Code_Retour': '01', 'Lib_Retour': 'whatever'}) resp = app.get('/dpark/test/ping/') assert resp.json['data'] is True def test_search(dpark, app, get_service): params = { 'lastname': 'bar', 'firstnames': 'foo', 'filenumber': '1' * 9, 'cardnumber': '3' * 9, } # missing lastname app.get('/dpark/test/search/', params={'firstnames': 'toto'}, status=400) # unknown file get_service.return_value = MockedService( replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'} ) resp = app.get('/dpark/test/search/', params=params) assert resp.json['err'] == 1 assert resp.json['code'] == 'unknown-file' # invalid cardnumber get_service.return_value = MockedService( replydata={'CodeRetour': '04', 'MessageRetour': 'Numéro de support inconnu'} ) resp = app.get('/dpark/test/search/', params=params) assert resp.json['err'] == 1 assert resp.json['code'] == 'support-number-unknown' # valid data get_service.return_value = MockedService( replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'} ) resp = app.get('/dpark/test/search/', params=params) assert resp.json['err'] == 0 def test_link(dpark, app, get_service): params = { 'lastname': 'bar ', 'firstnames': ' foo', 'filenumber': ' ' + '1' * 9, } # missing nameid app.post_json('/dpark/test/link/', params=params, status=400) params['nameid'] = 'abcd' * 8 # unknown file get_service.return_value = MockedService( replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'} ) resp = app.post_json('/dpark/test/link/', params=params) assert resp.json['err'] == 1 assert resp.json['code'] == 'unknown-file' # invalid cardnumber get_service.return_value = MockedService( replydata={'CodeRetour': '04', 'MessageRetour': 'Numéro de support inconnu'} ) resp = app.post_json('/dpark/test/link/', params=params) assert resp.json['err'] == 1 assert resp.json['code'] == 'support-number-unknown' # valid data get_service.return_value = MockedService( replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'} ) resp = app.post_json('/dpark/test/link/', params=params) assert resp.json['err'] == 0 assert Pairing.objects.count() == 1 pairing = Pairing.objects.get(resource=dpark) assert pairing.nameid == 'abcd' * 8 assert pairing.filenumber == '1' * 9 assert pairing.firstnames == 'foo' assert pairing.lastname == 'bar' def test_unlink(dpark, app, get_service): get_service.return_value = MockedService() nameid = 'abcd' * 8 params = {'nameid': nameid} # missing nameid app.post_json('/dpark/test/unlink/', params={}, status=400) # no pairing exists resp = app.post_json('/dpark/test/unlink/', params=params) assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'No pairing exists' # pairing exist Pairing.objects.create( resource=dpark, nameid=nameid, lastname='bar', firstnames='foo', filenumber='1' * 9, badgenumber='2' * 9, cardnumber='3' * 9, ) resp = app.post_json('/dpark/test/unlink/', params=params) assert resp.json['data'] is True assert Pairing.objects.count() == 0 def test_address_eligibility(dpark, app, soap_mock): # first response, will be removed from responses registry after first call soap_mock.add_soap_response( 'PLS_ELIGADR', { 'PLS_ELIGADRResult': { 'CodeRetour': '99', 'MessageRetour': 'Erreur extension', 'Adresse_EtageEscalierAppartement': '', 'Adresse_ImmeubleBatimentResidence': '', 'Adresse_NumeroVoie': '', 'Adresse_Extension': '', 'Adresse_NomVoie': '', 'Adresse_CodeSTI': '', 'Adresse_BoitePostaleLieudit': '', 'Adresse_CodePostal': '', 'Adresse_Localite': '', 'Adresse_Quartier': '', } }, ) soap_mock.add_soap_response( 'PLS_ELIGADR', { 'PLS_ELIGADRResult': { 'CodeRetour': '01', 'MessageRetour': 'Elligible', 'Adresse_EtageEscalierAppartement': '', 'Adresse_ImmeubleBatimentResidence': '', 'Adresse_NumeroVoie': '13', 'Adresse_Extension': '1', 'Adresse_NomVoie': 'Rue des Abeilles', 'Adresse_CodeSTI': '315550016038', 'Adresse_BoitePostaleLieudit': '', 'Adresse_CodePostal': '31000', 'Adresse_Localite': 'Toulouse', 'Adresse_Quartier': 'Dupuy', } }, ) params = {'address_sticode': '315553637461', 'address_zipcode': '44000'} # missing required parameter app.get('/dpark/test/address-eligibility/', params=params, status=400) # not eligible params['address_locality'] = 'Nantes' resp = app.get('/dpark/test/address-eligibility/', params=params) assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'Erreur extension' # eligible params['address_streetext'] = 1 resp = app.get('/dpark/test/address-eligibility/', params=params) content = resp.json assert content['data'] is True assert content['address'] assert content['address']['address_locality'] == 'Toulouse' def test_subscriber_infos(dpark, app, get_service): nameid = 'abcd' * 8 url = '/dpark/test/infos/%s/' % nameid params = { 'nameid': nameid, 'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': '1' * 9, 'badgenumber': '2' * 9, } Pairing.objects.create(resource=dpark, **params) # unknown subscriber resp = app.get('/dpark/test/infos/toto/') assert resp.json['data'] == [] # unknown file get_service.return_value = MockedService( replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'} ) resp = app.get(url) assert resp.json['data'] == [] # known file replydata = { 'CodeRetour': '01', 'MessageRetour': 'Dossier existant', "Adresse_BoitePostaleLieuDit": None, "Adresse_CodePostal": "44000", "Adresse_CodeSTI": "315553609651", "Adresse_EtageEscalierAppartement": None, "Adresse_Extension": 1, "Adresse_ImmeubleBatimentResidence": None, "Adresse_Localite": "Nantes", "Adresse_NomVoie": "All\u00e9es Jean Jaur\u00e8s", "Adresse_NumeroVoie": 80, "Adresse_Quartier": "PERI", "Demande_DateDebutAbo": "20180625", "Demande_DateFinAbo": "20190624", "Demande_DelaiAutorise": 30, "Demande_ImmatVehicule1": "CX453AD", "Demande_ImmatVehicule2": None, "Demande_MarqueVehicule1": "CITROEN", "Demande_MarqueVehicule2": None, "Demande_ModeleVehicule1": "GS", "Demande_ModeleVehicule2": None, "Demande_NumeroDossier": 22952, "Demandeur_Civilite": 1, "Demandeur_Email": "spameggs@example.net", "Demandeur_NomUsuel": "BAR", "Demandeur_Prenom": "Foo Spam", "Demandeur_TelephoneFixe": "0611111111", "Demandeur_TelephonePortable": None, } get_service.return_value = MockedService(replydata=replydata) resp = app.get(url) data = resp.json['data'] assert data[0]['id'] == '22952' assert data[0]['text'] == '22952 - BAR Foo Spam - CX453AD' assert data[0]['adresse_codepostal'] == '44000' assert data[0]['adresse_codesti'] == '315553609651' assert data[0]['adresse_localite'] == 'Nantes' assert data[0]['demande_numerodossier'] == 22952 assert data[0]['demandeur_email'] == 'spameggs@example.net' assert data[0]['demandeur_telephonefixe'] == '0611111111' assert data[0]['demande_datedebutabo'] == '2018-06-25' assert data[0]['demande_datefinabo'] == '2019-06-24' # mutiple pairing Pairing.objects.create( resource=dpark, nameid=nameid, firstnames='monty', lastname='eggs', filenumber='5' * 9, badgenumber='6' * 9, cardnumber='7' * 9, ) replydata2 = { 'CodeRetour': '01', 'MessageRetour': 'Dossier existant', "Adresse_BoitePostaleLieuDit": None, "Adresse_CodePostal": "94000", "Adresse_CodeSTI": "315553609651", "Adresse_EtageEscalierAppartement": None, "Adresse_Extension": 1, "Adresse_ImmeubleBatimentResidence": None, "Adresse_Localite": "Creteil", "Adresse_NomVoie": "Allée les sablons", "Adresse_NumeroVoie": 5, "Adresse_Quartier": "HOOLI", "Demande_DateDebutAbo": "20180430", "Demande_DateFinAbo": None, "Demande_DelaiAutorise": 30, "Demande_ImmatVehicule1": "AA555BB", "Demande_ImmatVehicule2": "XX333YY", "Demande_MarqueVehicule1": "FORD", "Demande_MarqueVehicule2": "MERCEDES", "Demande_ModeleVehicule1": "Fiesta", "Demande_ModeleVehicule2": "Serie A", "Demande_NumeroDossier": 22955, "Demandeur_Civilite": 1, "Demandeur_Email": "spameggs@example.net", "Demandeur_NomUsuel": "EGGS", "Demandeur_Prenom": "Monty", "Demandeur_TelephoneFixe": "0611111111", "Demandeur_TelephonePortable": None, } # there will be only one call as first pairing is now cached get_service.side_effect = [MockedService(replydata=replydata2)] resp = app.get(url) data = resp.json['data'] assert len(data) == 2 assert data[1]['id'] == '22955' assert data[1]['text'] == '22955 - EGGS Monty - AA555BB/XX333YY' assert data[1]['adresse_codepostal'] == '94000' assert data[1]['adresse_codesti'] == '315553609651' assert data[1]['adresse_localite'] == 'Creteil' assert data[1]['demande_numerodossier'] == 22955 assert data[1]['demandeur_email'] == 'spameggs@example.net' assert data[1]['demandeur_telephonefixe'] == '0611111111' assert data[1]['demande_datedebutabo'] == '2018-04-30' assert data[1]['demande_datefinabo'] is None # filtering by filenumber for pairing in Pairing.objects.all(): pairing.clear_cache() # we modify numerodossier to verify cache is not used replydata['Demande_NumeroDossier'] = 22953 get_service.side_effect = [ MockedService(replydata=replydata), ] resp = app.get(url, params={'filenumber': '1' * 9}) data = resp.json['data'] assert len(data) == 1 assert data[0]['id'] == '22953' assert data[0]['text'] == '22953 - BAR Foo Spam - CX453AD' assert data[0]['adresse_codepostal'] == '44000' assert data[0]['adresse_codesti'] == '315553609651' assert data[0]['adresse_localite'] == 'Nantes' assert data[0]['demande_numerodossier'] == 22953 assert data[0]['demandeur_email'] == 'spameggs@example.net' assert data[0]['demandeur_telephonefixe'] == '0611111111' assert data[0]['demande_datedebutabo'] == '2018-06-25' assert data[0]['demande_datefinabo'] == '2019-06-24' def test_check_renewal_time(dpark, app, get_service): url = '/dpark/test/check-renewal-time/' params = {'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': '1' * 9, 'badgenumber': '2' * 9} get_service.return_value = MockedService( replydata={'CodeRetour': '02', 'MessageRetour': 'Renouvellement hors délai'} ) resp = app.get(url, params=params) assert resp.json['data'] is False assert resp.json['desc'] == 'Renouvellement hors délai' get_service.return_value = MockedService( replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'} ) resp = app.get(url, params=params) assert resp.json['data'] is True def test_check_renewal_duplicate(dpark, app, get_service): url = '/dpark/test/check-renewal-time/' params = {'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': '1' * 9, 'badgenumber': '2' * 9} get_service.return_value = MockedService( replydata={'CodeRetour': '02', 'MessageRetour': 'Demande déjà en cours'} ) resp = app.get(url, params=params) assert resp.json['data'] is False assert resp.json['desc'] == 'Demande déjà en cours' get_service.return_value = MockedService( replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'} ) resp = app.get(url, params=params) assert resp.json['data'] is True assert resp.json['err'] == 0 def test_check_creation_duplicate(dpark, app, get_service): url = '/dpark/test/check-creation-duplicate/' params = { 'address_district': 'PERI', 'address_locality': 'Toulouse', 'address_sticode': '315553609651', 'address_streetext': '1', 'address_zipcode': '31000', 'applicant_firstnames': 'Spam', 'applicant_lastname': 'Ham', } get_service.return_value = MockedService( replydata={'CodeRetour': '02', 'MessageRetour': 'Demande déjà en cours'} ) resp = app.get(url, params=params) assert resp.json['data'] is False assert resp.json['desc'] == 'Demande déjà en cours' get_service.return_value = MockedService(replydata={'CodeRetour': '01', 'MessageRetour': ''}) resp = app.get(url, params=params) assert resp.json['data'] is True assert resp.json['err'] == 0 def test_check_creation_not_renewal(dpark, app, get_service): url = '/dpark/test/check-creation-not-renewal/' params = { 'address_district': 'PERI', 'address_locality': 'Toulouse', 'address_sticode': '315553609651', 'address_streetext': '1', 'address_zipcode': '31000', 'applicant_firstnames': 'Spam', 'applicant_lastname': 'Ham', } get_service.return_value = MockedService( replydata={'CodeRetour': '02', 'MessageRetour': 'Usager existe déjà dans D-Park'} ) resp = app.get(url, params=params) assert resp.json['data'] is False assert resp.json['desc'] == 'Usager existe déjà dans D-Park' get_service.return_value = MockedService(replydata={'CodeRetour': '01', 'MessageRetour': ''}) resp = app.get(url, params=params) assert resp.json['data'] is True def test_get_payment_infos(dpark, app, get_service): nameid = 'abcd' * 8 url = '/dpark/test/payment-info/%s/' % nameid resp = app.get(url) assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'No pairing exists' params = { 'nameid': nameid, 'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': '1' * 9, 'badgenumber': '2' * 9, } Pairing.objects.create(resource=dpark, **params) get_service.return_value = MockedService( replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'} ) resp = app.get(url) assert resp.json['err'] == 0 assert resp.json['data'] == [] replydata = { 'CodeRetour': '01', 'MessageRetour': 'Demande acceptée', 'NumeroDemande': '55555', 'Montant': 12500, 'TypePaiement': 10, 'NumeroTeledossierPhase1': 'E-8-0AA666BB', } get_service.return_value = MockedService(replydata=replydata) resp = app.get(url) data = resp.json['data'][0] assert data['montant'] == 125 assert data['typepaiement'] == 10 assert data['typepaiement_text'] == 'Carte Bancaire via Internet' assert data['numerodemande'] == '55555' @pytest.mark.parametrize( 'transaction_datetime,expected_date', [ ('20180611', '20180611'), # UTC datetime should be converted to Europe/Paris date ('2018-06-11T23:59:00', '20180612'), ], ) def test_payment_notification(dpark, app, transaction_datetime, expected_date, get_service): operation = mock.Mock(name='PLS_NOTIFCB') service = mock.Mock(spec=['PLS_NOTIFCB'], PLS_NOTIFCB=operation) get_service.return_value = service nameid = 'abcd' * 8 filenumber = '1' * 9 params = { 'nameid': nameid, 'filenumber': filenumber, 'transaction_id': 'I123456789', 'transaction_datetime': transaction_datetime, 'total_amount': '125', 'application_id': '61718', 'application_external_id': 'E-8-N5UTAK6P', } url = '/dpark/test/notify-payment/' resp = app.post_json(url, params=params) assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'No pairing exists' Pairing.objects.create( resource=dpark, **{ 'nameid': nameid, 'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': filenumber, 'badgenumber': '2' * 9, }, ) operation.return_value = mock.Mock(CodeRetour='02', MessageRetour='Dossier inconnu') resp = app.post_json(url, params=params) assert operation.call_args_list[-1].args[5] == expected_date assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'Dossier inconnu' operation.return_value = mock.Mock(CodeRetour='01') resp = app.post_json(url, params=params) assert resp.json['data'] is True @pytest.mark.parametrize('application_thirdparty_subscription', [True, False]) def test_registration(dpark, app, application_thirdparty_subscription, soap_mock): soap_mock.add_soap_response( 'PLS_ENREG', { 'PLS_ENREGResult': { 'CodeRetour': '02', 'MessageRetour': 'Dossier incomplet', 'NumeroDossier': 0, 'NumeroDemande': 0, } }, ) soap_mock.add_soap_response( 'PLS_ENREG', { 'PLS_ENREGResult': { 'CodeRetour': '01', 'MessageRetour': '', 'NumeroDossier': 22334, 'NumeroDemande': 59492, } }, ) url = '/dpark/test/register/' params = { "address_complement1": "", "address_complement2": "", "address_locality": "Toulouse", "address_sticode": "315553609651", "address_streetext": "1", "address_streetname": "", "address_streetno": "16", "address_zipcode": "31000", "applicant_email": "sh@eggs.org", "applicant_firstnames": "Spam Ham", "applicant_lastname": "EGGS", "applicant_mobilephone": "0655443322", "applicant_phone": "", "applicant_title": "1", "application_car1_brand": "Peugeot", "application_car1_exemption": "8", "application_car1_model": "206", "application_car1_plate": "AA777ZZ", "application_id": "12-4", "application_payment_type": "10", "application_thirdparty_subscription": application_thirdparty_subscription, "application_type": 1, } # with missing parameter app.post_json(url, params=params, status=400) params['address_district'] = "PERI" # with an incomplete application resp = app.post_json(url, params=params) assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'Dossier incomplet' soap_request = soap_mock.soap_requests[0] assert type(soap_request).__name__ == 'tPLS_ENREG' assert soap_request.Entree_Demande.Demande_AbonnementTiers is application_thirdparty_subscription # with complete application resp = app.post_json(url, params=params) soap_request = soap_mock.soap_requests[1] assert resp.json['data']['numerodossier'] == 22334 assert resp.json['data']['numerodemande'] == 59492 assert type(soap_request).__name__ == 'tPLS_ENREG' assert soap_request.Entree_Demande.Demande_AbonnementTiers is application_thirdparty_subscription # we need to freeze_time as Pillow (used by to_pdf()) embed the current time in # the produced PDF, so to get some deterministic behaviour it's needed to # freeze the time. def test_send_files(dpark, app, soap_mock, settings, freezer): params = {'application_external_id': 'E-8-N5UTAK6P'} with mock.patch('passerelle.contrib.dpark.models.DPark.call') as soap_call: url = '/dpark/test/send-files/' app.post_json(url, params=params, status=400) params['application_id'] = '' app.post_json(url, params=params, status=400) params['application_id'] = '61718' soap_call.side_effect = APIError('Numéro de demande introuvable') resp = app.post_json(url, params=params) assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'Numéro de demande introuvable' params['justif_domicile'] = { 'filename': 'address_proof.pDf', 'content_type': 'application/pdf', 'content': force_str(base64.b64encode(b'%PDF this is my proof of address')), } params['cartegrise,1'] = { 'filename': 'cartegrise.pdf', 'content_type': 'application/pdf', 'content': force_str(base64.b64encode(b'%PDF carte grise 1')), } params['toto,6'] = { 'filename': 'cartegrisetoto.jpg', 'content_type': 'application/pdf', 'content': force_str(base64.b64encode(JPEG_CONTENT)), } params['cartegrise,6'] = { 'filename': 'cartegrise2.pdf', 'content_type': 'application/pdf', 'content': force_str(base64.b64encode(b'%PDF carte grise 2')), } params['taxe_habitat'] = { 'filename': 'cartegrise2.pdf', 'content_type': 'application/pdf', 'content': None, } params['taxe_habitat,2'] = {'content_type': 'application/pdf', 'content': 'whatever'} params['impot_revenu'] = 'this is my tax notice' resp = app.post_json(url, params=params) errors = [ " value is not a dict", " is either absent or has an invalid value", " is either absent or has an invalid value", "Invalid document type: ", ] assert resp.json['err'] == 1 assert resp.json['err_desc'] == '%s' % errors params.pop('impot_revenu') params.pop('taxe_habitat') params.pop('taxe_habitat,2') # add custom document type settings.DPARK_DOCUMENT_CODES = {'toto': '73'} soap_mock.add_soap_response( 'PLS_ENVOIPJ', { 'PLS_ENVOIPJResult': { 'CodeRetour': '01', 'MessageRetour': '', } }, ) resp = app.post_json(url, params=params) assert resp.json['err'] == 0 assert resp.json['data'] is True assert len(soap_mock.soap_requests) == 1 soap_request = soap_mock.soap_requests[0] assert soap_request.NumeroTeledossier == 'E-8-N5UTAK6P' assert soap_request.NumeroDossier == 61718 assert soap_request.NbFichier == 4 assert soap_request.Bloc_Fichiers[0].TypeDocument == '6' assert soap_request.Bloc_Fichiers[0].NomFichier == 'cartegrise.pdf' assert soap_request.Bloc_Fichiers[0].Fichier == b'%PDF carte grise 1' assert soap_request.Bloc_Fichiers[1].TypeDocument == '6' assert soap_request.Bloc_Fichiers[1].NomFichier == 'cartegrise2.pdf' assert soap_request.Bloc_Fichiers[1].Fichier == b'%PDF carte grise 2' assert soap_request.Bloc_Fichiers[2].TypeDocument == '2' assert soap_request.Bloc_Fichiers[2].NomFichier == 'address_proof.pDf' assert soap_request.Bloc_Fichiers[2].Fichier == b'%PDF this is my proof of address' assert soap_request.Bloc_Fichiers[3].TypeDocument == '73' assert soap_request.Bloc_Fichiers[3].NomFichier == 'cartegrisetoto.jpg.pdf' assert soap_request.Bloc_Fichiers[3].Fichier == to_pdf(JPEG_CONTENT) assert soap_request.Bloc_Fichiers[3].Fichier.startswith(b'%PDF') @pytest.mark.parametrize('application_thirdparty_subscription', [True, False]) def test_registration_double_plaque(dpark, app, soap_mock, application_thirdparty_subscription): url = '/dpark/test/register/' params = { "address_complement1": "", "address_complement2": "", "address_district": "PERI", "address_locality": "Toulouse", "address_sticode": "315553609651", "address_streetext": "1", "address_streetname": "", "address_streetno": "16", "address_zipcode": "31000", "applicant_email": "sh@eggs.org", "applicant_firstnames": "Spam Ham", "applicant_lastname": "EGGS", "applicant_mobilephone": "0655443322", "applicant_phone": "", "applicant_title": "1", "application_car1_brand": "Peugeot", "application_car1_exemption": "8", "application_car1_model": "206", "application_car1_plate": "AA777ZZ", "application_id": "12-4", "application_payment_type": "10", "application_thirdparty_subscription": application_thirdparty_subscription, "application_type": 1, 'double_plaque': '1', } # with missing parameter app.post_json(url, params=params, status=400) params.update( { 'id_contexte': '1', 'id_produit': '2', } ) # with an imcplete application soap_mock.add_soap_response( 'PLS_ENREG2', { 'PLS_ENREG2Result': { 'CodeRetour': '02', 'MessageRetour': 'Dossier incomplet', 'NumeroDossier': 0, 'NumeroDemande': 0, } }, ) soap_mock.add_soap_response( 'PLS_ENREG2', { 'PLS_ENREG2Result': { 'CodeRetour': '01', 'MessageRetour': '', 'NumeroDossier': 22334, 'NumeroDemande': 59492, } }, ) # result is incomplete application resp = app.post_json(url, params=params) assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'Dossier incomplet' soap_request = soap_mock.soap_requests[0] assert soap_request.ID_CONTEXTE == 1 assert soap_request.ID_PRODUIT == 2 # with is ok resp = app.post_json(url, params=params) assert resp.json['data']['numerodossier'] == 22334 assert resp.json['data']['numerodemande'] == 59492 soap_request = soap_mock.soap_requests[0] assert soap_request.Entree_Demande.Demande_AbonnementTiers is application_thirdparty_subscription @pytest.mark.parametrize( 'transaction_datetime,expected_date', [ ('20180611', '20180611'), # UTC datetime should be converted to Europe/Paris date ('2018-06-11T23:59:00', '20180612'), ], ) def test_payment_notification_double_plaque(dpark, app, transaction_datetime, expected_date, get_service): operation = mock.Mock(name='PLS_NOTIFCB2') service = mock.Mock(spec=['PLS_NOTIFCB2'], PLS_NOTIFCB2=operation) get_service.return_value = service nameid = 'abcd' * 8 filenumber = '1' * 9 params = { 'nameid': nameid, 'filenumber': filenumber, 'transaction_id': 'I123456789', 'transaction_datetime': transaction_datetime, 'total_amount': '125', 'application_id': '61718', 'application_external_id': 'E-8-N5UTAK6P', 'double_plaque': '1', } url = '/dpark/test/notify-payment/' resp = app.post_json(url, params=params) assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'No pairing exists' Pairing.objects.create( resource=dpark, **{ 'nameid': nameid, 'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': filenumber, 'badgenumber': '2' * 9, }, ) operation.return_value = mock.Mock(CodeRetour='02', MessageRetour='Dossier inconnu') resp = app.post_json(url, params=params) assert operation.call_args_list[-1].args[5] == expected_date assert resp.json['err'] == 1 assert resp.json['err_desc'] == 'Dossier inconnu' operation.return_value = mock.Mock(CodeRetour='01') resp = app.post_json(url, params=params) assert resp.json['data'] is True