Projet

Général

Profil

0002-dpark-remove-hardcoding-of-the-service-binding-72638.patch

Benjamin Dauvergne, 20 décembre 2022 15:43

Télécharger (56,1 ko)

Voir les différences:

Subject: [PATCH 2/2] dpark: remove hardcoding of the service binding (#72638)

 passerelle/contrib/dpark/models.py |   16 +-
 tests/test_dpark.py                | 1208 ++++++++++++++--------------
 2 files changed, 598 insertions(+), 626 deletions(-)
passerelle/contrib/dpark/models.py
46 46
        return False
47 47

  
48 48

  
49
SERVICE_BINDING = '{urn:Webservice_Residants}Webservice_ResidantsSOAPBinding'
50

  
51

  
52 49
DOCUMENT_CODES = {
53 50
    'justif_domicile': '2',
54 51
    'assurance': '4',
......
195 192
    }
196 193

  
197 194

  
198
def get_client(instance):
199
    return instance.soap_client()
195
def get_service(instance):
196
    client = instance.soap_client()
197
    service_name = list(client.wsdl.services)[0]
198
    port_name = list(client.wsdl.services[service_name].ports)[0]
199
    binding_name = str(client.wsdl.services[service_name].ports[port_name].binding.name)
200
    return client.create_service(binding_name, instance.operation_url)
200 201

  
201 202

  
202 203
class DPark(BaseResource):
......
224 225
        return '%s - %s' % (self.slug, self.wsdl_url)
225 226

  
226 227
    def call(self, operation, *args, **kwargs):
227
        client = get_client(self)
228
        proxy_service = client.create_service(SERVICE_BINDING, self.operation_url)
228
        service = get_service(self)
229 229
        bypass_erroneous_reply = kwargs.pop('bypass_erroneous_reply', False)
230 230
        try:
231
            reply = getattr(proxy_service, operation)(*args, **kwargs)
231
            reply = getattr(service, operation)(*args, **kwargs)
232 232
        except (WebFault,) as exc:
233 233
            raise APIError('ServiceError: %s' % exc)
234 234
        except (Exception,) as exc:
tests/test_dpark.py
3 3
import xml.etree.ElementTree as ET
4 4
from unittest import mock
5 5

  
6
import httmock
7 6
import pytest
8 7
from django.utils.encoding import force_str
9 8
from zeep.exceptions import Fault as WebFault
10 9
from zeep.exceptions import TransportError
11 10

  
12 11
from passerelle.contrib.dpark.models import DPark, Pairing
12
from passerelle.utils.conversion import to_pdf
13 13
from passerelle.utils.jsonresponse import APIError
14
from tests.utils import make_resource
14
from tests.utils import ResponsesSoap, make_resource
15 15

  
16 16
SLUG = 'test'
17 17
WSDL_URL = 'https://example.net/dpark?wsdl'
18
OPERATIONAL_URL = 'https://example.net/dpark'
18
SERVICE_URL = 'https://example.net/dpark'
19 19

  
20 20
with open(os.path.join(os.path.dirname(__file__), 'data/dpark.awws.wsdl')) as f:
21 21
    WSDL_CONTENT = f.read()
......
52 52
        **{
53 53
            'slug': SLUG,
54 54
            'wsdl_url': WSDL_URL,
55
            'operation_url': OPERATIONAL_URL,
55
            'operation_url': SERVICE_URL,
56 56
        },
57 57
    )
58
    resource.mock_requests = []
59
    resource.mock_responses = []
58
    return resource
60 59

  
61
    @httmock.urlmatch(scheme='https', netloc='example.net', path='/dpark', query='wsdl', method='GET')
62
    def wsdl(url, request):
63
        return WSDL_CONTENT
64 60

  
65
    @httmock.urlmatch(scheme='https', netloc='example.net', path='/dpark', method='POST')
66
    def request(url, request):
67
        idx = len(resource.mock_requests)
68
        resource.mock_requests.append(request)
69
        return resource.mock_responses[idx]
70

  
71
    with httmock.HTTMock(wsdl, request):
72
        yield resource
61
@pytest.fixture
62
def soap_mock(dpark):
63
    responses_soap = ResponsesSoap(WSDL_URL, WSDL_CONTENT, address=SERVICE_URL)
64
    with responses_soap() as soap_mock:
65
        yield soap_mock
73 66

  
74 67

  
75 68
class ReplyDataClass(dict):
......
83 76

  
84 77

  
85 78
class MockedService:
86
    def __init__(self, success, error_class, replydata):
79
    def __init__(self, success=True, error_class=None, replydata=None):
87 80
        self.success = success
88 81
        self.error_class = error_class
89 82
        self.replydata = replydata
......
106 99
        return self.return_response
107 100

  
108 101

  
109
def get_client(success=True, error_class=None, replydata=None):
110
    service = MockedService(success, error_class, replydata)
111

  
112
    def create_service(binging, operation_endpoint):
113
        return service
102
@pytest.fixture
103
def get_service():
104
    with mock.patch('passerelle.contrib.dpark.models.get_service') as get_service:
105
        yield get_service
106

  
107

  
108
def test_call_service_error(dpark, app, get_service):
109
    get_service.return_value = MockedService(error_class=WebFault)
110
    resp = app.get('/dpark/test/ping/')
111
    assert 'ServiceError: ' in resp.json['err_desc']
112
    get_service.return_value = MockedService(error_class=TransportError)
113
    resp = app.get('/dpark/test/ping/')
114
    assert 'Error: connection error occured' in resp.json['err_desc']
115
    get_service.return_value = MockedService(error_class=Exception)
116
    resp = app.get('/dpark/test/ping/')
117
    assert 'Error: random error' in resp.json['err_desc']
118
    get_service.return_value = MockedService(error_class=WebFaultHavingLatin1)
119
    resp = app.get('/dpark/test/ping/')
120
    assert 'ServiceError: éêè' in resp.json['err_desc']
121

  
122

  
123
def test_ping(dpark, app, get_service):
124
    get_service.return_value = MockedService(replydata={'Code_Retour': '01', 'Lib_Retour': 'whatever'})
125
    resp = app.get('/dpark/test/ping/')
126
    assert resp.json['data'] is True
114 127

  
115
    return mock.Mock(create_service=create_service, service=service)
116 128

  
129
def test_search(dpark, app, get_service):
130
    params = {
131
        'lastname': 'bar',
132
        'firstnames': 'foo',
133
        'filenumber': '1' * 9,
134
        'cardnumber': '3' * 9,
135
    }
136
    # missing lastname
137
    app.get('/dpark/test/search/', params={'firstnames': 'toto'}, status=400)
138
    # unknown file
139
    get_service.return_value = MockedService(
140
        replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'}
141
    )
142
    resp = app.get('/dpark/test/search/', params=params)
143
    assert resp.json['err'] == 1
144
    assert resp.json['code'] == 'unknown-file'
145
    # invalid cardnumber
146
    get_service.return_value = MockedService(
147
        replydata={'CodeRetour': '04', 'MessageRetour': 'Numéro de support inconnu'}
148
    )
149
    resp = app.get('/dpark/test/search/', params=params)
150
    assert resp.json['err'] == 1
151
    assert resp.json['code'] == 'support-number-unknown'
152
    # valid data
153
    get_service.return_value = MockedService(
154
        replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'}
155
    )
156
    resp = app.get('/dpark/test/search/', params=params)
157
    assert resp.json['err'] == 0
117 158

  
118
def test_call_service_error(dpark, app):
119
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
120
        client.return_value = get_client(error_class=WebFault)
121
        resp = app.get('/dpark/test/ping/')
122
        assert 'ServiceError: ' in resp.json['err_desc']
123
        client.return_value = get_client(error_class=TransportError)
124
        resp = app.get('/dpark/test/ping/')
125
        assert 'Error: connection error occured' in resp.json['err_desc']
126
        client.return_value = get_client(error_class=Exception)
127
        resp = app.get('/dpark/test/ping/')
128
        assert 'Error: random error' in resp.json['err_desc']
129
        client.return_value = get_client(error_class=WebFaultHavingLatin1)
130
        resp = app.get('/dpark/test/ping/')
131
        assert 'ServiceError: éêè' in resp.json['err_desc']
132 159

  
160
def test_link(dpark, app, get_service):
161
    params = {
162
        'lastname': 'bar ',
163
        'firstnames': ' foo',
164
        'filenumber': ' ' + '1' * 9,
165
    }
166
    # missing nameid
167
    app.post_json('/dpark/test/link/', params=params, status=400)
168
    params['nameid'] = 'abcd' * 8
169
    # unknown file
170
    get_service.return_value = MockedService(
171
        replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'}
172
    )
173
    resp = app.post_json('/dpark/test/link/', params=params)
174
    assert resp.json['err'] == 1
175
    assert resp.json['code'] == 'unknown-file'
176
    # invalid cardnumber
177
    get_service.return_value = MockedService(
178
        replydata={'CodeRetour': '04', 'MessageRetour': 'Numéro de support inconnu'}
179
    )
180
    resp = app.post_json('/dpark/test/link/', params=params)
181
    assert resp.json['err'] == 1
182
    assert resp.json['code'] == 'support-number-unknown'
183
    # valid data
184
    get_service.return_value = MockedService(
185
        replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'}
186
    )
187
    resp = app.post_json('/dpark/test/link/', params=params)
188
    assert resp.json['err'] == 0
189
    assert Pairing.objects.count() == 1
190
    pairing = Pairing.objects.get(resource=dpark)
191
    assert pairing.nameid == 'abcd' * 8
192
    assert pairing.filenumber == '1' * 9
193
    assert pairing.firstnames == 'foo'
194
    assert pairing.lastname == 'bar'
195

  
196

  
197
def test_unlink(dpark, app, get_service):
198
    get_service.return_value = MockedService()
199
    nameid = 'abcd' * 8
200
    params = {'nameid': nameid}
201
    # missing nameid
202
    app.post_json('/dpark/test/unlink/', params={}, status=400)
203
    # no pairing exists
204
    resp = app.post_json('/dpark/test/unlink/', params=params)
205
    assert resp.json['err'] == 1
206
    assert resp.json['err_desc'] == 'No pairing exists'
207
    # pairing exist
208
    Pairing.objects.create(
209
        resource=dpark,
210
        nameid=nameid,
211
        lastname='bar',
212
        firstnames='foo',
213
        filenumber='1' * 9,
214
        badgenumber='2' * 9,
215
        cardnumber='3' * 9,
216
    )
217
    resp = app.post_json('/dpark/test/unlink/', params=params)
218
    assert resp.json['data'] is True
219
    assert Pairing.objects.count() == 0
133 220

  
134
def test_ping(dpark, app):
135
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
136
        client.return_value = get_client(replydata={'Code_Retour': '01', 'Lib_Retour': 'whatever'})
137
        resp = app.get('/dpark/test/ping/')
138
        assert resp.json['data'] is True
139 221

  
222
def test_address_eligibility(dpark, app, soap_mock):
223
    # first response, will be removed from responses registry after first call
224
    soap_mock.add_soap_response(
225
        'PLS_ELIGADR',
226
        {
227
            'PLS_ELIGADRResult': {
228
                'CodeRetour': '99',
229
                'MessageRetour': 'Erreur extension',
230
                'Adresse_EtageEscalierAppartement': '',
231
                'Adresse_ImmeubleBatimentResidence': '',
232
                'Adresse_NumeroVoie': '',
233
                'Adresse_Extension': '',
234
                'Adresse_NomVoie': '',
235
                'Adresse_CodeSTI': '',
236
                'Adresse_BoitePostaleLieudit': '',
237
                'Adresse_CodePostal': '',
238
                'Adresse_Localite': '',
239
                'Adresse_Quartier': '',
240
            }
241
        },
242
    )
243
    soap_mock.add_soap_response(
244
        'PLS_ELIGADR',
245
        {
246
            'PLS_ELIGADRResult': {
247
                'CodeRetour': '01',
248
                'MessageRetour': 'Elligible',
249
                'Adresse_EtageEscalierAppartement': '',
250
                'Adresse_ImmeubleBatimentResidence': '',
251
                'Adresse_NumeroVoie': '13',
252
                'Adresse_Extension': '1',
253
                'Adresse_NomVoie': 'Rue des Abeilles',
254
                'Adresse_CodeSTI': '315550016038',
255
                'Adresse_BoitePostaleLieudit': '',
256
                'Adresse_CodePostal': '31000',
257
                'Adresse_Localite': 'Toulouse',
258
                'Adresse_Quartier': 'Dupuy',
259
            }
260
        },
261
    )
140 262

  
141
def test_search(dpark, app):
142
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
143
        params = {
144
            'lastname': 'bar',
145
            'firstnames': 'foo',
146
            'filenumber': '1' * 9,
147
            'cardnumber': '3' * 9,
148
        }
149
        # missing lastname
150
        app.get('/dpark/test/search/', params={'firstnames': 'toto'}, status=400)
151
        # unknown file
152
        client.return_value = get_client(replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'})
153
        resp = app.get('/dpark/test/search/', params=params)
154
        assert resp.json['err'] == 1
155
        assert resp.json['code'] == 'unknown-file'
156
        # invalid cardnumber
157
        client.return_value = get_client(
158
            replydata={'CodeRetour': '04', 'MessageRetour': 'Numéro de support inconnu'}
159
        )
160
        resp = app.get('/dpark/test/search/', params=params)
161
        assert resp.json['err'] == 1
162
        assert resp.json['code'] == 'support-number-unknown'
163
        # valid data
164
        client.return_value = get_client(replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'})
165
        resp = app.get('/dpark/test/search/', params=params)
166
        assert resp.json['err'] == 0
167

  
168

  
169
def test_link(dpark, app):
170
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
171
        params = {
172
            'lastname': 'bar ',
173
            'firstnames': ' foo',
174
            'filenumber': ' ' + '1' * 9,
175
        }
176
        # missing nameid
177
        app.post_json('/dpark/test/link/', params=params, status=400)
178
        params['nameid'] = 'abcd' * 8
179
        # unknown file
180
        client.return_value = get_client(replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'})
181
        resp = app.post_json('/dpark/test/link/', params=params)
182
        assert resp.json['err'] == 1
183
        assert resp.json['code'] == 'unknown-file'
184
        # invalid cardnumber
185
        client.return_value = get_client(
186
            replydata={'CodeRetour': '04', 'MessageRetour': 'Numéro de support inconnu'}
187
        )
188
        resp = app.post_json('/dpark/test/link/', params=params)
189
        assert resp.json['err'] == 1
190
        assert resp.json['code'] == 'support-number-unknown'
191
        # valid data
192
        client.return_value = get_client(replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'})
193
        resp = app.post_json('/dpark/test/link/', params=params)
194
        assert resp.json['err'] == 0
195
        assert Pairing.objects.count() == 1
196
        pairing = Pairing.objects.get(resource=dpark)
197
        assert pairing.nameid == 'abcd' * 8
198
        assert pairing.filenumber == '1' * 9
199
        assert pairing.firstnames == 'foo'
200
        assert pairing.lastname == 'bar'
201

  
202

  
203
def test_unlink(dpark, app):
204
    with mock.patch('passerelle.contrib.dpark.models.get_client', get_client()):
205
        nameid = 'abcd' * 8
206
        params = {'nameid': nameid}
207
        # missing nameid
208
        app.post_json('/dpark/test/unlink/', params={}, status=400)
209
        # no pairing exists
210
        resp = app.post_json('/dpark/test/unlink/', params=params)
211
        assert resp.json['err'] == 1
212
        assert resp.json['err_desc'] == 'No pairing exists'
213
        # pairing exist
214
        Pairing.objects.create(
215
            resource=dpark,
216
            nameid=nameid,
217
            lastname='bar',
218
            firstnames='foo',
219
            filenumber='1' * 9,
220
            badgenumber='2' * 9,
221
            cardnumber='3' * 9,
222
        )
223
        resp = app.post_json('/dpark/test/unlink/', params=params)
224
        assert resp.json['data'] is True
225
        assert Pairing.objects.count() == 0
226

  
227

  
228
def test_address_eligibility(dpark, app):
229 263
    params = {'address_sticode': '315553637461', 'address_zipcode': '44000'}
230 264
    # missing required parameter
231 265
    app.get('/dpark/test/address-eligibility/', params=params, status=400)
232 266
    # not eligible
233
    dpark.mock_responses.append(
234
        make_response(
235
            'ELIGADR',
236
            (
237
                ('CodeRetour', '99'),
238
                ('MessageRetour', 'Erreur extension'),
239
            ),
240
        )
241
    )
242 267
    params['address_locality'] = 'Nantes'
243 268
    resp = app.get('/dpark/test/address-eligibility/', params=params)
244 269
    assert resp.json['err'] == 1
245 270
    assert resp.json['err_desc'] == 'Erreur extension'
246 271
    # eligible
247
    dpark.mock_responses.append(
248
        make_response(
249
            'ELIGADR',
250
            (
251
                ('CodeRetour', '01'),
252
                ('MessageRetour', 'Elligible'),
253
                ('Adresse_EtageEscalierAppartement', ''),
254
                ('Adresse_ImmeubleBatimentResidence', ''),
255
                ('Adresse_NumeroVoie', '13'),
256
                ('Adresse_Extension', '1'),
257
                ('Adresse_NomVoie', 'Rue des Abeilles'),
258
                ('Adresse_CodeSTI', '315550016038'),
259
                ('Adresse_BoitePostaleLieudit', ''),
260
                ('Adresse_CodePostal', '31000'),
261
                ('Adresse_Localite', 'Toulouse'),
262
                ('Adresse_Quartier', 'Dupuy'),
263
            ),
264
        )
265
    )
266 272
    params['address_streetext'] = 1
267 273
    resp = app.get('/dpark/test/address-eligibility/', params=params)
268 274
    content = resp.json
......
271 277
    assert content['address']['address_locality'] == 'Toulouse'
272 278

  
273 279

  
274
def test_subscriber_infos(dpark, app):
275
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
276
        nameid = 'abcd' * 8
277
        url = '/dpark/test/infos/%s/' % nameid
278
        params = {
279
            'nameid': nameid,
280
            'firstnames': 'spam eggs',
281
            'lastname': 'bar',
282
            'filenumber': '1' * 9,
283
            'badgenumber': '2' * 9,
284
        }
285
        Pairing.objects.create(resource=dpark, **params)
286
        # unknown subscriber
287
        resp = app.get('/dpark/test/infos/toto/')
288
        assert resp.json['data'] == []
289
        # unknown file
290
        client.return_value = get_client(replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'})
291
        resp = app.get(url)
292
        assert resp.json['data'] == []
293
        # known file
294
        replydata = {
295
            'CodeRetour': '01',
296
            'MessageRetour': 'Dossier existant',
297
            "Adresse_BoitePostaleLieuDit": None,
298
            "Adresse_CodePostal": "44000",
299
            "Adresse_CodeSTI": "315553609651",
300
            "Adresse_EtageEscalierAppartement": None,
301
            "Adresse_Extension": 1,
302
            "Adresse_ImmeubleBatimentResidence": None,
303
            "Adresse_Localite": "Nantes",
304
            "Adresse_NomVoie": "All\u00e9es Jean Jaur\u00e8s",
305
            "Adresse_NumeroVoie": 80,
306
            "Adresse_Quartier": "PERI",
307
            "Demande_DateDebutAbo": "20180625",
308
            "Demande_DateFinAbo": "20190624",
309
            "Demande_DelaiAutorise": 30,
310
            "Demande_ImmatVehicule1": "CX453AD",
311
            "Demande_ImmatVehicule2": None,
312
            "Demande_MarqueVehicule1": "CITROEN",
313
            "Demande_MarqueVehicule2": None,
314
            "Demande_ModeleVehicule1": "GS",
315
            "Demande_ModeleVehicule2": None,
316
            "Demande_NumeroDossier": 22952,
317
            "Demandeur_Civilite": 1,
318
            "Demandeur_Email": "spameggs@example.net",
319
            "Demandeur_NomUsuel": "BAR",
320
            "Demandeur_Prenom": "Foo Spam",
321
            "Demandeur_TelephoneFixe": "0611111111",
322
            "Demandeur_TelephonePortable": None,
323
        }
324
        client.return_value = get_client(replydata=replydata)
325
        resp = app.get(url)
326
        data = resp.json['data']
327
        assert data[0]['id'] == '22952'
328
        assert data[0]['text'] == '22952 - BAR Foo Spam - CX453AD'
329
        assert data[0]['adresse_codepostal'] == '44000'
330
        assert data[0]['adresse_codesti'] == '315553609651'
331
        assert data[0]['adresse_localite'] == 'Nantes'
332
        assert data[0]['demande_numerodossier'] == 22952
333
        assert data[0]['demandeur_email'] == 'spameggs@example.net'
334
        assert data[0]['demandeur_telephonefixe'] == '0611111111'
335
        assert data[0]['demande_datedebutabo'] == '2018-06-25'
336
        assert data[0]['demande_datefinabo'] == '2019-06-24'
337

  
338
        # mutiple pairing
339
        Pairing.objects.create(
340
            resource=dpark,
341
            nameid=nameid,
342
            firstnames='monty',
343
            lastname='eggs',
344
            filenumber='5' * 9,
345
            badgenumber='6' * 9,
346
            cardnumber='7' * 9,
347
        )
348
        replydata2 = {
349
            'CodeRetour': '01',
350
            'MessageRetour': 'Dossier existant',
351
            "Adresse_BoitePostaleLieuDit": None,
352
            "Adresse_CodePostal": "94000",
353
            "Adresse_CodeSTI": "315553609651",
354
            "Adresse_EtageEscalierAppartement": None,
355
            "Adresse_Extension": 1,
356
            "Adresse_ImmeubleBatimentResidence": None,
357
            "Adresse_Localite": "Creteil",
358
            "Adresse_NomVoie": "Allée les sablons",
359
            "Adresse_NumeroVoie": 5,
360
            "Adresse_Quartier": "HOOLI",
361
            "Demande_DateDebutAbo": "20180430",
362
            "Demande_DateFinAbo": None,
363
            "Demande_DelaiAutorise": 30,
364
            "Demande_ImmatVehicule1": "AA555BB",
365
            "Demande_ImmatVehicule2": "XX333YY",
366
            "Demande_MarqueVehicule1": "FORD",
367
            "Demande_MarqueVehicule2": "MERCEDES",
368
            "Demande_ModeleVehicule1": "Fiesta",
369
            "Demande_ModeleVehicule2": "Serie A",
370
            "Demande_NumeroDossier": 22955,
371
            "Demandeur_Civilite": 1,
372
            "Demandeur_Email": "spameggs@example.net",
373
            "Demandeur_NomUsuel": "EGGS",
374
            "Demandeur_Prenom": "Monty",
375
            "Demandeur_TelephoneFixe": "0611111111",
376
            "Demandeur_TelephonePortable": None,
377
        }
378
        # there will be only one call as first pairing is now cached
379
        client.side_effect = [get_client(replydata=replydata2)]
380
        resp = app.get(url)
381
        data = resp.json['data']
382
        assert len(data) == 2
383
        assert data[1]['id'] == '22955'
384
        assert data[1]['text'] == '22955 - EGGS Monty - AA555BB/XX333YY'
385
        assert data[1]['adresse_codepostal'] == '94000'
386
        assert data[1]['adresse_codesti'] == '315553609651'
387
        assert data[1]['adresse_localite'] == 'Creteil'
388
        assert data[1]['demande_numerodossier'] == 22955
389
        assert data[1]['demandeur_email'] == 'spameggs@example.net'
390
        assert data[1]['demandeur_telephonefixe'] == '0611111111'
391
        assert data[1]['demande_datedebutabo'] == '2018-04-30'
392
        assert data[1]['demande_datefinabo'] is None
393

  
394
        # filtering by filenumber
395
        for pairing in Pairing.objects.all():
396
            pairing.clear_cache()
397
        # we modify numerodossier to verify cache is not used
398
        replydata['Demande_NumeroDossier'] = 22953
399
        client.side_effect = [
400
            get_client(replydata=replydata),
401
        ]
402
        resp = app.get(url, params={'filenumber': '1' * 9})
403
        data = resp.json['data']
404
        assert len(data) == 1
405
        assert data[0]['id'] == '22953'
406
        assert data[0]['text'] == '22953 - BAR Foo Spam - CX453AD'
407
        assert data[0]['adresse_codepostal'] == '44000'
408
        assert data[0]['adresse_codesti'] == '315553609651'
409
        assert data[0]['adresse_localite'] == 'Nantes'
410
        assert data[0]['demande_numerodossier'] == 22953
411
        assert data[0]['demandeur_email'] == 'spameggs@example.net'
412
        assert data[0]['demandeur_telephonefixe'] == '0611111111'
413
        assert data[0]['demande_datedebutabo'] == '2018-06-25'
414
        assert data[0]['demande_datefinabo'] == '2019-06-24'
415

  
416

  
417
def test_check_renewal_time(dpark, app):
418
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
419
        url = '/dpark/test/check-renewal-time/'
420
        params = {'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': '1' * 9, 'badgenumber': '2' * 9}
421
        client.return_value = get_client(
422
            replydata={'CodeRetour': '02', 'MessageRetour': 'Renouvellement hors délai'}
423
        )
424
        resp = app.get(url, params=params)
425
        assert resp.json['data'] is False
426
        assert resp.json['desc'] == 'Renouvellement hors délai'
427
        client.return_value = get_client(replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'})
428
        resp = app.get(url, params=params)
429
        assert resp.json['data'] is True
430

  
431

  
432
def test_check_renewal_duplicate(dpark, app):
433
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
434
        url = '/dpark/test/check-renewal-time/'
435
        params = {'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': '1' * 9, 'badgenumber': '2' * 9}
436
        client.return_value = get_client(
437
            replydata={'CodeRetour': '02', 'MessageRetour': 'Demande déjà en cours'}
438
        )
439
        resp = app.get(url, params=params)
440
        assert resp.json['data'] is False
441
        assert resp.json['desc'] == 'Demande déjà en cours'
442
        client.return_value = get_client(replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'})
443
        resp = app.get(url, params=params)
444
        assert resp.json['data'] is True
445
        assert resp.json['err'] == 0
446

  
447

  
448
def test_check_creation_duplicate(dpark, app):
449
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
450
        url = '/dpark/test/check-creation-duplicate/'
451
        params = {
452
            'address_district': 'PERI',
453
            'address_locality': 'Toulouse',
454
            'address_sticode': '315553609651',
455
            'address_streetext': '1',
456
            'address_zipcode': '31000',
457
            'applicant_firstnames': 'Spam',
458
            'applicant_lastname': 'Ham',
459
        }
460
        client.return_value = get_client(
461
            replydata={'CodeRetour': '02', 'MessageRetour': 'Demande déjà en cours'}
462
        )
463
        resp = app.get(url, params=params)
464
        assert resp.json['data'] is False
465
        assert resp.json['desc'] == 'Demande déjà en cours'
466
        client.return_value = get_client(replydata={'CodeRetour': '01', 'MessageRetour': ''})
467
        resp = app.get(url, params=params)
468
        assert resp.json['data'] is True
469
        assert resp.json['err'] == 0
470

  
471

  
472
def test_check_creation_not_renewal(dpark, app):
473
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
474
        url = '/dpark/test/check-creation-not-renewal/'
475
        params = {
476
            'address_district': 'PERI',
477
            'address_locality': 'Toulouse',
478
            'address_sticode': '315553609651',
479
            'address_streetext': '1',
480
            'address_zipcode': '31000',
481
            'applicant_firstnames': 'Spam',
482
            'applicant_lastname': 'Ham',
483
        }
484
        client.return_value = get_client(
485
            replydata={'CodeRetour': '02', 'MessageRetour': 'Usager existe déjà dans D-Park'}
486
        )
487
        resp = app.get(url, params=params)
488
        assert resp.json['data'] is False
489
        assert resp.json['desc'] == 'Usager existe déjà dans D-Park'
490
        client.return_value = get_client(replydata={'CodeRetour': '01', 'MessageRetour': ''})
491
        resp = app.get(url, params=params)
492
        assert resp.json['data'] is True
493

  
494

  
495
def test_get_payment_infos(dpark, app):
496
    with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
497
        nameid = 'abcd' * 8
498
        url = '/dpark/test/payment-info/%s/' % nameid
499
        resp = app.get(url)
500
        assert resp.json['err'] == 1
501
        assert resp.json['err_desc'] == 'No pairing exists'
502
        params = {
503
            'nameid': nameid,
504
            'firstnames': 'spam eggs',
505
            'lastname': 'bar',
506
            'filenumber': '1' * 9,
507
            'badgenumber': '2' * 9,
508
        }
509
        Pairing.objects.create(resource=dpark, **params)
510
        client.return_value = get_client(replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'})
511
        resp = app.get(url)
512
        assert resp.json['err'] == 0
513
        assert resp.json['data'] == []
514
        replydata = {
515
            'CodeRetour': '01',
516
            'MessageRetour': 'Demande acceptée',
517
            'NumeroDemande': '55555',
518
            'Montant': 12500,
519
            'TypePaiement': 10,
520
            'NumeroTeledossierPhase1': 'E-8-0AA666BB',
521
        }
522
        client.return_value = get_client(replydata=replydata)
523
        resp = app.get(url)
524
        data = resp.json['data'][0]
525
        assert data['montant'] == 125
526
        assert data['typepaiement'] == 10
527
        assert data['typepaiement_text'] == 'Carte Bancaire via Internet'
528
        assert data['numerodemande'] == '55555'
280
def test_subscriber_infos(dpark, app, get_service):
281
    nameid = 'abcd' * 8
282
    url = '/dpark/test/infos/%s/' % nameid
283
    params = {
284
        'nameid': nameid,
285
        'firstnames': 'spam eggs',
286
        'lastname': 'bar',
287
        'filenumber': '1' * 9,
288
        'badgenumber': '2' * 9,
289
    }
290
    Pairing.objects.create(resource=dpark, **params)
291
    # unknown subscriber
292
    resp = app.get('/dpark/test/infos/toto/')
293
    assert resp.json['data'] == []
294
    # unknown file
295
    get_service.return_value = MockedService(
296
        replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'}
297
    )
298
    resp = app.get(url)
299
    assert resp.json['data'] == []
300
    # known file
301
    replydata = {
302
        'CodeRetour': '01',
303
        'MessageRetour': 'Dossier existant',
304
        "Adresse_BoitePostaleLieuDit": None,
305
        "Adresse_CodePostal": "44000",
306
        "Adresse_CodeSTI": "315553609651",
307
        "Adresse_EtageEscalierAppartement": None,
308
        "Adresse_Extension": 1,
309
        "Adresse_ImmeubleBatimentResidence": None,
310
        "Adresse_Localite": "Nantes",
311
        "Adresse_NomVoie": "All\u00e9es Jean Jaur\u00e8s",
312
        "Adresse_NumeroVoie": 80,
313
        "Adresse_Quartier": "PERI",
314
        "Demande_DateDebutAbo": "20180625",
315
        "Demande_DateFinAbo": "20190624",
316
        "Demande_DelaiAutorise": 30,
317
        "Demande_ImmatVehicule1": "CX453AD",
318
        "Demande_ImmatVehicule2": None,
319
        "Demande_MarqueVehicule1": "CITROEN",
320
        "Demande_MarqueVehicule2": None,
321
        "Demande_ModeleVehicule1": "GS",
322
        "Demande_ModeleVehicule2": None,
323
        "Demande_NumeroDossier": 22952,
324
        "Demandeur_Civilite": 1,
325
        "Demandeur_Email": "spameggs@example.net",
326
        "Demandeur_NomUsuel": "BAR",
327
        "Demandeur_Prenom": "Foo Spam",
328
        "Demandeur_TelephoneFixe": "0611111111",
329
        "Demandeur_TelephonePortable": None,
330
    }
331
    get_service.return_value = MockedService(replydata=replydata)
332
    resp = app.get(url)
333
    data = resp.json['data']
334
    assert data[0]['id'] == '22952'
335
    assert data[0]['text'] == '22952 - BAR Foo Spam - CX453AD'
336
    assert data[0]['adresse_codepostal'] == '44000'
337
    assert data[0]['adresse_codesti'] == '315553609651'
338
    assert data[0]['adresse_localite'] == 'Nantes'
339
    assert data[0]['demande_numerodossier'] == 22952
340
    assert data[0]['demandeur_email'] == 'spameggs@example.net'
341
    assert data[0]['demandeur_telephonefixe'] == '0611111111'
342
    assert data[0]['demande_datedebutabo'] == '2018-06-25'
343
    assert data[0]['demande_datefinabo'] == '2019-06-24'
344

  
345
    # mutiple pairing
346
    Pairing.objects.create(
347
        resource=dpark,
348
        nameid=nameid,
349
        firstnames='monty',
350
        lastname='eggs',
351
        filenumber='5' * 9,
352
        badgenumber='6' * 9,
353
        cardnumber='7' * 9,
354
    )
355
    replydata2 = {
356
        'CodeRetour': '01',
357
        'MessageRetour': 'Dossier existant',
358
        "Adresse_BoitePostaleLieuDit": None,
359
        "Adresse_CodePostal": "94000",
360
        "Adresse_CodeSTI": "315553609651",
361
        "Adresse_EtageEscalierAppartement": None,
362
        "Adresse_Extension": 1,
363
        "Adresse_ImmeubleBatimentResidence": None,
364
        "Adresse_Localite": "Creteil",
365
        "Adresse_NomVoie": "Allée les sablons",
366
        "Adresse_NumeroVoie": 5,
367
        "Adresse_Quartier": "HOOLI",
368
        "Demande_DateDebutAbo": "20180430",
369
        "Demande_DateFinAbo": None,
370
        "Demande_DelaiAutorise": 30,
371
        "Demande_ImmatVehicule1": "AA555BB",
372
        "Demande_ImmatVehicule2": "XX333YY",
373
        "Demande_MarqueVehicule1": "FORD",
374
        "Demande_MarqueVehicule2": "MERCEDES",
375
        "Demande_ModeleVehicule1": "Fiesta",
376
        "Demande_ModeleVehicule2": "Serie A",
377
        "Demande_NumeroDossier": 22955,
378
        "Demandeur_Civilite": 1,
379
        "Demandeur_Email": "spameggs@example.net",
380
        "Demandeur_NomUsuel": "EGGS",
381
        "Demandeur_Prenom": "Monty",
382
        "Demandeur_TelephoneFixe": "0611111111",
383
        "Demandeur_TelephonePortable": None,
384
    }
385
    # there will be only one call as first pairing is now cached
386
    get_service.side_effect = [MockedService(replydata=replydata2)]
387
    resp = app.get(url)
388
    data = resp.json['data']
389
    assert len(data) == 2
390
    assert data[1]['id'] == '22955'
391
    assert data[1]['text'] == '22955 - EGGS Monty - AA555BB/XX333YY'
392
    assert data[1]['adresse_codepostal'] == '94000'
393
    assert data[1]['adresse_codesti'] == '315553609651'
394
    assert data[1]['adresse_localite'] == 'Creteil'
395
    assert data[1]['demande_numerodossier'] == 22955
396
    assert data[1]['demandeur_email'] == 'spameggs@example.net'
397
    assert data[1]['demandeur_telephonefixe'] == '0611111111'
398
    assert data[1]['demande_datedebutabo'] == '2018-04-30'
399
    assert data[1]['demande_datefinabo'] is None
400

  
401
    # filtering by filenumber
402
    for pairing in Pairing.objects.all():
403
        pairing.clear_cache()
404
    # we modify numerodossier to verify cache is not used
405
    replydata['Demande_NumeroDossier'] = 22953
406
    get_service.side_effect = [
407
        MockedService(replydata=replydata),
408
    ]
409
    resp = app.get(url, params={'filenumber': '1' * 9})
410
    data = resp.json['data']
411
    assert len(data) == 1
412
    assert data[0]['id'] == '22953'
413
    assert data[0]['text'] == '22953 - BAR Foo Spam - CX453AD'
414
    assert data[0]['adresse_codepostal'] == '44000'
415
    assert data[0]['adresse_codesti'] == '315553609651'
416
    assert data[0]['adresse_localite'] == 'Nantes'
417
    assert data[0]['demande_numerodossier'] == 22953
418
    assert data[0]['demandeur_email'] == 'spameggs@example.net'
419
    assert data[0]['demandeur_telephonefixe'] == '0611111111'
420
    assert data[0]['demande_datedebutabo'] == '2018-06-25'
421
    assert data[0]['demande_datefinabo'] == '2019-06-24'
422

  
423

  
424
def test_check_renewal_time(dpark, app, get_service):
425
    url = '/dpark/test/check-renewal-time/'
426
    params = {'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': '1' * 9, 'badgenumber': '2' * 9}
427
    get_service.return_value = MockedService(
428
        replydata={'CodeRetour': '02', 'MessageRetour': 'Renouvellement hors délai'}
429
    )
430
    resp = app.get(url, params=params)
431
    assert resp.json['data'] is False
432
    assert resp.json['desc'] == 'Renouvellement hors délai'
433
    get_service.return_value = MockedService(
434
        replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'}
435
    )
436
    resp = app.get(url, params=params)
437
    assert resp.json['data'] is True
438

  
439

  
440
def test_check_renewal_duplicate(dpark, app, get_service):
441
    url = '/dpark/test/check-renewal-time/'
442
    params = {'firstnames': 'spam eggs', 'lastname': 'bar', 'filenumber': '1' * 9, 'badgenumber': '2' * 9}
443
    get_service.return_value = MockedService(
444
        replydata={'CodeRetour': '02', 'MessageRetour': 'Demande déjà en cours'}
445
    )
446
    resp = app.get(url, params=params)
447
    assert resp.json['data'] is False
448
    assert resp.json['desc'] == 'Demande déjà en cours'
449
    get_service.return_value = MockedService(
450
        replydata={'CodeRetour': '01', 'MessageRetour': 'Dossier existant'}
451
    )
452
    resp = app.get(url, params=params)
453
    assert resp.json['data'] is True
454
    assert resp.json['err'] == 0
455

  
456

  
457
def test_check_creation_duplicate(dpark, app, get_service):
458
    url = '/dpark/test/check-creation-duplicate/'
459
    params = {
460
        'address_district': 'PERI',
461
        'address_locality': 'Toulouse',
462
        'address_sticode': '315553609651',
463
        'address_streetext': '1',
464
        'address_zipcode': '31000',
465
        'applicant_firstnames': 'Spam',
466
        'applicant_lastname': 'Ham',
467
    }
468
    get_service.return_value = MockedService(
469
        replydata={'CodeRetour': '02', 'MessageRetour': 'Demande déjà en cours'}
470
    )
471
    resp = app.get(url, params=params)
472
    assert resp.json['data'] is False
473
    assert resp.json['desc'] == 'Demande déjà en cours'
474
    get_service.return_value = MockedService(replydata={'CodeRetour': '01', 'MessageRetour': ''})
475
    resp = app.get(url, params=params)
476
    assert resp.json['data'] is True
477
    assert resp.json['err'] == 0
478

  
479

  
480
def test_check_creation_not_renewal(dpark, app, get_service):
481
    url = '/dpark/test/check-creation-not-renewal/'
482
    params = {
483
        'address_district': 'PERI',
484
        'address_locality': 'Toulouse',
485
        'address_sticode': '315553609651',
486
        'address_streetext': '1',
487
        'address_zipcode': '31000',
488
        'applicant_firstnames': 'Spam',
489
        'applicant_lastname': 'Ham',
490
    }
491
    get_service.return_value = MockedService(
492
        replydata={'CodeRetour': '02', 'MessageRetour': 'Usager existe déjà dans D-Park'}
493
    )
494
    resp = app.get(url, params=params)
495
    assert resp.json['data'] is False
496
    assert resp.json['desc'] == 'Usager existe déjà dans D-Park'
497
    get_service.return_value = MockedService(replydata={'CodeRetour': '01', 'MessageRetour': ''})
498
    resp = app.get(url, params=params)
499
    assert resp.json['data'] is True
500

  
501

  
502
def test_get_payment_infos(dpark, app, get_service):
503
    nameid = 'abcd' * 8
504
    url = '/dpark/test/payment-info/%s/' % nameid
505
    resp = app.get(url)
506
    assert resp.json['err'] == 1
507
    assert resp.json['err_desc'] == 'No pairing exists'
508
    params = {
509
        'nameid': nameid,
510
        'firstnames': 'spam eggs',
511
        'lastname': 'bar',
512
        'filenumber': '1' * 9,
513
        'badgenumber': '2' * 9,
514
    }
515
    Pairing.objects.create(resource=dpark, **params)
516
    get_service.return_value = MockedService(
517
        replydata={'CodeRetour': '02', 'MessageRetour': 'Dossier inconnu'}
518
    )
519
    resp = app.get(url)
520
    assert resp.json['err'] == 0
521
    assert resp.json['data'] == []
522
    replydata = {
523
        'CodeRetour': '01',
524
        'MessageRetour': 'Demande acceptée',
525
        'NumeroDemande': '55555',
526
        'Montant': 12500,
527
        'TypePaiement': 10,
528
        'NumeroTeledossierPhase1': 'E-8-0AA666BB',
529
    }
530
    get_service.return_value = MockedService(replydata=replydata)
531
    resp = app.get(url)
532
    data = resp.json['data'][0]
533
    assert data['montant'] == 125
534
    assert data['typepaiement'] == 10
535
    assert data['typepaiement_text'] == 'Carte Bancaire via Internet'
536
    assert data['numerodemande'] == '55555'
529 537

  
530 538

  
531 539
@pytest.mark.parametrize(
......
536 544
        ('2018-06-11T23:59:00', '20180612'),
537 545
    ],
538 546
)
539
def test_payment_notification(dpark, app, transaction_datetime, expected_date):
547
def test_payment_notification(dpark, app, transaction_datetime, expected_date, get_service):
540 548
    operation = mock.Mock(name='PLS_NOTIFCB')
541 549
    service = mock.Mock(spec=['PLS_NOTIFCB'], PLS_NOTIFCB=operation)
542
    create_service = mock.Mock(spec=[], return_value=service)
543
    client = mock.NonCallableMock(spec=['create_service'], create_service=create_service)
544
    with mock.patch('passerelle.contrib.dpark.models.get_client', return_value=client):
545
        nameid = 'abcd' * 8
546
        filenumber = '1' * 9
547
        params = {
550
    get_service.return_value = service
551

  
552
    nameid = 'abcd' * 8
553
    filenumber = '1' * 9
554
    params = {
555
        'nameid': nameid,
556
        'filenumber': filenumber,
557
        'transaction_id': 'I123456789',
558
        'transaction_datetime': transaction_datetime,
559
        'total_amount': '125',
560
        'application_id': '61718',
561
        'application_external_id': 'E-8-N5UTAK6P',
562
    }
563
    url = '/dpark/test/notify-payment/'
564
    resp = app.post_json(url, params=params)
565
    assert resp.json['err'] == 1
566
    assert resp.json['err_desc'] == 'No pairing exists'
567
    Pairing.objects.create(
568
        resource=dpark,
569
        **{
548 570
            'nameid': nameid,
571
            'firstnames': 'spam eggs',
572
            'lastname': 'bar',
549 573
            'filenumber': filenumber,
550
            'transaction_id': 'I123456789',
551
            'transaction_datetime': transaction_datetime,
552
            'total_amount': '125',
553
            'application_id': '61718',
554
            'application_external_id': 'E-8-N5UTAK6P',
555
        }
556
        url = '/dpark/test/notify-payment/'
557
        resp = app.post_json(url, params=params)
558
        assert resp.json['err'] == 1
559
        assert resp.json['err_desc'] == 'No pairing exists'
560
        Pairing.objects.create(
561
            resource=dpark,
562
            **{
563
                'nameid': nameid,
564
                'firstnames': 'spam eggs',
565
                'lastname': 'bar',
566
                'filenumber': filenumber,
567
                'badgenumber': '2' * 9,
568
            },
569
        )
570
        operation.return_value = mock.Mock(CodeRetour='02', MessageRetour='Dossier inconnu')
571
        resp = app.post_json(url, params=params)
572
        assert operation.call_args_list[-1].args[5] == expected_date
573
        assert resp.json['err'] == 1
574
        assert resp.json['err_desc'] == 'Dossier inconnu'
575
        operation.return_value = mock.Mock(CodeRetour='01')
576
        resp = app.post_json(url, params=params)
577
        assert resp.json['data'] is True
574
            'badgenumber': '2' * 9,
575
        },
576
    )
577
    operation.return_value = mock.Mock(CodeRetour='02', MessageRetour='Dossier inconnu')
578
    resp = app.post_json(url, params=params)
579
    assert operation.call_args_list[-1].args[5] == expected_date
580
    assert resp.json['err'] == 1
581
    assert resp.json['err_desc'] == 'Dossier inconnu'
582
    operation.return_value = mock.Mock(CodeRetour='01')
583
    resp = app.post_json(url, params=params)
584
    assert resp.json['data'] is True
578 585

  
579 586

  
580 587
@pytest.mark.parametrize('application_thirdparty_subscription', [True, False])
581
def test_registration(dpark, app, application_thirdparty_subscription):
588
def test_registration(dpark, app, application_thirdparty_subscription, soap_mock):
589
    soap_mock.add_soap_response(
590
        'PLS_ENREG',
591
        {
592
            'PLS_ENREGResult': {
593
                'CodeRetour': '02',
594
                'MessageRetour': 'Dossier incomplet',
595
                'NumeroDossier': 0,
596
                'NumeroDemande': 0,
597
            }
598
        },
599
    )
600

  
601
    soap_mock.add_soap_response(
602
        'PLS_ENREG',
603
        {
604
            'PLS_ENREGResult': {
605
                'CodeRetour': '01',
606
                'MessageRetour': '',
607
                'NumeroDossier': 22334,
608
                'NumeroDemande': 59492,
609
            }
610
        },
611
    )
612

  
582 613
    url = '/dpark/test/register/'
583 614
    params = {
584 615
        "address_complement1": "",
......
607 638
    # with missing parameter
608 639
    app.post_json(url, params=params, status=400)
609 640
    params['address_district'] = "PERI"
610
    # with an imcplete application
611
    dpark.mock_responses.append(
612
        """<?xml version="1.0" encoding="utf-8"?>
613
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
614
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
615
  <SOAP-ENV:Header/>
616
  <SOAP-ENV:Body>
617
    <ns1:PLS_ENREGResponse xmlns:ns1="urn:Webservice_Residants">
618
      <PLS_ENREGResult>
619
        <CodeRetour>02</CodeRetour>
620
        <MessageRetour>Dossier incomplet</MessageRetour>
621
      </PLS_ENREGResult>
622
    </ns1:PLS_ENREGResponse>
623
  </SOAP-ENV:Body>
624
</SOAP-ENV:Envelope>"""
625
    )
641

  
642
    # with an incomplete application
626 643
    resp = app.post_json(url, params=params)
627
    demande_abonnementtiers = (
628
        '<Demande_AbonnementTiers>%s</Demande_AbonnementTiers>'
629
        % repr(application_thirdparty_subscription).lower()
630
    )
631
    body = dpark.mock_requests[0].body.decode()
632
    assert ':PLS_ENREG ' in body
633
    assert demande_abonnementtiers in body
634 644
    assert resp.json['err'] == 1
635 645
    assert resp.json['err_desc'] == 'Dossier incomplet'
646

  
647
    soap_request = soap_mock.soap_requests[0]
648
    assert type(soap_request).__name__ == 'tPLS_ENREG'
649
    assert soap_request.Entree_Demande.Demande_AbonnementTiers is application_thirdparty_subscription
650

  
636 651
    # with complete application
637
    dpark.mock_responses.append(
638
        """<?xml version="1.0" encoding="utf-8"?>
639
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
640
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
641
  <SOAP-ENV:Header/>
642
  <SOAP-ENV:Body>
643
    <ns1:PLS_ENREGResponse xmlns:ns1="urn:Webservice_Residants">
644
      <PLS_ENREGResult>
645
        <CodeRetour>01</CodeRetour>
646
        <MessageRetour/>
647
        <NumeroDossier>22334</NumeroDossier>
648
        <NumeroDemande>59492</NumeroDemande>
649
      </PLS_ENREGResult>
650
    </ns1:PLS_ENREGResponse>
651
  </SOAP-ENV:Body>
652
</SOAP-ENV:Envelope>"""
653
    )
654 652
    resp = app.post_json(url, params=params)
655
    assert demande_abonnementtiers in force_str(dpark.mock_requests[1].body)
653
    soap_request = soap_mock.soap_requests[1]
656 654
    assert resp.json['data']['numerodossier'] == 22334
657 655
    assert resp.json['data']['numerodemande'] == 59492
658 656

  
657
    assert type(soap_request).__name__ == 'tPLS_ENREG'
658
    assert soap_request.Entree_Demande.Demande_AbonnementTiers is application_thirdparty_subscription
659

  
659 660

  
660 661
# we need to freeze_time as Pillow (used by to_pdf()) embed the current time in
661 662
# the produced PDF, so to get some deterministic behaviour it's needed to
662 663
# freeze the time.
663
def test_send_files(dpark, app, settings, freezer):
664
def test_send_files(dpark, app, soap_mock, settings, freezer):
664 665
    params = {'application_external_id': 'E-8-N5UTAK6P'}
665 666
    with mock.patch('passerelle.contrib.dpark.models.DPark.call') as soap_call:
666 667
        url = '/dpark/test/send-files/'
......
716 717

  
717 718
    # add custom document type
718 719
    settings.DPARK_DOCUMENT_CODES = {'toto': '73'}
719
    response = """<?xml version="1.0" encoding="utf-8"?>
720
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
721
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
722
  <SOAP-ENV:Header/>
723
  <SOAP-ENV:Body>
724
    <ns1:PLS_ENVOIPJResponse xmlns:ns1="urn:Webservice_Residants">
725
      <PLS_ENVOIPJResult>
726
        <CodeRetour>01</CodeRetour>
727
        <MessageRetour/>
728
      </PLS_ENVOIPJResult>
729
    </ns1:PLS_ENVOIPJResponse>
730
  </SOAP-ENV:Body>
731
</SOAP-ENV:Envelope>"""
732

  
733
    dpark.mock_responses.append(response)
720
    soap_mock.add_soap_response(
721
        'PLS_ENVOIPJ',
722
        {
723
            'PLS_ENVOIPJResult': {
724
                'CodeRetour': '01',
725
                'MessageRetour': '',
726
            }
727
        },
728
    )
734 729
    resp = app.post_json(url, params=params)
735 730
    assert resp.json['err'] == 0
736 731
    assert resp.json['data'] is True
737
    assert len(dpark.mock_requests) == 1
738
    root = ET.fromstring(dpark.mock_requests[0].body)
739
    pj_node = root.find(
740
        '{http://schemas.xmlsoap.org/soap/envelope/}Body/{urn:Webservice_Residants}PLS_ENVOIPJ'
741
    )
742
    assert pj_node.find('NumeroTeledossier').text == 'E-8-N5UTAK6P'
743
    assert pj_node.find('NumeroDossier').text == '61718'
744
    assert pj_node.find('NbFichier').text == '4'
745
    assert len(pj_node.findall('Bloc_Fichiers')) == 4
746
    assert pj_node.findall('Bloc_Fichiers')[0].find('TypeDocument').text == '6'
747
    assert pj_node.findall('Bloc_Fichiers')[0].find('NomFichier').text == 'cartegrise.pdf'
748
    assert pj_node.findall('Bloc_Fichiers')[0].find('Fichier').text == force_str(
749
        base64.b64encode(b'%PDF carte grise 1')
750
    )
751
    assert pj_node.findall('Bloc_Fichiers')[1].find('TypeDocument').text == '6'
752
    assert pj_node.findall('Bloc_Fichiers')[1].find('NomFichier').text == 'cartegrise2.pdf'
753
    assert pj_node.findall('Bloc_Fichiers')[1].find('Fichier').text == force_str(
754
        base64.b64encode(b'%PDF carte grise 2')
755
    )
756
    assert pj_node.findall('Bloc_Fichiers')[2].find('TypeDocument').text == '2'
757
    assert pj_node.findall('Bloc_Fichiers')[2].find('NomFichier').text == 'address_proof.pDf'
758
    assert pj_node.findall('Bloc_Fichiers')[2].find('Fichier').text == force_str(
759
        base64.b64encode(b'%PDF this is my proof of address')
760
    )
732
    assert len(soap_mock.soap_requests) == 1
761 733

  
762
    assert pj_node.findall('Bloc_Fichiers')[3].find('TypeDocument').text == '73'
763
    from passerelle.utils.conversion import to_pdf
734
    soap_request = soap_mock.soap_requests[0]
735
    assert soap_request.NumeroTeledossier == 'E-8-N5UTAK6P'
736
    assert soap_request.NumeroDossier == 61718
737
    assert soap_request.NbFichier == 4
738
    assert soap_request.Bloc_Fichiers[0].TypeDocument == '6'
739
    assert soap_request.Bloc_Fichiers[0].NomFichier == 'cartegrise.pdf'
740
    assert soap_request.Bloc_Fichiers[0].Fichier == b'%PDF carte grise 1'
764 741

  
765
    assert pj_node.findall('Bloc_Fichiers')[3].find('NomFichier').text == 'cartegrisetoto.jpg.pdf'
766
    assert pj_node.findall('Bloc_Fichiers')[3].find('Fichier').text == force_str(
767
        base64.b64encode(to_pdf(JPEG_CONTENT))
768
    )
769
    assert base64.b64decode(pj_node.findall('Bloc_Fichiers')[3].find('Fichier').text).startswith(b'%PDF')
742
    assert soap_request.Bloc_Fichiers[1].TypeDocument == '6'
743
    assert soap_request.Bloc_Fichiers[1].NomFichier == 'cartegrise2.pdf'
744
    assert soap_request.Bloc_Fichiers[1].Fichier == b'%PDF carte grise 2'
745

  
746
    assert soap_request.Bloc_Fichiers[2].TypeDocument == '2'
747
    assert soap_request.Bloc_Fichiers[2].NomFichier == 'address_proof.pDf'
748
    assert soap_request.Bloc_Fichiers[2].Fichier == b'%PDF this is my proof of address'
749

  
750
    assert soap_request.Bloc_Fichiers[3].TypeDocument == '73'
751
    assert soap_request.Bloc_Fichiers[3].NomFichier == 'cartegrisetoto.jpg.pdf'
752
    assert soap_request.Bloc_Fichiers[3].Fichier == to_pdf(JPEG_CONTENT)
753
    assert soap_request.Bloc_Fichiers[3].Fichier.startswith(b'%PDF')
770 754

  
771 755

  
772 756
@pytest.mark.parametrize('application_thirdparty_subscription', [True, False])
773
def test_registration_double_plaque(dpark, app, application_thirdparty_subscription):
757
def test_registration_double_plaque(dpark, app, soap_mock, application_thirdparty_subscription):
774 758
    url = '/dpark/test/register/'
775 759
    params = {
776 760
        "address_complement1": "",
......
807 791
        }
808 792
    )
809 793
    # with an imcplete application
810
    dpark.mock_responses.append(
811
        """<?xml version="1.0" encoding="utf-8"?>
812
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
813
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
814
  <SOAP-ENV:Header/>
815
  <SOAP-ENV:Body>
816
    <ns1:PLS_ENREGResponse xmlns:ns1="urn:Webservice_Residants">
817
      <PLS_ENREG2Result>
818
        <CodeRetour>02</CodeRetour>
819
        <MessageRetour>Dossier incomplet</MessageRetour>
820
      </PLS_ENREG2Result>
821
    </ns1:PLS_ENREGResponse>
822
  </SOAP-ENV:Body>
823
</SOAP-ENV:Envelope>"""
794
    soap_mock.add_soap_response(
795
        'PLS_ENREG2',
796
        {
797
            'PLS_ENREG2Result': {
798
                'CodeRetour': '02',
799
                'MessageRetour': 'Dossier incomplet',
800
                'NumeroDossier': 0,
801
                'NumeroDemande': 0,
802
            }
803
        },
824 804
    )
825
    resp = app.post_json(url, params=params)
826
    demande_abonnementtiers = (
827
        '<Demande_AbonnementTiers>%s</Demande_AbonnementTiers>'
828
        % repr(application_thirdparty_subscription).lower()
805
    soap_mock.add_soap_response(
806
        'PLS_ENREG2',
807
        {
808
            'PLS_ENREG2Result': {
809
                'CodeRetour': '01',
810
                'MessageRetour': '',
811
                'NumeroDossier': 22334,
812
                'NumeroDemande': 59492,
813
            }
814
        },
829 815
    )
830
    body = dpark.mock_requests[0].body.decode()
831
    assert demande_abonnementtiers in body
832
    assert ':PLS_ENREG2 ' in body
833
    assert '<ID_CONTEXTE>1<' in body
834
    assert '<ID_PRODUIT>2<' in body
816

  
817
    # result is incomplete application
818
    resp = app.post_json(url, params=params)
835 819
    assert resp.json['err'] == 1
836 820
    assert resp.json['err_desc'] == 'Dossier incomplet'
837
    # with complete application
838
    dpark.mock_responses.append(
839
        """<?xml version="1.0" encoding="utf-8"?>
840
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
841
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
842
  <SOAP-ENV:Header/>
843
  <SOAP-ENV:Body>
844
    <ns1:PLS_ENREGResponse xmlns:ns1="urn:Webservice_Residants">
845
      <PLS_ENREG2Result>
846
        <CodeRetour>01</CodeRetour>
847
        <MessageRetour/>
848
        <NumeroDossier>22334</NumeroDossier>
849
        <NumeroDemande>59492</NumeroDemande>
850
      </PLS_ENREG2Result>
851
    </ns1:PLS_ENREGResponse>
852
  </SOAP-ENV:Body>
853
</SOAP-ENV:Envelope>"""
854
    )
821

  
822
    soap_request = soap_mock.soap_requests[0]
823
    assert soap_request.ID_CONTEXTE == 1
824
    assert soap_request.ID_PRODUIT == 2
825

  
826
    # with is ok
855 827
    resp = app.post_json(url, params=params)
856
    body = dpark.mock_requests[1].body.decode()
857
    assert demande_abonnementtiers in body
858 828
    assert resp.json['data']['numerodossier'] == 22334
859 829
    assert resp.json['data']['numerodemande'] == 59492
860 830

  
831
    soap_request = soap_mock.soap_requests[0]
832
    assert soap_request.Entree_Demande.Demande_AbonnementTiers is application_thirdparty_subscription
833

  
861 834

  
862 835
@pytest.mark.parametrize(
863 836
    'transaction_datetime,expected_date',
......
867 840
        ('2018-06-11T23:59:00', '20180612'),
868 841
    ],
869 842
)
870
def test_payment_notification_double_plaque(dpark, app, transaction_datetime, expected_date):
843
def test_payment_notification_double_plaque(dpark, app, transaction_datetime, expected_date, get_service):
871 844
    operation = mock.Mock(name='PLS_NOTIFCB2')
872 845
    service = mock.Mock(spec=['PLS_NOTIFCB2'], PLS_NOTIFCB2=operation)
873
    create_service = mock.Mock(spec=[], return_value=service)
874
    client = mock.NonCallableMock(spec=['create_service'], create_service=create_service)
875
    with mock.patch('passerelle.contrib.dpark.models.get_client', return_value=client):
876
        nameid = 'abcd' * 8
877
        filenumber = '1' * 9
878
        params = {
846
    get_service.return_value = service
847

  
848
    nameid = 'abcd' * 8
849
    filenumber = '1' * 9
850
    params = {
851
        'nameid': nameid,
852
        'filenumber': filenumber,
853
        'transaction_id': 'I123456789',
854
        'transaction_datetime': transaction_datetime,
855
        'total_amount': '125',
856
        'application_id': '61718',
857
        'application_external_id': 'E-8-N5UTAK6P',
858
        'double_plaque': '1',
859
    }
860
    url = '/dpark/test/notify-payment/'
861
    resp = app.post_json(url, params=params)
862
    assert resp.json['err'] == 1
863
    assert resp.json['err_desc'] == 'No pairing exists'
864
    Pairing.objects.create(
865
        resource=dpark,
866
        **{
879 867
            'nameid': nameid,
868
            'firstnames': 'spam eggs',
869
            'lastname': 'bar',
880 870
            'filenumber': filenumber,
881
            'transaction_id': 'I123456789',
882
            'transaction_datetime': transaction_datetime,
883
            'total_amount': '125',
884
            'application_id': '61718',
885
            'application_external_id': 'E-8-N5UTAK6P',
886
            'double_plaque': '1',
887
        }
888
        url = '/dpark/test/notify-payment/'
889
        resp = app.post_json(url, params=params)
890
        assert resp.json['err'] == 1
891
        assert resp.json['err_desc'] == 'No pairing exists'
892
        Pairing.objects.create(
893
            resource=dpark,
894
            **{
895
                'nameid': nameid,
896
                'firstnames': 'spam eggs',
897
                'lastname': 'bar',
898
                'filenumber': filenumber,
899
                'badgenumber': '2' * 9,
900
            },
901
        )
902
        operation.return_value = mock.Mock(CodeRetour='02', MessageRetour='Dossier inconnu')
903
        resp = app.post_json(url, params=params)
904
        assert operation.call_args_list[-1].args[5] == expected_date
905
        assert resp.json['err'] == 1
906
        assert resp.json['err_desc'] == 'Dossier inconnu'
907
        operation.return_value = mock.Mock(CodeRetour='01')
908
        resp = app.post_json(url, params=params)
909
        assert resp.json['data'] is True
871
            'badgenumber': '2' * 9,
872
        },
873
    )
874
    operation.return_value = mock.Mock(CodeRetour='02', MessageRetour='Dossier inconnu')
875
    resp = app.post_json(url, params=params)
876
    assert operation.call_args_list[-1].args[5] == expected_date
877
    assert resp.json['err'] == 1
878
    assert resp.json['err_desc'] == 'Dossier inconnu'
879
    operation.return_value = mock.Mock(CodeRetour='01')
880
    resp = app.post_json(url, params=params)
881
    assert resp.json['data'] is True
910
-