18 |
18 |
from webtest import TestApp
|
19 |
19 |
|
20 |
20 |
from combo.data.models import Page
|
21 |
|
from combo.apps.lingo.models import (Regie, BasketItem, Transaction,
|
22 |
|
TransactionOperation, RemoteItem, EXPIRED, LingoBasketCell)
|
|
21 |
from combo.apps.lingo.models import (
|
|
22 |
Regie, BasketItem, Transaction, TransactionOperation, RemoteItem, EXPIRED, LingoBasketCell,
|
|
23 |
PaymentBackend)
|
23 |
24 |
from combo.utils import sign_url
|
24 |
25 |
|
25 |
26 |
from .test_manager import login
|
... | ... | |
27 |
28 |
pytestmark = pytest.mark.django_db
|
28 |
29 |
|
29 |
30 |
|
|
31 |
def get_url(with_payment_backend, view_name, regie):
|
|
32 |
if with_payment_backend:
|
|
33 |
return reverse(
|
|
34 |
view_name + '-payment-backend',
|
|
35 |
kwargs={'payment_backend_pk': regie.payment_backend.id})
|
|
36 |
return reverse(view_name, kwargs={'regie_pk': regie.id})
|
|
37 |
|
|
38 |
|
30 |
39 |
@contextmanager
|
31 |
40 |
def check_log(caplog, message):
|
32 |
41 |
idx = len(caplog.records)
|
... | ... | |
37 |
46 |
|
38 |
47 |
@pytest.fixture
|
39 |
48 |
def regie():
|
|
49 |
try:
|
|
50 |
payment_backend = PaymentBackend.objects.get(slug='test1')
|
|
51 |
except PaymentBackend.DoesNotExist:
|
|
52 |
payment_backend = PaymentBackend.objects.create(
|
|
53 |
label='test1', slug='test1', service='dummy', service_options={'siret': '1234'})
|
40 |
54 |
try:
|
41 |
55 |
regie = Regie.objects.get(slug='test')
|
42 |
56 |
except Regie.DoesNotExist:
|
... | ... | |
45 |
59 |
regie.slug = 'test'
|
46 |
60 |
regie.description = 'test'
|
47 |
61 |
regie.payment_min_amount = Decimal(4.5)
|
48 |
|
regie.service = 'dummy'
|
49 |
|
regie.service_options = {'siret': '1234'}
|
|
62 |
regie.payment_backend = payment_backend
|
50 |
63 |
regie.save()
|
51 |
64 |
return regie
|
52 |
65 |
|
... | ... | |
85 |
98 |
return settings.LINGO_API_SIGN_KEY
|
86 |
99 |
|
87 |
100 |
def test_default_regie():
|
|
101 |
payment_backend = PaymentBackend.objects.create(label='foo', slug='foo')
|
88 |
102 |
Regie.objects.all().delete()
|
89 |
|
regie1 = Regie(label='foo', slug='foo')
|
|
103 |
regie1 = Regie(label='foo', slug='foo', payment_backend=payment_backend)
|
90 |
104 |
regie1.save()
|
91 |
105 |
assert bool(regie1.is_default) is True
|
92 |
|
regie2 = Regie(label='bar', slug='bar')
|
|
106 |
regie2 = Regie(label='bar', slug='bar', payment_backend=payment_backend)
|
93 |
107 |
regie2.save()
|
94 |
108 |
assert bool(regie2.is_default) is False
|
95 |
109 |
|
... | ... | |
121 |
135 |
resp = resp.form.submit()
|
122 |
136 |
assert resp.status_code == 302
|
123 |
137 |
|
124 |
|
def test_successfull_items_payment(app, basket_page, regie, user):
|
|
138 |
|
|
139 |
@pytest.mark.parametrize('with_payment_backend', [False, True])
|
|
140 |
def test_successfull_items_payment(app, basket_page, regie, user, with_payment_backend):
|
125 |
141 |
items = {'item1': {'amount': '10.5', 'source_url': 'http://example.org/item/1'},
|
126 |
142 |
'item2': {'amount': '42', 'source_url': 'http://example.org/item/2'},
|
127 |
143 |
'item3': {'amount': '100', 'source_url': 'http://example.org/item/3'},
|
... | ... | |
145 |
161 |
'ok': True, 'reason': 'Paid'}
|
146 |
162 |
# make sure return url is the user return URL
|
147 |
163 |
assert urlparse.urlparse(qs['return_url'][0]).path.startswith(
|
148 |
|
reverse('lingo-return', kwargs={'regie_pk': regie.id}))
|
|
164 |
reverse('lingo-return-payment-backend',
|
|
165 |
kwargs={'payment_backend_pk': regie.payment_backend.id}))
|
149 |
166 |
# simulate successful call to callback URL
|
150 |
167 |
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as request:
|
151 |
|
resp = app.get(reverse('lingo-callback', kwargs={'regie_pk': regie.id}), params=args)
|
|
168 |
resp = app.get(get_url(with_payment_backend, 'lingo-callback', regie), params=args)
|
152 |
169 |
assert resp.status_code == 200
|
153 |
170 |
# simulate successful return URL
|
154 |
171 |
resp = app.get(qs['return_url'][0], params=args)
|
... | ... | |
158 |
175 |
assert 'Your payment has been succesfully registered.' in resp.text
|
159 |
176 |
|
160 |
177 |
def test_add_amount_to_basket(app, key, regie, user):
|
161 |
|
other_regie = Regie(label='test2', slug='test2', service='dummy', service_options={'siret': '1234'})
|
|
178 |
payment_backend = PaymentBackend.objects.create(
|
|
179 |
label='test2', slug='test2', service='dummy', service_options={'siret': '1234'})
|
|
180 |
other_regie = Regie(label='test2', slug='test2', payment_backend=payment_backend)
|
162 |
181 |
other_regie.save()
|
163 |
182 |
|
164 |
183 |
user_email = 'foo@example.com'
|
... | ... | |
479 |
498 |
app.get(reverse('lingo-cancel-item', kwargs={'pk': basket_item_id}), status=404)
|
480 |
499 |
app.post(reverse('lingo-cancel-item', kwargs={'pk': basket_item_id}), status=403)
|
481 |
500 |
|
482 |
|
def test_payment_callback(app, basket_page, regie, user):
|
|
501 |
|
|
502 |
@pytest.mark.parametrize('with_payment_backend', [False, True])
|
|
503 |
def test_payment_callback(app, basket_page, regie, user, with_payment_backend):
|
483 |
504 |
page = Page(title='xxx', slug='index', template_name='standard')
|
484 |
505 |
page.save()
|
485 |
506 |
item = BasketItem.objects.create(user=user, regie=regie,
|
... | ... | |
497 |
518 |
assert data['amount'] == '10.50'
|
498 |
519 |
|
499 |
520 |
# call callback with GET
|
500 |
|
callback_url = reverse('lingo-callback', kwargs={'regie_pk': regie.id})
|
|
521 |
callback_url = get_url(with_payment_backend, 'lingo-callback', regie)
|
501 |
522 |
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as request:
|
502 |
523 |
get_resp = app.get(callback_url, params=data)
|
503 |
524 |
url = request.call_args[0][1]
|
... | ... | |
526 |
547 |
assert Transaction.objects.get(order_id=transaction_id).status == 3
|
527 |
548 |
|
528 |
549 |
# call return view
|
529 |
|
get_resp = app.get(reverse('lingo-return', kwargs={'regie_pk': regie.pk}), params=data)
|
|
550 |
return_url = get_url(with_payment_backend, 'lingo-return', regie)
|
|
551 |
get_resp = app.get(return_url, params=data)
|
530 |
552 |
assert get_resp.status_code == 302
|
531 |
553 |
resp = app.get(get_resp['Location'])
|
532 |
554 |
assert 'Your payment has been succesfully registered.' in resp.text
|
533 |
555 |
|
534 |
|
def test_payment_callback_no_regie(app, basket_page, regie, user):
|
|
556 |
@pytest.mark.parametrize('with_payment_backend', [False, True])
|
|
557 |
def test_payment_callback_no_regie(app, basket_page, regie, user, with_payment_backend):
|
535 |
558 |
item = BasketItem.objects.create(user=user, regie=regie,
|
536 |
559 |
subject='test_item', amount='10.5',
|
537 |
560 |
source_url='http://example.org/testitem/')
|
... | ... | |
547 |
570 |
assert data['amount'] == '10.50'
|
548 |
571 |
|
549 |
572 |
# call callback with GET
|
550 |
|
callback_url = reverse('lingo-callback', kwargs={'regie_pk': regie.id})
|
|
573 |
callback_url = get_url(with_payment_backend, 'lingo-callback', regie)
|
551 |
574 |
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as request:
|
552 |
575 |
get_resp = app.get(callback_url, params=data)
|
553 |
576 |
url = request.call_args[0][1]
|
... | ... | |
569 |
592 |
'amount': qs['amount'][0], 'ok': True}
|
570 |
593 |
assert data['amount'] == '11.50'
|
571 |
594 |
|
572 |
|
def test_nonexisting_transaction(app, regie, user):
|
|
595 |
|
|
596 |
@pytest.mark.parametrize('with_payment_backend', [False, True])
|
|
597 |
def test_nonexisting_transaction(app, regie, user, with_payment_backend):
|
573 |
598 |
app = login(app)
|
574 |
599 |
data = {'transaction_id': 'unknown', 'signed': True,
|
575 |
600 |
'amount': '23', 'ok': True}
|
576 |
601 |
|
577 |
602 |
# call callback with GET
|
578 |
|
callback_url = reverse('lingo-callback', kwargs={'regie_pk': regie.id})
|
|
603 |
callback_url = get_url(with_payment_backend, 'lingo-callback', regie)
|
579 |
604 |
app.get(callback_url, params=data, status=404)
|
580 |
605 |
|
581 |
|
def test_payment_callback_waiting(app, basket_page, regie, user):
|
|
606 |
|
|
607 |
@pytest.mark.parametrize('with_payment_backend', [False, True])
|
|
608 |
def test_payment_callback_waiting(app, basket_page, regie, user, with_payment_backend):
|
582 |
609 |
item = BasketItem.objects.create(user=user, regie=regie,
|
583 |
610 |
subject='test_item', amount='10.5',
|
584 |
611 |
source_url='http://example.org/testitem/')
|
... | ... | |
594 |
621 |
assert data['amount'] == '10.50'
|
595 |
622 |
|
596 |
623 |
# callback with WAITING state
|
597 |
|
callback_url = reverse('lingo-callback', kwargs={'regie_pk': regie.id})
|
|
624 |
callback_url = get_url(with_payment_backend, 'lingo-callback', regie)
|
598 |
625 |
resp = app.get(callback_url, params=data)
|
599 |
626 |
assert resp.status_code == 200
|
600 |
627 |
assert Transaction.objects.get(order_id=transaction_id).status == eopayment.WAITING
|
... | ... | |
615 |
642 |
assert BasketItem.objects.get(id=item.id).payment_date
|
616 |
643 |
assert BasketItem.get_items_to_be_paid(user).count() == 0
|
617 |
644 |
|
618 |
|
def test_payment_no_callback_just_return(caplog, app, basket_page, regie, user):
|
|
645 |
|
|
646 |
@pytest.mark.parametrize('with_payment_backend', [False, True])
|
|
647 |
def test_payment_no_callback_just_return(
|
|
648 |
caplog, app, basket_page, regie, user, with_payment_backend):
|
619 |
649 |
item = BasketItem.objects.create(user=user, regie=regie,
|
620 |
650 |
subject='test_item', amount='10.5',
|
621 |
651 |
source_url='http://example.org/testitem/')
|
... | ... | |
632 |
662 |
|
633 |
663 |
# call return with unsigned POST
|
634 |
664 |
with check_log(caplog, 'received unsigned payment'):
|
635 |
|
return_url = reverse('lingo-return', kwargs={'regie_pk': regie.id})
|
|
665 |
return_url = get_url(with_payment_backend, 'lingo-return', regie)
|
636 |
666 |
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as request:
|
637 |
667 |
get_resp = app.post(return_url, params=data)
|
638 |
668 |
assert request.call_count == 0
|
... | ... | |
654 |
684 |
|
655 |
685 |
# call return with signed POST
|
656 |
686 |
data['signed'] = True
|
657 |
|
return_url = reverse('lingo-return', kwargs={'regie_pk': regie.id})
|
|
687 |
return_url = get_url(with_payment_backend, 'lingo-return', regie)
|
658 |
688 |
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as request:
|
659 |
689 |
get_resp = app.post(return_url, params=data)
|
660 |
690 |
url = request.call_args[0][1]
|
... | ... | |
827 |
857 |
assert resp.status_code == 200
|
828 |
858 |
assert Transaction.objects.get(order_id=transaction_id).status == 3
|
829 |
859 |
|
830 |
|
def test_payment_callback_error(app, basket_page, regie, user):
|
|
860 |
|
|
861 |
@pytest.mark.parametrize('with_payment_backend', [False, True])
|
|
862 |
def test_payment_callback_error(app, basket_page, regie, user, with_payment_backend):
|
831 |
863 |
item = BasketItem.objects.create(user=user, regie=regie,
|
832 |
864 |
subject='test_item', amount='10.5',
|
833 |
865 |
source_url='http://example.org/testitem/')
|
... | ... | |
843 |
875 |
assert data['amount'] == '10.50'
|
844 |
876 |
|
845 |
877 |
# call callback with GET
|
846 |
|
callback_url = reverse('lingo-callback', kwargs={'regie_pk': regie.id})
|
|
878 |
callback_url = get_url(with_payment_backend, 'lingo-callback', regie)
|
847 |
879 |
with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as request:
|
848 |
880 |
mock_response = mock.Mock()
|
849 |
881 |
def kaboom():
|