Skip to content

Commit

Permalink
🎨 [#4398] Decouple variables endpoint validation behaviour from plugi…
Browse files Browse the repository at this point in the history
…n details

The important pattern is that certain validation checks run, not the
implementation details of the objects api prefill plugin. So, we
can properly isolate this by setting up a different plugin
registry and doing the dependency injection through a helper,
applying the same pattern as with registration plugins.
  • Loading branch information
sergei-maertens committed Dec 4, 2024
1 parent 6d45ca2 commit cc9a84d
Show file tree
Hide file tree
Showing 5 changed files with 310 additions and 193 deletions.
25 changes: 22 additions & 3 deletions src/openforms/forms/tests/variables/test_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.utils.translation import gettext_lazy as _

from factory.django import FileField
from rest_framework import status
from rest_framework import serializers, status
from rest_framework.reverse import reverse
from rest_framework.test import APITestCase
from zgw_consumers.constants import APITypes, AuthTypes
Expand All @@ -23,6 +23,8 @@
FormStepFactory,
FormVariableFactory,
)
from openforms.prefill.contrib.demo.plugin import DemoPrefill
from openforms.prefill.tests.utils import get_test_register, patch_prefill_registry
from openforms.variables.constants import (
DataMappingTypes,
FormVariableDataTypes,
Expand Down Expand Up @@ -903,6 +905,23 @@ def test_validators_accepts_only_numeric_keys(self):
self.assertEqual(status.HTTP_200_OK, response.status_code)

def test_bulk_create_and_update_with_prefill_constraints(self):
# Isolate the prefill registry/plugins for this test - we care about the pattern,
# not about particular plugin implementation details
new_register = get_test_register()

class OptionsSerializer(serializers.Serializer):
foo = serializers.CharField(required=True, allow_blank=False)

class OptionsPrefill(DemoPrefill):
options = OptionsSerializer

new_register("demo-options")(OptionsPrefill)

# set up registry patching for the test
cm = patch_prefill_registry(new_register)
cm.__enter__()
self.addCleanup(lambda: cm.__exit__(None, None, None))

user = StaffUserFactory.create(user_permissions=["change_form"])
self.client.force_authenticate(user)

Expand Down Expand Up @@ -1033,9 +1052,9 @@ def test_bulk_create_and_update_with_prefill_constraints(self):
"service_fetch_configuration": None,
"data_type": FormVariableDataTypes.string,
"source": FormVariableSources.user_defined,
"prefill_plugin": "objects_api",
"prefill_plugin": "demo-options",
"prefill_attribute": "",
"prefill_options": {"foo": "bar", "auth_attribute_path": ["bsn"]},
"prefill_options": {"foo": "bar"},
}
]

Expand Down
14 changes: 5 additions & 9 deletions src/openforms/prefill/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,18 @@

import elasticapm

from openforms.formio.service import FormioConfigurationWrapper
from openforms.formio.service import (
FormioConfigurationWrapper,
normalize_value_for_component,
)
from openforms.submissions.models import Submission
from openforms.submissions.models.submission_value_variable import (
SubmissionValueVariable,
)
from openforms.typing import JSONEncodable
from openforms.variables.constants import FormVariableSources

from .registry import Registry
from .registry import Registry, register as default_register
from .sources import (
fetch_prefill_values_from_attribute,
fetch_prefill_values_from_options,
Expand All @@ -71,9 +74,6 @@ def inject_prefill(
The prefill values are looped over by key: value, and for each value the matching
component is looked up to normalize it in the context of the component.
"""

from openforms.formio.service import normalize_value_for_component

prefilled_data = submission.get_prefilled_data()
for key, prefill_value in prefilled_data.items():
try:
Expand Down Expand Up @@ -111,10 +111,6 @@ def prefill_variables(submission: Submission, register: Registry | None = None)
be used to fetch the value. If ``register`` is not specified, the default registry instance
will be used.
"""
from openforms.formio.service import normalize_value_for_component

from .registry import register as default_register

register = register or default_register

state = submission.load_submission_value_variables_state()
Expand Down
5 changes: 2 additions & 3 deletions src/openforms/prefill/tests/test_prefill_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@
from ..contrib.demo.plugin import DemoPrefill
from ..registry import Registry, register as prefill_register
from ..service import inject_prefill, prefill_variables
from .utils import get_test_register

register = Registry()

register("demo")(DemoPrefill)
register = get_test_register()

CONFIGURATION = {
"display": "form",
Expand Down
Loading

0 comments on commit cc9a84d

Please sign in to comment.