import collections import datetime import pytest import sys import shutil import time from quixote import cleanup from quixote.http_request import Upload from wcs.qommon.template import Template from wcs.qommon.form import PicklableUpload from wcs.qommon.http_request import HTTPRequest from wcs import fields, formdef from wcs.categories import Category from wcs.conditions import Condition from wcs.formdef import FormDef from wcs.formdata import Evolution from wcs.roles import Role from wcs import sessions from wcs.variables import LazyFormData from wcs.workflows import Workflow, WorkflowStatusItem, WorkflowCriticalityLevel, WorkflowBackofficeFieldsFormDef from wcs.wf.anonymise import AnonymiseWorkflowStatusItem from wcs.wf.wscall import JournalWsCallErrorPart from wcs.wf.register_comment import JournalEvolutionPart from utilities import create_temporary_pub, clean_temporary_pub from test_api import local_user def pytest_generate_tests(metafunc): if 'pub' in metafunc.fixturenames: metafunc.parametrize('pub', ['pickle', 'sql'], indirect=True) @pytest.fixture def pub(request): pub = create_temporary_pub(sql_mode=(request.param == 'sql')) req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'}) pub.set_app_dir(req) pub._set_request(req) pub.cfg['identification'] = {'methods': ['password']} pub.cfg['language'] = {'language': 'en'} pub.write_cfg() FormDef.wipe() Category.wipe() cat = Category(name='test category') cat.store() global formdef formdef = FormDef() formdef.name = 'foobar' formdef.url_name = 'foobar' formdef.fields = [] formdef.category_id = cat.id formdef.store() return pub def teardown_module(module): clean_temporary_pub() def test_basic(pub): formdata = formdef.data_class()() substvars = formdata.get_substitution_variables() assert substvars.get('form_status') == 'Unknown' assert substvars.get('form_name') == 'foobar' assert substvars.get('form_slug') == 'foobar' assert substvars.get('category_name') == 'test category' def test_saved(pub): formdef.data_class().wipe() formdata = formdef.data_class()() formdata.store() substvars = formdata.get_substitution_variables() assert substvars.get('form_number') == '%s-1' % formdef.id assert substvars.get('form_number_raw') == '1' assert substvars.get('form_url').endswith('/foobar/1/') assert substvars.get('form_url_backoffice').endswith('/backoffice/management/foobar/1/') assert substvars.get('form_status_url').endswith('/foobar/1/status') def test_auto_display_id(pub): formdef.data_class().wipe() formdata = formdef.data_class()() formdata.store() substvars = formdata.get_substitution_variables() assert substvars.get('form_number') == '%s-%s' % (formdef.id, formdata.id) assert substvars.get('form_number_raw') == str(formdata.id) def test_manual_display_id(pub): formdef.data_class().wipe() formdata = formdef.data_class()() formdata.id_display = 'bar' formdata.store() substvars = formdata.get_substitution_variables() assert substvars.get('form_number') == 'bar' assert substvars.get('form_number_raw') == str(formdata.id) def test_submission_context(pub): formdef.data_class().wipe() formdata = formdef.data_class()() formdata.backoffice_submission = True formdata.submission_channel = 'mail' formdata.submission_context = { 'mail_url': 'http://www.example.com/test.pdf', } substvars = formdata.get_substitution_variables() assert substvars.get('form_submission_backoffice') is True assert substvars.get('form_submission_channel') == 'mail' assert substvars.get('form_submission_channel_label') == 'Mail' assert substvars.get('form_submission_context_mail_url') == 'http://www.example.com/test.pdf' formdata = formdef.data_class()() substvars = formdata.get_substitution_variables() assert substvars.get('form_submission_backoffice') is False assert substvars.get('form_submission_channel') is None assert substvars.get('form_submission_channel_label') == 'Web' def test_just_created(pub): formdef.data_class().wipe() formdata = formdef.data_class()() formdata.just_created() formdata.store() substvars = formdata.get_substitution_variables() assert substvars.get('form_status') == 'Just Submitted' assert substvars.get('form_status_is_endpoint') == False assert substvars.get('form_receipt_date') assert substvars.get('form_receipt_time') assert substvars.get('form_receipt_datetime') assert substvars.get('form_evolution') def test_field(pub): formdef.data_class().wipe() formdef.fields = [fields.StringField(id='0', label='string')] formdef.store() formdata = formdef.data_class()() substvars = formdata.get_substitution_variables() assert not substvars.get('form_f0') formdata.data = {'0': 'test'} substvars = formdata.get_substitution_variables() assert substvars.get('form_f0') == 'test' assert substvars.get('form_field_string') == 'test' def test_field_varname(pub): formdef.data_class().wipe() formdef.fields = [fields.StringField(id='0', label='string', varname='foo')] formdef.store() formdata = formdef.data_class()() formdata.data = {'0': 'test'} substvars = formdata.get_substitution_variables() assert substvars.get('form_f0') == 'test' assert substvars.get('form_var_foo') == 'test' def test_file_field(pub): formdef.data_class().wipe() formdef.fields = [fields.FileField(id='0', label='file', varname='foo')] formdef.store() formdata = formdef.data_class()() upload = Upload('test.txt', 'text/plain', 'ascii') upload.receive([b'first line', b'second line']) formdata.data = {'0': upload} formdata.id = 1 substvars = formdata.get_substitution_variables() assert substvars.get('form_var_foo') == 'test.txt' assert substvars.get('form_var_foo_url').endswith('/foobar/1/download?f=0') assert isinstance(substvars.get('form_var_foo_raw'), Upload) formdata.data = {'0': None} substvars = formdata.get_substitution_variables() assert substvars['form_var_foo'] is None assert substvars['form_var_foo_raw'] is None assert substvars['form_var_foo_url'] is None formdata.data = {} substvars = formdata.get_substitution_variables() assert substvars['form_var_foo'] is None assert substvars['form_var_foo_raw'] is None assert substvars['form_var_foo_url'] is None def test_get_submitter(pub): formdef.data_class().wipe() formdef.fields = [fields.StringField(id='0', label='email', varname='foo', prefill={'type': 'user', 'value': 'email'})] formdef.store() formdata = formdef.data_class()() assert formdef.get_submitter_email(formdata) is None formdata.data = {'0': 'foo@localhost'} assert formdef.get_submitter_email(formdata) == 'foo@localhost' user = pub.user_class() user.email = 'bar@localhost' user.store() formdata.user_id = user.id assert formdef.get_submitter_email(formdata) == 'foo@localhost' formdata.data = {} assert formdef.get_submitter_email(formdata) == 'bar@localhost' def test_get_last_update_time(pub): formdef.data_class().wipe() formdef.store() formdata = formdef.data_class()() assert formdata.last_update_time is None formdata.just_created() assert formdata.last_update_time == formdata.evolution[-1].time time.sleep(1) evo = Evolution() evo.time = time.localtime() evo.status = formdata.status evo.comment = 'hello world' formdata.evolution.append(evo) assert formdata.last_update_time != formdata.receipt_time assert formdata.last_update_time == formdata.evolution[-1].time # check with missing 'evolution' values formdata.evolution = None assert formdata.last_update_time == formdata.receipt_time def test_password_field(pub): formdef.data_class().wipe() formdef.fields = [fields.PasswordField(id='0', label='pwd')] formdef.store() formdata = formdef.data_class()() formdata.data = {'0': {'cleartext': 'foo'}} formdata.store() formdata2 = formdata.get(formdata.id) assert formdata2.data == {'0': {'cleartext': 'foo'}} def test_date_field(pub): formdef.data_class().wipe() formdef.fields = [fields.DateField(id='0', label='date')] formdef.store() formdata = formdef.data_class()() value = time.strptime('2015-05-12', '%Y-%m-%d') formdata.data = {'0': value} formdata.store() formdata2 = formdata.get(formdata.id) assert formdata2.data == {'0': value} assert formdata2.get_substitution_variables()['form_field_date'] == '2015-05-12' pub.cfg['language'] = {'language': 'fr'} assert formdata2.get_substitution_variables()['form_field_date'] == '12/05/2015' pub.cfg['language'] = {'language': 'en'} def test_clean_drafts(pub): formdef = FormDef() formdef.name = 'foo' formdef.fields = [] formdef.store() formdef.data_class().wipe() d = formdef.data_class()() d.status = 'draft' d.receipt_time = time.localtime() d.store() d_id1 = d.id d = formdef.data_class()() d.status = 'draft' d.receipt_time = time.localtime(0) # epoch, 1970-01-01 d.store() d_id2 = d.id assert formdef.data_class().count() == 2 from wcs.formdef import clean_drafts clean_drafts(pub) assert formdef.data_class().count() == 1 assert formdef.data_class().select()[0].id == d_id1 def test_criticality_levels(pub): workflow = Workflow(name='criticality') workflow.criticality_levels = [ WorkflowCriticalityLevel(name='green'), WorkflowCriticalityLevel(name='yellow'), WorkflowCriticalityLevel(name='red'), ] workflow.store() formdef = FormDef() formdef.name = 'foo' formdef.fields = [] formdef.workflow_id = workflow.id formdef.store() formdef.data_class().wipe() d = formdef.data_class()() assert d.get_criticality_level_object().name == 'green' d.increase_criticality_level() assert d.get_criticality_level_object().name == 'yellow' d.increase_criticality_level() assert d.get_criticality_level_object().name == 'red' d.increase_criticality_level() assert d.get_criticality_level_object().name == 'red' d.decrease_criticality_level() assert d.get_criticality_level_object().name == 'yellow' d.decrease_criticality_level() assert d.get_criticality_level_object().name == 'green' d.decrease_criticality_level() assert d.get_criticality_level_object().name == 'green' d.set_criticality_level(1) assert d.get_criticality_level_object().name == 'yellow' d.set_criticality_level(2) assert d.get_criticality_level_object().name == 'red' d.set_criticality_level(4) assert d.get_criticality_level_object().name == 'red' workflow.criticality_levels = [WorkflowCriticalityLevel(name='green')] workflow.store() formdef = FormDef.get(id=formdef.id) # reload formdef d = formdef.data_class()() assert d.get_criticality_level_object().name == 'green' d.increase_criticality_level() assert d.get_criticality_level_object().name == 'green' workflow.criticality_levels = [ WorkflowCriticalityLevel(name='green'), WorkflowCriticalityLevel(name='yellow'), ] workflow.store() formdef = FormDef.get(id=formdef.id) # reload formdef d = formdef.data_class()() d.criticality_level = 104 # set too high, this simulates a workflow being changed to have less # levels than before. assert d.get_criticality_level_object().name == 'yellow' d.increase_criticality_level() assert d.get_criticality_level_object().name == 'yellow' d.decrease_criticality_level() assert d.get_criticality_level_object().name == 'green' d.criticality_level = 104 d.decrease_criticality_level() assert d.get_criticality_level_object().name == 'green' assert d.get_static_substitution_variables().get('form_criticality_label') == 'green' assert d.get_substitution_variables().get('form_criticality_label') == 'green' def test_field_item_substvars(pub): ds = { 'type': 'formula', 'value': repr([('1', 'un'), ('2', 'deux')]), } formdef = FormDef() formdef.name = 'foobar' formdef.fields = [fields.ItemField(id='0', label='string', data_source=ds, varname='xxx')] formdef.store() formdata = formdef.data_class()() formdata.data = {'0': '1', '0_display': 'un'} variables = formdata.get_substitution_variables() assert variables.get('form_var_xxx') == 'un' assert variables.get('form_var_xxx_raw') == '1' def test_get_json_export_dict_evolution(pub, local_user): Workflow.wipe() workflow = Workflow(name='test') st_new = workflow.add_status('New') st_finished = workflow.add_status('Finished') workflow.store() formdef = FormDef() formdef.workflow_id = workflow.id formdef.name = 'foo' formdef.fields = [] formdef.store() formdef.data_class().wipe() d = formdef.data_class()() d.status = 'wf-%s' % st_new.id d.user_id = local_user.id d.receipt_time = time.localtime() evo = Evolution() evo.time = time.localtime() evo.status = 'wf-%s' % st_new.id evo.who = '_submitter' d.evolution = [evo] d.store() evo.add_part(JournalEvolutionPart(d, "ok")) evo.add_part(JournalWsCallErrorPart("summary", "label", "data")) evo = Evolution() evo.time = time.localtime() evo.status = 'wf-%s' % st_finished.id evo.who = '_submitter' d.evolution.append(evo) d.store() export = d.get_json_export_dict() assert 'evolution' in export assert len(export['evolution']) == 2 assert export['evolution'][0]['status'] == st_new.id assert 'time' in export['evolution'][0] assert export['evolution'][0]['who']['id'] == local_user.id assert export['evolution'][0]['who']['email'] == local_user.email assert export['evolution'][0]['who']['NameID'] == local_user.name_identifiers assert 'parts' in export['evolution'][0] assert len(export['evolution'][0]['parts']) == 2 assert export['evolution'][0]['parts'][0]['type'] == 'workflow-comment' assert export['evolution'][0]['parts'][0]['content'] == 'ok' assert export['evolution'][0]['parts'][1]['type'] == 'wscall-error' assert export['evolution'][0]['parts'][1]['summary'] == 'summary' assert export['evolution'][0]['parts'][1]['label'] == 'label' assert export['evolution'][0]['parts'][1]['data'] == 'data' assert export['evolution'][1]['status'] == st_finished.id assert 'time' in export['evolution'][1] assert export['evolution'][1]['who']['id'] == local_user.id assert export['evolution'][1]['who']['email'] == local_user.email assert export['evolution'][1]['who']['NameID'] == local_user.name_identifiers assert 'parts' not in export['evolution'][1] export = d.get_json_export_dict(anonymise=True) assert 'evolution' in export assert len(export['evolution']) == 2 assert export['evolution'][0]['status'] == st_new.id assert 'time' in export['evolution'][0] assert 'who' not in export['evolution'][0] assert 'parts' in export['evolution'][0] assert len(export['evolution'][0]['parts']) == 2 assert len(export['evolution'][0]['parts'][0]) == 1 assert export['evolution'][0]['parts'][0]['type'] == 'workflow-comment' assert len(export['evolution'][0]['parts'][1]) == 1 assert export['evolution'][0]['parts'][1]['type'] == 'wscall-error' assert export['evolution'][1]['status'] == st_finished.id assert 'time' in export['evolution'][1] assert 'who' not in export['evolution'][0] assert 'parts' not in export['evolution'][1] def test_field_bool_substvars(pub): formdef = FormDef() formdef.name = 'foobar' formdef.fields = [fields.BoolField(id='0', label='checkbox', varname='xxx')] formdef.store() formdata = formdef.data_class()() formdata.data = {'0': False} variables = formdata.get_substitution_variables() assert variables.get('form_var_xxx') == 'False' assert variables.get('form_var_xxx_raw') is False formdata.data = {'0': True} variables = formdata.get_substitution_variables() assert variables.get('form_var_xxx') == 'True' assert variables.get('form_var_xxx_raw') is True def test_backoffice_field_varname(pub): wf = Workflow(name='bo fields') wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf) wf.backoffice_fields_formdef.fields = [ fields.StringField(id='bo1', label='1st backoffice field', type='string', varname='backoffice_blah'), ] st1 = wf.add_status('Status1') wf.store() formdef.workflow_id = wf.id formdef.data_class().wipe() formdef.fields = [fields.StringField(id='0', label='string', varname='foo')] formdef.store() formdata = formdef.data_class()() formdata.data = {'bo1': 'test'} substvars = formdata.get_substitution_variables() assert substvars.get('form_var_backoffice_blah') == 'test' def test_workflow_data_file_url(pub): upload = PicklableUpload('test.txt', 'text/plain', 'ascii') upload.receive([b'first line', b'second line']) formdata = formdef.data_class()() formdata.store() # create workflow_data as ordered dict to be sure _url comes last, to # trigger #17233. formdata.workflow_data = collections.OrderedDict( foo_var_file='test.txt', foo_var_file_raw=upload, foo_var_file_url=None, ) substvars = formdata.get_substitution_variables() assert substvars['foo_var_file_url'] def test_evolution_get_status(pub): Workflow.wipe() workflow = Workflow(name='test') st_new = workflow.add_status('New') st_finished = workflow.add_status('Finished') workflow.store() formdef = FormDef() formdef.workflow_id = workflow.id formdef.name = 'foo' formdef.fields = [] formdef.store() formdef.data_class().wipe() d = formdef.data_class()() d.evolution = [] evo = Evolution() evo.time = time.localtime() evo.status = 'wf-%s' % st_new.id d.evolution.append(evo) evo = Evolution() evo.time = time.localtime() d.evolution.append(evo) evo = Evolution() evo.time = time.localtime() d.evolution.append(evo) evo = Evolution() evo.time = time.localtime() evo.status = 'wf-%s' % st_finished.id d.evolution.append(evo) evo = Evolution() evo.time = time.localtime() d.evolution.append(evo) d.store() d = formdef.data_class().get(d.id) assert [x.get_status().id for x in d.evolution] == ['1', '1', '1', '2', '2'] @pytest.fixture def variable_test_data(pub): pub.user_class.wipe() user = pub.user_class() user.email = 'bar@localhost' user.name_identifiers = ['....'] user.store() role = Role(name='foobar') role.store() FormDef.wipe() formdef = FormDef() formdef.name = 'foobarlazy' formdef.fields = [ fields.StringField(id='0', label='string', varname='foo_foo'), fields.BoolField(id='1', label='checkbox', varname='boolfield'), fields.BoolField(id='2', label='checkbox', varname='boolfield2'), fields.DateField(id='3', label='date', varname='datefield'), fields.ItemsField(id='4', label='items', items=['aa', 'ab', 'ac'], varname='itemsfield'), fields.FileField(id='5', label='file', varname='filefield'), fields.StringField(id='6', label='string2', varname='foo_foo_baz_baz'), fields.MapField(id='7', label='map', varname='map'), fields.DateField(id='8', label='date2', varname='datefield2'), fields.StringField(id='9', label='string2', varname='datestring'), fields.StringField(id='10', label='number1', varname='term1'), fields.StringField(id='11', label='number2', varname='term2'), fields.StringField(id='12', label='float1', varname='value'), ] formdef.workflow_roles = {'_receiver': role.id} formdef.geolocations = {'base': 'Base'} formdef.store() formdef.data_class().wipe() formdata = formdef.data_class()() formdata.just_created() formdata.user_id = user.id formdata.data = { '0': 'bar', '1': False, '2': True, '3': time.strptime('2018-07-31', '%Y-%m-%d'), '4': ['aa', 'ac'], '4_display': 'aa, ac', '5': PicklableUpload('test.txt', 'text/plain'), '6': 'other', '7': '2;4', # map '8': time.strptime('2018-08-31', '%Y-%m-%d'), '9': '2018-07-31', '10': '3', '11': '4', '12': '3.14', } formdata.data['5'].receive([b'hello world']) formdata.geolocations = {'base': {'lat': 1, 'lon': 2}} formdata.store() pub.substitutions.feed(pub) pub.substitutions.feed(formdef) pub.substitutions.feed(formdata) return LazyFormData(formdata) def test_lazy_formdata(pub, variable_test_data): formdata = FormDef.select()[0].data_class().select()[0] lazy_formdata = LazyFormData(formdata) assert lazy_formdata.receipt_date == time.strftime('%Y-%m-%d', formdata.receipt_time) assert lazy_formdata.receipt_time == time.strftime('%H:%M', formdata.receipt_time) assert lazy_formdata.internal_id == formdata.id assert lazy_formdata.name == 'foobarlazy' assert lazy_formdata.display_name == 'foobarlazy #%s' % formdata.get_display_id() assert lazy_formdata.page_no == 0 assert lazy_formdata.url.endswith('/foobarlazy/%s/' % formdata.id) assert lazy_formdata.url_backoffice.endswith('/backoffice/management/foobarlazy/%s/' % formdata.id) assert lazy_formdata.backoffice_url == lazy_formdata.url_backoffice assert lazy_formdata.api_url == formdata.get_api_url() assert lazy_formdata.attachments assert lazy_formdata.geoloc['base'] == {'lat': 1, 'lon': 2} assert lazy_formdata.geoloc['base_lon'] == 2 static_vars = formdata.get_static_substitution_variables() for attribute in ('name', 'receipt_date', 'receipt_time', 'previous_status', 'uri', 'status_changed', 'comment', 'evolution', 'details', 'criticality_level', 'digest'): assert getattr(lazy_formdata, attribute) == static_vars['form_' + attribute] assert lazy_formdata.user.email == 'bar@localhost' assert lazy_formdata.var.foo_foo == 'bar' assert lazy_formdata.var.boolfield == 'False' assert bool(lazy_formdata.var.boolfield) is False assert lazy_formdata.var.boolfield2 == 'True' assert bool(lazy_formdata.var.boolfield2) is True assert lazy_formdata.var.datefield.raw == time.strptime('2018-07-31', '%Y-%m-%d') assert lazy_formdata.var.datefield.tm_year == 2018 assert lazy_formdata.var.datefield.tm_mon == 7 assert lazy_formdata.var.datefield.tm_mday == 31 for attr in ('tm_year', 'tm_mon', 'tm_mday', 'tm_hour', 'tm_min', 'tm_sec', 'tm_wday', 'tm_yday'): getattr(lazy_formdata.var.datefield, attr) # flexible date comparison assert lazy_formdata.var.datefield == lazy_formdata.var.datefield assert not lazy_formdata.var.datefield == lazy_formdata.var.datefield2 assert not lazy_formdata.var.datefield2 == lazy_formdata.var.datefield assert lazy_formdata.var.datefield != lazy_formdata.var.datefield2 assert lazy_formdata.var.datefield2 != lazy_formdata.var.datefield assert not lazy_formdata.var.datefield != lazy_formdata.var.datefield assert lazy_formdata.var.datefield < lazy_formdata.var.datefield2 assert lazy_formdata.var.datefield <= lazy_formdata.var.datefield2 assert not lazy_formdata.var.datefield > lazy_formdata.var.datefield2 assert not lazy_formdata.var.datefield >= lazy_formdata.var.datefield2 assert lazy_formdata.var.datefield2 > lazy_formdata.var.datefield assert lazy_formdata.var.datefield2 >= lazy_formdata.var.datefield assert not lazy_formdata.var.datefield2 < lazy_formdata.var.datefield assert not lazy_formdata.var.datefield2 <= lazy_formdata.var.datefield assert lazy_formdata.var.datefield == lazy_formdata.var.datestring assert lazy_formdata.var.datestring == lazy_formdata.var.datefield assert lazy_formdata.var.datefield >= lazy_formdata.var.datestring assert lazy_formdata.var.datestring >= lazy_formdata.var.datefield assert lazy_formdata.var.datefield <= lazy_formdata.var.datestring assert lazy_formdata.var.datestring <= lazy_formdata.var.datefield assert not lazy_formdata.var.datefield != lazy_formdata.var.datestring assert not lazy_formdata.var.datestring != lazy_formdata.var.datefield assert not lazy_formdata.var.datefield < lazy_formdata.var.datestring assert not lazy_formdata.var.datestring < lazy_formdata.var.datefield assert not lazy_formdata.var.datefield > lazy_formdata.var.datestring assert not lazy_formdata.var.datestring > lazy_formdata.var.datefield for date in ('2018-07-31', '2018-07-31 00:00', '2018-07-31 00:00:00', '31/07/2018', '31/07/2018 00h00', '31/07/2018 00:00:00', datetime.date(2018, 7, 31), datetime.datetime(2018, 7, 31, 0, 0), time.strptime('2018-07-31', '%Y-%m-%d')): assert lazy_formdata.var.datefield == date assert lazy_formdata.var.datefield >= date assert lazy_formdata.var.datefield <= date assert date == lazy_formdata.var.datefield assert date <= lazy_formdata.var.datefield assert date >= lazy_formdata.var.datefield assert not lazy_formdata.var.datefield != date assert not date != lazy_formdata.var.datefield assert not lazy_formdata.var.datefield > date assert not lazy_formdata.var.datefield < date assert not date < lazy_formdata.var.datefield assert not date > lazy_formdata.var.datefield for date in ('2018-08-31', '2018-07-31 01:00', '2018-07-31 01:00:00', '31/08/2018', '31/07/2018 01h00', '31/07/2018 01:00:00', datetime.date(2018, 8, 31), datetime.datetime(2018, 8, 31, 0, 0), time.strptime('2018-08-31', '%Y-%m-%d')): assert lazy_formdata.var.datefield != date assert date != lazy_formdata.var.datefield assert not lazy_formdata.var.datefield == date assert not date == lazy_formdata.var.datefield assert lazy_formdata.var.datefield < date assert not lazy_formdata.var.datefield >= date assert lazy_formdata.var.datefield <= date assert not lazy_formdata.var.datefield > date assert date > lazy_formdata.var.datefield assert not date <= lazy_formdata.var.datefield assert date >= lazy_formdata.var.datefield assert not date < lazy_formdata.var.datefield assert lazy_formdata.var.itemsfield == 'aa, ac' assert 'aa' in lazy_formdata.var.itemsfield # taken as a list assert 'aa,' not in lazy_formdata.var.itemsfield # not as a string assert lazy_formdata.var.filefield == 'test.txt' assert lazy_formdata.var.filefield.raw.base_filename == 'test.txt' assert lazy_formdata.var.filefield.raw.content_type == 'text/plain' formdata = FormDef.select()[0].data_class() lazy_formdata = LazyFormData(formdata) assert lazy_formdata.tracking_code is None formdata.data = {'future_tracking_code': 'CDCBGWQX'} assert lazy_formdata.tracking_code == 'CDCBGWQX' formdata = FormDef.select()[0].data_class().select()[0] lazy_formdata = LazyFormData(formdata) assert lazy_formdata.tracking_code is None tracking_code = pub.tracking_code_class() tracking_code.formdata = formdata tracking_code.store() formdata = FormDef.select()[0].data_class().get(formdata.id) lazy_formdata = LazyFormData(formdata) assert lazy_formdata.tracking_code == tracking_code.id def test_lazy_formdata_queryset(pub, variable_test_data): lazy_formdata = variable_test_data data_class = lazy_formdata._formdef.data_class() for i in range(6): formdata = data_class() formdata.just_created() formdata.store() for i in range(4): formdata = data_class() formdata.just_created() formdata.jump_status('finished') formdata.store() formdata = data_class() formdata.status = 'draft' formdata.store() assert lazy_formdata.objects.count == 11 assert lazy_formdata.objects.drafts().count == 1 assert lazy_formdata.objects.pending().count == 7 assert lazy_formdata.objects.done().count == 4 assert lazy_formdata.objects.drafts().count == 1 # check __len__ assert len(lazy_formdata.objects.drafts()) == 1 assert lazy_formdata.objects.current_user().count == 0 pub.get_request()._user = () # reset cache pub.get_request().session = sessions.BasicSession(id=1) pub.get_request().session.set_user(pub.user_class.select()[0].id) assert lazy_formdata.objects.current_user().count == 1 qs = lazy_formdata.objects.drafts() # check __iter__ for draft in qs: assert draft.internal_id == formdata.id # check __getitem__ assert qs[0].internal_id == formdata.id # check against for cached resultset assert qs[0].internal_id == formdata.id # check __iter__ with cached resultset for draft in qs: assert draft.internal_id == formdata.id # check __iter__ creates a cached resultset qs = lazy_formdata.objects.drafts() for formdata1, formdata2 in zip(list(qs), list(qs)): assert formdata1 is formdata2 # check ordering qs = lazy_formdata.objects.pending().order_by('id') assert [x.number for x in qs] == ['1-1', '1-2', '1-3', '1-4', '1-5', '1-6', '1-7'] # Check accessing an non-numeric attribute doesn't try to cache things # (see code for explanation) manager = lazy_formdata.objects with pytest.raises(TypeError): manager['drafts'] assert manager._cached_resultset is None def test_lazy_formdata_queryset_distance(pub, variable_test_data): lazy_formdata = variable_test_data formdef = lazy_formdata._formdef formdef.geolocations = {'base': 'Base'} formdef.store() data_class = lazy_formdata._formdef.data_class() for i in range(6): formdata = data_class() formdata.geolocations = {'base': {'lat': i, 'lon': i}} formdata.just_created() formdata.store() for i in range(4): formdata = data_class() formdata.geolocations = {'base': {'lat': i + 0.5, 'lon': i + 0.5}} formdata.just_created() formdata.jump_status('finished') formdata.store() formdata = data_class() formdata.status = 'draft' formdata.store() # compute distance against map field of lazy formdata nearby = lazy_formdata.objects.distance_filter(200000) assert len(nearby) == 6 assert set([x.number for x in nearby]) == set(['1-1', '1-3', '1-4', '1-8', '1-9', '1-10']) # compute distance against geolocation lazy_formdata._formdata.geolocations = {'base': {'lat': 2, 'lon': 2.5}} nearby = lazy_formdata.objects.distance_filter(200000) assert len(nearby) == 6 assert set([x.number for x in nearby]) == set(['1-1', '1-4', '1-5', '1-9', '1-10', '1-11']) assert bool(nearby) is True lazy_formdata._formdata.geolocations = {'base': {'lat': 7, 'lon': 7.5}} nearby = lazy_formdata.objects.distance_filter(200000) assert bool(nearby) is False assert len(nearby) == 0 def test_lazy_variables(pub, variable_test_data): formdata = FormDef.select()[0].data_class().select()[0] for mode in (None, 'lazy'): context = pub.substitutions.get_context_variables(mode=mode) assert context['form_number'] == formdata.get_display_id() assert context['form_display_name'] == formdata.get_display_name() assert context['form_var_foo_foo'] == 'bar' with pytest.raises(KeyError): context['form_var_xxx'] assert 'bar' in context['form_var_foo_foo'] assert context['form_var_foo_foo'] + 'ab' == 'barab' for item in enumerate(context['form_var_foo_foo']): assert item in [(0, 'b'), (1, 'a'), (2, 'r')] assert context['form_var_foo_foo_baz_baz'] == 'other' def test_lazy_variables_missing(pub, variable_test_data): formdef = FormDef.select()[0] formdata = formdef.data_class()() formdata.just_created() formdata.data = { '0': 'bar', } pub.substitutions.reset() pub.substitutions.feed(formdef) pub.substitutions.feed(formdata) for mode in (None, 'lazy'): context = pub.substitutions.get_context_variables(mode=mode) assert context['form_var_foo_foo_baz_baz'] is None assert context['form_var_foo_foo'] == 'bar' with pytest.raises(KeyError): assert context['form_var_foo_foo_xxx'] == 'bar' def test_lazy_map_variable(pub, variable_test_data): formdef = FormDef.select()[0] formdata = formdef.data_class().select()[0] for mode in (None, 'lazy'): pub.substitutions.reset() pub.substitutions.feed(formdef) with pub.substitutions.temporary_feed(formdata, force_mode=mode): assert WorkflowStatusItem.compute('=form_var_map', raises=True) == '2;4' assert WorkflowStatusItem.compute('{{ form_var_map }}', raises=True) == '2;4' assert WorkflowStatusItem.compute('=form_var_map.split(";")[0]', raises=True) == '2' assert WorkflowStatusItem.compute('{{ form_var_map|split:";"|first }}', raises=True) == '2' assert WorkflowStatusItem.compute('=form_var_map_lat', raises=True) == 2 assert WorkflowStatusItem.compute('{{ form_var_map_lat }}', raises=True) == '2.0' assert WorkflowStatusItem.compute('=form_var_map_lon', raises=True) == 4 assert WorkflowStatusItem.compute('{{ form_var_map_lon }}', raises=True) == '4.0' assert WorkflowStatusItem.compute('{{ form_var_map|distance:form_var_map|floatformat }}', raises=True) == '0' assert WorkflowStatusItem.compute('{{ form_var_map|distance:"2.1;4.1"|floatformat }}', raises=True) == '15685.4' assert WorkflowStatusItem.compute('{{ "2.1;4.1"|distance:form_var_map|floatformat }}', raises=True) == '15685.4' assert WorkflowStatusItem.compute('{{ form|distance:"1;2"|floatformat }}', raises=True) == '0' assert WorkflowStatusItem.compute('{{ form|distance:"1.1;2.1"|floatformat }}', raises=True) == '15689.1' assert WorkflowStatusItem.compute('{{ "1.1;2.1"|distance:form|floatformat }}', raises=True) == '15689.1' assert WorkflowStatusItem.compute('{{ form|distance:form_var_map|floatformat }}', raises=True) == '248515.5' assert WorkflowStatusItem.compute('{{ form_var_map|distance:form|floatformat }}', raises=True) == '248515.5' formdata.data['7'] = None formdata.store() pub.substitutions.reset() pub.substitutions.feed(formdef) pub.substitutions.feed(formdata) for mode in (None, 'lazy'): pub.substitutions.reset() pub.substitutions.feed(formdef) with pub.substitutions.temporary_feed(formdata, force_mode=mode): assert WorkflowStatusItem.compute('=form_var_map', raises=True) is None assert WorkflowStatusItem.compute('{{ form_var_map|distance:"1;2"|floatformat }}', raises=True) == '' assert WorkflowStatusItem.compute('{{ "1;2"|distance:form_var_map|floatformat }}', raises=True) == '' def test_lazy_conditions(pub, variable_test_data): condition = Condition({'type': 'django', 'value': 'form_var_foo_foo == "bar"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_foo_foo|startswith:"ba"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_foo_foo|startswith:"fo"'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form_var_foo_foo|slice:":2" == "ba"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_foo_foo|slice:":2" == "fo"'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form.var.foo_foo == "bar"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_field_string == "bar"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_role_receiver_name == "foobar"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_user_email == "bar@localhost"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_filefield_raw_content_type == "text/plain"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_user_admin_access'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form_user_backoffice_access'}) assert condition.evaluate() is False condition = Condition({'type': 'python', 'value': 'vars().get("form_var_foo_foo_xxx", "") == ""'}) assert condition.evaluate() is True user = pub.user_class.select()[0] user.is_admin = True user.store() condition = Condition({'type': 'django', 'value': 'form_user_admin_access'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_user_backoffice_access'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datefield == "2018-07-31"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datefield != "2018-07-31"'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form_var_datefield == "31/07/2018"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datefield != "31/07/2018"'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form_var_datefield >= "31/07/2018"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datefield <= "31/07/2018"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datefield > "31/07/2018"'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form_var_datefield < "31/07/2018"'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': '"2018-07-31" == form_var_datefield'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': '"31/07/2018" == form_var_datefield'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datefield != form_var_datefield2'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datefield == form_var_datefield2'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form_var_datefield < form_var_datefield2'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datefield > form_var_datefield2'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form_var_datefield <= form_var_datefield2'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datefield >= form_var_datefield2'}) assert condition.evaluate() is False # compare with string var representing a date condition = Condition({'type': 'django', 'value': 'form_var_datefield == form_var_datestring'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datestring == "2018-07-31"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_var_datestring == "31/07/2018"'}) assert condition.evaluate() is False # datestring is not a date ! # non existing form_var condition = Condition({'type': 'django', 'value': 'form_var_datefield == form_var_barbarbar'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'not form_var_datefield == form_var_barbarbar'}) assert condition.evaluate() is True def test_has_role_templatetag(pub, variable_test_data): condition = Condition({'type': 'django', 'value': 'form_user|has_role:"foobar"'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form_user|has_role:form_role_receiver_name'}) assert condition.evaluate() is False role = Role.select()[0] user = pub.user_class.select()[0] user.roles = [role.id, '42'] # role.id 42 does not exist user.store() condition = Condition({'type': 'django', 'value': 'form_user|has_role:"foobar"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_user|has_role:form_role_receiver_name'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'form_user|has_role:"barfoo"'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'form_user|has_role:form_var_foo_foo'}) assert condition.evaluate() is False # non-user object condition = Condition({'type': 'django', 'value': 'form_var_foo_foo|has_role:"foobar"'}) assert condition.evaluate() is False condition = Condition({'type': 'django', 'value': 'xxx|has_role:"foobar"'}) assert condition.evaluate() is False def test_lazy_now_and_today(pub, variable_test_data): for condition_value in ( 'now > "1970-01-01"', '"1970-01-01" < now', 'now < "2100-01-01"', '"2100-01-01" > now', 'not now < "1970-01-01"', 'not "1970-01-01" > now', 'not now > "2100-01-01"', 'not "2100-01-01" < now', # form_var_datefield is in 2018, we hope now is after 2019 'form_var_datefield < now', 'not form_var_datefield > now', 'form_var_datefield <= now', 'not form_var_datefield >= now', 'form_var_datefield != now', 'not form_var_datefield == now'): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': condition_value.replace('now', 'today')}) assert condition.evaluate() is True def test_lazy_date_templatetags(pub, variable_test_data): for condition_value in ( '"2017-10-10"|date == "2017-10-10"', '"2017-10-10"|date == "2017-10-10 00:00"', '"2017-10-10 00:00"|date == "2017-10-10 00:00"', '"2017-10-10"|date == "10/10/2017"', '"2017-10-10"|date == "10/10/2017 00:00"', '"2017-10-10"|date == "10/10/2017 00h00"', 'not "2017-10-10"|date == "11/10/2017"', '"2017-10-10"|date != "11/10/2017"', 'not "2017-10-10"|date != "10/10/2017"', '"2017-10-10"|date > "09/10/2017"', 'not "2017-10-10"|date > "10/10/2017"', '"2017-10-10"|date < "11/10/2017"', 'not "2017-10-10"|date < "10/10/2017"', '"2017-10-10"|date >= "09/10/2017"', '"2017-10-10"|date <= "10/10/2017"', '"2017-10-10"|date >= "10/10/2017"', ): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': condition_value.replace('date', 'datetime')}) assert condition.evaluate() is True # |date on the right member condition = Condition({'type': 'django', 'value': condition_value.replace('|date', '') + '|date'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': condition_value.replace('|date', '') + '|datetime'}) assert condition.evaluate() is True for condition_value in ( '"2017-10-11 12:13"|datetime == "2017-10-11 12:13"', '"2017-10-11 12:13:14"|datetime == "2017-10-11 12:13:14"', '"2017-10-11 12:13"|datetime != "2017-10-11 12:13:14"', 'not "2017-10-11 12:13"|datetime == "2017-10-11 12:13:14"', '"2017-10-11 12:13"|datetime < "2017-10-11 12:13:14"', '"2017-10-11 12:13"|datetime <= "2017-10-11 12:13:14"', '"2017-10-11 12:13:14"|datetime <= "2017-10-11 12:13:14"', '"2017-10-11 12:13:14"|datetime > "2017-10-11 12:13"', '"2017-10-11 12:13:14"|datetime >= "2017-10-11 12:13"', '"2017-10-11 12:13:14"|datetime >= "2017-10-11 12:13:14"', ): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True # |datetime on the right member condition = Condition({'type': 'django', 'value': condition_value.replace('|datetime', '') + '|datetime'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': '"2017-10-11 00:00"|datetime == "2017-10-11"|date'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': '"2017-10-11 12:13"|date == "2017-10-11"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': '"2017-10-11 12:13"|date == "2017-10-11 00:00"|datetime'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': '"2017-10-11 12:13"|date == "2017-10-11 14:15"|date'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': '"2017-10-11 01:00"|datetime|date == "2017-10-11"'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'now|date == today'}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': 'today == now|date'}) assert condition.evaluate() is True def test_lazy_date_with_maths(pub, variable_test_data): # form_var_datefield : 2018-07-31 # form_var_datefield2 : 2018-08-31 # form_var_datestring : "2018-07-31" for condition_value in ( 'form_var_datefield|add_days:0 <= "2019-01-01"', 'form_var_datefield|add_days:0 >= "1980-01-01"', 'form_var_datefield|add_days:0 == "2018-07-31"', 'form_var_datefield|add_days:0 == "31/07/2018"', 'form_var_datefield|add_days:5 == "2018-08-05"', 'form_var_datefield|add_days:5 <= "2018-08-05"', 'form_var_datefield|add_days:5 >= "2018-08-05"', 'form_var_datefield|add_days:-5 == "2018-07-26"', 'form_var_datefield|add_days:36500 > "2100-01-01"', # 2118 'form_var_datefield|add_days:-36500 < "1950-01-01"', # 1918 'form_var_datefield|add_days:31 == form_var_datefield2', 'form_var_datefield|add_days:5|add_days:-5 == form_var_datestring', 'form_var_datestring|add_days:31 == form_var_datefield2', 'form_var_datestring|add_days:32 > form_var_datefield2', 'form_var_datestring|add_days:30 < form_var_datefield2', ): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True # form_var_datefield is in 2018, we hope today/now is after 2019 for condition_value in ( 'form_var_datefield <= today', '"1970-01-01"|add_days:0 < today', '"2100-12-31"|add_days:0 > today', 'form_var_datefield|add_days:0 <= today', 'form_var_datefield|add_days:10 < today', 'form_var_datefield|add_days:36500 > today', 'form_var_datefield|add_days:36500 >= today', 'form_var_datefield <= today|add_days:0', 'form_var_datefield < today|add_days:-10', 'form_var_datefield > today|add_days:-36500', 'form_var_datefield >= today|add_days:-36500', ): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': condition_value.replace('today', 'now')}) assert condition.evaluate() is True for condition_value in ( '"1970-01-01"|add_hours:0 < today', '"2100-12-31"|add_hours:0 > today', 'form_var_datefield|add_hours:0 <= today', 'form_var_datefield|add_hours:10 < today', 'form_var_datefield|add_hours:876000 > today', # + 100 years 'form_var_datefield|add_hours:876000 >= today', ): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': condition_value.replace('today', 'now')}) assert condition.evaluate() is True for condition_value in ( 'today|add_days:0 == today', 'today|add_hours:0 == today', 'now|add_hours:0 == now', ): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True for condition_value in ( 'today|add_days:2 >= today', 'today|add_days:2 > today', 'today|add_days:2 != today', 'not today|add_days:2 == today', 'not today|add_days:2 <= today', 'not today|add_days:2 < today', 'today|add_days:-2 <= today', 'today|add_days:-2 < today', 'today|add_days:-2 != today', 'not today|add_days:-2 >= today', 'not today|add_days:-2 > today', 'not today|add_days:-2 == today', ): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True condition = Condition({'type': 'django', 'value': condition_value.replace('today', 'now')}) assert condition.evaluate() is True def test_lazy_templates(pub, variable_test_data): context = pub.substitutions.get_context_variables(mode='lazy') tmpl = Template('{{form_var_foo_foo}}') assert tmpl.render(context) == 'bar' tmpl = Template('[form_var_foo_foo]') assert tmpl.render(context) == 'bar' tmpl = Template('[form_name]') assert tmpl.render(context) == 'foobarlazy' tmpl = Template('[form_user_email]') assert tmpl.render(context) == 'bar@localhost' tmpl = Template('{{form_user_name_identifier_0}}') assert tmpl.render(context) == pub.user_class.select()[0].name_identifiers[0] tmpl = Template('{% if form_user_email == "bar@localhost" %}HELLO{% endif %}') assert tmpl.render(context) == 'HELLO' def test_lazy_ezt_templates(pub, variable_test_data): context = pub.substitutions.get_context_variables(mode='lazy') tmpl = Template('[form_var_foo_foo]') assert tmpl.render(context) == 'bar' tmpl = Template('[is form_var_foo_foo "bar"]HELLO[else]BYE[end]') assert tmpl.render(context) == 'HELLO' def test_lazy_formdata_fields(pub): formdef = FormDef() formdef.name = 'foobar' formdef.url_name = 'foobar' formdef.fields = [ fields.StringField(id='0', label='string', varname='string'), fields.ItemField(id='1', label='item', varname='item', items=['Foo', 'Bar']) ] formdef.store() formdata = formdef.data_class()() formdata.data = {'0': 'Foo', '1': 'Foo', '1_display': 'Foo'} formdata.store() pub.substitutions.feed(formdata) context = pub.substitutions.get_context_variables(mode='lazy') tmpl = Template('{% if form_var_string == "Foo" %}HELLO{% endif %}') assert tmpl.render(context) == 'HELLO' tmpl = Template('{% if form_var_item == "Foo" %}HELLO{% endif %}') assert tmpl.render(context) == 'HELLO' tmpl = Template('{% if form_var_string != "Foo" %}HELLO{% endif %}') assert tmpl.render(context) == '' tmpl = Template('{% if form_var_item != "Foo" %}HELLO{% endif %}') assert tmpl.render(context) == '' def test_date_conditions_python(pub, variable_test_data): for pycondition in ( 'utils.age_in_days(form_var_datefield, form_var_datefield2) == 31', 'utils.age_in_days(form_var_datefield, form_var_datefield) == 0', 'utils.age_in_days(form_var_datefield, form_var_datestring) == 0', 'utils.age_in_days(utils.add_days(today, -5)) == 5', 'date(form_var_datefield) < today', 'utils.add_days(form_var_datefield, 36500) > today', 'date(form_var_datefield) + days(36500) > today', 'utils.add_days(form_var_datefield, 31) == date(form_var_datefield2)', 'date(form_var_datefield) + days(31) == date(form_var_datefield2)', 'utils.add_days(form_var_datefield, 32) > date(form_var_datefield2)', 'date(form_var_datefield) + days(32) > date(form_var_datefield2)', 'utils.add_days(form_var_datefield, 30) < date(form_var_datefield2)', 'date(form_var_datefield) + days(30) < date(form_var_datefield2)', 'isinstance(now, datetime.datetime)', 'isinstance(today, datetime.date)', 'utils.age_in_days(today) == 0', 'utils.age_in_days(now) == 0', 'utils.age_in_years(today) == 0', 'utils.age_in_years(now) == 0', 'utils.age_in_years_and_months(today) == (0, 0)', 'utils.age_in_years_and_months(now) == (0, 0)', 'utils.age_in_years_and_months(form_var_datefield, form_var_datefield2) == (0, 1)', ): condition = Condition({'type': 'python', 'value': pycondition}) assert condition.evaluate() is True def test_date_conditions_django(pub, variable_test_data): for condition_value in ( # hope date is > 2018 # age_in_days '"1970-01-01"|age_in_days > 0', '"01/01/1970"|age_in_days > 0', '"2500-01-01"|age_in_days < 0', '"01/01/2500"|age_in_days < 0', 'form_var_datefield|age_in_days > 50', 'form_var_datefield|age_in_days:form_var_datestring == 0', 'form_var_datefield|age_in_days:form_var_datefield2 == 31', 'form_var_datefield2|age_in_days:form_var_datefield == -31', 'form_var_datefield|age_in_days:form_var_datefield == 0', 'form_var_datestring|age_in_days:form_var_datefield == 0', 'form_var_datestring|age_in_days:form_var_datestring == 0', 'today|add_days:-5|age_in_days == 5', 'today|add_days:5|age_in_days == -5', 'today|age_in_days == 0', # with datetimes '"1970-01-01 02:03"|age_in_days > 0', '"01/01/1970 02h03"|age_in_days > 0', '"2500-01-01 02:03"|age_in_days < 0', '"01/01/2500 02h03"|age_in_days < 0', 'now|age_in_days == 0', 'now|add_hours:-24|age_in_days == 1', 'now|add_hours:24|age_in_days == -1', '"2010-11-12 13:14"|age_in_days:"2010-11-12 13:14" == 0', '"2010-11-12 13:14"|age_in_days:"2010-11-12 12:14" == 0', '"2010-11-12 13:14"|age_in_days:"2010-11-12 14:14" == 0', '"2010-11-12 13:14"|age_in_days:"2010-11-13 13:13" == 1', '"2010-11-12 13:14"|age_in_days:"2010-11-13 13:15" == 1', # age_in_hours 'now|add_hours:-5|age_in_hours == 5', 'now|add_hours:25|age_in_hours == -24', 'now|age_in_hours == 0', '"2010-11-12 13:14"|age_in_hours:"2010-11-12 13:14" == 0', '"2010-11-12 13:14"|age_in_hours:"2010-11-12 12:14" == -1', '"2010-11-12 13:14"|age_in_hours:"2010-11-12 14:14" == 1', '"2010-11-12 13:14"|age_in_hours:"2010-11-13 13:13" == 23', '"2010-11-12 13:14"|age_in_hours:"2010-11-13 13:15" == 24', '"1970-01-01 02:03"|age_in_hours > 0', '"01/01/1970 02h03"|age_in_hours > 0', '"2500-01-01 02:03"|age_in_hours < 0', '"01/01/2500 02h03"|age_in_hours < 0', # with dates '"1970-01-01"|age_in_hours > 0', '"01/01/1970"|age_in_hours > 0', '"2500-01-01"|age_in_hours < 0', '"01/01/2500"|age_in_hours < 0', 'form_var_datefield|age_in_hours > 1200', 'form_var_datefield|age_in_hours:form_var_datestring == 0', 'form_var_datefield|age_in_hours:form_var_datefield2 == 744', # 31*24 'form_var_datefield2|age_in_hours:form_var_datefield == -744', 'form_var_datefield|age_in_hours:form_var_datefield == 0', 'form_var_datestring|age_in_hours:form_var_datefield == 0', 'form_var_datestring|age_in_hours:form_var_datestring == 0', 'today|add_days:-1|age_in_hours >= 24', 'today|add_days:1|age_in_hours <= -0', 'today|add_days:1|age_in_hours >= -24', 'today|age_in_hours >= 0', # age_in_years '"1970-01-01"|age_in_years > 0', '"01/01/1970"|age_in_years > 0', '"2500-01-01"|age_in_years < 0', '"01/01/2500"|age_in_years < 0', 'form_var_datefield|age_in_years:"2019-07-31" == 1', 'form_var_datefield|age_in_years:"2019-09-20" == 1', 'form_var_datefield|age_in_years:"2020-07-30" == 1', 'form_var_datefield|age_in_years:"2020-07-31" == 2', 'form_var_datestring|age_in_years:"2019-07-31" == 1', 'today|age_in_years == 0', 'today|add_days:-500|age_in_years == 1', 'today|add_days:-300|age_in_years == 0', 'today|add_days:300|age_in_years == -1', 'now|age_in_years == 0', 'now|add_days:-500|age_in_years == 1', 'now|add_days:-300|age_in_years == 0', 'now|add_days:300|age_in_years == -1', '"1970-01-01 02:03"|age_in_years > 0', '"2500-01-01 02:03"|age_in_years < 0', # age_in_months 'form_var_datefield|age_in_months:form_var_datefield2 == 1', 'form_var_datefield2|age_in_months:form_var_datefield == -1', 'form_var_datefield|age_in_months:"2019-07-31" == 12', 'form_var_datefield|age_in_months:"2019-08-20" == 12', 'form_var_datefield|age_in_months:"2019-09-20" == 13', 'form_var_datestring|age_in_months:"2019-09-20" == 13', '"1970-01-01"|age_in_months > 0', '"01/01/1970"|age_in_months > 0', '"2500-01-01"|age_in_months < 0', '"01/01/2500"|age_in_months < 0', '"1970-01-01 02:03"|age_in_months > 0', '"2500-01-01 02:03"|age_in_months < 0', # fail produce empty string 'foobar|age_in_days == ""', '"foobar"|age_in_days == ""', '"1970-01-01"|age_in_days:"foobar" == ""', 'foobar|age_in_hours == ""', '"foobar"|age_in_hours == ""', '"1970-01-01"|age_in_hours:"foobar" == ""', 'foobar|age_in_years == ""', '"foobar"|age_in_years == ""', '"1970-01-01"|age_in_years:"foobar" == ""', 'foobar|age_in_months == ""', '"foobar"|age_in_months == ""', '"1970-01-01"|age_in_months:"foobar" == ""', ): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True def test_form_digest_date(pub): formdef = FormDef() formdef.name = 'foobar' formdef.url_name = 'foobar' formdef.fields = [fields.DateField(id='0', label='date', varname='date')] formdef.digest_template = 'plop {{ form_var_date }} plop' formdef.store() formdata = formdef.data_class()() formdata.data = {'0': time.strptime('2015-05-12', '%Y-%m-%d')} formdata.store() assert formdef.data_class().get(formdata.id).digest == 'plop 2015-05-12 plop' pub.cfg['language'] = {'language': 'fr'} pub.write_cfg() formdata = formdef.data_class()() formdata.data = {'0': time.strptime('2015-05-12', '%Y-%m-%d')} formdata.store() assert formdef.data_class().get(formdata.id).digest == 'plop 12/05/2015 plop' formdef.digest_template = 'plop {{ form_var_date|date:"Y" }} plop' formdef.store() formdata = formdef.data_class()() formdata.data = {'0': time.strptime('2015-05-12', '%Y-%m-%d')} formdata.store() assert formdef.data_class().get(formdata.id).digest == 'plop 2015 plop' formdef.digest_template = 'plop {{ form_var_date_raw|date:"Y" }} plop' formdef.store() formdata = formdef.data_class()() formdata.data = {'0': time.strptime('2015-05-12', '%Y-%m-%d')} formdata.store() assert formdef.data_class().get(formdata.id).digest == 'plop 2015 plop' formdef.digest_template = 'plop {{ form_var_date|date:"Y" }} plop' formdef.store() formdata = formdef.data_class()() formdata.data = {'0': None} formdata.store() assert formdef.data_class().get(formdata.id).digest == 'plop plop' # check there's no crash when an invaliad variable is given formdef.digest_template = 'plop {{ blah|date:"Y" }} plop' formdef.store() formdata = formdef.data_class()() formdata.data = {'0': time.strptime('2015-05-12', '%Y-%m-%d')} formdata.store() assert formdef.data_class().get(formdata.id).digest == 'plop plop' def test_lazy_formdata_decimal_filter(pub): formdef = FormDef() formdef.name = 'foobar' formdef.url_name = 'foobar' formdef.fields = [ fields.StringField(id='0', label='value', varname='value'), fields.StringField(id='1', label='arg', varname='arg') ] formdef.store() formdata = formdef.data_class()() formdata.data = {'0': '3.14', '1': '3'} formdata.store() pub.substitutions.feed(formdata) for mode in (None, 'lazy'): context = pub.substitutions.get_context_variables(mode=mode) tmpl = Template('{{ form_var_value|decimal }}') assert tmpl.render(context) == '3.14' tmpl = Template('{{ form_var_value|decimal:1 }}') assert tmpl.render(context) == '3.1' tmpl = Template('{{ form_var_value|decimal:form_var_arg }}') assert tmpl.render(context) == '3.140' tmpl = Template('{{ 4.12|decimal:form_var_arg }}') assert tmpl.render(context) == '4.120' def test_decimal_conditions_django(pub, variable_test_data): for condition_value in ( 'form_var_foo_foo|decimal == 0', 'form_var_boolfield|decimal == 0', 'form_var_boolfield2|decimal == 0', 'form_var_datefield|decimal == 0', 'form_var_datefield|decimal == 0', 'form_var_filefield|decimal == 0', 'form_var_foo_foo_baz_baz|decimal == 0', 'form_var_map|decimal == 0', 'form_var_datefield2|decimal == 0', 'form_var_datestring|decimal == 0', 'form_var_term1|decimal == 3', 'form_var_term2|decimal == 4', ): condition = Condition({'type': 'django', 'value': condition_value}) assert condition.evaluate() is True def test_lazy_formdata_mathematics_filters(pub): formdef = FormDef() formdef.name = 'foobar' formdef.url_name = 'foobar' formdef.fields = [ fields.StringField(id='0', label='term1', varname='term1'), fields.StringField(id='1', label='term2', varname='term2') ] formdef.store() formdata = formdef.data_class()() formdata.data = {'0': '3', '1': '4'} formdata.store() pub.substitutions.feed(formdata) for mode in (None, 'lazy'): context = pub.substitutions.get_context_variables(mode=mode) tmpl = Template('{{ form_var_term1|decimal }}') assert tmpl.render(context) == '3' tmpl = Template('{{ form_var_term1|add:form_var_term2 }}') assert tmpl.render(context) == '7' tmpl = Template('{{ form_var_term1|subtract:form_var_term2 }}') assert tmpl.render(context) == '-1' tmpl = Template('{{ form_var_term1|multiply:form_var_term2 }}') assert tmpl.render(context) == '12' tmpl = Template('{{ form_var_term1|divide:form_var_term2 }}') assert tmpl.render(context) == '0.75' def test_mathematic_conditions_django(pub, variable_test_data): for true_condition_value in ( # reminder 'form_var_term1 == 3', 'form_var_term2 == 4', # add 'form_var_term1|add:form_var_term2 == 7', 'form_var_term1|add:form_var_term2 == 7.0', 'form_var_term1|add:form_var_term2 == "7"|decimal', 'form_var_term1|add:form_var_term2 > 6', # subtract 'form_var_term1|subtract:form_var_term2 == -1', 'form_var_term1|subtract:form_var_term2 == -1.0', 'form_var_term1|subtract:form_var_term2 == "-1"|decimal', 'form_var_term1|subtract:form_var_term2 < 0', # multiply 'form_var_term1|multiply:form_var_term2 == 12', 'form_var_term1|multiply:form_var_term2 == 12.0', 'form_var_term1|multiply:form_var_term2 == "12"|decimal', 'form_var_term1|multiply:form_var_term2 > 10', # divide 'form_var_term1|divide:form_var_term2 == 0.75', 'form_var_term1|divide:form_var_term2 == 0.750', 'form_var_term1|divide:form_var_term2 == "0.75"|decimal', 'form_var_term1|divide:form_var_term2 > 0.5', ): condition = Condition({'type': 'django', 'value': true_condition_value}) assert condition.evaluate() is True for false_condition_value in ( 'form_var_term1|add:form_var_term2 > 8', 'form_var_term1|subtract:form_var_term2 > 0', 'form_var_term1|multiply:form_var_term2 > 20', 'form_var_term1|divide:form_var_term2 > 1', ): condition = Condition({'type': 'django', 'value': false_condition_value}) assert condition.evaluate() is False def test_lazy_formdata_ceil_filter(pub): formdef = FormDef() formdef.name = 'foobar' formdef.url_name = 'foobar' formdef.fields = [ fields.StringField(id='0', label='value', varname='value'), ] formdef.store() formdata = formdef.data_class()() formdata.data = {'0': '3.14'} formdata.store() pub.substitutions.feed(formdata) for mode in (None, 'lazy'): context = pub.substitutions.get_context_variables(mode=mode) tmpl = Template('{{ form_var_value|ceil }}') assert tmpl.render(context) == '4' tmpl = Template('{{ form_var_value|floor }}') assert tmpl.render(context) == '3' tmpl = Template('{{ form_var_value|abs }}') assert tmpl.render(context) == '3.14' def test_rounding_and_abs_conditions_django(pub, variable_test_data): for true_condition_value in ( # reminder 'form_var_value == 3.14', # ceil 'form_var_value|ceil == 4', 'form_var_value|ceil == 4.0', 'form_var_value|ceil > 3', # floor 'form_var_value|floor == 3', 'form_var_value|floor == 3.0', 'form_var_value|floor >= 3', # abs 'form_var_value|abs == 3.14|decimal', 'form_var_value|abs == 3.140|decimal', 'form_var_value|abs >= 3', ): condition = Condition({'type': 'django', 'value': true_condition_value}) assert condition.evaluate() is True for false_condition_value in ( 'form_var_value|ceil < 4', 'form_var_value|ceil >= 5', 'form_var_value|floor < 3', ): condition = Condition({'type': 'django', 'value': false_condition_value}) assert condition.evaluate() is False def test_formdata_user_field(pub, variable_test_data): local_user = variable_test_data._formdata.user from wcs.admin.settings import UserFieldsFormDef user_formdef = UserFieldsFormDef(pub) user_formdef.fields.append(fields.StringField(id='3', label='test', varname='test', type='string')) user_formdef.store() local_user.form_data = {'3': 'nono'} local_user.set_attributes_from_formdata(local_user.form_data) local_user.store() for mode in (None, 'lazy'): context = pub.substitutions.get_context_variables(mode=mode) tmpl = Template('{{ form_user_var_test }}') assert tmpl.render(context) == 'nono' condition = Condition({'type': 'django', 'value': 'form_user_var_test'}) assert condition.evaluate() is True local_user.form_data = {'3': ''} local_user.set_attributes_from_formdata(local_user.form_data) local_user.store() condition = Condition({'type': 'django', 'value': 'form_user_var_test'}) assert condition.evaluate() is False def test_string_filters(pub, variable_test_data): tmpl = Template('{% with form_var_foo_foo|split:"a" as x %}{{x.0}}{% endwith %}', raises=True) for mode in (None, 'lazy'): context = pub.substitutions.get_context_variables(mode=mode) assert tmpl.render(context) == 'b' tmpl = Template('{% if form_var_foo_foo|startswith:"b" %}test{% endif %}', raises=True) for mode in (None, 'lazy'): context = pub.substitutions.get_context_variables(mode=mode) assert tmpl.render(context) == 'test' tmpl = Template('{% if form_var_foo_foo|startswith:form_var_term1 %}test{% endif %}', raises=True) for mode in (None, 'lazy'): context = pub.substitutions.get_context_variables(mode=mode) assert tmpl.render(context) == '' def test_user_label(pub): from wcs.admin.settings import UserFieldsFormDef user_formdef = UserFieldsFormDef(pub) user_formdef.fields.append(fields.StringField(id='3', label='first_name', type='string')) user_formdef.fields.append(fields.StringField(id='4', label='last_name', type='string')) user_formdef.store() pub.cfg['users']['field_name'] = ['3', '4'] pub.write_cfg() formdef = FormDef() formdef.name = 'foobar' formdef.url_name = 'foobar' formdef.fields = [ fields.StringField(id='1', label='first_name', prefill={'type': 'user', 'value': '3'}), fields.StringField(id='2', label='last_name', prefill={'type': 'user', 'value': '4'}), ] formdef.store() user = pub.user_class() user.email = 'bar@localhost' user.store() formdata = formdef.data_class()() formdata.data = {} formdata.user_id = user.id formdata.store() assert str(formdef.data_class().get(formdata.id).user_id) == str(user.id) assert formdef.data_class().get(formdata.id).user_label is None assert formdef.data_class().get(formdata.id).get_user_label() == 'bar@localhost' formdata = formdef.data_class()() formdata.data = {} formdata.store() assert formdef.data_class().get(formdata.id).user_id is None assert formdef.data_class().get(formdata.id).user_label == '' assert formdef.data_class().get(formdata.id).get_user_label() == '' formdata = formdef.data_class()() formdata.data = {'1': 'blah'} formdata.store() assert formdef.data_class().get(formdata.id).user_id is None assert formdef.data_class().get(formdata.id).user_label == 'blah' assert formdef.data_class().get(formdata.id).get_user_label() == 'blah' formdata = formdef.data_class()() formdata.data = {'1': 'blah', '2': 'xxx'} formdata.store() assert formdef.data_class().get(formdata.id).user_id is None assert formdef.data_class().get(formdata.id).user_label == 'blah xxx' assert formdef.data_class().get(formdata.id).get_user_label() == 'blah xxx'