workflows: allow role to be computed value in dispatch action (#18586)

This commit is contained in:
Frédéric Péters 2017-09-11 14:31:49 +02:00
parent 1444fa10d1
commit 51c44f7996
4 changed files with 62 additions and 8 deletions

View File

@ -363,6 +363,46 @@ def test_dispatch_auto(pub):
item.perform(formdata)
assert formdata.workflow_roles == {'_receiver': role2.id}
def test_dispatch_computed(pub, caplog):
pub.cfg['debug'] = {'logger': True}
pub.write_cfg()
pub.get_app_logger(force=True) # force new logger
formdef = FormDef()
formdef.name = 'baz'
formdef.store()
Role.wipe()
role = Role(name='xxx')
role.slug = 'yyy'
role.store()
item = DispatchWorkflowStatusItem()
formdata = formdef.data_class()()
item.perform(formdata)
assert not formdata.workflow_roles
formdata = formdef.data_class()()
item.role_key = '_receiver'
item.role_id = '="yyy"' # slug
item.perform(formdata)
assert formdata.workflow_roles == {'_receiver': role.id}
formdata = formdef.data_class()()
item.role_key = '_receiver'
item.role_id = '="xxx"' # name
item.perform(formdata)
assert formdata.workflow_roles == {'_receiver': role.id}
# unknown role
formdata = formdef.data_class()()
item.role_key = '_receiver'
item.role_id = '="foobar"'
item.perform(formdata)
assert not formdata.workflow_roles
assert caplog.records[-1].message == 'error in dispatch, missing role foobar (="foobar")'
def test_roles(pub):
user = pub.user_class()
user.store()

View File

@ -2191,6 +2191,8 @@ class HiddenErrorWidget(HiddenWidget):
class SingleSelectWidgetWithOther(CompositeWidget):
def __init__(self, name, value=None, **kwargs):
CompositeWidget.__init__(self, name, value=value, **kwargs)
if 'title' in kwargs:
del kwargs['title']
options = kwargs.get('options')[:]
if len(options[0]) == 1:
options = [(x[0], x[0], x[0]) for x in options]

View File

@ -79,10 +79,6 @@ div.SubmitWidget input, input[type=submit] {
vertical-align: middle;
}
div.SingleSelectWidgetWithOther div.SingleSelectWidget select {
padding: 4px 3px;
}
div.SingleSelectWidgetWithOther .content .widget {
display: inline-block;
}

View File

@ -144,9 +144,10 @@ class DispatchWorkflowStatusItem(WorkflowStatusItem):
required=True,
attrs={'data-dynamic-display-parent': 'true'})
if 'role_id' in parameters:
form.add(SingleSelectWidget, '%srole_id' % prefix,
title=_('Role'), value=str(self.role_id),
options=[(None, '----', None)] + get_user_roles(),
form.add(SingleSelectWidgetWithOther, '%srole_id' % prefix,
title=_('Role'),
value=str(self.role_id) if self.role_id else None,
options=[(None, '---', None)] + get_user_roles(),
attrs={
'data-dynamic-display-child-of': '%sdispatch_type' % prefix,
'data-dynamic-display-value': dispatch_types.get('manual'),
@ -180,7 +181,22 @@ class DispatchWorkflowStatusItem(WorkflowStatusItem):
if self.dispatch_type == 'manual' or not self.dispatch_type:
if not (self.role_id and self.role_key):
return
new_role_id = self.role_id
new_role_id = self.compute(self.role_id)
if not Role.has_key(new_role_id):
# computed value, not an id, try to get role by slug
new_role = Role.get_on_index(new_role_id, 'slug', ignore_errors=True)
if not new_role:
# fallback to role label
for role in Role.select():
if role.name == new_role_id:
new_role = role
break
if new_role:
new_role_id = new_role.id
else:
get_logger().error('error in dispatch, missing role %s (%s)' % (
new_role_id, self.role_id))
new_role_id = None
elif self.dispatch_type == 'automatic':
if not (self.role_key and self.variable and self.rules):
return