Browse Source

Added custom field API tests

Jeremy Stretch 8 years ago
parent
commit
1c86b00b5c

+ 6 - 0
netbox/extras/api/customfields.py

@@ -32,6 +32,12 @@ class CustomFieldsSerializer(serializers.BaseSerializer):
             if parent_content_type not in cf.obj_type.all():
                 raise ValidationError(u"Invalid custom field for {} objects".format(parent_content_type))
 
+            # Validate selected choice
+            if cf.type == CF_TYPE_SELECT:
+                valid_choices = [c.pk for c in cf.choices.all()]
+                if value not in valid_choices:
+                    raise ValidationError(u"Invalid choice ({}) for field {}".format(value, custom_field))
+
         return data
 
 

+ 1 - 4
netbox/extras/models.py

@@ -156,10 +156,7 @@ class CustomField(models.Model):
             # Read date as YYYY-MM-DD
             return date(*[int(n) for n in serialized_value.split('-')])
         if self.type == CF_TYPE_SELECT:
-            try:
-                return self.choices.get(pk=int(serialized_value))
-            except CustomFieldChoice.DoesNotExist:
-                return None
+            return self.choices.get(pk=int(serialized_value))
         return serialized_value
 
 

+ 214 - 1
netbox/extras/tests/test_customfields.py

@@ -1,7 +1,12 @@
 from datetime import date
 
+from rest_framework import status
+from rest_framework.test import APITestCase
+
+from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
 from django.test import TestCase
+from django.urls import reverse
 
 from dcim.models import Site
 
@@ -9,9 +14,11 @@ from extras.models import (
     CustomField, CustomFieldValue, CustomFieldChoice, CF_TYPE_TEXT, CF_TYPE_INTEGER, CF_TYPE_BOOLEAN, CF_TYPE_DATE,
     CF_TYPE_SELECT, CF_TYPE_URL,
 )
+from users.models import Token
+from utilities.tests import HttpStatusMixin
 
 
-class CustomFieldTestCase(TestCase):
+class CustomFieldTest(TestCase):
 
     def setUp(self):
 
@@ -95,3 +102,209 @@ class CustomFieldTestCase(TestCase):
 
         # Delete the custom field
         cf.delete()
+
+
+class CustomFieldAPITest(HttpStatusMixin, APITestCase):
+
+    def setUp(self):
+
+        user = User.objects.create(username='testuser', is_superuser=True)
+        token = Token.objects.create(user=user)
+        self.header = {'HTTP_AUTHORIZATION': 'Token {}'.format(token.key)}
+
+        content_type = ContentType.objects.get_for_model(Site)
+
+        # Text custom field
+        self.cf_text = CustomField(type=CF_TYPE_TEXT, name='magic_word')
+        self.cf_text.save()
+        self.cf_text.obj_type = [content_type]
+        self.cf_text.save()
+
+        # Integer custom field
+        self.cf_integer = CustomField(type=CF_TYPE_INTEGER, name='magic_number')
+        self.cf_integer.save()
+        self.cf_integer.obj_type = [content_type]
+        self.cf_integer.save()
+
+        # Boolean custom field
+        self.cf_boolean = CustomField(type=CF_TYPE_BOOLEAN, name='is_magic')
+        self.cf_boolean.save()
+        self.cf_boolean.obj_type = [content_type]
+        self.cf_boolean.save()
+
+        # Date custom field
+        self.cf_date = CustomField(type=CF_TYPE_DATE, name='magic_date')
+        self.cf_date.save()
+        self.cf_date.obj_type = [content_type]
+        self.cf_date.save()
+
+        # URL custom field
+        self.cf_url = CustomField(type=CF_TYPE_URL, name='magic_url')
+        self.cf_url.save()
+        self.cf_url.obj_type = [content_type]
+        self.cf_url.save()
+
+        # Select custom field
+        self.cf_select = CustomField(type=CF_TYPE_SELECT, name='magic_choice')
+        self.cf_select.save()
+        self.cf_select.obj_type = [content_type]
+        self.cf_select.save()
+        self.cf_select_choice1 = CustomFieldChoice(field=self.cf_select, value='Foo')
+        self.cf_select_choice1.save()
+        self.cf_select_choice2 = CustomFieldChoice(field=self.cf_select, value='Bar')
+        self.cf_select_choice2.save()
+        self.cf_select_choice3 = CustomFieldChoice(field=self.cf_select, value='Baz')
+        self.cf_select_choice3.save()
+
+        self.site = Site.objects.create(name='Test Site 1', slug='test-site-1')
+
+    def test_get_obj_without_custom_fields(self):
+
+        url = reverse('dcim-api:site-detail', kwargs={'pk': self.site.pk})
+        response = self.client.get(url, **self.header)
+
+        self.assertEqual(response.data['name'], self.site.name)
+        self.assertEqual(response.data['custom_fields'], {
+            'magic_word': None,
+            'magic_number': None,
+            'is_magic': None,
+            'magic_date': None,
+            'magic_url': None,
+            'magic_choice': None,
+        })
+
+    def test_get_obj_with_custom_fields(self):
+
+        CUSTOM_FIELD_VALUES = [
+            (self.cf_text, 'Test string'),
+            (self.cf_integer, 1234),
+            (self.cf_boolean, True),
+            (self.cf_date, date(2016, 6, 23)),
+            (self.cf_url, 'http://example.com/'),
+            (self.cf_select, self.cf_select_choice1.pk),
+        ]
+        for field, value in CUSTOM_FIELD_VALUES:
+            cfv = CustomFieldValue(field=field, obj=self.site)
+            cfv.value = value
+            cfv.save()
+
+        url = reverse('dcim-api:site-detail', kwargs={'pk': self.site.pk})
+        response = self.client.get(url, **self.header)
+
+        self.assertEqual(response.data['name'], self.site.name)
+        self.assertEqual(response.data['custom_fields'].get('magic_word'), CUSTOM_FIELD_VALUES[0][1])
+        self.assertEqual(response.data['custom_fields'].get('magic_number'), CUSTOM_FIELD_VALUES[1][1])
+        self.assertEqual(response.data['custom_fields'].get('is_magic'), CUSTOM_FIELD_VALUES[2][1])
+        self.assertEqual(response.data['custom_fields'].get('magic_date'), CUSTOM_FIELD_VALUES[3][1])
+        self.assertEqual(response.data['custom_fields'].get('magic_url'), CUSTOM_FIELD_VALUES[4][1])
+        self.assertEqual(response.data['custom_fields'].get('magic_choice'), {
+            'value': self.cf_select_choice1.pk, 'label': 'Foo'
+        })
+
+    def test_set_custom_field_text(self):
+
+        data = {
+            'name': 'Test Site 1',
+            'slug': 'test-site-1',
+            'custom_fields': {
+                'magic_word': 'Foo bar baz',
+            }
+        }
+
+        url = reverse('dcim-api:site-detail', kwargs={'pk': self.site.pk})
+        response = self.client.put(url, data, format='json', **self.header)
+
+        self.assertHttpStatus(response, status.HTTP_200_OK)
+        self.assertEqual(response.data['custom_fields'].get('magic_word'), data['custom_fields']['magic_word'])
+        cfv = self.site.custom_field_values.get(field=self.cf_text)
+        self.assertEqual(cfv.value, data['custom_fields']['magic_word'])
+
+    def test_set_custom_field_integer(self):
+
+        data = {
+            'name': 'Test Site 1',
+            'slug': 'test-site-1',
+            'custom_fields': {
+                'magic_number': 42,
+            }
+        }
+
+        url = reverse('dcim-api:site-detail', kwargs={'pk': self.site.pk})
+        response = self.client.put(url, data, format='json', **self.header)
+
+        self.assertHttpStatus(response, status.HTTP_200_OK)
+        self.assertEqual(response.data['custom_fields'].get('magic_number'), data['custom_fields']['magic_number'])
+        cfv = self.site.custom_field_values.get(field=self.cf_integer)
+        self.assertEqual(cfv.value, data['custom_fields']['magic_number'])
+
+    def test_set_custom_field_boolean(self):
+
+        data = {
+            'name': 'Test Site 1',
+            'slug': 'test-site-1',
+            'custom_fields': {
+                'is_magic': False,
+            }
+        }
+
+        url = reverse('dcim-api:site-detail', kwargs={'pk': self.site.pk})
+        response = self.client.put(url, data, format='json', **self.header)
+
+        self.assertHttpStatus(response, status.HTTP_200_OK)
+        self.assertEqual(response.data['custom_fields'].get('is_magic'), data['custom_fields']['is_magic'])
+        cfv = self.site.custom_field_values.get(field=self.cf_boolean)
+        self.assertEqual(cfv.value, data['custom_fields']['is_magic'])
+
+    def test_set_custom_field_date(self):
+
+        data = {
+            'name': 'Test Site 1',
+            'slug': 'test-site-1',
+            'custom_fields': {
+                'magic_date': date(2017, 4, 25),
+            }
+        }
+
+        url = reverse('dcim-api:site-detail', kwargs={'pk': self.site.pk})
+        response = self.client.put(url, data, format='json', **self.header)
+
+        self.assertHttpStatus(response, status.HTTP_200_OK)
+        self.assertEqual(response.data['custom_fields'].get('magic_date'), data['custom_fields']['magic_date'])
+        cfv = self.site.custom_field_values.get(field=self.cf_date)
+        self.assertEqual(cfv.value, data['custom_fields']['magic_date'])
+
+    def test_set_custom_field_url(self):
+
+        data = {
+            'name': 'Test Site 1',
+            'slug': 'test-site-1',
+            'custom_fields': {
+                'magic_url': 'http://example.com/2/',
+            }
+        }
+
+        url = reverse('dcim-api:site-detail', kwargs={'pk': self.site.pk})
+        response = self.client.put(url, data, format='json', **self.header)
+
+        self.assertHttpStatus(response, status.HTTP_200_OK)
+        self.assertEqual(response.data['custom_fields'].get('magic_url'), data['custom_fields']['magic_url'])
+        cfv = self.site.custom_field_values.get(field=self.cf_url)
+        self.assertEqual(cfv.value, data['custom_fields']['magic_url'])
+
+    def test_set_custom_field_select(self):
+
+        data = {
+            'name': 'Test Site 1',
+            'slug': 'test-site-1',
+            'custom_fields': {
+                'magic_choice': self.cf_select_choice2.pk,
+            }
+        }
+
+        url = reverse('dcim-api:site-detail', kwargs={'pk': self.site.pk})
+        response = self.client.put(url, data, format='json', **self.header)
+
+        self.assertHttpStatus(response, status.HTTP_200_OK)
+        self.assertEqual(response.data['custom_fields'].get('magic_choice'), data['custom_fields']['magic_choice'])
+        cfv = self.site.custom_field_values.get(field=self.cf_select)
+        self.assertEqual(cfv.value.pk, data['custom_fields']['magic_choice'])