"""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()