From 2c7bdf2c3b6520b3fb1585fd4b71a3002199b151 Mon Sep 17 00:00:00 2001 From: Serghei Mihai Date: Wed, 19 Sep 2018 17:46:16 +0200 Subject: [PATCH 2/2] lingo: handle single basket item payment (#25725) --- combo/apps/lingo/urls.py | 4 +++- combo/apps/lingo/views.py | 21 ++++++++++++++++++++- tests/test_lingo_payment.py | 32 +++++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/combo/apps/lingo/urls.py b/combo/apps/lingo/urls.py index 33d7ac41..eede96a0 100644 --- a/combo/apps/lingo/urls.py +++ b/combo/apps/lingo/urls.py @@ -21,7 +21,7 @@ from combo.urls_utils import decorated_includes, manager_required from .views import (RegiesApiView, AddBasketItemApiView, PayView, CallbackView, ReturnView, ItemDownloadView, ItemView, CancelItemView, RemoveBasketItemApiView, ValidateTransactionApiView, - CancelTransactionApiView, SelfInvoiceView) + CancelTransactionApiView, SelfInvoiceView, BasketItemPayView) from .manager_views import (RegieListView, RegieCreateView, RegieUpdateView, RegieDeleteView, TransactionListView, download_transactions_csv) @@ -56,6 +56,8 @@ urlpatterns = [ ItemDownloadView.as_view(), name='download-item-pdf'), url(r'^lingo/item/(?P[\w,-]+)/(?P[\w,-]+)/$', ItemView.as_view(), name='view-item'), + url(r'^lingo/item/(?P\d+)/pay$', + BasketItemPayView.as_view(), name='basket-item-pay-view'), url(r'^lingo/self-invoice/(?P\w+)/$', SelfInvoiceView.as_view(), name='lingo-self-invoice'), ] diff --git a/combo/apps/lingo/views.py b/combo/apps/lingo/views.py index 57cbd31a..226b2b45 100644 --- a/combo/apps/lingo/views.py +++ b/combo/apps/lingo/views.py @@ -165,7 +165,9 @@ class AddBasketItemApiView(View): item.regie.compute_extra_fees(user=item.user) response = HttpResponse(content_type='application/json') - response.write(json.dumps({'result': 'success', 'id': str(item.id)})) + payment_url = reverse('basket-item-pay-view', kwargs={'item_id': item.id}) + response.write(json.dumps({'result': 'success', 'id': str(item.id), + 'payment_url': request.build_absolute_uri(payment_url)})) return response @@ -391,6 +393,23 @@ class PayView(PayMixin, View): return self.handle_payment(request, regie, items, remote_items, next_url, email) +class BasketItemPayView(PayMixin, View): + @atomic + def get(self, request, *args, **kwargs): + next_url = request.GET.get('next_url') or '/' + if request.user and request.user.is_authenticated(): + item = BasketItem.objects.get(pk=kwargs['item_id']) + regie = item.regie + if item.user != request.user or regie.extra_fees_ws_url: + messages.error(request, _(u'Item payment forbidden.')) + return HttpResponseRedirect(next_url) + + return self.handle_payment(request, regie, [item], [], next_url) + + messages.error(request, _(u'Payment requires to be logged in.')) + return HttpResponseRedirect(next_url) + + class PaymentException(Exception): pass diff --git a/tests/test_lingo_payment.py b/tests/test_lingo_payment.py index b1186217..fe8f92c6 100644 --- a/tests/test_lingo_payment.py +++ b/tests/test_lingo_payment.py @@ -199,8 +199,11 @@ def test_add_amount_to_basket(app, key, regie, user): url = '%s?email=%s&orig=wcs' % (reverse('api-add-basket-item'), user_email) url = sign_url(url, settings.LINGO_API_SIGN_KEY) resp = app.post_json(url, params=data) + item = BasketItem.objects.get(amount=Decimal('22.23')) assert resp.status_code == 200 - assert json.loads(resp.content)['result'] == 'success' + response = json.loads(resp.content) + assert response['result'] == 'success' + assert response['payment_url'].endswith('/lingo/item/%s/pay' % item.id) assert BasketItem.objects.filter(amount=Decimal('22.23')).exists() assert BasketItem.objects.filter(amount=Decimal('22.23'))[0].regie_id == other_regie.id @@ -230,6 +233,33 @@ def test_add_amount_to_basket(app, key, regie, user): resp = app.post_json(url, params=data, status=400) assert resp.text == 'Unknown regie' +def test_pay_single_basket_item(app, key, regie, user, john_doe): + page = Page(title='xxx', slug='index', template_name='standard') + page.save() + cell = LingoBasketCell(page=page, placeholder='content', order=0) + cell.save() + + amount = 12 + data = {'amount': amount, 'display_name': 'test amount', + 'url': 'http://example.com'} + url = '%s?email=%s&orig=wcs' % (reverse('api-add-basket-item'), user.email) + url = sign_url(url, key) + resp = app.post_json(url, params=data) + payment_url = json.loads(resp.content)['payment_url'] + resp = app.get(payment_url).follow() + assert 'Payment requires to be logged in.' in resp.text + + login(app, username='john.doe', password='john.doe') + resp = app.get(payment_url).follow() + assert 'Item payment forbidden.' in resp.text + + app.reset() + login(app) + resp = app.get(payment_url) + assert resp.location.startswith('http://dummy-payment.demo.entrouvert.com/') + qs = urlparse.parse_qs(urlparse.urlparse(resp.location).query) + assert qs['amount'] == ['12.00'] + def test_pay_multiple_regies(app, key, regie, user): test_add_amount_to_basket(app, key, regie, user) -- 2.19.0