From af97ab9ec8487c652d735ecacc9008ba4242e4a2 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 7 May 2020 09:29:57 +0200 Subject: [PATCH] lingo: fix typo on Transaction.bank_transaction_date (#42565) --- combo/apps/lingo/views.py | 8 ++-- tests/test_lingo_payment.py | 78 +++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 4 deletions(-) diff --git combo/apps/lingo/views.py combo/apps/lingo/views.py index 832dc959..c91ed59e 100644 --- combo/apps/lingo/views.py +++ combo/apps/lingo/views.py @@ -611,13 +611,13 @@ class PaymentView(View): # store transaction_date but prevent multiple updates if payment_response.transaction_date is None: logger.warning('no transaction date') - elif transaction.transaction_date is None: - transaction.transaction_date = payment_response.transaction_date - elif payment_response.transaction_date != transaction.transaction_date: + elif transaction.bank_transaction_date is None: + transaction.bank_transaction_date = payment_response.transaction_date + elif payment_response.transaction_date != transaction.bank_transaction_date: # XXX: don't know if it can happen, but I would like to know when it does # as for differed payments there can be multiple notifications. logger.error('new transaction_date for transaction %s was %s, received %s', - transaction.id, transaction.transaction_date, payment_response.transaction_date) + transaction.id, transaction.bank_transaction_date, payment_response.transaction_date) transaction.save() if payment_response.result == eopayment.WAITING: diff --git tests/test_lingo_payment.py tests/test_lingo_payment.py index 7f35bd31..f88c7902 100644 --- tests/test_lingo_payment.py +++ tests/test_lingo_payment.py @@ -16,6 +16,7 @@ from django.test import override_settings from django.utils import timezone from django.utils.http import urlencode from django.utils.six.moves.urllib import parse as urlparse +from django.utils.timezone import utc from django.contrib.messages.storage.session import SessionStorage from webtest import TestApp @@ -1302,3 +1303,80 @@ def test_request_payment_exception(app, basket_page, regie, user): resp = login(app).get(basket_page.get_online_url()) resp = resp.form.submit().follow() assert 'Failed to initiate payment request' in resp.text + + +@pytest.mark.parametrize('transaction_date', [None, datetime(2020, 1, 1, 12, 00, 00, tzinfo=utc)]) +def test_bank_transaction_date(app, key, regie, user, john_doe, caplog, transaction_date): + amount = 12 + data = { + 'amount': amount, + 'display_name': 'test amount', + 'url': 'http://example.com/' + } + url = reverse('api-add-basket-item') + '?orig=wcs' + url = sign_url(url, key) + resp = app.post_json(url, params=data) + # check that an unpaid item exists in basket + assert BasketItem.objects.filter(regie=regie, amount=amount, payment_date__isnull=True).exists() + + payment_url = resp.json['payment_url'] + resp = app.get(payment_url, params={'next_url': 'http://example.net/form/id/'}) + + assert Transaction.objects.count() == 1 + transaction = Transaction.objects.get() + order_id = transaction.order_id + + # make sure the redirection is done to the payment backend + assert resp.location.startswith('http://dummy-payment.demo.entrouvert.com/') + qs = urlparse.parse_qs(urlparse.urlparse(resp.location).query) + assert qs['amount'] == ['12.00'] + # simulate successful payment response from dummy backend + transaction_id = qs['transaction_id'][0], + data = { + 'transaction_id': transaction_id, + 'ok': True, + 'amount': qs['amount'][0], + 'signed': True, + } + mock_response = mock.Mock() + mock_response.status_code = 200 + # simulate payment service redirecting the user to /lingo/return/... (eopayment + # dummy module put that URL in return_url query string parameter). + with mock.patch('eopayment.dummy.Payment.response') as eopayment_response: + return_value = eopayment_response.return_value + return_value.result = 1 # eopayment.RECEIVED + return_value.order_id = order_id + return_value.bank_data = {'a': 'b'} + return_value.transaction_id = '1234' + return_value.transaction_date = transaction_date + with mock.patch('combo.utils.requests_wrapper.RequestsSession.request', return_value=mock_response) as request: + resp = app.get(qs['return_url'][0], params=data) + assert request.call_count == 0 + # check transaction_date was recorded + transaction.refresh_from_db() + assert transaction.bank_transaction_date == transaction_date + if transaction_date is None: + assert 'no transaction date' in caplog.text + + # send another transaction_date + with mock.patch('eopayment.dummy.Payment.response') as eopayment_response: + return_value = eopayment_response.return_value + return_value.result = 3 # eopayment.PAID + return_value.order_id = order_id + return_value.bank_data = {'a': 'b'} + return_value.transaction_id = '1234' + return_value.transaction_date = datetime(2020, 1, 2, 12, 0, tzinfo=utc) + with mock.patch('combo.utils.requests_wrapper.RequestsSession.post', return_value=mock_response) as post: + resp = app.get(qs['return_url'][0], params=data) + if transaction_date is None: + assert json.loads(post.call_args[1]['data'])['bank_transaction_date'] == '2020-01-02T12:00:00' + else: + assert json.loads(post.call_args[1]['data'])['bank_transaction_date'] == '2020-01-01T12:00:00' + assert post.call_args[0][0] == 'http://example.com/jump/trigger/paid' + transaction.refresh_from_db() + if transaction_date is None: + transaction.refresh_from_db() + assert transaction.bank_transaction_date == datetime(2020, 1, 2, 12, 0, tzinfo=utc) + else: + assert transaction.bank_transaction_date == transaction_date + assert 'new transaction_date for transaction' in caplog.text -- 2.26.0