From e80bdd3c97ddff198a3e10509c4987fe593fb400 Mon Sep 17 00:00:00 2001 From: Frederico Sequeira <frederico.sequeira@ext.ec.europa.eu> Date: Fri, 17 Jan 2025 16:09:18 +0000 Subject: [PATCH 1/6] =?UTF-8?q?=E2=9C=85=20Add=20API=20tests=20to=20Domain?= =?UTF-8?q?=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- netbox_sys_plugin/api/serializers.py | 12 +- netbox_sys_plugin/forms/machine.py | 2 +- .../tests/vm_domain_names/__init__.py | 0 .../test_vm_domain_names_api.py | 216 ++++++++++++++++++ 4 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 netbox_sys_plugin/tests/vm_domain_names/__init__.py create mode 100644 netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_api.py diff --git a/netbox_sys_plugin/api/serializers.py b/netbox_sys_plugin/api/serializers.py index 2c4bcbd..f9086f8 100644 --- a/netbox_sys_plugin/api/serializers.py +++ b/netbox_sys_plugin/api/serializers.py @@ -113,13 +113,21 @@ class DomainNamesSerializer(NetBoxModelSerializer): id = serializers.IntegerField(read_only=True) virtual_machine = NestedVirtualMachineSerializer(source='assigned_object', read_only=True) assigned_object_id = serializers.IntegerField(write_only=True) - assigned_object_type = serializers.CharField(write_only=True) - display = serializers.CharField(source="__str__") + assigned_object_type = serializers.PrimaryKeyRelatedField( + queryset=ContentType.objects.all(), + write_only=True, + ) + display = serializers.CharField(source="__str__",read_only=True) class Meta: model = DomainNames fields = '__all__' + def create(self, validated_data): + assigned_object_type = validated_data.pop("assigned_object_type") + validated_data["assigned_object_type"] = assigned_object_type + return super().create(validated_data) + class WebhookSettingsSerializer(NetBoxModelSerializer): id = serializers.IntegerField(read_only=True) diff --git a/netbox_sys_plugin/forms/machine.py b/netbox_sys_plugin/forms/machine.py index 36d18c3..2d9fb45 100644 --- a/netbox_sys_plugin/forms/machine.py +++ b/netbox_sys_plugin/forms/machine.py @@ -190,7 +190,7 @@ class DomainNamesForm(NetBoxModelForm): #Check if Virtual Machine is assigned corretly if not vm: raise ValidationError( - {"__all__": "Can't assign more than one Maintenance Window to the same Virtual Machine"}, + {"__all__": "Can't assign more than one group of domain names to the same Virtual Machine"}, ) def save(self, *args, **kwargs): diff --git a/netbox_sys_plugin/tests/vm_domain_names/__init__.py b/netbox_sys_plugin/tests/vm_domain_names/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_api.py b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_api.py new file mode 100644 index 0000000..9240b0d --- /dev/null +++ b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_api.py @@ -0,0 +1,216 @@ +"""SYS Plugin VM domain names API Test Case Class""" + +from users.models import ObjectPermission +from django.contrib.contenttypes.models import ContentType +from rest_framework import status +from virtualization.models import VirtualMachine, Cluster, ClusterType +from netbox_sys_plugin.models import DomainNames +from ..base import BaseAPITestCase + +class VirtualMachineMaintenanceApiTestCase(BaseAPITestCase): + """Test suite for VirtualMachineMaintenance API""" + model = DomainNames + brief_fields = ["domain_names", "assigned_object_id", "assigned_object_type"] + + + @classmethod + def setUpTestData(cls): + + """Set up test data for DomainNames API""" + cls.vm_ct = ContentType.objects.get_for_model(VirtualMachine) + + # Create a ClusterType + cls.cluster_type = ClusterType.objects.create(name="Test ClusterType") + + # Create a Cluster linked to the ClusterType + cls.cluster = Cluster.objects.create(name="Test Cluster", type=cls.cluster_type) + + # Create a VirtualMachine linked to the Cluster + cls.virtual_machine = VirtualMachine.objects.create( + name="Test VM", + status="active", + cluster=cls.cluster + ) + + # Create a VirtualMachine 2 linked to the Cluster + cls.virtual_machine2 = VirtualMachine.objects.create( + name="Test VM2", + status="active", + cluster=cls.cluster + ) + + # Create a VirtualMachine 3 linked to the Cluster + cls.virtual_machine3 = VirtualMachine.objects.create( + name="Test VM3", + status="active", + cluster=cls.cluster + ) + + # Create a VirtualMachine 4 linked to the Cluster + cls.virtual_machine4 = VirtualMachine.objects.create( + name="Test VM4", + status="active", + cluster=cls.cluster + ) + # Create a VirtualMachine 5 linked to the Cluster + cls.virtual_machine5 = VirtualMachine.objects.create( + name="Test VM5", + status="active", + cluster=cls.cluster + ) + # Create a VirtualMachine 6 linked to the Cluster + cls.virtual_machine6 = VirtualMachine.objects.create( + name="Test VM6", + status="active", + cluster=cls.cluster + ) + + # Create maintenance entries linked to the VirtualMachine + DomainNames.objects.create( + domain_names={'domain1':'ec.test.test','domain2':'ec.test2.test2'}, + assigned_object=cls.virtual_machine + ) + DomainNames.objects.create( + domain_names={'domain1':'ec.test.test','domain2':'ec.test2.test2'}, + assigned_object=cls.virtual_machine2 + ) + + # Data for valid creation + cls.valid_create_data = [ + { + "domain_names": {'domain1':'ec.test.test','domain2':'ec.test2.test2'}, + "assigned_object_type": cls.vm_ct.pk, + "assigned_object_id": cls.virtual_machine3.id, + } + ] + + # Data for invalid creation + cls.invalid_create_data = [ + #{ + # "domain_names": "invalid-format", + # "assigned_object_type": cls.vm_ct.pk, + # "assigned_object_id": cls.virtual_machine4.id, + #}, + { + "domain_names": {'domain1':'ec.test.test','domain2':'ec.test2.test2'}, + "assigned_object_type": cls.vm_ct.pk, + "assigned_object_id": None, # Missing VirtualMachine + }, + ] + + # Data for checking unique key + cls.valid_check_unique_data = [ + { + "domain_names": {'domain1':'ec.test.test','domain2':'ec.test2.test2'}, + "assigned_object_type": cls.vm_ct.pk, + "assigned_object_id": cls.virtual_machine6.id, # Same Virtual Machine + }, + { + "domain_names": {'domain1':'ec.test.test','domain2':'ec.test2.test2'}, + "assigned_object_type": cls.vm_ct.pk, + "assigned_object_id": cls.virtual_machine6.id, # Same Virtual Machine + } + ] + + def test_create_valid_domain_names(self): + """Test creating a valid Domain Names""" + obj_perm = ObjectPermission( + name="Create Domain Names Permission", + actions=["add", "view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(DomainNames)) + + 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["domain_names"], form_data["domain_names"]) + + def test_maintenance_window_unique_key(self): + """Test maintenance windows unique key""" + obj_perm = ObjectPermission( + name="Invalid Maintenance Permission", + actions=["add", "view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(DomainNames)) + + 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) + + def test_create_invalid_domain_names(self): + """Test creating invalid domain names""" + obj_perm = ObjectPermission( + name="Invalid domain names Permission", + actions=["add", "view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(DomainNames)) + + for form_data in self.invalid_create_data: + response = self.client.post(self._get_list_url(), form_data, format="json", **self.header) + self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST) + + def test_update_domain_names(self): + """Test updating an existing domain names""" + domain_names = DomainNames.objects.first() + obj_perm = ObjectPermission( + name="Update domain names Permission", + actions=["change", "view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(DomainNames)) + + update_data = {'domain_names': {'domain1':'ec.test.test','domain2':'ec.test2.test2'}} + response = self.client.patch(self._get_detail_url(domain_names), update_data, format="json", **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + self.assertEqual(response.data["domain_names"], update_data["domain_names"]) + + def test_delete_domain_names(self): + """Test deleting a domain names""" + maintenance = DomainNames.objects.first() + obj_perm = ObjectPermission( + name="Delete Maintenance Permission", + actions=["delete"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(DomainNames)) + + response = self.client.delete(self._get_detail_url(maintenance), **self.header) + self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT) + self.assertFalse(DomainNames.objects.filter(id=maintenance.id).exists()) + + def test_get_all_maintenance_windows(self): + """Test fetching all maintenance windows""" + obj_perm = ObjectPermission( + name="View Maintenance Permission", + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(DomainNames)) + + 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_domain_names(self): + """Test fetching a single domain names""" + obj_perm = ObjectPermission( + name="View domain names Permission", + actions=["view"], + ) + obj_perm.save() + obj_perm.users.add(self.user) + obj_perm.object_types.add(ContentType.objects.get_for_model(DomainNames)) + + domain_names = DomainNames.objects.first() + response = self.client.get(self._get_detail_url(domain_names), **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + self.assertEqual(response.data["domain_names"], domain_names.domain_names) -- GitLab From 2b24f4134da9aa0af1c0cbd61a758eab6ecfd776 Mon Sep 17 00:00:00 2001 From: Frederico Sequeira <frederico.sequeira@ext.ec.europa.eu> Date: Fri, 17 Jan 2025 17:10:02 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=E2=9C=85=20=F0=9F=90=9B=20Add=20working=20?= =?UTF-8?q?API=20tests=20and=20bug=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- netbox_sys_plugin/forms/machine.py | 8 ++- .../0004_alter_domainnames_domain_names.py | 19 +++++++ netbox_sys_plugin/models/machine.py | 2 +- .../test_provider_type_extra_config_view.py | 2 +- .../test_vm_domain_names_api.py | 51 +++++++++++-------- 5 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 netbox_sys_plugin/migrations/0004_alter_domainnames_domain_names.py diff --git a/netbox_sys_plugin/forms/machine.py b/netbox_sys_plugin/forms/machine.py index 2d9fb45..e78e861 100644 --- a/netbox_sys_plugin/forms/machine.py +++ b/netbox_sys_plugin/forms/machine.py @@ -152,7 +152,7 @@ class DomainNamesForm(NetBoxModelForm): ) domain_names = JSONField( label=_('Domain Names'), - required=False + required=True ) def __init__(self, *args, **kwargs): @@ -186,6 +186,7 @@ class DomainNamesForm(NetBoxModelForm): super().clean() vm = self.cleaned_data.get("virtual_machine") + domain_names = self.cleaned_data.get("domain_names") #Check if Virtual Machine is assigned corretly if not vm: @@ -193,6 +194,11 @@ class DomainNamesForm(NetBoxModelForm): {"__all__": "Can't assign more than one group of domain names to the same Virtual Machine"}, ) + if not domain_names: + raise ValidationError( + {"__all__": "Domain names should not be empty"}, + ) + def save(self, *args, **kwargs): """Set assigned object and save""" # Set assigned object diff --git a/netbox_sys_plugin/migrations/0004_alter_domainnames_domain_names.py b/netbox_sys_plugin/migrations/0004_alter_domainnames_domain_names.py new file mode 100644 index 0000000..561c270 --- /dev/null +++ b/netbox_sys_plugin/migrations/0004_alter_domainnames_domain_names.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.16 on 2025-01-17 17:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('netbox_sys_plugin', '0003_alter_providertypeextraconfig_assigned_object_type_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='domainnames', + name='domain_names', + field=models.JSONField(blank=True, default={}), + preserve_default=False, + ), + ] diff --git a/netbox_sys_plugin/models/machine.py b/netbox_sys_plugin/models/machine.py index 6ffd6d9..9dc3495 100644 --- a/netbox_sys_plugin/models/machine.py +++ b/netbox_sys_plugin/models/machine.py @@ -120,7 +120,7 @@ class DomainNames(NetBoxModel): domain_names = models.JSONField( blank=True, - null=True, + null=False, ) assigned_object_type = models.ForeignKey( diff --git a/netbox_sys_plugin/tests/provider_type_extra_config/test_provider_type_extra_config_view.py b/netbox_sys_plugin/tests/provider_type_extra_config/test_provider_type_extra_config_view.py index 243f050..d0c1218 100644 --- a/netbox_sys_plugin/tests/provider_type_extra_config/test_provider_type_extra_config_view.py +++ b/netbox_sys_plugin/tests/provider_type_extra_config/test_provider_type_extra_config_view.py @@ -78,7 +78,7 @@ class ProviderTypeExtraConfigFormTestCase( def test_invalid_extra_config_format(self): """ - Test invalid maintenance window invalid format. + Test invalid extra config invalid format. """ # Create VLAN and VLANGroup for testing diff --git a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_api.py b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_api.py index 9240b0d..0117333 100644 --- a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_api.py +++ b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_api.py @@ -7,8 +7,8 @@ from virtualization.models import VirtualMachine, Cluster, ClusterType from netbox_sys_plugin.models import DomainNames from ..base import BaseAPITestCase -class VirtualMachineMaintenanceApiTestCase(BaseAPITestCase): - """Test suite for VirtualMachineMaintenance API""" +class VirtualMachinedomain_namesApiTestCase(BaseAPITestCase): + """Test suite for VirtualMachinedomain_names API""" model = DomainNames brief_fields = ["domain_names", "assigned_object_id", "assigned_object_type"] @@ -65,7 +65,7 @@ class VirtualMachineMaintenanceApiTestCase(BaseAPITestCase): cluster=cls.cluster ) - # Create maintenance entries linked to the VirtualMachine + # Create domain_names entries linked to the VirtualMachine DomainNames.objects.create( domain_names={'domain1':'ec.test.test','domain2':'ec.test2.test2'}, assigned_object=cls.virtual_machine @@ -86,11 +86,11 @@ class VirtualMachineMaintenanceApiTestCase(BaseAPITestCase): # Data for invalid creation cls.invalid_create_data = [ - #{ - # "domain_names": "invalid-format", - # "assigned_object_type": cls.vm_ct.pk, - # "assigned_object_id": cls.virtual_machine4.id, - #}, + { + "domain_names": None, + "assigned_object_type": cls.vm_ct.pk, + "assigned_object_id": cls.virtual_machine4.id, + }, { "domain_names": {'domain1':'ec.test.test','domain2':'ec.test2.test2'}, "assigned_object_type": cls.vm_ct.pk, @@ -127,10 +127,10 @@ class VirtualMachineMaintenanceApiTestCase(BaseAPITestCase): self.assertHttpStatus(response, status.HTTP_201_CREATED) self.assertEqual(response.data["domain_names"], form_data["domain_names"]) - def test_maintenance_window_unique_key(self): - """Test maintenance windows unique key""" + def test_domain_names_unique_key(self): + """Test domain names unique key""" obj_perm = ObjectPermission( - name="Invalid Maintenance Permission", + name="Invalid domain names Permission", actions=["add", "view"], ) obj_perm.save() @@ -151,9 +151,18 @@ class VirtualMachineMaintenanceApiTestCase(BaseAPITestCase): obj_perm.users.add(self.user) obj_perm.object_types.add(ContentType.objects.get_for_model(DomainNames)) - for form_data in self.invalid_create_data: - response = self.client.post(self._get_list_url(), form_data, format="json", **self.header) - self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST) + form_data = self.invalid_create_data[0] + print("form_data",form_data) + response = self.client.post(self._get_list_url(), form_data, format="json", **self.header) + print("RESPONSE API 1",response.data) + 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[1] + response = self.client.post(self._get_list_url(), form_data, format="json", **self.header) + print("RESPONSE API 2",response.data) + self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST) + self.assertIn('This field may not be null.',str(response.data)) def test_update_domain_names(self): """Test updating an existing domain names""" @@ -173,23 +182,23 @@ class VirtualMachineMaintenanceApiTestCase(BaseAPITestCase): def test_delete_domain_names(self): """Test deleting a domain names""" - maintenance = DomainNames.objects.first() + domain_names = DomainNames.objects.first() obj_perm = ObjectPermission( - name="Delete Maintenance Permission", + name="Delete domain names Permission", actions=["delete"], ) obj_perm.save() obj_perm.users.add(self.user) obj_perm.object_types.add(ContentType.objects.get_for_model(DomainNames)) - response = self.client.delete(self._get_detail_url(maintenance), **self.header) + response = self.client.delete(self._get_detail_url(domain_names), **self.header) self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT) - self.assertFalse(DomainNames.objects.filter(id=maintenance.id).exists()) + self.assertFalse(DomainNames.objects.filter(id=domain_names.id).exists()) - def test_get_all_maintenance_windows(self): - """Test fetching all maintenance windows""" + def test_get_all_domain_names(self): + """Test fetching all domain names""" obj_perm = ObjectPermission( - name="View Maintenance Permission", + name="View domain_names Permission", actions=["view"], ) obj_perm.save() -- GitLab From c6f182c5822885a42e73ec6e920eeb9fa08c6bb5 Mon Sep 17 00:00:00 2001 From: Frederico Sequeira <frederico.sequeira@ext.ec.europa.eu> Date: Mon, 20 Jan 2025 10:24:30 +0000 Subject: [PATCH 3/6] =?UTF-8?q?=E2=9C=85=20Add=20view=20test=20for=20Domai?= =?UTF-8?q?n=20Names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test_vm_domain_names_view.py | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py diff --git a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py new file mode 100644 index 0000000..c6f7b99 --- /dev/null +++ b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py @@ -0,0 +1,129 @@ +"""VM domain names Views Test Case Class""" + +from django.contrib.contenttypes.models import ContentType +from users.models import ObjectPermission +from virtualization.models import VirtualMachine, Cluster, ClusterType +from netbox_sys_plugin.models import DomainNames +from netbox_sys_plugin.forms import DomainNamesForm +from .. base import BaseModelViewTestCase + + + +class DomainNamesFormTestCase( + BaseModelViewTestCase, +): + """VM domain names Test Case Class""" + + model = DomainNames + form = DomainNamesForm + + + @classmethod + # pylint: disable=invalid-name + def setUpTestData(cls): + """ SetUp Test Data """ + #Create Cluster type, Cluster and VMs + vm_content_type = ContentType.objects.get_for_model(VirtualMachine) + cluster_type = ClusterType.objects.create(name="Test ClusterType1", slug="ClusterType1") + cluster = Cluster.objects.create(name="Test Cluster1", type=cluster_type) + virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=cluster) + virtual_machine2 = VirtualMachine.objects.create(name="Test VM2",status="active",cluster=cluster) + DomainNames.objects.create(domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]},assigned_object_type=vm_content_type, assigned_object_id=virtual_machine.pk) + DomainNames.objects.create(domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]},assigned_object_type=vm_content_type, assigned_object_id=virtual_machine2.pk) + + cls.form_data = { + "domain_names": {'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + "virtual_machine": virtual_machine2.pk, + + } + + def test_create_domain_names_with_no_assigment(self): + """Test the creation a VM domain names with no VM assignement""" + + form = DomainNamesForm(data= { + "domain_names": {'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + }) + + self.assertFalse(form.is_valid()) + # Setup object permissions for the test user + obj_perm = ObjectPermission( + name='Test permission', + actions=['add', 'change'] + ) + obj_perm.save() + obj_perm.users.add(self.user) # pylint: disable=no-member + obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) # pylint: disable=no-member + + + def test_create_vm_with_two_assigment(self): + """Test the assignment of 2 domain namess to the same VM """ + # pylint: disable=W0201 + self.vm_content_type = ContentType.objects.get_for_model(VirtualMachine) + # pylint: disable=W0201 + self.cluster_type = ClusterType.objects.create(name="Test ClusterType2", slug="ClusterType2") + # pylint: disable=W0201 + self.cluster = Cluster.objects.create(name="Test Cluster2", type=self.cluster_type) + # pylint: disable=W0201 + self.virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=self.cluster) + # pylint: disable=W0201 + self.domain_names = DomainNames.objects.create( + domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + assigned_object_type=self.vm_content_type, + assigned_object_id=self.virtual_machine.pk + ) + + form = DomainNamesForm(data= { + "domain_names": {'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + "virtual_machine": self.virtual_machine.pk, + }) + + self.assertFalse(form.is_valid()) + # Setup object permissions for the test user + obj_perm = ObjectPermission( + name='Test permission', + actions=['add', 'change'] + ) + obj_perm.save() + obj_perm.users.add(self.user) # pylint: disable=no-member + obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) # pylint: disable=no-member + + self.assertIn( + "Can't assign more than one group of domain names to the same Virtual Machine", + form.errors.get("__all__",[]) + ) + + def test_invalid_domain_names_format(self): + """ + Test invalid domain names invalid format. + """ + + # Create VLAN and VLANGroup for testing + # pylint: disable=W0201 + self.vm_content_type = ContentType.objects.get_for_model(VirtualMachine) + # pylint: disable=W0201 + self.cluster_type = ClusterType.objects.create(name="Test ClusterType3", slug="ClusterType3") + # pylint: disable=W0201 + self.cluster = Cluster.objects.create(name="Test Cluster3", type=self.cluster_type) + # pylint: disable=W0201 + self.virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=self.cluster) + + # Set up valid form data + self.valid_form_data = { + "virtual_machine": self.virtual_machine.pk, + "domain_names": {'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + "tags": "", + } + + invalid_form_data = self.valid_form_data.copy() + invalid_form_data["domain_names"] = "invalid" # Invalid format + form = self.form(data=invalid_form_data) + self.assertFalse(form.is_valid()) + self.assertIn( + "Enter a valid JSON.", + form.errors.get("domain_names", []), + ) + + def tearDown(self) -> None:# pylint: disable=invalid-name + """Method called immediately after the test method has been called and the result recorded.""" + DomainNames.objects.all().delete() + super().tearDown() -- GitLab From 1c50cc0d94c46cbde4ac9552393e8361e869b3a7 Mon Sep 17 00:00:00 2001 From: Frederico Sequeira <frederico.sequeira@ext.ec.europa.eu> Date: Mon, 20 Jan 2025 10:34:24 +0000 Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=9A=A8=20Fix=20lint=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/vm_domain_names/test_vm_domain_names_view.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py index c6f7b99..fb05def 100644 --- a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py +++ b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py @@ -28,8 +28,14 @@ class DomainNamesFormTestCase( cluster = Cluster.objects.create(name="Test Cluster1", type=cluster_type) virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=cluster) virtual_machine2 = VirtualMachine.objects.create(name="Test VM2",status="active",cluster=cluster) - DomainNames.objects.create(domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]},assigned_object_type=vm_content_type, assigned_object_id=virtual_machine.pk) - DomainNames.objects.create(domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]},assigned_object_type=vm_content_type, assigned_object_id=virtual_machine2.pk) + DomainNames.objects.create( + domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + assigned_object_type=vm_content_type, + assigned_object_id=virtual_machine.pk) + DomainNames.objects.create( + domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + assigned_object_type=vm_content_type, + assigned_object_id=virtual_machine2.pk) cls.form_data = { "domain_names": {'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, -- GitLab From a2ac97bcf770523cca997caabda1d6fc49ff0d2f Mon Sep 17 00:00:00 2001 From: Frederico Sequeira <frederico.sequeira@ext.ec.europa.eu> Date: Mon, 20 Jan 2025 10:46:17 +0000 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=9A=A8=20Fix=20Trailing=20whitespace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/vm_domain_names/test_vm_domain_names_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py index fb05def..21f3053 100644 --- a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py +++ b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py @@ -30,7 +30,7 @@ class DomainNamesFormTestCase( virtual_machine2 = VirtualMachine.objects.create(name="Test VM2",status="active",cluster=cluster) DomainNames.objects.create( domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, - assigned_object_type=vm_content_type, + assigned_object_type=vm_content_type, assigned_object_id=virtual_machine.pk) DomainNames.objects.create( domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, -- GitLab From d55f82903208391181ec48226735064851dcf992 Mon Sep 17 00:00:00 2001 From: Frederico Sequeira <frederico.sequeira@ext.ec.europa.eu> Date: Mon, 20 Jan 2025 11:40:07 +0000 Subject: [PATCH 6/6] =?UTF-8?q?=E2=9C=85=20Add=20new=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test_vm_domain_names_view.py | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py index 21f3053..7757766 100644 --- a/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py +++ b/netbox_sys_plugin/tests/vm_domain_names/test_vm_domain_names_view.py @@ -29,25 +29,52 @@ class DomainNamesFormTestCase( virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=cluster) virtual_machine2 = VirtualMachine.objects.create(name="Test VM2",status="active",cluster=cluster) DomainNames.objects.create( - domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + domain_names={'test_setup': [{'id': {'required': 'true','type': 'String'}}]}, assigned_object_type=vm_content_type, assigned_object_id=virtual_machine.pk) DomainNames.objects.create( - domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + domain_names={'test_setup': [{'id': {'required': 'true','type': 'String'}}]}, assigned_object_type=vm_content_type, assigned_object_id=virtual_machine2.pk) cls.form_data = { - "domain_names": {'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + "domain_names": {'test_setup': [{'id': {'required': 'true','type': 'String'}}]}, "virtual_machine": virtual_machine2.pk, } + def test_create_valid_domain_names(self): + """Test domain name valid creation""" + # pylint: disable=W0201 + self.vm_content_type = ContentType.objects.get_for_model(VirtualMachine) + # pylint: disable=W0201 + self.cluster_type = ClusterType.objects.create(name="Test ClusterType2", slug="ClusterType2") + # pylint: disable=W0201 + self.cluster = Cluster.objects.create(name="Test Cluster2", type=self.cluster_type) + # pylint: disable=W0201 + self.virtual_machine_valid = VirtualMachine.objects.create(name="Test VM",status="active",cluster=self.cluster) + + form = DomainNamesForm(data= { + "domain_names": {'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + "virtual_machine": self.virtual_machine_valid.pk, + }) + + self.assertTrue(form.is_valid()) + # Setup object permissions for the test user + obj_perm = ObjectPermission( + name='Test permission', + actions=['add', 'change'] + ) + obj_perm.save() + obj_perm.users.add(self.user) # pylint: disable=no-member + obj_perm.object_types.add(ContentType.objects.get_for_model(self.model)) # pylint: disable=no-member + + def test_create_domain_names_with_no_assigment(self): """Test the creation a VM domain names with no VM assignement""" form = DomainNamesForm(data= { - "domain_names": {'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + "domain_names": {'test_no_assignment': [{'id': {'required': 'true','type': 'String'}}]}, }) self.assertFalse(form.is_valid()) @@ -66,14 +93,14 @@ class DomainNamesFormTestCase( # pylint: disable=W0201 self.vm_content_type = ContentType.objects.get_for_model(VirtualMachine) # pylint: disable=W0201 - self.cluster_type = ClusterType.objects.create(name="Test ClusterType2", slug="ClusterType2") + self.cluster_type = ClusterType.objects.create(name="Test ClusterType3", slug="ClusterType3") # pylint: disable=W0201 - self.cluster = Cluster.objects.create(name="Test Cluster2", type=self.cluster_type) + self.cluster = Cluster.objects.create(name="Test Cluster3", type=self.cluster_type) # pylint: disable=W0201 self.virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=self.cluster) # pylint: disable=W0201 self.domain_names = DomainNames.objects.create( - domain_names={'test_valid': [{'id': {'required': 'true','type': 'String'}}]}, + domain_names={'test_2_assignment': [{'id': {'required': 'true','type': 'String'}}]}, assigned_object_type=self.vm_content_type, assigned_object_id=self.virtual_machine.pk ) @@ -107,9 +134,9 @@ class DomainNamesFormTestCase( # pylint: disable=W0201 self.vm_content_type = ContentType.objects.get_for_model(VirtualMachine) # pylint: disable=W0201 - self.cluster_type = ClusterType.objects.create(name="Test ClusterType3", slug="ClusterType3") + self.cluster_type = ClusterType.objects.create(name="Test ClusterType4", slug="ClusterType4") # pylint: disable=W0201 - self.cluster = Cluster.objects.create(name="Test Cluster3", type=self.cluster_type) + self.cluster = Cluster.objects.create(name="Test Cluster4", type=self.cluster_type) # pylint: disable=W0201 self.virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=self.cluster) -- GitLab