general: store conditions as type/value dictionaries (#21550)
This commit is contained in:
parent
653a2b8efc
commit
2c0e8e4d05
|
@ -1210,18 +1210,18 @@ def test_form_edit_page_field(pub):
|
|||
assert FormDef.get(1).fields[0].label == 'foobar'
|
||||
|
||||
resp = resp.click('Edit', href='1/')
|
||||
resp.form['post_conditions$element0$condition'] = 'foo'
|
||||
resp.form['post_conditions$element0$condition$value_python'] = 'foo'
|
||||
resp.form['post_conditions$element0$error_message'] = 'bar'
|
||||
resp = resp.form.submit('post_conditions$add_element')
|
||||
resp.form['post_conditions$element1$condition'] = 'foo2'
|
||||
resp.form['post_conditions$element1$condition$value_python'] = 'foo2'
|
||||
resp = resp.form.submit('submit')
|
||||
assert 'Both condition and error message are required.' in resp.body
|
||||
resp.form['post_conditions$element1$error_message'] = 'bar2'
|
||||
resp = resp.form.submit('submit')
|
||||
|
||||
assert FormDef.get(1).fields[0].post_conditions == [
|
||||
{'condition': 'foo', 'error_message': 'bar'},
|
||||
{'condition': 'foo2', 'error_message': 'bar2'},
|
||||
{'condition': {'type': 'python', 'value': 'foo'}, 'error_message': 'bar'},
|
||||
{'condition': {'type': 'python', 'value': 'foo2'}, 'error_message': 'bar2'},
|
||||
]
|
||||
|
||||
def test_form_edit_comment_field(pub):
|
||||
|
|
|
@ -3676,7 +3676,7 @@ def test_backoffice_logged_errors(pub):
|
|||
jump = JumpWorkflowStatusItem()
|
||||
jump.id = '_jump'
|
||||
jump.status = 'rejected'
|
||||
jump.condition = '1/0' # ZeroDivisionError
|
||||
jump.condition = {'type': 'python', 'value': '1/0'} # ZeroDivisionError
|
||||
st1 = workflow.possible_status[0]
|
||||
st1.items.insert(0, jump)
|
||||
jump.parent = st1
|
||||
|
|
|
@ -119,7 +119,7 @@ def test_page():
|
|||
formdef.fields = []
|
||||
page = fields.PageField()
|
||||
assert page.is_visible({}, formdef) is True
|
||||
page.condition = 'var_foo == "bar"'
|
||||
page.condition = {'type': 'python', 'value': 'var_foo == "bar"'}
|
||||
assert page.is_visible({}, formdef) is True # 'var_foo' is not defined
|
||||
formdef.fields = [fields.StringField(id='1', label='string', varname='foo')]
|
||||
assert page.is_visible({}, formdef) is False
|
||||
|
|
|
@ -463,7 +463,7 @@ def test_form_multi_page(pub):
|
|||
fields.StringField(id='1', label='string'),
|
||||
fields.PageField(id='2', label='2nd page', type='page'),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
formdef.fields[0].condition = initial_condition
|
||||
formdef.fields[0].condition = {'type': 'python', 'value': initial_condition}
|
||||
formdef.store()
|
||||
page = get_app(pub).get('/test/')
|
||||
formdef.data_class().wipe()
|
||||
|
@ -489,7 +489,8 @@ def test_form_multi_page_condition(pub):
|
|||
formdef = create_formdef()
|
||||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),
|
||||
fields.StringField(id='1', label='string'),
|
||||
fields.PageField(id='2', label='2nd page', type='page', condition='False'),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition={'type': 'python', 'value': 'False'}),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
formdef.store()
|
||||
resp = get_app(pub).get('/test/')
|
||||
|
@ -508,9 +509,9 @@ def test_form_multi_page_condition_select(pub):
|
|||
required=True,
|
||||
varname='foo', items=['Foo', 'Bar']),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition='var_foo == "Foo"'),
|
||||
condition={'type': 'python', 'value': 'var_foo == "Foo"'}),
|
||||
fields.PageField(id='3', label='3rd page', type='page',
|
||||
condition='var_foo == "Bar"'),
|
||||
condition={'type': 'python', 'value': 'var_foo == "Bar"'}),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
@ -537,9 +538,9 @@ def test_form_multi_page_condition_select_new_varname(pub):
|
|||
required=True,
|
||||
varname='foo', items=['Foo', 'Bar']),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition='form_var_foo == "Foo"'),
|
||||
condition={'type': 'python', 'value': 'form_var_foo == "Foo"'}),
|
||||
fields.PageField(id='3', label='3rd page', type='page',
|
||||
condition='form_var_foo == "Bar"'),
|
||||
condition={'type': 'python', 'value': 'form_var_foo == "Bar"'}),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
@ -564,7 +565,7 @@ def test_form_multi_page_condition_checkbox(pub):
|
|||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),
|
||||
fields.BoolField(id='1', label='checkbox', varname='checkbox'),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition='var_checkbox == "False"'),
|
||||
condition={'type': 'python', 'value': 'var_checkbox == "False"'}),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
formdef.store()
|
||||
resp = get_app(pub).get('/test/')
|
||||
|
@ -585,10 +586,10 @@ def test_form_multi_page_condition_json_check(pub):
|
|||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),
|
||||
fields.BoolField(id='1', label='checkbox', varname='checkbox'),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition='var_checkbox == "False"'),
|
||||
condition={'type': 'python', 'value': 'var_checkbox == "False"'}),
|
||||
fields.StringField(id='3', label='string 2', varname='st2'),
|
||||
fields.PageField(id='4', label='3rd page', type='page',
|
||||
condition='var_checkbox == "True"'),
|
||||
condition={'type': 'python', 'value': 'var_checkbox == "True"'}),
|
||||
fields.StringField(id='5', label='string 3', varname='st3'),
|
||||
]
|
||||
formdef.store()
|
||||
|
@ -627,10 +628,10 @@ def test_form_multi_page_condition_no_confirmation_json_check(pub):
|
|||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),
|
||||
fields.BoolField(id='1', label='checkbox', varname='checkbox'),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition='var_checkbox == "False"'),
|
||||
condition={'type': 'python', 'value': 'var_checkbox == "False"'}),
|
||||
fields.StringField(id='3', label='string 2', varname='st2'),
|
||||
fields.PageField(id='4', label='3rd page', type='page',
|
||||
condition='var_checkbox == "True"'),
|
||||
condition={'type': 'python', 'value': 'var_checkbox == "True"'}),
|
||||
fields.StringField(id='5', label='string 3', varname='st3'),
|
||||
fields.PageField(id='6', label='4th page', type='page'),
|
||||
fields.CommentField(id='7', label='Check values then click submit.',
|
||||
|
@ -670,7 +671,7 @@ def test_form_multi_page_condition_data_source(pub):
|
|||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),
|
||||
fields.BoolField(id='1', label='checkbox', varname='checkbox'),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition='len(data_source.foobar) > 0'),
|
||||
condition={'type': 'python', 'value': 'len(data_source.foobar) > 0'}),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
formdef.store()
|
||||
|
||||
|
@ -707,7 +708,7 @@ def test_form_multi_page_condition_data_source_with_form_variable(pub):
|
|||
fields.StringField(id='1', label='string', varname='xxx',
|
||||
required=False),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition='len(data_source.foobar) > 0'),
|
||||
condition={'type': 'python', 'value': 'len(data_source.foobar) > 0'}),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
formdef.store()
|
||||
|
||||
|
@ -731,7 +732,9 @@ def test_form_multi_page_condition_data_source_with_form_variable(pub):
|
|||
|
||||
def test_form_multi_page_condition_on_first_page(pub):
|
||||
formdef = create_formdef()
|
||||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page', condition='False'),
|
||||
formdef.fields = [
|
||||
fields.PageField(id='0', label='1st page', type='page',
|
||||
condition={'type': 'condition', 'value': 'False'}),
|
||||
fields.StringField(id='1', label='string'),
|
||||
fields.PageField(id='2', label='2nd page', type='page'),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
|
@ -752,9 +755,12 @@ def test_form_multi_page_condition_on_first_page(pub):
|
|||
|
||||
def test_form_multi_page_condition_no_visible_page(pub):
|
||||
formdef = create_formdef()
|
||||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page', condition='False'),
|
||||
formdef.fields = [
|
||||
fields.PageField(id='0', label='1st page', type='page',
|
||||
condition={'type': 'python', 'value': 'False'}),
|
||||
fields.StringField(id='1', label='string'),
|
||||
fields.PageField(id='2', label='2nd page', type='page', condition='False'),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition={'type': 'python', 'value': 'False'}),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
formdef.store()
|
||||
get_app(pub).get('/test/', status=404)
|
||||
|
@ -763,7 +769,8 @@ def test_form_multi_page_post_conditions(pub):
|
|||
formdef = create_formdef()
|
||||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),
|
||||
fields.StringField(id='1', label='string', varname='foo'),
|
||||
fields.PageField(id='2', label='2nd page', type='page', condition='False'),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition={'type': 'python', 'value': 'False'}),
|
||||
fields.StringField(id='3', label='string 2'),
|
||||
fields.PageField(id='4', label='3rd page', type='page'),
|
||||
fields.StringField(id='5', label='string 3', varname='bar'),
|
||||
|
@ -783,7 +790,7 @@ def test_form_multi_page_post_conditions(pub):
|
|||
assert formdef.data_class().select()[0].data['5'] == 'bar'
|
||||
|
||||
formdef.fields[4].post_conditions = [
|
||||
{'condition': 'False', 'error_message': 'You shall not pass.'},
|
||||
{'condition': {'type': 'python', 'value': 'False'}, 'error_message': 'You shall not pass.'},
|
||||
]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
@ -797,7 +804,7 @@ def test_form_multi_page_post_conditions(pub):
|
|||
assert 'You shall not pass.' in resp.body
|
||||
|
||||
formdef.fields[4].post_conditions = [
|
||||
{'condition': 'form_var_foo == "foo"', 'error_message': 'You shall not pass.'},
|
||||
{'condition': {'type': 'python', 'value': 'form_var_foo == "foo"'}, 'error_message': 'You shall not pass.'},
|
||||
]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
@ -818,7 +825,7 @@ def test_form_multi_page_post_conditions(pub):
|
|||
|
||||
# check a post-condition raising an exception, they should always fail.
|
||||
formdef.fields[4].post_conditions = [
|
||||
{'condition': '1/0', 'error_message': 'You shall not pass.'},
|
||||
{'condition': {'type': 'python', 'value': '1/0'}, 'error_message': 'You shall not pass.'},
|
||||
]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
@ -832,7 +839,7 @@ def test_form_multi_page_post_conditions(pub):
|
|||
|
||||
# check a post-condition referring to a field on the same page
|
||||
formdef.fields[4].post_conditions = [
|
||||
{'condition': 'form_var_bar == "bar"', 'error_message': 'You shall not pass.'},
|
||||
{'condition': {'type': 'python', 'value': 'form_var_bar == "bar"'}, 'error_message': 'You shall not pass.'},
|
||||
]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
@ -1350,7 +1357,7 @@ def test_form_multi_page_formdef_count_condition(pub):
|
|||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),
|
||||
fields.StringField(id='1', label='string'),
|
||||
fields.PageField(id='2', label='2nd page', type='page',
|
||||
condition='form_objects.count > 0'),
|
||||
condition={'type': 'python', 'value': 'form_objects.count > 0'}),
|
||||
fields.StringField(id='3', label='string 2')]
|
||||
formdef.store()
|
||||
|
||||
|
@ -1459,7 +1466,7 @@ def test_form_count_dispatching(pub):
|
|||
workflow = Workflow(name='test')
|
||||
st1 = workflow.add_status('Status1', 'st1')
|
||||
jump = JumpWorkflowStatusItem()
|
||||
jump.condition = 'form_objects.count_status_st2 < 1'
|
||||
jump.condition = {'type': 'python', 'value': 'form_objects.count_status_st2 < 1'}
|
||||
jump.status = 'st2'
|
||||
st1.items.append(jump)
|
||||
jump.parent = st1
|
||||
|
@ -2964,12 +2971,14 @@ def test_form_middle_session_change(pub):
|
|||
def test_form_autocomplete_variadic_url(pub):
|
||||
formdef = create_formdef()
|
||||
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),
|
||||
fields.PageField(id='3', label='2nd page', type='page', condition="True"),
|
||||
fields.PageField(id='3', label='2nd page', type='page',
|
||||
condition={'type': 'python', 'value': 'True'}),
|
||||
fields.ItemField(id='1', label='string', type='item',
|
||||
varname='foo', items=['Foo', 'Bar']),
|
||||
fields.StringField(id='2', label='string2', required=True,
|
||||
data_source={'type': 'jsonp', 'value': '[var_foo]'}),
|
||||
fields.PageField(id='4', label='3rd page', type='page', condition="True")
|
||||
fields.PageField(id='4', label='3rd page', type='page',
|
||||
condition={'type': 'python', 'value': 'True'})
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
|
@ -3842,7 +3851,7 @@ def test_logged_errors(pub):
|
|||
jump = JumpWorkflowStatusItem()
|
||||
jump.id = '_jump'
|
||||
jump.status = 'rejected'
|
||||
jump.condition = '1/0' # ZeroDivisionError
|
||||
jump.condition = {'type': 'python', 'value': '1/0'} # ZeroDivisionError
|
||||
st1 = workflow.possible_status[0]
|
||||
st1.items.insert(0, jump)
|
||||
jump.parent = st1
|
||||
|
|
|
@ -12,7 +12,7 @@ from wcs import formdef
|
|||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.http_request import HTTPRequest
|
||||
from wcs.workflows import Workflow
|
||||
from wcs.fields import StringField, FileField, DateField, ItemField
|
||||
from wcs.fields import StringField, FileField, DateField, ItemField, PageField
|
||||
|
||||
from utilities import create_temporary_pub, clean_temporary_pub
|
||||
|
||||
|
@ -211,3 +211,19 @@ def test_internal_identifier_migration(pub):
|
|||
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert formdef.internal_identifier == 'foo'
|
||||
|
||||
def test_page_field_migration(pub):
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'foo'
|
||||
formdef.fields = [
|
||||
PageField(id='1', type='page',
|
||||
condition='foo',
|
||||
post_conditions=[{'condition': 'blah', 'error_message': 'blah'}]),
|
||||
]
|
||||
formdef.store()
|
||||
formdef = FormDef.get(formdef.id)
|
||||
assert formdef.fields[0].condition == {'type': 'python', 'value': 'foo'}
|
||||
assert formdef.fields[0].post_conditions == [
|
||||
{'condition': {'type': 'python', 'value': 'blah'},
|
||||
'error_message': 'blah'}]
|
||||
|
|
|
@ -320,26 +320,54 @@ def test_wrong_max_field_id():
|
|||
formdef2 = FormDef.import_from_xml(StringIO.StringIO(export), include_id=True)
|
||||
assert formdef2.max_field_id == 2
|
||||
|
||||
def test_page_condition():
|
||||
formdef = FormDef()
|
||||
formdef.name = 'foo'
|
||||
formdef.fields = [
|
||||
fields.PageField(id='1', type='page',
|
||||
condition={'type': 'python', 'value': 'blah'})
|
||||
]
|
||||
fd2 = assert_xml_import_export_works(formdef)
|
||||
assert fd2.fields[0].type == 'page'
|
||||
assert fd2.fields[0].condition == formdef.fields[0].condition
|
||||
|
||||
# test legacy condition (simple string)
|
||||
formdef_xml = formdef.export_to_xml(include_id=True)
|
||||
condition = formdef_xml.findall('fields/field/condition')[0]
|
||||
condition.clear()
|
||||
condition.text = 'blah'
|
||||
fd2 = FormDef.import_from_xml_tree(formdef_xml, include_id=True)
|
||||
assert fd2.fields[0].condition == formdef.fields[0].condition
|
||||
|
||||
def test_page_post_conditions():
|
||||
formdef = FormDef()
|
||||
formdef.name = 'foo'
|
||||
formdef.fields = [
|
||||
fields.PageField(id='1', type='page',
|
||||
post_conditions=[{'condition': 'blah', 'error_message': 'bar'}]),
|
||||
post_conditions=[{'condition': {'type': 'python', 'value': 'blah'}, 'error_message': 'bar'}]),
|
||||
]
|
||||
fd2 = assert_xml_import_export_works(formdef)
|
||||
assert fd2.fields[0].type == 'page'
|
||||
assert fd2.fields[0].post_conditions == formdef.fields[0].post_conditions
|
||||
|
||||
# test legacy condition (simple string)
|
||||
formdef_xml = formdef.export_to_xml(include_id=True)
|
||||
post_condition = formdef_xml.findall('fields/field/post_conditions/post_condition/condition')[0]
|
||||
post_condition.clear()
|
||||
post_condition.text = 'blah'
|
||||
fd2 = FormDef.import_from_xml_tree(formdef_xml, include_id=True)
|
||||
assert fd2.fields[0].post_conditions[0]['condition'] == {'type': 'python', 'value': 'blah'}
|
||||
assert fd2.fields[0].post_conditions[0]['error_message'] == 'bar'
|
||||
|
||||
# test incomplete post condition (not allowed anymore but old formdefs may
|
||||
# have this)
|
||||
formdef.fields = [
|
||||
fields.PageField(id='1', type='page',
|
||||
post_conditions=[{'condition': 'blah', 'error_message': None}]),
|
||||
post_conditions=[{'condition': {'type': 'python', 'value': 'blah'}, 'error_message': None}]),
|
||||
]
|
||||
formdef_xml = formdef.export_to_xml(include_id=True)
|
||||
fd2 = FormDef.import_from_xml_tree(formdef_xml, include_id=True)
|
||||
assert fd2.fields[0].post_conditions[0]['condition'] == 'blah'
|
||||
assert fd2.fields[0].post_conditions[0]['condition'] == {'type': 'python', 'value': 'blah'}
|
||||
assert fd2.fields[0].post_conditions[0]['error_message'] == ''
|
||||
|
||||
def test_workflow_roles():
|
||||
|
|
|
@ -297,7 +297,7 @@ def test_jump_action(pub):
|
|||
jump = JumpWorkflowStatusItem()
|
||||
jump.id = '_jump'
|
||||
jump.by = ['_submitter', '_receiver']
|
||||
jump.condition = '"foo"'
|
||||
jump.condition = {'type': 'python', 'value': '"foo"'}
|
||||
jump.trigger = 'bar'
|
||||
jump.timeout = 1200
|
||||
jump.status = 'st2'
|
||||
|
@ -305,10 +305,19 @@ def test_jump_action(pub):
|
|||
jump.parent = st1
|
||||
|
||||
wf2 = assert_import_export_works(wf)
|
||||
assert wf2.possible_status[0].items[0].condition == '"foo"'
|
||||
assert wf2.possible_status[0].items[0].condition == {'type': 'python', 'value': '"foo"'}
|
||||
assert wf2.possible_status[0].items[0].trigger == 'bar'
|
||||
assert wf2.possible_status[0].items[0].timeout == 1200
|
||||
|
||||
# legacy condition value
|
||||
workflow_xml = wf.export_to_xml(wf)
|
||||
condition = workflow_xml.findall('possible_status/*/items/item/condition')[0]
|
||||
condition.clear()
|
||||
condition.text = '"foo"'
|
||||
|
||||
wf2 = Workflow.import_from_xml_tree(workflow_xml)
|
||||
assert wf2.possible_status[0].items[0].condition == {'type': 'python', 'value': '"foo"'}
|
||||
|
||||
|
||||
def test_commentable_action(pub):
|
||||
wf = Workflow(name='status')
|
||||
|
|
|
@ -204,13 +204,13 @@ def test_jump_datetime_condition(pub):
|
|||
formdata = formdef.data_class()()
|
||||
item = JumpWorkflowStatusItem()
|
||||
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
|
||||
item.condition = 'datetime.datetime.now() > datetime.datetime(%s, %s, %s)' % \
|
||||
yesterday.timetuple()[:3]
|
||||
item.condition = {'type': 'python', 'value': 'datetime.datetime.now() > datetime.datetime(%s, %s, %s)' % \
|
||||
yesterday.timetuple()[:3]}
|
||||
assert item.must_jump(formdata) is True
|
||||
|
||||
tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
|
||||
item.condition = 'datetime.datetime.now() > datetime.datetime(%s, %s, %s)' % \
|
||||
tomorrow.timetuple()[:3]
|
||||
item.condition = {'type': 'python', 'value': 'datetime.datetime.now() > datetime.datetime(%s, %s, %s)' % \
|
||||
tomorrow.timetuple()[:3]}
|
||||
assert item.must_jump(formdata) is False
|
||||
|
||||
def test_jump_date_conditions(pub):
|
||||
|
@ -229,23 +229,33 @@ def test_jump_date_conditions(pub):
|
|||
pub.substitutions.feed(formdata)
|
||||
|
||||
item = JumpWorkflowStatusItem()
|
||||
item.condition = 'utils.make_date(form_var_date) == utils.make_date("2015-01-04")'
|
||||
item.condition = {
|
||||
'type': 'python',
|
||||
'value': 'utils.make_date(form_var_date) == utils.make_date("2015-01-04")'}
|
||||
assert item.must_jump(formdata) is True
|
||||
|
||||
item = JumpWorkflowStatusItem()
|
||||
item.condition = 'utils.time_delta(form_var_date, "2015-01-04").days == 0'
|
||||
item.condition = {
|
||||
'type': 'python',
|
||||
'value': 'utils.time_delta(form_var_date, "2015-01-04").days == 0'}
|
||||
assert item.must_jump(formdata) is True
|
||||
|
||||
item = JumpWorkflowStatusItem()
|
||||
item.condition = 'utils.time_delta(utils.today(), "2015-01-04").days > 0'
|
||||
item.condition = {
|
||||
'type': 'python',
|
||||
'value': 'utils.time_delta(utils.today(), "2015-01-04").days > 0'}
|
||||
assert item.must_jump(formdata) is True
|
||||
|
||||
item = JumpWorkflowStatusItem()
|
||||
item.condition = 'utils.time_delta(datetime.datetime.now(), "2015-01-04").days > 0'
|
||||
item.condition = {
|
||||
'type': 'python',
|
||||
'value': 'utils.time_delta(datetime.datetime.now(), "2015-01-04").days > 0'}
|
||||
assert item.must_jump(formdata) is True
|
||||
|
||||
item = JumpWorkflowStatusItem()
|
||||
item.condition = 'utils.time_delta(utils.time.localtime(), "2015-01-04").days > 0'
|
||||
item.condition = {
|
||||
'type': 'python',
|
||||
'value': 'utils.time_delta(utils.time.localtime(), "2015-01-04").days > 0'}
|
||||
assert item.must_jump(formdata) is True
|
||||
|
||||
|
||||
|
@ -258,14 +268,14 @@ def test_jump_count_condition(pub):
|
|||
formdef.data_class().wipe()
|
||||
formdata = formdef.data_class()()
|
||||
item = JumpWorkflowStatusItem()
|
||||
item.condition = 'form_objects.count < 2'
|
||||
item.condition = {'type': 'python', 'value': 'form_objects.count < 2'}
|
||||
assert item.must_jump(formdata) is True
|
||||
|
||||
for i in range(10):
|
||||
formdata = formdef.data_class()()
|
||||
formdata.store()
|
||||
|
||||
item.condition = 'form_objects.count < 2'
|
||||
item.condition = {'type': 'python', 'value': 'form_objects.count < 2'}
|
||||
assert item.must_jump(formdata) is False
|
||||
|
||||
def test_check_auth(pub):
|
||||
|
@ -3171,3 +3181,22 @@ def test_redirect_to_url(pub):
|
|||
item.url = '{% if nada %}https://www.example.net/{% endif %}'
|
||||
pub.substitutions.feed(formdata)
|
||||
assert item.perform(formdata) == None
|
||||
|
||||
def test_workflow_jump_condition_migration(pub):
|
||||
workflow = Workflow(name='jump condition migration')
|
||||
st1 = workflow.add_status('Status1', 'st1')
|
||||
|
||||
jump = JumpWorkflowStatusItem()
|
||||
jump.id = '_jump'
|
||||
st1.items.append(jump)
|
||||
jump.parent = st1
|
||||
workflow.store()
|
||||
|
||||
reloaded_workflow = Workflow.get(workflow.id)
|
||||
assert reloaded_workflow.possible_status[0].items[0].condition is None
|
||||
|
||||
jump.condition = 'foobar'
|
||||
workflow.store()
|
||||
reloaded_workflow = Workflow.get(workflow.id)
|
||||
assert reloaded_workflow.possible_status[0].items[0].condition == {
|
||||
'type': 'python', 'value': 'foobar'}
|
||||
|
|
|
@ -1426,7 +1426,7 @@ class PostConditionsRowWidget(CompositeWidget):
|
|||
CompositeWidget.__init__(self, name, value, **kwargs)
|
||||
if not value:
|
||||
value = {}
|
||||
self.add(StringWidget, name='condition', title=_('Condition'),
|
||||
self.add(ConditionWidget, name='condition', title=_('Condition'),
|
||||
value=value.get('condition'), size=50)
|
||||
self.add(StringWidget, name='error_message', title=_('Error message if condition is not met'),
|
||||
value=value.get('error_message'), size=50)
|
||||
|
@ -1464,13 +1464,34 @@ class PageField(Field):
|
|||
condition = None
|
||||
post_conditions = None
|
||||
|
||||
def condition_init_with_xml(self, node, charset, include_id=False):
|
||||
if node is None:
|
||||
return
|
||||
if node.findall('type'):
|
||||
self.condition = {
|
||||
'type': node.find('type').text.encode(charset),
|
||||
'value': node.find('value').text.encode(charset),
|
||||
}
|
||||
else:
|
||||
self.condition = {'type': 'python', 'value': node.text.encode(charset)}
|
||||
|
||||
def post_conditions_init_with_xml(self, node, charset, include_id=False):
|
||||
if node is None:
|
||||
return
|
||||
self.post_conditions = []
|
||||
for post_condition_node in node.findall('post_condition'):
|
||||
if post_condition_node.findall('condition/type'):
|
||||
condition = {
|
||||
'type': post_condition_node.find('condition/type').text.encode(charset),
|
||||
'value': post_condition_node.find('condition/value').text.encode(charset),
|
||||
}
|
||||
else:
|
||||
condition = {
|
||||
'type': 'python',
|
||||
'value': post_condition_node.find('condition').text.encode(charset),
|
||||
}
|
||||
self.post_conditions.append({
|
||||
'condition': post_condition_node.find('condition').text.encode(charset),
|
||||
'condition': condition,
|
||||
'error_message': post_condition_node.find('error_message').text.encode(charset),
|
||||
})
|
||||
|
||||
|
@ -1480,17 +1501,20 @@ class PageField(Field):
|
|||
|
||||
conditions_node = ET.SubElement(node, 'post_conditions')
|
||||
for post_condition in self.post_conditions:
|
||||
condition_node = ET.SubElement(conditions_node, 'post_condition')
|
||||
ET.SubElement(condition_node, 'condition').text = unicode(
|
||||
post_condition['condition'] or '', charset, 'replace')
|
||||
ET.SubElement(condition_node, 'error_message').text = unicode(
|
||||
post_condition_node = ET.SubElement(conditions_node, 'post_condition')
|
||||
condition_node = ET.SubElement(post_condition_node, 'condition')
|
||||
ET.SubElement(condition_node, 'type').text = unicode(
|
||||
post_condition['condition'].get('type') or '', charset, 'replace')
|
||||
ET.SubElement(condition_node, 'value').text = unicode(
|
||||
post_condition['condition'].get('value') or '', charset, 'replace')
|
||||
ET.SubElement(post_condition_node, 'error_message').text = unicode(
|
||||
post_condition['error_message'] or '', charset, 'replace')
|
||||
|
||||
def fill_admin_form(self, form):
|
||||
form.add(StringWidget, 'label', title = _('Label'), value = self.label,
|
||||
required = True, size = 50)
|
||||
form.add(StringWidget, 'condition', title = _('Condition'), value = self.condition,
|
||||
required = False, size = 50)
|
||||
form.add(ConditionWidget, 'condition', title=_('Condition'), value=self.condition,
|
||||
required=False, size=50)
|
||||
form.add(PostConditionsTableWidget, 'post_conditions',
|
||||
title=_('Post Conditions'),
|
||||
value=self.post_conditions,
|
||||
|
@ -1499,12 +1523,26 @@ class PageField(Field):
|
|||
def get_admin_attributes(self):
|
||||
return Field.get_admin_attributes(self) + ['condition', 'post_conditions']
|
||||
|
||||
def migrate(self):
|
||||
changed = super(PageField, self).migrate()
|
||||
if isinstance(self.condition, basestring):
|
||||
self.condition = {'type': 'python', 'value': self.condition}
|
||||
changed = True
|
||||
for post_condition in self.post_conditions or []:
|
||||
condition = post_condition.get('condition')
|
||||
if isinstance(condition, basestring):
|
||||
post_condition['condition'] = {'type': 'python', 'value': condition}
|
||||
changed = True
|
||||
return changed
|
||||
|
||||
def add_to_view_form(self, *args):
|
||||
pass
|
||||
|
||||
def evaluate_condition(self, dict_vars, formdef, condition):
|
||||
if not condition:
|
||||
return True
|
||||
if not condition.get('value'):
|
||||
return True
|
||||
|
||||
# create variables with values currently being evaluated, not yet
|
||||
# available in the formdata.
|
||||
|
@ -1528,10 +1566,10 @@ class PageField(Field):
|
|||
data.update(live_data)
|
||||
|
||||
try:
|
||||
if eval(condition, get_publisher().get_global_eval_dict(), data):
|
||||
if eval(condition['value'], get_publisher().get_global_eval_dict(), data):
|
||||
return True
|
||||
except Exception, e:
|
||||
get_logger().warn('failed to evaluate condition "%s" (%r)' % (self.condition, e))
|
||||
get_logger().warn('failed to evaluate condition "%s" (%r)' % (condition['value'], e))
|
||||
raise RuntimeError()
|
||||
|
||||
return False
|
||||
|
|
|
@ -2275,3 +2275,35 @@ class ComputedExpressionWidget(StringWidget):
|
|||
self.validate(self.value)
|
||||
except ValidationError as e:
|
||||
self.set_error(str(e))
|
||||
|
||||
|
||||
class ConditionWidget(CompositeWidget):
|
||||
def __init__(self, name, value=None, **kwargs):
|
||||
CompositeWidget.__init__(self, name, value, **kwargs)
|
||||
|
||||
if not value:
|
||||
value = {}
|
||||
|
||||
self.add(HiddenWidget, 'type', value=value.get('type'))
|
||||
self.add(StringWidget, 'value_python', value=value.get('value'), **kwargs)
|
||||
|
||||
def _parse(self, request):
|
||||
self.value = {}
|
||||
self.value['type'] = self.get('type') or 'python'
|
||||
if self.value['type']:
|
||||
self.value['value'] = self.get('value_%s' % self.value['type'])
|
||||
|
||||
if self.value['type'] == 'python' and self.value.get('value'):
|
||||
try:
|
||||
compile(self.value.get('value'), '<string>', 'eval')
|
||||
except (SyntaxError, TypeError), e:
|
||||
self.set_error(_('invalid expression: %s') % e)
|
||||
|
||||
if not self.value['value']:
|
||||
self.value = None
|
||||
|
||||
def render_content(self):
|
||||
r = TemplateIO(html=True)
|
||||
for widget in self.get_widgets():
|
||||
r += widget.render_content()
|
||||
return r.getvalue()
|
||||
|
|
|
@ -117,6 +117,25 @@ class JumpWorkflowStatusItem(WorkflowStatusJumpItem):
|
|||
else:
|
||||
self.timeout = int(timeout)
|
||||
|
||||
def condition_init_with_xml(self, node, charset, include_id=False):
|
||||
if node is None:
|
||||
self.condition = None
|
||||
elif node.findall('type'):
|
||||
self.condition = {
|
||||
'type': node.find('type').text.encode(charset),
|
||||
'value': node.find('value').text.encode(charset),
|
||||
}
|
||||
else:
|
||||
# backward compatibility
|
||||
self.condition = {'type': 'python', 'value': node.text.encode(charset)}
|
||||
|
||||
def migrate(self):
|
||||
changed = super(JumpWorkflowStatusItem, self).migrate()
|
||||
if isinstance(self.condition, basestring):
|
||||
self.condition = {'type': 'python', 'value': self.condition}
|
||||
changed = True
|
||||
return changed
|
||||
|
||||
@property
|
||||
def waitpoint(self):
|
||||
if self.timeout or self.trigger:
|
||||
|
@ -150,7 +169,7 @@ class JumpWorkflowStatusItem(WorkflowStatusJumpItem):
|
|||
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
|
||||
WorkflowStatusJumpItem.add_parameters_widgets(self, form, parameters, prefix, formdef)
|
||||
if 'condition' in parameters:
|
||||
form.add(StringWidget, '%scondition' % prefix, title=_('Condition (formula)'),
|
||||
form.add(ConditionWidget, '%scondition' % prefix, title=_('Condition (formula)'),
|
||||
value=self.condition, size=40)
|
||||
if 'trigger' in parameters:
|
||||
form.add(StringWidget, '%strigger' % prefix, title=_('Trigger (string)'),
|
||||
|
@ -201,7 +220,7 @@ class JumpWorkflowStatusItem(WorkflowStatusJumpItem):
|
|||
if self.condition:
|
||||
variables = get_publisher().substitutions.get_context_variables()
|
||||
try:
|
||||
must_jump = eval(self.condition, get_publisher().get_global_eval_dict(), variables)
|
||||
must_jump = eval(self.condition['value'], get_publisher().get_global_eval_dict(), variables)
|
||||
except:
|
||||
# get the variables in the locals() namespace so they are
|
||||
# displayed within the trace.
|
||||
|
|
Loading…
Reference in New Issue