2015-12-25 21:16:44 +01:00
|
|
|
import pytest
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
import urlparse
|
|
|
|
import urllib
|
|
|
|
from decimal import Decimal
|
|
|
|
import json
|
|
|
|
|
|
|
|
from django.contrib.auth.models import User
|
|
|
|
from django.core.urlresolvers import reverse
|
|
|
|
from django.core.wsgi import get_wsgi_application
|
2015-12-31 16:16:04 +01:00
|
|
|
from django.conf import settings
|
2015-12-25 21:16:44 +01:00
|
|
|
from webtest import TestApp
|
|
|
|
|
|
|
|
from django.test import Client
|
|
|
|
|
|
|
|
from combo.apps.lingo.models import Regie, BasketItem, Transaction, RemoteItem
|
2015-12-31 16:16:04 +01:00
|
|
|
from combo.utils import sign_url
|
2015-12-25 21:16:44 +01:00
|
|
|
|
|
|
|
pytestmark = pytest.mark.django_db
|
|
|
|
|
|
|
|
client = Client()
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def regie():
|
|
|
|
try:
|
|
|
|
regie = Regie.objects.get(slug='test')
|
|
|
|
except Regie.DoesNotExist:
|
|
|
|
regie = Regie()
|
|
|
|
regie.label = 'Test'
|
|
|
|
regie.slug = 'test'
|
|
|
|
regie.description = 'test'
|
|
|
|
regie.payment_min_amount = Decimal(4.5)
|
|
|
|
regie.service = 'dummy'
|
|
|
|
regie.service_options = {'siret': '1234'}
|
|
|
|
regie.save()
|
|
|
|
return regie
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def user():
|
|
|
|
try:
|
|
|
|
user = User.objects.get(username='admin')
|
|
|
|
except User.DoesNotExist:
|
|
|
|
user = User.objects.create_user('admin', email=None, password='admin')
|
|
|
|
return user
|
|
|
|
|
|
|
|
def login(username='admin', password='admin'):
|
|
|
|
resp = client.post('/login/', {'username': username, 'password': password})
|
|
|
|
assert resp.status_code == 302
|
|
|
|
|
|
|
|
def test_payment_min_amount(regie, user):
|
|
|
|
items = {'item1': {'amount': '1.5', 'source_url': '/item/1'},
|
|
|
|
'item2': {'amount': '2.4', 'source_url': '/item/2'}
|
|
|
|
}
|
|
|
|
b_items = []
|
|
|
|
for subject, details in items.iteritems():
|
|
|
|
b_item = BasketItem.objects.create(user=user, regie=regie,
|
|
|
|
subject=subject, **details)
|
|
|
|
b_items.append(b_item.pk)
|
|
|
|
login()
|
|
|
|
resp = client.post(reverse('lingo-pay'), {'item': b_items, 'regie': regie.pk})
|
|
|
|
assert resp.status_code == 403
|
|
|
|
|
|
|
|
def test_successfull_items_payment(regie, user):
|
|
|
|
items = {'item1': {'amount': '10.5', 'source_url': '/item/1'},
|
|
|
|
'item2': {'amount': '42', 'source_url': '/item/2'},
|
|
|
|
'item3': {'amount': '100', 'source_url': '/item/3'},
|
|
|
|
'item4': {'amount': '354', 'source_url': '/item/4'}
|
|
|
|
}
|
|
|
|
b_items = []
|
|
|
|
for subject, details in items.iteritems():
|
|
|
|
b_item = BasketItem.objects.create(user=user, regie=regie,
|
|
|
|
subject=subject, **details)
|
|
|
|
b_items.append(b_item.pk)
|
|
|
|
login()
|
|
|
|
resp = client.post(reverse('lingo-pay'), {'item': b_items, 'regie': regie.pk})
|
|
|
|
assert resp.status_code == 302
|
|
|
|
location = resp.get('location')
|
|
|
|
assert 'dummy-payment' in location
|
|
|
|
parsed = urlparse.urlparse(location)
|
|
|
|
# get return_url and transaction id from location
|
|
|
|
qs = urlparse.parse_qs(parsed.query)
|
|
|
|
args = {'transaction_id': qs['transaction_id'][0], 'signed': True,
|
|
|
|
'ok': True, 'reason': 'Paid'}
|
|
|
|
# simulate backend callback call
|
|
|
|
resp = client.get(qs['return_url'][0], args)
|
|
|
|
assert resp.status_code == 200
|
|
|
|
|
|
|
|
def test_add_amount_to_basket(regie, user):
|
|
|
|
user_email = 'foo@example.com'
|
|
|
|
User.objects.get_or_create(email=user_email)
|
|
|
|
amount = 42
|
|
|
|
data = {'amount': amount, 'display_name': 'test amount',
|
|
|
|
'url': 'http://example.com'}
|
|
|
|
url = '%s?email=%s' % (reverse('api-add-basket-item'), user_email)
|
2015-12-31 16:16:04 +01:00
|
|
|
url = sign_url(url, settings.LINGO_API_SIGN_KEY)
|
2015-12-25 21:16:44 +01:00
|
|
|
resp = client.post(url, json.dumps(data), content_type='application/json')
|
|
|
|
assert resp.status_code == 200
|
|
|
|
assert json.loads(resp.content) == {'result': 'success'}
|
|
|
|
assert BasketItem.objects.filter(amount=amount).exists()
|
|
|
|
|
|
|
|
data['extra'] = {'amount': '22.22'}
|
2015-12-31 16:16:04 +01:00
|
|
|
url = sign_url(url, settings.LINGO_API_SIGN_KEY)
|
2015-12-25 21:16:44 +01:00
|
|
|
resp = client.post(url, json.dumps(data), content_type='application/json')
|
|
|
|
assert resp.status_code == 200
|
|
|
|
assert json.loads(resp.content) == {'result': 'success'}
|
|
|
|
assert BasketItem.objects.filter(amount=Decimal('64.22')).exists()
|
|
|
|
|
|
|
|
data['amount'] = [amount]
|
|
|
|
data['extra'] = {'amount': ['22.22', '12']}
|
|
|
|
resp = client.post('%s&amount=5' % url, json.dumps(data),
|
|
|
|
content_type='application/json')
|
|
|
|
assert resp.status_code == 200
|
|
|
|
assert json.loads(resp.content) == {'result': 'success'}
|
|
|
|
assert BasketItem.objects.filter(amount=Decimal('81.22')).exists()
|
|
|
|
|
|
|
|
|
|
|
|
def test_payment_callback(regie, user):
|
|
|
|
item = BasketItem.objects.create(user=user, regie=regie,
|
|
|
|
subject='test_item', amount='10.5',
|
|
|
|
source_url='/testitem')
|
|
|
|
login()
|
|
|
|
resp = client.post(reverse('lingo-pay'), {'item': [item.pk],
|
|
|
|
'regie': regie.pk})
|
|
|
|
assert resp.status_code == 302
|
|
|
|
location = resp.get('location')
|
|
|
|
parsed = urlparse.urlparse(location)
|
|
|
|
qs = urlparse.parse_qs(parsed.query)
|
|
|
|
transaction_id = qs['transaction_id'][0]
|
|
|
|
data = {'transaction_id': transaction_id, 'signed': True,
|
|
|
|
'amount': qs['amount'][0], 'ok': True}
|
|
|
|
|
|
|
|
# call callback with GET
|
|
|
|
get_resp = client.get(qs['return_url'][0], data)
|
|
|
|
assert get_resp.status_code == 200
|
|
|
|
assert Transaction.objects.get(order_id=transaction_id).status == 3
|
|
|
|
|
|
|
|
resp = client.post(reverse('lingo-pay'), {'item': [item.pk],
|
|
|
|
'regie': regie.pk})
|
|
|
|
assert resp.status_code == 302
|
|
|
|
location = resp.get('location')
|
|
|
|
parsed = urlparse.urlparse(location)
|
|
|
|
qs = urlparse.parse_qs(parsed.query)
|
|
|
|
transaction_id = qs['transaction_id'][0]
|
|
|
|
data = {'transaction_id': transaction_id, 'signed': True,
|
|
|
|
'amount': qs['amount'][0], 'ok': True}
|
|
|
|
|
|
|
|
# call callback with POST
|
|
|
|
post_resp = client.post(qs['return_url'][0], urllib.urlencode(data),
|
|
|
|
content_type='text/html')
|
|
|
|
assert post_resp.status_code == 200
|
|
|
|
assert Transaction.objects.get(order_id=transaction_id).status == 3
|