diff --git a/src/openforms/validations/registry.py b/src/openforms/validations/registry.py index 08a7819edb..8bfe462887 100644 --- a/src/openforms/validations/registry.py +++ b/src/openforms/validations/registry.py @@ -59,8 +59,9 @@ def _flat(it): def filter_empty_values(value: Any) -> Any: if not isinstance(value, dict): - # Let the serializer raise a the validation error + # Let the serializer raise the validation error return value + return {k: v for k, v in value.items() if v} @@ -141,7 +142,6 @@ def validate( SerializerClass = validator.callable.value_serializer serializer = SerializerClass(data={"value": filter_empty_values(value)}) serializer.is_valid(raise_exception=True) - try: validator(serializer.data["value"], submission) except (DJ_ValidationError, DRF_ValidationError) as e: diff --git a/src/openforms/validations/tests/test_api.py b/src/openforms/validations/tests/test_api.py index a4ce880a1a..fc7c735670 100644 --- a/src/openforms/validations/tests/test_api.py +++ b/src/openforms/validations/tests/test_api.py @@ -11,6 +11,7 @@ from openforms.submissions.tests.factories import SubmissionFactory from openforms.validations.registry import Registry, StringValueSerializer from openforms.validations.tests.test_registry import ( + DictValidator, DjangoValidator, DRFValidator, function_validator, @@ -38,6 +39,12 @@ def setUp(self): "demo", verbose_name="Demo function", for_components=(), is_demo_plugin=True )(function_validator) + register( + "dict_validator", + verbose_name="Dict validator", + for_components=("addressNL",), + )(DictValidator) + patcher = patch("openforms.validations.api.views.register", new=register) patcher.start() self.addCleanup(patcher.stop) @@ -76,6 +83,11 @@ def test_validations_list(self): "label": "Django function Validator", "for_components": [], }, + { + "id": "dict_validator", + "label": "Dict validator", + "for_components": ["addressNL"], + }, ], ) @@ -137,6 +149,11 @@ def test_validations_list(self): "label": "Django function Validator", "for_components": [], }, + { + "id": "dict_validator", + "label": "Dict validator", + "for_components": ["addressNL"], + }, ], ) @@ -154,6 +171,16 @@ def test_default_string_serializer(self): self.assertFalse(StringValueSerializer(data={"value": None}).is_valid()) self.assertFalse(StringValueSerializer(data={"bazz": "buzz"}).is_valid()) + def test_validation_forbidden(self): + submission = SubmissionFactory.create() + submission_uuid = str(submission.uuid) + url = reverse("api:validate-value", kwargs={"validator": "django"}) + + response = self.client.post( + url, {"value": "VALID", "submission_uuid": submission_uuid}, format="json" + ) + self.assertEqual(response.status_code, 403) + def test_validation(self): submission = SubmissionFactory.create() submission_uuid = str(submission.uuid) @@ -183,3 +210,27 @@ def test_validation(self): } self.assertEqual(response.status_code, 200) self.assertEqual(response.data, expected) + + def test_validation_dict(self): + # This test exists to add coverage to the `filter_empty_values` function + submission = SubmissionFactory.create() + submission_uuid = str(submission.uuid) + url = reverse("api:validate-value", kwargs={"validator": "dict_validator"}) + session = self.client.session + session[SUBMISSIONS_SESSION_KEY] = [submission_uuid] + session.save() + + response = self.client.post( + url, + { + "value": {"field": "dummy", "extra": ""}, + "submission_uuid": submission_uuid, + }, + format="json", + ) + expected = { + "is_valid": True, + "messages": [], + } + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data, expected) diff --git a/src/openforms/validations/tests/test_registry.py b/src/openforms/validations/tests/test_registry.py index a0ae27fa5b..75cad324a6 100644 --- a/src/openforms/validations/tests/test_registry.py +++ b/src/openforms/validations/tests/test_registry.py @@ -2,11 +2,20 @@ from django.test import TestCase from django.utils.translation import gettext as _ +from rest_framework import serializers from rest_framework.exceptions import ValidationError as DRFValidationError from openforms.validations.registry import Registry, StringValueSerializer +class DummyDataSerializer(serializers.Serializer): + field = serializers.CharField() + + +class DictValueSerializer(serializers.Serializer): + value = DummyDataSerializer() + + class DjangoValidator: is_enabled = True components = ("textfield",) @@ -37,6 +46,14 @@ def __call__(self, value, submission): raise DRFValidationError("not VALID value") +class DictValidator: + is_enabled = True + value_serializer = DictValueSerializer + + def __call__(self, value, submission): + return True + + def function_validator(value, submission): if value != "VALID": raise DjangoValidationError("not VALID value")