lingo: ignore empty response in return view (#61240)

This commit is contained in:
Benjamin Dauvergne 2022-01-29 08:05:56 +01:00 committed by Frédéric Péters
parent d6cfee4ec3
commit 1f4667c202
2 changed files with 29 additions and 17 deletions

View File

@ -71,6 +71,10 @@ from .utils import signing_dumps, signing_loads
logger = logging.getLogger(__name__)
class EmptyPaymentResponse(PaymentException):
pass
class ErrorJsonResponse(JsonResponse):
def __init__(self, err_desc, *args, **kwargs):
data = {'err': 1, 'err_desc': err_desc}
@ -640,6 +644,8 @@ class PaymentView(View):
raise Http404("A payment backend or regie primary key or slug must be specified")
payment = payment_backend.make_eopayment(request=request)
if not backend_response and not payment.has_empty_response:
raise EmptyPaymentResponse
logger.info('received payment response: %r', backend_response)
try:
eopayment_response_kwargs = {'redirect': not callback}
@ -707,21 +713,22 @@ class ReturnView(PaymentView):
else:
transaction = Transaction.objects.filter(id=transaction_id).first()
response_is_ok = True
try:
transaction = self.handle_response(
request, backend_response, callback=False, transaction=transaction, **kwargs
)
except UnsignedPaymentException:
except (EmptyPaymentResponse, UnsignedPaymentException):
# some payment backends do not sign return URLs, don't mark this as
# an error, they will provide a notification to the callback
# endpoint.
if transaction_id:
return HttpResponseRedirect(get_payment_status_view(transaction_id))
return HttpResponseRedirect(get_basket_url())
response_is_ok = False
except PaymentException:
response_is_ok = False
messages.error(
request, _('We are sorry but the payment service failed to provide a correct answer.')
)
if not response_is_ok:
if transaction_id:
return HttpResponseRedirect(get_payment_status_view(transaction_id))
return HttpResponseRedirect(get_basket_url())

View File

@ -992,21 +992,26 @@ def test_payment_return_without_query_string(app, basket_page, regie, user, with
assert transaction.status == 3
# then return view is called without any data, which should be expected by the backend
with mock.patch.object(eopayment.dummy.Payment, 'response', autospec=True) as mock_response:
mock_response.return_value = eopayment.common.PaymentResponse(
result=transaction.status, order_id=transaction.order_id
)
get_resp = app.get(return_url)
mock_response.assert_called_once_with(
mock.ANY,
'',
redirect=True,
order_id_hint=transaction.order_id,
order_status_hint=transaction.status,
)
if regie.eopayment.has_empty_response:
with mock.patch.object(eopayment.dummy.Payment, 'response', autospec=True) as mock_response:
mock_response.return_value = eopayment.common.PaymentResponse(
result=transaction.status, order_id=transaction.order_id
)
get_resp = app.get(return_url)
mock_response.assert_called_once_with(
mock.ANY,
'',
redirect=True,
order_id_hint=transaction.order_id,
order_status_hint=transaction.status,
)
else:
with mock.patch.object(eopayment.dummy.Payment, 'response', autospec=True, side_effect=Exception):
get_resp = app.get(return_url)
assert get_resp.status_code == 302
resp = app.get(get_resp['Location'])
assert 'Your payment has been succesfully registered.' in resp.text
if regie.eopayment.has_empty_response:
assert 'Your payment has been succesfully registered.' in resp.text
@pytest.mark.parametrize('with_payment_backend', [False, True])