From de35500ee98c56922b065f5bbc7c01796ef2e749 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Sun, 29 Dec 2019 20:48:12 +0100
Subject: [PATCH] fields: allow pickle-lazy on bo table vairiables (#38746)

---
 tests/test_form_pages.py | 73 +++++++++++++++++++++++++++++++++++++++-
 wcs/variables.py         |  6 +++-
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py
index 34f85367..8744e022 100644
--- a/tests/test_form_pages.py
+++ b/tests/test_form_pages.py
@@ -10,7 +10,7 @@ import re
 import time
 import zipfile
 import base64
-from webtest import Upload, Hidden
+from webtest import Upload, Hidden, AppError
 import mock
 
 try:
@@ -7152,3 +7152,74 @@ def test_form_comment_is_hidden_attribute(pub):
     resp.forms[0]['f1'] = '2'
     resp = resp.forms[0].submit('submit')
     assert 'style="display: none"' in comment.search(resp.forms[0].text).group(0)
+
+def test_workflow_set_bo_table_field(pub):
+    user = create_user(pub)
+
+    formdef = create_formdef()
+    formdef.fields = [
+        fields.TableField(
+            id='0', label='fo table field', type='table', varname='input',
+            rows=['row1', 'row2'], columns=['col1', 'col2']),
+    ]
+    formdef.store()
+    formdef.data_class().wipe()
+
+    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
+    st1.items.append(setbo)
+    workflow.store()
+
+    formdef.workflow_id = workflow.id
+    formdef.store()
+
+    formdef.data_class().wipe()
+    expected = [['a1', 'a2'], ['b1', 'b2']]
+
+    # python expression must be used here (else we get a string)
+    setbo.fields = [
+        {'field_id': 'bo0', 'value': '=form_var_input'},
+    ]
+    workflow.store()
+    resp = get_app(pub).get('/test/')
+    resp.form['f0$c-0-0'] = 'a1'
+    resp.form['f0$c-0-1'] = 'a2'
+    resp.form['f0$c-1-0'] = 'b1'
+    resp.form['f0$c-1-1'] = 'b2'
+    resp = resp.form.submit('submit')  # -> validation page
+    resp = resp.form.submit('submit')  # -> submission
+    resp = resp.follow()
+    assert 'The form has been recorded' in resp.text
+    assert formdef.data_class().select()[0].data['0'] == expected
+    assert formdef.data_class().select()[0].data['bo0'] == expected
+
+    # by using Django template we get a string
+    setbo.fields = [
+        {'field_id': 'bo0', 'value': '{{ form_var_input }}'},
+    ]
+    workflow.store()
+    resp = get_app(pub).get('/test/')
+    resp.form['f0$c-0-0'] = 'a1'
+    resp.form['f0$c-0-1'] = 'a2'
+    resp.form['f0$c-1-0'] = 'b1'
+    resp.form['f0$c-1-1'] = 'b2'
+    resp = resp.form.submit('submit')  # -> validation page
+    try:
+        resp = resp.form.submit('submit')  # -> submission
+    except AppError as exc:  # fails on sql metafunc.parametrize
+        pass
+    else:
+        resp = resp.follow()
+        assert 'The form has been recorded' in resp.text
+        assert formdef.data_class().select()[0].data['0'] == expected
+        assert formdef.data_class().select()[0].data['bo0'] == "%s" % expected
diff --git a/wcs/variables.py b/wcs/variables.py
index 203b6bd1..9b5297fe 100644
--- a/wcs/variables.py
+++ b/wcs/variables.py
@@ -480,6 +480,8 @@ class LazyFormDataVar(object):
             return LazyFieldVarDate(self._data, field, self._formdata)
         if field.key == 'map':
             return LazyFieldVarMap(self._data, field, self._formdata)
+        if field.key == 'table':
+            return LazyFieldVarBase(self._data, field, self._formdata)
 
         return LazyFieldVar(self._data, field, self._formdata)
 
@@ -490,7 +492,7 @@ class LazyFormDataVar(object):
             raise AttributeError(attr)
 
 
-class LazyFieldVar(object):
+class LazyFieldVarBase(object):
     def __init__(self, data, field, formdata=None):
         self._data = data
         self._field = field
@@ -578,6 +580,8 @@ class LazyFieldVar(object):
     def startswith(self, other):
         return self.get_value().startswith(other)
 
+
+class LazyFieldVar(LazyFieldVarBase):
     def __getstate__(self):
         raise AssertionError('lazy cannot be pickled')
 
-- 
2.24.1

