74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
"""Persona-specific channel and initiation contracts."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
import pytest
|
|
|
|
from app.services.persona_generator import PersonaGenerator
|
|
from app.services.store import ensure_persona_shape, validate_persona_traits
|
|
from app.api.chat_routes import _scenario_config
|
|
|
|
|
|
class StubPersonaLLM:
|
|
def __init__(self, personas):
|
|
self.personas = personas
|
|
|
|
def complete_json(self, system_prompt, user_prompt, **kwargs):
|
|
return {"personas": self.personas}
|
|
|
|
|
|
def _persona(channel="line", initiation_mode="customer", **extra):
|
|
value = {
|
|
"name": "Customer",
|
|
"tier": "B",
|
|
"channel": channel,
|
|
"initiation_mode": initiation_mode,
|
|
}
|
|
value.update(extra)
|
|
return value
|
|
|
|
|
|
def _fifteen(**kwargs):
|
|
return [_persona(**kwargs) for _ in range(15)]
|
|
|
|
|
|
def test_persona_owns_initiation_even_when_scenario_changes():
|
|
customer = ensure_persona_shape(_persona(initiation_mode="customer"))
|
|
seller = ensure_persona_shape(_persona(initiation_mode="seller"))
|
|
|
|
_, customer_mode = _scenario_config("f2f_call", customer, "th")
|
|
_, seller_mode = _scenario_config("social", seller, "th")
|
|
|
|
assert customer_mode == "customer"
|
|
assert seller_mode == "seller"
|
|
|
|
|
|
def test_channel_and_initiation_are_retained_in_normalized_persona():
|
|
persona = ensure_persona_shape(_persona(channel="facebook", initiation_mode="seller"))
|
|
|
|
assert persona["channel"] == "facebook"
|
|
assert persona["initiation_mode"] == "seller"
|
|
validate_persona_traits(persona)
|
|
|
|
|
|
def test_invalid_channel_is_rejected_not_mapped_to_social():
|
|
generator = PersonaGenerator(StubPersonaLLM(_fifteen(channel="social")))
|
|
|
|
with pytest.raises(ValueError, match="channel"):
|
|
generator.generate(sales_kit={}, language="th", channel="facebook")
|
|
|
|
|
|
def test_invalid_initiation_is_rejected_not_mapped_to_customer():
|
|
generator = PersonaGenerator(StubPersonaLLM(_fifteen(initiation_mode="f2f_call")))
|
|
|
|
with pytest.raises(ValueError, match="initiation_mode"):
|
|
generator.generate(sales_kit={}, language="th", channel="facebook")
|
|
|
|
|
|
def test_generator_rejects_invalid_requested_channel():
|
|
generator = PersonaGenerator(StubPersonaLLM(_fifteen()))
|
|
|
|
with pytest.raises(ValueError, match="channel"):
|
|
generator.generate(sales_kit={}, language="th", channel="social")
|