Skip to content

Commit 95c7a00

Browse files
committed
refactor: remove string boolean coercion and rely on JSON schema validation
1 parent 040987f commit 95c7a00

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

helm_values_manager/models/helm_values_config.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""HelmValuesConfig class for managing Helm values and secrets."""
22

33
import json
4+
import logging
45
import os
56
from dataclasses import dataclass, field
67
from typing import Any, Dict, Optional
@@ -12,6 +13,8 @@
1213
from helm_values_manager.models.path_data import PathData
1314
from helm_values_manager.models.value import Value
1415

16+
logger = logging.getLogger(__name__)
17+
1518

1619
@dataclass
1720
class Deployment:
@@ -45,6 +48,24 @@ def _load_schema(cls) -> Dict[str, Any]:
4548
with open(schema_path, "r", encoding="utf-8") as f:
4649
return json.load(f)
4750

51+
@classmethod
52+
def _validate_schema(cls, data: dict) -> None:
53+
"""
54+
Validate data against JSON schema.
55+
56+
Args:
57+
data: Dictionary to validate against schema
58+
59+
Raises:
60+
ValidationError: If the data does not match the schema
61+
"""
62+
schema = cls._load_schema()
63+
try:
64+
jsonschema.validate(instance=data, schema=schema)
65+
except ValidationError as e:
66+
logger.error("JSON schema validation failed: %s", e)
67+
raise
68+
4869
def add_config_path(
4970
self, path: str, description: Optional[str] = None, required: bool = False, sensitive: bool = False
5071
) -> None:
@@ -110,6 +131,10 @@ def set_value(self, path: str, environment: str, value: str) -> None:
110131

111132
def validate(self) -> None:
112133
"""Validate the configuration."""
134+
# Validate against JSON schema first
135+
self._validate_schema(self.to_dict())
136+
137+
# Then validate each path_data
113138
for path_data in self._path_map.values():
114139
path_data.validate()
115140

@@ -136,19 +161,9 @@ def from_dict(cls, data: dict) -> "HelmValuesConfig":
136161
Raises:
137162
ValidationError: If the configuration data is invalid
138163
"""
139-
# Convert string boolean values to actual booleans for backward compatibility
140-
data = data.copy() # Don't modify the input
141-
for config_item in data.get("config", []):
142-
for boolean_field in ["required", "sensitive"]:
143-
if boolean_field in config_item and isinstance(config_item[boolean_field], str):
144-
config_item[boolean_field] = config_item[boolean_field].lower() == "true"
145-
146164
# Validate against schema
147-
schema = cls._load_schema()
148-
try:
149-
jsonschema.validate(instance=data, schema=schema)
150-
except ValidationError as e:
151-
raise e
165+
data = data.copy() # Don't modify the input
166+
cls._validate_schema(data)
152167

153168
config = cls()
154169
config.version = data["version"]

tests/unit/models/test_helm_values_config.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Test suite for HelmValuesConfig class."""
22

3+
import jsonschema
34
import pytest
45

56
from helm_values_manager.models.helm_values_config import HelmValuesConfig
@@ -157,3 +158,18 @@ def test_validate():
157158

158159
# Should not raise error since path_data.validate() handles validation
159160
config.validate()
161+
162+
163+
def test_validate_with_schema():
164+
"""Test validation including schema validation."""
165+
# Create config with invalid version
166+
config = HelmValuesConfig()
167+
config.version = "invalid" # Version must match pattern in schema
168+
169+
# Should raise ValidationError due to schema validation
170+
with pytest.raises(jsonschema.exceptions.ValidationError, match=r"'invalid' is not one of"):
171+
config.validate()
172+
173+
# Fix version and test valid case
174+
config.version = "1.0"
175+
config.validate() # Should not raise error

tests/unit/models/test_schema_validation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ def test_type_coercion():
8686
"config": [
8787
{
8888
"path": "app.config.key1",
89-
"required": "true", # String instead of boolean
90-
"sensitive": "false", # String instead of boolean
89+
"required": True, # Proper boolean
90+
"sensitive": False, # Proper boolean
9191
"values": {},
9292
}
9393
],

0 commit comments

Comments
 (0)