82 lines
2.1 KiB
Python
82 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from pydantic import ValidationError
|
|
from schemas import AnalysisConfig
|
|
from services.post_call.analyzer import (
|
|
_json_schema,
|
|
_parse_json_content,
|
|
_validated_result,
|
|
)
|
|
|
|
|
|
FIELDS = [
|
|
{
|
|
"id": "intent",
|
|
"name": "customer_intent",
|
|
"type": "enum",
|
|
"description": "客户意向",
|
|
"enum_values": ["high", "low"],
|
|
},
|
|
{
|
|
"id": "follow_up",
|
|
"name": "need_follow_up",
|
|
"type": "boolean",
|
|
"description": "是否需要跟进",
|
|
"enum_values": [],
|
|
},
|
|
]
|
|
|
|
|
|
class AnalysisConfigTest(unittest.TestCase):
|
|
def test_enabled_analysis_requires_model_and_fields(self):
|
|
with self.assertRaises(ValidationError):
|
|
AnalysisConfig(enabled=True)
|
|
|
|
def test_field_names_must_be_unique(self):
|
|
field = {
|
|
"id": "one",
|
|
"name": "customer_name",
|
|
"type": "string",
|
|
"description": "客户姓名",
|
|
}
|
|
with self.assertRaises(ValidationError):
|
|
AnalysisConfig(
|
|
enabled=True,
|
|
model_resource_id="model_001",
|
|
fields=[field, {**field, "id": "two"}],
|
|
)
|
|
|
|
|
|
class StructuredExtractionTest(unittest.TestCase):
|
|
def test_schema_marks_every_field_nullable_and_required(self):
|
|
schema = _json_schema(FIELDS)
|
|
self.assertEqual(
|
|
schema["required"], ["customer_intent", "need_follow_up"]
|
|
)
|
|
self.assertEqual(
|
|
schema["properties"]["customer_intent"]["enum"],
|
|
["high", "low", None],
|
|
)
|
|
|
|
def test_invalid_values_are_normalized_to_null(self):
|
|
result = _validated_result(
|
|
{"customer_intent": "medium", "need_follow_up": "yes"},
|
|
FIELDS,
|
|
)
|
|
self.assertEqual(
|
|
result,
|
|
{"customer_intent": None, "need_follow_up": None},
|
|
)
|
|
|
|
def test_json_parser_accepts_fenced_model_output(self):
|
|
self.assertEqual(
|
|
_parse_json_content('```json\n{"need_follow_up": true}\n```'),
|
|
{"need_follow_up": True},
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|