forms: don't let old formdata get used by workflow after edit jump (#30942)

This commit is contained in:
Frédéric Péters 2019-02-27 15:09:32 +01:00
parent 6ddfd68c6d
commit 78799be562
3 changed files with 75 additions and 0 deletions

View File

@ -5773,3 +5773,70 @@ def test_field_live_select_content(pub, http_requests):
assert formdata.data['2'] == 'plop'
assert formdata.data['3'] == 'a'
assert formdata.data['3_display'] == 'b'
def test_form_edit_and_backoffice_field_change(pub):
create_user(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')
]
formdef.store()
formdef.data_class().wipe()
Workflow.wipe()
workflow = Workflow(name='test')
workflow.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(workflow)
workflow.backoffice_fields_formdef.fields = [
fields.StringField(id='bo1', label='bo field 1', type='string',
varname='plop'),
]
st1 = workflow.add_status('Status1', 'st1')
setbo = SetBackofficeFieldsWorkflowStatusItem()
setbo.parent = st1
setbo.fields = [{'field_id': 'bo1', 'value': '=form_var_foo'}]
setbo2 = SetBackofficeFieldsWorkflowStatusItem()
setbo2.parent = st1
setbo2.fields = [{'field_id': 'bo1', 'value': '="foo" + form_var_plop'}]
jump = JumpWorkflowStatusItem()
jump.status = 'st2'
st1.items = [setbo, setbo2, jump]
st2 = workflow.add_status('Status2', 'st2')
editable = EditableWorkflowStatusItem()
editable.id = '_editable'
editable.by = ['_submitter']
st2.items.append(editable)
editable.parent = st2
editable.status = st1.id
workflow.store()
formdef.workflow_id = workflow.id
formdef.store()
formdef.data_class().wipe()
resp = login(get_app(pub), username='foo', password='foo').get('/test/')
resp.form['f1'] = 'bar'
resp = resp.form.submit('submit') # -> page 2
resp = resp.form.submit('submit') # -> validation
resp = resp.form.submit('submit').follow() # -> submitted
assert 'The form has been recorded' in resp.body
data_id = formdef.data_class().select()[0].id
assert formdef.data_class().get(data_id).data['bo1'] == 'foobar'
app = login(get_app(pub), username='foo', password='foo')
resp = app.get('/test/%s/' % data_id)
assert 'button_editable-button' in resp.body
resp = resp.form.submit('button_editable')
resp = resp.follow()
assert resp.form['f1'].value == 'bar'
resp.form['f1'].value = 'baz'
resp = resp.form.submit('submit') # -> page 2
resp = resp.form.submit('submit').follow() # -> saved
assert formdef.data_class().get(data_id).data['bo1'] == 'foobaz'

View File

@ -1150,6 +1150,10 @@ class FormPage(Directory, FormTemplateMixin):
new_data[k] = v
self.edited_data.data = new_data
self.edited_data.store()
# remove previous formdata from substitution variables
get_publisher().substitutions.unfeed(lambda x: isinstance(x, FormData))
# and add new one
get_publisher().substitutions.feed(self.edited_data)
wf_status = self.edited_data.get_status()
url = None
for item in wf_status.items:

View File

@ -69,6 +69,10 @@ class Substitutions(object):
self.sources.append(source)
self.invalidate_cache()
def unfeed(self, predicate):
self.sources = [x for x in self.sources if not predicate(x)]
self.invalidate_cache()
@contextmanager
def freeze(self):
orig_sources, self.sources = self.sources, self.sources[:]