wcs/tests/test_formdata.py

1704 lines
71 KiB
Python

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'