Kaynağa Gözat

5509 Add Test cases for Custom Fields (#12312)

* 5509 add content type data to model tests create and update

* 5509 update use cf form data

* 5509 update tests to use CustomFieldTypeChoices

* 5509 update tests to check custom fields

* Simplify custom fields used for testing

* Move custom field data functions to testing.utils

* Move validate_custom_field_data() into assertInstanceEqual()

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Arthur Hanson 1 yıl önce
ebeveyn
işleme
928014c766

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

@@ -10,10 +10,11 @@ from django.test import Client, TestCase as _TestCase
 from netaddr import IPNetwork
 from taggit.managers import TaggableManager
 
+from netbox.models.features import CustomFieldsMixin
 from users.models import ObjectPermission
 from utilities.permissions import resolve_permission_ct
 from utilities.utils import content_type_identifier
-from .utils import extract_form_failures
+from .utils import DUMMY_CF_DATA, extract_form_failures
 
 __all__ = (
     'ModelTestCase',
@@ -166,8 +167,12 @@ class ModelTestCase(TestCase):
         model_dict = self.model_to_dict(instance, fields=fields, api=api)
 
         # Omit any dictionary keys which are not instance attributes or have been excluded
-        relevant_data = {
+        model_data = {
             k: v for k, v in data.items() if hasattr(instance, k) and k not in exclude
         }
 
-        self.assertDictEqual(model_dict, relevant_data)
+        self.assertDictEqual(model_dict, model_data)
+
+        # Validate any custom field data, if present
+        if getattr(instance, 'custom_field_data', None):
+            self.assertDictEqual(instance.custom_field_data, DUMMY_CF_DATA)

+ 43 - 1
netbox/utilities/testing/utils.py

@@ -1,13 +1,16 @@
+import json
 import logging
 import re
 from contextlib import contextmanager
 
 from django.contrib.auth import get_user_model
 from django.contrib.auth.models import Permission
+from django.contrib.contenttypes.models import ContentType
 from django.utils.text import slugify
 
 from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Site
-from extras.models import Tag
+from extras.choices import CustomFieldTypeChoices
+from extras.models import CustomField, Tag
 from virtualization.models import Cluster, ClusterType, VirtualMachine
 
 
@@ -102,3 +105,42 @@ def disable_warnings(logger_name):
     logger.setLevel(logging.ERROR)
     yield
     logger.setLevel(current_level)
+
+
+#
+# Custom field testing
+#
+
+DUMMY_CF_DATA = {
+    'text_field': 'foo123',
+    'integer_field': 456,
+    'decimal_field': 456.12,
+    'boolean_field': True,
+    'json_field': {'abc': 123},
+}
+
+
+def add_custom_field_data(form_data, model):
+    """
+    Create some custom fields for the model and add a value for each to the form data.
+
+    Args:
+        form_data: The dictionary of form data to be updated
+        model: The model of the object the form seeks to create or modify
+    """
+    content_type = ContentType.objects.get_for_model(model)
+    custom_fields = (
+        CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='text_field', default='foo'),
+        CustomField(type=CustomFieldTypeChoices.TYPE_INTEGER, name='integer_field', default=123),
+        CustomField(type=CustomFieldTypeChoices.TYPE_DECIMAL, name='decimal_field', default=123.45),
+        CustomField(type=CustomFieldTypeChoices.TYPE_BOOLEAN, name='boolean_field', default=False),
+        CustomField(type=CustomFieldTypeChoices.TYPE_JSON, name='json_field', default='{"x": "y"}'),
+    )
+    CustomField.objects.bulk_create(custom_fields)
+    for cf in custom_fields:
+        cf.content_types.set([content_type])
+
+    form_data.update({
+        f'cf_{k}': v if type(v) is str else json.dumps(v)
+        for k, v in DUMMY_CF_DATA.items()
+    })

+ 10 - 3
netbox/utilities/testing/views.py

@@ -10,11 +10,11 @@ from django.utils.translation import gettext as _
 
 from extras.choices import ObjectChangeActionChoices
 from extras.models import ObjectChange
-from netbox.models.features import ChangeLoggingMixin
+from netbox.models.features import ChangeLoggingMixin, CustomFieldsMixin
 from users.models import ObjectPermission
 from utilities.choices import CSVDelimiterChoices, ImportFormatChoices
 from .base import ModelTestCase
-from .utils import disable_warnings, post_data
+from .utils import add_custom_field_data, disable_warnings, post_data
 
 __all__ = (
     'ModelViewTestCase',
@@ -26,7 +26,6 @@ __all__ = (
 # UI Tests
 #
 
-
 class ModelViewTestCase(ModelTestCase):
     """
     Base TestCase for model views. Subclass to test individual views.
@@ -166,6 +165,10 @@ class ViewTestCases:
             # Try GET with model-level permission
             self.assertHttpStatus(self.client.get(self._get_url('add')), 200)
 
+            # Add custom field data if the model supports it
+            if issubclass(self.model, CustomFieldsMixin):
+                add_custom_field_data(self.form_data, self.model)
+
             # Try POST with model-level permission
             initial_count = self._get_queryset().count()
             request = {
@@ -265,6 +268,10 @@ class ViewTestCases:
             # Try GET with model-level permission
             self.assertHttpStatus(self.client.get(self._get_url('edit', instance)), 200)
 
+            # Add custom field data if the model supports it
+            if issubclass(self.model, CustomFieldsMixin):
+                add_custom_field_data(self.form_data, self.model)
+
             # Try POST with model-level permission
             request = {
                 'path': self._get_url('edit', instance),