dpark: accept UTC datetime in payment notification (#41373)
This commit is contained in:
parent
555aa3c49d
commit
f2b06c9a08
|
@ -16,8 +16,11 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
import base64
|
||||
|
||||
import pytz
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils import six, timezone
|
||||
|
@ -115,11 +118,31 @@ def date_to_isoformat(idate):
|
|||
if not idate:
|
||||
return None
|
||||
try:
|
||||
return timezone.datetime.strptime(idate, '%Y%m%d').date().isoformat()
|
||||
return datetime.datetime.strptime(idate, '%Y%m%d').date().isoformat()
|
||||
except (ValueError,):
|
||||
return idate
|
||||
|
||||
|
||||
def date_or_datetime_to_local_date(value):
|
||||
try:
|
||||
dt = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S')
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
dt = pytz.utc.localize(dt)
|
||||
dt = dt.astimezone(pytz.timezone('Europe/Paris'))
|
||||
return dt.date()
|
||||
|
||||
try:
|
||||
dt = datetime.datetime.strptime(value, '%Y%m%d')
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
return dt.date()
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def normalize_reply(reply):
|
||||
excluded = ('CodeRetour', 'MessageRetour')
|
||||
serialized_reply = serialize_object(reply)
|
||||
|
@ -414,6 +437,10 @@ class DPark(BaseResource):
|
|||
'transaction_datetime', 'total_amount',
|
||||
'application_external_id')
|
||||
)
|
||||
# We accept a simple date or a datetime using UTC, we convert it to Europe/Paris timezone on exit
|
||||
transaction_date = date_or_datetime_to_local_date(data['transaction_datetime'])
|
||||
if transaction_date is None:
|
||||
raise APIError(_('Invalid value for transaction datetime'))
|
||||
pairings = Pairing.objects.filter(resource=self,
|
||||
nameid=data['nameid'],
|
||||
filenumber=data['filenumber'])
|
||||
|
@ -427,7 +454,7 @@ class DPark(BaseResource):
|
|||
data['application_id'],
|
||||
data.get('applicaiton_payment_type', 10),
|
||||
total_amount,
|
||||
data['transaction_datetime'],
|
||||
transaction_date.strftime('%Y%m%d'),
|
||||
data['transaction_id'])
|
||||
for pairing in pairings:
|
||||
pairing.clear_cache()
|
||||
|
|
1
setup.py
1
setup.py
|
@ -110,6 +110,7 @@ setup(name='passerelle',
|
|||
'pdfrw',
|
||||
'httplib2',
|
||||
'xmlschema',
|
||||
'pytz',
|
||||
],
|
||||
cmdclass={
|
||||
'build': build,
|
||||
|
|
|
@ -73,7 +73,6 @@ def dpark(db):
|
|||
|
||||
|
||||
class ReplyDataClass(dict):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.__dict__.update(kwargs)
|
||||
super(ReplyDataClass, self).__init__(**kwargs)
|
||||
|
@ -110,11 +109,12 @@ class MockedService(object):
|
|||
|
||||
|
||||
def get_client(success=True, error_class=None, replydata=None):
|
||||
service = MockedService(success, error_class, replydata)
|
||||
|
||||
def create_service(binging, operation_endpoint):
|
||||
return MockedService(success, error_class, replydata)
|
||||
return service
|
||||
|
||||
return mock.Mock(create_service=create_service)
|
||||
return mock.Mock(create_service=create_service, service=service)
|
||||
|
||||
|
||||
def test_call_service_error(dpark, app):
|
||||
|
@ -492,13 +492,22 @@ def test_get_payment_infos(dpark, app):
|
|||
assert data['numerodemande'] == '55555'
|
||||
|
||||
|
||||
def test_payment_notification(dpark, app):
|
||||
with mock.patch('passerelle.contrib.dpark.models.get_client') as client:
|
||||
@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):
|
||||
operation = mock.Mock(name='PLS_NOTIFCB')
|
||||
service = mock.Mock(spec=['PLS_NOTIFCB'], PLS_NOTIFCB=operation)
|
||||
create_service = mock.Mock(spec=[], return_value=service)
|
||||
client = mock.NonCallableMock(spec=['create_service'], create_service=create_service)
|
||||
with mock.patch('passerelle.contrib.dpark.models.get_client', return_value=client):
|
||||
nameid = 'abcd' * 8
|
||||
filenumber = '1' * 9
|
||||
params = {
|
||||
'nameid': nameid, 'filenumber': filenumber, 'transaction_id': 'I123456789',
|
||||
'transaction_datetime': '2018-06-11T10:23', 'total_amount': '125',
|
||||
'transaction_datetime': transaction_datetime, 'total_amount': '125',
|
||||
'application_id': '61718', 'application_external_id': 'E-8-N5UTAK6P'
|
||||
}
|
||||
url = '/dpark/test/notify-payment/'
|
||||
|
@ -509,11 +518,12 @@ def test_payment_notification(dpark, app):
|
|||
'nameid': nameid, 'firstnames': 'spam eggs', 'lastname': 'bar',
|
||||
'filenumber': filenumber, 'badgenumber': '2' * 9}
|
||||
)
|
||||
client.return_value = get_client(replydata={'CodeRetour': '02', 'MessageRetour': u'Dossier inconnu'})
|
||||
operation.return_value = mock.Mock(CodeRetour='02', MessageRetour=u'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'
|
||||
client.return_value = get_client(replydata={'CodeRetour': '01'})
|
||||
operation.return_value = mock.Mock(CodeRetour='01')
|
||||
resp = app.post_json(url, params=params)
|
||||
assert resp.json['data'] is True
|
||||
|
||||
|
|
Loading…
Reference in New Issue