lingo/tests/pricing/manager/test_agenda.py

1001 lines
42 KiB
Python

import datetime
from decimal import Decimal
from unittest import mock
import pytest
from django.utils.timezone import now
from lingo.agendas.chrono import ChronoError
from lingo.agendas.models import Agenda, CheckType, CheckTypeGroup
from lingo.pricing.models import AgendaPricing, Criteria, CriteriaCategory, Pricing, PricingError
from tests.utils import login
pytestmark = pytest.mark.django_db
@mock.patch('lingo.pricing.views.refresh_agendas')
def test_refresh_agendas(mock_refresh, app, admin_user):
app = login(app)
resp = app.get('/manage/pricing/agendas/')
resp = resp.click('Refresh agendas')
assert resp.location.endswith('/manage/pricing/agendas/')
resp = resp.follow()
assert "Agendas refreshed." in resp
assert mock_refresh.call_args_list == [mock.call()]
def test_agenda_chrono_link(settings, app, admin_user):
settings.KNOWN_SERVICES = {}
agenda = Agenda.objects.create(label='Foo bar')
app = login(app)
resp = app.get('/manage/pricing/agendas/')
assert '/manage/agendas/%s/settings/' % agenda.slug not in resp
resp = app.get('/manage/pricing/agenda/%s/' % agenda.pk)
assert 'Agenda options' not in resp
assert '/manage/agendas/%s/settings/' % agenda.slug not in resp
settings.KNOWN_SERVICES['chrono'] = {'default': {'url': 'https://chrono.dev/'}}
resp = app.get('/manage/pricing/agendas/')
assert 'https://chrono.dev/manage/agendas/%s/settings/' % agenda.slug in resp
resp = app.get('/manage/pricing/agenda/%s/' % agenda.pk)
assert 'Agenda options' in resp
assert 'https://chrono.dev/manage/agendas/%s/settings/' % agenda.slug in resp
def test_add_agenda_pricing(app, admin_user):
agenda = Agenda.objects.create(label='Foo Bar')
pricing = Pricing.objects.create(label='Model')
app = login(app)
resp = app.get('/manage/pricing/agendas/')
resp = resp.click(href='/manage/pricing/agenda/%s/' % agenda.pk)
resp = resp.click('New pricing')
# first pricing, starts on today
assert resp.form['date_start'].value == now().strftime('%Y-%m-%d')
resp.form['pricing'] = pricing.pk
resp.form['date_start'] = '2021-09-01'
resp.form['date_end'] = '2021-09-01'
resp = resp.form.submit()
assert resp.context['form'].errors['date_end'] == ['End date must be greater than start date.']
resp.form['date_end'] = '2022-09-01'
resp = resp.form.submit()
agenda_pricing = AgendaPricing.objects.latest('pk')
assert resp.location.endswith('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
assert agenda_pricing.pricing == pricing
assert agenda_pricing.agenda == agenda
assert agenda_pricing.date_start == datetime.date(2021, 9, 1)
assert agenda_pricing.date_end == datetime.date(2022, 9, 1)
resp = app.get('/manage/pricing/agenda/%s/pricing/add/' % agenda.pk)
# starts on last date_end
assert resp.form['date_start'].value == '2022-09-01'
resp.form['pricing'] = pricing.pk
resp.form['date_start'] = '2021-11-01'
resp.form['date_end'] = '2022-11-01'
resp = resp.form.submit()
assert resp.context['form'].errors['__all__'] == ['Pricing overlaps existing pricings.']
resp.form['date_start'] = '2020-09-01'
resp.form['date_end'] = '2021-09-01'
resp = resp.form.submit()
agenda_pricing = AgendaPricing.objects.latest('pk')
assert agenda_pricing.pricing == pricing
assert agenda_pricing.agenda == agenda
assert agenda_pricing.date_start == datetime.date(2020, 9, 1)
assert agenda_pricing.date_end == datetime.date(2021, 9, 1)
resp = app.get('/manage/pricing/agenda/%s/' % agenda.pk)
assert AgendaPricing.objects.filter(agenda=agenda, pricing=pricing).count() == 2
assert resp.text.count('"/manage/pricing/model/%s/"' % pricing.pk) == 2
resp = app.get('/manage/pricing/agenda/%s/pricing/add/' % agenda.pk)
# starts on last date_end
assert resp.form['date_start'].value == '2022-09-01'
def test_edit_agenda_pricing(app, admin_user):
agenda = Agenda.objects.create(label='Foo Bar')
pricing = Pricing.objects.create(label='Model')
pricing2 = Pricing.objects.create(label='Model 2')
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
agenda2 = Agenda.objects.create(label='Foo Bar')
agenda_pricing2 = AgendaPricing.objects.create(
agenda=agenda2,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2022, month=9, day=1),
date_end=datetime.date(year=2023, month=9, day=1),
)
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
resp = resp.click(href='/manage/pricing/agenda/%s/pricing/%s/edit/' % (agenda.pk, agenda_pricing.pk))
assert resp.form['date_start'].value == '2021-09-01'
resp.form['pricing'] = pricing2.pk
resp.form['date_start'] = '2021-09-01'
resp.form['date_end'] = '2021-09-01'
resp = resp.form.submit()
assert resp.context['form'].errors['date_end'] == ['End date must be greater than start date.']
resp.form['date_start'] = '2021-11-01'
resp.form['date_end'] = '2022-11-01'
resp = resp.form.submit()
assert resp.context['form'].errors['__all__'] == ['Pricing overlaps existing pricings.']
resp.form['date_start'] = '2021-08-01'
resp.form['date_end'] = '2022-09-01'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
agenda_pricing.refresh_from_db()
assert agenda_pricing.pricing == pricing2
assert agenda_pricing.agenda == agenda
assert agenda_pricing.date_start == datetime.date(2021, 8, 1)
assert agenda_pricing.date_end == datetime.date(2022, 9, 1)
app.get('/manage/pricing/agenda/%s/pricing/%s/edit/' % (agenda.pk, agenda_pricing2.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/edit/' % (0, agenda_pricing.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/edit/' % (agenda.pk, 0), status=404)
def test_delete_agenda_pricing(app, admin_user):
agenda = Agenda.objects.create(label='Foo Bar')
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
agenda2 = Agenda.objects.create(label='Foo Bar')
agenda_pricing2 = AgendaPricing.objects.create(
agenda=agenda2,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
app = login(app)
app.get('/manage/pricing/agenda/%s/pricing/%s/delete/' % (agenda.pk, agenda_pricing2.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/delete/' % (0, agenda_pricing.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/delete/' % (agenda.pk, 0), status=404)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
resp = resp.click(href='/manage/pricing/agenda/%s/pricing/%s/delete/' % (agenda.pk, agenda_pricing.pk))
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda/%s/' % agenda.pk)
assert AgendaPricing.objects.filter(pk=agenda_pricing.pk).exists() is False
def test_detail_agenda_redirect(app, admin_user):
agenda = Agenda.objects.create(label='Foo Bar')
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/' % agenda.slug, status=302)
assert resp.location.endswith('/manage/pricing/agenda/%s/' % agenda.pk)
def test_detail_agenda_pricing(app, admin_user):
agenda = Agenda.objects.create(label='Foo Bar')
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
agenda2 = Agenda.objects.create(label='Foo Bar')
agenda_pricing2 = AgendaPricing.objects.create(
agenda=agenda2,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/' % agenda.pk)
resp = resp.click(href='/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing2.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/' % (0, agenda_pricing.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, 0), status=404)
def test_detail_agenda_pricing_3_categories(app, admin_user):
category1 = CriteriaCategory.objects.create(label='Cat 1')
Criteria.objects.create(label='Crit 1-1', slug='crit-1-1', category=category1, order=1)
Criteria.objects.create(label='Crit 1-2', slug='crit-1-2', category=category1, order=2)
category2 = CriteriaCategory.objects.create(label='Cat 2')
Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1)
Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2)
Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3)
category3 = CriteriaCategory.objects.create(label='Cat 3')
Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category1, through_defaults={'order': 1})
pricing.categories.add(category2, through_defaults={'order': 2})
pricing.categories.add(category3, through_defaults={'order': 3})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-1:crit-1-1': {
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-2': 132,
},
},
'cat-1:crit-1-2': {
'cat-2:crit-2-2': {
'cat-3:crit-3-3': 223,
},
},
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
assert '<h3>Crit 1-1</h3>' in resp
ths = resp.pyquery.find('table.pricing-matrix-crit-1-1 thead th')
assert len(ths) == 4
assert ths[0].text is None
assert ths[1].text == 'Crit 2-1'
assert ths[2].text == 'Crit 2-2'
assert ths[3].text == 'Crit 2-3'
assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1'
assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2'
assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3'
assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4'
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-1 td.pricing-cell-crit-2-1')[
0
].text
== '111.00'
)
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-1')[
0
].text
is None
) # not defined
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-3 td.pricing-cell-crit-2-1')[
0
].text
is None
) # wrong value
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-4 td.pricing-cell-crit-2-1')[
0
].text
== '114.00'
)
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-3')[
0
].text
== '132.00'
)
assert '<h3>Crit 1-2</h3>' in resp
ths = resp.pyquery.find('table.pricing-matrix-crit-1-2 thead th')
assert len(ths) == 4
assert ths[0].text is None
assert ths[1].text == 'Crit 2-1'
assert ths[2].text == 'Crit 2-2'
assert ths[3].text == 'Crit 2-3'
assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1'
assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2'
assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3'
assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4'
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-2')[
0
].text
is None
) # not defined
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-3 td.pricing-cell-crit-2-2')[
0
].text
== '223.00'
)
def test_detail_agenda_pricing_2_categories(app, admin_user):
category2 = CriteriaCategory.objects.create(label='Cat 2')
Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1)
Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2)
Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3)
category3 = CriteriaCategory.objects.create(label='Cat 3')
Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category2, through_defaults={'order': 1})
pricing.categories.add(category3, through_defaults={'order': 2})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-2': 132,
},
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
assert len(resp.pyquery.find('div.section.prixing-matrix h3')) == 0
ths = resp.pyquery.find('table thead th')
assert len(ths) == 4
assert ths[0].text is None
assert ths[1].text == 'Crit 2-1'
assert ths[2].text == 'Crit 2-2'
assert ths[3].text == 'Crit 2-3'
assert resp.pyquery.find('table tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1'
assert resp.pyquery.find('table tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2'
assert resp.pyquery.find('table tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3'
assert resp.pyquery.find('table tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4'
assert resp.pyquery.find('table tr.pricing-row-crit-3-1 td.pricing-cell-crit-2-1')[0].text == '111.00'
assert (
resp.pyquery.find('table tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-1')[0].text is None
) # not defined
assert (
resp.pyquery.find('table tr.pricing-row-crit-3-3 td.pricing-cell-crit-2-1')[0].text is None
) # wrong value
assert resp.pyquery.find('table tr.pricing-row-crit-3-4 td.pricing-cell-crit-2-1')[0].text == '114.00'
assert resp.pyquery.find('table tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-3')[0].text == '132.00'
def test_detail_agenda_pricing_1_category(app, admin_user):
category3 = CriteriaCategory.objects.create(label='Cat 3')
Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category3, through_defaults={'order': 3})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
assert len(resp.pyquery.find('div.section.prixing-matrix h3')) == 0
ths = resp.pyquery.find('table thead')
assert len(ths) == 0
assert resp.pyquery.find('table tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1'
assert resp.pyquery.find('table tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2'
assert resp.pyquery.find('table tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3'
assert resp.pyquery.find('table tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4'
assert resp.pyquery.find('table tr.pricing-row-crit-3-1 td')[0].text == '111.00'
assert resp.pyquery.find('table tr.pricing-row-crit-3-2 td')[0].text is None # not defined
assert resp.pyquery.find('table tr.pricing-row-crit-3-3 td')[0].text is None # wrong value
assert resp.pyquery.find('table tr.pricing-row-crit-3-4 td')[0].text == '114.00'
@mock.patch('lingo.pricing.forms.get_event')
@mock.patch('lingo.pricing.forms.get_subscriptions')
@mock.patch('lingo.pricing.models.AgendaPricing.get_pricing_data')
def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions, mock_event, app, admin_user):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
assert 'Computed pricing data' not in resp
# check event date
mock_event.return_value = {'start_datetime': '2021-08-31T12:00:00+02:00'}
resp.form['event_slug'] = 'foo'
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp.form['booking_status'] = 'presence'
resp = resp.form.submit()
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['event_slug'] == [
'This event takes place outside the period covered by this pricing'
]
assert mock_event.call_args_list == [mock.call('foo-bar@foo')]
assert mock_pricing_data.call_args_list == []
mock_event.return_value = {'start_datetime': '2021-10-01T12:00:00+02:00'}
resp = resp.form.submit()
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['event_slug'] == [
'This event takes place outside the period covered by this pricing'
]
mock_event.return_value = {'start_datetime': '2021-09-01T12:00:00+02:00'}
# check event_slug & agenda
resp.form['event_slug'] = 'foo@foo'
resp = resp.form.submit()
assert resp.context['test_tool_form'].errors['event_slug'] == ['The agenda identifier is wrong (foo)']
# check subscriptions dates
mock_subscriptions.return_value = []
mock_event.reset_mock()
resp.form['event_slug'] = 'foo-bar@foo'
resp = resp.form.submit()
assert mock_event.call_args_list == [mock.call('foo-bar@foo')]
assert mock_pricing_data.call_args_list == []
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['user_external_id'] == [
'No subscription found for this event'
]
mock_subscriptions.return_value = [
{
'date_start': '2021-08-01',
'date_end': '2021-09-01',
},
{
'date_start': '2021-09-02',
'date_end': '2021-09-03',
},
]
resp = resp.form.submit()
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['user_external_id'] == [
'No subscription found for this event'
]
mock_subscriptions.return_value = [
{
'date_start': '2021-08-01',
'date_end': '2021-09-01',
},
{
'date_start': '2021-09-01',
'date_end': '2021-09-02',
},
{
'date_start': '2021-09-02',
'date_end': '2021-09-03',
},
]
mock_pricing_data.return_value = {'foo': 'bar', 'pricing': Decimal('42')}
resp = resp.form.submit()
assert 'Computed pricing data' in resp
assert mock_pricing_data.call_args_list == [
mock.call(
request=mock.ANY,
agenda=agenda,
agenda_pricing=agenda_pricing,
event={'start_datetime': '2021-09-01T12:00:00+02:00'},
subscription={'date_start': '2021-09-01', 'date_end': '2021-09-02'},
check_status={'status': 'presence', 'check_type': None},
booking={},
user_external_id='user:1',
adult_external_id='adult:1',
)
]
assert '<p>Pricing: 42.00</p>' in resp
assert '<pre>{&#39;foo&#39;: &#39;bar&#39;, &#39;pricing&#39;: Decimal(&#39;42&#39;)}</pre>' in resp
mock_pricing_data.side_effect = PricingError(details={'foo': 'error'})
resp = resp.form.submit()
assert 'Computed pricing data' in resp
assert '<pre>{&#39;error&#39;: {&#39;foo&#39;: &#39;error&#39;}}</pre>' in resp
@mock.patch('lingo.pricing.forms.get_event')
@mock.patch('lingo.pricing.forms.get_subscriptions')
def test_detail_agenda_pricing_test_tool_event_error(mock_subscriptions, mock_event, app, admin_user):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
mock_event.side_effect = ChronoError('foo bar foo-bar@foo-event')
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
resp.form['event_slug'] = 'foo-event'
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp.form['booking_status'] = 'presence'
# agenda slug is removed from error message
resp = resp.form.submit()
assert resp.context['test_tool_form'].errors['event_slug'] == ['foo bar foo-event']
# except it was included in event_slug
resp.form['event_slug'] = 'foo-bar@foo-event'
resp = resp.form.submit()
assert resp.context['test_tool_form'].errors['event_slug'] == ['foo bar foo-bar@foo-event']
@mock.patch('lingo.pricing.forms.get_event')
@mock.patch('lingo.pricing.forms.get_subscriptions')
def test_detail_agenda_pricing_test_tool_subscription_error(mock_subscriptions, mock_event, app, admin_user):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
mock_event.return_value = {'start_datetime': '2021-09-01T12:00:00+02:00'}
mock_subscriptions.side_effect = ChronoError('foo bar')
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
resp.form['event_slug'] = 'foo-event'
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp.form['booking_status'] = 'presence'
resp = resp.form.submit()
assert resp.context['test_tool_form'].errors['user_external_id'] == ['foo bar']
@mock.patch('lingo.pricing.forms.get_event')
@mock.patch('lingo.pricing.forms.get_subscriptions')
@mock.patch('lingo.pricing.models.AgendaPricing.get_pricing_data')
def test_detail_agenda_pricing_test_tool_booking_status(
mock_pricing_data, mock_subscriptions, mock_event, app, admin_user
):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
mock_event.return_value = {'start_datetime': '2021-09-01T12:00:00+02:00'}
mock_subscriptions.return_value = [
{
'date_start': '2021-09-01',
'date_end': '2021-09-02',
},
]
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
assert resp.form['booking_status'].options == [
('presence', False, 'Presence'),
('absence', False, 'Absence'),
]
group = CheckTypeGroup.objects.create(label='Foo bar')
CheckType.objects.create(label='Foo presence reason', group=group, kind='presence')
CheckType.objects.create(label='Foo absence reason', group=group, kind='absence')
agenda.check_type_group = group
agenda.save()
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
assert resp.form['booking_status'].options == [
('presence', False, 'Presence'),
('presence::foo-presence-reason', False, 'Presence (Foo presence reason)'),
('absence', False, 'Absence'),
('absence::foo-absence-reason', False, 'Absence (Foo absence reason)'),
]
resp.form['event_slug'] = 'foo'
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp.form['booking_status'] = 'presence'
resp = resp.form.submit()
assert mock_pricing_data.call_args_list[0][1]['check_status'] == {
'check_type': None,
'status': 'presence',
}
mock_pricing_data.reset_mock()
resp.form['booking_status'] = 'presence::foo-presence-reason'
resp = resp.form.submit()
assert mock_pricing_data.call_args_list[0][1]['check_status'] == {
'check_type': 'foo-presence-reason',
'status': 'presence',
}
mock_pricing_data.reset_mock()
resp.form['booking_status'] = 'absence'
resp = resp.form.submit()
assert mock_pricing_data.call_args_list[0][1]['check_status'] == {'check_type': None, 'status': 'absence'}
mock_pricing_data.reset_mock()
resp.form['booking_status'] = 'absence::foo-absence-reason'
resp = resp.form.submit()
assert mock_pricing_data.call_args_list[0][1]['check_status'] == {
'check_type': 'foo-absence-reason',
'status': 'absence',
}
def test_edit_agenda_pricing_matrix_3_categories(app, admin_user):
category1 = CriteriaCategory.objects.create(label='Cat 1')
criteria11 = Criteria.objects.create(label='Crit 1-1', slug='crit-1-1', category=category1, order=1)
criteria12 = Criteria.objects.create(label='Crit 1-2', slug='crit-1-2', category=category1, order=2)
category2 = CriteriaCategory.objects.create(label='Cat 2')
criteria21 = Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1)
Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2)
Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3)
category3 = CriteriaCategory.objects.create(label='Cat 3')
criteria31 = Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category1, through_defaults={'order': 1})
pricing.categories.add(category2, through_defaults={'order': 2})
pricing.categories.add(category3, through_defaults={'order': 3})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-1:crit-1-1': {
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-2': 132,
},
},
'cat-1:crit-1-2': {
'cat-2:crit-2-2': {
'cat-3:crit-3-3': 223,
},
},
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
resp = resp.click(
href='/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/'
% (agenda.pk, agenda_pricing.pk, criteria11.slug)
)
assert resp.form['form-0-crit_0'].value == '111'
assert resp.form['form-0-crit_1'].value == ''
assert resp.form['form-0-crit_2'].value == ''
assert resp.form['form-1-crit_0'].value == ''
assert resp.form['form-1-crit_1'].value == ''
assert resp.form['form-1-crit_2'].value == '132'
assert resp.form['form-2-crit_0'].value == ''
assert resp.form['form-2-crit_1'].value == ''
assert resp.form['form-2-crit_2'].value == ''
assert resp.form['form-3-crit_0'].value == '114'
assert resp.form['form-3-crit_1'].value == ''
assert resp.form['form-3-crit_2'].value == ''
resp.form['form-0-crit_1'] = '121'
resp.form['form-0-crit_2'] = '131'
resp.form['form-1-crit_0'] = '112'
resp.form['form-1-crit_1'] = '122'
resp.form['form-1-crit_2'] = '132.5'
resp.form['form-2-crit_0'] = '113'
resp.form['form-2-crit_1'] = '123'
resp.form['form-2-crit_2'] = '133'
resp.form['form-3-crit_0'] = '914'
resp.form['form-3-crit_1'] = '124'
resp.form['form-3-crit_2'] = '134'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
agenda_pricing.refresh_from_db()
assert agenda_pricing.pricing_data == {
'cat-1:crit-1-1': {
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-2': 112,
'cat-3:crit-3-3': 113,
'cat-3:crit-3-4': 914,
},
'cat-2:crit-2-2': {
'cat-3:crit-3-1': 121,
'cat-3:crit-3-2': 122,
'cat-3:crit-3-3': 123,
'cat-3:crit-3-4': 124,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-1': 131,
'cat-3:crit-3-2': 132.5,
'cat-3:crit-3-3': 133,
'cat-3:crit-3-4': 134,
},
},
'cat-1:crit-1-2': {
'cat-2:crit-2-2': {
'cat-3:crit-3-3': 223,
},
},
}
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/'
% (agenda.pk, agenda_pricing.pk, criteria12.slug),
status=200,
)
agenda2 = Agenda.objects.create(label='Foo Bar')
agenda_pricing2 = AgendaPricing.objects.create(
agenda=agenda2,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/'
% (agenda.pk, agenda_pricing2.pk, criteria11.slug),
status=404,
)
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' % (0, agenda_pricing.pk, criteria11.slug),
status=404,
)
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' % (agenda.pk, 0, criteria11.slug), status=404
)
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' % (agenda.pk, agenda_pricing.pk, 'unknown'),
status=404,
)
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/'
% (agenda.pk, agenda_pricing.pk, criteria21.slug),
status=404,
)
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/'
% (agenda.pk, agenda_pricing.pk, criteria31.slug),
status=404,
)
app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk), status=404)
def test_edit_agenda_pricing_matrix_2_categories(app, admin_user):
category2 = CriteriaCategory.objects.create(label='Cat 2')
criteria21 = Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1)
Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2)
Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3)
category3 = CriteriaCategory.objects.create(label='Cat 3')
criteria31 = Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category2, through_defaults={'order': 1})
pricing.categories.add(category3, through_defaults={'order': 2})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-2': 132,
},
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
resp = resp.click(
href='/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk)
)
assert resp.form['form-0-crit_0'].value == '111'
assert resp.form['form-0-crit_1'].value == ''
assert resp.form['form-0-crit_2'].value == ''
assert resp.form['form-1-crit_0'].value == ''
assert resp.form['form-1-crit_1'].value == ''
assert resp.form['form-1-crit_2'].value == '132'
assert resp.form['form-2-crit_0'].value == ''
assert resp.form['form-2-crit_1'].value == ''
assert resp.form['form-2-crit_2'].value == ''
assert resp.form['form-3-crit_0'].value == '114'
assert resp.form['form-3-crit_1'].value == ''
assert resp.form['form-3-crit_2'].value == ''
resp.form['form-0-crit_1'] = '121'
resp.form['form-0-crit_2'] = '131'
resp.form['form-1-crit_0'] = '112'
resp.form['form-1-crit_1'] = '122'
resp.form['form-1-crit_2'] = '132.5'
resp.form['form-2-crit_0'] = '113'
resp.form['form-2-crit_1'] = '123'
resp.form['form-2-crit_2'] = '133'
resp.form['form-3-crit_0'] = '914'
resp.form['form-3-crit_1'] = '124'
resp.form['form-3-crit_2'] = '134'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
agenda_pricing.refresh_from_db()
assert agenda_pricing.pricing_data == {
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-2': 112,
'cat-3:crit-3-3': 113,
'cat-3:crit-3-4': 914,
},
'cat-2:crit-2-2': {
'cat-3:crit-3-1': 121,
'cat-3:crit-3-2': 122,
'cat-3:crit-3-3': 123,
'cat-3:crit-3-4': 124,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-1': 131,
'cat-3:crit-3-2': 132.5,
'cat-3:crit-3-3': 133,
'cat-3:crit-3-4': 134,
},
}
agenda2 = Agenda.objects.create(label='Foo Bar')
agenda_pricing2 = AgendaPricing.objects.create(
agenda=agenda2,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing2.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (0, agenda_pricing.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, 0), status=404)
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/'
% (agenda.pk, agenda_pricing.pk, criteria21.slug),
status=404,
)
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/'
% (agenda.pk, agenda_pricing.pk, criteria31.slug),
status=404,
)
def test_edit_agenda_pricing_matrix_1_category(app, admin_user):
category3 = CriteriaCategory.objects.create(label='Cat 3')
criteria31 = Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category3, through_defaults={'order': 3})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
resp = resp.click(
href='/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk)
)
assert resp.form['form-0-crit_0'].value == '111'
assert resp.form['form-1-crit_0'].value == ''
assert resp.form['form-2-crit_0'].value == ''
assert resp.form['form-3-crit_0'].value == '114'
resp.form['form-1-crit_0'] = '112.5'
resp.form['form-2-crit_0'] = '113'
resp.form['form-3-crit_0'] = '914'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk))
agenda_pricing.refresh_from_db()
assert agenda_pricing.pricing_data == {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-2': 112.5,
'cat-3:crit-3-3': 113,
'cat-3:crit-3-4': 914,
}
agenda2 = Agenda.objects.create(label='Foo Bar')
agenda_pricing2 = AgendaPricing.objects.create(
agenda=agenda2,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing2.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (0, agenda_pricing.pk), status=404)
app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, 0), status=404)
app.get(
'/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/'
% (agenda.pk, agenda_pricing.pk, criteria31.slug),
status=404,
)
def test_edit_agenda_pricing_matrix_empty(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
agenda=agenda,
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app = login(app)
app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk), status=404)
def test_edit_agenda_check_type_group(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar')
group = CheckTypeGroup.objects.create(label='Foo bar')
app = login(app)
resp = app.get('/manage/pricing/agenda/%s/' % agenda.pk)
assert 'No check types configured for this agenda.' in resp
resp = resp.click(href='/manage/pricing/agenda/%s/check-options' % agenda.pk)
resp.form['check_type_group'] = group.pk
resp = resp.form.submit().follow()
agenda.refresh_from_db()
assert agenda.check_type_group == group
assert 'Check type group: Foo bar' in resp