1576 lines
49 KiB
Python
1576 lines
49 KiB
Python
import datetime
|
|
import decimal
|
|
import io
|
|
import json
|
|
import time
|
|
import xml.etree.ElementTree as ET
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
import responses
|
|
from django.utils.timezone import make_aware, now
|
|
|
|
from wcs import fields, workflow_tests
|
|
from wcs.blocks import BlockDef
|
|
from wcs.carddef import CardDef
|
|
from wcs.formdef import FormDef
|
|
from wcs.qommon.http_request import HTTPRequest
|
|
from wcs.qommon.storage import Equal
|
|
from wcs.qommon.upload_storage import PicklableUpload
|
|
from wcs.testdef import TestDef, TestDefXmlProxy, TestError, TestResult, WebserviceResponse
|
|
from wcs.wscalls import NamedWsCall
|
|
|
|
from .utilities import clean_temporary_pub, create_temporary_pub
|
|
|
|
|
|
@pytest.fixture
|
|
def pub():
|
|
pub = create_temporary_pub()
|
|
|
|
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
|
|
pub.set_app_dir(req)
|
|
pub.write_cfg()
|
|
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
WebserviceResponse.wipe()
|
|
NamedWsCall.wipe()
|
|
TestResult.wipe()
|
|
TestDef.wipe()
|
|
return pub
|
|
|
|
|
|
def teardown_module(module):
|
|
clean_temporary_pub()
|
|
|
|
|
|
def test_testdef_export_to_xml(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.ItemsField(id='1', label='Test', items=['foo', 'bar', 'baz']),
|
|
fields.BoolField(id='2', label='Check', varname='check'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
|
|
formdata.data['1'] = ['foo', 'baz']
|
|
formdata.data['2'] = True
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.workflow_tests.actions = [
|
|
workflow_tests.AssertStatus(status_name='End status'),
|
|
]
|
|
testdef.name = 'test'
|
|
testdef.expected_error = 'xxx'
|
|
testdef.store()
|
|
|
|
response = WebserviceResponse()
|
|
response.testdef_id = testdef.id
|
|
response.name = 'Fake response'
|
|
response.store()
|
|
|
|
testdef_xml = ET.tostring(testdef.export_to_xml())
|
|
TestDef.wipe()
|
|
workflow_tests.WorkflowTests.wipe()
|
|
WebserviceResponse.wipe()
|
|
|
|
testdef2 = TestDef.import_from_xml(io.BytesIO(testdef_xml), formdef)
|
|
testdef2.store()
|
|
assert testdef2.name == 'test'
|
|
assert testdef2.object_type == 'formdefs'
|
|
assert testdef2.object_id == str(formdef.id)
|
|
assert testdef2.data == {'fields': {'1': ['foo', 'baz'], '2': True}}
|
|
assert testdef2.expected_error == 'xxx'
|
|
assert testdef2.is_in_backoffice is False
|
|
|
|
assert len(testdef2.workflow_tests.actions) == 1
|
|
assert testdef2.workflow_tests.actions[0].status_name == 'End status'
|
|
|
|
assert len(testdef2.get_webservice_responses()) == 1
|
|
assert testdef2.get_webservice_responses()[0].name == 'Fake response'
|
|
|
|
# check storage of temporary object used during import is forbidden
|
|
testdef_xml = TestDefXmlProxy()
|
|
with pytest.raises(AssertionError):
|
|
testdef_xml.store()
|
|
|
|
|
|
def test_testdef_result_migrate_legacy_json(pub):
|
|
test_result = TestResult()
|
|
test_result.object_type = 'formdef'
|
|
test_result.object_id = '1'
|
|
test_result.timestamp = datetime.datetime(2021, 1, 1, 0, 0)
|
|
test_result.success = False
|
|
test_result.reason = 'xxx'
|
|
test_result.results = [
|
|
{
|
|
'id': '1',
|
|
'name': 'xxx',
|
|
'error': 'xxx',
|
|
'recorded_errors': ['a', 'b'],
|
|
'missing_required_fields': ['c', 'd'],
|
|
},
|
|
{
|
|
'id': '2',
|
|
'name': 'xxx',
|
|
'error': 'xxx',
|
|
},
|
|
]
|
|
test_result.store()
|
|
test_result.store()
|
|
|
|
TestResult.migrate_legacy()
|
|
test_result = TestResult.get(test_result.id)
|
|
assert test_result.results == [
|
|
{
|
|
'id': '1',
|
|
'name': 'xxx',
|
|
'error': 'xxx',
|
|
'details': {
|
|
'form_status': None,
|
|
'recorded_errors': ['a', 'b'],
|
|
'missing_required_fields': ['c', 'd'],
|
|
'workflow_test_action_uuid': None,
|
|
},
|
|
},
|
|
{
|
|
'id': '2',
|
|
'name': 'xxx',
|
|
'error': 'xxx',
|
|
'details': {
|
|
'form_status': None,
|
|
'recorded_errors': [],
|
|
'missing_required_fields': [],
|
|
'workflow_test_action_uuid': None,
|
|
},
|
|
},
|
|
]
|
|
|
|
|
|
def test_testdef_result_clean(pub, freezer):
|
|
def make_result(formdef_id, success):
|
|
test_result = TestResult()
|
|
test_result.object_type = 'formdef'
|
|
test_result.object_id = formdef_id
|
|
test_result.timestamp = now()
|
|
test_result.success = success
|
|
test_result.reason = 'xxx'
|
|
test_result.store()
|
|
|
|
# FormDef 1
|
|
freezer.move_to('2024-01-25 12:00')
|
|
for i in range(20):
|
|
make_result(formdef_id='1', success=True)
|
|
|
|
# FormDef 2
|
|
freezer.move_to('2024-01-10 12:00')
|
|
for i in range(15):
|
|
make_result(formdef_id='2', success=True)
|
|
|
|
for i in range(15):
|
|
freezer.move_to('2024-01-15 12:%s' % i)
|
|
make_result(formdef_id='2', success=True)
|
|
|
|
# FormDef 3
|
|
freezer.move_to('2024-01-10 12:00')
|
|
for i in range(15):
|
|
make_result(formdef_id='3', success=False)
|
|
|
|
freezer.move_to('2024-01-11 12:00')
|
|
make_result(formdef_id='3', success=True)
|
|
|
|
freezer.move_to('2024-01-12 12:00')
|
|
for i in range(5):
|
|
make_result(formdef_id='3', success=False)
|
|
|
|
freezer.move_to('2024-01-25 12:00')
|
|
for i in range(10):
|
|
make_result(formdef_id='3', success=False)
|
|
|
|
freezer.move_to('2024-02-01 12:00')
|
|
TestResult.clean()
|
|
|
|
# no deletion for FormDef 1
|
|
results_formdef1 = TestResult.select(clause=[Equal('object_id', '1')])
|
|
assert len(results_formdef1) == 20
|
|
|
|
# 10 most recent results were kept for FormDef 2
|
|
results_formdef2 = TestResult.select(clause=[Equal('object_id', '2')])
|
|
assert len(results_formdef2) == 10
|
|
assert all(x.timestamp.day == 15 for x in results_formdef2)
|
|
|
|
# all recently failed results were kept for FormDef 3, including last success
|
|
results_formdef3 = TestResult.select(clause=[Equal('object_id', '3')])
|
|
assert len(results_formdef3) == 16
|
|
assert len([x for x in results_formdef3 if x.success]) == 1
|
|
assert len([x for x in results_formdef3 if x.timestamp.day == 12]) == 5
|
|
assert len([x for x in results_formdef3 if x.timestamp.day == 25]) == 10
|
|
|
|
|
|
def test_testdef_create_from_formdata_boolean(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [fields.BoolField(id='1', label='Check', varname='check')]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
assert testdef.build_formdata(formdef, include_fields=True).data == {}
|
|
|
|
formdata.data['1'] = None
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
assert testdef.build_formdata(formdef, include_fields=True).data['1'] is None
|
|
|
|
formdata.data['1'] = True
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
assert testdef.build_formdata(formdef, include_fields=True).data['1'] is True
|
|
|
|
formdata.data['1'] = False
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
assert testdef.build_formdata(formdef, include_fields=True).data['1'] is False
|
|
|
|
|
|
def test_testdef_create_from_formdata_computed_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.ComputedField(id='1', label='Computed', varname='foo', value_template='{{ 1.2|decimal }}')
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.data['1'] = decimal.Decimal('1.2')
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.store()
|
|
|
|
assert testdef.data['fields'] == {}
|
|
|
|
|
|
def test_page_post_conditions(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.TitleField(id='0', label='Title'),
|
|
fields.PageField(
|
|
id='1',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{'condition': {'type': 'django', 'value': 'form_var_text == "a"'}, 'error_message': 'Error'}
|
|
],
|
|
),
|
|
fields.StringField(id='2', label='Text', varname='text'),
|
|
fields.PageField(
|
|
id='3',
|
|
label='2nd page',
|
|
post_conditions=[
|
|
{'condition': {'type': 'django', 'value': 'form_var_text2 == "a"'}, 'error_message': 'Error'}
|
|
],
|
|
),
|
|
fields.StringField(id='4', label='Text', varname='text2'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['2'] = 'a'
|
|
formdata.data['4'] = 'a'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['4'] = 'b'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 2 post condition was not met (form_var_text2 == "a").'
|
|
|
|
formdata.data['2'] = 'b'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 1 post condition was not met (form_var_text == "a").'
|
|
|
|
|
|
def test_page_post_condition_invalid(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[{'condition': {'type': 'django', 'value': '{{}'}, 'error_message': 'Error'}],
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Failed to evaluate page 1 post condition.'
|
|
|
|
|
|
def test_session_variables(pub):
|
|
user = pub.user_class(name='test user')
|
|
user.email = 'test@example.com'
|
|
user.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='1',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'session_hash_id|length == 40'},
|
|
'error_message': 'Error',
|
|
}
|
|
],
|
|
),
|
|
fields.PageField(
|
|
id='2',
|
|
label='2nd page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'session_user_email == "test@example.com"'},
|
|
'error_message': 'Error',
|
|
}
|
|
],
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.user = user
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.user = None
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert (
|
|
str(excinfo.value) == 'Page 2 post condition was not met (session_user_email == "test@example.com").'
|
|
)
|
|
|
|
|
|
def test_field_conditions(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.StringField(id='1', label='Text', varname='text'),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Text with condition',
|
|
varname='text_cond',
|
|
required=False,
|
|
condition={'type': 'django', 'value': 'form_var_text == "a"'},
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = 'a'
|
|
formdata.data['2'] = 'xxx'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = 'b'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Tried to fill field "Text with condition" on page 1 but it is hidden.'
|
|
|
|
formdata.data['2'] = None
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = 'a'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_field_conditions_boolean(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.BoolField(id='1', label='Check', varname='check'),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Text with condition',
|
|
varname='text_cond',
|
|
condition={'type': 'django', 'value': 'form_var_check == True'},
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = False
|
|
formdata.data['2'] = None
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['2'] = 'xxx'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Tried to fill field "Text with condition" on page 1 but it is hidden.'
|
|
|
|
formdata.data['1'] = True
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_multi_page_condition(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page'),
|
|
fields.StringField(id='1', label='Text', varname='text'),
|
|
fields.PageField(
|
|
id='2',
|
|
label='2nd page',
|
|
condition={'type': 'django', 'value': 'form_var_text == "a"'},
|
|
post_conditions=[
|
|
{'condition': {'type': 'django', 'value': 'form_var_text2'}, 'error_message': ''}
|
|
],
|
|
),
|
|
fields.StringField(id='3', label='Text 2', varname='text2', required=False),
|
|
fields.PageField(id='4', label='3rd page', condition={'type': 'django', 'value': 'form_var_text'}),
|
|
fields.StringField(id='5', label='Text 3', varname='text3'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = 'a'
|
|
formdata.data['3'] = 'xxx'
|
|
formdata.data['5'] = 'yyy'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = 'b'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Tried to fill field "Text 2" on page 2 but page was not shown.'
|
|
|
|
formdata.data['3'] = None
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = 'a'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 2 post condition was not met (form_var_text2).'
|
|
|
|
|
|
def test_validation_string_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.StringField(id='1', label='String field digits', validation={'type': 'digits'}),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = '1'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = 'xxx'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert (
|
|
str(excinfo.value)
|
|
== 'Invalid value "xxx" for field "String field digits": You should enter digits only, for example: 123.'
|
|
)
|
|
|
|
|
|
def test_validation_required_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.StringField(id='1', label='Text', required=False),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == []
|
|
|
|
formdef.fields[0].required = True
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == ['Text']
|
|
|
|
|
|
def test_validation_item_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [fields.ItemField(id='1', label='Test', items=['foo', 'bar', 'baz'])]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = 'foo'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = 'xxx'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Invalid value "xxx" for field "Test": invalid value selected'
|
|
|
|
# no check on invalid value for field with data source
|
|
formdef.fields[0].data_source = {'type': 'jsonvalue', 'value': json.dumps({})}
|
|
formdef.store()
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = None
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == ['Test']
|
|
|
|
|
|
def test_validation_item_field_inside_block(pub):
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [fields.ItemField(id='1', label='Test', items=['foo', 'bar', 'baz'])]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='Block Data', varname='blockdata', block_slug='foobar', max_items=3),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = {'data': [{'1': 'foo'}]}
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = {'data': [{'1': 'xxx'}]}
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert (
|
|
str(excinfo.value) == 'Empty value for field "Test" (of field "Block Data"): invalid value selected'
|
|
)
|
|
|
|
# no check on invalid value for field with data source
|
|
block.fields[0].data_source = {'type': 'jsonvalue', 'value': json.dumps({})}
|
|
block.store()
|
|
formdef.refresh_from_storage()
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
# ignore required field errors
|
|
formdata.data['1'] = {'data': [{'1': None}]}
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == ['foobar']
|
|
|
|
|
|
def test_validation_optional_field_inside_required_block(pub):
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [fields.StringField(id='1', label='Test', required=False)]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='Block Data', varname='blockdata', block_slug='foobar', max_items=3),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = {'data': [{'1': 'foo'}]}
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == []
|
|
|
|
formdata.data['1'] = {'data': [{'1': None}]}
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == ['foobar']
|
|
|
|
|
|
def test_item_field_display_value(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{'condition': {'type': 'django', 'value': 'form_var_item == "foo"'}, 'error_message': ''}
|
|
],
|
|
),
|
|
fields.ItemField(id='1', label='Test', items=['foo', 'bar', 'baz'], varname='item'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = 'foo'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_item_field_structured_value(pub):
|
|
data_source = {
|
|
'type': 'jsonvalue',
|
|
'value': json.dumps(
|
|
[{'id': '1', 'text': 'un', 'more': 'foo'}, {'id': '2', 'text': 'deux', 'more': 'bar'}]
|
|
),
|
|
}
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{'condition': {'type': 'django', 'value': 'form_var_item_more == "bar"'}, 'error_message': ''}
|
|
],
|
|
),
|
|
fields.ItemField(id='1', label='Test', varname='item', data_source=data_source),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data = {
|
|
'1': '2',
|
|
'1_raw': '2',
|
|
'1_display': 'deux',
|
|
'1_structured': {'id': '2', 'text': 'deux', 'more': 'bar'},
|
|
}
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
# change in data source doesn't affect test
|
|
formdef.fields[1].data_source = {
|
|
'type': 'jsonvalue',
|
|
'value': json.dumps([{'id': '2', 'text': 'deux', 'more': 'foo'}]),
|
|
}
|
|
testdef.run(formdef)
|
|
|
|
formdef.fields[1].data_source = data_source = {'type': 'jsonvalue', 'value': json.dumps([])}
|
|
testdef.run(formdef)
|
|
|
|
# unavailable remote data source is not called
|
|
formdef.fields[1].data_source = {'type': 'json', 'value': 'https://example.net'}
|
|
with responses.RequestsMock():
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_item_field_structured_value_inside_block(pub):
|
|
data_source = {
|
|
'type': 'jsonvalue',
|
|
'value': json.dumps(
|
|
[{'id': '1', 'text': 'un', 'more': 'foo'}, {'id': '2', 'text': 'deux', 'more': 'bar'}]
|
|
),
|
|
}
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.ItemField(id='1', label='Test', varname='item', data_source=data_source),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'form_var_blockdata_0_item_more == "bar"'},
|
|
'error_message': '',
|
|
}
|
|
],
|
|
),
|
|
fields.BlockField(id='1', label='Block Data', varname='blockdata', block_slug='foobar', max_items=3),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = {
|
|
'data': [
|
|
{
|
|
'1': '2',
|
|
'1_display': 'deux',
|
|
'1_structured': {'id': '2', 'text': 'deux', 'more': 'bar'},
|
|
}
|
|
]
|
|
}
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
# change in data source doesn't affect test
|
|
formdef.fields[1].block.fields[0].data_source = {
|
|
'type': 'jsonvalue',
|
|
'value': json.dumps([{'id': '2', 'text': 'deux', 'more': 'foo'}]),
|
|
}
|
|
testdef.run(formdef)
|
|
|
|
formdef.fields[1].block.fields[0].data_source = {'type': 'jsonvalue', 'value': json.dumps([])}
|
|
testdef.run(formdef)
|
|
|
|
# unavailable remote data source is not called
|
|
formdef.fields[1].block.fields[0].data_source = {'type': 'json', 'value': 'https://example.net'}
|
|
with responses.RequestsMock():
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_item_field_card_data_source_live(pub):
|
|
CardDef.wipe()
|
|
carddef = CardDef()
|
|
carddef.name = 'card title'
|
|
carddef.fields = [fields.StringField(id='0', label='Name', varname='name')]
|
|
carddef.store()
|
|
|
|
carddata = carddef.data_class()()
|
|
carddata.data['0'] = 'xxx'
|
|
carddata.just_created()
|
|
carddata.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'form_var_foo_live_var_name == "abc"'},
|
|
'error_message': 'Error',
|
|
},
|
|
],
|
|
),
|
|
fields.ItemField(
|
|
id='1',
|
|
label='Foo',
|
|
varname='foo',
|
|
data_source={'type': 'carddef:card-title'},
|
|
display_mode='autocomplete',
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = str(carddata.id)
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 1 post condition was not met (form_var_foo_live_var_name == "abc").'
|
|
|
|
carddata.data['0'] = 'abc'
|
|
carddata.just_created()
|
|
carddata.store()
|
|
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_validation_items_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [fields.ItemsField(id='1', label='Test', items=['foo', 'bar', 'baz'])]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = ['foo', 'baz']
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
# no check on invalid value
|
|
formdata.data['1'] = ['foo', 'xxx']
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = []
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == ['Test']
|
|
|
|
|
|
def test_validation_email_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.EmailField(id='1', label='Test'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = 'test@entrouvert.com'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = 'xxx'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert (
|
|
str(excinfo.value)
|
|
== 'Invalid value "xxx" for field "Test": You should enter a valid email address, for example name@example.com.'
|
|
)
|
|
|
|
|
|
def test_validation_boolean_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.BoolField(id='1', label='Test'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = False
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdef.fields[0].required = True
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == ['Test']
|
|
|
|
formdata.data['1'] = True
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_validation_date_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.DateField(id='1', label='Test'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = time.strptime('2022-07-19', '%Y-%m-%d')
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = time.strptime('1312-01-01', '%Y-%m-%d')
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Invalid value "1312-01-01" for field "Test": You should enter a valid date.'
|
|
|
|
|
|
def test_validation_map_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'form_var_map == "1.0;2.0"'},
|
|
'error_message': 'Error',
|
|
}
|
|
],
|
|
),
|
|
fields.MapField(id='1', label='Map', varname='map'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = '1.0;2.0'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_validation_file_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.FileField(id='1', label='File', varname='foo', max_file_size='1ko'),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Text',
|
|
varname='text',
|
|
condition={'type': 'django', 'value': 'form_var_foo == "hop.pdf"'},
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
|
|
upload = PicklableUpload('test.pdf', 'application/pdf', 'ascii')
|
|
upload.receive([b'first line', b'second line'])
|
|
formdata.data['1'] = upload
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
# test against empty value
|
|
formdata.data['1'] = None
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == ['File']
|
|
|
|
# test with filename that will negate next field condition
|
|
upload = PicklableUpload('hop.pdf', 'application/pdf', 'ascii')
|
|
upload.receive([b'first line', b'second line'])
|
|
formdata.data['1'] = upload
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == ['Text']
|
|
|
|
formdata.data['2'] = 'xxx'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == []
|
|
|
|
pub.site_options.set('options', 'blacklisted-file-types', 'application/pdf')
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Invalid value "hop.pdf" for field "File": forbidden file type'
|
|
|
|
|
|
def test_validation_block_field(pub):
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='1', label='Text', varname='text'),
|
|
fields.StringField(id='2', label='Hop'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'form_var_blockdata_1_text == "a"'},
|
|
'error_message': '',
|
|
}
|
|
],
|
|
),
|
|
fields.BlockField(id='1', label='Block Data', varname='blockdata', block_slug='foobar', max_items=3),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = {'data': [{'1': 'b'}, {'1': 'a'}]}
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
assert testdef.missing_required_fields == ['Hop', 'Hop']
|
|
|
|
formdata.data['1'] = {'data': [{'1': 'a', '2': 'z'}, {'1': 'b', '2': 'z'}]}
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 1 post condition was not met (form_var_blockdata_1_text == "a").'
|
|
|
|
formdata.data['1'] = {'data': [{'1': 'b', '2': 'z'}, {'1': 'a', '2': 'z'}]}
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_computed_field_support(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {
|
|
'type': 'django',
|
|
'value': 'form_var_foo == "xxx" and form_var_bar == "hop"',
|
|
},
|
|
'error_message': '',
|
|
}
|
|
],
|
|
),
|
|
fields.ComputedField(
|
|
id='1',
|
|
label='Computed (frozen)',
|
|
varname='foo',
|
|
value_template='{% firstof form_var_text "xxx" %}',
|
|
freeze_on_initial_value=True,
|
|
),
|
|
fields.ComputedField(
|
|
id='2', label='Computed (live)', varname='bar', value_template='{% firstof form_var_text "xxx" %}'
|
|
),
|
|
fields.StringField(id='3', label='Text', varname='text'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = 'zzz'
|
|
formdata.data['3'] = 'hop'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdef.fields[1].value_template = '{% for %}'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert (
|
|
str(excinfo.value)
|
|
== 'Page 1 post condition was not met (form_var_foo == "xxx" and form_var_bar == "hop").'
|
|
)
|
|
|
|
|
|
def test_computed_field_support_complex_data(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{'condition': {'type': 'django', 'value': 'form_var_foo|length == 3'}, 'error_message': ''}
|
|
],
|
|
),
|
|
fields.ComputedField(
|
|
id='1',
|
|
label='Computed',
|
|
varname='foo',
|
|
value_template='{{form_objects|first|get:"form_var_items_raw"}}',
|
|
),
|
|
fields.ItemsField(id='2', label='Items', varname='items', required=False),
|
|
]
|
|
formdef.store()
|
|
|
|
submitted_formdata = formdef.data_class()()
|
|
submitted_formdata.just_created()
|
|
submitted_formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
submitted_formdata.data['2'] = ['a', 'bc']
|
|
submitted_formdata.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 1 post condition was not met (form_var_foo|length == 3).'
|
|
|
|
submitted_formdata.data['2'] = ['a', 'b', 'c']
|
|
submitted_formdata.store()
|
|
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_computed_field_support_webservice(pub, http_requests):
|
|
wscall = NamedWsCall()
|
|
wscall.name = 'Hello world'
|
|
wscall.request = {'url': 'http://remote.example.net/json'}
|
|
wscall.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'form_var_computed_foo == "bar"'},
|
|
'error_message': '',
|
|
}
|
|
],
|
|
),
|
|
fields.ComputedField(
|
|
id='1',
|
|
label='Computed',
|
|
varname='computed',
|
|
value_template='{{ webservice.hello_world }}',
|
|
freeze_on_initial_value=True,
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.store()
|
|
testdef.run(formdef)
|
|
|
|
assert len(testdef.sent_requests) == 1
|
|
assert testdef.sent_requests[0]['method'] == 'GET'
|
|
assert testdef.sent_requests[0]['url'] == 'http://remote.example.net/json'
|
|
|
|
response = WebserviceResponse()
|
|
response.testdef_id = testdef.id
|
|
response.name = 'Fake response'
|
|
response.url = 'http://remote.example.net/json'
|
|
response.payload = '{"foo": "bar"}'
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
|
|
assert len(testdef.sent_requests) == 1
|
|
assert testdef.sent_requests[0]['url'] == 'http://remote.example.net/json'
|
|
assert testdef.sent_requests[0]['webservice_response_id'] == response.id
|
|
|
|
response.payload = '{"foo": "baz"}'
|
|
response.store()
|
|
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 1 post condition was not met (form_var_computed_foo == "bar").'
|
|
assert len(testdef.sent_requests) == 1
|
|
assert testdef.sent_requests[0]['url'] == 'http://remote.example.net/json'
|
|
assert testdef.sent_requests[0]['webservice_response_id'] == response.id
|
|
|
|
response.url = 'http://example.com/json'
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
assert len(testdef.sent_requests) == 1
|
|
assert testdef.sent_requests[0]['url'] == 'http://remote.example.net/json'
|
|
assert testdef.sent_requests[0]['webservice_response_id'] is None
|
|
|
|
response.url = None
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
assert len(testdef.sent_requests) == 1
|
|
assert testdef.sent_requests[0]['url'] == 'http://remote.example.net/json'
|
|
assert testdef.sent_requests[0]['webservice_response_id'] is None
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with mock.patch('wcs.testdef.MockWebserviceResponseAdapter._send', side_effect=KeyError('missing key')):
|
|
with pytest.raises(TestError):
|
|
testdef.run(formdef)
|
|
|
|
assert len(testdef.sent_requests) == 0
|
|
assert testdef.recorded_errors == [
|
|
"Unexpected error when mocking webservice call for url http://remote.example.net/json: 'missing key'."
|
|
]
|
|
|
|
|
|
def test_computed_field_value_too_long(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'not form_var_computed'},
|
|
'error_message': '',
|
|
}
|
|
],
|
|
),
|
|
fields.ComputedField(
|
|
id='1',
|
|
label='Computed',
|
|
varname='computed',
|
|
value_template='{% token_decimal length=9999 %}',
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError):
|
|
testdef.run(formdef)
|
|
|
|
formdef.fields[1].value_template = '{% token_decimal length=100000 %}'
|
|
formdef.store()
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_computed_field_forms_template_access(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'form_var_computed == 1'},
|
|
'error_message': 'Not enough chars.',
|
|
}
|
|
],
|
|
),
|
|
fields.ComputedField(
|
|
id='1',
|
|
label='Computed',
|
|
varname='computed',
|
|
value_template='{{ forms|objects:"test-title"|count }}',
|
|
freeze_on_initial_value=True,
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.store()
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdef.fields[
|
|
1
|
|
].value_template = '{{ forms|objects:"test-title"|filter_by:"unknown"|filter_value:"xxx"|count }}'
|
|
formdef.store()
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 1 post condition was not met (form_var_computed == 1).'
|
|
assert testdef.recorded_errors == ['Invalid filter "unknown"']
|
|
|
|
|
|
def test_numeric_field_support(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{'condition': {'type': 'django', 'value': 'form_var_foo == 13.12'}, 'error_message': ''}
|
|
],
|
|
),
|
|
fields.NumericField(
|
|
id='1', label='Numeric', varname='foo', restrict_to_integers=False, min_value=decimal.Decimal(10)
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.data['1'] = decimal.Decimal(13.12)
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.store()
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = decimal.Decimal(9)
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert (
|
|
str(excinfo.value)
|
|
== 'Invalid value "9" for field "Numeric": You should enter a number greater than or equal to 10.'
|
|
)
|
|
|
|
formdata.data['1'] = decimal.Decimal(42)
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 1 post condition was not met (form_var_foo == 13.12).'
|
|
|
|
|
|
def test_expected_error(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'form_var_text|length > 5'},
|
|
'error_message': 'Not enough chars.',
|
|
}
|
|
],
|
|
),
|
|
fields.StringField(id='1', label='Text', varname='text', validation={'type': 'digits'}),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = '123456'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = '1'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 1 post condition was not met (form_var_text|length > 5).'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.expected_error = 'Not enough chars.'
|
|
testdef.run(formdef)
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.expected_error = 'Other error.'
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Expected error "Other error." but got error "Not enough chars." instead.'
|
|
|
|
formdata.data['1'] = 'abcdef'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.expected_error = 'You should enter digits only, for example: 123.'
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_expected_error_conditional_field(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.StringField(id='1', label='Text', varname='text'),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Text 2',
|
|
varname='text2',
|
|
validation={'type': 'digits'},
|
|
condition={'type': 'django', 'value': 'form_var_text == "a"'},
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
formdata.data['1'] = 'a'
|
|
formdata.data['2'] = 'b'
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert (
|
|
str(excinfo.value)
|
|
== 'Invalid value "b" for field "Text 2": You should enter digits only, for example: 123.'
|
|
)
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.expected_error = 'You should enter digits only, for example: 123.'
|
|
testdef.run(formdef)
|
|
|
|
formdata.data['1'] = 'b'
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.expected_error = 'You should enter digits only, for example: 123.'
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == (
|
|
'Expected error "You should enter digits only, for example: 123." but got error "Tried to fill field "Text 2" on '
|
|
'page 1 but it is hidden." instead.'
|
|
)
|
|
|
|
|
|
def test_is_in_backoffice(pub):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.PageField(
|
|
id='0',
|
|
label='1st page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'not is_in_backoffice'},
|
|
'error_message': 'Must not be in backoffice',
|
|
}
|
|
],
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.run(formdef)
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.is_in_backoffice = True
|
|
with pytest.raises(TestError) as excinfo:
|
|
testdef.run(formdef)
|
|
assert str(excinfo.value) == 'Page 1 post condition was not met (not is_in_backoffice).'
|
|
|
|
testdef.is_in_backoffice = False
|
|
testdef.run(formdef)
|
|
|
|
|
|
def test_webservice_response_match_request(pub, http_requests):
|
|
formdef = FormDef()
|
|
formdef.name = 'test title'
|
|
formdef.fields = [
|
|
fields.ComputedField(
|
|
id='1',
|
|
label='Computed',
|
|
varname='computed',
|
|
value_template='{{ webservice.hello_world }}',
|
|
freeze_on_initial_value=True,
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
|
|
testdef = TestDef.create_from_formdata(formdef, formdata)
|
|
testdef.store()
|
|
|
|
wscall = NamedWsCall()
|
|
wscall.name = 'Hello world'
|
|
wscall.request = {
|
|
'url': 'http://remote.example.net/json',
|
|
'method': 'POST',
|
|
'qs_data': {'foo': 'bar'},
|
|
'post_data': {'foo2': 'bar2'},
|
|
}
|
|
wscall.store()
|
|
|
|
response = WebserviceResponse()
|
|
response.testdef_id = testdef.id
|
|
response.name = 'Fake response'
|
|
response.url = 'http://remote.example.net/json'
|
|
response.payload = '{}'
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
assert testdef.sent_requests[0]['webservice_response_id'] == response.id
|
|
|
|
# method restriction
|
|
response.method = 'GET'
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
assert testdef.sent_requests[0]['webservice_response_id'] is None
|
|
|
|
response.method = 'POST'
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
assert testdef.sent_requests[0]['webservice_response_id'] == response.id
|
|
|
|
# query string restriction
|
|
response.qs_data = {
|
|
'foo': 'bar',
|
|
'xxx': 'yyy',
|
|
}
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
assert testdef.sent_requests[0]['webservice_response_id'] is None
|
|
|
|
del response.qs_data['xxx']
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
assert testdef.sent_requests[0]['webservice_response_id'] == response.id
|
|
|
|
# post data restriction
|
|
response.post_data = {
|
|
'foo2': 'bar2',
|
|
'xxx': 'yyy',
|
|
}
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
assert testdef.sent_requests[0]['webservice_response_id'] is None
|
|
|
|
del response.post_data['xxx']
|
|
response.store()
|
|
|
|
testdef.run(formdef)
|
|
assert testdef.sent_requests[0]['webservice_response_id'] == response.id
|