Projet

Général

Profil

0001-dpark-add-support-for-methods-PLS_ENREG2-and-PLS_NOT.patch

Benjamin Dauvergne, 31 mai 2022 18:18

Télécharger (14,8 ko)

Voir les différences:

Subject: [PATCH] dpark: add support for methods PLS_ENREG2 and PLS_NOTIFCB2
 (#65777)

 passerelle/contrib/dpark/models.py |  47 ++++++----
 tests/data/dpark.awws.wsdl         |  75 ++++++++++++++-
 tests/test_dpark.py                | 144 ++++++++++++++++++++++++++++-
 3 files changed, 247 insertions(+), 19 deletions(-)
passerelle/contrib/dpark/models.py
31 31

  
32 32
from passerelle.base.models import BaseResource
33 33
from passerelle.utils.api import endpoint
34
from passerelle.utils.conversion import to_pdf
34
from passerelle.utils.conversion import any2bool, to_pdf
35 35
from passerelle.utils.jsonresponse import APIError
36 36
from passerelle.views import WrongParameter
37 37

  
......
290 290
    @endpoint(perm='can_access', methods=['post'], description=_('Register a subscription application'))
291 291
    def register(self, request, *args, **kwargs):
292 292
        data = json.loads(request.body)
293
        is_erroneous(
294
            data,
295
            (
296
                'application_id',
297
                'applicant_title',
298
                'applicant_lastname',
299
                'applicant_firstnames',
300
                'applicant_email',
301
                'address_sticode',
302
                'address_zipcode',
303
                'address_locality',
304
                'address_district',
305
            ),
306
        )
293
        double_plaque = any2bool(data.get('double_plaque'))
294
        required_fields = [
295
            'application_id',
296
            'applicant_title',
297
            'applicant_lastname',
298
            'applicant_firstnames',
299
            'applicant_email',
300
            'address_sticode',
301
            'address_zipcode',
302
            'address_locality',
303
            'address_district',
304
        ]
305
        if double_plaque:
306
            required_fields.extend(['id_contexte', 'id_produit'])
307
        is_erroneous(data, required_fields)
307 308
        application_id = data['application_id']
308 309
        applicant = {
309 310
            'Demandeur_Civilite': data['applicant_title'],
......
339 340
            'Demande_IBAN': data.get('application_bank_iban', ''),
340 341
            'Demande_BIC': data.get('application_bank_bic', ''),
341 342
        }
342
        reply = self.call('PLS_ENREG', application_id, applicant, address, application)
343
        if double_plaque:
344
            reply = self.call(
345
                'PLS_ENREG2',
346
                application_id,
347
                applicant,
348
                address,
349
                application,
350
                data['id_produit'],
351
                data['id_contexte'],
352
            )
353
        else:
354
            reply = self.call('PLS_ENREG', application_id, applicant, address, application)
343 355
        if filenumber:
344 356
            for pairing in Pairing.objects.filter(filenumber=filenumber):
345 357
                pairing.clear_cache()
......
499 511
        total_amount = int(data['total_amount']) * 100  # in cents
500 512
        if not pairings:
501 513
            raise APIError(_('No pairing exists'))
514
        double_plaque = any2bool(data.get('double_plaque'))
502 515
        self.call(
503
            'PLS_NOTIFCB',
516
            'PLS_NOTIFCB2' if double_plaque else 'PLS_NOTIFCB',
504 517
            data['application_external_id'],
505 518
            data['filenumber'],
506 519
            data['application_id'],
tests/data/dpark.awws.wsdl
360 360
        </xsd:sequence>
361 361
      </xsd:complexType>
362 362
      <xsd:element name="FPS_Rech_ImmatResponse" type="s0:tFPS_Rech_ImmatResponse"/>
363
      <xsd:complexType name="tPLS_ENREG2">
364
        <xsd:sequence>
365
          <xsd:element name="NumeroTeledossier" type="xsd:string"/>
366
          <xsd:element name="Entree_Demandeur" type="s0:tEntree_Demandeur_PLS_ENREG"/>
367
          <xsd:element name="Entree_Adresse" type="s0:tEntree_Adresse"/>
368
          <xsd:element name="Entree_Demande" type="s0:tEntree_Demande_PLS_ENREG"/>
369
          <xsd:element name="ID_PRODUIT" type="xsd:int"/>
370
          <xsd:element name="ID_CONTEXTE" type="xsd:int"/>
371
        </xsd:sequence>
372
      </xsd:complexType>
373
      <xsd:element name="PLS_ENREG2" type="s0:tPLS_ENREG2"/>
374
      <xsd:complexType name="tPLS_ENREG2Response">
375
        <xsd:sequence>
376
          <xsd:element name="PLS_ENREG2Result" type="s0:tRetour_PLS_ENREG"/>
377
        </xsd:sequence>
378
      </xsd:complexType>
379
      <xsd:element name="PLS_ENREG2Response" type="s0:tPLS_ENREG2Response"/>
380
      <xsd:complexType name="tPLS_NOTIFCB2">
381
        <xsd:sequence>
382
          <xsd:element name="NumeroTeledossierPhase1" type="xsd:string"/>
383
          <xsd:element name="NumeroDossier" type="xsd:int"/>
384
          <xsd:element name="NumeroDemande" type="xsd:int"/>
385
          <xsd:element name="TypePaiement" type="xsd:int"/>
386
          <xsd:element name="MontantPaye" type="xsd:int"/>
387
          <xsd:element name="DatePaiement" type="xsd:string"/>
388
          <xsd:element name="RefTransaction" type="xsd:string"/>
389
        </xsd:sequence>
390
      </xsd:complexType>
391
      <xsd:element name="PLS_NOTIFCB2" type="s0:tPLS_NOTIFCB2"/>
392
      <xsd:complexType name="tPLS_NOTIFCB2Response">
393
        <xsd:sequence>
394
          <xsd:element name="PLS_NOTIFCB2Result" type="s0:tRetour_PLS"/>
395
        </xsd:sequence>
396
      </xsd:complexType>
397
      <xsd:element name="PLS_NOTIFCB2Response" type="s0:tPLS_NOTIFCB2Response"/>
363 398
    </xsd:schema>
364 399
  </types>
365 400
  <message name="Webservice_Residants_PLS_EXIST_MessageIn">
......
434 469
  <message name="Webservice_Residants_FPS_Rech_Immat_MessageOut">
435 470
    <part name="parameters" element="s0:FPS_Rech_ImmatResponse"/>
436 471
  </message>
472
  <message name="Webservice_Residants_PLS_ENREG2_MessageIn">
473
    <part name="parameters" element="s0:PLS_ENREG2"/>
474
  </message>
475
  <message name="Webservice_Residants_PLS_ENREG2_MessageOut">
476
    <part name="parameters" element="s0:PLS_ENREG2Response"/>
477
  </message>
478
  <message name="Webservice_Residants_PLS_NOTIFCB2_MessageIn">
479
    <part name="parameters" element="s0:PLS_NOTIFCB2"/>
480
  </message>
481
  <message name="Webservice_Residants_PLS_NOTIFCB2_MessageOut">
482
    <part name="parameters" element="s0:PLS_NOTIFCB2Response"/>
483
  </message>
437 484
  <portType name="Webservice_ResidantsSOAPPortType">
438 485
    <operation name="PLS_EXIST">
439 486
      <input message="s0:Webservice_Residants_PLS_EXIST_MessageIn"/>
......
484 531
      <input message="s0:Webservice_Residants_FPS_Rech_Immat_MessageIn"/>
485 532
      <output message="s0:Webservice_Residants_FPS_Rech_Immat_MessageOut"/>
486 533
    </operation>
534
    <operation name="PLS_ENREG2">
535
      <input message="s0:Webservice_Residants_PLS_ENREG2_MessageIn"/>
536
      <output message="s0:Webservice_Residants_PLS_ENREG2_MessageOut"/>
537
    </operation>
538
    <operation name="PLS_NOTIFCB2">
539
      <input message="s0:Webservice_Residants_PLS_NOTIFCB2_MessageIn"/>
540
      <output message="s0:Webservice_Residants_PLS_NOTIFCB2_MessageOut"/>
541
    </operation>
487 542
  </portType>
488 543
  <binding name="Webservice_ResidantsSOAPBinding" type="s0:Webservice_ResidantsSOAPPortType">
489 544
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
......
595 650
        <soap:body use="literal"/>
596 651
      </output>
597 652
    </operation>
653
    <operation name="PLS_ENREG2">
654
      <soap:operation soapAction="urn:Webservice_Residants/PLS_ENREG2" style="document"/>
655
      <input>
656
        <soap:body use="literal"/>
657
      </input>
658
      <output>
659
        <soap:body use="literal"/>
660
      </output>
661
    </operation>
662
    <operation name="PLS_NOTIFCB2">
663
      <soap:operation soapAction="urn:Webservice_Residants/PLS_NOTIFCB2" style="document"/>
664
      <input>
665
        <soap:body use="literal"/>
666
      </input>
667
      <output>
668
        <soap:body use="literal"/>
669
      </output>
670
    </operation>
598 671
  </binding>
599 672
  <service name="Webservice_Residants">
600 673
    <port name="Webservice_ResidantsSOAPPort" binding="s0:Webservice_ResidantsSOAPBinding">
601
      <soap:address location="http://W01DPA001T/WEBSERVICE_RESIDANTS_WEB/awws/Webservice_Residants.awws"/>
674
      <soap:address location="http://w01dpa001i/WEBSERVICE_RESIDANTS_WEB/awws/Webservice_Residants.awws"/>
602 675
    </port>
603 676
  </service>
604 677
</definitions>
tests/test_dpark.py
629 629
        '<Demande_AbonnementTiers>%s</Demande_AbonnementTiers>'
630 630
        % repr(application_thirdparty_subscription).lower()
631 631
    )
632
    assert demande_abonnementtiers in force_text(dpark.mock_requests[0].body)
632
    body = dpark.mock_requests[0].body.decode()
633
    assert ':PLS_ENREG ' in body
634
    assert demande_abonnementtiers in body
633 635
    assert resp.json['err'] == 1
634 636
    assert resp.json['err_desc'] == 'Dossier incomplet'
635 637
    # with complete application
......
766 768
        base64.b64encode(to_pdf(JPEG_CONTENT))
767 769
    )
768 770
    assert base64.b64decode(pj_node.findall('Bloc_Fichiers')[3].find('Fichier').text).startswith(b'%PDF')
771

  
772

  
773
@pytest.mark.parametrize('application_thirdparty_subscription', [True, False])
774
def test_registration_double_plaque(dpark, app, application_thirdparty_subscription):
775
    url = '/dpark/test/register/'
776
    params = {
777
        "address_complement1": "",
778
        "address_complement2": "",
779
        "address_district": "PERI",
780
        "address_locality": "Toulouse",
781
        "address_sticode": "315553609651",
782
        "address_streetext": "1",
783
        "address_streetname": "",
784
        "address_streetno": "16",
785
        "address_zipcode": "31000",
786
        "applicant_email": "sh@eggs.org",
787
        "applicant_firstnames": "Spam Ham",
788
        "applicant_lastname": "EGGS",
789
        "applicant_mobilephone": "0655443322",
790
        "applicant_phone": "",
791
        "applicant_title": "1",
792
        "application_car1_brand": "Peugeot",
793
        "application_car1_exemption": "8",
794
        "application_car1_model": "206",
795
        "application_car1_plate": "AA777ZZ",
796
        "application_id": "12-4",
797
        "application_payment_type": "10",
798
        "application_thirdparty_subscription": application_thirdparty_subscription,
799
        "application_type": 1,
800
        'double_plaque': '1',
801
    }
802
    # with missing parameter
803
    app.post_json(url, params=params, status=400)
804
    params.update(
805
        {
806
            'id_contexte': '1',
807
            'id_produit': '2',
808
        }
809
    )
810
    # with an imcplete application
811
    dpark.mock_responses.append(
812
        """<?xml version="1.0" encoding="utf-8"?>
813
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
814
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
815
  <SOAP-ENV:Header/>
816
  <SOAP-ENV:Body>
817
    <ns1:PLS_ENREGResponse xmlns:ns1="urn:Webservice_Residants">
818
      <PLS_ENREG2Result>
819
        <CodeRetour>02</CodeRetour>
820
        <MessageRetour>Dossier incomplet</MessageRetour>
821
      </PLS_ENREG2Result>
822
    </ns1:PLS_ENREGResponse>
823
  </SOAP-ENV:Body>
824
</SOAP-ENV:Envelope>"""
825
    )
826
    resp = app.post_json(url, params=params)
827
    demande_abonnementtiers = (
828
        '<Demande_AbonnementTiers>%s</Demande_AbonnementTiers>'
829
        % repr(application_thirdparty_subscription).lower()
830
    )
831
    body = dpark.mock_requests[0].body.decode()
832
    assert demande_abonnementtiers in body
833
    assert ':PLS_ENREG2 ' in body
834
    assert '<ID_CONTEXTE>1<' in body
835
    assert '<ID_PRODUIT>2<' in body
836
    assert resp.json['err'] == 1
837
    assert resp.json['err_desc'] == 'Dossier incomplet'
838
    # with complete application
839
    dpark.mock_responses.append(
840
        """<?xml version="1.0" encoding="utf-8"?>
841
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
842
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
843
  <SOAP-ENV:Header/>
844
  <SOAP-ENV:Body>
845
    <ns1:PLS_ENREGResponse xmlns:ns1="urn:Webservice_Residants">
846
      <PLS_ENREG2Result>
847
        <CodeRetour>01</CodeRetour>
848
        <MessageRetour/>
849
        <NumeroDossier>22334</NumeroDossier>
850
        <NumeroDemande>59492</NumeroDemande>
851
      </PLS_ENREG2Result>
852
    </ns1:PLS_ENREGResponse>
853
  </SOAP-ENV:Body>
854
</SOAP-ENV:Envelope>"""
855
    )
856
    resp = app.post_json(url, params=params)
857
    body = dpark.mock_requests[1].body.decode()
858
    assert demande_abonnementtiers in body
859
    assert resp.json['data']['numerodossier'] == 22334
860
    assert resp.json['data']['numerodemande'] == 59492
861

  
862

  
863
@pytest.mark.parametrize(
864
    'transaction_datetime,expected_date',
865
    [
866
        ('20180611', '20180611'),
867
        # UTC datetime should be converted to Europe/Paris date
868
        ('2018-06-11T23:59:00', '20180612'),
869
    ],
870
)
871
def test_payment_notification_double_plaque(dpark, app, transaction_datetime, expected_date):
872
    operation = mock.Mock(name='PLS_NOTIFCB2')
873
    service = mock.Mock(spec=['PLS_NOTIFCB2'], PLS_NOTIFCB2=operation)
874
    create_service = mock.Mock(spec=[], return_value=service)
875
    client = mock.NonCallableMock(spec=['create_service'], create_service=create_service)
876
    with mock.patch('passerelle.contrib.dpark.models.get_client', return_value=client):
877
        nameid = 'abcd' * 8
878
        filenumber = '1' * 9
879
        params = {
880
            'nameid': nameid,
881
            'filenumber': filenumber,
882
            'transaction_id': 'I123456789',
883
            'transaction_datetime': transaction_datetime,
884
            'total_amount': '125',
885
            'application_id': '61718',
886
            'application_external_id': 'E-8-N5UTAK6P',
887
            'double_plaque': '1',
888
        }
889
        url = '/dpark/test/notify-payment/'
890
        resp = app.post_json(url, params=params)
891
        assert resp.json['err'] == 1
892
        assert resp.json['err_desc'] == 'No pairing exists'
893
        Pairing.objects.create(
894
            resource=dpark,
895
            **{
896
                'nameid': nameid,
897
                'firstnames': 'spam eggs',
898
                'lastname': 'bar',
899
                'filenumber': filenumber,
900
                'badgenumber': '2' * 9,
901
            },
902
        )
903
        operation.return_value = mock.Mock(CodeRetour='02', MessageRetour='Dossier inconnu')
904
        resp = app.post_json(url, params=params)
905
        assert operation.call_args_list[-1].args[5] == expected_date
906
        assert resp.json['err'] == 1
907
        assert resp.json['err_desc'] == 'Dossier inconnu'
908
        operation.return_value = mock.Mock(CodeRetour='01')
909
        resp = app.post_json(url, params=params)
910
        assert resp.json['data'] is True
769
-