misc: always disable python expression for new values (#72091) #74

Open
lguerin wants to merge 1 commits from wip/72091-remove-python-option into main
9 changed files with 178 additions and 260 deletions

View File

@ -183,8 +183,8 @@ def test_data_sources_new(pub):
resp.forms[0]['name'] = 'a new data source'
resp.forms[0]['description'] = 'description of the data source'
resp.forms[0]['data_source$type'] = 'python'
resp.forms[0]['data_source$value'] = repr([{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}])
resp.forms[0]['data_source$type'] = 'jsonvalue'
resp.forms[0]['data_source$value'] = json.dumps([{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}])
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/settings/data-sources/'
resp = resp.follow()
@ -202,9 +202,9 @@ def test_data_sources_new(pub):
resp = resp.click('New Data Source')
resp.forms[0]['name'] = 'an other data source'
resp.forms[0]['description'] = 'description of the data source'
resp.forms[0]['data_source$type'] = 'python'
resp.forms[0]['data_source$type'] = 'jsonvalue'
resp = resp.forms[0].submit('data_source$apply')
resp.forms[0]['data_source$value'] = repr([{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}])
resp.forms[0]['data_source$value'] = json.dumps([{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}])
resp = resp.forms[0].submit('submit')
assert NamedDataSource.count() == 2
@ -226,43 +226,6 @@ def test_data_sources_users_new(pub):
assert 'category_id' not in resp.form.fields
def test_data_sources_type_options(pub):
create_superuser(pub)
data_source = NamedDataSource(name='foobar')
data_source.store()
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'disable-python-expressions', 'false')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
app = login(get_app(pub))
resp = app.get('/backoffice/settings/data-sources/%s/edit' % data_source.id)
assert resp.form['data_source$type'].options == [
('None', True, 'None'),
('json', False, 'JSON URL'),
('jsonp', False, 'JSONP URL'),
('geojson', False, 'GeoJSON URL'),
('python', False, 'Python Expression (deprecated)'),
('jsonvalue', False, 'JSON Expression'),
]
pub.site_options.set('options', 'disable-python-expressions', 'true')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
resp = app.get('/backoffice/settings/data-sources/%s/edit' % data_source.id)
assert resp.form['data_source$type'].options == [
('None', True, 'None'),
('json', False, 'JSON URL'),
('jsonp', False, 'JSONP URL'),
('geojson', False, 'GeoJSON URL'),
('jsonvalue', False, 'JSON Expression'),
]
def test_data_sources_type_options_jsonp(pub):
create_superuser(pub)
@ -299,20 +262,7 @@ def test_data_sources_type_options_python(pub):
data_source = NamedDataSource(name='foobar')
data_source.store()
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'disable-python-expressions', 'false')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
app = login(get_app(pub))
resp = app.get('/backoffice/settings/data-sources/%s/edit' % data_source.id)
assert 'python' in [x[0] for x in resp.form['data_source$type'].options]
pub.site_options.set('options', 'disable-python-expressions', 'true')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
resp = app.get('/backoffice/settings/data-sources/%s/edit' % data_source.id)
assert 'python' not in [x[0] for x in resp.form['data_source$type'].options]
@ -330,24 +280,11 @@ def test_data_sources_agenda_manual_qs_data_type_options(pub):
data_source.external = 'agenda_manual'
data_source.store()
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'disable-python-expressions', 'false')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
# check expression type is always forced (no python allowed).
app = login(get_app(pub))
resp = app.get('/backoffice/settings/data-sources/%s/edit' % data_source.id)
assert 'qs_data$element0value$type' not in resp.text
pub.site_options.set('options', 'disable-python-expressions', 'true')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
resp = app.get('/backoffice/settings/data-sources/%s/edit' % data_source.id)
assert 'qs_data$element0value$type' not in resp.text
def test_data_sources_category(pub):
create_superuser(pub)
@ -384,8 +321,8 @@ def test_data_sources_category(pub):
resp = app.get('/backoffice/settings/data-sources/%s/' % data_source.id)
resp = resp.click(href=re.compile('^edit$'))
resp.form['category_id'] = str(category.id)
resp.form['data_source$type'] = 'python'
resp.form['data_source$value'] = repr([{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}])
resp.form['data_source$type'] = 'jsonvalue'
resp.form['data_source$value'] = json.dumps([{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}])
resp = resp.form.submit('submit').follow()
data_source.refresh_from_storage()
assert str(data_source.category_id) == str(category.id)

View File

@ -1982,6 +1982,10 @@ def test_form_prefill_field(pub):
resp = resp.form.submit('submit').follow()
assert FormDef.get(formdef.id).fields[0].prefill == {'type': 'string', 'value': 'test', 'locked': False}
formdef.fields = [
fields.StringField(id='1', label='1st field', prefill={'type': 'formula', 'value': 'foo'})
]
formdef.store()
resp = app.get('/backoffice/forms/1/fields/1/')
resp.form['prefill$type'] = 'Python Expression (deprecated)'
resp.form['prefill$value_formula'] = 'True'
@ -1999,6 +2003,10 @@ def test_form_prefill_field(pub):
}
# check error handling
formdef.fields = [
fields.StringField(id='1', label='1st field', prefill={'type': 'formula', 'value': 'foo'})
]
formdef.store()
resp = app.get('/backoffice/forms/1/fields/1/')
resp.form['prefill$type'] = 'Python Expression (deprecated)'
resp.form['prefill$value_formula'] = ':'
@ -2018,29 +2026,35 @@ def test_form_prefill_type_options(pub):
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [fields.StringField(id='1', label='1st field')]
formdef.fields = [
fields.StringField(id='1', label='1st field', prefill={'type': 'formula', 'value': 'foo'})
]
formdef.store()
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'disable-python-expressions', 'false')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/fields/1/')
assert resp.forms[0]['prefill$type'].options == [
('None', True, 'None'),
('None', False, 'None'),
('String / Template', False, 'String / Template'),
('Python Expression (deprecated)', False, 'Python Expression (deprecated)'),
('Python Expression (deprecated)', True, 'Python Expression (deprecated)'),
('User Field', False, 'User Field'),
('Geolocation', False, 'Geolocation'),
]
pub.site_options.set('options', 'disable-python-expressions', 'true')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
formdef.fields = [
fields.StringField(id='1', label='1st field', prefill={'type': 'string', 'value': 'foo'})
]
formdef.store()
resp = app.get('/backoffice/forms/1/fields/1/')
assert resp.forms[0]['prefill$type'].options == [
('None', False, 'None'),
('String / Template', True, 'String / Template'),
('User Field', False, 'User Field'),
('Geolocation', False, 'Geolocation'),
]
formdef.fields = [fields.StringField(id='1', label='1st field')]
formdef.store()
resp = app.get('/backoffice/forms/1/fields/1/')
assert resp.forms[0]['prefill$type'].options == [
('None', True, 'None'),
@ -2195,16 +2209,18 @@ def test_form_edit_item_field_data_source(pub):
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [fields.ItemField(id='1', label='1st field')]
formdef.fields = [
fields.ItemField(id='1', label='1st field', data_source={'type': 'formula', 'value': 'foo'})
]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/fields/1/')
assert resp.form['data_source$type'].options == [
('None', True, 'None'),
('None', False, 'None'),
('json', False, 'JSON URL'),
('jsonp', False, 'JSONP URL'),
('python', False, 'Python Expression (deprecated)'),
('python', True, 'Python Expression (deprecated)'),
('jsonvalue', False, 'JSON Expression'),
]
resp = resp.form.submit('submit').follow()
@ -2215,13 +2231,15 @@ def test_form_edit_item_field_data_source(pub):
data_source.notify_on_errors = True
data_source.store()
formdef.fields = [fields.ItemField(id='1', label='1st field')]
formdef.store()
resp = app.get('/backoffice/forms/1/fields/1/')
assert resp.form['data_source$type'].options == [
('None', True, 'None'),
('foobar', False, 'Foobar'),
('json', False, 'JSON URL'),
('jsonp', False, 'JSONP URL'),
('python', False, 'Python Expression (deprecated)'),
('jsonvalue', False, 'JSON Expression'),
]
resp.form['data_mode'].value = 'data-source'
@ -2241,7 +2259,6 @@ def test_form_edit_item_field_data_source(pub):
('foobar', True, 'Foobar'),
('json', False, 'JSON URL'),
('jsonp', False, 'JSONP URL'),
('python', False, 'Python Expression (deprecated)'),
('jsonvalue', False, 'JSON Expression'),
]
@ -2261,7 +2278,6 @@ def test_form_edit_item_field_data_source(pub):
('foobar', True, 'Foobar'),
('json', False, 'JSON URL'),
('jsonp', False, 'JSONP URL'),
('python', False, 'Python Expression (deprecated)'),
('jsonvalue', False, 'JSON Expression'),
]
assert (
@ -2336,14 +2352,13 @@ def test_form_edit_item_field_data_source_with_categories(pub):
)
assert (
PyQuery(resp.pyquery('select[name="data_source$type"] optgroup')[1]).find('option').text()
== 'JSON URL JSONP URL Python Expression (deprecated) JSON Expression'
== 'JSON URL JSONP URL JSON Expression'
)
assert [o[0] for o in resp.form['data_source$type'].options] == [
'None',
'test',
'json',
'jsonp',
'python',
'jsonvalue',
]
@ -2386,7 +2401,7 @@ def test_form_edit_item_field_data_source_with_categories(pub):
)
assert (
PyQuery(resp.pyquery('select[name="data_source$type"] optgroup')[3]).find('option').text()
== 'JSON URL JSONP URL Python Expression (deprecated) JSON Expression'
== 'JSON URL JSONP URL JSON Expression'
)
assert [o[0] for o in resp.form['data_source$type'].options] == [
'None',
@ -2396,7 +2411,6 @@ def test_form_edit_item_field_data_source_with_categories(pub):
'test',
'json',
'jsonp',
'python',
'jsonvalue',
]
@ -2446,7 +2460,7 @@ def test_form_edit_item_field_data_source_with_carddef_categories(pub):
)
assert (
PyQuery(resp.pyquery('select[name="data_source$type"] optgroup')[1]).find('option').text()
== 'JSON URL JSONP URL Python Expression (deprecated) JSON Expression'
== 'JSON URL JSONP URL JSON Expression'
)
assert [o[0] for o in resp.form['data_source$type'].options] == [
'None',
@ -2455,7 +2469,6 @@ def test_form_edit_item_field_data_source_with_carddef_categories(pub):
'carddef:baz:card-view',
'json',
'jsonp',
'python',
'jsonvalue',
]
@ -2483,7 +2496,7 @@ def test_form_edit_item_field_data_source_with_carddef_categories(pub):
)
assert (
PyQuery(resp.pyquery('select[name="data_source$type"] optgroup')[2]).find('option').text()
== 'JSON URL JSONP URL Python Expression (deprecated) JSON Expression'
== 'JSON URL JSONP URL JSON Expression'
)
assert [o[0] for o in resp.form['data_source$type'].options] == [
'None',
@ -2492,7 +2505,6 @@ def test_form_edit_item_field_data_source_with_carddef_categories(pub):
'carddef:bar',
'json',
'jsonp',
'python',
'jsonvalue',
]
@ -2586,12 +2598,15 @@ def test_form_edit_items_field(pub):
assert FormDef.get(1).fields[0].max_choices == 5
# check prefilling is possible with a template or a Python expression
formdef.refresh_from_storage()
formdef.fields[0].prefill = {'type': 'formula', 'value': 'foo'}
formdef.store()
resp = resp.follow()
resp = resp.click('Edit', href='1/')
assert resp.forms[0]['prefill$type'].options == [
('None', True, 'None'),
('None', False, 'None'),
('String / Template', False, 'String / Template'),
('Python Expression (deprecated)', False, 'Python Expression (deprecated)'),
('Python Expression (deprecated)', True, 'Python Expression (deprecated)'),
]
# change configuration for datasource
@ -2674,14 +2689,12 @@ def test_form_edit_page_field(pub):
assert formdef.fields[0].label == 'foobar'
resp = resp.click('Edit', href='%s/' % formdef.fields[0].id)
resp.form['post_conditions$element0$condition$type'] = 'python'
resp.form['post_conditions$element0$condition$value_python'] = 'foo'
resp.form['post_conditions$element0$condition$value_django'] = 'foo'
resp.form['post_conditions$element0$error_message'] = 'bar'
resp = resp.form.submit('post_conditions$add_element')
# check advanced tab is open after adding a line
assert resp.pyquery('[aria-selected="true"]').text() == 'Advanced'
resp.form['post_conditions$element1$condition$type'] = 'python'
resp.form['post_conditions$element1$condition$value_python'] = 'foo2'
resp.form['post_conditions$element1$condition$value_django'] = 'foo2'
resp = resp.form.submit('submit')
assert 'Both condition and error message are required.' in resp.text
resp.form['post_conditions$element1$error_message'] = 'bar2'
@ -2689,23 +2702,21 @@ def test_form_edit_page_field(pub):
formdef.refresh_from_storage()
assert formdef.fields[0].post_conditions == [
{'condition': {'type': 'python', 'value': 'foo'}, 'error_message': 'bar'},
{'condition': {'type': 'python', 'value': 'foo2'}, 'error_message': 'bar2'},
{'condition': {'type': 'django', 'value': 'foo'}, 'error_message': 'bar'},
{'condition': {'type': 'django', 'value': 'foo2'}, 'error_message': 'bar2'},
]
resp = resp.click('Edit', href='%s/' % formdef.fields[0].id)
resp.form['post_conditions$element1$condition$type'] = 'django'
resp.form['post_conditions$element1$condition$value_django'] = 'foo3'
resp = resp.form.submit('submit').follow()
formdef.refresh_from_storage()
assert formdef.fields[0].post_conditions == [
{'condition': {'type': 'python', 'value': 'foo'}, 'error_message': 'bar'},
{'condition': {'type': 'django', 'value': 'foo'}, 'error_message': 'bar'},
{'condition': {'type': 'django', 'value': 'foo3'}, 'error_message': 'bar2'},
]
# check error in expression
resp = resp.click('Edit', href='%s/' % formdef.fields[0].id)
resp.form['post_conditions$element1$condition$type'] = 'django'
resp.form['post_conditions$element1$condition$value_django'] = 'foo3 >'
resp = resp.form.submit('submit')
assert 'syntax error: Unexpected end of expression in if tag.' in resp.text
@ -3027,27 +3038,28 @@ def test_form_page_field_condition_types(pub):
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.PageField(id='0', label='1st page'),
fields.PageField(id='0', label='1st page', condition={'type': 'python', 'value': '"foo"'}),
]
formdef.store()
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'disable-python-expressions', 'false')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/fields/0/')
assert resp.form['condition$type'].options == [
('django', False, 'Django Expression'),
('python', False, 'Python Expression (deprecated)'),
('python', True, 'Python Expression (deprecated)'),
]
pub.site_options.set('options', 'disable-python-expressions', 'true')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
formdef.fields = [
fields.PageField(id='0', label='1st page', condition={'type': 'django', 'value': 'True'}),
]
formdef.store()
resp = app.get('/backoffice/forms/1/fields/0/')
assert 'condition$type' not in resp.text
formdef.fields = [
fields.PageField(id='0', label='1st page'),
]
formdef.store()
resp = app.get('/backoffice/forms/1/fields/0/')
assert 'condition$type' not in resp.text

View File

@ -1242,11 +1242,10 @@ def test_workflows_edit_email_action(pub):
assert sendmail.condition is None
resp = app.get(item_url)
resp.form['condition$type'] = 'python'
resp.form['condition$value_python'] = 'True'
resp.form['condition$value_django'] = 'True'
resp = resp.form.submit('submit')
sendmail = Workflow.get(workflow.id).get_status(st1.id).items[0]
assert sendmail.condition == {'type': 'python', 'value': 'True'}
assert sendmail.condition == {'type': 'django', 'value': 'True'}
# check "custom_from" is not advertised
resp = app.get(item_url)
@ -2561,14 +2560,11 @@ def test_workflows_global_actions_timeout_trigger_anchor_options(pub):
action = workflow.add_global_action('Global')
action.add_action('modify_criticality')
trigger = action.append_trigger('timeout')
trigger.anchor_expression = 'False'
trigger.anchor = 'python'
trigger.timeout = 42
workflow.store()
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'disable-python-expressions', 'false')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/%s/global-actions/1/triggers/%s/' % (workflow.id, trigger.id))
assert resp.form['anchor'].options == [
@ -2578,13 +2574,16 @@ def test_workflows_global_actions_timeout_trigger_anchor_options(pub):
('Arrival in final status', False, 'Arrival in final status'),
('Anonymisation', False, 'Anonymisation'),
('String / Template', False, 'String / Template'),
('Python Expression (deprecated)', False, 'Python Expression (deprecated)'),
('Python Expression (deprecated)', True, 'Python Expression (deprecated)'),
]
# check inspect page with python expression, and python disabled
workflow.store()
app.get('/backoffice/workflows/%s/inspect' % workflow.id) # no error
pub.site_options.set('options', 'disable-python-expressions', 'true')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
trigger.anchor_expression = ''
trigger.anchor = None
trigger.timeout = None
workflow.store()
resp = app.get('/backoffice/workflows/%s/global-actions/1/triggers/%s/' % (workflow.id, trigger.id))
assert resp.form['anchor'].options == [
('Creation', False, 'Creation'),
@ -2595,13 +2594,6 @@ def test_workflows_global_actions_timeout_trigger_anchor_options(pub):
('String / Template', False, 'String / Template'),
]
# check inspect page with python expression, and python disabled
trigger.anchor_expression = 'False'
trigger.anchor = 'python'
trigger.timeout = 42
workflow.store()
app.get('/backoffice/workflows/%s/inspect' % workflow.id) # no error
def test_workflows_global_actions_external_workflow_action(pub):
FormDef.wipe()
@ -2656,7 +2648,6 @@ def test_workflows_global_actions_external_workflow_action(pub):
resp = app.get('/backoffice/workflows/%s/status/%s/items/1/' % (workflow.id, st.id))
resp.forms[0]['target_mode'] = 'manual'
resp.forms[0]['target_id$type'] = 'template'
resp.forms[0]['target_id$value_template'] = '{{ form_var_plop_id }}'
resp = resp.forms[0].submit('submit')
assert Workflow.get(workflow.id).possible_status[0].items[0].target_mode == 'manual'
@ -2707,7 +2698,6 @@ def test_workflows_external_workflow_action_config(pub):
assert "required field" in resp
# multiple errors: do as usual
resp.forms[0]['slug'] = 'formdef:external'
resp.forms[0]['condition$type'] = 'django'
resp.forms[0]['condition$value_django'] = '{{ 42 }}'
resp = resp.forms[0].submit('submit')
assert 'There were errors processing your form. See below for details.' in resp
@ -2837,7 +2827,6 @@ def test_workflows_create_formdata_action_config(pub):
assert 'Please define new mappings' in resp
# multiple errors: do as usual
resp.forms[0]['formdef_slug'] = 'target-form'
resp.forms[0]['condition$type'] = 'django'
resp.forms[0]['condition$value_django'] = '{{ 42 }}'
resp = resp.forms[0].submit('submit')
assert 'There were errors processing your form. See below for details.' in resp
@ -2949,7 +2938,6 @@ def test_workflows_create_carddata_action_config(pub):
assert 'Please define new mappings' in resp
# multiple errors: do as usual
resp.forms[0]['formdef_slug'] = 'my-card'
resp.forms[0]['condition$type'] = 'django'
resp.forms[0]['condition$value_django'] = '{{ 42 }}'
resp = resp.forms[0].submit('submit')
assert 'There were errors processing your form. See below for details.' in resp
@ -2970,25 +2958,20 @@ def test_workflows_create_formdata_expression_types(pub):
st1 = wf.add_status('New')
create_formdata = st1.add_action('create_formdata')
create_formdata.formdef_slug = target_formdef.url_name
create_formdata.mappings = [
Mapping(field_id='0', expression='=form_var_toto_string'),
]
wf.store()
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'disable-python-expressions', 'false')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/%s/status/%s/items/1/' % (wf.id, st1.id))
assert resp.form['mappings$element0$expression$type'].options == [
('template', False, 'Template'),
('python', False, 'Python Expression (deprecated)'),
('python', True, 'Python Expression (deprecated)'),
]
pub.site_options.set('options', 'disable-python-expressions', 'true')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
create_formdata.mappings = []
wf.store()
resp = app.get('/backoffice/workflows/%s/status/%s/items/1/' % (wf.id, st1.id))
assert 'mappings$element0$expression$type' not in resp.text
@ -3018,7 +3001,6 @@ def test_workflows_edit_carddata_action_config(pub):
assert 'Please define new mappings' in resp
# multiple errors: do as usual
resp.forms[0]['formdef_slug'] = 'my-card'
resp.forms[0]['condition$type'] = 'django'
resp.forms[0]['condition$value_django'] = '{{ 42 }}'
resp = resp.forms[0].submit('submit')
assert 'There were errors processing your form. See below for details.' in resp
@ -3064,7 +3046,6 @@ def test_workflows_edit_carddata_action(pub):
resp = app.get('/backoffice/workflows/%s/status/%s/items/1/' % (wf.id, st.id))
resp.forms[0]['target_mode'] = 'manual'
resp.forms[0]['target_id$type'] = 'template'
resp.forms[0]['target_id$value_template'] = '{{ form_var_plop_id }}'
resp = resp.forms[0].submit('submit')
assert Workflow.get(wf.id).possible_status[0].items[0].target_mode == 'manual'
@ -3087,15 +3068,11 @@ def test_workflows_assign_carddata_action_options(pub):
app = login(get_app(pub))
for value in ['false', 'true']:
# no python expressions
pub.site_options.set('options', 'disable-python-expressions', value)
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
resp = app.get('/backoffice/workflows/%s/status/%s/items/1/' % (wf.id, st.id))
assert 'target_id$type' not in resp.text
assert 'user_association_template$type' not in resp.text
assert 'condition$type' not in resp.text
# no python expressions
resp = app.get('/backoffice/workflows/%s/status/%s/items/1/' % (wf.id, st.id))
assert 'target_id$type' not in resp.text
assert 'user_association_template$type' not in resp.text
assert 'condition$type' not in resp.text
def test_workflows_assign_carddata_action(pub):
@ -3411,7 +3388,6 @@ def test_workflows_form_action_config(pub):
resp = app.get('/backoffice/workflows/%s/status/%s/items/1/' % (wf.id, st.id))
resp.form['by$element0'] = '_submitter'
resp.form['varname'] = 'myform'
resp.form['condition$type'] = 'django'
resp.form['condition$value_django'] = '42'
assert 'Edit Fields' not in resp.text
assert resp.form.fields['submit'][0]._value == 'Submit and go to fields edition'

View File

@ -304,17 +304,14 @@ def test_fc_settings():
resp.forms[0]['user_field_mappings$element0$field_varname'] = 'prenoms'
resp.forms[0]['user_field_mappings$element0$value$value_template'] = '[given_name ""]'
resp.forms[0]['user_field_mappings$element0$value$type'] = 'template'
resp.forms[0]['user_field_mappings$element0$verified'] = 'Always'
resp.forms[0]['user_field_mappings$element1$field_varname'] = 'nom'
resp.forms[0]['user_field_mappings$element1$value$value_template'] = '[family_name ""]'
resp.forms[0]['user_field_mappings$element1$value$type'] = 'template'
resp.forms[0]['user_field_mappings$element1$verified'] = 'Always'
resp.forms[0]['user_field_mappings$element2$field_varname'] = 'email'
resp.forms[0]['user_field_mappings$element2$value$value_template'] = '[email ""]'
resp.forms[0]['user_field_mappings$element2$value$type'] = 'template'
resp.forms[0]['user_field_mappings$element2$verified'] = 'Always'
resp = resp.forms[0].submit('submit').follow()
@ -362,12 +359,10 @@ def test_fc_settings_no_user_profile():
resp.forms[0]['user_field_mappings$element0$field_varname'] = '__name'
resp.forms[0]['user_field_mappings$element0$value$value_template'] = '[given_name ""] [family_name ""]'
resp.forms[0]['user_field_mappings$element0$value$type'] = 'template'
resp.forms[0]['user_field_mappings$element0$verified'] = 'Always'
resp.forms[0]['user_field_mappings$element2$field_varname'] = '__email'
resp.forms[0]['user_field_mappings$element2$value$value_template'] = '[email ""]'
resp.forms[0]['user_field_mappings$element2$value$type'] = 'template'
resp.forms[0]['user_field_mappings$element2$verified'] = 'Always'
resp = resp.forms[0].submit('submit').follow()

View File

@ -717,68 +717,6 @@ def test_composite_widget():
) # extra_css_class is present
def test_computed_expression_widget():
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': 'hello world', 'test$type': ['template']})
assert widget.parse() == 'hello world'
assert not widget.has_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': '', 'test$type': ['template']})
assert widget.parse() is None
assert not widget.has_error()
# python value left empty
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_python': '', 'test$type': ['python']})
assert not widget.has_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$type': ['python']})
assert not widget.has_error()
# but field marqued as required
widget = ComputedExpressionWidget('test', required=True)
mock_form_submission(req, widget, {'test$value_python': '', 'test$type': ['python']})
assert widget.has_error()
# invalid values
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_python': 'hello world', 'test$type': ['python']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error')
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_python': '=3', 'test$type': ['python']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error')
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_python': '{{form_var_foo}}', 'test$type': ['python']})
assert widget.has_error()
assert 'Python expression cannot contain {{' in widget.get_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(
req, widget, {'test$value_template': '{{ form_var_xxx }}', 'test$type': ['template']}
)
assert not widget.has_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': '{% if True %}', 'test$type': ['template']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error in Django template')
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': '[form_var_xxx]', 'test$type': ['template']})
assert not widget.has_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': '[end]', 'test$type': ['template']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error in ezt template')
def test_wcsextrastringwidget():
widget = WcsExtraStringWidget('test', value='foo', required=True)
mock_form_submission(req, widget, {'test': ''})
@ -1378,10 +1316,69 @@ def test_profile_fields_sorting():
assert [f[1] for f in widget.get_widgets()[0].options] == ['Email', 'Name']
def test_computed_expression_widget_no_python():
pub.load_site_options()
pub.site_options.set('options', 'disable-python-expressions', 'true')
def test_computed_expression_widget():
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$value_template': 'hello world', 'test$type': ['template']})
assert widget.parse() == 'hello world'
assert not widget.has_error()
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$value_template': '', 'test$type': ['template']})
assert widget.parse() is None
assert not widget.has_error()
# python value left empty
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$value_python': '', 'test$type': ['python']})
assert not widget.has_error()
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$type': ['python']})
assert not widget.has_error()
# but field marqued as required
widget = ComputedExpressionWidget('test', value='=foo', required=True)
mock_form_submission(req, widget, {'test$value_python': '', 'test$type': ['python']})
assert widget.has_error()
# invalid values
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$value_python': 'hello world', 'test$type': ['python']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error')
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$value_python': '=3', 'test$type': ['python']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error')
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$value_python': '{{form_var_foo}}', 'test$type': ['python']})
assert widget.has_error()
assert 'Python expression cannot contain {{' in widget.get_error()
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(
req, widget, {'test$value_template': '{{ form_var_xxx }}', 'test$type': ['template']}
)
assert not widget.has_error()
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$value_template': '{% if True %}', 'test$type': ['template']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error in Django template')
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$value_template': '[form_var_xxx]', 'test$type': ['template']})
assert not widget.has_error()
widget = ComputedExpressionWidget('test', value='=foo')
mock_form_submission(req, widget, {'test$value_template': '[end]', 'test$type': ['template']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error in ezt template')
def test_computed_expression_widget_no_python():
widget = ComputedExpressionWidget('test')
form = Form(method='post', use_tokens=False, enctype='application/x-www-form-urlencoded')
form.widgets.append(widget)
@ -1392,6 +1389,11 @@ def test_computed_expression_widget_no_python():
assert widget.parse() == 'hello world'
assert not widget.has_error()
widget = ComputedExpressionWidget('test', value='{{ foo }}')
mock_form_submission(req, widget, {'test$value_template': 'hello world'})
assert widget.parse() == 'hello world'
assert not widget.has_error()
widget = ComputedExpressionWidget('test')
mock_form_submission(req, widget, {'test$value_template': ''})
assert widget.parse() is None
@ -1406,50 +1408,50 @@ def test_computed_expression_widget_no_python():
assert widget.has_error()
assert widget.get_error().startswith('syntax error in Django template')
pub.site_options.set('options', 'disable-python-expressions', 'false')
def test_condition_widget():
widget = ConditionWidget('test')
widget = ConditionWidget('test', value={'type': 'python', 'value': 'foo'})
form = Form(method='post', use_tokens=False, enctype='application/x-www-form-urlencoded')
form.widgets.append(widget)
assert '$type' in str(form.render())
widget = ConditionWidget('test')
mock_form_submission(req, widget, {'test$value_django': 'hello == 1'})
widget = ConditionWidget('test', value={'type': 'python', 'value': 'foo'})
mock_form_submission(req, widget, {'test$value_django': 'hello == 1', 'test$type': ['django']})
assert widget.parse() == {'type': 'django', 'value': 'hello == 1'}
assert not widget.has_error()
widget = ConditionWidget('test')
mock_form_submission(req, widget, {'test$value_django': ''})
widget = ConditionWidget('test', value={'type': 'python', 'value': 'foo'})
mock_form_submission(req, widget, {'test$value_django': '', 'test$type': ['django']})
assert widget.parse() is None
assert not widget.has_error()
widget = ConditionWidget('test')
mock_form_submission(req, widget, {'test$value_django': '{{ form_var_xxx }}'})
widget = ConditionWidget('test', value={'type': 'python', 'value': 'foo'})
mock_form_submission(req, widget, {'test$value_django': '{{ form_var_xxx }}', 'test$type': ['django']})
assert widget.has_error()
assert widget.get_error() == "syntax error: Could not parse the remainder: '{{' from '{{'"
widget = ConditionWidget('test')
widget = ConditionWidget('test', value={'type': 'python', 'value': 'foo'})
mock_form_submission(req, widget, {'test$value_python': 'hello == 1', 'test$type': ['python']})
assert widget.parse() == {'type': 'python', 'value': 'hello == 1'}
assert not widget.has_error()
widget = ConditionWidget('test')
widget = ConditionWidget('test', value={'type': 'python', 'value': 'foo'})
mock_form_submission(req, widget, {'test$value_python': 'hello~', 'test$type': ['python']})
assert widget.has_error()
assert widget.get_error().startswith('syntax error:')
def test_condition_widget_no_python():
pub.load_site_options()
pub.site_options.set('options', 'disable-python-expressions', 'true')
widget = ConditionWidget('test')
form = Form(method='post', use_tokens=False, enctype='application/x-www-form-urlencoded')
form.widgets.append(widget)
assert '$type' not in str(form.render())
widget = ConditionWidget('test', value={'type': 'django', 'value': 'foo'})
form = Form(method='post', use_tokens=False, enctype='application/x-www-form-urlencoded')
form.widgets.append(widget)
assert '$type' not in str(form.render())
widget = ConditionWidget('test')
mock_form_submission(req, widget, {'test$value_django': 'hello == 1'})
assert widget.parse() == {'type': 'django', 'value': 'hello == 1'}
@ -1465,8 +1467,6 @@ def test_condition_widget_no_python():
assert widget.has_error()
assert widget.get_error() == "syntax error: Could not parse the remainder: '{{' from '{{'"
pub.site_options.set('options', 'disable-python-expressions', 'false')
def test_emoji_button():
# textual button

View File

@ -60,7 +60,7 @@ class DataSourceSelectionWidget(CompositeWidget):
def __init__(self, name, value=None, allowed_source_types=None, disallowed_source_types=None, **kwargs):
if allowed_source_types is None:
allowed_source_types = {'json', 'jsonp', 'geojson', 'named', 'cards', 'python', 'jsonvalue'}
if get_publisher().has_site_option('disable-python-expressions') and 'python' in allowed_source_types:
if 'python' in allowed_source_types:
allowed_source_types.remove('python')
if get_publisher().has_site_option('disable-jsonp-sources') and 'jsonp' in allowed_source_types:
allowed_source_types.remove('jsonp')

View File

@ -118,7 +118,7 @@ class PrefillSelectionWidget(CompositeWidget):
('none', _('None')),
('string', _('String / Template')),
]
if not get_publisher().has_site_option('disable-python-expressions'):
if value.get('type') == 'formula':
options.append(('formula', _('Python Expression (deprecated)')))
options += [
('user', _('User Field')),

View File

@ -3584,13 +3584,13 @@ class ComputedExpressionWidget(CompositeWidget):
)
self.has_python = False
if self.allow_python and not get_publisher().has_site_option('disable-python-expressions'):
if self.allow_python and value.get('type') == 'python':
self.has_python = True
self.add(
StringWidget,
'value_python',
size=80,
value=value.get('value') if value.get('type') == 'python' else None,
value=value.get('value'),
placeholder=value_placeholder,
)
self.add(
@ -3709,15 +3709,13 @@ class ConditionWidget(CompositeWidget):
value=value.get('value') if value.get('type') == 'django' else None,
)
if kwargs.get('allow_python', True) and not get_publisher().has_site_option(
'disable-python-expressions'
):
if kwargs.get('allow_python', True) and value.get('type') == 'python':
self.has_python = True
self.add(
StringWidget,
'value_python',
size=80,
value=value.get('value') if value.get('type') == 'python' else None,
value=value.get('value'),
)
self.add(
SingleSelectWidget,

View File

@ -1664,7 +1664,7 @@ class WorkflowGlobalActionTimeoutTrigger(WorkflowGlobalActionTrigger):
def form(self, workflow):
form = Form(enctype='multipart/form-data')
options = self.get_anchor_labels()
if get_publisher().has_site_option('disable-python-expressions'):
if not self.anchor_expression:
options.pop('python')
options = list(options.items())
form.add(