110 lines
4.3 KiB
Python
110 lines
4.3 KiB
Python
"""Regression tests for persona draft generation contract helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from .contracts.engine_gateway import GenerateResponse
|
|
from . import persona_generation_contract as contract
|
|
from .persona_read_model import PersonaDraftGenerateRequest
|
|
|
|
|
|
class PersonaGenerationContractTest(unittest.TestCase):
|
|
def test_persona_generation_schema_pins_required_fields(self) -> None:
|
|
schema = contract.persona_generation_schema()
|
|
draft_schema = schema["properties"]["draft"]
|
|
|
|
self.assertFalse(schema["additionalProperties"])
|
|
self.assertEqual(schema["required"], ["draft", "source_summary", "warnings"])
|
|
self.assertFalse(draft_schema["additionalProperties"])
|
|
self.assertIn("source_provenance", draft_schema["required"])
|
|
self.assertEqual(draft_schema["properties"]["difficulty"]["enum"], ["easy", "moderate", "hard"])
|
|
|
|
def test_persona_draft_prompt_bundle_is_stable(self) -> None:
|
|
bundle = contract.persona_draft_prompt_bundle()
|
|
|
|
self.assertEqual(bundle["id"], "persona-draft-rag")
|
|
self.assertEqual(bundle["version"], "2026-06-28.1")
|
|
self.assertRegex(bundle["hash"], r"^[0-9a-f]{12}$")
|
|
|
|
def test_persona_generation_payload_from_response_uses_legacy_json_fallback(self) -> None:
|
|
response = GenerateResponse(
|
|
text='```json\n{"source_summary":"요약","warnings":["검수 필요"]}\n```',
|
|
model="test-model",
|
|
provider="test-provider",
|
|
structured=None,
|
|
)
|
|
|
|
payload = contract.persona_generation_payload_from_response(response)
|
|
|
|
self.assertEqual(payload["source_summary"], "요약")
|
|
self.assertEqual(payload["warnings"], ["검수 필요"])
|
|
|
|
def test_persona_generation_payload_from_response_returns_empty_dict_for_invalid_output(self) -> None:
|
|
response = GenerateResponse(text="[1, 2, 3]", model="test-model", provider="test-provider")
|
|
|
|
self.assertEqual(contract.persona_generation_payload_from_response(response), {})
|
|
|
|
def test_coerce_persona_generated_draft_normalizes_nested_draft(self) -> None:
|
|
request = PersonaDraftGenerateRequest(
|
|
source_ids=["persona_authoring_test"],
|
|
source_kind="client_record",
|
|
code_hint="p9",
|
|
display_name_hint="힌트 페르소나",
|
|
difficulty="hard",
|
|
theory_target=["CBT"],
|
|
)
|
|
|
|
draft = contract.coerce_persona_generated_draft(
|
|
{
|
|
"draft": {
|
|
"difficulty": "unsupported",
|
|
"theory_target": [" Humanistic ", ""],
|
|
"big5": {"O": 0.8, "C": "ignored"},
|
|
"resistance": {},
|
|
"affect_baseline": {},
|
|
"is_synthetic": False,
|
|
}
|
|
},
|
|
request,
|
|
)
|
|
|
|
self.assertEqual(draft.code, "P9")
|
|
self.assertEqual(draft.display_name, "힌트 페르소나")
|
|
self.assertEqual(draft.difficulty, "hard")
|
|
self.assertEqual(draft.theory_target, ["humanistic"])
|
|
self.assertEqual(draft.big5, {"O": 0.8})
|
|
self.assertEqual(draft.resistance["base_resistance"], 0.5)
|
|
self.assertEqual(draft.source_provenance, "masked client_record")
|
|
self.assertFalse(draft.is_synthetic)
|
|
self.assertFalse(draft.submit_for_review)
|
|
|
|
def test_coerce_persona_generated_draft_accepts_top_level_payload_without_draft(self) -> None:
|
|
request = PersonaDraftGenerateRequest(
|
|
source_ids=["persona_authoring_test"],
|
|
source_kind="mixed_notes",
|
|
difficulty="moderate",
|
|
)
|
|
|
|
draft = contract.coerce_persona_generated_draft(
|
|
{
|
|
"code": "p10",
|
|
"display_name": "상위 페르소나",
|
|
"difficulty": "easy",
|
|
"theory_target": ["CBT"],
|
|
"demographics": "not-a-dict",
|
|
"presenting": {"summary": "불안"},
|
|
},
|
|
request,
|
|
)
|
|
|
|
self.assertEqual(draft.code, "P10")
|
|
self.assertEqual(draft.display_name, "상위 페르소나")
|
|
self.assertEqual(draft.difficulty, "easy")
|
|
self.assertEqual(draft.theory_target, ["cbt"])
|
|
self.assertEqual(draft.demographics, {})
|
|
self.assertEqual(draft.presenting, {"summary": "불안"})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|