From fc53ad1d3975b472f08f35d627dda5892ee2a4b4 Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Tue, 12 Nov 2024 14:03:06 +0100 Subject: [PATCH] :sparkles: [#4398] Make auth_attribute_path required if update existing object True this field is necessary to perform the initial data reference ownership check, which is performed when updating existing objects --- .../form_design/RegistrationFields.stories.js | 31 ++++++++++++++++++- .../objectsapi/fields/AuthAttributePath.js | 3 +- .../contrib/objects_api/config.py | 10 ++++++ .../objects_api/tests/test_serializer.py | 17 ++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/openforms/js/components/admin/form_design/RegistrationFields.stories.js b/src/openforms/js/components/admin/form_design/RegistrationFields.stories.js index e4487210fc..31ccfd554a 100644 --- a/src/openforms/js/components/admin/form_design/RegistrationFields.stories.js +++ b/src/openforms/js/components/admin/form_design/RegistrationFields.stories.js @@ -12,6 +12,7 @@ import { mockCataloguesGet as mockZGWApisCataloguesGet, } from 'components/admin/form_design/registrations/zgw/mocks'; import { + FeatureFlagsDecorator, FormDecorator, ValidationErrorsDecorator, } from 'components/admin/form_design/story-decorators'; @@ -20,7 +21,7 @@ import RegistrationFields from './RegistrationFields'; export default { title: 'Form design / Registration / RegistrationFields', - decorators: [ValidationErrorsDecorator, FormDecorator], + decorators: [FeatureFlagsDecorator, ValidationErrorsDecorator, FormDecorator], component: RegistrationFields, args: { availableBackends: [ @@ -572,6 +573,11 @@ export const ConfiguredBackends = { }; export const ObjectsAPI = { + parameters: { + featureFlags: { + REGISTRATION_OBJECTS_API_ENABLE_EXISTING_OBJECT_INTEGRATION: true, + }, + }, args: { configuredBackends: [ { @@ -623,6 +629,29 @@ export const ObjectsAPI = { await selectEvent.select(catalogueSelect, 'Catalogus 2'); }); + await step( + 'Path to auth attribute is required if updating existing objects is enabled', + async () => { + const otherSettingsTitle = modal.getByRole('heading', { + name: 'Overige instellingen (Tonen)', + }); + expect(otherSettingsTitle).toBeVisible(); + await userEvent.click(within(otherSettingsTitle).getByRole('link', {name: '(Tonen)'})); + + const authAttributePath = modal.getByText( + 'Path to auth attribute (e.g. BSN/KVK) in objects' + ); + + expect(authAttributePath).not.toHaveClass('required'); + + const updateExistingObject = modal.getByLabelText('Bestaand object bijwerken'); + await userEvent.click(updateExistingObject); + + // Checking `updateExistingObject` should make `authAttributePath` required + expect(authAttributePath).toHaveClass('required'); + } + ); + await step('Submit the form', async () => { await userEvent.click(modal.getByRole('button', {name: 'Opslaan'})); expect(args.onChange).toHaveBeenCalled(); diff --git a/src/openforms/js/components/admin/form_design/registrations/objectsapi/fields/AuthAttributePath.js b/src/openforms/js/components/admin/form_design/registrations/objectsapi/fields/AuthAttributePath.js index 55c2e1e523..a7a323cb8b 100644 --- a/src/openforms/js/components/admin/form_design/registrations/objectsapi/fields/AuthAttributePath.js +++ b/src/openforms/js/components/admin/form_design/registrations/objectsapi/fields/AuthAttributePath.js @@ -6,10 +6,10 @@ import {FeatureFlagsContext} from 'components/admin/form_design/Context'; import ArrayInput from 'components/admin/forms/ArrayInput'; import Field from 'components/admin/forms/Field'; import FormRow from 'components/admin/forms/FormRow'; -import {Checkbox} from 'components/admin/forms/Inputs'; const AuthAttributePath = () => { const [fieldProps, , fieldHelpers] = useField({name: 'authAttributePath', type: 'array'}); + const [updateExistingObject] = useField('updateExistingObject'); const {setValue} = fieldHelpers; const {REGISTRATION_OBJECTS_API_ENABLE_EXISTING_OBJECT_INTEGRATION = false} = useContext(FeatureFlagsContext); @@ -33,6 +33,7 @@ const AuthAttributePath = () => { defaultMessage="This is used to perform validation to verify that the authenticated user is the owner of the object." /> } + required={!!updateExistingObject.value} > RegistrationOptions: {"version": _("Unknown version: {version}").format(version=version)} ) + if attrs.get("update_existing_object") and not attrs.get("auth_attribute_path"): + raise serializers.ValidationError( + { + "auth_attribute_path": _( + 'This field is required if "Update existing object" is checked' + ) + }, + code="required", + ) + if not self.context.get("validate_business_logic", True): return attrs diff --git a/src/openforms/registrations/contrib/objects_api/tests/test_serializer.py b/src/openforms/registrations/contrib/objects_api/tests/test_serializer.py index 59dc1e7332..de84b30108 100644 --- a/src/openforms/registrations/contrib/objects_api/tests/test_serializer.py +++ b/src/openforms/registrations/contrib/objects_api/tests/test_serializer.py @@ -188,6 +188,23 @@ def test_invalid_objects_api_group(self): error = options.errors["objects_api_group"][0] self.assertEqual(error.code, "does_not_exist") + def test_auth_attribute_path_required_if_update_existing_object_is_true(self): + options = ObjectsAPIOptionsSerializer( + data={ + "objects_api_group": self.objects_api_group.pk, + "version": 2, + "objecttype": "8e46e0a5-b1b4-449b-b9e9-fa3cea655f48", + "objecttype_version": 1, + "update_existing_object": True, + "auth_attribute_path": [], + }, + ) + + self.assertFalse(options.is_valid()) + self.assertIn("auth_attribute_path", options.errors) + error = options.errors["auth_attribute_path"][0] + self.assertEqual(error.code, "required") + def test_valid_serializer(self): options = ObjectsAPIOptionsSerializer( data={