mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-17 21:18:16 -06:00
Fixes #14755: ValueError in web UI after REST API accepts invalid custom-field choice-set data
This commit is contained in:
parent
3d941411d4
commit
e87e11377a
@ -179,6 +179,15 @@ class CustomFieldChoiceSetSerializer(ValidatedModelSerializer):
|
||||
'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
|
||||
@ -374,7 +383,8 @@ class JournalEntrySerializer(NetBoxModelSerializer):
|
||||
|
||||
@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
|
||||
|
||||
|
@ -14,14 +14,12 @@ from extras.reports import Report
|
||||
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)
|
||||
|
||||
@ -52,7 +50,6 @@ class WebhookTest(APIViewTestCases.APIViewTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
|
||||
webhooks = (
|
||||
Webhook(
|
||||
name='Webhook 1',
|
||||
@ -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'),
|
||||
@ -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}),
|
||||
@ -731,7 +726,6 @@ class ConfigTemplateTest(APIViewTestCases.APIViewTestCase):
|
||||
|
||||
|
||||
class ReportTest(APITestCase):
|
||||
|
||||
class TestReport(Report):
|
||||
|
||||
def test_foo(self):
|
||||
@ -762,9 +756,7 @@ class ReportTest(APITestCase):
|
||||
|
||||
|
||||
class ScriptTest(APITestCase):
|
||||
|
||||
class TestScript(Script):
|
||||
|
||||
class Meta:
|
||||
name = "Test script"
|
||||
|
||||
@ -773,7 +765,6 @@ class ScriptTest(APITestCase):
|
||||
var3 = BooleanVar()
|
||||
|
||||
def run(self, data, commit=True):
|
||||
|
||||
self.log_info(data['var1'])
|
||||
self.log_success(data['var2'])
|
||||
self.log_failure(data['var3'])
|
||||
@ -798,7 +789,6 @@ class ScriptTest(APITestCase):
|
||||
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)
|
||||
|
||||
|
@ -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)
|
Loading…
Reference in New Issue
Block a user