diff --git a/netbox_sys_plugin/api/serializers.py b/netbox_sys_plugin/api/serializers.py index d8a257908aa665887e4d7ba8b3546293839b7964..35af0e1441e210663a3fc7e5651d4688a30b124b 100644 --- a/netbox_sys_plugin/api/serializers.py +++ b/netbox_sys_plugin/api/serializers.py @@ -1,6 +1,5 @@ from rest_framework import serializers from virtualization.models import VirtualMachine, Cluster, ClusterType -from ipam.models import Service from netbox.api.fields import ChoiceField from dcim.api.nested_serializers import ( NestedDeviceSerializer, NestedDeviceRoleSerializer, NestedPlatformSerializer, NestedSiteSerializer, @@ -207,6 +206,12 @@ class WebhookSettingsSerializer(NetBoxModelSerializer): model = WebhookSettings fields = '__all__' + def validate(self, data): + # Validate uniqueness + if not self.partial and WebhookSettings.objects.exists(): + raise serializers.ValidationError("You can only have one webbook setting.") + return data + class ProviderTypeExtraConfigSerializer(NetBoxModelSerializer): id = serializers.IntegerField(read_only=True) extra_config_structure = serializers.JSONField() diff --git a/netbox_sys_plugin/tests/webhook_settings/test_webhook_settings_api.py b/netbox_sys_plugin/tests/webhook_settings/test_webhook_settings_api.py new file mode 100644 index 0000000000000000000000000000000000000000..5412fc728fe9232a75ce726249ff607f23d38477 --- /dev/null +++ b/netbox_sys_plugin/tests/webhook_settings/test_webhook_settings_api.py @@ -0,0 +1,209 @@ +"""SYS Plugin Webhook Settings API Test Case Class""" + +from users.models import ObjectPermission +from django.contrib.contenttypes.models import ContentType +from rest_framework import status +from netbox_sys_plugin.models import WebhookSettings +from ..base import BaseAPITestCase + +class WebhookSettingsApiTestCase(BaseAPITestCase): + """Test suite for WebhookSettings API""" + model = WebhookSettings + brief_fields = ["payload_url","http_content_type"] + + + @classmethod + def setUpTestData(cls): + + """Set up test data for WebhookSettings API""" + + # Data for valid creation + cls.valid_create_data = [ + { + "payload_url": "https://www.testAnother.com", + "http_content_type": "Test another http content type" + } + ] + + # Data for invalid creation + cls.invalid_create_data = [ + { + "payload_url": "Invalid URL", # Invalid URL + "http_content_type": "Test http content type" + }, + { + "payload_url": None, # Missing + "http_content_type": "Test structure" + + }, + { + "payload_url": "https://www.testAnother.com", + "http_content_type": None # Missing + }, + ] + + # Data for checking unique key + cls.valid_check_unique_data = [ + { + "payload_url": "https://www.test1.com", + "http_content_type": "Test http content type 1" + }, + { + "payload_url": "https://www.test2.com", + "http_content_type": "Test http content type 2" + } + ] + + def test_create_valid_webhook_settings(self): + """Test creating a valid webhook settings""" + + obj_perm = ObjectPermission( + name="Create Webhook Settings Permission", + actions=["add", "view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(WebhookSettings)) + + form_data = self.valid_create_data[0] + response = self.client.post(self._get_list_url(), form_data, format="json", **self.header) + + self.assertHttpStatus(response, status.HTTP_201_CREATED) + self.assertEqual(response.data["payload_url"], form_data["payload_url"]) + self.assertEqual(response.data["http_content_type"], form_data["http_content_type"]) + + def test_only_one_webhook_settings(self): + """Test the creation of 2 webhook settings""" + + # Create Webhook Settings + WebhookSettings.objects.create( + payload_url='https://www.test.com', + http_content_type='test http content type' + ) + + obj_perm = ObjectPermission( + name="Invalid Webhook Settings Permission", + actions=["add", "view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(WebhookSettings)) + + for form_data in self.valid_check_unique_data: + response = self.client.post(self._get_list_url(), form_data, format="json", **self.header) + self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST) + self.assertIn('You can only have one webbook setting',str(response.data)) + + def test_create_invalid_webhook_settings(self): + """Test creating invalid webhook settings""" + obj_perm = ObjectPermission( + name="Invalid Webhook Settings Permission", + actions=["add", "view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(WebhookSettings)) + + form_data = self.invalid_create_data[0] + response = self.client.post(self._get_list_url(), form_data, format="json", **self.header) + self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST) + self.assertIn('Enter a valid URL.',str(response.data)) + + form_data = self.invalid_create_data[1] + response = self.client.post(self._get_list_url(), form_data, format="json", **self.header) + self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST) + self.assertIn('This field may not be null.',str(response.data)) + + form_data = self.invalid_create_data[2] + response = self.client.post(self._get_list_url(), form_data, format="json", **self.header) + self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST) + self.assertIn('This field may not be null.',str(response.data)) + + def test_update_webhook_settings(self): + """Test updating an existing webhook settings""" + + # Create Webhook Settings + WebhookSettings.objects.create( + payload_url='https://www.test.com', + http_content_type='test http content type' + ) + + webhook_settings = WebhookSettings.objects.first() + obj_perm = ObjectPermission( + name="Update Webhook Settings Permission", + actions=["change", "view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(WebhookSettings)) + + update_data = {"payload_url": "https://www.testupdated.com"} + response = self.client.patch(self._get_detail_url(webhook_settings), update_data, format="json", **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + self.assertEqual(response.data["payload_url"], update_data["payload_url"]) + + def test_get_webhook_settings_list(self): + """Test fetching webhook settings list""" + + # Create Webhook Settings + WebhookSettings.objects.create( + payload_url='https://www.test.com', + http_content_type='test http content type' + ) + + obj_perm = ObjectPermission( + name="Create Webhook Settings Permission", + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(WebhookSettings)) + + response = self.client.get(self._get_list_url(), **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + self.assertGreaterEqual(len(response.data), 2) + + def test_get_single_webhook_settings(self): + """Test fetching a single webhook settings""" + + # Create Webhook Settings + WebhookSettings.objects.create( + payload_url='https://www.test.com', + http_content_type='test http content type' + ) + + obj_perm = ObjectPermission( + name="View Webhook Settings Permission", + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(WebhookSettings)) + + webhook_settings = WebhookSettings.objects.first() + response = self.client.get(self._get_detail_url(webhook_settings), **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + self.assertEqual(response.data["payload_url"], webhook_settings.payload_url) + self.assertEqual(response.data["http_content_type"], webhook_settings.http_content_type) + + def test_delete_webhook_settings(self): + """Test deleting a webhook settings""" + + # Create Webhook Settings + WebhookSettings.objects.create( + payload_url='https://www.test.com', + http_content_type='test http content type' + ) + + webhook_settings = WebhookSettings.objects.first() + obj_perm = ObjectPermission( + name="Delete Webhook Settings Permission", + actions=["delete"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(WebhookSettings)) + + response = self.client.delete(self._get_detail_url(webhook_settings), **self.header) + self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT) + self.assertFalse(WebhookSettings.objects.filter(id=webhook_settings.id).exists()) diff --git a/netbox_sys_plugin/tests/webhook_settings/test_webhook_settings_view.py b/netbox_sys_plugin/tests/webhook_settings/test_webhook_settings_view.py index 5e8e8f7ed1c4fd45d56636c3eff5989c4acbaf6b..21049522b1e9cd5ea7bbbef7296d6497d9c9874c 100644 --- a/netbox_sys_plugin/tests/webhook_settings/test_webhook_settings_view.py +++ b/netbox_sys_plugin/tests/webhook_settings/test_webhook_settings_view.py @@ -75,11 +75,11 @@ class WebhookSettingsFormTestCase( form.errors.get("http_content_type", []), ) - def test_create_more_than_one_webhook_settings(self): + def test_only_one_webhook_settings(self): """Test the creation of 2 webhook settings""" # pylint: disable=W0201 - self.vmMachineType1 = WebhookSettings.objects.create( + self.webhookSettings = WebhookSettings.objects.create( payload_url='https://www.test.com', http_content_type='test http content type')