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>
This commit is contained in:
Arthur Hanson 2024-04-17 13:05:05 -07:00 committed by GitHub
parent b5bb732031
commit 928014c766
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 7 deletions

View File

@ -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)

View File

@ -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()
})

View File

@ -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),