From 1b6b7602b3f972da42d83a06508dd3b4225f6fa5 Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:49:20 -0700 Subject: [PATCH 1/6] Enforce readonly name field for existing Test_Type instances in form --- dojo/forms.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dojo/forms.py b/dojo/forms.py index b2b39509933..000dec362a0 100644 --- a/dojo/forms.py +++ b/dojo/forms.py @@ -324,6 +324,17 @@ class Meta: model = Test_Type exclude = ["dynamically_generated"] + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + if self.instance.pk: + self.fields["name"].widget.attrs["readonly"] = True + + def clean_name(self): + if self.instance.pk: + return self.instance.name + return self.cleaned_data["name"] + class Development_EnvironmentForm(forms.ModelForm): class Meta: From 952a703a5e4af9de20201eed222cec8d1c6e1bf8 Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:49:30 -0700 Subject: [PATCH 2/6] Add TestTypeCreateSerializer and enforce readonly name field in TestTypeSerializer --- dojo/api_v2/serializers.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dojo/api_v2/serializers.py b/dojo/api_v2/serializers.py index 6bc18b5115f..9a17e4be985 100644 --- a/dojo/api_v2/serializers.py +++ b/dojo/api_v2/serializers.py @@ -1472,8 +1472,15 @@ class Meta: exclude = ("inherited_tags",) +class TestTypeCreateSerializer(serializers.ModelSerializer): + + class Meta: + model = Test_Type + exclude = ("dynamically_generated",) + + class TestTypeSerializer(serializers.ModelSerializer): - tags = TagListSerializerField(required=False) + name = serializers.ReadOnlyField() class Meta: model = Test_Type From a773672ce02cc0a8eccd6ab9c5a9f21eabcad99b Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:49:36 -0700 Subject: [PATCH 3/6] Add dynamic serializer selection in TestTypesViewSet for create action --- dojo/api_v2/views.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dojo/api_v2/views.py b/dojo/api_v2/views.py index 01318a70bc5..43be77262af 100644 --- a/dojo/api_v2/views.py +++ b/dojo/api_v2/views.py @@ -2263,6 +2263,11 @@ class TestTypesViewSet( def get_queryset(self): return Test_Type.objects.all().order_by("id") + def get_serializer_class(self): + if self.action == "create": + return serializers.TestTypeCreateSerializer + return serializers.TestTypeSerializer + # @extend_schema_view(**schema_with_prefetch()) # Nested models with prefetch make the response schema too long for Swagger UI From a6f0c259b95fda8a88ed8a184a888af9990ad7ea Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Wed, 14 Jan 2026 11:44:38 -0700 Subject: [PATCH 4/6] Update test payload to set 'active' field instead of 'name' --- unittests/test_rest_framework.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittests/test_rest_framework.py b/unittests/test_rest_framework.py index b379c01c2e2..f79406dfd1a 100644 --- a/unittests/test_rest_framework.py +++ b/unittests/test_rest_framework.py @@ -3450,7 +3450,7 @@ def __init__(self, *args, **kwargs): self.viewname = "test_type" self.viewset = TestTypesViewSet self.payload = { - "name": "Test_1", + "active": False, } self.update_fields = {"name": "Test_2"} self.test_type = TestType.CONFIGURATION_PERMISSIONS From b31e9f3f7d988fbcc136277f893e6b67e2a9b6cd Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Wed, 14 Jan 2026 12:06:41 -0700 Subject: [PATCH 5/6] Update TestTypeTest payload to use 'name' and modify update_fields to 'active' --- unittests/test_rest_framework.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unittests/test_rest_framework.py b/unittests/test_rest_framework.py index f79406dfd1a..a7b9f898ecf 100644 --- a/unittests/test_rest_framework.py +++ b/unittests/test_rest_framework.py @@ -3450,9 +3450,9 @@ def __init__(self, *args, **kwargs): self.viewname = "test_type" self.viewset = TestTypesViewSet self.payload = { - "active": False, + "name": "Test_1", } - self.update_fields = {"name": "Test_2"} + self.update_fields = {"active": False} self.test_type = TestType.CONFIGURATION_PERMISSIONS self.deleted_objects = 1 BaseClass.RESTEndpointTest.__init__(self, *args, **kwargs) From 3d07c9f575812cb78403ec724bdbe64caf149e9c Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Thu, 15 Jan 2026 10:01:08 -0700 Subject: [PATCH 6/6] Add test to verify 'name' field is read-only in TestType --- unittests/test_rest_framework.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/unittests/test_rest_framework.py b/unittests/test_rest_framework.py index a7b9f898ecf..7f2001dd193 100644 --- a/unittests/test_rest_framework.py +++ b/unittests/test_rest_framework.py @@ -3457,6 +3457,15 @@ def __init__(self, *args, **kwargs): self.deleted_objects = 1 BaseClass.RESTEndpointTest.__init__(self, *args, **kwargs) + def test_name_read_only(self): + current_objects = self.client.get(self.url, format="json").data + relative_url = self.url + "{}/".format(current_objects["results"][-1]["id"]) + payload = {"name": "New name"} + response = self.client.patch(relative_url, payload, format="json") + self.assertEqual(200, response.status_code, response.content[:1000]) + # See that the request was politley ignored and that name did not change + self.assertEqual(current_objects["results"][-1]["name"], response.data["name"]) + class ConfigurationPermissionTest(BaseClass.BaseClassTest): fixtures = ["dojo_testdata.json"]