From b1bbb8475f2561f6a15fdf4a299245d11ff9369b Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Mon, 2 Dec 2024 11:41:11 +0100 Subject: [PATCH 1/5] :sparkles: [#4789] Add identifier field to ZGWAPIGroupConfig to make sure there is a unique field that can be used to refer to the groups and identify them when they are loaded using setup-configuration --- .../registrations/contrib/zgw_apis/admin.py | 18 ++++++-- .../0016_zgwapigroupconfig_identifier.py | 43 +++++++++++++++++++ ...0017_alter_zgwapigroupconfig_identifier.py | 22 ++++++++++ .../registrations/contrib/zgw_apis/models.py | 7 +++ .../contrib/zgw_apis/tests/factories.py | 3 ++ .../contrib/zgw_apis/tests/test_migrations.py | 24 +++++++++++ 6 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 src/openforms/registrations/contrib/zgw_apis/migrations/0016_zgwapigroupconfig_identifier.py create mode 100644 src/openforms/registrations/contrib/zgw_apis/migrations/0017_alter_zgwapigroupconfig_identifier.py diff --git a/src/openforms/registrations/contrib/zgw_apis/admin.py b/src/openforms/registrations/contrib/zgw_apis/admin.py index 5924927471..f824a48341 100644 --- a/src/openforms/registrations/contrib/zgw_apis/admin.py +++ b/src/openforms/registrations/contrib/zgw_apis/admin.py @@ -6,14 +6,26 @@ @admin.register(ZGWApiGroupConfig) class ZGWApiGroupConfigAdmin(admin.ModelAdmin): - list_display = ("name", "zrc_service", "drc_service", "ztc_service") + list_display = ("name", "identifier", "zrc_service", "drc_service", "ztc_service") list_select_related = ("zrc_service", "drc_service", "ztc_service") - search_fields = ("name",) + search_fields = ( + "name", + "identifier", + ) raw_id_fields = ("zrc_service", "drc_service", "ztc_service") + prepopulated_fields = {"identifier": ["name"]} ordering = ("name",) fieldsets = ( - (None, {"fields": ("name",)}), + ( + None, + { + "fields": ( + "name", + "identifier", + ) + }, + ), ( _("Services"), { diff --git a/src/openforms/registrations/contrib/zgw_apis/migrations/0016_zgwapigroupconfig_identifier.py b/src/openforms/registrations/contrib/zgw_apis/migrations/0016_zgwapigroupconfig_identifier.py new file mode 100644 index 0000000000..7bf1d17d4e --- /dev/null +++ b/src/openforms/registrations/contrib/zgw_apis/migrations/0016_zgwapigroupconfig_identifier.py @@ -0,0 +1,43 @@ +# Generated by Django 4.2.16 on 2024-12-02 10:30 + +from django.db import migrations, models +from django.utils.text import slugify + + +def set_zgw_api_group_config_identifier_from_name(apps, schema_editor): + ZGWApiGroupConfig = apps.get_model("zgw_apis", "ZGWApiGroupConfig") + + def generate_unique_identifier(original_identifier, count=0): + identifier = original_identifier + ("-" + str(count) if count else "") + if not ZGWApiGroupConfig.objects.filter(identifier=identifier).exists(): + return identifier + + return generate_unique_identifier(original_identifier, count + 1) + + for row in ZGWApiGroupConfig.objects.all(): + candidate_slug = slugify(row.name) + row.identifier = generate_unique_identifier(candidate_slug) + row.save(update_fields=["identifier"]) + + +class Migration(migrations.Migration): + + dependencies = [ + ("zgw_apis", "0015_explicit_objects_api_groups"), + ] + + operations = [ + migrations.AddField( + model_name="zgwapigroupconfig", + name="identifier", + field=models.SlugField( + blank=True, + help_text="A unique, human-friendly identifier to identify this group.", + verbose_name="identifier", + ), + ), + migrations.RunPython( + set_zgw_api_group_config_identifier_from_name, + reverse_code=migrations.RunPython.noop, + ), + ] diff --git a/src/openforms/registrations/contrib/zgw_apis/migrations/0017_alter_zgwapigroupconfig_identifier.py b/src/openforms/registrations/contrib/zgw_apis/migrations/0017_alter_zgwapigroupconfig_identifier.py new file mode 100644 index 0000000000..e74020acd0 --- /dev/null +++ b/src/openforms/registrations/contrib/zgw_apis/migrations/0017_alter_zgwapigroupconfig_identifier.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.16 on 2024-12-02 10:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("zgw_apis", "0016_zgwapigroupconfig_identifier"), + ] + + operations = [ + migrations.AlterField( + model_name="zgwapigroupconfig", + name="identifier", + field=models.SlugField( + help_text="A unique, human-friendly identifier to identify this group.", + unique=True, + verbose_name="identifier", + ), + ), + ] diff --git a/src/openforms/registrations/contrib/zgw_apis/models.py b/src/openforms/registrations/contrib/zgw_apis/models.py index 2d38d1344c..c911a4978e 100644 --- a/src/openforms/registrations/contrib/zgw_apis/models.py +++ b/src/openforms/registrations/contrib/zgw_apis/models.py @@ -54,6 +54,13 @@ class ZGWApiGroupConfig(models.Model): max_length=255, help_text=_("A recognisable name for this set of ZGW APIs."), ) + identifier = models.SlugField( + _("identifier"), + blank=False, + null=False, + unique=True, + help_text=_("A unique, human-friendly identifier to identify this group."), + ) zrc_service = models.ForeignKey( "zgw_consumers.Service", verbose_name=_("Zaken API"), diff --git a/src/openforms/registrations/contrib/zgw_apis/tests/factories.py b/src/openforms/registrations/contrib/zgw_apis/tests/factories.py index 67c1cb943c..719fe3fb75 100644 --- a/src/openforms/registrations/contrib/zgw_apis/tests/factories.py +++ b/src/openforms/registrations/contrib/zgw_apis/tests/factories.py @@ -1,3 +1,5 @@ +from django.utils.text import slugify + import factory from zgw_consumers.constants import APITypes, AuthTypes from zgw_consumers.test.factories import ServiceFactory @@ -7,6 +9,7 @@ class ZGWApiGroupConfigFactory(factory.django.DjangoModelFactory): name = factory.Sequence(lambda n: "ZGW API set %03d" % n) + identifier = factory.LazyAttribute(lambda o: slugify(o.name)) zrc_service = factory.SubFactory( "zgw_consumers.test.factories.ServiceFactory", api_type=APITypes.zrc ) diff --git a/src/openforms/registrations/contrib/zgw_apis/tests/test_migrations.py b/src/openforms/registrations/contrib/zgw_apis/tests/test_migrations.py index 51bdd2dd48..f1631ef6e9 100644 --- a/src/openforms/registrations/contrib/zgw_apis/tests/test_migrations.py +++ b/src/openforms/registrations/contrib/zgw_apis/tests/test_migrations.py @@ -43,3 +43,27 @@ def test_set_explicit_objects_api_groups_on_zgw_api_group_configs(self): backend_with_api_group.options["objects_api_group"], self.objects_api_group.pk, ) + + +class AddZGWApiGroupConfigIdentifierTests(TestMigrations): + app = "zgw_apis" + migrate_from = "0015_explicit_objects_api_groups" + migrate_to = "0016_zgwapigroupconfig_identifier" + + def setUpBeforeMigration(self, apps: StateApps): + ZGWApiGroupConfig = apps.get_model("zgw_apis", "ZGWApiGroupConfig") + ZGWApiGroupConfig.objects.create(name="Group name") + ZGWApiGroupConfig.objects.create(name="Duplicate name") + ZGWApiGroupConfig.objects.create(name="Duplicate name") + + def test_identifiers_generated(self): + ZGWApiGroupConfig = self.apps.get_model("zgw_apis", "ZGWApiGroupConfig") + groups = ZGWApiGroupConfig.objects.all() + + self.assertEqual(groups.count(), 3) + + group1, group2, group3 = groups + + self.assertEqual(group1.identifier, "group-name") + self.assertEqual(group2.identifier, "duplicate-name") + self.assertEqual(group3.identifier, "duplicate-name-1") From 680438a00c3233ba55007820846f05c99af78802 Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Mon, 9 Dec 2024 09:40:39 +0100 Subject: [PATCH 2/5] :sparkles: [#4789] ConfigurationStep for ZGW API registration config this step relies on the previously added ServiceConfigurationStep and can be used to set up the necessary configuration for the ZGW API registration backend --- src/openforms/conf/base.py | 1 + .../zgw_apis/setup_configuration/__init__.py | 0 .../zgw_apis/setup_configuration/models.py | 48 +++++++++++++++++ .../zgw_apis/setup_configuration/steps.py | 53 +++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/openforms/registrations/contrib/zgw_apis/setup_configuration/__init__.py create mode 100644 src/openforms/registrations/contrib/zgw_apis/setup_configuration/models.py create mode 100644 src/openforms/registrations/contrib/zgw_apis/setup_configuration/steps.py diff --git a/src/openforms/conf/base.py b/src/openforms/conf/base.py index 3b35decec6..d712991037 100644 --- a/src/openforms/conf/base.py +++ b/src/openforms/conf/base.py @@ -1212,6 +1212,7 @@ SETUP_CONFIGURATION_STEPS = [ "zgw_consumers.contrib.setup_configuration.steps.ServiceConfigurationStep", "openforms.contrib.objects_api.setup_configuration.steps.ObjectsAPIConfigurationStep", + "openforms.registrations.contrib.zgw_apis.setup_configuration.steps.ZGWApiConfigurationStep", ] # diff --git a/src/openforms/registrations/contrib/zgw_apis/setup_configuration/__init__.py b/src/openforms/registrations/contrib/zgw_apis/setup_configuration/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/openforms/registrations/contrib/zgw_apis/setup_configuration/models.py b/src/openforms/registrations/contrib/zgw_apis/setup_configuration/models.py new file mode 100644 index 0000000000..83520aa272 --- /dev/null +++ b/src/openforms/registrations/contrib/zgw_apis/setup_configuration/models.py @@ -0,0 +1,48 @@ +from django_setup_configuration.fields import DjangoModelRef +from django_setup_configuration.models import ConfigurationModel +from pydantic import Field + +from openforms.registrations.contrib.zgw_apis.models import ZGWApiGroupConfig + + +class SingleZGWApiGroupConfigModel(ConfigurationModel): + zaken_service_identifier: str = DjangoModelRef(ZGWApiGroupConfig, "zrc_service") + documenten_service_identifier: str = DjangoModelRef( + ZGWApiGroupConfig, + "drc_service", + ) + catalogi_service_identifier: str = DjangoModelRef( + ZGWApiGroupConfig, + "ztc_service", + ) + + # Slightly more descriptive name + objects_api_json_content_template: str = DjangoModelRef( + ZGWApiGroupConfig, "content_json" + ) + + # FIXME choices and blank=True doesn't seem to be picked up properly + zaak_vertrouwelijkheidaanduiding: str = DjangoModelRef( + ZGWApiGroupConfig, + "zaak_vertrouwelijkheidaanduiding", + default="", + ) + doc_vertrouwelijkheidaanduiding: str = DjangoModelRef( + ZGWApiGroupConfig, "doc_vertrouwelijkheidaanduiding", default="" + ) + + class Meta: + django_model_refs = { + ZGWApiGroupConfig: [ + "name", + "identifier", + "catalogue_domain", + "catalogue_rsin", + "organisatie_rsin", + "auteur", + ] + } + + +class ZGWApiGroupConfigModel(ConfigurationModel): + groups: list[SingleZGWApiGroupConfigModel] = Field(default_factory=list) diff --git a/src/openforms/registrations/contrib/zgw_apis/setup_configuration/steps.py b/src/openforms/registrations/contrib/zgw_apis/setup_configuration/steps.py new file mode 100644 index 0000000000..f803e0fb7b --- /dev/null +++ b/src/openforms/registrations/contrib/zgw_apis/setup_configuration/steps.py @@ -0,0 +1,53 @@ +from django_setup_configuration.configuration import BaseConfigurationStep +from zgw_consumers.models import Service + +from openforms.registrations.contrib.zgw_apis.models import ZGWApiGroupConfig + +from .models import SingleZGWApiGroupConfigModel, ZGWApiGroupConfigModel + + +def get_service(slug: str) -> Service: + """ + Try to find a Service and re-raise DoesNotExist with the identifier to make debugging + easier + """ + try: + return Service.objects.get(slug=slug) + except Service.DoesNotExist as e: + raise Service.DoesNotExist(f"{str(e)} (identifier = {slug})") + + +class ZGWApiConfigurationStep(BaseConfigurationStep[ZGWApiGroupConfigModel]): + """ + Configure configuration groups for the ZGW API backend + """ + + verbose_name = "Configuration to set up ZGW API registration backend services" + config_model = ZGWApiGroupConfigModel + namespace = "zgw_api" + enable_setting = "zgw_api_config_enable" + + def execute(self, model: ZGWApiGroupConfigModel): + config: SingleZGWApiGroupConfigModel + for config in model.groups: + # setup_configuration typing doesn't work for `django_model_refs` yet, + # hence the type: ignores + # (https://github.com/maykinmedia/django-setup-configuration/issues/25) + defaults = { + "name": config.name, # type: ignore + "zrc_service": get_service(config.zaken_service_identifier), + "drc_service": get_service(config.documenten_service_identifier), + "ztc_service": get_service(config.catalogi_service_identifier), + "catalogue_domain": config.catalogue_domain, # type: ignore + "catalogue_rsin": config.catalogue_rsin, # type: ignore + "organisatie_rsin": config.organisatie_rsin, # type: ignore + "zaak_vertrouwelijkheidaanduiding": config.zaak_vertrouwelijkheidaanduiding, + "doc_vertrouwelijkheidaanduiding": config.doc_vertrouwelijkheidaanduiding, + "auteur": config.auteur, # type: ignore + "content_json": config.objects_api_json_content_template, + } + + ZGWApiGroupConfig.objects.update_or_create( + identifier=config.identifier, # type: ignore + defaults=defaults, + ) From 49a40511c11ed27e3254174d7872089b7d6385e1 Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Mon, 9 Dec 2024 09:44:01 +0100 Subject: [PATCH 3/5] :white_check_mark: [#4789] Add tests for ZGWApiConfigurationStep --- .../contrib/zgw_apis/tests/factories.py | 4 +- .../tests/setup_configuration/__init__.py | 0 .../files/setup_config.yaml | 32 +++ .../files/setup_config_all_fields.yaml | 23 ++ .../files/setup_config_required_fields.yaml | 9 + .../test_zgw_api_config.py | 222 ++++++++++++++++++ .../contrib/zgw_apis/tests/test_migrations.py | 2 +- 7 files changed, 288 insertions(+), 4 deletions(-) create mode 100644 src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/__init__.py create mode 100644 src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config.yaml create mode 100644 src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config_all_fields.yaml create mode 100644 src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config_required_fields.yaml create mode 100644 src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/test_zgw_api_config.py diff --git a/src/openforms/registrations/contrib/zgw_apis/tests/factories.py b/src/openforms/registrations/contrib/zgw_apis/tests/factories.py index 719fe3fb75..f795295307 100644 --- a/src/openforms/registrations/contrib/zgw_apis/tests/factories.py +++ b/src/openforms/registrations/contrib/zgw_apis/tests/factories.py @@ -1,5 +1,3 @@ -from django.utils.text import slugify - import factory from zgw_consumers.constants import APITypes, AuthTypes from zgw_consumers.test.factories import ServiceFactory @@ -9,7 +7,7 @@ class ZGWApiGroupConfigFactory(factory.django.DjangoModelFactory): name = factory.Sequence(lambda n: "ZGW API set %03d" % n) - identifier = factory.LazyAttribute(lambda o: slugify(o.name)) + identifier = factory.Sequence(lambda n: f"zgw-api-group-{n}") zrc_service = factory.SubFactory( "zgw_consumers.test.factories.ServiceFactory", api_type=APITypes.zrc ) diff --git a/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/__init__.py b/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config.yaml b/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config.yaml new file mode 100644 index 0000000000..520a5d83f6 --- /dev/null +++ b/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config.yaml @@ -0,0 +1,32 @@ +zgw_api_config_enable: True +zgw_api: + groups: + - name: Config 1 + identifier: config-1 + zaken_service_identifier: zaken-test + documenten_service_identifier: documenten-test + catalogi_service_identifier: catalogi-test + catalogue_domain: TEST + catalogue_rsin: "000000000" + organisatie_rsin: "000000000" + zaak_vertrouwelijkheidaanduiding: zaakvertrouwelijk + doc_vertrouwelijkheidaanduiding: openbaar + auteur: John Doe + objects_api_json_content_template: | + { + "data": {% json_summary %}, + "type": "{{ productaanvraag_type }}", + "bsn": "{{ variables.auth_bsn }}", + "submission_id": "{{ submission.kenmerk }}", + "language_code": "{{ submission.language_code }}", + "custom_field": "foo" + } + - name: Config 2 + identifier: config-2 + zaken_service_identifier: zaken-test + documenten_service_identifier: documenten-test + catalogi_service_identifier: catalogi-test + catalogue_domain: OTHER + catalogue_rsin: "000000000" + organisatie_rsin: "000000000" + auteur: Jane Doe \ No newline at end of file diff --git a/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config_all_fields.yaml b/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config_all_fields.yaml new file mode 100644 index 0000000000..8ce6667fba --- /dev/null +++ b/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config_all_fields.yaml @@ -0,0 +1,23 @@ +zgw_api_config_enable: True +zgw_api: + groups: + - name: Config 1 + identifier: config-1 + zaken_service_identifier: zaken-test + documenten_service_identifier: documenten-test + catalogi_service_identifier: catalogi-test + catalogue_domain: TEST + catalogue_rsin: "000000000" + organisatie_rsin: "000000000" + zaak_vertrouwelijkheidaanduiding: zaakvertrouwelijk + doc_vertrouwelijkheidaanduiding: openbaar + auteur: John Doe + objects_api_json_content_template: | + { + "data": {% json_summary %}, + "type": "{{ productaanvraag_type }}", + "bsn": "{{ variables.auth_bsn }}", + "submission_id": "{{ submission.kenmerk }}", + "language_code": "{{ submission.language_code }}", + "custom_field": "foo" + } \ No newline at end of file diff --git a/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config_required_fields.yaml b/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config_required_fields.yaml new file mode 100644 index 0000000000..ba283093de --- /dev/null +++ b/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/files/setup_config_required_fields.yaml @@ -0,0 +1,9 @@ +zgw_api_config_enable: True +zgw_api: + groups: + - name: Config 1 + identifier: config-1 + zaken_service_identifier: zaken-test + documenten_service_identifier: documenten-test + catalogi_service_identifier: catalogi-test + auteur: Jane Doe diff --git a/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/test_zgw_api_config.py b/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/test_zgw_api_config.py new file mode 100644 index 0000000000..bc0f3b0441 --- /dev/null +++ b/src/openforms/registrations/contrib/zgw_apis/tests/setup_configuration/test_zgw_api_config.py @@ -0,0 +1,222 @@ +import textwrap +from pathlib import Path + +from django.test import TestCase + +from django_setup_configuration.test_utils import execute_single_step +from zgw_consumers.api_models.constants import VertrouwelijkheidsAanduidingen +from zgw_consumers.constants import APITypes, AuthTypes +from zgw_consumers.models import Service +from zgw_consumers.test.factories import ServiceFactory + +from openforms.registrations.contrib.zgw_apis.models import ( + ZGWApiGroupConfig, + get_content_text, +) +from openforms.registrations.contrib.zgw_apis.setup_configuration.steps import ( + ZGWApiConfigurationStep, +) +from openforms.registrations.contrib.zgw_apis.tests.factories import ( + ZGWApiGroupConfigFactory, +) + +TEST_FILES = (Path(__file__).parent / "files").resolve() +CONFIG_FILE_PATH = str(TEST_FILES / "setup_config.yaml") +CONFIG_FILE_PATH_REQUIRED_FIELDS = str(TEST_FILES / "setup_config_required_fields.yaml") +CONFIG_FILE_PATH_ALL_FIELDS = str(TEST_FILES / "setup_config_all_fields.yaml") + + +class ZGWApiConfigurationStepTests(TestCase): + maxDiff = None + + @classmethod + def setUpTestData(cls): + super().setUpTestData() + + cls.zaken_service = ServiceFactory.create( + slug="zaken-test", + label="Zaken API test", + api_root="http://localhost:8003/zaken/api/v1/", + api_type=APITypes.zrc, + auth_type=AuthTypes.zgw, + client_id="test_client_id", + secret="test_secret_key", + ) + cls.documenten_service = ServiceFactory.create( + slug="documenten-test", + label="Documenten API test", + api_root="http://localhost:8003/documenten/api/v1/", + api_type=APITypes.drc, + auth_type=AuthTypes.zgw, + client_id="test_client_id", + secret="test_secret_key", + ) + cls.catalogi_service = ServiceFactory.create( + slug="catalogi-test", + label="Catalogi API test", + api_root="http://localhost:8003/catalogi/api/v1/", + api_type=APITypes.ztc, + auth_type=AuthTypes.zgw, + client_id="test_client_id", + secret="test_secret_key", + ) + + def test_execute_success(self): + execute_single_step(ZGWApiConfigurationStep, yaml_source=CONFIG_FILE_PATH) + + self.assertEqual(ZGWApiGroupConfig.objects.count(), 2) + + config1, config2 = ZGWApiGroupConfig.objects.order_by("pk") + + self.assertEqual(config1.name, "Config 1") + self.assertEqual(config1.identifier, "config-1") + self.assertEqual(config1.zrc_service, self.zaken_service) + self.assertEqual(config1.drc_service, self.documenten_service) + self.assertEqual(config1.ztc_service, self.catalogi_service) + self.assertEqual(config1.catalogue_domain, "TEST") + self.assertEqual(config1.catalogue_rsin, "000000000") + self.assertEqual(config1.organisatie_rsin, "000000000") + self.assertEqual( + config1.zaak_vertrouwelijkheidaanduiding, + VertrouwelijkheidsAanduidingen.zaakvertrouwelijk, + ) + self.assertEqual( + config1.doc_vertrouwelijkheidaanduiding, + VertrouwelijkheidsAanduidingen.openbaar, + ) + + expected_json = textwrap.dedent( + """\ + { + "data": {% json_summary %}, + "type": "{{ productaanvraag_type }}", + "bsn": "{{ variables.auth_bsn }}", + "submission_id": "{{ submission.kenmerk }}", + "language_code": "{{ submission.language_code }}", + "custom_field": "foo" + } + """ + ) + + self.assertEqual(config1.content_json, expected_json) + + self.assertEqual(config2.name, "Config 2") + self.assertEqual(config2.identifier, "config-2") + self.assertEqual(config2.zrc_service, self.zaken_service) + self.assertEqual(config2.drc_service, self.documenten_service) + self.assertEqual(config2.ztc_service, self.catalogi_service) + self.assertEqual(config2.catalogue_domain, "OTHER") + self.assertEqual(config2.catalogue_rsin, "000000000") + self.assertEqual(config2.organisatie_rsin, "000000000") + self.assertEqual(config2.zaak_vertrouwelijkheidaanduiding, "") + self.assertEqual(config2.doc_vertrouwelijkheidaanduiding, "") + self.assertEqual(config2.content_json, get_content_text()) + + def test_execute_update_existing_config(self): + ZGWApiGroupConfigFactory.create(name="old name", identifier="config-1") + + execute_single_step(ZGWApiConfigurationStep, yaml_source=CONFIG_FILE_PATH) + + self.assertEqual(ZGWApiGroupConfig.objects.count(), 2) + + config1, config2 = ZGWApiGroupConfig.objects.order_by("pk") + + self.assertEqual(config1.name, "Config 1") + self.assertEqual(config1.identifier, "config-1") + + self.assertEqual(config2.name, "Config 2") + self.assertEqual(config2.identifier, "config-2") + + def test_execute_with_required_fields(self): + execute_single_step( + ZGWApiConfigurationStep, yaml_source=CONFIG_FILE_PATH_REQUIRED_FIELDS + ) + + self.assertEqual(ZGWApiGroupConfig.objects.count(), 1) + + config = ZGWApiGroupConfig.objects.get() + + self.assertEqual(config.name, "Config 1") + self.assertEqual(config.identifier, "config-1") + self.assertEqual(config.zrc_service, self.zaken_service) + self.assertEqual(config.drc_service, self.documenten_service) + self.assertEqual(config.ztc_service, self.catalogi_service) + + self.assertEqual(config.catalogue_domain, "") + self.assertEqual(config.catalogue_rsin, "") + self.assertEqual(config.organisatie_rsin, "") + self.assertEqual(config.zaak_vertrouwelijkheidaanduiding, "") + self.assertEqual(config.doc_vertrouwelijkheidaanduiding, "") + self.assertEqual(config.content_json, get_content_text()) + + def test_execute_with_all_fields(self): + execute_single_step( + ZGWApiConfigurationStep, yaml_source=CONFIG_FILE_PATH_ALL_FIELDS + ) + + self.assertEqual(ZGWApiGroupConfig.objects.count(), 1) + + config = ZGWApiGroupConfig.objects.get() + + self.assertEqual(config.name, "Config 1") + self.assertEqual(config.identifier, "config-1") + self.assertEqual(config.zrc_service, self.zaken_service) + self.assertEqual(config.drc_service, self.documenten_service) + self.assertEqual(config.ztc_service, self.catalogi_service) + self.assertEqual(config.catalogue_domain, "TEST") + self.assertEqual(config.catalogue_rsin, "000000000") + self.assertEqual(config.organisatie_rsin, "000000000") + self.assertEqual( + config.zaak_vertrouwelijkheidaanduiding, + VertrouwelijkheidsAanduidingen.zaakvertrouwelijk, + ) + self.assertEqual( + config.doc_vertrouwelijkheidaanduiding, + VertrouwelijkheidsAanduidingen.openbaar, + ) + + expected_json = textwrap.dedent( + """\ + { + "data": {% json_summary %}, + "type": "{{ productaanvraag_type }}", + "bsn": "{{ variables.auth_bsn }}", + "submission_id": "{{ submission.kenmerk }}", + "language_code": "{{ submission.language_code }}", + "custom_field": "foo" + }""" + ) + + self.assertEqual(config.content_json, expected_json) + + def test_execute_is_idempotent(self): + self.assertFalse(ZGWApiGroupConfig.objects.exists()) + + with self.subTest("run step first time"): + execute_single_step( + ZGWApiConfigurationStep, yaml_source=CONFIG_FILE_PATH_ALL_FIELDS + ) + + self.assertEqual(ZGWApiGroupConfig.objects.count(), 1) + + with self.subTest("run step second time"): + execute_single_step( + ZGWApiConfigurationStep, yaml_source=CONFIG_FILE_PATH_ALL_FIELDS + ) + + # no additional configs created, but existing one updated + self.assertEqual(ZGWApiGroupConfig.objects.count(), 1) + + def test_execute_service_not_found_raises_error(self): + self.zaken_service.delete() + + with self.assertRaisesMessage( + Service.DoesNotExist, + "Service matching query does not exist. (identifier = zaken-test)", + ): + execute_single_step( + ZGWApiConfigurationStep, + yaml_source=CONFIG_FILE_PATH_REQUIRED_FIELDS, + ) + + self.assertEqual(ZGWApiGroupConfig.objects.count(), 0) diff --git a/src/openforms/registrations/contrib/zgw_apis/tests/test_migrations.py b/src/openforms/registrations/contrib/zgw_apis/tests/test_migrations.py index f1631ef6e9..9d94186cb7 100644 --- a/src/openforms/registrations/contrib/zgw_apis/tests/test_migrations.py +++ b/src/openforms/registrations/contrib/zgw_apis/tests/test_migrations.py @@ -58,7 +58,7 @@ def setUpBeforeMigration(self, apps: StateApps): def test_identifiers_generated(self): ZGWApiGroupConfig = self.apps.get_model("zgw_apis", "ZGWApiGroupConfig") - groups = ZGWApiGroupConfig.objects.all() + groups = ZGWApiGroupConfig.objects.order_by("pk") self.assertEqual(groups.count(), 3) From df117af3e6081f7bdd29fabda831df53e94079d1 Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Mon, 2 Dec 2024 13:58:39 +0100 Subject: [PATCH 4/5] :whale: [#4789] Add example data for ZGW config step --- docker/setup_configuration/data.yaml | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docker/setup_configuration/data.yaml b/docker/setup_configuration/data.yaml index dbb99974b2..430656dd7e 100644 --- a/docker/setup_configuration/data.yaml +++ b/docker/setup_configuration/data.yaml @@ -15,6 +15,13 @@ zgw_consumers: auth_type: api_key header_key: Authorization header_value: Token 7657474c3d75f56ae0abd0d1bf7994b09964dca9 + - identifier: zaken-test + label: Zaken API test + api_root: http://openzaak-web.local:8000/zaken/api/v1/ + api_type: zrc + auth_type: zgw + client_id: test_client_id + secret: test_secret_key - identifier: documenten-test label: Documenten API test api_root: http://openzaak-web.local:8000/documenten/api/v1/ @@ -54,3 +61,27 @@ objects_api: catalogue_domain: OTHER catalogue_rsin: "000000000" organisatie_rsin: "000000000" + +zgw_api_config_enable: True +zgw_api: + groups: + - name: Config 1 + identifier: config-1 + zaken_service_identifier: zaken-test + documenten_service_identifier: documenten-test + catalogi_service_identifier: catalogi-test + catalogue_domain: TEST + catalogue_rsin: "000000000" + organisatie_rsin: "000000000" + zaak_vertrouwelijkheidaanduiding: zaakvertrouwelijk + doc_vertrouwelijkheidaanduiding: openbaar + auteur: John Doe + objects_api_json_content_template: | + { + "data": {% json_summary %}, + "type": "{{ productaanvraag_type }}", + "bsn": "{{ variables.auth_bsn }}", + "submission_id": "{{ submission.kenmerk }}", + "language_code": "{{ submission.language_code }}", + "custom_field": "foo" + } From 6635402c8f39fee5f9ae75607596ae979c77f2d3 Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Mon, 9 Dec 2024 09:51:29 +0100 Subject: [PATCH 5/5] :green_heart: Fix failing CI due to openapitools issue the generate-sdks job was failing due to some network calls that were performed when validating the OAS, this is avoided by specifying the version of the generator-cli in openapitools.json see also: OpenAPITools/openapi-generator-cli#802 --- .github/workflows/ci.yml | 3 --- openapitools.json | 7 +++++++ 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 openapitools.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2f5d627fa..ddb189895f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -556,9 +556,6 @@ jobs: run: npm install -g @openapitools/openapi-generator-cli@2.4.2 - name: Validate schema run: openapi-generator-cli validate -i ./openapi.yaml - - name: Set the version of openapi-generator which gets used - run: | - openapi-generator-cli version-manager set 7.0.0 - name: Generate Java client run: openapi-generator-cli generate -i ./openapi.yaml diff --git a/openapitools.json b/openapitools.json new file mode 100644 index 0000000000..8e697a4f57 --- /dev/null +++ b/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.0.0" + } +}