diff --git a/netbox/dcim/forms/object_create.py b/netbox/dcim/forms/object_create.py index 6f6cd8f7c..b279aec9b 100644 --- a/netbox/dcim/forms/object_create.py +++ b/netbox/dcim/forms/object_create.py @@ -153,6 +153,7 @@ class FrontPortTemplateCreateForm(ComponentCreateForm, model_forms.FrontPortTemp self.fields['rear_port'].choices = choices def clean(self): + super().clean() # Check that the number of FrontPortTemplates to be created matches the selected number of RearPortTemplate # positions @@ -302,6 +303,7 @@ class FrontPortCreateForm(ComponentCreateForm, model_forms.FrontPortForm): self.fields['rear_port'].choices = choices def clean(self): + super().clean() # Check that the number of FrontPorts to be created matches the selected number of RearPort positions frontport_count = len(self.cleaned_data['name']) diff --git a/netbox/dcim/tests/test_forms.py b/netbox/dcim/tests/test_forms.py index 89b7508f3..73d5dbd98 100644 --- a/netbox/dcim/tests/test_forms.py +++ b/netbox/dcim/tests/test_forms.py @@ -1,6 +1,12 @@ from django.test import TestCase -from dcim.choices import DeviceFaceChoices, DeviceStatusChoices, InterfaceTypeChoices, InterfaceModeChoices +from dcim.choices import ( + DeviceFaceChoices, + DeviceStatusChoices, + InterfaceModeChoices, + InterfaceTypeChoices, + PortTypeChoices, +) from dcim.forms import * from dcim.models import * from ipam.models import VLAN @@ -118,6 +124,51 @@ class DeviceTestCase(TestCase): self.assertIn('position', form.errors) +class FrontPortTestCase(TestCase): + + @classmethod + def setUpTestData(cls): + cls.device = create_test_device('Panel Device 1') + cls.rear_ports = ( + RearPort(name='RearPort1', device=cls.device, type=PortTypeChoices.TYPE_8P8C), + RearPort(name='RearPort2', device=cls.device, type=PortTypeChoices.TYPE_8P8C), + RearPort(name='RearPort3', device=cls.device, type=PortTypeChoices.TYPE_8P8C), + RearPort(name='RearPort4', device=cls.device, type=PortTypeChoices.TYPE_8P8C), + ) + RearPort.objects.bulk_create(cls.rear_ports) + + def test_front_port_label_count_valid(self): + """ + Test that generating an equal number of names and labels passes form validation. + """ + front_port_data = { + 'device': self.device.pk, + 'name': 'FrontPort[1-4]', + 'label': 'Port[1-4]', + 'type': PortTypeChoices.TYPE_8P8C, + 'rear_port': [f'{rear_port.pk}:1' for rear_port in self.rear_ports], + } + form = FrontPortCreateForm(front_port_data) + + self.assertTrue(form.is_valid()) + + def test_front_port_label_count_mismatch(self): + """ + Check that attempting to generate a differing number of names and labels results in a validation error. + """ + bad_front_port_data = { + 'device': self.device.pk, + 'name': 'FrontPort[1-4]', + 'label': 'Port[1-2]', + 'type': PortTypeChoices.TYPE_8P8C, + 'rear_port': [f'{rear_port.pk}:1' for rear_port in self.rear_ports], + } + form = FrontPortCreateForm(bad_front_port_data) + + self.assertFalse(form.is_valid()) + self.assertIn('label', form.errors) + + class InterfaceTestCase(TestCase): @classmethod