From 9c1ca53dcd9fa47f0da2d1a1011c5d6b3950ae46 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Mon, 23 Dec 2019 15:06:48 +0100
Subject: [PATCH] bo-fields: warning table fields required python arrays
 (#38541)

---
 tests/test_admin_pages.py | 67 +++++++++++++++++++++++++++++++++++++++
 wcs/admin/workflows.py    | 10 ++++++
 2 files changed, 77 insertions(+)

diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py
index 53e25947..144ef458 100644
--- a/tests/test_admin_pages.py
+++ b/tests/test_admin_pages.py
@@ -41,6 +41,7 @@ from wcs.roles import Role
 from wcs.workflows import (Workflow, DisplayMessageWorkflowStatusItem,
         WorkflowCriticalityLevel, WorkflowBackofficeFieldsFormDef,
         CommentableWorkflowStatusItem)
+from wcs.wf.backoffice_fields import SetBackofficeFieldsWorkflowStatusItem
 from wcs.wf.export_to_model import ExportToModel
 from wcs.wf.jump import JumpWorkflowStatusItem
 from wcs.wf.register_comment import RegisterCommenterWorkflowStatusItem
@@ -3142,6 +3143,72 @@ def test_workflows_backoffice_fields(pub):
     workflow = Workflow.get(workflow.id)
     assert workflow.possible_status[0].items[0].fields == [{'field_id': first_field_id, 'value': 'Hello'}]
 
+def test_workflows_edit_backoffice_table_fields(pub):
+    create_superuser(pub)
+    create_role()
+
+    Workflow.wipe()
+    workflow = Workflow(name='test')
+    workflow.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(workflow)
+    workflow.backoffice_fields_formdef.fields = [
+        fields.TableField(
+            id='bo0', label='bo table field',
+            type='table', varname='backoffice_table',
+            rows=['row1', 'row2'], columns=['col1', 'col2']),
+    ]
+    st1 = workflow.add_status('status1', 'st1')
+    setbo = SetBackofficeFieldsWorkflowStatusItem()
+    setbo.parent = st1
+    setbo.fields = [
+        {'field_id': 'bo0', 'value': "=[['a1', 'a2'], ['b1', 'b2']]"},
+    ]
+    st1.items.append(setbo)
+    workflow.store()
+
+    formdef = FormDef()
+    formdef.name = 'form title'
+    formdef.workflow_id = workflow.id
+    formdef.fields = []
+    formdef.store()
+
+    app = login(get_app(pub))
+    resp = app.get('/backoffice/workflows/1/')
+    resp = resp.click('status1')
+    resp = resp.click('Backoffice Data')
+
+    # check backoffice fields
+    value = "[['a1', 'a2'], ['b1', 'b2']]"
+    assert [x[0] for x
+            in resp.form['fields$element0$field_id'].options
+            if x[1] == True][0] == 'bo0'  # selected var
+    assert [x[0] for x
+            in resp.form['fields$element0$value$type'].options
+            if x[1] == True][0] == 'python'  # selected type
+    assert resp.form['fields$element0$value$value_python'].value == value
+
+    # assert python expression is required for table fields
+    resp.form['fields$element0$value$value_python'].value = ''
+    resp = resp.form.submit('submit')
+    assert 'There were errors processing your form' in resp.text
+    assert 'Array fields require python expression' not in resp.text
+
+    resp.form['fields$element0$value$type'] = 'text'
+    resp.form['fields$element0$value$value_text'].value = value
+    resp = resp.form.submit('submit')
+    assert 'There were errors processing your form' in resp.text
+    assert 'Array fields require python expression' in resp.text
+
+    resp.form['fields$element0$value$type'] = 'template'
+    resp.form['fields$element0$value$value_template'].value = value
+    resp = resp.form.submit('submit')
+    assert 'There were errors processing your form' in resp.text
+    assert 'Array fields require python expression' in resp.text
+
+    resp.form['fields$element0$value$type'] = 'python'
+    resp.form['fields$element0$value$value_python'].value = value
+    resp = resp.form.submit('submit')
+    assert 'There were errors processing your form' not in resp.text
+
 def test_workflows_functions(pub):
     create_superuser(pub)
     create_role()
diff --git a/wcs/admin/workflows.py b/wcs/admin/workflows.py
index 6480d966..ef1c26fe 100644
--- a/wcs/admin/workflows.py
+++ b/wcs/admin/workflows.py
@@ -279,6 +279,16 @@ class WorkflowItemPage(Directory):
         if form.get_widget('cancel').parse():
             return redirect('..')
 
+        if (not form.has_errors()
+                and form._names.get('fields') and form._names['fields'].value):
+            workflow =  self.item.parent.parent
+            for bo_field in form._names['fields'].value or []:
+                bo_field_type = [x.type for x
+                                 in workflow.backoffice_fields_formdef.fields
+                                 if x.id == bo_field['field_id']][0]
+                if bo_field_type == 'table' and not bo_field['value'].startswith('='):
+                    form.widgets[1].error = 'Array fields require python expression'
+
         if not form.get_submit() == 'submit' or form.has_errors():
             self.html_top('%s - %s' % (_('Workflow'), self.workflow.name))
             r = TemplateIO(html=True)
-- 
2.24.1

