misc: make |exclude_self work in post conditions (#47746)

This commit is contained in:
Frédéric Péters 2020-12-01 08:38:47 +01:00
parent 93a9a55847
commit ea1657efd6
3 changed files with 71 additions and 0 deletions

View File

@ -2311,6 +2311,7 @@ def test_form_multi_page_post_edit(pub):
assert resp.forms[0]['f1'].value == 'foo2'
resp.forms[0]['f1'] = 'foo3'
resp = resp.forms[0].submit('submit')
assert formdef.data_class().get(data_id).data['1'] == 'foo2' # check foo3 has not been overwritten in database
assert resp.forms[0]['f3'].value == 'barXYZ'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/test/%s/' % data_id
@ -9036,3 +9037,66 @@ def test_structured_workflow_options(pub):
'1_structured': {'id': '1', 'text': 'un', 'more': 'foo'},
}
assert '2020-04-18' in formdata.evolution[0].parts[0].content
def test_exclude_self_condition(pub):
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.PageField(id='1', label='1st page', type='page',
post_conditions=[{
'condition': {
'type': 'django', 'value': 'form_objects|filter_by:"foo"|filter_value:form_var_foo|exclude_self|count == 0',
},
'error_message': 'You shall not pass.'
}]
),
fields.StringField(id='1', label='string', type='string', varname='foo'),
]
workflow = Workflow(name='test')
st1 = workflow.add_status('Status1', 'st1')
editable = EditableWorkflowStatusItem()
editable.id = '_editable'
editable.by = ['_submitter', '_receiver']
st1.items.append(editable)
editable.parent = st1
workflow.store()
formdef.workflow_id = workflow.id
formdef.store()
app = get_app(pub)
resp = app.get(formdef.get_url())
resp.form['f1'] = 'test'
resp = resp.form.submit('submit') # -> validation page
assert 'You shall not pass.' not in resp.text
resp = resp.form.submit('submit') # -> submit
resp = resp.follow()
# edit is ok
resp = resp.form.submit('button_editable').follow()
resp = resp.form.submit('submit') # -> validation page
assert 'You shall not pass.' not in resp
# 2nd submission
resp = app.get(formdef.get_url())
resp.form['f1'] = 'test'
resp = resp.form.submit('submit') # -> validation page
assert 'You shall not pass.' in resp.text
# submission with other value
resp = app.get(formdef.get_url())
resp.form['f1'] = 'other'
resp = resp.form.submit('submit') # -> validation page
assert 'You shall not pass.' not in resp.text
resp = resp.form.submit('submit') # -> submit
resp = resp.follow()
# edit is ok
resp = resp.form.submit('button_editable').follow()
resp.form['f1'] = 'test'
resp = resp.form.submit('submit') # -> validation page
assert 'You shall not pass.' in resp

View File

@ -619,6 +619,9 @@ class FormPage(Directory, FormTemplateMixin):
# keep associated user as it may be required as a parameter in
# data source URLs.
formdata.user = self.edited_data.user
# keep track of original formdata id so it can be used by
# |exclude_self filter.
formdata._edited_id = self.edited_data.id
return formdata
if get_request().is_in_backoffice():

View File

@ -106,6 +106,10 @@ class LazyFormDefObjectsManager(object):
def exclude_self(self):
assert self._formdata
if not self._formdata.id:
if hasattr(self._formdata, '_edited_id'):
return self._clone(self._criterias + [NotEqual('id', str(self._formdata._edited_id))])
return self._clone(self._criterias)
return self._clone(self._criterias + [NotEqual('id', str(self._formdata.id))])
def same_user(self):