diff --git a/tests/test_lingo_cells.py b/tests/test_lingo_cells.py new file mode 100644 index 00000000..8c9d83df --- /dev/null +++ b/tests/test_lingo_cells.py @@ -0,0 +1,70 @@ +import pytest + +from django.contrib.auth.models import User +from django.test.client import RequestFactory +from django.template import Context +from django.utils import timezone + +from combo.data.models import Page +from combo.apps.lingo.models import Regie, BasketItem, Transaction +from combo.apps.lingo.models import LingoBasketCell, LingoRecentTransactionsCell + +pytestmark = pytest.mark.django_db + +@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 + +@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.save() + return regie + +def test_cell_disabled(): + Regie.objects.all().delete() + assert LingoBasketCell.is_enabled() is False + assert LingoRecentTransactionsCell.is_enabled() is False + +def test_cell_enabled(regie): + assert LingoBasketCell.is_enabled() is True + assert LingoRecentTransactionsCell.is_enabled() is True + +def test_basket_cell(regie, user): + page = Page(title='xxx', slug='test_basket_cell', template_name='standard') + page.save() + cell = LingoBasketCell(page=page, placeholder='content', order=0) + + context = Context({'request': RequestFactory().get('/')}) + context['request'].user = None + assert cell.is_relevant(context) is False + context['request'].user = user + assert cell.is_relevant(context) is False + item = BasketItem() + item.user = user + item.regie = regie + item.subject = 'foo' + item.source_url = 'http://example.net' + item.amount = 12345 + item.save() + assert cell.is_relevant(context) is True + + item.cancellation_date = timezone.now() + item.save() + assert cell.is_relevant(context) is False + + item.cancellation_date = None + item.save() + + content = cell.render(context) + assert '12345' in content diff --git a/tests/test_lingo_manager.py b/tests/test_lingo_manager.py new file mode 100644 index 00000000..2150f317 --- /dev/null +++ b/tests/test_lingo_manager.py @@ -0,0 +1,68 @@ +from django.contrib.auth.models import User +from django.core.wsgi import get_wsgi_application +from webtest import TestApp +import pytest + +from combo.apps.lingo.models import Regie + +pytestmark = pytest.mark.django_db + +@pytest.fixture +def admin_user(): + try: + user = User.objects.get(username='admin') + except User.DoesNotExist: + user = User.objects.create_superuser('admin', email=None, password='admin') + return user + +def login(app, username='admin', password='admin'): + login_page = app.get('/login/') + login_form = login_page.forms[0] + login_form['username'] = username + login_form['password'] = password + resp = login_form.submit() + assert resp.status_int == 302 + return app + +def test_access(admin_user): + app = login(TestApp(get_wsgi_application())) + resp = app.get('/manage/', status=200) + assert '/manage/lingo/' in resp.body + +def test_add_regie(admin_user): + Regie.objects.all().delete() + app = login(TestApp(get_wsgi_application())) + resp = app.get('/manage/lingo/regies/', status=200) + resp = resp.click('New') + resp.forms[0]['label'] = 'Test' + resp.forms[0]['slug'] = 'test' + resp.forms[0]['description'] = 'description' + resp.forms[0]['service'] = 'dummy' + resp = resp.forms[0].submit() + assert resp.location == 'http://localhost:80/manage/lingo/regies/' + assert Regie.objects.count() == 1 + regie = Regie.objects.all()[0] + assert regie.label == 'Test' + +def test_edit_regie(admin_user): + test_add_regie(admin_user) + app = login(TestApp(get_wsgi_application())) + resp = app.get('/manage/lingo/regies/', status=200) + resp = resp.click('Test') + resp.forms[0]['description'] = 'other description' + resp = resp.forms[0].submit() + assert resp.location == 'http://localhost:80/manage/lingo/regies/' + assert Regie.objects.count() == 1 + regie = Regie.objects.all()[0] + assert regie.description == 'other description' + +def test_delete_regie(admin_user): + test_add_regie(admin_user) + app = login(TestApp(get_wsgi_application())) + resp = app.get('/manage/lingo/regies/', status=200) + resp = resp.click('Test') + resp = resp.click('Delete') + assert 'Are you sure you want to delete this?' in resp.body + resp = resp.forms[0].submit() + assert resp.location == 'http://localhost:80/manage/lingo/regies/' + assert Regie.objects.count() == 0 diff --git a/tests/test_lingo_payment.py b/tests/test_lingo_payment.py new file mode 100644 index 00000000..b4098674 --- /dev/null +++ b/tests/test_lingo_payment.py @@ -0,0 +1,147 @@ +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 +from webtest import TestApp + +from django.test import Client + +from combo.apps.lingo.models import Regie, BasketItem, Transaction, RemoteItem + +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) + 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'} + 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