From 94febf900511b973643f3b769efde0462c4fdb4a Mon Sep 17 00:00:00 2001 From: Arkadiusz Szczecinski <arkadiusz.szczecinski@ext.ec.europa.eu> Date: Fri, 24 Jan 2025 09:41:56 +0100 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=85=20Add=20valid=20VmAssignedVmTypeF?= =?UTF-8?q?ormTestCase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...t_vm_assigned_virtual_machine_type_view.py | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py diff --git a/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py b/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py new file mode 100644 index 0000000..296c096 --- /dev/null +++ b/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py @@ -0,0 +1,160 @@ +"""VM Assigned Extra Config 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 VmAssignedVirtualMachineType, VirtualMachineType +from netbox_sys_plugin.forms import VmAssignedVmTypeForm +from ..base import BaseModelViewTestCase + + + +class VmAssignedVmTypeFormTestCase( + BaseModelViewTestCase, +): + """VM Assigned Extra Config Test Case Class""" + + model = VmAssignedVirtualMachineType + form = VmAssignedVmTypeForm + + def test_create_valid_assigned_extra_config(self): + """Create a valid Extra Config Assignment""" + + clt_content_type = ContentType.objects.get_for_model(ClusterType) + + cluster_type = ClusterType.objects.create(name="Test ClusterType1", slug="ClusterType1") + + cluster = Cluster.objects.create(name="Test Cluster1", type=cluster_type) + + vm_type = VirtualMachineType.objects.create(virtual_machine_type_name='VMType1', + assigned_object=cluster_type, + virtual_machine_type_desc='AWS description') + + virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=cluster) + + + form = VmAssignedVmTypeForm(data= { + "virtual_machine": virtual_machine.pk, + "virtual_machine_type_assignment_desc": 'Test virtual_machine_type_assignment', + "virtual_machine_type": vm_type.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_vm_with_two_extra_config_value_assigment(self): + # """Test the assignment of 2 extra configs to the same Cluster Type """ + + # clt_content_type = ContentType.objects.get_for_model(ClusterType) + + # 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) + + # extra_config = ProviderTypeExtraConfig.objects.create( + # extra_config_name="Test Structure2", + # extra_config_structure={'test_extra2': [{'id': {'required': 'true','type': 'String'}}]}, + # extra_config_description="Test Structure for Test2", + # assigned_object_type=clt_content_type, + # assigned_object_id=cluster_type.pk + # ) + + # VmAssignedExtraConfig.objects.create( + # assigned_object_type=vm_content_type, + # assigned_object_id=virtual_machine.pk, + # provider_type_extra_config= extra_config, + # extra_config_values= {"id":"TestID"}, + # provider_type_extra_config_assignment_desc= "Test Extra Config Assignment", + # ) + + # form = VmAssignedExtraConfigForm(data= { + # "virtual_machine": virtual_machine.pk, + # "provider_type_extra_config": extra_config.pk, + # "extra_config_values": {"id":"TestID"}, + # "provider_type_extra_config_assignment_desc": "Test Extra Config Assignment", + # }) + + # 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 Extra Config to the same Virtual Machine", + # form.errors.get("__all__",[]) + # ) + + # def test_invalid_assigned_extra_config_format(self): + # """ + # Test invalid extra config invalid format. + # """ + + # clt_content_type = ContentType.objects.get_for_model(ClusterType) + + # 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) + + # extra_config = ProviderTypeExtraConfig.objects.create( + # extra_config_name="Test Structure", + # extra_config_structure={'test_extra1': [{'id': {'required': 'true','type': 'String'}}]}, + # extra_config_description="Test Structure for Test", + # assigned_object_type=clt_content_type, + # assigned_object_id=cluster_type.pk + # ) + + # # Set up valid form data + # invalid_valid_form_data = { + # "virtual_machine": virtual_machine.pk, + # "provider_type_extra_config": extra_config.pk, + # "extra_config_values": {"id":"TestID"}, + # "provider_type_extra_config_assignment_desc": "Test Extra Config Assignment", + # } + # #Invalid JSON + # invalid_form_data = invalid_valid_form_data.copy() + # invalid_form_data["extra_config_values"] = "Invalid" # Invalid format + # form = self.form(data=invalid_form_data) + # self.assertFalse(form.is_valid()) + # self.assertIn( + # "Enter a valid JSON.", + # form.errors.get("extra_config_values", []), + # ) + # #List Validation + # invalid_form_data["extra_config_values"] = {"description":"description"} # Wrong field + # form = self.form(data=invalid_form_data) + # self.assertFalse(form.is_valid()) + # self.assertIn( + # "Missing or empty required field: 'id' with type string", + # form.errors.get("extra_config_values", []), + # ) + # #Missing property Type + # invalid_form_data["extra_config_values"] = {"id":True} # Wrong type + # form = self.form(data=invalid_form_data) + # self.assertFalse(form.is_valid()) + # self.assertIn( + # "Incorrect type for field 'id': expected string, got bool", + # form.errors.get("extra_config_values", []), + # ) + + # def tearDown(self) -> None:# pylint: disable=invalid-name + # """Method called immediately after the test method has been called and the result recorded.""" + # VmAssignedExtraConfig.objects.all().delete() + # ProviderTypeExtraConfig.objects.all().delete() + # super().tearDown() -- GitLab From 16c7e3cf2be03a0b8d6a557e5cb36d666f119b65 Mon Sep 17 00:00:00 2001 From: Arkadiusz Szczecinski <arkadiusz.szczecinski@ext.ec.europa.eu> Date: Fri, 24 Jan 2025 10:20:36 +0100 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=A7=AA=20add=20test=20for=20assgn=202?= =?UTF-8?q?=20types=20to=20VM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...t_vm_assigned_virtual_machine_type_view.py | 162 ++++++------------ 1 file changed, 57 insertions(+), 105 deletions(-) diff --git a/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py b/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py index 296c096..e7e48f2 100644 --- a/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py +++ b/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py @@ -17,7 +17,7 @@ class VmAssignedVmTypeFormTestCase( model = VmAssignedVirtualMachineType form = VmAssignedVmTypeForm - def test_create_valid_assigned_extra_config(self): + def test_create_valid_vm_assigned_virtual_machine_type(self): """Create a valid Extra Config Assignment""" clt_content_type = ContentType.objects.get_for_model(ClusterType) @@ -48,110 +48,62 @@ class VmAssignedVmTypeFormTestCase( 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_extra_config_value_assigment(self): - # """Test the assignment of 2 extra configs to the same Cluster Type """ - - # clt_content_type = ContentType.objects.get_for_model(ClusterType) - - # 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) - - # extra_config = ProviderTypeExtraConfig.objects.create( - # extra_config_name="Test Structure2", - # extra_config_structure={'test_extra2': [{'id': {'required': 'true','type': 'String'}}]}, - # extra_config_description="Test Structure for Test2", - # assigned_object_type=clt_content_type, - # assigned_object_id=cluster_type.pk - # ) - - # VmAssignedExtraConfig.objects.create( - # assigned_object_type=vm_content_type, - # assigned_object_id=virtual_machine.pk, - # provider_type_extra_config= extra_config, - # extra_config_values= {"id":"TestID"}, - # provider_type_extra_config_assignment_desc= "Test Extra Config Assignment", - # ) - - # form = VmAssignedExtraConfigForm(data= { - # "virtual_machine": virtual_machine.pk, - # "provider_type_extra_config": extra_config.pk, - # "extra_config_values": {"id":"TestID"}, - # "provider_type_extra_config_assignment_desc": "Test Extra Config Assignment", - # }) - - # 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 Extra Config to the same Virtual Machine", - # form.errors.get("__all__",[]) - # ) - - # def test_invalid_assigned_extra_config_format(self): - # """ - # Test invalid extra config invalid format. - # """ - - # clt_content_type = ContentType.objects.get_for_model(ClusterType) - - # 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) - - # extra_config = ProviderTypeExtraConfig.objects.create( - # extra_config_name="Test Structure", - # extra_config_structure={'test_extra1': [{'id': {'required': 'true','type': 'String'}}]}, - # extra_config_description="Test Structure for Test", - # assigned_object_type=clt_content_type, - # assigned_object_id=cluster_type.pk - # ) - - # # Set up valid form data - # invalid_valid_form_data = { - # "virtual_machine": virtual_machine.pk, - # "provider_type_extra_config": extra_config.pk, - # "extra_config_values": {"id":"TestID"}, - # "provider_type_extra_config_assignment_desc": "Test Extra Config Assignment", - # } - # #Invalid JSON - # invalid_form_data = invalid_valid_form_data.copy() - # invalid_form_data["extra_config_values"] = "Invalid" # Invalid format - # form = self.form(data=invalid_form_data) - # self.assertFalse(form.is_valid()) - # self.assertIn( - # "Enter a valid JSON.", - # form.errors.get("extra_config_values", []), - # ) - # #List Validation - # invalid_form_data["extra_config_values"] = {"description":"description"} # Wrong field - # form = self.form(data=invalid_form_data) - # self.assertFalse(form.is_valid()) - # self.assertIn( - # "Missing or empty required field: 'id' with type string", - # form.errors.get("extra_config_values", []), - # ) - # #Missing property Type - # invalid_form_data["extra_config_values"] = {"id":True} # Wrong type - # form = self.form(data=invalid_form_data) - # self.assertFalse(form.is_valid()) - # self.assertIn( - # "Incorrect type for field 'id': expected string, got bool", - # form.errors.get("extra_config_values", []), - # ) + def test_invalid_vm_assigned_virtual_machine_type(self): + """ + Test invalid extra config invalid format. + """ + + clt_content_type = ContentType.objects.get_for_model(ClusterType) + + cluster_type = ClusterType.objects.create(name="Test ClusterType1", slug="ClusterType1") + + cluster = Cluster.objects.create(name="Test Cluster1", type=cluster_type) + + vm_type = VirtualMachineType.objects.create(virtual_machine_type_name='VMType1', + assigned_object=cluster_type, + virtual_machine_type_desc='AWS description') + + vm_type2 = VirtualMachineType.objects.create(virtual_machine_type_name='VMType2', + assigned_object=cluster_type, + virtual_machine_type_desc='AWS description') + + virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=cluster) + + # Assign VirtualMachineTypes to VirtualMachines + VmAssignedVirtualMachineType.objects.create(virtual_machine_type=vm_type, assigned_object_id=virtual_machine.pk) + + # Set up valid form data + invalid_valid_form_data = { + "virtual_machine": virtual_machine.pk, + "virtual_machine_type_assignment_desc": 'Test virtual_machine_type_assignment', + "virtual_machine_type": vm_type2.pk + } + + #Invalid assigment 2 types to 1 VM + # invalid_form_data = invalid_valid_form_data.copy() + # invalid_form_data["virtual_machine_type"] = vm_type2.pk # assign second type + form = self.form(data=invalid_valid_form_data) + self.assertFalse(form.is_valid()) + self.assertIn( + "Can't assign more than one Type to the same Virtual Machine", + form.errors.get("virtual_machine_type", []), + ) + #List Validation + # invalid_form_data["extra_config_values"] = {"description":"description"} # Wrong field + # form = self.form(data=invalid_form_data) + # self.assertFalse(form.is_valid()) + # self.assertIn( + # "Missing or empty required field: 'id' with type string", + # form.errors.get("extra_config_values", []), + # ) + # #Missing property Type + # invalid_form_data["extra_config_values"] = {"id":True} # Wrong type + # form = self.form(data=invalid_form_data) + # self.assertFalse(form.is_valid()) + # self.assertIn( + # "Incorrect type for field 'id': expected string, got bool", + # form.errors.get("extra_config_values", []), + # ) # def tearDown(self) -> None:# pylint: disable=invalid-name # """Method called immediately after the test method has been called and the result recorded.""" -- GitLab From 3eb6fc4877b4a4feaea13b6be48d63a71fbbd6be Mon Sep 17 00:00:00 2001 From: Frederico Sequeira <frederico.sequeira@ext.ec.europa.eu> Date: Fri, 24 Jan 2025 16:14:37 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=85=20=F0=9F=90=9B=20Fix=20issue=20in?= =?UTF-8?q?=20form=20validation=20and=20add=20test=20for=20multiple=20assi?= =?UTF-8?q?gnment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- netbox_sys_plugin/forms/machine.py | 25 ++++---- ...t_vm_assigned_virtual_machine_type_view.py | 57 ++++++------------- 2 files changed, 31 insertions(+), 51 deletions(-) diff --git a/netbox_sys_plugin/forms/machine.py b/netbox_sys_plugin/forms/machine.py index e78e861..56aa943 100644 --- a/netbox_sys_plugin/forms/machine.py +++ b/netbox_sys_plugin/forms/machine.py @@ -36,16 +36,6 @@ class VmAssignedVmTypeForm(NetBoxModelForm): kwargs["initial"] = initial super().__init__(*args, **kwargs) - if instance: - current_vm_id = instance.assigned_object.id if instance.assigned_object else None - else: - current_vm_id = None - - assigned_vms = VmAssignedVirtualMachineType.objects.filter( - assigned_object_type=ContentType.objects.get_for_model(VirtualMachine) - ).exclude(assigned_object_id=current_vm_id).values_list('assigned_object_id', flat=True) - self.fields['virtual_machine'].queryset = VirtualMachine.objects.exclude(id__in=assigned_vms) - class Meta: """Meta class""" model = VmAssignedVirtualMachineType @@ -55,14 +45,25 @@ class VmAssignedVmTypeForm(NetBoxModelForm): """Validates form inputs before submitting:""" super().clean() + vm = self.cleaned_data.get("virtual_machine") + vm_ct = ContentType.objects.get_for_model(VirtualMachine) - #Check if Virtual Machine is assigned corretly if not vm: raise ValidationError( - {"__all__": "Can't assign more than one Type to the same Virtual Machine"}, + {"__all__":"Virtual Machine can't be null"} + ) + + if VmAssignedVirtualMachineType.objects.filter( + assigned_object_type=vm_ct, + assigned_object_id=vm.id + ).exclude(pk=self.instance.pk).exists(): + raise ValidationError( + {"__all__":"Can't assign more than one Type to the same Virtual Machine"} ) + + def save(self, *args, **kwargs): """Set assigned object and save""" # Set assigned object diff --git a/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py b/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py index e7e48f2..aa8f470 100644 --- a/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py +++ b/netbox_sys_plugin/tests/vm_assigned_virtual_machine_type/test_vm_assigned_virtual_machine_type_view.py @@ -20,19 +20,14 @@ class VmAssignedVmTypeFormTestCase( def test_create_valid_vm_assigned_virtual_machine_type(self): """Create a valid Extra Config Assignment""" - clt_content_type = ContentType.objects.get_for_model(ClusterType) - cluster_type = ClusterType.objects.create(name="Test ClusterType1", slug="ClusterType1") - cluster = Cluster.objects.create(name="Test Cluster1", type=cluster_type) - - vm_type = VirtualMachineType.objects.create(virtual_machine_type_name='VMType1', + vm_type = VirtualMachineType.objects.create(virtual_machine_type_name='VMType1', assigned_object=cluster_type, virtual_machine_type_desc='AWS description') virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=cluster) - form = VmAssignedVmTypeForm(data= { "virtual_machine": virtual_machine.pk, "virtual_machine_type_assignment_desc": 'Test virtual_machine_type_assignment', @@ -53,60 +48,44 @@ class VmAssignedVmTypeFormTestCase( Test invalid extra config invalid format. """ - clt_content_type = ContentType.objects.get_for_model(ClusterType) + 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) - vm_type = VirtualMachineType.objects.create(virtual_machine_type_name='VMType1', + vm_type = VirtualMachineType.objects.create(virtual_machine_type_name='VMType1', assigned_object=cluster_type, virtual_machine_type_desc='AWS description') - - vm_type2 = VirtualMachineType.objects.create(virtual_machine_type_name='VMType2', + vm_type2 = VirtualMachineType.objects.create(virtual_machine_type_name='VMType2', assigned_object=cluster_type, virtual_machine_type_desc='AWS description') virtual_machine = VirtualMachine.objects.create(name="Test VM",status="active",cluster=cluster) # Assign VirtualMachineTypes to VirtualMachines - VmAssignedVirtualMachineType.objects.create(virtual_machine_type=vm_type, assigned_object_id=virtual_machine.pk) + VmAssignedVirtualMachineType.objects.create( + virtual_machine_type=vm_type, + assigned_object_id=virtual_machine.pk, + assigned_object_type=vm_content_type + ) - # Set up valid form data + # Set up invalid form data invalid_valid_form_data = { "virtual_machine": virtual_machine.pk, "virtual_machine_type_assignment_desc": 'Test virtual_machine_type_assignment', "virtual_machine_type": vm_type2.pk } - #Invalid assigment 2 types to 1 VM - # invalid_form_data = invalid_valid_form_data.copy() - # invalid_form_data["virtual_machine_type"] = vm_type2.pk # assign second type form = self.form(data=invalid_valid_form_data) self.assertFalse(form.is_valid()) self.assertIn( "Can't assign more than one Type to the same Virtual Machine", - form.errors.get("virtual_machine_type", []), - ) - #List Validation - # invalid_form_data["extra_config_values"] = {"description":"description"} # Wrong field - # form = self.form(data=invalid_form_data) - # self.assertFalse(form.is_valid()) - # self.assertIn( - # "Missing or empty required field: 'id' with type string", - # form.errors.get("extra_config_values", []), - # ) - # #Missing property Type - # invalid_form_data["extra_config_values"] = {"id":True} # Wrong type - # form = self.form(data=invalid_form_data) - # self.assertFalse(form.is_valid()) - # self.assertIn( - # "Incorrect type for field 'id': expected string, got bool", - # form.errors.get("extra_config_values", []), - # ) - - # def tearDown(self) -> None:# pylint: disable=invalid-name - # """Method called immediately after the test method has been called and the result recorded.""" - # VmAssignedExtraConfig.objects.all().delete() - # ProviderTypeExtraConfig.objects.all().delete() - # super().tearDown() + form.non_field_errors(),[] + ) + + def tearDown(self) -> None:# pylint: disable=invalid-name + """Method called immediately after the test method has been called and the result recorded.""" + VmAssignedVirtualMachineType.objects.all().delete() + VirtualMachineType.objects.all().delete() + super().tearDown() -- GitLab