Add default config

This commit is contained in:
Tobias Kunze 2025-11-10 14:02:34 +01:00
parent 228ab9bc0d
commit c7c22aa265
3 changed files with 238 additions and 11 deletions

View file

@ -5,6 +5,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from servala.core.crd import generate_custom_form_class
from servala.core.crd.forms import DEFAULT_FIELD_CONFIGS, MANDATORY_FIELDS
from servala.core.forms import ServiceDefinitionAdminForm
from servala.core.models import ControlPlaneCRD
@ -904,3 +905,182 @@ def test_three_plus_element_choices_fail_validation():
assert len(errors) > 0
assert "must have 1 or 2 elements" in str(errors[0])
def test_field_with_default_config_only_needs_mapping():
class TestModel(models.Model):
name = models.CharField(max_length=100)
class Meta:
app_label = "test"
minimal_config = {
"fieldsets": [
{
"fields": [
{
"controlplane_field_mapping": "name",
},
]
}
]
}
form_class = generate_custom_form_class(minimal_config, TestModel)
form = form_class()
name_field = form.fields["name"]
assert name_field.label == DEFAULT_FIELD_CONFIGS["name"]["label"]
assert name_field.help_text == DEFAULT_FIELD_CONFIGS["name"]["help_text"]
assert name_field.required == DEFAULT_FIELD_CONFIGS["name"]["required"]
def test_field_with_default_config_can_override_defaults():
class TestModel(models.Model):
name = models.CharField(max_length=100)
class Meta:
app_label = "test"
override_config = {
"fieldsets": [
{
"fields": [
{
"controlplane_field_mapping": "name",
"label": "Custom Name Label",
"required": False,
},
]
}
]
}
form_class = generate_custom_form_class(override_config, TestModel)
form = form_class()
name_field = form.fields["name"]
assert name_field.label == "Custom Name Label"
assert name_field.required is False
assert name_field.help_text == DEFAULT_FIELD_CONFIGS["name"]["help_text"]
def test_admin_form_validates_mandatory_fields_present():
mock_crd = Mock()
mock_crd.resource_schema = {
"properties": {
"spec": {
"properties": {
"environment": {
"type": "string",
"enum": ["dev", "prod"],
}
}
}
}
}
config_without_name = {
"fieldsets": [
{
"fields": [
{
"type": "choice",
"label": "Environment",
"controlplane_field_mapping": "spec.environment",
"choices": [["dev", "Development"]],
},
]
}
]
}
errors = []
included_mappings = set()
for fieldset in config_without_name.get("fieldsets", []):
for field in fieldset.get("fields", []):
mapping = field.get("controlplane_field_mapping")
included_mappings.add(mapping)
for mandatory_field in MANDATORY_FIELDS:
if mandatory_field not in included_mappings:
errors.append(f"Required field '{mandatory_field}' must be included")
assert len(errors) > 0
assert "name" in str(errors[0]).lower()
def test_admin_form_validates_fields_without_defaults_need_label_and_type():
config_with_incomplete_field = {
"fieldsets": [
{
"fields": [
{"controlplane_field_mapping": "name"}, # Has defaults - OK
{
"controlplane_field_mapping": "spec.unknown", # No defaults
# Missing label and type
},
]
}
]
}
errors = []
for fieldset in config_with_incomplete_field.get("fieldsets", []):
for field in fieldset.get("fields", []):
mapping = field.get("controlplane_field_mapping")
if mapping not in DEFAULT_FIELD_CONFIGS:
if not field.get("label"):
errors.append(
f"Field with mapping '{mapping}' must have a 'label' property"
)
if not field.get("type"):
errors.append(
f"Field with mapping '{mapping}' must have a 'type' property"
)
assert len(errors) == 2
assert any("label" in str(e) for e in errors)
assert any("type" in str(e) for e in errors)
def test_empty_values_dont_override_default_configs():
class TestModel(models.Model):
name = models.CharField(max_length=100)
class Meta:
app_label = "test"
admin_form_config = {
"fieldsets": [
{
"fields": [
{
"controlplane_field_mapping": "name",
"type": "",
"label": "",
"help_text": None,
"max_length": None,
"required": False,
},
]
}
]
}
form_class = generate_custom_form_class(admin_form_config, TestModel)
form = form_class()
name_field = form.fields["name"]
assert name_field.label == DEFAULT_FIELD_CONFIGS["name"]["label"]
assert name_field.help_text == DEFAULT_FIELD_CONFIGS["name"]["help_text"]
assert name_field.max_length == DEFAULT_FIELD_CONFIGS["name"]["max_length"]
assert name_field.required is False # Was overridden by explicit False