From 7cb0ecc11fe21e1861ef81979da0af5d77b47dd5 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 27 Feb 2023 16:07:39 -0500 Subject: [PATCH] Add tests for provisioning available ASNs --- netbox/ipam/api/serializers.py | 5 +-- netbox/ipam/tests/test_api.py | 56 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index 408403c6f..f62ed0d83 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -39,6 +39,7 @@ class ASNRangeSerializer(NetBoxModelSerializer): class ASNSerializer(NetBoxModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='ipam-api:asn-detail') + rir = NestedRIRSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True) site_count = serializers.IntegerField(read_only=True) provider_count = serializers.IntegerField(read_only=True) @@ -58,11 +59,11 @@ class AvailableASNSerializer(serializers.Serializer): asn = serializers.IntegerField(read_only=True) def to_representation(self, asn): - range = NestedASNRangeSerializer(self.context['range'], context={ + rir = NestedRIRSerializer(self.context['range'].rir, context={ 'request': self.context['request'] }).data return { - 'range': range, + 'rir': rir, 'asn': asn, } diff --git a/netbox/ipam/tests/test_api.py b/netbox/ipam/tests/test_api.py index b876aabc0..3908c8f3d 100644 --- a/netbox/ipam/tests/test_api.py +++ b/netbox/ipam/tests/test_api.py @@ -76,6 +76,62 @@ class ASNRangeTest(APIViewTestCases.APIViewTestCase): }, ] + def test_list_available_asns(self): + """ + Test retrieval of all available ASNs within a parent range. + """ + rir = RIR.objects.first() + asnrange = ASNRange.objects.create(name='Range 1', slug='range-1', rir=rir, start=101, end=110) + url = reverse('ipam-api:asnrange-available-asns', kwargs={'pk': asnrange.pk}) + self.add_permissions('ipam.view_asnrange', 'ipam.view_asn') + + response = self.client.get(url, **self.header) + self.assertHttpStatus(response, status.HTTP_200_OK) + self.assertEqual(len(response.data), 10) + + def test_create_single_available_asn(self): + """ + Test creation of the first available ASN within a range. + """ + rir = RIR.objects.first() + asnrange = ASNRange.objects.create(name='Range 1', slug='range-1', rir=rir, start=101, end=110) + url = reverse('ipam-api:asnrange-available-asns', kwargs={'pk': asnrange.pk}) + self.add_permissions('ipam.view_asnrange', 'ipam.add_asn') + + data = { + 'description': 'New ASN' + } + response = self.client.post(url, data, format='json', **self.header) + self.assertHttpStatus(response, status.HTTP_201_CREATED) + self.assertEqual(response.data['rir']['id'], asnrange.rir.pk) + self.assertEqual(response.data['description'], data['description']) + + def test_create_multiple_available_asns(self): + """ + Test the creation of several available ASNs within a parent range. + """ + rir = RIR.objects.first() + asnrange = ASNRange.objects.create(name='Range 1', slug='range-1', rir=rir, start=101, end=110) + url = reverse('ipam-api:asnrange-available-asns', kwargs={'pk': asnrange.pk}) + self.add_permissions('ipam.view_asnrange', 'ipam.add_asn') + + # Try to create eleven ASNs (only ten are available) + data = [ + {'description': f'New ASN {i}'} + for i in range(1, 12) + ] + assert len(data) == 11 + response = self.client.post(url, data, format='json', **self.header) + self.assertHttpStatus(response, status.HTTP_409_CONFLICT) + self.assertIn('detail', response.data) + + # Create all ten available ASNs in a single request + data.pop() + assert len(data) == 10 + response = self.client.post(url, data, format='json', **self.header) + self.assertHttpStatus(response, status.HTTP_201_CREATED) + self.assertEqual(len(response.data), 10) + class ASNTest(APIViewTestCases.APIViewTestCase): model = ASN