misc: do not jump to unknown status (#76421)

This commit is contained in:
Frédéric Péters 2023-04-08 09:28:44 +02:00
parent c5406f3a28
commit a4f28ff48c
7 changed files with 75 additions and 10 deletions

View File

@ -285,6 +285,7 @@ def test_formdata(pub, local_user, user, auth):
workflow.add_status('Status1', 'st1')
workflow.possible_status[-1].visibility = ['unknown']
workflow.store()
formdef.refresh_from_storage() # also update cached workflow
formdata.jump_status('st1')
assert formdata.status == 'wf-st1'

View File

@ -917,6 +917,58 @@ def test_backoffice_multi_actions_jump_condition(pub):
assert formdef.data_class().get(id).status == 'wf-new'
@pytest.mark.parametrize('target', [None, 'xxx'])
def test_backoffice_multi_actions_mistarget_jump(pub, target):
create_superuser(pub)
FormDef.wipe()
Workflow.wipe()
# add extra jump, with no target
workflow = Workflow.get_default_workflow()
workflow.id = '2'
jump = workflow.get_status('new').add_action('choice', id='_test')
jump.label = 'Test'
jump.identifier = 'test'
jump.by = ['_receiver']
jump.status = target
workflow.store()
formdef = FormDef()
formdef.name = 'form title'
formdef.workflow_roles = {'_receiver': 1}
formdef.workflow_id = workflow.id
formdef.store()
formdef.data_class().wipe()
formdata = formdef.data_class()()
formdata.just_created()
formdata.jump_status('new')
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/?filter=all')
assert 'select[]' in resp.forms['multi-actions'].fields
assert len(resp.pyquery.find('#multi-actions div.buttons button')) == 1
assert resp.pyquery.find('#multi-actions div.buttons button').text() == 'Test'
ids = []
for checkbox in resp.forms[0].fields['select[]']:
if checkbox._value == '_all':
continue
# check them all
ids.append(checkbox._value)
checkbox.checked = True
resp = resp.forms['multi-actions'].submit('button-action-st-new-test-_test')
assert '?job=' in resp.location
resp = resp.follow()
assert 'Executing task "Test" on forms' in resp.text
assert '>completed<' in resp.text
# check status didn't change
formdata = formdef.data_class().get(formdata.id)
assert formdata.get_status().id == 'new'
def test_backoffice_multi_actions_oldest_form(pub):
create_superuser(pub)
create_environment(pub)

View File

@ -178,8 +178,7 @@ class ApiFormdataPage(FormStatusPage):
self.formdata.data.update(data)
self.formdata.store()
if item.status:
self.formdata.jump_status(item.status)
if self.formdata.jump_status(item.status):
self.formdata.record_workflow_event('api-post-edit-action', action_item_id=item.id)
self.formdata.perform_workflow()
ContentSnapshotPart.take(formdata=self.formdata, old_data=old_data)

View File

@ -818,8 +818,13 @@ class FormData(StorableObject):
if not previous_status:
summary = _('Failed to compute previous status')
get_publisher().record_error(summary, formdata=self)
return
return False
status_id = previous_status.id
if not self.formdef.workflow.has_status(status_id):
# do not jump to undefined or missing status
return False
status = 'wf-%s' % status_id
if not self.evolution:
self.evolution = []
@ -833,7 +838,7 @@ class FormData(StorableObject):
# just update last jump time on last evolution, do not add one
self.evolution[-1].last_jump_datetime = datetime.datetime.now()
self.store()
return
return True
evo = Evolution(self)
evo.time = time.localtime()
evo.status = status
@ -841,6 +846,7 @@ class FormData(StorableObject):
self.evolution.append(evo)
self.status = status
self.store()
return True
def get_url(self, backoffice=False, include_category=False, language=None):
return '%s%s/' % (

View File

@ -1761,9 +1761,9 @@ class FormPage(FormdefDirectoryBase, FormTemplateMixin):
user_id = user.id
wf_status = item.get_target_status(self.edited_data)
if wf_status:
self.edited_data.jump_status(wf_status[0].id, user_id=user_id)
self.edited_data.record_workflow_event('edit-action', action_item_id=item.id)
url = self.edited_data.perform_workflow()
if self.edited_data.jump_status(wf_status[0].id, user_id=user_id):
self.edited_data.record_workflow_event('edit-action', action_item_id=item.id)
url = self.edited_data.perform_workflow()
else:
# add history entry
evo = Evolution()

View File

@ -45,8 +45,8 @@ def jump_and_perform(formdata, action, workflow_data=None):
if workflow_data:
formdata.update_workflow_data(workflow_data)
formdata.store()
formdata.jump_status(action.status)
return formdata.perform_workflow()
if formdata.jump_status(action.status):
return formdata.perform_workflow()
class JumpDirectory(Directory):

View File

@ -833,13 +833,20 @@ class Workflow(StorableObject):
return status
def get_status(self, id):
if id.startswith('wf-'):
if id and id.startswith('wf-'):
id = id[3:]
for status in self.possible_status:
if status.id == id:
return status
raise KeyError()
def has_status(self, id):
try:
self.get_status(id)
return True
except KeyError:
return False
def get_backoffice_fields(self):
if self.backoffice_fields_formdef:
return self.backoffice_fields_formdef.fields or []