Skip to content

Commit

Permalink
Fixes netbox-community#14755: ValueError in web UI after REST API acc…
Browse files Browse the repository at this point in the history
…epts invalid custom-field choice-set data
  • Loading branch information
julio.oliveira committed Jan 15, 2024
1 parent 3d94141 commit e87e113
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 11 deletions.
12 changes: 11 additions & 1 deletion netbox/extras/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,15 @@ class Meta:
'choices_count', 'created', 'last_updated',
]

def validate_extra_choices(self, value):
for choice in value:
if isinstance(choice, list):
if len(choice) < 2:
raise serializers.ValidationError('Each choice must have 2 elements.')
else:
raise serializers.ValidationError('Extra choice must be a list of two elements.')
return value


#
# Custom links
Expand Down Expand Up @@ -374,7 +383,8 @@ def validate(self, data):

@extend_schema_field(serializers.JSONField(allow_null=True))
def get_assigned_object(self, instance):
serializer = get_serializer_for_model(instance.assigned_object_type.model_class(), prefix=NESTED_SERIALIZER_PREFIX)
serializer = get_serializer_for_model(instance.assigned_object_type.model_class(),
prefix=NESTED_SERIALIZER_PREFIX)
context = {'request': self.context['request']}
return serializer(instance.assigned_object, context=context).data

Expand Down
10 changes: 0 additions & 10 deletions netbox/extras/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@
from extras.scripts import BooleanVar, IntegerVar, Script, StringVar
from utilities.testing import APITestCase, APIViewTestCases


User = get_user_model()


class AppTest(APITestCase):

def test_root(self):

url = reverse('extras-api:api-root')
response = self.client.get('{}?format=api'.format(url), **self.header)

Expand Down Expand Up @@ -52,7 +50,6 @@ class WebhookTest(APIViewTestCases.APIViewTestCase):

@classmethod
def setUpTestData(cls):

webhooks = (
Webhook(
name='Webhook 1',
Expand Down Expand Up @@ -505,7 +502,6 @@ class TagTest(APIViewTestCases.APIViewTestCase):

@classmethod
def setUpTestData(cls):

tags = (
Tag(name='Tag 1', slug='tag-1'),
Tag(name='Tag 2', slug='tag-2'),
Expand Down Expand Up @@ -632,7 +628,6 @@ class ConfigContextTest(APIViewTestCases.APIViewTestCase):

@classmethod
def setUpTestData(cls):

config_contexts = (
ConfigContext(name='Config Context 1', weight=100, data={'foo': 123}),
ConfigContext(name='Config Context 2', weight=200, data={'bar': 456}),
Expand Down Expand Up @@ -731,7 +726,6 @@ def setUpTestData(cls):


class ReportTest(APITestCase):

class TestReport(Report):

def test_foo(self):
Expand Down Expand Up @@ -762,9 +756,7 @@ def test_get_report(self):


class ScriptTest(APITestCase):

class TestScript(Script):

class Meta:
name = "Test script"

Expand All @@ -773,7 +765,6 @@ class Meta:
var3 = BooleanVar()

def run(self, data, commit=True):

self.log_info(data['var1'])
self.log_success(data['var2'])
self.log_failure(data['var3'])
Expand All @@ -798,7 +789,6 @@ def setUp(self):
ScriptViewSet._get_script = self.get_test_script

def test_get_script(self):

url = reverse('extras-api:script-detail', kwargs={'pk': None})
response = self.client.get(url, **self.header)

Expand Down
59 changes: 59 additions & 0 deletions netbox/extras/tests/test_custom_field_choice_sets_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from django.contrib.auth import get_user_model
from rest_framework.test import APITestCase

from users.models import Token

User = get_user_model()


class CustomFieldChoiceSetsEndpointTest(APITestCase):

def setUp(self):
self.super_user = User.objects.create_user(username='testuser', is_staff=True, is_superuser=True)
self.token = Token.objects.create(user=self.super_user)
self.header = {'HTTP_AUTHORIZATION': f'Token {self.token.key}'}
self.url = '/api/extras/custom-field-choice-sets/'

def test_extra_choices_only_one_choice_element_return_400(self):
payload = {
"name": "test",
"extra_choices": [["choice1"]]
}

response = self.client.post(self.url, payload, format='json', **self.header)

self.assertEqual(response.status_code, 400)

def test_extra_choices_two_wrong_choice_elements_return_400(self):
payload = {
"name": "test",
"extra_choices": [["choice1"], ["choice2"]]
}

response = self.client.post(self.url, payload, format='json', **self.header)

self.assertEqual(response.status_code, 400)

def test_extra_choices_one_is_wrong_other_correct_choice_elements_return_400(self):
payload = {
"name": "test",
"extra_choices": [["1A", "choice1"], ["choice2"]]
}

response = self.client.post(self.url, payload, format='json', **self.header)

self.assertEqual(response.status_code, 400)

def test_extra_choices_correct_choices_return_201(self):
payload = {
'name': 'Choice Set',
'extra_choices': [
['4A', 'Choice 1'],
['4B', 'Choice 2'],
['4C', 'Choice 3'],
],
}

response = self.client.post(self.url, payload, format='json', **self.header)

self.assertEqual(response.status_code, 201)

0 comments on commit e87e113

Please sign in to comment.