|
17 | 17 | from google.adk.utils._schema_utils import get_list_inner_type |
18 | 18 | from google.adk.utils._schema_utils import is_basemodel_schema |
19 | 19 | from google.adk.utils._schema_utils import is_list_of_basemodel |
| 20 | +from google.adk.utils._schema_utils import validate_node_data |
20 | 21 | from google.adk.utils._schema_utils import validate_schema |
| 22 | +from google.genai import types |
21 | 23 | from pydantic import BaseModel |
| 24 | +from pydantic import ValidationError |
| 25 | +import pytest |
22 | 26 |
|
23 | 27 |
|
24 | 28 | class SampleModel(BaseModel): |
@@ -144,3 +148,63 @@ def test_dict_schema(self): |
144 | 148 | json_text = '{"key1": 1, "key2": 2}' |
145 | 149 | result = validate_schema(dict[str, int], json_text) |
146 | 150 | assert result == {'key1': 1, 'key2': 2} |
| 151 | + |
| 152 | + |
| 153 | +class TestValidateNodeData: |
| 154 | + """Tests for validate_node_data function.""" |
| 155 | + |
| 156 | + def test_none_schema_or_data_returns_data(self): |
| 157 | + """Bypasses validation if schema or data is None.""" |
| 158 | + assert validate_node_data(None, 'some_data') == 'some_data' |
| 159 | + assert validate_node_data(SampleModel, None) is None |
| 160 | + |
| 161 | + def test_dict_or_types_schema_returns_data(self): |
| 162 | + """Bypasses validation if schema is dict or types.Schema.""" |
| 163 | + assert validate_node_data({'key': int}, 'some_data') == 'some_data' |
| 164 | + # Mock types.Schema |
| 165 | + schema = types.Schema(type=types.Type.STRING) |
| 166 | + assert validate_node_data(schema, 'some_data') == 'some_data' |
| 167 | + |
| 168 | + def test_content_schema_returns_data(self): |
| 169 | + """Bypasses validation if target schema is types.Content or subclass.""" |
| 170 | + result = validate_node_data( |
| 171 | + types.Content, types.Content(role='user', parts=[]) |
| 172 | + ) |
| 173 | + assert result == {'role': 'user', 'parts': []} |
| 174 | + |
| 175 | + def test_plain_basemodel_schema_validates_raw_dict(self): |
| 176 | + """Validates raw dict data against BaseModel schema.""" |
| 177 | + result = validate_node_data(SampleModel, {'name': 'test', 'value': 42}) |
| 178 | + assert result == {'name': 'test', 'value': 42} |
| 179 | + |
| 180 | + def test_content_data_and_preserve_content(self): |
| 181 | + """Validates wrapped content and wraps result back into Content.""" |
| 182 | + data = types.Content( |
| 183 | + role='user', |
| 184 | + parts=[types.Part(text='{"name": "test", "value": 42}')], |
| 185 | + ) |
| 186 | + result = validate_node_data(SampleModel, data, preserve_content=True) |
| 187 | + assert isinstance(result, types.Content) |
| 188 | + assert result.role == 'user' |
| 189 | + assert len(result.parts) == 1 |
| 190 | + assert result.parts[0].text == '{"name": "test", "value": 42}' |
| 191 | + |
| 192 | + def test_content_data_no_preserve_content(self): |
| 193 | + """Validates wrapped content and returns unwrapped dictionary.""" |
| 194 | + data = types.Content( |
| 195 | + role='user', |
| 196 | + parts=[types.Part(text='{"name": "test", "value": 42}')], |
| 197 | + ) |
| 198 | + result = validate_node_data(SampleModel, data, preserve_content=False) |
| 199 | + assert isinstance(result, dict) |
| 200 | + assert result == {'name': 'test', 'value': 42} |
| 201 | + |
| 202 | + def test_raw_json_string_validated_against_basemodel_schema(self): |
| 203 | + """Raw JSON string fails validation against BaseModel schema (not auto-parsed).""" |
| 204 | + with pytest.raises(ValidationError): |
| 205 | + validate_node_data(SampleModel, '{"name": "test", "value": 42}') |
| 206 | + |
| 207 | + def test_raw_string_not_parsed_with_str_schema(self): |
| 208 | + """Bypasses JSON parsing if schema is str.""" |
| 209 | + result = validate_node_data(str, 'hello') |
| 210 | + assert result == 'hello' |
0 commit comments