From 567b6b3bc982128a31ffc18dd8afe50c25fdcef1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Thu, 26 Nov 2020 16:51:07 +0100
Subject: [PATCH] workflow: display role details on inspect page (#48829)

---
 tests/admin_pages/test_workflow.py | 23 ++++++++++++++++++++++-
 wcs/wf/dispatch.py                 | 13 ++++++++++++-
 wcs/workflows.py                   | 26 ++++++++++++--------------
 3 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/tests/admin_pages/test_workflow.py b/tests/admin_pages/test_workflow.py
index 0eabec0c..8af0583a 100644
--- a/tests/admin_pages/test_workflow.py
+++ b/tests/admin_pages/test_workflow.py
@@ -16,6 +16,7 @@ from wcs.roles import Role
 from wcs.workflows import (
     Workflow, WorkflowCriticalityLevel, DisplayMessageWorkflowStatusItem,
     WorkflowBackofficeFieldsFormDef, CommentableWorkflowStatusItem)
+from wcs.wf.dispatch import DispatchWorkflowStatusItem
 from wcs.wf.export_to_model import ExportToModel
 from wcs.wf.jump import JumpWorkflowStatusItem
 from wcs.wf.register_comment import RegisterCommenterWorkflowStatusItem
@@ -1708,6 +1709,18 @@ def test_workflows_inspect_view(pub):
     wscall.parent = baz_status
     baz_status.items.append(wscall)
 
+    dispatch1 = DispatchWorkflowStatusItem()
+    dispatch1.dispatch_type = 'automatic'
+    dispatch1.rules = [
+        {'role_id': role.id, 'value': 'foo'},
+    ]
+    baz_status.items.append(dispatch1)
+    dispatch2 = DispatchWorkflowStatusItem()
+    dispatch2.dispatch_type = 'manual'
+    dispatch2.role_key = '_receiver'
+    dispatch2.role_id = role.id
+    baz_status.items.append(dispatch2)
+
     baz_status.backoffice_info_text = '<p>Hello</p>'
 
     display_form = FormWorkflowStatusItem()
@@ -1748,7 +1761,15 @@ def test_workflows_inspect_view(pub):
     workflow.store()
 
     app = login(get_app(pub))
-    app.get('/backoffice/workflows/%s/inspect' % workflow.id)
+    resp = app.get('/backoffice/workflows/%s/inspect' % workflow.id)
+    assert (
+        '<li><span class="parameter">Dispatch Type:</span> Multiple</li>'
+        '<li><span class="parameter">Rules:</span> '
+        '<ul class="rules"><li>foo → foobar</li></ul>'
+        '</li>') in resp.text
+    assert (
+        '<li><span class="parameter">Dispatch Type:</span> Simple</li>'
+        '<li><span class="parameter">Role:</span> foobar</li>') in resp.text
 
 
 def test_workflows_unused(pub):
diff --git a/wcs/wf/dispatch.py b/wcs/wf/dispatch.py
index c7cb9c1e..24255d49 100644
--- a/wcs/wf/dispatch.py
+++ b/wcs/wf/dispatch.py
@@ -17,12 +17,14 @@
 import collections
 import xml.etree.ElementTree as ET
 
+from quixote.html import htmltext
+
 from ..qommon import _, N_
 from ..qommon.form import *
 from ..qommon.template import Template
 from ..qommon import get_logger
 from wcs.roles import Role, get_user_roles
-from wcs.workflows import XmlSerialisable, WorkflowStatusItem, register_item_class
+from wcs.workflows import XmlSerialisable, WorkflowStatusItem, register_item_class, get_role_name
 
 
 class AutomaticDispatchRowWidget(CompositeWidget):
@@ -177,6 +179,15 @@ class DispatchWorkflowStatusItem(WorkflowStatusItem):
                         }
                     )
 
+    def get_role_id_parameter_view_value(self):
+        return get_role_name(self.role_id)
+
+    def get_rules_parameter_view_value(self):
+        result = []
+        for rule in self.rules or []:
+            result.append(htmltext('<li>%s → %s</li>') % (rule.get('value'), get_role_name(rule.get('role_id'))))
+        return htmltext('<ul class="rules">%s</ul>') % htmltext('').join(result)
+
     def perform(self, formdata):
         if not formdata.workflow_roles:
             formdata.workflow_roles = {}
diff --git a/wcs/workflows.py b/wcs/workflows.py
index 985415d2..c137e366 100644
--- a/wcs/workflows.py
+++ b/wcs/workflows.py
@@ -961,13 +961,7 @@ class XmlSerialisable(object):
             if role_id is None:
                 continue
             role_id = str(role_id)
-            if role_id.startswith('_') or role_id == 'logged-users':
-                role = force_text(role_id, charset)
-            else:
-                try:
-                    role = force_text(Role.get(role_id).name, charset)
-                except KeyError:
-                    role = force_text(role_id, charset)
+            role = get_role_name(role_id, charset)
             sub = ET.SubElement(el, 'item')
             sub.attrib['role_id'] = role_id
             sub.text = role
@@ -986,13 +980,7 @@ class XmlSerialisable(object):
         if not hasattr(self, attribute) or not getattr(self, attribute):
             return
         role_id = str(getattr(self, attribute))
-        if role_id.startswith('_') or role_id == 'logged-users':
-            role = force_text(role_id, charset)
-        else:
-            try:
-                role = force_text(Role.get(role_id).name, charset)
-            except KeyError:
-                role_id = role = force_text(role_id, charset)
+        role = get_role_name(role_id, charset)
         sub = ET.SubElement(item, attribute)
         if include_id:
             sub.attrib['role_id'] = role_id
@@ -2289,6 +2277,16 @@ def get_role_translation_label(workflow, role_id):
             return
 
 
+def get_role_name(role_id, charset=None):
+    role_id = str(role_id)
+    if role_id.startswith('_') or role_id == 'logged-users':
+        return force_text(role_id, charset)
+    try:
+        return force_text(Role.get(role_id).name, charset)
+    except KeyError:
+        return force_text(role_id, charset)
+
+
 def render_list_of_roles(workflow, roles):
     t = []
     for r in roles:
-- 
2.28.0

