empêcher une démarche avec workflow sans statut (#5907) #476

Merged
fpeters merged 3 commits from wip/5907-do-not-submit-without-status into main 2023-07-14 09:03:32 +02:00
5 changed files with 39 additions and 9 deletions

View File

@ -101,10 +101,14 @@ def test_forms_new(pub):
workflow = Workflow(name='Workflow Two')
workflow.possible_status = Workflow.get_default_workflow().possible_status[:]
workflow.store()
workflow3 = Workflow(name='Workflow Three') # without any status
workflow3.store()
resp = app.get('/backoffice/forms/')
resp = resp.click('New Form')
resp.forms[0]['name'] = 'second form'
with pytest.raises(ValueError):
resp.forms[0]['workflow_id'].select(text='Workflow Three')
resp.forms[0]['workflow_id'].select(text='Workflow Two')
# check select is setup for autocompletion
assert resp.pyquery('select#form_workflow_id')[0].attrib['data-autocomplete']

View File

@ -386,22 +386,33 @@ def test_workflows_delete_status(pub):
create_superuser(pub)
Workflow.wipe()
workflow = Workflow(name='foo')
workflow.add_status(name='bar')
workflow.add_status(name='baz')
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/1/')
resp = resp.click('baz')
resp = resp.click('bar')
resp = resp.click('Delete')
resp = resp.form.submit('cancel')
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/'
resp = resp.follow()
assert len(Workflow.get(workflow.id).possible_status) == 2
resp = resp.click('Delete')
assert resp.pyquery('form .delete-button')
resp = resp.form.submit('submit')
assert resp.location == 'http://example.net/backoffice/workflows/1/'
resp = resp.follow()
assert len(Workflow.get(workflow.id).possible_status) == 1
resp = resp.click('baz')
resp = resp.click('Delete')
assert 'the workflow would not have any status left' in resp.text
assert not resp.pyquery('form .delete-button')
resp = resp.form.submit('submit')
assert len(Workflow.get(workflow.id).possible_status) == 1
@pytest.mark.parametrize(

View File

@ -91,12 +91,12 @@ class FormDefUI:
return get_categories(self.category_class, filter_function=filter_function)
@classmethod
def get_workflows(cls, condition=lambda x: True, formdef_category=None):
def get_workflows(cls, formdef_category=None):
default_workflow = cls.formdef_class.get_default_workflow()
t = sorted(
(misc.simplify(x.name), x.category.name if x.category else '', x.id, x.name, x.id)
for x in Workflow.select()
if condition(x)
if x.possible_status
)
workflows_by_category_names = defaultdict(list)
for x in t:
@ -1081,9 +1081,7 @@ class FormDefPage(Directory):
def workflow(self):
form = Form(enctype='multipart/form-data')
workflows = self.formdef_ui_class.get_workflows(
condition=lambda x: x.possible_status, formdef_category=self.formdef.category
)
workflows = self.formdef_ui_class.get_workflows(formdef_category=self.formdef.category)
form.add(
SingleSelectWidget,
'workflow_id',

View File

@ -748,9 +748,23 @@ class WorkflowStatusPage(Directory):
def delete(self):
form = Form(enctype="multipart/form-data")
form.widgets.append(HtmlWidget('<p>%s</p>' % _("You are about to remove a status.")))
form.add_submit('delete', _('Delete'))
form.add_submit("cancel", _("Cancel"))
if self.workflow.possible_status and len(self.workflow.possible_status) == 1:
form.widgets.append(
HtmlWidget(
htmltext('<div class="warningnotice"><p>%s</p></div>')
% _(
'It is not possible to remove this status as '
'the workflow would not have any status left.'
)
)
)
form.add_submit('cancel', _('Cancel'))
if form.is_submitted():
return redirect('../../')
else:
form.widgets.append(HtmlWidget('<p>%s</p>' % _('You are about to remove a status.')))
form.add_submit('delete', _('Delete'))
form.add_submit('cancel', _('Cancel'))
if form.get_widget('cancel').parse():
return redirect('.')
if not form.is_submitted() or form.has_errors():

View File

@ -456,6 +456,9 @@ class FormData(StorableObject):
def just_created(self):
from wcs.workflows import ContentSnapshotPart
# it should not be possible to have a formdef/carddef with a workflow without any status.
assert self.formdef.workflow.possible_status
self.receipt_time = time.localtime()
self.status = 'wf-%s' % self.formdef.workflow.possible_status[0].id
# we add the initial status to the history, this makes it more readable