From 4bf6f06bb2516502c79bfd1442e55423844d9a3c Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Fri, 24 May 2024 15:08:22 +0200 Subject: [PATCH] :bug: [#4241] Fix validation of field with nested key in fieldset by not adding a serializer field for layout components Backport-of: #4329 --- src/openforms/formio/rendering/nodes.py | 5 ++++- src/openforms/formio/serializers.py | 9 ++++++++- .../formio/tests/validation/test_fieldset.py | 20 +++++++++++++++++++ src/openforms/formio/utils.py | 4 ++++ src/openforms/forms/models/form_variable.py | 2 +- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/openforms/formio/rendering/nodes.py b/src/openforms/formio/rendering/nodes.py index 47fac3bf48..7607dc5aa2 100644 --- a/src/openforms/formio/rendering/nodes.py +++ b/src/openforms/formio/rendering/nodes.py @@ -235,7 +235,10 @@ def __iter__(self) -> Iterator["ComponentNode"]: return # in export mode, only emit if the component is not a layout component - if self.mode != RenderModes.export or not is_layout_component(self.component): + if self.mode != RenderModes.export or ( + not is_layout_component(self.component) + and self.component["type"] != "editgrid" + ): yield self for child in self.get_children(): diff --git a/src/openforms/formio/serializers.py b/src/openforms/formio/serializers.py index 2569fae068..a291be9aa8 100644 --- a/src/openforms/formio/serializers.py +++ b/src/openforms/formio/serializers.py @@ -18,7 +18,7 @@ from .datastructures import FormioConfigurationWrapper from .typing import Component -from .utils import iter_components +from .utils import is_layout_component, iter_components if TYPE_CHECKING: from .registry import ComponentRegistry @@ -62,6 +62,10 @@ def apply_hidden_state( if is_visible: continue + # Layout components do not have serializer fields associated with them + if is_layout_component(component): + continue + # when it's not visible, grab the field from the serializer and remove all # the validators to match Formio's behaviour. serializer_field = glom(fields, component["key"]) @@ -149,6 +153,9 @@ def build_serializer( config: JSONObject = {"components": components} for component in iter_components(config, recurse_into_editgrid=False): + if is_layout_component(component): + continue + field = register.build_serializer_field(component) assign(obj=fields, path=component["key"], val=field, missing=dict) diff --git a/src/openforms/formio/tests/validation/test_fieldset.py b/src/openforms/formio/tests/validation/test_fieldset.py index ff96433137..707bbe2b78 100644 --- a/src/openforms/formio/tests/validation/test_fieldset.py +++ b/src/openforms/formio/tests/validation/test_fieldset.py @@ -58,3 +58,23 @@ def test_hidden_fieldset_with_nested_required_fields(self): is_valid, _ = validate_formio_data(component, {"textfield": ""}) self.assertTrue(is_valid) + + def test_validate_nested_field_with_nested_key(self): + component: FieldsetComponent = { + "type": "fieldset", + "key": "fieldset", + "label": "A field set", + "components": [ + { + "type": "textfield", + "key": "fieldset.textfield", + "label": "Text field", + "validate": {"required": True}, + }, + ], + "hidden": False, + } + + is_valid, _ = validate_formio_data(component, {"fieldset": {"textfield": ""}}) + + self.assertFalse(is_valid) diff --git a/src/openforms/formio/utils.py b/src/openforms/formio/utils.py index a591fe1704..758a607b79 100644 --- a/src/openforms/formio/utils.py +++ b/src/openforms/formio/utils.py @@ -156,6 +156,10 @@ def get_readable_path_from_configuration_path( def is_layout_component(component): # Adapted from isLayoutComponent util function in Formio # https://github.com/formio/formio.js/blob/4.13.x/src/utils/formUtils.js#L25 + # FIXME ideally there would be a cleaner fix for this + if component["type"] == "editgrid": + return False + column = component.get("columns") components = component.get("components") rows = component.get("rows") diff --git a/src/openforms/forms/models/form_variable.py b/src/openforms/forms/models/form_variable.py index a642080b65..1aa0493cd8 100644 --- a/src/openforms/forms/models/form_variable.py +++ b/src/openforms/forms/models/form_variable.py @@ -53,7 +53,7 @@ def create_for_formstep(self, form_step: "FormStep") -> list["FormVariable"]: configuration=form_definition_configuration, recursive=True ): if ( - (is_layout_component(component) and not component["type"] == "editgrid") + is_layout_component(component) or component["type"] == "content" or component["key"] in existing_form_variables_keys or component_in_editgrid(form_definition_configuration, component)