소스 검색

feat(ipam): Normalize numeric ranges in API output

Adds logic to handle numeric range fields in API responses by
converting them into inclusive `[low, high]` pairs for consistent
behavior. Updates test cases with `vid_ranges` fields to reflect the
changes.

Closes #20491
Martin Hauser 4 달 전
부모
커밋
60fce84c96
2개의 변경된 파일10개의 추가작업 그리고 3개의 파일을 삭제
  1. 3 0
      netbox/ipam/tests/test_api.py
  2. 7 3
      netbox/utilities/testing/base.py

+ 3 - 0
netbox/ipam/tests/test_api.py

@@ -1071,14 +1071,17 @@ class VLANGroupTest(APIViewTestCases.APIViewTestCase):
         {
             'name': 'VLAN Group 4',
             'slug': 'vlan-group-4',
+            'vid_ranges': [[1, 4094]]
         },
         {
             'name': 'VLAN Group 5',
             'slug': 'vlan-group-5',
+            'vid_ranges': [[1, 4094]]
         },
         {
             'name': 'VLAN Group 6',
             'slug': 'vlan-group-6',
+            'vid_ranges': [[1, 4094]]
         },
     ]
     bulk_update_data = {

+ 7 - 3
netbox/utilities/testing/base.py

@@ -141,8 +141,8 @@ class ModelTestCase(TestCase):
             elif value and type(field) is GenericForeignKey:
                 model_dict[key] = value.pk
 
+            # Handle API output
             elif api:
-
                 # Replace ContentType numeric IDs with <app_label>.<model>
                 if type(getattr(instance, key)) in (ContentType, ObjectType):
                     object_type = ObjectType.objects.get(pk=value)
@@ -152,9 +152,13 @@ class ModelTestCase(TestCase):
                 elif type(value) is IPNetwork:
                     model_dict[key] = str(value)
 
-            else:
-                field = instance._meta.get_field(key)
+                # Normalize arrays of numeric ranges (e.g. VLAN IDs or port ranges).
+                # DB uses canonical half-open [lo, hi) via NumericRange; API uses inclusive [lo, hi].
+                # Convert to inclusive pairs for stable API comparisons.
+                elif type(field) is ArrayField and issubclass(type(field.base_field), RangeField):
+                    model_dict[key] = [[r.lower, r.upper - 1] for r in value]
 
+            else:
                 # Convert ArrayFields to CSV strings
                 if type(field) is ArrayField:
                     if getattr(field.base_field, 'choices', None):