From 9e6d6608510a1e6ff486b0def438eee3ff3629ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Sun, 22 May 2022 21:12:18 +0200
Subject: [PATCH] fields: do not consider prefill of type none as a real
 prefill (#65544)

---
 tests/admin_pages/test_form.py |  4 +--
 tests/form_pages/test_block.py | 57 ++++++++++++++++++++++++++++++++++
 wcs/fields.py                  |  5 +--
 wcs/forms/root.py              |  3 ++
 4 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/tests/admin_pages/test_form.py b/tests/admin_pages/test_form.py
index 9a7a3e700..62d5362b3 100644
--- a/tests/admin_pages/test_form.py
+++ b/tests/admin_pages/test_form.py
@@ -1978,7 +1978,7 @@ def test_form_prefill_type_options(pub):
     app = login(get_app(pub))
     resp = app.get('/backoffice/forms/1/fields/1/')
     assert resp.forms[0]['prefill$type'].options == [
-        ('None', False, 'None'),
+        ('None', True, 'None'),
         ('String / Template', False, 'String / Template'),
         ('Python Expression', False, 'Python Expression'),
         ('User Field', False, 'User Field'),
@@ -1991,7 +1991,7 @@ def test_form_prefill_type_options(pub):
 
     resp = app.get('/backoffice/forms/1/fields/1/')
     assert resp.forms[0]['prefill$type'].options == [
-        ('None', False, 'None'),
+        ('None', True, 'None'),
         ('String / Template', False, 'String / Template'),
         ('User Field', False, 'User Field'),
         ('Geolocation', False, 'Geolocation'),
diff --git a/tests/form_pages/test_block.py b/tests/form_pages/test_block.py
index 9edcf5138..9455cf834 100644
--- a/tests/form_pages/test_block.py
+++ b/tests/form_pages/test_block.py
@@ -1889,3 +1889,60 @@ def test_block_with_block_counter_condition(pub):
         '1_display': 'foobar, foobar',
     }
     formdef.data_class().wipe()
+
+
+def test_block_with_block_item_field_condition_and_prefill(pub):
+    BlockDef.wipe()
+    block = BlockDef()
+    block.name = 'foobar'
+    block.fields = [
+        fields.StringField(
+            id='123',
+            required=True,
+            label='One',
+            type='string',
+            prefill={'type': 'string', 'value': '{{ "plop" }}'},
+        ),
+        fields.ItemField(
+            id='234',
+            required=True,
+            label='Test2',
+            type='item',
+            varname='item',
+            items=['Foo', 'Bar'],
+            prefill={'type': 'none'},
+        ),
+        fields.StringField(
+            id='345',
+            required=True,
+            label='Two',
+            type='string',
+            condition={'type': 'django', 'value': 'block_var_item == "Foo"'},
+        ),
+    ]
+    block.store()
+
+    FormDef.wipe()
+    formdef = FormDef()
+    formdef.name = 'form title'
+    formdef.fields = [
+        fields.BlockField(id='1', label='test', type='block:foobar'),
+    ]
+    formdef.store()
+    formdef.data_class().wipe()
+
+    app = get_app(pub)
+    resp = app.get(formdef.get_url())
+    assert resp.form['f1$element0$f123'].value == 'plop'
+    assert resp.form['f1$element0$f234'].value == 'Foo'
+    assert resp.pyquery('[data-widget-name="f1$element0$f234"]').attr['data-live-source'] == 'true'
+    assert resp.pyquery('[data-widget-name="f1$element0$f345"]').attr.style == 'display: none'
+    live_resp = app.post(
+        formdef.get_url() + 'live?modified_field_id=123&modified_block_id=1&modified_block_row=0',
+        params=resp.form.submit_fields(),
+    )
+    assert live_resp.json['result']['1-123-0']['visible'] is True
+    assert live_resp.json['result']['1-234-0']['visible'] is True
+    assert live_resp.json['result']['1-345-0']['visible'] is True
+    resp.form['f1$element0$f345'] = 'test'
+    resp = resp.form.submit('submit')  # validation
diff --git a/wcs/fields.py b/wcs/fields.py
index bd9cf2aae..01780a31f 100644
--- a/wcs/fields.py
+++ b/wcs/fields.py
@@ -131,7 +131,7 @@ class PrefillSelectionWidget(CompositeWidget):
             SingleSelectWidget,
             'type',
             options=options,
-            value=value.get('type'),
+            value=value.get('type') or 'none',
             attrs={'data-dynamic-display-parent': 'true'},
         )
 
@@ -230,7 +230,7 @@ class PrefillSelectionWidget(CompositeWidget):
     def _parse(self, request):
         values = {}
         type_ = self.get('type')
-        if type_:
+        if type_ and type_ != 'none':
             values['type'] = type_
             values['locked'] = self.get('locked')
             value = self.get('value_%s' % type_)
@@ -2260,6 +2260,7 @@ class ItemField(WidgetField, MapOptionsMixin, ItemFieldMixin):
                 widget.extra_css_class = '%s %s' % (widget.extra_css_class, self.extra_css_class)
             else:
                 widget.extra_css_class = self.extra_css_class
+        return widget
 
     def store_display_value(self, data, field_id, raise_on_error=False):
         value = data.get(field_id)
diff --git a/wcs/forms/root.py b/wcs/forms/root.py
index cc1cabfdc..e1ea191cb 100644
--- a/wcs/forms/root.py
+++ b/wcs/forms/root.py
@@ -410,6 +410,9 @@ class FormPage(Directory, FormTemplateMixin):
             prefilled = False
             locked = False
 
+            if field.prefill and field.prefill.get('type') == 'none':
+                field.prefill = {}
+
             if field.prefill:
                 prefill_user = get_request().user
                 if get_request().is_in_backoffice():
-- 
2.36.1

