Add default config
This commit is contained in:
parent
228ab9bc0d
commit
c7c22aa265
3 changed files with 238 additions and 11 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue