diff --git a/src/openforms/submissions/cosigning.py b/src/openforms/submissions/cosigning.py index c3bae8bd1a..f070253e59 100644 --- a/src/openforms/submissions/cosigning.py +++ b/src/openforms/submissions/cosigning.py @@ -87,6 +87,11 @@ def _find_component(self) -> Component | None: """ Discover the Formio cosign component in the submission/form. """ + from .form_logic import check_submission_logic + from .logic.datastructures import DataContainer + + check_submission_logic(self.submission) + # use the complete view on the Formio component tree(s) configuration_wrapper = self.submission.total_configuration_wrapper @@ -94,6 +99,18 @@ def _find_component(self) -> Component | None: # component. for component in configuration_wrapper.component_map.values(): if component["type"] == "cosign": + # we can't just blindly return the component, as it may be conditionally + # displayed, which is equivalent to "cosign not relevant". See + # https://github.com/open-formulieren/open-forms/issues/3901 + container = DataContainer( + self.submission.load_submission_value_variables_state() + ) + visible = configuration_wrapper.is_visible_in_frontend( + component["key"], + values=container.data, + ) + if not visible: + return None return component return None diff --git a/src/openforms/submissions/tests/test_post_submission_event.py b/src/openforms/submissions/tests/test_post_submission_event.py index bcbc50d8ad..bffe0ecab4 100644 --- a/src/openforms/submissions/tests/test_post_submission_event.py +++ b/src/openforms/submissions/tests/test_post_submission_event.py @@ -15,7 +15,8 @@ from openforms.authentication.service import AuthAttribute from openforms.config.models import GlobalConfiguration from openforms.emails.tests.factories import ConfirmationEmailTemplateFactory -from openforms.forms.tests.factories import FormDefinitionFactory +from openforms.forms.constants import LogicActionTypes, PropertyTypes +from openforms.forms.tests.factories import FormDefinitionFactory, FormLogicFactory from openforms.payments.constants import PaymentStatus from openforms.payments.tests.factories import SubmissionPaymentFactory from openforms.registrations.base import PreRegistrationResult @@ -24,7 +25,7 @@ ) from openforms.utils.tests.logging import ensure_logger_level -from ..constants import PostSubmissionEvents +from ..constants import PostSubmissionEvents, RegistrationStatuses from ..models import SubmissionReport from ..tasks import on_post_submission_event from .factories import SubmissionFactory @@ -996,6 +997,87 @@ def test_cosign_not_required_but_filled_in_does_not_proceed_with_registration(se self.assertTrue(submission.confirmation_email_sent) self.assertEqual(submission.auth_info.value, "111222333") + @tag("gh-3901", "hlmr-86") + def test_cosign_required_but_hidden_proceeds_with_registration(self): + """ + A conditionally hidden cosign component may not block registration. + """ + submission = SubmissionFactory.from_components( + components_list=[ + { + "key": "cosign", + "type": "cosign", + "label": "Cosign component", + "validate": {"required": True}, + "hidden": True, + }, + ], + submitted_data={"cosign": ""}, + completed=True, + cosign_complete=False, + form__registration_backend="email", + form__registration_backend_options={"to_emails": ["test@registration.nl"]}, + auth_info__attribute=AuthAttribute.bsn, + auth_info__value="111222333", + language_code="en", + ) + assert submission.registration_status == RegistrationStatuses.pending + + on_post_submission_event(submission.pk, PostSubmissionEvents.on_completion) + + submission.refresh_from_db() + self.assertEqual(submission.registration_status, RegistrationStatuses.success) + + @tag("gh-3901", "hlmr-86") + def test_cosign_required_and_visible_via_logic_does_not_proceed_with_registration( + self, + ): + """ + A conditionally displayed cosign component must block registration. + """ + submission = SubmissionFactory.from_components( + components_list=[ + { + "key": "cosign", + "type": "cosign", + "label": "Cosign component", + "validate": {"required": True}, + "hidden": True, + }, + ], + submitted_data={"cosign": ""}, + completed=True, + cosign_complete=False, + form__registration_backend="email", + form__registration_backend_options={"to_emails": ["test@registration.nl"]}, + auth_info__attribute=AuthAttribute.bsn, + auth_info__value="111222333", + language_code="en", + ) + FormLogicFactory.create( + form=submission.form, + json_logic_trigger=True, + actions=[ + { + "action": { + "type": LogicActionTypes.property, + "property": { + "type": PropertyTypes.bool, + "value": "hidden", + }, + "state": False, + }, + "component": "cosign", + } + ], + ) + assert submission.registration_status == RegistrationStatuses.pending + + on_post_submission_event(submission.pk, PostSubmissionEvents.on_completion) + + submission.refresh_from_db() + self.assertEqual(submission.registration_status, RegistrationStatuses.pending) + @tag("gh-3924") def test_payment_complete_does_not_set_retry_flag(self): submission = SubmissionFactory.create(