From 410e1ec46a7b43af51fec356bde31e60d76425e4 Mon Sep 17 00:00:00 2001 From: denyshon Date: Thu, 19 Feb 2026 15:52:16 +0100 Subject: [PATCH] Switch ZendeskForm to ModelForm Switch ZendeskForm from Form to ModelForm to benefit from model validation. Specify SupportTicket.description max_length based on the Zendesk API. Set blank=True for SupportTicket.category to prevent a model validation error in case we decide to make this field optional. Adjust kitsune.customercare.tests.test_forms.ZendeskFormTests.test_send_with_no_category_selected to ignore a form validation error. --- kitsune/customercare/forms.py | 29 +++++++++++------------- kitsune/customercare/models.py | 4 ++-- kitsune/customercare/tests/test_forms.py | 3 +++ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/kitsune/customercare/forms.py b/kitsune/customercare/forms.py index 7d68b4ec072..a66361f80e4 100644 --- a/kitsune/customercare/forms.py +++ b/kitsune/customercare/forms.py @@ -80,7 +80,7 @@ ZENDESK_PRODUCT_SLUGS = {v: k for k, v in PRODUCT_SLUG_ALIASES.items()} -class ZendeskForm(forms.Form): +class ZendeskForm(forms.ModelForm): """Form for submitting a ticket to Zendesk.""" required_css_class = "required" @@ -112,6 +112,10 @@ class ZendeskForm(forms.Form): description = forms.CharField(label=_lazy("Tell us more"), widget=forms.Textarea()) country = forms.CharField(widget=forms.HiddenInput, required=False) + class Meta: + model = SupportTicket + fields = ["subject", "description", "category", "email", "os", "country", "update_channel", "policy_distribution"] + def __init__(self, *args, product, user=None, **kwargs): super().__init__(*args, **kwargs) @@ -188,6 +192,7 @@ def clean_email(self): def send(self, user, product): """Create a SupportTicket record and trigger async classification.""" + selected_category_slug = self.cleaned_data.get("category") zendesk_tags = [] @@ -232,21 +237,13 @@ def send(self, user, product): from kitsune.customercare.tasks import zendesk_submission_classifier from kitsune.customercare.utils import resolve_org_group - submission = SupportTicket.objects.create( - subject=self.cleaned_data["subject"], - description=self.cleaned_data["description"], - category=self.cleaned_data.get("category", ""), - email=self.cleaned_data["email"], - os=self.cleaned_data.get("os", ""), - country=self.cleaned_data.get("country", ""), - update_channel=self.cleaned_data.get("update_channel", ""), - policy_distribution=self.cleaned_data.get("policy_distribution", ""), - product=product, - user=user if (user and user.is_authenticated) else None, - org_group=resolve_org_group(user, product), - zendesk_tags=zendesk_tags, - submission_status=SupportTicket.STATUS_PENDING, - ) + self.instance.product = product + self.instance.user = user if (user and user.is_authenticated) else None + self.instance.org_group = resolve_org_group(user, product) + self.instance.zendesk_tags = zendesk_tags + self.instance.submission_status = SupportTicket.STATUS_PENDING + + submission = super().save() zendesk_submission_classifier.delay(submission.id) diff --git a/kitsune/customercare/models.py b/kitsune/customercare/models.py index 9201c31cabd..763df45306a 100644 --- a/kitsune/customercare/models.py +++ b/kitsune/customercare/models.py @@ -143,8 +143,8 @@ class SupportTicket(ModelBase): } subject = models.CharField(max_length=255) - description = models.TextField() - category = models.CharField(max_length=255) + description = models.TextField(max_length=65563) + category = models.CharField(max_length=255, blank=True, default="") email = models.EmailField() os = models.CharField(max_length=50, blank=True, default="") country = models.CharField(max_length=255, blank=True, default="") diff --git a/kitsune/customercare/tests/test_forms.py b/kitsune/customercare/tests/test_forms.py index 1d2544cbe71..8112e464abb 100644 --- a/kitsune/customercare/tests/test_forms.py +++ b/kitsune/customercare/tests/test_forms.py @@ -352,6 +352,9 @@ def test_send_with_no_category_selected(self, mock_task): "description": "Test description", "category": "", # Empty category } + # An empty category field will result in a form validation error in send()->save(). + # Since we don't care about the form, we'll just clear the errors to run send(). + form._errors = "" submission = form.send(self.user, self.vpn_product) self.assertIsInstance(submission, SupportTicket)