Spaces:
Running
Running
File size: 5,357 Bytes
a1757c5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | """
Unit tests for compose() — the brain.
Tests cover: message body generation, CTA, template params,
category-specific outputs, and customer-facing messages.
"""
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from app.core.compose import compose
# ── Sample contexts for testing ─────────────────────────────────────────────
DENTIST_CATEGORY = {
"slug": "dentists",
"voice": {"tone": "peer_clinical", "vocab_taboo": ["cure", "guaranteed"]},
"peer_stats": {"avg_rating": 4.4, "avg_ctr": 0.030},
"digest": [
{"id": "d_2026W17_jida_fluoride", "kind": "research",
"title": "3-mo fluoride recall cuts caries recurrence 38% better than 6-mo",
"source": "JIDA Oct 2026, p.14", "trial_n": 2100,
"patient_segment": "high_risk_adults"}
],
"offer_catalog": [],
"seasonal_beats": [],
"trend_signals": [],
}
MERCHANT_DRMEERA = {
"merchant_id": "m_001_drmeera",
"category_slug": "dentists",
"identity": {"name": "Dr. Meera's Dental Clinic", "owner_first_name": "Meera",
"city": "Delhi", "locality": "Lajpat Nagar", "verified": True,
"languages": ["en", "hi"]},
"subscription": {"status": "active", "plan": "Pro", "days_remaining": 82},
"performance": {"views": 2410, "calls": 18, "directions": 45, "ctr": 0.021,
"delta_7d": {"views_pct": 0.18, "calls_pct": -0.05}},
"offers": [{"id": "o1", "title": "Dental Cleaning @ ₹299", "status": "active"}],
"customer_aggregate": {"total_unique_ytd": 540, "lapsed_180d_plus": 78,
"retention_6mo_pct": 0.38, "high_risk_adult_count": 124},
"signals": ["stale_posts:22d", "ctr_below_peer_median"],
"review_themes": [],
}
TRIGGER_RESEARCH = {
"id": "trg_001", "scope": "merchant", "kind": "research_digest",
"source": "external", "merchant_id": "m_001_drmeera",
"payload": {"category": "dentists", "top_item_id": "d_2026W17_jida_fluoride"},
"urgency": 2, "suppression_key": "research:dentists:2026-W17",
"expires_at": "2026-05-03T00:00:00Z",
}
TRIGGER_PERF_DIP = {
"id": "trg_004", "scope": "merchant", "kind": "perf_dip",
"source": "internal", "merchant_id": "m_002",
"payload": {"metric": "calls", "delta_pct": -0.50, "window": "7d"},
"urgency": 4, "suppression_key": "perf_dip:m_002:calls:2026-W17",
}
CUSTOMER_PRIYA = {
"customer_id": "c_001_priya",
"merchant_id": "m_001_drmeera",
"identity": {"name": "Priya", "language_pref": "hi-en mix"},
"relationship": {"visits_total": 4, "last_visit": "2026-05-12"},
"state": "lapsed_soft",
}
TRIGGER_RECALL = {
"id": "trg_003", "scope": "customer", "kind": "recall_due",
"source": "internal", "merchant_id": "m_001_drmeera",
"customer_id": "c_001_priya",
"payload": {"service_due": "6_month_cleaning",
"available_slots": [{"label": "Wed 5 Nov, 6pm"}, {"label": "Thu 6 Nov, 5pm"}]},
"urgency": 3, "suppression_key": "recall:c_001:6mo",
}
# ── Tests ────────────────────────────────────────────────────────────────────
def test_research_digest_compose():
result = compose(DENTIST_CATEGORY, MERCHANT_DRMEERA, TRIGGER_RESEARCH)
assert "body" in result
assert len(result["body"]) > 30
# Should mention JIDA
assert "JIDA" in result["body"] or "jida" in result["body"].lower()
# Should mention the merchant's patients
assert "124" in result["body"] or "high-risk" in result["body"]
# Should have a CTA
assert "?" in result["body"]
print(f"PASS: research_digest — {result['body'][:80]}...")
def test_perf_dip_compose():
merchant = {**MERCHANT_DRMEERA, "merchant_id": "m_002",
"performance": {"views": 980, "calls": 4, "delta_7d": {"calls_pct": -0.50}}}
result = compose(DENTIST_CATEGORY, merchant, TRIGGER_PERF_DIP)
assert "body" in result
assert "50%" in result["body"] or "calls" in result["body"]
print(f"PASS: perf_dip — {result['body'][:80]}...")
def test_recall_customer_facing():
result = compose(DENTIST_CATEGORY, MERCHANT_DRMEERA, TRIGGER_RECALL, CUSTOMER_PRIYA)
assert "body" in result
assert "Priya" in result["body"]
assert "Dental Clinic" in result["body"] or "Dr. Meera" in result["body"]
print(f"PASS: recall — {result['body'][:80]}...")
def test_no_taboo_terms():
result = compose(DENTIST_CATEGORY, MERCHANT_DRMEERA, TRIGGER_RESEARCH)
body_l = result["body"].lower()
assert "cure" not in body_l
assert "guaranteed" not in body_l
print("PASS: no taboo terms in dentist output")
def test_compose_returns_required_keys():
result = compose(DENTIST_CATEGORY, MERCHANT_DRMEERA, TRIGGER_RESEARCH)
for key in ("body", "cta", "rationale"):
assert key in result, f"Missing key: {key}"
print("PASS: all required keys present")
if __name__ == "__main__":
test_research_digest_compose()
test_perf_dip_compose()
test_recall_customer_facing()
test_no_taboo_terms()
test_compose_returns_required_keys()
print("\nAll compose tests passed!")
|