Projet

Général

Profil

0004-lingo-handle-empty-payload-in-ReturnView-42581.patch

Valentin Deniaud, 14 mai 2020 17:31

Télécharger (5,05 ko)

Voir les différences:

Subject: [PATCH 4/5] lingo: handle empty payload in ReturnView (#42581)

 combo/apps/lingo/views.py   | 16 ++++++++++++---
 tests/test_lingo_payment.py | 40 +++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 3 deletions(-)
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
-