mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-18 15:29:36 +00:00
371 lines
16 KiB
Python
371 lines
16 KiB
Python
"""Smoke tests for the event-sourced Revenue Memory layer."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
import pytest
|
|
|
|
from auto_client_acquisition.revenue_memory.audit import dsr_export, full_audit_export
|
|
from auto_client_acquisition.revenue_memory.event_store import InMemoryEventStore
|
|
from auto_client_acquisition.revenue_memory.events import (
|
|
EVENT_TYPES,
|
|
event_from_dict,
|
|
event_to_dict,
|
|
make_event,
|
|
)
|
|
from auto_client_acquisition.revenue_memory.projections import (
|
|
build_account_timeline,
|
|
build_agent_ledger,
|
|
build_campaign_performance,
|
|
build_compliance_audit,
|
|
build_customer_roi,
|
|
build_deal_health,
|
|
)
|
|
from auto_client_acquisition.revenue_memory.replay import (
|
|
replay_agent_ledger,
|
|
replay_campaign,
|
|
replay_compliance_audit,
|
|
replay_deal_health,
|
|
replay_for_account,
|
|
replay_for_customer,
|
|
)
|
|
from auto_client_acquisition.revenue_memory.retention import (
|
|
LEGAL_HOLD_TYPES,
|
|
apply_retention,
|
|
classify_retention_tier,
|
|
is_expired,
|
|
retention_summary,
|
|
)
|
|
from auto_client_acquisition.revenue_memory.timeline import (
|
|
render_timeline_markdown,
|
|
timeline_to_dashboard_dict,
|
|
)
|
|
|
|
|
|
def _now():
|
|
return datetime.now(timezone.utc).replace(tzinfo=None)
|
|
|
|
|
|
# ── events.py ─────────────────────────────────────────────────────
|
|
def test_make_event_assigns_unique_id():
|
|
e1 = make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1")
|
|
e2 = make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1")
|
|
assert e1.event_id != e2.event_id
|
|
assert e1.event_id.startswith("evt_")
|
|
|
|
|
|
def test_make_event_unknown_type_raises():
|
|
with pytest.raises(ValueError):
|
|
make_event(event_type="totally.fake", customer_id="c", subject_type="x", subject_id="y")
|
|
|
|
|
|
def test_event_serialization_round_trip():
|
|
e = make_event(
|
|
event_type="deal.won",
|
|
customer_id="c1",
|
|
subject_type="deal",
|
|
subject_id="d1",
|
|
payload={"value_sar": 50000},
|
|
)
|
|
e2 = event_from_dict(event_to_dict(e))
|
|
assert e2.event_id == e.event_id
|
|
assert e2.payload == e.payload
|
|
assert e2.event_type == "deal.won"
|
|
|
|
|
|
def test_event_taxonomy_no_duplicates():
|
|
assert len(EVENT_TYPES) == len(set(EVENT_TYPES))
|
|
|
|
|
|
# ── event_store.py ────────────────────────────────────────────────
|
|
def test_event_store_append_and_count():
|
|
store = InMemoryEventStore()
|
|
e = make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1")
|
|
store.append(e)
|
|
assert store.count() == 1
|
|
assert store.count(customer_id="c1") == 1
|
|
assert store.count(customer_id="c2") == 0
|
|
|
|
|
|
def test_event_store_filters_by_subject():
|
|
store = InMemoryEventStore()
|
|
store.append(make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1"))
|
|
store.append(make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a2"))
|
|
a1_events = list(store.read_for_subject("account", "a1", customer_id="c1"))
|
|
assert len(a1_events) == 1
|
|
assert a1_events[0].subject_id == "a1"
|
|
|
|
|
|
def test_event_store_export_import():
|
|
store = InMemoryEventStore()
|
|
store.append(make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1"))
|
|
store.append(make_event(event_type="message.sent", customer_id="c1", subject_type="account", subject_id="a1"))
|
|
dump = store.export_all()
|
|
new_store = InMemoryEventStore()
|
|
new_store.import_all(dump)
|
|
assert new_store.count() == 2
|
|
|
|
|
|
# ── projections.py — account timeline ────────────────────────────
|
|
def test_account_timeline_replays_metrics():
|
|
n = _now()
|
|
events = [
|
|
make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1", occurred_at=n - timedelta(days=10)),
|
|
make_event(event_type="message.sent", customer_id="c1", subject_type="account", subject_id="a1", occurred_at=n - timedelta(days=8)),
|
|
make_event(event_type="reply.received", customer_id="c1", subject_type="account", subject_id="a1", occurred_at=n - timedelta(days=7)),
|
|
make_event(event_type="meeting.booked", customer_id="c1", subject_type="account", subject_id="a1", occurred_at=n - timedelta(days=5)),
|
|
make_event(event_type="signal.detected", customer_id="c1", subject_type="account", subject_id="a1", occurred_at=n - timedelta(days=4)),
|
|
]
|
|
timeline = build_account_timeline(customer_id="c1", account_id="a1", events=events)
|
|
assert timeline.n_messages_sent == 1
|
|
assert timeline.n_replies == 1
|
|
assert timeline.n_meetings == 1
|
|
assert timeline.n_signals == 1
|
|
assert timeline.first_seen is not None
|
|
assert timeline.last_activity > timeline.first_seen
|
|
|
|
|
|
def test_account_timeline_empty_returns_empty():
|
|
timeline = build_account_timeline(customer_id="c1", account_id="a1", events=[])
|
|
assert timeline.n_messages_sent == 0
|
|
assert timeline.first_seen is None
|
|
|
|
|
|
def test_timeline_markdown_render():
|
|
n = _now()
|
|
events = [
|
|
make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1", occurred_at=n),
|
|
]
|
|
timeline = build_account_timeline(customer_id="c1", account_id="a1", events=events)
|
|
md = render_timeline_markdown(timeline)
|
|
assert "Timeline" in md
|
|
assert "a1" in md
|
|
|
|
|
|
def test_timeline_dashboard_dict():
|
|
n = _now()
|
|
events = [make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1", occurred_at=n)]
|
|
timeline = build_account_timeline(customer_id="c1", account_id="a1", events=events)
|
|
d = timeline_to_dashboard_dict(timeline)
|
|
assert "metrics" in d
|
|
assert d["account_id"] == "a1"
|
|
|
|
|
|
# ── projections.py — deal health ──────────────────────────────────
|
|
def test_deal_health_basic():
|
|
n = _now()
|
|
events = [
|
|
make_event(event_type="deal.created", customer_id="c1", subject_type="deal", subject_id="d1",
|
|
occurred_at=n - timedelta(days=5), payload={"value_sar": 100000, "stage": "discovery"}),
|
|
make_event(event_type="deal.stage_changed", customer_id="c1", subject_type="deal", subject_id="d1",
|
|
occurred_at=n - timedelta(days=2), payload={"to_stage": "proposal"}),
|
|
]
|
|
proj = build_deal_health(customer_id="c1", deal_id="d1", events=events, now=n)
|
|
assert proj.value_sar == 100000
|
|
assert proj.current_stage == "proposal"
|
|
assert proj.days_in_current_stage == 2
|
|
assert len(proj.stage_history) == 2
|
|
|
|
|
|
def test_deal_health_stalled_flag():
|
|
n = _now()
|
|
events = [
|
|
make_event(event_type="deal.created", customer_id="c1", subject_type="deal", subject_id="d1",
|
|
occurred_at=n - timedelta(days=30), payload={"value_sar": 50000, "stage": "open"}),
|
|
]
|
|
proj = build_deal_health(customer_id="c1", deal_id="d1", events=events, now=n)
|
|
assert any(f.startswith("in_stage_") for f in proj.risk_flags)
|
|
|
|
|
|
def test_deal_health_won_zeroes_risk():
|
|
n = _now()
|
|
events = [
|
|
make_event(event_type="deal.created", customer_id="c1", subject_type="deal", subject_id="d1",
|
|
occurred_at=n - timedelta(days=10), payload={"value_sar": 100000}),
|
|
make_event(event_type="deal.won", customer_id="c1", subject_type="deal", subject_id="d1",
|
|
occurred_at=n, payload={}),
|
|
]
|
|
proj = build_deal_health(customer_id="c1", deal_id="d1", events=events, now=n)
|
|
assert proj.health_score == 100
|
|
assert proj.current_stage == "won"
|
|
|
|
|
|
# ── projections.py — campaign ────────────────────────────────────
|
|
def test_campaign_performance():
|
|
events = []
|
|
for _ in range(10):
|
|
events.append(make_event(event_type="message.sent", customer_id="c1", subject_type="campaign", subject_id="camp1",
|
|
payload={"campaign_id": "camp1"}))
|
|
for _ in range(2):
|
|
events.append(make_event(event_type="reply.received", customer_id="c1", subject_type="campaign", subject_id="camp1",
|
|
payload={"campaign_id": "camp1"}))
|
|
proj = build_campaign_performance(customer_id="c1", campaign_id="camp1", events=events)
|
|
assert proj.sent == 10
|
|
assert proj.replied == 2
|
|
assert proj.reply_rate == 0.2
|
|
|
|
|
|
# ── projections.py — agent ledger ────────────────────────────────
|
|
def test_agent_ledger_counts():
|
|
events = [
|
|
make_event(event_type="agent.action_requested", customer_id="c1", subject_type="agent_task", subject_id="t1",
|
|
payload={"agent_id": "outreach", "task_id": "t1", "requires_approval": True}),
|
|
make_event(event_type="agent.action_approved", customer_id="c1", subject_type="agent_task", subject_id="t1",
|
|
payload={"agent_id": "outreach", "task_id": "t1"}),
|
|
make_event(event_type="agent.action_executed", customer_id="c1", subject_type="agent_task", subject_id="t1",
|
|
payload={"agent_id": "outreach", "task_id": "t1"}),
|
|
]
|
|
ledger = build_agent_ledger(customer_id="c1", events=events)
|
|
assert ledger.by_agent.get("outreach") == 3
|
|
assert ledger.by_status.get("action_executed") == 1
|
|
assert ledger.requires_review == 1
|
|
|
|
|
|
# ── projections.py — compliance audit ────────────────────────────
|
|
def test_compliance_audit_counts_opt_outs():
|
|
events = [
|
|
make_event(event_type="compliance.consent_recorded", customer_id="c1", subject_type="contact", subject_id="x"),
|
|
make_event(event_type="compliance.opt_out_received", customer_id="c1", subject_type="contact", subject_id="y"),
|
|
make_event(event_type="compliance.blocked", customer_id="c1", subject_type="message", subject_id="m1",
|
|
payload={"reason": "no_consent"}),
|
|
]
|
|
audit = build_compliance_audit(customer_id="c1", events=events)
|
|
assert audit.consent_recorded == 1
|
|
assert audit.opt_outs == 1
|
|
assert audit.blocked_messages == 1
|
|
assert audit.last_block_reason == "no_consent"
|
|
|
|
|
|
# ── projections.py — customer ROI ────────────────────────────────
|
|
def test_customer_roi_aggregates():
|
|
events = [
|
|
make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1"),
|
|
make_event(event_type="meeting.booked", customer_id="c1", subject_type="meeting", subject_id="m1"),
|
|
make_event(event_type="deal.created", customer_id="c1", subject_type="deal", subject_id="d1",
|
|
payload={"value_sar": 50000}),
|
|
make_event(event_type="deal.won", customer_id="c1", subject_type="deal", subject_id="d1",
|
|
payload={"value_sar": 50000}),
|
|
]
|
|
roi = build_customer_roi(customer_id="c1", events=events)
|
|
assert roi.n_leads == 1
|
|
assert roi.n_meetings == 1
|
|
assert roi.n_deals_won == 1
|
|
assert roi.revenue_won_sar == 50000
|
|
|
|
|
|
# ── replay.py end-to-end ─────────────────────────────────────────
|
|
def test_replay_for_account_via_store():
|
|
store = InMemoryEventStore()
|
|
n = _now()
|
|
store.append(make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a1", occurred_at=n))
|
|
store.append(make_event(event_type="message.sent", customer_id="c1", subject_type="account", subject_id="a1", occurred_at=n))
|
|
timeline = replay_for_account(customer_id="c1", account_id="a1", store=store)
|
|
assert timeline.n_messages_sent == 1
|
|
|
|
|
|
def test_replay_for_customer_via_store():
|
|
store = InMemoryEventStore()
|
|
store.append(make_event(event_type="deal.won", customer_id="c1", subject_type="deal", subject_id="d1",
|
|
payload={"value_sar": 25000}))
|
|
roi = replay_for_customer(customer_id="c1", store=store)
|
|
assert roi.revenue_won_sar == 25000
|
|
|
|
|
|
# ── retention.py ─────────────────────────────────────────────────
|
|
def test_retention_classifies_legal_hold():
|
|
assert classify_retention_tier("compliance.consent_recorded") == "legal_hold"
|
|
assert classify_retention_tier("compliance.opt_out_received") == "legal_hold"
|
|
|
|
|
|
def test_retention_classifies_operational():
|
|
assert classify_retention_tier("message.opened") == "operational"
|
|
assert classify_retention_tier("signal.detected") == "operational"
|
|
|
|
|
|
def test_retention_default_is_business_record():
|
|
assert classify_retention_tier("lead.created") == "business_record"
|
|
assert classify_retention_tier("deal.won") == "business_record"
|
|
|
|
|
|
def test_retention_legal_hold_never_expires():
|
|
n = _now()
|
|
e = make_event(
|
|
event_type="compliance.consent_recorded",
|
|
customer_id="c1", subject_type="contact", subject_id="x",
|
|
occurred_at=n - timedelta(days=365 * 100), # 100 years
|
|
)
|
|
assert is_expired(e, now=n) is False
|
|
|
|
|
|
def test_apply_retention_keeps_legal_hold_drops_old_business():
|
|
n = _now()
|
|
legal = make_event(
|
|
event_type="compliance.opt_out_received",
|
|
customer_id="c1", subject_type="contact", subject_id="x",
|
|
occurred_at=n - timedelta(days=365 * 5),
|
|
)
|
|
old_lead = make_event(
|
|
event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a",
|
|
occurred_at=n - timedelta(days=365 * 5),
|
|
)
|
|
fresh = make_event(
|
|
event_type="lead.created", customer_id="c1", subject_type="account", subject_id="b",
|
|
)
|
|
kept, removed = apply_retention([legal, old_lead, fresh], now=n)
|
|
kept_ids = {e.event_id for e in kept}
|
|
assert legal.event_id in kept_ids
|
|
assert fresh.event_id in kept_ids
|
|
assert old_lead.event_id in removed
|
|
|
|
|
|
def test_apply_retention_tombstones_old_operational():
|
|
n = _now()
|
|
old_op = make_event(
|
|
event_type="message.opened",
|
|
customer_id="c1", subject_type="message", subject_id="m1",
|
|
occurred_at=n - timedelta(days=200),
|
|
payload={"ip": "192.0.2.1"},
|
|
)
|
|
kept, removed = apply_retention([old_op], now=n)
|
|
assert len(kept) == 1
|
|
assert kept[0].event_type.endswith(".tombstoned")
|
|
assert kept[0].payload.get("_tombstoned") is True
|
|
# Original PII (ip) is gone
|
|
assert "ip" not in kept[0].payload
|
|
|
|
|
|
def test_retention_summary_counts():
|
|
n = _now()
|
|
events = [
|
|
make_event(event_type="message.opened", customer_id="c1", subject_type="message", subject_id="m"),
|
|
make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a"),
|
|
make_event(event_type="compliance.consent_recorded", customer_id="c1", subject_type="contact", subject_id="x"),
|
|
]
|
|
s = retention_summary(events)
|
|
assert s["operational"] == 1
|
|
assert s["business_record"] == 1
|
|
assert s["legal_hold"] == 1
|
|
|
|
|
|
# ── audit.py ─────────────────────────────────────────────────────
|
|
def test_full_audit_export_filters_customer():
|
|
events = [
|
|
make_event(event_type="lead.created", customer_id="c1", subject_type="account", subject_id="a"),
|
|
make_event(event_type="lead.created", customer_id="c2", subject_type="account", subject_id="b"),
|
|
]
|
|
out = full_audit_export(customer_id="c1", events=events)
|
|
assert len(out) == 1
|
|
assert out[0]["customer_id"] == "c1"
|
|
|
|
|
|
def test_dsr_export_finds_subject_by_id_or_payload():
|
|
events = [
|
|
make_event(event_type="lead.created", customer_id="c1", subject_type="contact", subject_id="ali@example.sa"),
|
|
make_event(event_type="message.sent", customer_id="c1", subject_type="message", subject_id="m1",
|
|
payload={"contact_id": "ali@example.sa"}),
|
|
]
|
|
out = dsr_export(customer_id="c1", data_subject_id="ali@example.sa", events=events)
|
|
assert out["n_events"] == 2
|
|
assert out["right_invoked"].startswith("Right of access")
|