0004-lingo-handle-empty-payload-in-ReturnView-42581.patch
combo/apps/lingo/views.py | ||
---|---|---|
553 | 553 |
logger = logging.getLogger(__name__) |
554 | 554 |
logger.info(u'received payment response: %r', backend_response) |
555 | 555 |
try: |
556 |
payment_response = payment.response(backend_response) |
|
556 |
payment_response = payment.response( |
|
557 |
backend_response, **kwargs.get('backend_kwargs', {}) |
|
558 |
) |
|
557 | 559 |
except eopayment.PaymentException as e: |
558 | 560 |
logger.error(u'failed to process payment response: %s', e, |
559 | 561 |
extra={'eopayment_raw_response': repr(backend_response)}) |
... | ... | |
676 | 678 |
return super(ReturnView, self).dispatch(*args, **kwargs) |
677 | 679 | |
678 | 680 |
def get(self, request, *args, **kwargs): |
679 |
if not request.environ['QUERY_STRING']: |
|
680 |
return HttpResponseBadRequest('Missing query string') |
|
681 | 681 |
return self.handle_return(request, request.environ['QUERY_STRING'], **kwargs) |
682 | 682 | |
683 | 683 |
def post(self, request, *args, **kwargs): |
684 | 684 |
return self.handle_return(request, force_text(request.body) or request.environ['QUERY_STRING'], **kwargs) |
685 | 685 | |
686 | 686 |
def handle_return(self, request, backend_response, **kwargs): |
687 |
kwargs.setdefault('backend_kwargs', {})['redirect'] = True |
|
687 | 688 |
transaction = None |
688 | 689 |
transaction_id = kwargs.get('transaction_signature') |
689 | 690 |
if transaction_id: |
690 | 691 |
try: |
691 | 692 |
transaction_id = signing_loads(transaction_id) |
692 | 693 |
except signing.BadSignature: |
694 |
transaction_id = None |
|
695 |
if transaction_id: |
|
696 |
try: |
|
697 |
current_transaction = Transaction.objects.get(pk=transaction_id) |
|
698 |
except Transaction.DoesNotExist: |
|
693 | 699 |
pass |
700 |
else: |
|
701 |
# include info about current state |
|
702 |
kwargs['backend_kwargs']['order_id_hint'] = current_transaction.order_id |
|
703 |
kwargs['backend_kwargs']['order_status_hint'] = current_transaction.status |
|
694 | 704 |
try: |
695 | 705 |
transaction = self.handle_response(request, backend_response, **kwargs) |
696 | 706 |
except UnsignedPaymentException as e: |
tests/test_lingo_payment.py | ||
---|---|---|
757 | 757 |
assert data['amount'] == '11.50' |
758 | 758 | |
759 | 759 | |
760 |
@pytest.mark.parametrize('with_payment_backend', [False, True]) |
|
761 |
def test_payment_return_without_query_string(app, basket_page, regie, user, with_payment_backend): |
|
762 |
page = Page(title='xxx', slug='index', template_name='standard') |
|
763 |
page.save() |
|
764 |
item = BasketItem.objects.create(user=user, regie=regie, |
|
765 |
subject='test_item', amount='10.5', |
|
766 |
source_url='http://example.org/testitem/') |
|
767 |
resp = login(app).get(basket_page.get_online_url()) |
|
768 |
resp = resp.form.submit() |
|
769 |
assert resp.status_code == 302 |
|
770 |
location = resp.location |
|
771 |
parsed = urlparse.urlparse(location) |
|
772 |
qs = urlparse.parse_qs(parsed.query) |
|
773 |
return_url = qs['return_url'][0] |
|
774 |
transaction_id = qs['transaction_id'][0] |
|
775 |
data = {'transaction_id': transaction_id, 'signed': True, |
|
776 |
'amount': qs['amount'][0], 'ok': True} |
|
777 | ||
778 |
# payment status is obtained through callback |
|
779 |
callback_url = get_url(with_payment_backend, 'lingo-callback', regie) |
|
780 |
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as request: |
|
781 |
get_resp = app.get(callback_url, params=data) |
|
782 |
transaction = Transaction.objects.get(order_id=transaction_id) |
|
783 |
assert transaction.status == 3 |
|
784 | ||
785 |
def response(self, query_string, redirect=False, order_id_hint=None, |
|
786 |
order_status_hint=None): |
|
787 |
assert redirect is True |
|
788 |
assert order_id_hint == transaction.order_id |
|
789 |
assert order_status_hint == transaction.status |
|
790 |
return eopayment.common.PaymentResponse(result=order_status_hint, order_id=order_id_hint) |
|
791 | ||
792 |
# then return view is called without any data, which should be expected by the backend |
|
793 |
with mock.patch('eopayment.dummy.Payment.response', new=response): |
|
794 |
get_resp = app.get(return_url) |
|
795 |
assert get_resp.status_code == 302 |
|
796 |
resp = app.get(get_resp['Location']) |
|
797 |
assert 'Your payment has been succesfully registered.' in resp.text |
|
798 | ||
799 | ||
760 | 800 |
@pytest.mark.parametrize('with_payment_backend', [False, True]) |
761 | 801 |
def test_nonexisting_transaction(app, regie, user, with_payment_backend): |
762 | 802 |
app = login(app) |
763 |
- |