diff --git a/tests/pricing/manager/test_agenda.py b/tests/pricing/manager/test_agenda.py index 75ffec7..7a19f32 100644 --- a/tests/pricing/manager/test_agenda.py +++ b/tests/pricing/manager/test_agenda.py @@ -1,13 +1,8 @@ -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 lingo.agendas.models import Agenda, CheckTypeGroup from tests.utils import login pytestmark = pytest.mark.django_db @@ -43,82 +38,6 @@ def test_agenda_chrono_link(settings, app, admin_user): assert 'https://chrono.dev/manage/agendas/%s/settings/' % agenda.slug in resp -def test_add_agenda_pricing(app, admin_user): - pricing = Pricing.objects.create(label='Model') - - app = login(app) - resp = app.get('/manage/pricing/') - resp = resp.click(href='/manage/pricing/agenda-pricings/') - 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-pricing/%s/' % agenda_pricing.pk) - assert agenda_pricing.pricing == pricing - assert list(agenda_pricing.agendas.all()) == [] - 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-pricing/add/') - # starts on last date_end - assert resp.form['date_start'].value == '2022-09-01' - - -def test_edit_agenda_pricing(app, admin_user): - pricing = Pricing.objects.create(label='Model') - pricing2 = Pricing.objects.create(label='Model 2') - agenda_pricing = AgendaPricing.objects.create( - 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) - resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk) - resp = resp.click(href='/manage/pricing/agenda-pricing/%s/edit/' % 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-08-01' - resp.form['date_end'] = '2022-09-01' - resp = resp.form.submit() - assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk) - agenda_pricing.refresh_from_db() - assert agenda_pricing.pricing == pricing2 - 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-pricing/%s/edit/' % 0, status=404) - - -def test_delete_agenda_pricing(app, admin_user): - pricing = Pricing.objects.create(label='Model') - agenda_pricing = AgendaPricing.objects.create( - 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-pricing/%s/delete/' % 0, status=404) - - resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk) - resp = resp.click(href='/manage/pricing/agenda-pricing/%s/delete/' % agenda_pricing.pk) - resp = resp.form.submit() - assert resp.location.endswith('/manage/pricing/agenda-pricings/') - assert AgendaPricing.objects.exists() is False - - def test_detail_agenda_redirect(app, admin_user): agenda = Agenda.objects.create(label='Foo Bar') @@ -127,737 +46,6 @@ def test_detail_agenda_redirect(app, admin_user): assert resp.location.endswith('/manage/pricing/agenda/%s/' % agenda.pk) -def test_detail_agenda_pricing(app, admin_user): - pricing = Pricing.objects.create(label='Model') - agenda_pricing = AgendaPricing.objects.create( - 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-pricings/') - resp = resp.click(href='/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk) - - app.get('/manage/pricing/agenda-pricing/%s/' % 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) - - 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( - 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-pricing/%s/' % agenda_pricing.pk) - assert '

Crit 1-1

' 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 '

Crit 1-2

' 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) - - 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( - 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-pricing/%s/' % 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) - - 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( - 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-pricing/%s/' % 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( - pricing=pricing, - date_start=datetime.date(year=2021, month=9, day=1), - date_end=datetime.date(year=2021, month=10, day=1), - ) - agenda_pricing.agendas.add(agenda) - - app = login(app) - resp = app.get('/manage/pricing/agenda-pricing/%s/' % 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 '

Pricing: 42.00

' in resp - assert '
{'foo': 'bar', 'pricing': Decimal('42')}
' in resp - - mock_pricing_data.side_effect = PricingError(details={'foo': 'error'}) - resp = resp.form.submit() - assert 'Computed pricing data' in resp - assert '
{'error': {'foo': 'error'}}
' 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( - pricing=pricing, - date_start=datetime.date(year=2021, month=9, day=1), - date_end=datetime.date(year=2021, month=10, day=1), - ) - agenda_pricing.agendas.add(agenda) - - mock_event.side_effect = ChronoError('foo bar foo-bar@foo-event') - - app = login(app) - resp = app.get('/manage/pricing/agenda-pricing/%s/' % 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( - pricing=pricing, - date_start=datetime.date(year=2021, month=9, day=1), - date_end=datetime.date(year=2021, month=10, day=1), - ) - agenda_pricing.agendas.add(agenda) - - 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-pricing/%s/' % 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( - pricing=pricing, - date_start=datetime.date(year=2021, month=9, day=1), - date_end=datetime.date(year=2021, month=10, day=1), - ) - agenda_pricing.agendas.add(agenda) - - 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-pricing/%s/' % 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-pricing/%s/' % 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) - - 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( - 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-pricing/%s/' % agenda_pricing.pk) - resp = resp.click( - href='/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (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-pricing/%s/' % 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-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria12.slug), - status=200, - ) - - app.get('/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (0, criteria11.slug), status=404) - app.get( - '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, 'unknown'), - status=404, - ) - app.get( - '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria21.slug), - status=404, - ) - app.get( - '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria31.slug), - status=404, - ) - app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % 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) - - 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( - 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-pricing/%s/' % agenda_pricing.pk) - resp = resp.click(href='/manage/pricing/agenda-pricing/%s/matrix/edit/' % 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-pricing/%s/' % 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, - }, - } - - app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % 0, status=404) - app.get( - '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria21.slug), - status=404, - ) - app.get( - '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (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) - - 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( - 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-pricing/%s/' % agenda_pricing.pk) - resp = resp.click(href='/manage/pricing/agenda-pricing/%s/matrix/edit/' % 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-pricing/%s/' % 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, - } - - app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % 0, status=404) - app.get( - '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria31.slug), - status=404, - ) - - -def test_edit_agenda_pricing_matrix_empty(app, admin_user): - pricing = Pricing.objects.create(label='Foo bar') - agenda_pricing = AgendaPricing.objects.create( - 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-pricing/%s/matrix/edit/' % 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') diff --git a/tests/pricing/manager/test_agenda_pricing.py b/tests/pricing/manager/test_agenda_pricing.py new file mode 100644 index 0000000..fe4b2a6 --- /dev/null +++ b/tests/pricing/manager/test_agenda_pricing.py @@ -0,0 +1,820 @@ +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 + + +def test_add_agenda_pricing(app, admin_user): + pricing = Pricing.objects.create(label='Model') + + app = login(app) + resp = app.get('/manage/pricing/') + resp = resp.click(href='/manage/pricing/agenda-pricings/') + 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-pricing/%s/' % agenda_pricing.pk) + assert agenda_pricing.pricing == pricing + assert list(agenda_pricing.agendas.all()) == [] + 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-pricing/add/') + # starts on last date_end + assert resp.form['date_start'].value == '2022-09-01' + + +def test_edit_agenda_pricing(app, admin_user): + pricing = Pricing.objects.create(label='Model') + pricing2 = Pricing.objects.create(label='Model 2') + agenda_pricing = AgendaPricing.objects.create( + 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) + resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk) + resp = resp.click(href='/manage/pricing/agenda-pricing/%s/edit/' % 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-08-01' + resp.form['date_end'] = '2022-09-01' + resp = resp.form.submit() + assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk) + agenda_pricing.refresh_from_db() + assert agenda_pricing.pricing == pricing2 + 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-pricing/%s/edit/' % 0, status=404) + + +def test_detail_agenda_pricing(app, admin_user): + pricing = Pricing.objects.create(label='Model') + agenda_pricing = AgendaPricing.objects.create( + 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-pricings/') + resp = resp.click(href='/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk) + + app.get('/manage/pricing/agenda-pricing/%s/' % 0, status=404) + + +def test_delete_agenda_pricing(app, admin_user): + pricing = Pricing.objects.create(label='Model') + agenda_pricing = AgendaPricing.objects.create( + 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-pricing/%s/delete/' % 0, status=404) + + resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk) + resp = resp.click(href='/manage/pricing/agenda-pricing/%s/delete/' % agenda_pricing.pk) + resp = resp.form.submit() + assert resp.location.endswith('/manage/pricing/agenda-pricings/') + assert AgendaPricing.objects.exists() is False + + +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) + + 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( + 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-pricing/%s/' % agenda_pricing.pk) + assert '

Crit 1-1

' 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 '

Crit 1-2

' 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) + + 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( + 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-pricing/%s/' % 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) + + 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( + 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-pricing/%s/' % 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( + pricing=pricing, + date_start=datetime.date(year=2021, month=9, day=1), + date_end=datetime.date(year=2021, month=10, day=1), + ) + agenda_pricing.agendas.add(agenda) + + app = login(app) + resp = app.get('/manage/pricing/agenda-pricing/%s/' % 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 '

Pricing: 42.00

' in resp + assert '
{'foo': 'bar', 'pricing': Decimal('42')}
' in resp + + mock_pricing_data.side_effect = PricingError(details={'foo': 'error'}) + resp = resp.form.submit() + assert 'Computed pricing data' in resp + assert '
{'error': {'foo': 'error'}}
' 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( + pricing=pricing, + date_start=datetime.date(year=2021, month=9, day=1), + date_end=datetime.date(year=2021, month=10, day=1), + ) + agenda_pricing.agendas.add(agenda) + + mock_event.side_effect = ChronoError('foo bar foo-bar@foo-event') + + app = login(app) + resp = app.get('/manage/pricing/agenda-pricing/%s/' % 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( + pricing=pricing, + date_start=datetime.date(year=2021, month=9, day=1), + date_end=datetime.date(year=2021, month=10, day=1), + ) + agenda_pricing.agendas.add(agenda) + + 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-pricing/%s/' % 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( + pricing=pricing, + date_start=datetime.date(year=2021, month=9, day=1), + date_end=datetime.date(year=2021, month=10, day=1), + ) + agenda_pricing.agendas.add(agenda) + + 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-pricing/%s/' % 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-pricing/%s/' % 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) + + 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( + 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-pricing/%s/' % agenda_pricing.pk) + resp = resp.click( + href='/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (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-pricing/%s/' % 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-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria12.slug), + status=200, + ) + + app.get('/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (0, criteria11.slug), status=404) + app.get( + '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, 'unknown'), + status=404, + ) + app.get( + '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria21.slug), + status=404, + ) + app.get( + '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria31.slug), + status=404, + ) + app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % 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) + + 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( + 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-pricing/%s/' % agenda_pricing.pk) + resp = resp.click(href='/manage/pricing/agenda-pricing/%s/matrix/edit/' % 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-pricing/%s/' % 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, + }, + } + + app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % 0, status=404) + app.get( + '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria21.slug), + status=404, + ) + app.get( + '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (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) + + 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( + 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-pricing/%s/' % agenda_pricing.pk) + resp = resp.click(href='/manage/pricing/agenda-pricing/%s/matrix/edit/' % 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-pricing/%s/' % 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, + } + + app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % 0, status=404) + app.get( + '/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria31.slug), + status=404, + ) + + +def test_edit_agenda_pricing_matrix_empty(app, admin_user): + pricing = Pricing.objects.create(label='Foo bar') + agenda_pricing = AgendaPricing.objects.create( + 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-pricing/%s/matrix/edit/' % agenda_pricing.pk, status=404)