From ccd05ce535aa73d2faa5892e391b179c2e83b5f0 Mon Sep 17 00:00:00 2001 From: Sidney Richards Date: Tue, 4 Mar 2025 16:48:30 +0100 Subject: [PATCH] Ensure case contact form selects klanten backend from API group --- .../cms/cases/tests/test_contactform.py | 54 +++++++++++++++++-- src/open_inwoner/cms/cases/views/mixins.py | 8 ++- src/open_inwoner/cms/cases/views/status.py | 29 ++++++++-- 3 files changed, 82 insertions(+), 9 deletions(-) diff --git a/src/open_inwoner/cms/cases/tests/test_contactform.py b/src/open_inwoner/cms/cases/tests/test_contactform.py index e11ecede9d..afcd204dc9 100644 --- a/src/open_inwoner/cms/cases/tests/test_contactform.py +++ b/src/open_inwoner/cms/cases/tests/test_contactform.py @@ -1,9 +1,10 @@ +import uuid from unittest.mock import ANY, patch from django.conf import settings from django.contrib.auth import signals from django.core import mail -from django.test import override_settings +from django.test import Client, TestCase, override_settings from django.urls import reverse from django.utils.translation import gettext as _ @@ -31,7 +32,11 @@ from open_inwoner.openklant.tests.data import CONTACTMOMENTEN_ROOT, KLANTEN_ROOT from open_inwoner.openklant.tests.factories import OpenKlant2ConfigFactory from open_inwoner.openklant.tests.mocks import MockOpenKlant2Service -from open_inwoner.openzaak.models import CatalogusConfig, OpenZaakConfig +from open_inwoner.openzaak.models import ( + CatalogusConfig, + OpenZaakConfig, + ZGWApiGroupConfig, +) from open_inwoner.openzaak.tests.factories import ( ServiceFactory, ZaakTypeConfigFactory, @@ -530,6 +535,14 @@ def test_form_success_with_api_esuite( self._setUpOpenKlantMocks(m) response = self.app.get(self.case_detail_url, user=self.user) + + # Set the primary to the opposite API, to ensure we pick the connected + # backend from the ZGWApiGroup + self.klant_config.primary_backend = KlantenServiceType.OPENKLANT2.value + self.klant_config.save() + self.api_group.klant_backend = KlantenServiceType.ESUITE.value + self.api_group.save() + form = response.forms["contact-form"] form.action = reverse( "cases:case_detail_contact_form", @@ -595,8 +608,12 @@ def test_form_success_with_api_openklant( subject="oip_subject", ) - self.klant_config.primary_backend = KlantenServiceType.OPENKLANT2.value + # Set the primary to the opposite API, to ensure we pick the connected + # backend from the ZGWApiGroup + self.klant_config.primary_backend = KlantenServiceType.ESUITE.value self.klant_config.save() + self.api_group.klant_backend = KlantenServiceType.OPENKLANT2.value + self.api_group.save() response = self.app.get(self.case_detail_url, user=self.user) form = response.forms["contact-form"] @@ -886,3 +903,34 @@ def test_send_email_confirmation_is_configurable__send_disabled( form["question"] = "Sample text" response = form.submit() mock_send_confirm.assert_not_called() + + +@override_settings( + ROOT_URLCONF="open_inwoner.cms.tests.urls", MIDDLEWARE=PATCHED_MIDDLEWARE +) +class CasesContactFormInvalidParamsTestCase(TestCase): + def setUp(self) -> None: + super().setUp() + self.user = DigidUserFactory(bsn="900222086", email="foo@example.com") + self.client = Client() + self.client.force_login(self.user) + + def test_non_existent_zgw_api_group_yields_404(self): + fake_group_id = 8888 + self.assertFalse(ZGWApiGroupConfig.objects.filter(id=fake_group_id).exists()) + + for method in ("get", "post"): + with self.subTest(method): + action = getattr(self.client, method) + response = action( + reverse( + "cases:case_detail_contact_form", + kwargs={ + "object_id": str(uuid.uuid4()), + "api_group_id": fake_group_id, + }, + ), + user=self.user, + ) + + self.assertEqual(response.status_code, 404) diff --git a/src/open_inwoner/cms/cases/views/mixins.py b/src/open_inwoner/cms/cases/views/mixins.py index 278457daa9..873f975703 100644 --- a/src/open_inwoner/cms/cases/views/mixins.py +++ b/src/open_inwoner/cms/cases/views/mixins.py @@ -1,6 +1,7 @@ import logging from django.contrib.auth.mixins import AccessMixin, LoginRequiredMixin +from django.http import Http404 from django.template.response import TemplateResponse from django.utils.translation import gettext_lazy as _ @@ -62,7 +63,12 @@ def dispatch(self, request, *args, **kwargs): object_id := self.kwargs.get("object_id") ) if is_retrieving_case: - api_group = ZGWApiGroupConfig.objects.get(pk=api_group_id) + try: + api_group = ZGWApiGroupConfig.objects.get(pk=api_group_id) + except ZGWApiGroupConfig.DoesNotExist as exc: + logger.exception("Non-existent ZGWApiGroupConfig passed") + raise Http404 from exc + client = api_group.zaken_client self.case = client.fetch_single_case(object_id) if self.case: diff --git a/src/open_inwoner/cms/cases/views/status.py b/src/open_inwoner/cms/cases/views/status.py index e7fb5d5b08..cd07c102b5 100644 --- a/src/open_inwoner/cms/cases/views/status.py +++ b/src/open_inwoner/cms/cases/views/status.py @@ -914,6 +914,12 @@ class CaseContactFormView(CaseAccessMixin, LogMixin, FormView): form_class = CaseContactForm def post(self, request, *args, **kwargs): + try: + api_group = ZGWApiGroupConfig.objects.get(pk=self.kwargs["api_group_id"]) + except ZGWApiGroupConfig.DoesNotExist as exc: + logger.exception("Non-existent ZGWApiGroupConfig passed") + raise Http404 from exc + form = self.get_form() if form.is_valid(): @@ -933,7 +939,7 @@ def post(self, request, *args, **kwargs): send_confirmation = email_success if klant_config.register_contact_via_api: - api_success = self.register_by_api(form, config=klant_config) + api_success = self.register_by_api(form, api_group) if api_success: send_confirmation = klant_config.send_email_confirmation # else keep the send_confirmation if email set it @@ -1000,10 +1006,23 @@ def register_by_email(self, form, recipient_email): ) return False - def register_by_api(self, form, config: KlantenSysteemConfig): - if config.primary_backend == KlantenServiceType.ESUITE.value: - return self._register_via_esuite(form, config=ESuiteKlantConfig.get_solo()) - return self._register_via_openklant(form, config=OpenKlant2Config.get_solo()) + def register_by_api(self, form, api_group: ZGWApiGroupConfig): + if not api_group.klant_backend: + return + + match api_group.klant_backend: + case KlantenServiceType.ESUITE.value: + return self._register_via_esuite( + form, config=ESuiteKlantConfig.get_solo() + ) + case KlantenServiceType.OPENKLANT2.value: + return self._register_via_openklant( + form, config=OpenKlant2Config.get_solo() + ) + case _: + logger.error( + "Got non-existent klanten backend %s", api_group.klant_backend + ) def _register_via_openklant(self, form, config: OpenKlant2Config) -> bool: user = self.request.user