combo/tests/test_lingo_manager.py

631 lines
23 KiB
Python

# -*- coding: utf-8 -*-
import datetime
from django.contrib.auth.models import User
from django.utils.timezone import now
import mock
import pytest
import eopayment
from combo.data.models import Page
from combo.apps.lingo.models import (Regie, BasketItem, Transaction, ActiveItems,
TipiPaymentFormCell, PaymentBackend)
from decimal import Decimal
pytestmark = pytest.mark.django_db
@pytest.fixture
def payment_backend():
return PaymentBackend.objects.create(
label='test1', slug='test1', service='dummy', service_options={'siret': '1234'})
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(app, admin_user):
app = login(app)
resp = app.get('/manage/', status=200)
assert '/manage/lingo/' in resp.text
def test_add_regie(app, admin_user, payment_backend):
Regie.objects.all().delete()
app = login(app)
resp = app.get('/manage/lingo/regies/', status=200)
resp = resp.click('New')
assert '/manage/lingo/regies/' in resp.text
resp.forms[0]['label'] = 'Test'
resp.forms[0]['slug'] = 'test'
resp.forms[0]['description'] = 'description'
resp.forms[0]['payment_backend'] = payment_backend.pk
resp = resp.forms[0].submit()
assert resp.location.endswith('/manage/lingo/regies/')
assert Regie.objects.count() == 1
regie = Regie.objects.all()[0]
assert regie.label == 'Test'
assert regie.is_default is True
def test_edit_regie(app, admin_user, payment_backend):
test_add_regie(app, admin_user, payment_backend)
app = login(app)
resp = app.get('/manage/lingo/regies/', status=200)
resp = resp.click('Test')
assert '/manage/lingo/regies/' in resp.text
resp.forms[0]['description'] = 'other description'
resp = resp.forms[0].submit()
assert resp.location.endswith('/manage/lingo/regies/')
assert Regie.objects.count() == 1
regie = Regie.objects.all()[0]
assert regie.description == 'other description'
def test_edit_regie_dynamic_backend_fields(app, admin_user):
payment_backend = PaymentBackend.objects.create(
label='test1', slug='test1', service='systempayv2', service_options={'siret': '1234'})
regie = Regie.objects.create(
label='test-regie', slug='test-regie', payment_backend=payment_backend)
assert regie.transaction_options == {}
app = login(app)
resp = app.get('/manage/lingo/regies/%s/edit' % regie.pk, status=200)
resp.forms[0]['label'] = 'test-regie'
resp.forms[0]['slug'] = 'test-regie'
resp.forms[0]['description'] = 'description'
resp.forms[0]['payment_backend'] = payment_backend.pk
assert resp.forms[0]['manual_validation'].checked is False
resp.forms[0]['manual_validation'] = True
resp = resp.forms[0].submit()
assert Regie.objects.count() == 1
regie = Regie.objects.get(slug='test-regie')
assert regie.transaction_options['manual_validation']
# No dynamic fields if no backend capabilities
payment_backend_dummy = PaymentBackend.objects.create(
label='test1', slug='test-dummy', service='dummy', service_options={'siret': '1234'})
regie_dummy = Regie.objects.create(
label='test-regie-2', slug='test-regie-2', payment_backend=payment_backend_dummy)
resp = app.get('/manage/lingo/regies/%s/edit' % regie_dummy.pk, status=200)
assert 'manual_validation' not in resp.forms[0].fields
resp.forms[0]['label'] = 'Test'
resp.forms[0]['slug'] = 'test-regie-2'
resp.forms[0]['description'] = 'description'
resp.forms[0]['payment_backend'] = payment_backend_dummy.pk
resp = resp.forms[0].submit()
regie_dummy = Regie.objects.get(slug='test-regie-2')
assert regie_dummy.transaction_options == {}
# Change backend
resp = app.get('/manage/lingo/regies/%s/edit' % regie.pk, status=200)
resp.forms[0]['label'] = 'test-regie'
resp.forms[0]['slug'] = 'test-regie'
resp.forms[0]['description'] = 'description'
resp.forms[0]['payment_backend'] = payment_backend_dummy.pk
assert resp.forms[0]['manual_validation'].checked is True
resp.forms[0]['manual_validation'] = True
resp = resp.forms[0].submit()
regie = Regie.objects.get(slug='test-regie')
assert regie.transaction_options == {}
def test_delete_regie(app, admin_user, payment_backend):
test_add_regie(app, admin_user, payment_backend)
app = login(app)
resp = app.get('/manage/lingo/regies/', status=200)
resp = resp.click('remove')
assert 'Are you sure you want to delete this?' in resp.text
resp = resp.forms[0].submit()
assert Regie.objects.count() == 0
def test_add_second_regie(app, admin_user, payment_backend):
test_add_regie(app, admin_user, payment_backend)
regie = Regie.objects.all()[0]
app = login(app)
resp = app.get('/manage/lingo/regies/', status=200)
resp = resp.click('New')
resp.forms[0]['label'] = 'Test2'
resp.forms[0]['slug'] = 'test2'
resp.forms[0]['description'] = 'description'
resp.forms[0]['payment_backend'] = payment_backend.pk
resp = resp.forms[0].submit()
assert resp.location.endswith('/manage/lingo/regies/')
assert Regie.objects.count() == 2
assert Regie.objects.get(id=regie.id).is_default is True
assert Regie.objects.exclude(id=regie.id)[0].is_default is False
def test_download_transaction(app, admin_user, payment_backend):
test_add_regie(app, admin_user, payment_backend)
regie = Regie.objects.filter(slug='test')[0]
user = User.objects.create_user('dimebag', 'dime@bag.pan', 'pwd')
user.last_name = u'Darëll'
user.first_name = 'Dimebag'
user.save()
b_item = BasketItem.objects.create(user=user, regie=regie, subject='it\'s a subject',
source_url='http://example.net', amount=18.5)
trans1 = Transaction.objects.create(regie=regie, remote_items='remote items lol', order_id='1', user=user,
bank_transaction_id='567', status=eopayment.PAID)
trans2 = Transaction.objects.create(regie=regie, remote_items='remote items omg', order_id='2', user=user,
bank_transaction_id='136', status=eopayment.PAID)
trans1.items.set([b_item])
trans1.start_date = datetime.date(2019, 7, 29)
trans1.save()
trans2.items.set([b_item])
trans2.start_date = datetime.date(2019, 10, 1)
trans2.save()
app = login(app)
resp = app.get('/manage/lingo/transactions/download-csv/', status=200)
resp.forms[0]['start_date'] = datetime.date(2019, 10, 1)
resp.forms[0]['end_date'] = datetime.date(2019, 11, 1)
resp = resp.forms[0].submit()
content = [i for i in [item.split(',') for item in resp.text.split('\r\n')] if len(i) > 1]
assert len(content) == 1
row = content[0]
assert row[0] == '2'
assert row[1] == trans2.bank_transaction_id
assert row[3] == '%s %s' % (user.first_name, user.last_name)
assert Decimal(row[4]) == Decimal(trans2.amount)
assert row[5] == b_item.subject
assert Decimal(row[6]) == b_item.amount
resp = app.get('/manage/lingo/transactions/download-csv/', status=200)
resp.forms[0]['start_date'] = datetime.date(2019, 7, 1)
resp.forms[0]['end_date'] = datetime.date(2019, 11, 1)
resp = resp.forms[0].submit()
content = [i for i in [item.split(',') for item in resp.text.split('\r\n')] if len(i) > 1]
assert len(content) == 2
row = content[0]
assert row[0] == '2'
row = content[1]
assert row[0] == '1'
assert row[1] == trans1.bank_transaction_id
assert row[3] == '%s %s' % (user.first_name, user.last_name)
assert Decimal(row[4]) == Decimal(trans1.amount)
assert row[5] == b_item.subject
assert Decimal(row[6]) == b_item.amount
def test_transactions_search(app, admin_user):
for i in range(50):
Transaction(status=eopayment.PAID,
order_id='order id %s' % (i+1),
bank_transaction_id='bank id %s' % (i+1),
amount=1+i).save()
app = login(app)
resp = app.get('/manage/lingo/', status=200)
assert resp.text.count('<tr') == 11
resp.form['q'] = 'order id 16'
resp = resp.form.submit()
assert resp.text.count('<tr') == 2
resp.form['q'] = now().strftime('%d/%m/%Y')
resp = resp.form.submit()
assert resp.text.count('<tr') == 11
resp.form['q'] = (now() + datetime.timedelta(days=2)).strftime('%d/%m%/Y')
resp = resp.form.submit()
assert resp.text.count('<tr') == 0
assert 'No transactions found matching' in resp.text
def test_basketitem_error_list(app, admin_user, payment_backend):
regie = Regie.objects.create(
label='test-regie',
slug='test-regie',
payment_backend=payment_backend)
user = User.objects.create_user('dimebag', 'dime@bag.pan', 'pwd')
regie_with_webservice_url = Regie.objects.create(
label='test-regie2',
slug='test-regie2',
payment_backend=payment_backend,
webservice_url='http://example.net')
date_now = now()
date_in_past = date_now - datetime.timedelta(minutes=300)
# item with payment_date and notification_date, status PAID
# => not displayed
item1 = BasketItem.objects.create(
user=user,
regie=regie,
subject='item 1',
source_url='http://example.net/1',
amount=1,
payment_date=date_in_past,
notification_date=date_in_past)
transaction11 = Transaction.objects.create(
status=eopayment.ERROR,
order_id='order id 1.1',
bank_transaction_id='bank_id_11',
amount=1)
transaction11.items.add(item1)
transaction12 = Transaction.objects.create(
status=eopayment.PAID,
order_id='order id 1.2',
bank_transaction_id='bank_id_12',
amount=1)
transaction12.items.add(item1)
# item with payment_date and notification_date, status ERROR
# => displayed
item2 = BasketItem.objects.create(
user=user,
regie=regie,
subject='item 2',
source_url='',
amount=2,
payment_date=date_in_past,
notification_date=date_in_past)
transaction21 = Transaction.objects.create(
status=eopayment.ERROR,
order_id='order id 2.1',
bank_transaction_id='bank_id_21',
amount=2)
transaction21.items.add(item2)
transaction22 = Transaction.objects.create(
status=eopayment.ERROR,
order_id='order id 2.2',
bank_transaction_id='bank_id_22',
amount=2)
transaction22.items.add(item2)
# the same but for the other regie
item2_bis = BasketItem.objects.create(
user=user,
regie=regie_with_webservice_url,
subject='item 2 bis',
source_url='',
amount=22222,
payment_date=date_in_past,
notification_date=date_in_past)
transaction2_bis = Transaction.objects.create(
status=eopayment.ERROR,
order_id='order id 2 bis',
bank_transaction_id='bank_id_2_bis',
amount=22222)
transaction2_bis.items.add(item2_bis)
# item without dates, status ERROR
# => displayed
item3 = BasketItem.objects.create(
user=user,
regie=regie,
subject='item 3',
source_url='http://example.net/3',
amount=3)
transaction3 = Transaction.objects.create(
status=eopayment.ERROR,
order_id='order id 3',
bank_transaction_id='bank_id_3',
amount=3)
transaction3.items.add(item3)
# item with payment_date but no notification_date, too young
# => not displayed
item4 = BasketItem.objects.create(
user=user,
regie=regie,
subject='item 4',
source_url='http://example.net/4',
amount=4,
payment_date=date_now,
notification_date=None)
transaction4 = Transaction.objects.create(
order_id='order id 4',
bank_transaction_id='bank_id_4',
amount=4)
transaction4.items.add(item4)
# item with payment_date but no notification_date, in the past
# => displayed
item5 = BasketItem.objects.create(
user=user,
regie=regie,
subject='item 5',
source_url='http://example.net/5',
amount=5,
payment_date=date_in_past,
notification_date=None)
transaction5 = Transaction.objects.create(
order_id='order id 5',
bank_transaction_id='bank_id_5',
amount=5)
transaction5.items.add(item5)
# the same but for the other regie
item5_bis = BasketItem.objects.create(
user=user,
regie=regie_with_webservice_url,
subject='item 5 bis',
source_url='http://example.net/5_bis',
amount=55555,
payment_date=date_in_past,
notification_date=None)
transaction5_bis = Transaction.objects.create(
order_id='order id 5 bis',
bank_transaction_id='bank_id_5_bis',
amount=55555)
transaction5_bis.items.add(item5_bis)
# item with payment_date but no notification_date, in the past
# => displayed
item6 = BasketItem.objects.create(
user=user,
regie=regie,
subject='item 6',
source_url='', # without source_url
amount=6,
payment_date=date_in_past,
notification_date=None)
transaction6 = Transaction.objects.create(
order_id='order id 6',
bank_transaction_id='bank_id_6',
amount=6)
transaction6.items.add(item6)
# item with payment_date, no notification_date, but a cancellation_date, in the past
# => not displayed
item7 = BasketItem.objects.create(
user=user,
regie=regie,
subject='item 7',
source_url='http://example.net/7',
amount=7,
payment_date=date_in_past,
notification_date=None,
cancellation_date=date_now)
transaction7 = Transaction.objects.create(
order_id='order id 7',
bank_transaction_id='bank_id_7',
amount=7)
transaction7.items.add(item7)
app = login(app)
resp = app.get('/manage/lingo/payments/error/', status=200)
assert list(resp.context['object_list']) == [item6, item5, item3, item2]
assert '<a href="%s">' % item6.source_url not in resp.text
assert '<a href="%s">' % item5.source_url in resp.text
assert '<a href="%s">' % item3.source_url in resp.text
assert '<a href="%s">' % item2.source_url not in resp.text
assert '/manage/lingo/?q=%s' % transaction6.bank_transaction_id in resp.text
assert '/manage/lingo/?q=%s' % transaction5.bank_transaction_id in resp.text
assert '/manage/lingo/?q=%s' % transaction3.bank_transaction_id not in resp.text
assert '/manage/lingo/?q=%s' % transaction22.bank_transaction_id not in resp.text
assert '/manage/lingo/item/%s/mark-as-notified/' % item6.pk not in resp.text
assert '/manage/lingo/item/%s/mark-as-notified/' % item5.pk in resp.text
assert '/manage/lingo/item/%s/mark-as-notified/' % item3.pk not in resp.text
assert '/manage/lingo/item/%s/mark-as-notified/' % item2.pk not in resp.text
def test_basketitem_error_list_search(app, admin_user, payment_backend):
regie = Regie.objects.create(
label='test-regie', slug='test-regie', payment_backend=payment_backend)
user = User.objects.create_user('dimebag', 'dime@bag.pan', 'pwd')
item = BasketItem.objects.create(
user=user,
regie=regie,
subject='item 1',
source_url='http://example.net/1',
amount=1)
transaction = Transaction.objects.create(
status=eopayment.ERROR,
order_id='order id 1',
bank_transaction_id='bank_id_1',
amount=1)
transaction.items.add(item)
app = login(app)
resp = app.get('/manage/lingo/payments/error/', status=200)
assert list(resp.context['object_list']) == [item]
resp.form['q'] = 'item 42'
resp = resp.form.submit()
assert list(resp.context['object_list']) == []
resp.form['q'] = 'item 1'
resp = resp.form.submit()
assert list(resp.context['object_list']) == [item]
resp.form['q'] = 'item'
resp = resp.form.submit()
assert list(resp.context['object_list']) == [item]
def test_basketitem_mark_as_notified(app, admin_user, payment_backend):
regie = Regie.objects.create(
label='test-regie', slug='test-regie', payment_backend=payment_backend)
user = User.objects.create_user('dimebag', 'dime@bag.pan', 'pwd')
date_now = now()
date_in_past = date_now - datetime.timedelta(minutes=300)
item = BasketItem.objects.create(
user=user,
regie=regie,
subject='item',
source_url='http://example.net/',
amount=42,
payment_date=date_in_past,
notification_date=date_in_past)
app = login(app)
# notification_date is not None
resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
# payment_date is not old enough
item.notification_date = None
item.payment_date = date_now
item.save()
resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
# cancellation_date is not None
item.payment_date = date_in_past
item.cancellation_date = date_now
item.save()
resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
# notification_date and cancellation_date are None, payment_date is old enough
# but webservice_url is not None
item.cancellation_date = None
item.save()
regie.webservice_url = 'http://example.net'
regie.save()
resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
# notification_date and cancellation_date are None, payment_date is old enough
# but source_url is not set
regie.webservice_url = ''
regie.save()
item.source_url = ''
item.save()
resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
# source_url is set
item.source_url = 'http://example.com'
item.save()
with mock.patch('combo.apps.lingo.models.BasketItem.notify') as mock_notify:
resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=302)
assert mock_notify.call_args_list == []
assert resp.location.endswith('/manage/lingo/payments/error/')
item.refresh_from_db()
assert item.notification_date is not None
def test_configure_tipi_cell(app, admin_user):
page = Page(title='tipi', slug='tipi', template_name='standard')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id, status=200)
cell = TipiPaymentFormCell(title='Test payment', page=page, placeholder='content', order=0)
cell.save()
resp = app.get('/manage/pages/%s/' % page.id, status=200)
assert resp.text.count('Exer:') == 1
assert resp.text.count('IDPCE:') == 1
assert resp.text.count('IDLIGNE:') == 1
assert resp.text.count('ROLREC:') == 1
assert resp.text.count('ROLDEB:') == 1
assert resp.text.count('ROLDET:') == 1
def test_configure_invoices_cell(app, admin_user, payment_backend):
page = Page(title='xxx', slug='test', template_name='standard')
page.save()
app = login(app)
resp = app.get('/manage/pages/%s/' % page.id, status=200)
# 2 occurences of tipi payment form should be present, and no other cells
assert resp.text.count('lingo') == 2
assert resp.text.count('lingo_tipipaymentformcell') == 2
regie = Regie()
regie.label = 'Test'
regie.slug = 'test'
regie.description = 'test'
regie.payment_backend = payment_backend
regie.save()
resp = app.get('/manage/pages/%s/' % page.id, status=200)
assert 'lingorecenttransactionscell' in resp.text # because there's a regie
assert not 'lingo_activeitems' in resp.text # because there's no webservice
regie.webservice_url = 'http://example.net/'
regie.save()
resp = app.get('/manage/pages/%s/' % page.id, status=200)
assert 'lingo_activeitems' in resp.text
cell = ActiveItems(regie='remote', page=page, placeholder='content', order=0)
cell.save()
resp = app.get('/manage/pages/%s/' % page.id, status=200)
assert 'clingo_activeitems-%s-regie' % cell.id not in resp.form.fields
assert 'clingo_activeitems-%s-title' % cell.id in resp.form.fields
regie2 = Regie()
regie2.label = 'Test2'
regie2.slug = 'test2'
regie2.description = 'test2'
regie2.webservice_url = 'http://example.net/'
regie2.payment_backend = payment_backend
regie2.save()
resp = app.get('/manage/pages/%s/' % page.id, status=200)
assert 'clingo_activeitems-%s-regie' % cell.id in resp.form.fields
assert 'clingo_activeitems-%s-title' % cell.id in resp.form.fields
options = [x[2] for x in resp.form['clingo_activeitems-%s-regie' % cell.id].options]
assert 'All' in options
assert regie.label in options
assert regie2.label in options
resp.form['clingo_activeitems-%s-regie' % cell.id].value = 'test2'
resp.form.submit()
assert ActiveItems.objects.get(id=cell.id).regie == regie2.slug
def test_payment_backend_list(app, admin_user):
PaymentBackend.objects.create(label='label1', slug='slug1')
PaymentBackend.objects.create(label='label2', slug='slug2')
app = login(app)
resp = app.get('/manage/lingo/paymentbackends/', status=200)
assert '/manage/lingo/paymentbackends/add' in resp.text
assert 'label1' in resp.text
assert 'label2' in resp.text
for payment_backend in PaymentBackend.objects.all():
assert '/manage/lingo/paymentbackends/%s' % payment_backend.pk in resp.text
assert '/manage/lingo/paymentbackends/%s/delete' % payment_backend.pk in resp.text
def test_add_payment_backend(app, admin_user):
assert not PaymentBackend.objects.count()
app = login(app)
resp = app.get('/manage/lingo/paymentbackends/add/', status=200)
assert '/manage/lingo/paymentbackends/' in resp.text
resp.forms[0]['label'] = 'Test'
resp.forms[0]['slug'] = 'test-add'
resp.forms[0]['service'] = 'dummy'
resp.forms[0]['service_options'] = '{"siret": "1234"}'
resp = resp.forms[0].submit()
assert PaymentBackend.objects.count() == 1
payment_backend = PaymentBackend.objects.get(slug='test-add')
assert payment_backend.label == 'Test'
assert payment_backend.service_options == {'siret': '1234'}
assert resp.location.endswith('/manage/lingo/paymentbackends/')
def test_edit_payment_backend(app, admin_user):
payment_backend = PaymentBackend.objects.create(label='label1', slug='slug1')
app = login(app)
resp = app.get('/manage/lingo/paymentbackends/%s/edit' % payment_backend.pk, status=200)
assert '/manage/lingo/paymentbackends/' in resp.text
resp.forms[0]['label'] = 'label1-modified'
resp.forms[0]['slug'] = 'slug1'
resp.forms[0]['service'] = 'dummy'
resp.forms[0]['service_options'] = '{"siret": "1234"}'
resp = resp.forms[0].submit()
assert resp.location.endswith('/manage/lingo/paymentbackends/')
payment_backend = PaymentBackend.objects.get(slug='slug1')
assert payment_backend.label == 'label1-modified'